Date: Wed, 8 Aug 2007 18:16:31 GMT From: Matus Harvan <mharvan@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 124911 for review Message-ID: <200708081816.l78IGVHi004383@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=124911 Change 124911 by mharvan@mharvan_home on 2007/08/08 18:15:52 ICMP plugin: keep-alive is timed by the last request sent rather than response received (relevant only for the client) Affected files ... .. //depot/projects/soc2007/mharvan-mtund/mtund.src/plugin_icmp.c#7 edit .. //depot/projects/soc2007/mharvan-mtund/mtund.src/tunneld.c#16 edit Differences ... ==== //depot/projects/soc2007/mharvan-mtund/mtund.src/plugin_icmp.c#7 (text+ko) ==== @@ -36,12 +36,13 @@ * how often should an empty request be sent to the server - This is * useful when the server has data to send but the client doesn't. */ -#define PLUGIN_ICMP_KEEP_ALIVE 1 +#define PLUGIN_ICMP_KEEP_ALIVE 2 typedef struct { int fd; /* udp socket to the other endpoint */ int state; /* is a client connected? */ int server; + struct event timer_ev; } plugin_icmp_datat; struct my_icmp_hdr { @@ -67,10 +68,10 @@ int old_sysctl; size_t old_sysctl_size = sizeof(old_sysctl); struct event ev; /* used by libevent to monitor our fd */ -int data_sent_after_last_receive = 0; /* has the client sent data - * after the last reply from the - * server was received? - */ +static int data_sent_after_last_receive = 0; /* has the client sent data + * after the last reply from the + * server was received? + */ u_int16_t in_cksum(u_int16_t *addr, int len) { @@ -176,6 +177,33 @@ } } +/* register a timer event */ +void +register_timer_ev(struct event *ev) +{ + struct timeval tv; + + tv.tv_sec=PLUGIN_ICMP_KEEP_ALIVE; + tv.tv_usec=0; + evtimer_del(ev); + evtimer_add(ev, &tv); +} + +/* handler function for the libevent timer event */ +void +plugin_icmp_timer_ev_handler(int fd, short ev_type, void *arg) +{ + plugin_icmp_datat *data = ((plugint*)arg)->data; + + /* send a request to the server */ + if (data->server == 0) { + plugin_receive(data->fd, EV_TIMEOUT, arg); + } + + /* register a timer event again */ + register_timer_ev(&data->timer_ev); +} + /* * server: 0 - client, 1 - server * @@ -223,41 +251,41 @@ freeaddrinfo(ai); } + /* open the socket */ data->fd = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP); - if (data->fd != -1) { - /* non-blocking i/o */ - fd_flags = fcntl(data->fd, F_GETFL, 0); - if (fd_flags == -1) - errx(EX_OSFILE, "Failed to get flags from the icmp socket fd\n"); - fcntl(data->fd, F_SETFL, fd_flags|O_NONBLOCK); + if (data->fd < 0) + return -1; + + /* non-blocking i/o */ + fd_flags = fcntl(data->fd, F_GETFL, 0); + if (fd_flags == -1) + errx(EX_OSFILE, "Failed to get flags from the icmp socket fd\n"); + fcntl(data->fd, F_SETFL, fd_flags|O_NONBLOCK); + + register_select_fd(data->fd, plugin_receive, pl, -1); - if (server) { - register_select_fd(data->fd, plugin_receive, pl, -1); - data->state = PLUGIN_STATE_INITIALIZED; - } else { - /* the client should send keep-alive request to the server */ - register_select_fd(data->fd, plugin_receive, pl, - PLUGIN_ICMP_KEEP_ALIVE); - data->state = PLUGIN_STATE_CONNECTED; - } - - if (server) { + if (server) { #ifdef __FreeBSD__ - if (0 != sysctlbyname("net.inet.icmp.echo_user", - &old_sysctl, &old_sysctl_size, - &new_sysctl, sizeof(new_sysctl))) - errx(EX_UNAVAILABLE, "Cannot set net.inet.icmp.echo_user " - "sysctl. Maybe you need to patch your kernel?"); - //system("sysctl net.inet.icmp.echo_user=1"); + if (0 != sysctlbyname("net.inet.icmp.echo_user", + &old_sysctl, &old_sysctl_size, + &new_sysctl, sizeof(new_sysctl))) + errx(EX_UNAVAILABLE, "Cannot set net.inet.icmp.echo_user " + "sysctl. Maybe you need to patch your kernel?"); + //system("sysctl net.inet.icmp.echo_user=1"); #endif #ifdef __linux__ - system("sysctl net.ipv4.icmp_echo_ignore_all=0"); + system("sysctl net.ipv4.icmp_echo_ignore_all=0"); #endif - } - return 0; - } else { - return -1; + + data->state = PLUGIN_STATE_INITIALIZED; + } else { /* client */ + data->state = PLUGIN_STATE_CONNECTED; + /* the client should send keep-alive request to the server */ + evtimer_set(&data->timer_ev, plugin_icmp_timer_ev_handler, pl); + register_timer_ev(&data->timer_ev); } + + return 0; } void @@ -311,6 +339,11 @@ (struct sockaddr*)&dst_addr, dst_addr_len); //(struct sockaddr*)dst, sizeof (struct sockaddr_in)); fprintf(stderr, "plugin_send: send returned %d\n", n); + + /* the client has to reset the timer for keep-alive requests */ + if (! datapl->server) /* client */ + register_timer_ev(&datapl->timer_ev); + return n; } @@ -329,6 +362,8 @@ char serv[NI_MAXSERV]; struct my_icmp_hdr *icmp = NULL; + data_sent_after_last_receive = 0; + printf("plugin_receive(ev_type: 0x%x)\n", ev_type); if (! (data->state == PLUGIN_STATE_CONNECTED @@ -337,11 +372,8 @@ } /* upon timeout send another request to the server */ - if (ev_type == EV_TIMEOUT) { - register_select_fd(data->fd, plugin_receive, arg, - PLUGIN_ICMP_KEEP_ALIVE); - //goto send_request; - } +/* if (ev_type == EV_TIMEOUT) */ +/* goto send_request; */ n = recvfrom(data->fd, packet, sizeof(packet), 0, (struct sockaddr *) &from, &fromlen); @@ -399,11 +431,10 @@ // goto pkt_not_for_us; } } - data_sent_after_last_receive = 0; if (n > 0) process_data_from_plugin(pl, packetp, n); - // send_request: + send_request: /* if no data was queued then ask the daemon for more data */ if (queued_urgent_data == NULL && queued_normal_data == NULL) plugin_report(pl, REPORT_READY_TO_SEND); ==== //depot/projects/soc2007/mharvan-mtund/mtund.src/tunneld.c#16 (text+ko) ====
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200708081816.l78IGVHi004383>