PERFORCE change 145824 for review
Rui Paulo
rpaulo at FreeBSD.org
Thu Jul 24 16:45:27 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=145824
Change 145824 by rpaulo at 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;
}
More information about the p4-projects
mailing list