Skip site navigation (1)Skip section navigation (2)
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>