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