Skip site navigation (1)Skip section navigation (2)
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>