Rev 359: fixed tcp data offset and checksum in http://samba.org/~tridge/ctdb

tridge at samba.org tridge at samba.org
Sun May 27 06:56:13 GMT 2007


------------------------------------------------------------
revno: 359
revision-id: tridge at samba.org-20070527065612-eru5ramnlqtgqkdy
parent: tridge at samba.org-20070527054743-ldficagg4243oz4g
committer: Andrew Tridgell <tridge at samba.org>
branch nick: tridge
timestamp: Sun 2007-05-27 16:56:12 +1000
message:
  fixed tcp data offset and checksum
modified:
  takeover/ctdb_takeover.c       ctdb_takeover.c-20070525071636-a5n1ihghjtppy08r-2
  takeover/system.c              system.c-20070525071636-a5n1ihghjtppy08r-3
  tools/ctdb_control.c           ctdb_control.c-20070426122705-9ehj1l5lu2gn9kuj-1
=== modified file 'takeover/ctdb_takeover.c'
--- a/takeover/ctdb_takeover.c	2007-05-27 05:47:43 +0000
+++ b/takeover/ctdb_takeover.c	2007-05-27 06:56:12 +0000
@@ -71,7 +71,7 @@
 			 (unsigned)ntohs(tcp->daddr.sin_port), 
 			 inet_ntoa(tcp->saddr.sin_addr),
 			 (unsigned)ntohs(tcp->saddr.sin_port)));
-		ret = ctdb_sys_send_ack(&tcp->daddr, &tcp->saddr);
+		ret = ctdb_sys_send_ack(&tcp->saddr, &tcp->daddr);
 		if (ret != 0) {
 			DEBUG(0,(__location__ " Failed to send tcp tickle ack for %s\n",
 				 inet_ntoa(tcp->saddr.sin_addr)));

=== modified file 'takeover/system.c'
--- a/takeover/system.c	2007-05-27 05:47:43 +0000
+++ b/takeover/system.c	2007-05-27 06:56:12 +0000
@@ -127,20 +127,42 @@
 	return 0;
 }
 
+
 /*
-  simple IP checksum - assumes data is multiple of 2 bytes long
+  uint16 checksum for n bytes
  */
-static uint16_t ip_checksum(uint16_t *data, size_t n)
+static uint32_t uint16_checksum(uint16_t *data, size_t n)
 {
-	uint16_t sum=0;
-	while (n--) {
-		sum += ntohs(*data);
+	uint32_t sum=0;
+	while (n>=2) {
+		sum += (uint32_t)ntohs(*data);
 		data++;
-	}
-	if (sum == 0) {
+		n -= 2;
+	}
+	if (n == 1) {
+		sum += (uint32_t)ntohs(*(uint8_t *)data);
+	}
+	return sum;
+}
+
+/*
+  simple TCP checksum - assumes data is multiple of 2 bytes long
+ */
+static uint16_t tcp_checksum(uint16_t *data, size_t n, struct iphdr *ip)
+{
+	uint32_t sum = uint16_checksum(data, n);
+	uint16_t sum2;
+	sum += uint16_checksum((uint16_t *)&ip->saddr, sizeof(ip->saddr));
+	sum += uint16_checksum((uint16_t *)&ip->daddr, sizeof(ip->daddr));
+	sum += ip->protocol + n;
+	sum = (sum & 0xFFFF) + (sum >> 16);
+	sum = (sum & 0xFFFF) + (sum >> 16);
+	sum2 = htons(sum);
+	sum2 = ~sum2;
+	if (sum2 == 0) {
 		return 0xFFFF;
 	}
-	return htons(sum);
+	return sum2;
 }
 
 /*
@@ -185,20 +207,21 @@
 	ZERO_STRUCT(pkt);
 	pkt.ip.version  = 4;
 	pkt.ip.ihl      = sizeof(pkt.ip)/4;
-	pkt.ip.tot_len  = sizeof(pkt);
+	pkt.ip.tot_len  = htons(sizeof(pkt));
 	pkt.ip.ttl      = 255;
 	pkt.ip.protocol = IPPROTO_TCP;
 	pkt.ip.saddr    = src->sin_addr.s_addr;
 	pkt.ip.daddr    = dest->sin_addr.s_addr;
-	pkt.ip.check    = ip_checksum((uint16_t *)&pkt.ip, sizeof(pkt.ip)/2);
+	pkt.ip.check    = 0;
 
 	pkt.tcp.source   = src->sin_port;
 	pkt.tcp.dest     = dest->sin_port;
 	pkt.tcp.ack      = 1;
-	pkt.tcp.check    = 0;
+	pkt.tcp.doff     = sizeof(pkt.tcp)/4;
+	pkt.tcp.check    = tcp_checksum((uint16_t *)&pkt.tcp, sizeof(pkt.tcp), &pkt.ip);
 
 	ret = sendto(s, &pkt, sizeof(pkt), 0, dest, sizeof(*dest));
-	if (ret != 0) {
+	if (ret != sizeof(pkt)) {
 		DEBUG(0,(__location__ " failed sendto (%s)\n", strerror(errno)));
 	}
 	close(s);

=== modified file 'tools/ctdb_control.c'
--- a/tools/ctdb_control.c	2007-05-25 07:04:13 +0000
+++ b/tools/ctdb_control.c	2007-05-27 06:56:12 +0000
@@ -1139,6 +1139,20 @@
 		{ "thaw", control_thaw },
 	};
 
+	{
+		struct sockaddr_in saddr, daddr;
+		inet_aton("192.168.115.128", &daddr.sin_addr);
+		inet_aton("192.168.115.1",   &saddr.sin_addr);
+		daddr.sin_port = htons(1234);
+		saddr.sin_port = htons(445);
+		daddr.sin_family = AF_INET;
+		saddr.sin_family = AF_INET;
+		ctdb_sys_send_ack(&daddr, &saddr);
+		exit(0);
+	}
+
+
+
 	pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_KEEP_FIRST);
 
 	while ((opt = poptGetNextOpt(pc)) != -1) {



More information about the samba-cvs mailing list