|
From: James C. <qu...@us...> - 2007-04-04 06:43:29
|
Update of /cvsroot/pptpclient/pptp-linux In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29248 Modified Files: ChangeLog Makefile NEWS pptp.8 pptp.c pptp_gre.c Added Files: test.c test.h Log Message: add reordering test code --- NEW FILE: test.c --- /* Packet reordering test implementation, intended to cause packets to be reordered for testing pptpd and other servers. Avoids the use of pqueue.c so that it can be tested independently. */ #include <unistd.h> #include <stdlib.h> #include <string.h> #include "util.h" #include "test.h" /* whether we are asked to test ordering, obtained from command line */ extern int test_type; /* rate at which to do test ordering changes */ extern int test_rate; /* trigger cycle */ static int test_ordering_cycle = 0; /* phase of reordering */ static int test_ordering_phase = 0; /* swap a packet every now and then */ static ssize_t write_reordered_swap(int fd, const void *buf, size_t count) { static void *pocket_buf = NULL; static int pocket_count = 0; int stat; switch (test_ordering_phase) { case 0: /* between triggers, send as normal */ test_ordering_cycle++; if (test_ordering_cycle == test_rate) test_ordering_phase++; return write(fd, buf, count); case 1: /* triggered, swap a packet */ test_ordering_cycle++; if (test_ordering_cycle == (test_rate+1)) { /* pocket the packet */ pocket_count = count; pocket_buf = malloc(count); memcpy(pocket_buf, buf, count); log("test order swap, packet buffered"); /* lie about the result */ return count; } else { /* after this, reset to normal */ test_ordering_cycle = 0; test_ordering_phase = 0; /* send the new packet first */ stat = write(fd, buf, count); if (stat != count) return stat; /* then send the old packet next */ stat = write(fd, pocket_buf, pocket_count); free(pocket_buf); log("test order swap, packets sent"); return count; } default: return write(fd, buf, count); } } /* hold ten packets and send the eleventh, then the ten in order */ static ssize_t write_reordered_retransmit(int fd, const void *buf, size_t count) { int test_length = 10; static void *pocket_buf[10]; static int pocket_count[10]; int stat, n; switch (test_ordering_phase) { case 0: /* between triggers, send as normal */ test_ordering_cycle++; if (test_ordering_cycle == test_rate) test_ordering_phase++; return write(fd, buf, count); case 1: /* triggered, buffer the packets */ test_ordering_cycle++; if (test_ordering_cycle == (test_rate+test_length)) { test_ordering_phase = 2; } /* pocket the packet */ n = test_ordering_cycle - test_rate - 1; pocket_count[n] = count; pocket_buf[n] = malloc(count); memcpy(pocket_buf[n], buf, count); log("test order retransmit, packet buffered"); /* lie about the result */ return count; case 2: /* after this, reset to normal */ test_ordering_cycle = 0; test_ordering_phase = 0; /* send the new packet first */ stat = write(fd, buf, count); if (stat != count) return stat; /* send the buffered packets in normal order */ for (n=0; n<test_length; n++) { stat = write(fd, pocket_buf[n], pocket_count[n]); /* ignores failures */ free(pocket_buf[n]); } log("test order retransmit, packets sent"); return count; default: return write(fd, buf, count); } } /* hold ten packets and send them in reverse order */ static ssize_t write_reordered_reverse(int fd, const void *buf, size_t count) { int test_length = 10; static void *pocket_buf[10]; static int pocket_count[10]; int stat, n; switch (test_ordering_phase) { case 0: /* between triggers, send as normal */ test_ordering_cycle++; if (test_ordering_cycle == test_rate) test_ordering_phase++; return write(fd, buf, count); case 1: /* triggered, buffer the packets */ test_ordering_cycle++; if (test_ordering_cycle == (test_rate+test_length)) { test_ordering_phase = 2; } /* pocket the packet */ n = test_ordering_cycle - test_rate - 1; pocket_count[n] = count; pocket_buf[n] = malloc(count); memcpy(pocket_buf[n], buf, count); log("test order reverse, packet buffered"); /* lie about the result */ return count; case 2: /* after this, reset to normal */ test_ordering_cycle = 0; test_ordering_phase = 0; /* send the new packet first */ stat = write(fd, buf, count); if (stat != count) return stat; /* send the buffered packets in reverse order */ for (n=test_length-1; n>0; n--) { stat = write(fd, pocket_buf[n], pocket_count[n]); /* ignores failures */ free(pocket_buf[n]); } log("test order reverse, packets sent"); return count; default: return write(fd, buf, count); } } /* dispatcher for write reordering tests */ static ssize_t write_reordered(int fd, const void *buf, size_t count) { switch (test_type) { case 1: /* swap a packet every now and then */ return write_reordered_swap(fd, buf, count); case 2: /* hold ten packets and send the eleventh, then the ten in order */ return write_reordered_retransmit(fd, buf, count); case 3: /* hold ten packets and send them in reverse order */ return write_reordered_reverse(fd, buf, count); default: return write(fd, buf, count); } } struct test_redirections *test_redirections() { static struct test_redirections *my = NULL; if (my == NULL) my = malloc(sizeof(struct test_redirections)); my->write = write; if (test_type) my->write = write_reordered; return my; } --- NEW FILE: test.h --- struct test_redirections { ssize_t (*write)(int fd, const void *buf, size_t count); }; struct test_redirections *test_redirections(); Index: ChangeLog =================================================================== RCS file: /cvsroot/pptpclient/pptp-linux/ChangeLog,v retrieving revision 1.111 retrieving revision 1.112 diff -u -d -r1.111 -r1.112 --- ChangeLog 15 Dec 2006 05:05:51 -0000 1.111 +++ ChangeLog 4 Apr 2007 06:43:15 -0000 1.112 @@ -1,3 +1,13 @@ +Wed Apr 4 16:30:24 2007 James Cameron <qu...@us...> + + * pptp.8, pptp.c: add --test-type and --test-rate options. + + * pptp_gre.c: use alternate write(2) function for sending GRE + packets. + + * test.c: implement reordering tests to assist with pptpd testing. + These tests reorder the stream to simulate real-world examples. + Fri Dec 15 02:02:08 2006 Michael Adda <mi...@ha...> * pptp_gre.c: when we fail to write due to a transient error Index: Makefile =================================================================== RCS file: /cvsroot/pptpclient/pptp-linux/Makefile,v retrieving revision 1.44 retrieving revision 1.45 diff -u -d -r1.44 -r1.45 --- Makefile 17 Aug 2006 04:39:28 -0000 1.44 +++ Makefile 4 Apr 2007 06:43:15 -0000 1.45 @@ -24,10 +24,10 @@ PPTP_OBJS = pptp.o pptp_gre.o ppp_fcs.o \ pptp_ctrl.o dirutil.o vector.o \ - inststr.o util.o version.o \ + inststr.o util.o version.o test.o \ pptp_quirks.o orckit_quirks.o pqueue.o pptp_callmgr.o routing.o -PPTP_DEPS = pptp_callmgr.h pptp_gre.h ppp_fcs.h util.h \ +PPTP_DEPS = pptp_callmgr.h pptp_gre.h ppp_fcs.h util.h test.h \ pptp_quirks.h orckit_quirks.h config.h pqueue.h routing.h all: config.h $(PPTP_BIN) pptpsetup.8 Index: NEWS =================================================================== RCS file: /cvsroot/pptpclient/pptp-linux/NEWS,v retrieving revision 1.55 retrieving revision 1.56 diff -u -d -r1.55 -r1.56 --- NEWS 15 Dec 2006 05:05:51 -0000 1.55 +++ NEWS 4 Apr 2007 06:43:15 -0000 1.56 @@ -1,3 +1,4 @@ +- add packet reordering test code for pptpd testing [Cameron] - ignore transient send errors [Adda] - fix flaw in return status check of select in GRE pipe [Cameron] - add route to PPTP server [Cameron] Index: pptp.8 =================================================================== RCS file: /cvsroot/pptpclient/pptp-linux/pptp.8,v retrieving revision 1.11 retrieving revision 1.12 diff -u -d -r1.11 -r1.12 --- pptp.8 19 Apr 2006 22:58:56 -0000 1.11 +++ pptp.8 4 Apr 2007 06:43:15 -0000 1.12 @@ -85,6 +85,15 @@ .B \-\-loglevel <level> Sets the debugging level (0=low, 1=default, 2=high) +.TP +.B \-\-test-type <n> +Enable packet reordering tests that damage the integrity of the packet stream to the server. Use this only when testing servers. Zero is the default, and means that packets are sent in the correct order. A value of one (1) causes a single swap between two packets, such that the sequence numbers might be 1 2 3 4 6 5 7 8 9. A value of two (2) causes ten packets to be buffered, then sent out of order but ascending, such that the sequence numbers might be 1 2 3 4 16 6 7 8 9 10 11 12 13 14 15 17 18 19 20. A value of three (3) causes ten packets to be buffered, then sent in the reverse order, like this; 1 2 3 4 16 15 14 13 12 11 10 9 8 7 6 5 17 18 19 20. + +.TP +.B \-\-test-rate <n> +Sets the number of packets to pass before causing a reordering test. Default is 100. Has no effect if test-type is zero. The result of test types 2 and 3 are undefined if this value is less than ten. + + .SH "QUIRKS" .TP Index: pptp.c =================================================================== RCS file: /cvsroot/pptpclient/pptp-linux/pptp.c,v retrieving revision 1.45 retrieving revision 1.46 diff -u -d -r1.45 -r1.46 --- pptp.c 2 Aug 2006 06:22:34 -0000 1.45 +++ pptp.c 4 Apr 2007 06:43:15 -0000 1.46 @@ -60,6 +60,8 @@ int syncppp = 0; int log_level = 1; int disable_buffer = 0; +int test_type = 0; +int test_rate = 100; struct in_addr get_ip_address(char *name); int open_callmgr(struct in_addr inetaddr, char *phonenr, int argc,char **argv,char **envp, int pty_fd, int gre_fd); @@ -93,7 +95,9 @@ " --max-echo-wait Time to wait before giving up on lack of reply\n" " --logstring <name> Use <name> instead of 'anon' in syslog messages\n" " --localbind <addr> Bind to specified IP address instead of wildcard\n" - " --loglevel <level> Sets the debugging level (0=low, 1=default, 2=high)\n", + " --loglevel <level> Sets the debugging level (0=low, 1=default, 2=high)\n" + " --test-type <type> Damage the packet stream by reordering\n" + " --test-rate <n> Do the test every n packets\n", version, progname, progname); log("%s called with wrong arguments, program not started.", progname); @@ -178,6 +182,8 @@ {"idle-wait", 1, 0, 0}, {"max-echo-wait", 1, 0, 0}, {"version", 0, 0, 0}, + {"test-type", 1, 0, 0}, + {"test-rate", 1, 0, 0}, {0, 0, 0, 0} }; int option_index = 0; @@ -252,6 +258,10 @@ } else if (option_index == 12) { /* --version */ fprintf(stdout, "%s\n", version); exit(0); + } else if (option_index == 13) { /* --test-type */ + test_type = atoi(optarg); + } else if (option_index == 14) { /* --test-rate */ + test_rate = atoi(optarg); } break; case '?': /* unrecognised option */ Index: pptp_gre.c =================================================================== RCS file: /cvsroot/pptpclient/pptp-linux/pptp_gre.c,v retrieving revision 1.42 retrieving revision 1.43 diff -u -d -r1.42 -r1.43 --- pptp_gre.c 15 Dec 2006 05:05:51 -0000 1.42 +++ pptp_gre.c 4 Apr 2007 06:43:15 -0000 1.43 @@ -12,6 +12,7 @@ #include <sys/stat.h> #include <sys/time.h> #include <unistd.h> +#include <stdlib.h> #include <string.h> #include <errno.h> #include <fcntl.h> @@ -20,6 +21,7 @@ #include "pptp_gre.h" #include "util.h" #include "pqueue.h" +#include "test.h" #define PACKET_MAX 8196 /* test for a 32 bit counter overflow */ @@ -42,6 +44,9 @@ int encaps_gre (int fd, void *pack, unsigned int len); int dequeue_gre(callback_t callback, int cl); +/* test redirection function pointers */ +struct test_redirections *my; + #if 1 #include <stdio.h> void print_packet(int fd, void *pack, unsigned int len) @@ -94,6 +99,8 @@ if (connect(s, (struct sockaddr *) &src_addr, sizeof(src_addr)) < 0) { warn("connect: %s", strerror(errno)); close(s); return -1; } + my = test_redirections(); + return s; } @@ -477,7 +484,8 @@ /* ack is in odd place because S == 0 */ u.header.seq = hton32(seq_recv); ack_sent = seq_recv; - rc = write(fd, &u.header, sizeof(u.header) - sizeof(u.header.seq)); + rc = (*my->write)(fd, &u.header, + sizeof(u.header) - sizeof(u.header.seq)); if (rc < 0) { if (errno == ENOBUFS) rc = 0; /* Simply ignore it */ @@ -511,7 +519,7 @@ seq_sent = seq; seq++; /* write this baby out to the net */ /* print_packet(2, u.buffer, header_len + len); */ - rc = write(fd, u.buffer, header_len + len); + rc = (*my->write)(fd, u.buffer, header_len + len); if (rc < 0) { if (errno == ENOBUFS) rc = 0; /* Simply ignore it */ |