Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 19 Aug 2007 12:30:49 GMT
From:      Matus Harvan <mharvan@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 125345 for review
Message-ID:  <200708191230.l7JCUnhR016715@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=125345

Change 125345 by mharvan@mharvan_bike-planet on 2007/08/19 12:30:34

	udp catchall plugin should set up a socket only after the daemon determines
	that payload was not garbage

Affected files ...

.. //depot/projects/soc2007/mharvan-mtund/mtund.src/mtund.c#7 edit
.. //depot/projects/soc2007/mharvan-mtund/mtund.src/plugin_udp_catchall.c#2 edit

Differences ...

==== //depot/projects/soc2007/mharvan-mtund/mtund.src/mtund.c#7 (text+ko) ====

@@ -1074,6 +1074,7 @@
 					    "plugin %s\n", pl->name);
 					set_client_pl(cl, pl);
 					cl->ping_counter = 0;
+					send_echo_request(cl);
 					return;
 				} else {
 					fprintf(stderr, "plugin %s failed to "

==== //depot/projects/soc2007/mharvan-mtund/mtund.src/plugin_udp_catchall.c#2 (text+ko) ====

@@ -53,6 +53,9 @@
 	/* previous value of net.inet.raw.udp_catchall sysctl variable */
 	int		 old_sysctl;
 	size_t		 old_sysctl_size;
+	/* last connection - addresses */
+	struct sockaddr_in sa1;
+	struct sockaddr_in sa2;
 };
 
 void plugin_accept_new_conn(int fd, short ev_type, void *arg);
@@ -207,8 +210,11 @@
 {
 	struct conn *conn = &data->conns[clid];
 	
-	if (conn->clid == clid && conn->fd == fd)
+	printf("conn_update_to_perm()\n");
+	if (conn->clid == clid && conn->fd == fd){
+		printf("nothing to do...\n");
 		return; /* nothing to do */
+	}
 	
 	/* discard previous connection */
 	if (conn->status == CONN_STATUS_PERM)
@@ -217,10 +223,13 @@
 	/* set up the new connection */
 	conn->fd = fd;
 	conn->clid = clid;
+	conn->status = CONN_STATUS_PERM;
 	event_set(&conn->ev, conn->fd, EV_PERSIST | EV_READ,
 	    plugin_receive, conn);
 	event_add(&conn->ev, NULL);
 	evtimer_set(&conn->timer_ev, plugin_conn_timeout, conn);
+
+	data->conn = conn;
 }
 
 
@@ -230,27 +239,97 @@
 	struct plugin_udpall_data *data = pl->data;
 	struct conn *conn = data->conn;
 	int fd;
+	int new_fd;
+	struct timeval tv;
 
-	/* update the connection status */
-	switch (conn_flag) {
-	case CONN_DISCARD:
-		conn_discard(conn);
+	printf("plugin_conn_map()\n");
+	
+	if (conn->status == CONN_STATUS_FREE) {	/* new connection */
+		printf("setting up a new connection\n");
+		switch (conn_flag) {
+		case CONN_DISCARD:
 			return;
 			
-	case CONN_TEMP:
-		break;
+		case CONN_TEMP:
+			break;
+			
+		case CONN_PERM:
+			conn = &data->conns[clid];
+			break;
+
+		default:
+			warnx("plugin_udp_catchall: invalid conn_flag 0x%x\n",
+			    conn_flag);
+			return;
+		}
 		
-	case CONN_PERM:
-		/* migrate a temporary connection to a permanent one */
-		fd = conn->fd;
-		if (conn->status == CONN_STATUS_TEMP) {
-			conn->status = CONN_STATUS_FREE;
-			evtimer_del(&conn->timer_ev);
-			event_del(&conn->ev);
-			conn->fd = -1;
+		/* set up the socket */
+		new_fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+		if (new_fd == -1) {
+			warn("socket() failed");
+			return;
+		}
+		/* set the source port */
+                if (0 != bind(new_fd, (struct sockaddr *)&data->sa1,
+			      sizeof(struct sockaddr))) {
+			warn("bind() failed");
+			close(new_fd);
+			return;
+		}
+		/* set the destination address and port */
+		if (0 != connect(new_fd, (struct sockaddr *)&data->sa2,
+				 sizeof(struct sockaddr))) {
+			warn("connect() failed");
+			close(new_fd);
+			return;
+		}
+		printf("new client connection accepted\n");
+
+		conn->fd = new_fd;
+		event_set(&conn->ev, conn->fd, EV_PERSIST | EV_READ,
+			  plugin_receive, conn);
+		event_add(&conn->ev, NULL);
+		evtimer_set(&conn->timer_ev, plugin_conn_timeout, conn);
+		if (conn_flag == CONN_TEMP) {
+			conn->clid = 0;
+			conn->status = CONN_STATUS_TEMP;
+			
+			tv.tv_sec = TEMP_CONN_TIMEOUT;
+			tv.tv_usec = 0;
+			evtimer_add(&conn->timer_ev, &tv);
+		} else { /* CONN_PERM */
+			conn->clid = clid;
+			conn->status = CONN_STATUS_PERM;
+			data->conn = conn;
+		}
+
+	} else { /* existing connection - update the connection status */
+		printf("updating an existing connection\n");
+		switch (conn_flag) {
+		case CONN_DISCARD:
+			conn_discard(conn);
+			return;
+			
+		case CONN_TEMP:
+			break;
+			
+		case CONN_PERM:
+			/* migrate a temporary connection to a permanent one */
+			fd = conn->fd;
+			if (conn->status == CONN_STATUS_TEMP) {
+				conn->status = CONN_STATUS_FREE;
+				evtimer_del(&conn->timer_ev);
+				event_del(&conn->ev);
+				conn->fd = -1;
+			}
+			conn_update_to_perm(data, clid, fd);
+			break;
+			
+		default:
+			warnx("plugin_udp_catchall: invalid conn_flag 0x%x\n",
+			    conn_flag);
+			return;
 		}
-		conn_update_to_perm(data, clid, fd);
-		break;
 	}
 }
 
@@ -260,23 +339,20 @@
 	struct plugin_udpall_data *data = ((struct conn *)arg)->data;
 	struct conn *conn = NULL;
 	int i;
-	struct timeval tv;
 	struct ip *iphdr;
 	struct udphdr *uhdr;    
 	struct sockaddr_storage from;
 	socklen_t fromlen = sizeof(from);
-	struct sockaddr_in sa1;
-	struct sockaddr_in sa2;
 	char buf[BUFLEN];
 	int buflen = 0;
 	char *bufp = buf;
 	char *payload;    
 	int payloadlen;
 	int nread;
-	int new_fd;
 	uint8_t clid;
 	int conn_flag;
 
+	printf("plugin_accept_new_conn()\n");
 	/* find a free tmpconn to store the connection metadata */
 	for (i = 0; i < MAXTMPCONNS; i++)
 		if (data->tmpconns[i].status == CONN_STATUS_FREE) {
@@ -287,6 +363,7 @@
 		printf("plugin_udp_catchall: too many new connections\n");
 		return;
 	}
+	data->conn = conn;
 
 	/* read the packet */
         nread = recvfrom(data->conns->fd, buf, BUFLEN, 0,
@@ -311,10 +388,10 @@
 	bufp += sizeof(*uhdr);
 	buflen -= sizeof(*uhdr);
 
-	memset(&sa1,0,sizeof(sa1));
-	sa1.sin_port = uhdr->uh_dport;
-	memcpy(&sa2, &from, sizeof(sa2));
-	sa2.sin_port = uhdr->uh_sport;
+	memset(&data->sa1,0,sizeof(data->sa1));
+	data->sa1.sin_port = uhdr->uh_dport;
+	memcpy(&data->sa2, &from, sizeof(data->sa2));
+	data->sa2.sin_port = uhdr->uh_sport;
 
 	if (buflen <= 0)
 		return;
@@ -323,43 +400,9 @@
 	payload = bufp;
 	payloadlen = buflen;
 
-/* 	process_data_from_plugin(data->pl, payload, payloadlen, */
-/* 	    &clid, &conn_flag); */
-	//TODO discard if CONN_DISCARD
-
-	new_fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
-	if (new_fd == -1)
-                err(EX_UNAVAILABLE, "socket() failed");
-	
-	int nbind =
-                bind(new_fd, (struct sockaddr *)&sa1, sizeof(struct sockaddr));
-	if (nbind != 0)
-                err(EX_NOHOST, "bind()failed");
-	
-	int nconnect = 
-		connect(new_fd, (struct sockaddr *)&sa2,
-		    sizeof(struct sockaddr));
-	if (nconnect != 0)
-                err(EX_NOHOST, "connect() failed");
-
-	printf("new client connection accepted\n");
-	conn->fd = new_fd;
-	conn->clid = 0;
-	conn->status = CONN_STATUS_TEMP;
-	event_set(&conn->ev, conn->fd, EV_PERSIST | EV_READ,
-		  plugin_receive, conn);
-	event_add(&conn->ev, NULL);
-
-	tv.tv_sec = TEMP_CONN_TIMEOUT;
-	tv.tv_usec = 0;
-	evtimer_set(&conn->timer_ev, plugin_conn_timeout, conn);
-	evtimer_add(&conn->timer_ev, &tv);
-	
-	data->conn = conn;
-
-
 	process_data_from_plugin(data->pl, payload, payloadlen,
 	    &clid, &conn_flag);
+	/* conn_map() will se up the connection */
 }
 
 
@@ -371,6 +414,8 @@
 	int conn_flag;
 	uint8_t clid = 0;
 
+	printf("plugin_receive()\n");
+
 	n = recv(fd, packet, sizeof(packet), 0);
 	
 	if (n == -1) {
@@ -414,6 +459,7 @@
 		return (SEND_PKT_SENT);
 	else {
 		warn("plugin_send: send returned %d", nwrite);
+		plugin_report(pl, clid, REPORT_ERROR_SEND);
 		return (SEND_ERROR);
 	}
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200708191230.l7JCUnhR016715>