PERFORCE change 124853 for review

Matus Harvan mharvan at FreeBSD.org
Tue Aug 7 16:13:36 PDT 2007


http://perforce.freebsd.org/chv.cgi?CH=124853

Change 124853 by mharvan at mharvan_bike-planet on 2007/08/07 23:12:42

	fragmentation now works with polling-style plugins as well

Affected files ...

.. //depot/projects/soc2007/mharvan-mtund/mtund.src/plugin_icmp.c#6 edit
.. //depot/projects/soc2007/mharvan-mtund/mtund.src/plugin_tcp.c#8 edit
.. //depot/projects/soc2007/mharvan-mtund/mtund.src/plugin_udp.c#7 edit
.. //depot/projects/soc2007/mharvan-mtund/mtund.src/tunneld.c#15 edit

Differences ...

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


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


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


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

@@ -36,6 +36,7 @@
  */
 static int process_data_from_tun(char *data, int len);
 
+static int send_next_frag();
 
 /* max transfered unit - encapsulated packet size */
 #define MTU 1500
@@ -59,6 +60,9 @@
 
 /* fragment id for the next packet to be fragmented */
 frag_hdr_t frag_hdr;
+char frag_data[MTU+sizeof(frag_hdr_t)];
+char *frag_datap = NULL;
+int frag_data_len = 0;
 uint frag_id = 0; // TODO: randomize
 
 /* fragmentat reassembly info list */
@@ -171,6 +175,11 @@
     if (current_pl == NULL)
 	return;
     
+    if (frag_datap != NULL) {
+	send_next_frag();
+	return;
+    }
+
     do {
 	//memset(packet, 0, sizeof(packet));
 	nread = tun_read(tun_fd, packet, PACKETLEN);
@@ -480,9 +489,7 @@
 static int
 process_data_from_tun(char *data, int len)
 {
-    int n = 0;
     char ldata[MTU+1];
-    char *ldatap = ldata;
 
     if (current_pl == NULL) {
 	fprintf(stderr, "no plugin connected yet, discarding tun data\n");
@@ -493,8 +500,7 @@
     printf("process_data_from_tun: len: %d, current_pl->mtu: %d\n",
 	   len, current_pl->mtu);
     /* no need to add the fragmentation header */
-    //TODO: fix fragmentation
-    if (len < current_pl->mtu || 1) {
+    if (len < current_pl->mtu) {
 	*ldata = DISPATCH_DATA;
 	memcpy(ldata+1, data, min(sizeof(ldata)-1, len));
 	return current_pl->send(current_pl, ldata, min(sizeof(ldata), len+1),
@@ -509,38 +515,55 @@
 	frag_hdr.size = len;
 	frag_hdr.offset = 0;
 	
+	frag_datap = frag_data;
+	frag_data_len = 0;
+
 	/* copy the payload */
-	memcpy(ldatap + sizeof(frag_hdr), data,
+	memcpy(frag_datap + sizeof(frag_hdr), data,
 	       min(sizeof(ldata) - sizeof(frag_hdr), len));
-	len += sizeof(frag_hdr);
-	    
-	while(len > sizeof(frag_hdr)) {
-	    printf("process_data_from_tun: sending frag "
-		   "offset %d, send_len %d, len %d\n",
-		   frag_hdr.offset, min(current_pl->mtu, len), len);
+	frag_data_len = len + sizeof(frag_hdr);
+
+	return send_next_frag();
+    }
+}
+
+static int
+send_next_frag()
+{
+    int nwrite = SEND_PKT_SENT;
+    int n;
+
+    while(frag_data_len > sizeof(frag_hdr) && nwrite == SEND_PKT_SENT) {
+	    printf("send_next_frag: sending frag "
+		   "offset %d, send_len %d, frag_data_len %d\n",
+		   frag_hdr.offset, min(current_pl->mtu, frag_data_len),
+		   frag_data_len);
 	    /* prepend the frag dispatch and header before the payload */
-	    memcpy(ldatap, &frag_hdr, sizeof(frag_hdr));
+	    memcpy(frag_datap, &frag_hdr, sizeof(frag_hdr));
 	    
 	    /* send it */
-	    //TODO: change the logic here, we should not fragment based
-	    //      on the return value from send()
-	    n = min(current_pl->mtu, len);
-	    (void) current_pl->send(current_pl, ldatap,
-				    min(current_pl->mtu, len), NORMAL_DATA);
-	    n -= sizeof(frag_hdr);
-	    if (n <= 0) {
-		fprintf(stderr, "process_data_from_tun: failed to send "
-			"data (%d)\n", n);
-		plugin_report(current_pl, REPORT_ERROR_SEND);
-		return SEND_ERROR;
+	    //TODO: maybe we should check how much data was actually sent
+	    n = min(current_pl->mtu, frag_data_len);
+	    nwrite = current_pl->send(current_pl, frag_datap, n, NORMAL_DATA);
+	    switch (nwrite) {
+	    case SEND_PKT_SENT:
+	    case SEND_PKT_QUEUED:
+		n -= sizeof(frag_hdr);
+		frag_datap += n;
+		frag_hdr.offset += n;
+		frag_data_len -= n;
+		break;
+	    default:
+		//plugin_report(current_pl, REPORT_ERROR_SEND);
+		return nwrite;
 	    }
-	    ldatap += n;
-	    frag_hdr.offset += n;
-	    len -= n;
-	}
-	return SEND_PKT_SENT;
+    }
+    if (frag_data_len <= sizeof(frag_hdr)) {
+	frag_datap = NULL;
+	frag_data_len = 0;
     }
-}
+    return nwrite;
+ }
 
 void
 plugin_report(plugint *pl, int err)


More information about the p4-projects mailing list