Date: Thu, 24 Jul 2008 16:45:26 GMT From: Rui Paulo <rpaulo@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 145824 for review Message-ID: <200807241645.m6OGjQeS075894@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=145824 Change 145824 by rpaulo@rpaulo_epsilon on 2008/07/24 16:44:33 Add more reading material. Move the analysis to verify.c. Implement 2MSL timeout. Affected files ... .. //depot/projects/soc2008/rpaulo-tcpad/Makefile#11 edit .. //depot/projects/soc2008/rpaulo-tcpad/READING#2 edit .. //depot/projects/soc2008/rpaulo-tcpad/dumper.c#9 edit .. //depot/projects/soc2008/rpaulo-tcpad/dumper.h#7 edit .. //depot/projects/soc2008/rpaulo-tcpad/handler.c#15 edit .. //depot/projects/soc2008/rpaulo-tcpad/tcpad.h#12 edit .. //depot/projects/soc2008/rpaulo-tcpad/timer.c#5 edit .. //depot/projects/soc2008/rpaulo-tcpad/verify.c#1 add .. //depot/projects/soc2008/rpaulo-tcpad/verify.h#1 add Differences ... ==== //depot/projects/soc2008/rpaulo-tcpad/Makefile#11 (text+ko) ==== @@ -1,7 +1,7 @@ -# $P4: //depot/projects/soc2008/rpaulo-tcpad/Makefile#10 $ +# $P4: //depot/projects/soc2008/rpaulo-tcpad/Makefile#11 $ PROG=tcpad -SRCS=main.c device.c linkhdr.c handler.c helper.c dumper.c timer.c +SRCS=main.c device.c linkhdr.c handler.c helper.c dumper.c timer.c verify.c CFLAGS+=-DDEBUG -ggdb CFLAGS+=-DDUMPER_PATH=\"dumpfiles\" WARNS=5 ==== //depot/projects/soc2008/rpaulo-tcpad/READING#2 (text+ko) ==== @@ -3,7 +3,14 @@ TCP: * RFC 793 - Transmission Control Protocol * RFC 2581 - TCP Congestion Control + * RFC 4614 - A Roadmap for Transmission Control Protocol (TCP) + Specification Documents TCP Extensions: * RFC 1323 - TCP Extensions for High Performance * RFC 2018 - TCP Selective Acknowledgement Options (SACK) * RFC 3168 - Explicit Congestion Notification (ECN) + + +Books: + + TCP/IP Illustrated, Vol. II ==== //depot/projects/soc2008/rpaulo-tcpad/dumper.c#9 (text+ko) ==== @@ -23,7 +23,7 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * $P4: //depot/projects/soc2008/rpaulo-tcpad/dumper.c#8 $ + * $P4: //depot/projects/soc2008/rpaulo-tcpad/dumper.c#9 $ */ #include <assert.h> @@ -45,11 +45,16 @@ * Adds a packet to a pool of packets pertinent to this connection. */ void -dumper_addpkt(struct dumppkth *head, const struct pcap_pkthdr *ph, +dumper_addpkt(struct tcpc *cp, const struct pcap_pkthdr *ph, const unsigned char *headers) { + struct dumppkth *head; struct dumppkt *dp; + assert(cp != NULL); + head = cp->pktshead; + assert(head != NULL); + dp = malloc(sizeof(*dp)); if (dp == NULL) { fprintf(stderr, "%s: malloc failed\n", __func__); @@ -75,6 +80,9 @@ FILE *fp; va_list ap; + assert(cp != NULL); + assert(cp->pktshead != NULL); + for (i = 0; i < 3000; i++) { snprintf(path, sizeof(path), "%s/dump%d.txt", DUMPER_PATH, i); if (access(path, F_OK) != 0) @@ -120,11 +128,11 @@ if (strlen(name) < 7) \ fprintf(fp, "\t"); \ if (cp) \ - fprintf(fp, "| %18u | ", cp->tp.field); \ + fprintf(fp, "| %18u | ", cp->tcb.field); \ else \ fprintf(fp, "| | "); \ if (cp->rcp) \ - fprintf(fp, "%18u |", cp->rcp->tp.field); \ + fprintf(fp, "%18u |", cp->rcp->tcb.field); \ \ fprintf(fp, "\n"); \ } while (0) @@ -149,10 +157,13 @@ * Free a list of packets and the head. */ void -dumper_free(struct dumppkth *head) +dumper_free(struct tcpc *cp) { + struct dumppkth *head; struct dumppkt *p1, *p2; + assert(cp != NULL); + head = cp->pktshead; assert(head != NULL); DPRINTF(DEBUG_DUMP, "freeing dumppkth struct @ %p\n", head); ==== //depot/projects/soc2008/rpaulo-tcpad/dumper.h#7 (text+ko) ==== @@ -23,7 +23,7 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * $P4: //depot/projects/soc2008/rpaulo-tcpad/dumper.h#6 $ + * $P4: //depot/projects/soc2008/rpaulo-tcpad/dumper.h#7 $ */ #ifndef _DUMPER_H_ @@ -39,9 +39,9 @@ TAILQ_HEAD(dumppkth, dumppkt); -void dumper_addpkt(struct dumppkth *head, const struct pcap_pkthdr *ph, +void dumper_addpkt(struct tcpc *cp, const struct pcap_pkthdr *ph, const unsigned char *headers); void dumper_error(struct tcpc *cp, const char *msg, ...); -void dumper_free(struct dumppkth *head); +void dumper_free(struct tcpc *cp); #endif /* _DUMPER_H_ */ ==== //depot/projects/soc2008/rpaulo-tcpad/handler.c#15 (text+ko) ==== @@ -23,7 +23,7 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * $P4: //depot/projects/soc2008/rpaulo-tcpad/handler.c#14 $ + * $P4: //depot/projects/soc2008/rpaulo-tcpad/handler.c#15 $ */ #include <assert.h> @@ -42,181 +42,49 @@ #include <arpa/inet.h> #include <pcap.h> +#include "tcpad.h" +#include "verify.h" #include "linkhdr.h" #include "handler.h" #include "dumper.h" #include "helper.h" -#include "tcpad.h" #include "debug.h" - void tcpad_pcaphandler(unsigned char *user, const struct pcap_pkthdr *ph, const unsigned char *bytes) { const struct ip *ip; - const struct tcphdr *tcp; + const struct tcphdr *th; + struct tcphdr tcp; int linkhlen; - struct tcpc *cp; - struct tcpc *rcp; + struct tcpc *cp, *rcp; linkhlen = (int)*user; - ip = (const struct ip *)linkhdr_remove(bytes, linkhlen); - tcp = (const struct tcphdr *)linkhdr_remove(bytes, + th = (const struct tcphdr *)linkhdr_remove(bytes, linkhlen + sizeof(struct ip)); - cp = find_conn(ip->ip_src, ip->ip_dst, tcp->th_sport, - tcp->th_dport); - rcp = find_conn(ip->ip_dst, ip->ip_src, tcp->th_dport, - tcp->th_sport); + memcpy(&tcp, th, sizeof(tcp)); - if ((tcp->th_flags & TH_FLAGS) == TH_SYN) { - if (cp) { - dumper_addpkt(cp->pktshead, ph, bytes); - dumper_error(p, cp->pktshead); - dumper_free(cp->pktshead); - LIST_REMOVE(cp, entries); - free(cp); - } - cp = malloc(sizeof(*cp)); - cp->t_state = TCPS_SYN_SENT; - cp->dport = tcp->th_dport; - cp->sport = tcp->th_sport; - cp->isv6 = 0; - cp->iss = tcp->th_seq; - cp->snd_una = cp->iss; - cp->snd_nxt = cp->iss+1; - cp->rcv_wnd = tcp->th_win; - memcpy(&cp->sv4addr, &ip->ip_src, sizeof(struct in_addr)); - memcpy(&cp->dv4addr, &ip->ip_dst, sizeof(struct in_addr)); - DPRINTF("tracking (syn) connection between %s and ", - inet_ntoa(cp->sv4addr)); - (tcp->th_flags & TH_FLAGS) == (TH_PSH|TH_ACK)) DPRINTF("%s\n",inet_ntoa(cp->dv4addr)); - LIST_INSERT_HEAD(&tcpchead, cp, entries); + tcp.th_seq = ntohl(tcp.th_seq); + tcp.th_ack = ntohl(tcp.th_ack); + tcp.th_win = ntohs(tcp.th_win); + tcp.th_urp = ntohs(tcp.th_urp); + tcp.th_sport = ntohs(tcp.th_sport); + tcp.th_dport = ntohs(tcp.th_dport); - /* - * Packet list. Only one per connection. - */ - cp->pktshead = malloc(sizeof(*cp->pktshead)); - TAILQ_INIT(cp->pktshead); - dumper_addpkt(cp->pktshead, ph, bytes); - } else if ((tcp->th_flags & TH_FLAGS) == (TH_SYN|TH_ACK)) { - if (rcp == NULL) { - /* ignore this syn+ack because we missed - the earlier syn. - */ - return; - } - if (cp) { - dumper_addpkt(cp->pktshead, ph, bytes); - dumper_error(p, cp->pktshead); - LIST_REMOVE(cp, entries); - LIST_REMOVE(rcp, entries); - free(cp); - free(rcp); - return; - } + /* Local endpoint */ + cp = find_conn(ip->ip_src, ip->ip_dst, tcp.th_sport, + tcp.th_dport); - if (SEQ_LT(tcp->th_ack, rcp->snd_nxt)) { - dumper_addpkt(rcp->pktshead, ph, bytes); - dumper_error(p, rcp->pktshead); - LIST_REMOVE(rcp, entries); - free(rcp); - return; - } - + /* Remote endpoint */ + rcp = find_conn(ip->ip_dst, ip->ip_src, tcp.th_dport, + tcp.th_sport); - cp = malloc(sizeof(*cp)); - cp->t_state = TCPS_SYN_RECEIVED; - cp->dport = tcp->th_dport; - cp->sport = tcp->th_sport; - cp->isv6 = 0; - cp->iss = tcp->th_seq; - cp->irs = rcp->iss; - cp->snd_una = cp->iss; - cp->snd_nxt = cp->iss+1; - rcp->irs = cp->iss; - memcpy(&cp->sv4addr, &ip->ip_src, sizeof(struct in_addr)); - memcpy(&cp->dv4addr, &ip->ip_dst, sizeof(struct in_addr)); - DPRINTF("tracking (syn/ack) connection between %s and ", - inet_ntoa(cp->sv4addr)); - DPRINTF("%s\n",inet_ntoa(cp->dv4addr)); - LIST_INSERT_HEAD(&tcpchead, cp, entries); + if (cp && cp->pktshead) + dumper_addpkt(cp, ph, bytes); - assert(rcp->pktshead != NULL); - cp->pktshead = rcp->pktshead; - dumper_addpkt(cp->pktshead, ph, bytes); - } else if ((tcp->th_flags & TH_FLAGS) == TH_ACK || - (tcp->th_flags & TH_FLAGS) == (TH_PSH|TH_ACK)) { - if (cp == NULL || rcp == NULL) - return; - - dumper_addpkt(cp->pktshead, ph, bytes); - if (cp->t_state == TCPS_ESTABLISHED && - rcp->t_state == TCPS_ESTABLISHED) { - if (tcp->th_len == 0 && cp->rcv_win == 0) { - - if (SEQ_LT(tcp->th_ack, cp->snd_una) && - SEQ_LEQ(tcp->th_ack, cp->snd_nxt)) { - - } else { - dumper_error(p, rcp->pktshead); - LIST_REMOVE(rcp, entries); - free(rcp); - return; - } - - } - else if (cp->t_state == TCPS_SYN_SENT || - cp->t_state == TCPS_SYN_RECEIVED) { - cp->t_state = TCPS_ESTABLISHED; - rcp->t_state = TCPS_ESTABLISHED; - DPRINTF("established\n"); - } - else if (cp->t_state == TCPS_ESTABLISHED && - rcp->t_state == TCPS_FIN_WAIT_1) { - DPRINTF("first ack\n"); - cp->t_state = TCPS_CLOSE_WAIT; - rcp->t_state = TCPS_FIN_WAIT_2; - } - else if (cp->t_state == TCPS_LAST_ACK || - cp->t_state == TCPS_CLOSING) { - cp->rcp = rcp; - rcp->rcp = cp; - cp->t_state = TCPS_TIME_WAIT; - DPRINTF("connection down\n"); - } - } else if ((tcp->th_flags & TH_FLAGS) == (TH_FIN|TH_ACK)) { - if (cp == NULL || rcp == NULL) - return; - - dumper_addpkt(cp->pktshead, ph, bytes); - if (cp->t_state == TCPS_ESTABLISHED) { - cp->t_state = TCPS_FIN_WAIT_1; - DPRINTF("fin_wait_1\n"); - } - if (cp->t_state == TCPS_CLOSE_WAIT && - rcp->t_state == TCPS_FIN_WAIT_2) { - DPRINTF("last_ack\n"); - cp->t_state = TCPS_TIME_WAIT; - rcp->t_state = TCPS_LAST_ACK; - } - if (rcp->t_state == TCPS_FIN_WAIT_1) { - DPRINTF("closing\n"); - cp->t_state = TCPS_CLOSING; - } - } else if ((tcp->th_flags & TH_FLAGS) == (TH_RST|TH_ACK)) { - if (rcp && rcp->t_state == TCPS_SYN_SENT) { - dumper_addpkt(rcp->pktshead, ph, bytes); - if (SEQ_GEQ(tcp->th_ack, rcp->snd_nxt)) { - DPRINTF("stopped tracking connection (rst) between" - " %s and ", inet_ntoa(rcp->sv4addr)); - DPRINTF("%s\n",inet_ntoa(rcp->dv4addr)); - LIST_REMOVE(rcp, entries); - free(rcp); - } else - dumper_error(p, rcp->pktshead); - } - } + cp = tcpad_verify_output(cp, rcp, ip, &tcp); + tcpad_verify_input(rcp, cp, ip, &tcp); } ==== //depot/projects/soc2008/rpaulo-tcpad/tcpad.h#12 (text+ko) ==== @@ -23,7 +23,7 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * $P4: //depot/projects/soc2008/rpaulo-tcpad/tcpad.h#11 $ + * $P4: //depot/projects/soc2008/rpaulo-tcpad/tcpad.h#12 $ */ #ifndef _TCPAD_H_ @@ -45,9 +45,12 @@ unsigned short sport; int isv6; struct dumppkth *pktshead; - struct tcpcb tp; + struct tcpcb tcb; struct tcpc *rcp; }; LIST_HEAD(tcpchead, tcpc) tcpchead; + + +#define TCPAD_MSL 60 /* sec. */ #endif /* _TCPAD_H_ */ ==== //depot/projects/soc2008/rpaulo-tcpad/timer.c#5 (text+ko) ==== @@ -23,9 +23,10 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * $P4: //depot/projects/soc2008/rpaulo-tcpad/timer.c#4 $ + * $P4: //depot/projects/soc2008/rpaulo-tcpad/timer.c#5 $ */ +#include <assert.h> #include <stdio.h> #include <stdlib.h> #include <signal.h> @@ -81,19 +82,21 @@ nc = 0; LIST_FOREACH_SAFE(cp, &tcpchead, entries, cp_t) { nc++; - if (cp->tp.t_state == TCPS_TIME_WAIT) { - DPRINTF(DEBUG_TIMER, "freeing tcp connection @ %p\n", + if (cp->tcb.t_state == TCPS_TIME_WAIT && + (time(NULL) - cp->tcb.t_rcvtime >= 2 * TCPAD_MSL)) { + DPRINTF(DEBUG_TIMER, "2 MSL timer went off: %p\n", cp); LIST_REMOVE(cp, entries); if (cp->pktshead) - dumper_free(cp->pktshead); + dumper_free(cp); cp->pktshead = NULL; + assert(cp->rcp != NULL); cp->rcp->pktshead = NULL; free(cp); nc--; } } if (nc != prevnc) - DPRINTF(DEBUG_TIMER, "connections being tracked: %d\n", nc); + DPRINTF(DEBUG_TIMER, "connections being tracked: %d\n", nc/2); prevnc = nc; }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200807241645.m6OGjQeS075894>