qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Blue Swirl <blauwirbel@gmail.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [6288] Fix 64 bit issue in slirp
Date: Tue, 13 Jan 2009 19:48:42 +0000	[thread overview]
Message-ID: <E1LMpFi-0004jl-OJ@cvs.savannah.gnu.org> (raw)

Revision: 6288
          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=6288
Author:   blueswir1
Date:     2009-01-13 19:48:42 +0000 (Tue, 13 Jan 2009)

Log Message:
-----------
Fix 64 bit issue in slirp

Signed-off-by: Gleb Natapov <gleb@redhat.com>

Modified Paths:
--------------
    trunk/slirp/ip.h
    trunk/slirp/ip_input.c
    trunk/slirp/misc.c
    trunk/slirp/slirp.c
    trunk/slirp/slirp.h
    trunk/slirp/tcp_input.c
    trunk/slirp/tcp_subr.c
    trunk/slirp/tcp_var.h
    trunk/slirp/tcpip.h
    trunk/slirp/udp.c
    trunk/slirp/udp.h

Modified: trunk/slirp/ip.h
===================================================================
--- trunk/slirp/ip.h	2009-01-13 19:47:10 UTC (rev 6287)
+++ trunk/slirp/ip.h	2009-01-13 19:48:42 UTC (rev 6288)
@@ -183,35 +183,31 @@
 
 #define	IP_MSS		576		/* default maximum segment size */
 
-#ifdef HAVE_SYS_TYPES32_H  /* Overcome some Solaris 2.x junk */
-#include <sys/types32.h>
-#else
 #if SIZEOF_CHAR_P == 4
-typedef caddr_t caddr32_t;
+struct mbuf_ptr {
+	struct mbuf *mptr;
+	uint32_t dummy;
+};
 #else
-typedef u_int32_t caddr32_t;
+struct mbuf_ptr {
+	struct mbuf *mptr;
+};
 #endif
-#endif
+struct qlink {
+	void *next, *prev;
+};
 
-#if SIZEOF_CHAR_P == 4
-typedef struct ipq *ipqp_32;
-typedef struct ipasfrag *ipasfragp_32;
-#else
-typedef caddr32_t ipqp_32;
-typedef caddr32_t ipasfragp_32;
-#endif
-
 /*
  * Overlay for ip header used by other protocols (tcp, udp).
  */
 struct ipovly {
-	caddr32_t	ih_next, ih_prev;	/* for protocol sequence q's */
+	struct mbuf_ptr ih_mbuf;	/* backpointer to mbuf */
 	u_int8_t	ih_x1;			/* (unused) */
 	u_int8_t	ih_pr;			/* protocol */
 	u_int16_t	ih_len;			/* protocol length */
 	struct	in_addr ih_src;		/* source internet address */
 	struct	in_addr ih_dst;		/* destination internet address */
-};
+} __attribute__((packed));
 
 /*
  * Ip reassembly queue structure.  Each fragment
@@ -221,44 +217,30 @@
  * size 28 bytes
  */
 struct ipq {
-	ipqp_32 next,prev;	/* to other reass headers */
+        struct qlink frag_link;			/* to ip headers of fragments */
+	struct qlink ip_link;				/* to other reass headers */
 	u_int8_t	ipq_ttl;		/* time for reass q to live */
 	u_int8_t	ipq_p;			/* protocol of this fragment */
 	u_int16_t	ipq_id;			/* sequence id for reassembly */
-	ipasfragp_32 ipq_next,ipq_prev;
-					/* to ip headers of fragments */
 	struct	in_addr ipq_src,ipq_dst;
 };
 
 /*
  * Ip header, when holding a fragment.
  *
- * Note: ipf_next must be at same offset as ipq_next above
+ * Note: ipf_link must be at same offset as frag_link above
  */
 struct	ipasfrag {
-#ifdef WORDS_BIGENDIAN
-	u_int	ip_v:4,
- 		ip_hl:4;
-#else
-	u_int	ip_hl:4,
-		ip_v:4;
-#endif
-                                        /* BUG : u_int changed to u_int8_t.
-                                         * sizeof(u_int)==4 on linux 2.0
-					 */
-        u_int8_t ipf_mff;		/* XXX overlays ip_tos: use low bit
-					 * to avoid destroying tos (PPPDTRuu);
-					 * copied from (ip_off&IP_MF) */
-	u_int16_t	ip_len;
-	u_int16_t	ip_id;
-	u_int16_t	ip_off;
-	u_int8_t	ip_ttl;
-	u_int8_t	ip_p;
-	u_int16_t	ip_sum;
-	ipasfragp_32 ipf_next;		/* next fragment */
-	ipasfragp_32 ipf_prev;		/* previous fragment */
+	struct qlink ipf_link;
+	struct ip ipf_ip;
 };
 
+#define ipf_off      ipf_ip.ip_off
+#define ipf_tos      ipf_ip.ip_tos
+#define ipf_len      ipf_ip.ip_len
+#define ipf_next     ipf_link.next
+#define ipf_prev     ipf_link.prev 
+
 /*
  * Structure stored in mbuf in inpcb.ip_options
  * and passed to ip_output when ip options are in use.

Modified: trunk/slirp/ip_input.c
===================================================================
--- trunk/slirp/ip_input.c	2009-01-13 19:47:10 UTC (rev 6287)
+++ trunk/slirp/ip_input.c	2009-01-13 19:48:42 UTC (rev 6288)
@@ -43,6 +43,7 @@
  */
 
 #include <slirp.h>
+#include <osdep.h>
 #include "ip_icmp.h"
 
 #ifdef LOG_ENABLED
@@ -51,7 +52,7 @@
 
 struct ipq ipq;
 
-static struct ip *ip_reass(register struct ipasfrag *ip,
+static struct ip *ip_reass(register struct ip *ip,
                            register struct ipq *fp);
 static void ip_freef(struct ipq *fp);
 static void ip_enq(register struct ipasfrag *p,
@@ -65,7 +66,7 @@
 void
 ip_init()
 {
-	ipq.next = ipq.prev = (ipqp_32)&ipq;
+	ipq.ip_link.next = ipq.ip_link.prev = &ipq.ip_link;
 	ip_id = tt.tv_sec & 0xffff;
 	udp_init();
 	tcp_init();
@@ -188,18 +189,20 @@
 	 */
 	if (ip->ip_off &~ IP_DF) {
 	  register struct ipq *fp;
+      struct qlink *l;
 		/*
 		 * Look for queue of fragments
 		 * of this datagram.
 		 */
-		for (fp = (struct ipq *) ipq.next; fp != &ipq;
-		     fp = (struct ipq *) fp->next)
-		  if (ip->ip_id == fp->ipq_id &&
-		      ip->ip_src.s_addr == fp->ipq_src.s_addr &&
-		      ip->ip_dst.s_addr == fp->ipq_dst.s_addr &&
-		      ip->ip_p == fp->ipq_p)
+		for (l = ipq.ip_link.next; l != &ipq.ip_link; l = l->next) {
+            fp = container_of(l, struct ipq, ip_link);
+            if (ip->ip_id == fp->ipq_id &&
+                    ip->ip_src.s_addr == fp->ipq_src.s_addr &&
+                    ip->ip_dst.s_addr == fp->ipq_dst.s_addr &&
+                    ip->ip_p == fp->ipq_p)
 		    goto found;
-		fp = 0;
+        }
+        fp = NULL;
 	found:
 
 		/*
@@ -209,9 +212,9 @@
 		 */
 		ip->ip_len -= hlen;
 		if (ip->ip_off & IP_MF)
-		  ((struct ipasfrag *)ip)->ipf_mff |= 1;
+		  ip->ip_tos |= 1;
 		else
-		  ((struct ipasfrag *)ip)->ipf_mff &= ~1;
+		  ip->ip_tos &= ~1;
 
 		ip->ip_off <<= 3;
 
@@ -220,9 +223,9 @@
 		 * or if this is not the first fragment,
 		 * attempt reassembly; if it succeeds, proceed.
 		 */
-		if (((struct ipasfrag *)ip)->ipf_mff & 1 || ip->ip_off) {
+		if (ip->ip_tos & 1 || ip->ip_off) {
 			STAT(ipstat.ips_fragments++);
-			ip = ip_reass((struct ipasfrag *)ip, fp);
+			ip = ip_reass(ip, fp);
 			if (ip == 0)
 				return;
 			STAT(ipstat.ips_reassembled++);
@@ -258,6 +261,8 @@
 	return;
 }
 
+#define iptofrag(P) ((struct ipasfrag *)(((char*)(P)) - sizeof(struct qlink)))
+#define fragtoip(P) ((struct ip*)(((char*)(P)) + sizeof(struct qlink)))
 /*
  * Take incoming datagram fragment and try to
  * reassemble it into whole datagram.  If a chain for
@@ -265,7 +270,7 @@
  * is given as fp; otherwise have to make a chain.
  */
 static struct ip *
-ip_reass(register struct ipasfrag *ip, register struct ipq *fp)
+ip_reass(register struct ip *ip, register struct ipq *fp)
 {
 	register struct mbuf *m = dtom(ip);
 	register struct ipasfrag *q;
@@ -292,13 +297,13 @@
 	  struct mbuf *t;
 	  if ((t = m_get()) == NULL) goto dropfrag;
 	  fp = mtod(t, struct ipq *);
-	  insque_32(fp, &ipq);
+	  insque(&fp->ip_link, &ipq.ip_link);
 	  fp->ipq_ttl = IPFRAGTTL;
 	  fp->ipq_p = ip->ip_p;
 	  fp->ipq_id = ip->ip_id;
-	  fp->ipq_next = fp->ipq_prev = (ipasfragp_32)fp;
-	  fp->ipq_src = ((struct ip *)ip)->ip_src;
-	  fp->ipq_dst = ((struct ip *)ip)->ip_dst;
+	  fp->frag_link.next = fp->frag_link.prev = &fp->frag_link;
+	  fp->ipq_src = ip->ip_src;
+	  fp->ipq_dst = ip->ip_dst;
 	  q = (struct ipasfrag *)fp;
 	  goto insert;
 	}
@@ -306,9 +311,9 @@
 	/*
 	 * Find a segment which begins after this one does.
 	 */
-	for (q = (struct ipasfrag *)fp->ipq_next; q != (struct ipasfrag *)fp;
-	    q = (struct ipasfrag *)q->ipf_next)
-		if (q->ip_off > ip->ip_off)
+	for (q = fp->frag_link.next; q != (struct ipasfrag *)&fp->frag_link;
+            q = q->ipf_next)
+		if (q->ipf_off > ip->ip_off)
 			break;
 
 	/*
@@ -316,9 +321,9 @@
 	 * our data already.  If so, drop the data from the incoming
 	 * segment.  If it provides all of our data, drop us.
 	 */
-	if (q->ipf_prev != (ipasfragp_32)fp) {
-		i = ((struct ipasfrag *)(q->ipf_prev))->ip_off +
-		  ((struct ipasfrag *)(q->ipf_prev))->ip_len - ip->ip_off;
+	if (q->ipf_prev != &fp->frag_link) {
+        struct ipasfrag *pq = q->ipf_prev;
+		i = pq->ipf_off + pq->ipf_len - ip->ip_off;
 		if (i > 0) {
 			if (i >= ip->ip_len)
 				goto dropfrag;
@@ -332,17 +337,18 @@
 	 * While we overlap succeeding segments trim them or,
 	 * if they are completely covered, dequeue them.
 	 */
-	while (q != (struct ipasfrag *)fp && ip->ip_off + ip->ip_len > q->ip_off) {
-		i = (ip->ip_off + ip->ip_len) - q->ip_off;
-		if (i < q->ip_len) {
-			q->ip_len -= i;
-			q->ip_off += i;
+	while (q != (struct ipasfrag*)&fp->frag_link &&
+            ip->ip_off + ip->ip_len > q->ipf_off) {
+		i = (ip->ip_off + ip->ip_len) - q->ipf_off;
+		if (i < q->ipf_len) {
+			q->ipf_len -= i;
+			q->ipf_off += i;
 			m_adj(dtom(q), i);
 			break;
 		}
-		q = (struct ipasfrag *) q->ipf_next;
-		m_freem(dtom((struct ipasfrag *) q->ipf_prev));
-		ip_deq((struct ipasfrag *) q->ipf_prev);
+		q = q->ipf_next;
+		m_freem(dtom(q->ipf_prev));
+		ip_deq(q->ipf_prev);
 	}
 
 insert:
@@ -350,27 +356,26 @@
 	 * Stick new segment in its place;
 	 * check for complete reassembly.
 	 */
-	ip_enq(ip, (struct ipasfrag *) q->ipf_prev);
+	ip_enq(iptofrag(ip), q->ipf_prev);
 	next = 0;
-	for (q = (struct ipasfrag *) fp->ipq_next; q != (struct ipasfrag *)fp;
-	     q = (struct ipasfrag *) q->ipf_next) {
-		if (q->ip_off != next)
+	for (q = fp->frag_link.next; q != (struct ipasfrag*)&fp->frag_link;
+            q = q->ipf_next) {
+		if (q->ipf_off != next)
 			return (0);
-		next += q->ip_len;
+		next += q->ipf_len;
 	}
-	if (((struct ipasfrag *)(q->ipf_prev))->ipf_mff & 1)
+	if (((struct ipasfrag *)(q->ipf_prev))->ipf_tos & 1)
 		return (0);
 
 	/*
 	 * Reassembly is complete; concatenate fragments.
 	 */
-	q = (struct ipasfrag *) fp->ipq_next;
+    q = fp->frag_link.next;
 	m = dtom(q);
 
 	q = (struct ipasfrag *) q->ipf_next;
-	while (q != (struct ipasfrag *)fp) {
-	  struct mbuf *t;
-	  t = dtom(q);
+	while (q != (struct ipasfrag*)&fp->frag_link) {
+	  struct mbuf *t = dtom(q);
 	  q = (struct ipasfrag *) q->ipf_next;
 	  m_cat(m, t);
 	}
@@ -381,7 +386,7 @@
 	 * dequeue and discard fragment reassembly header.
 	 * Make header visible.
 	 */
-	ip = (struct ipasfrag *) fp->ipq_next;
+	q = fp->frag_link.next;
 
 	/*
 	 * If the fragments concatenated to an mbuf that's
@@ -393,23 +398,23 @@
 	if (m->m_flags & M_EXT) {
 	  int delta;
 	  delta = (char *)ip - m->m_dat;
-	  ip = (struct ipasfrag *)(m->m_ext + delta);
+	  q = (struct ipasfrag *)(m->m_ext + delta);
 	}
 
 	/* DEBUG_ARG("ip = %lx", (long)ip);
 	 * ip=(struct ipasfrag *)m->m_data; */
 
+    ip = fragtoip(q);
 	ip->ip_len = next;
-	ip->ipf_mff &= ~1;
-	((struct ip *)ip)->ip_src = fp->ipq_src;
-	((struct ip *)ip)->ip_dst = fp->ipq_dst;
-	remque_32(fp);
+	ip->ip_tos &= ~1;
+	ip->ip_src = fp->ipq_src;
+	ip->ip_dst = fp->ipq_dst;
+	remque(&fp->ip_link);
 	(void) m_free(dtom(fp));
-	m = dtom(ip);
 	m->m_len += (ip->ip_hl << 2);
 	m->m_data -= (ip->ip_hl << 2);
 
-	return ((struct ip *)ip);
+	return ip;
 
 dropfrag:
 	STAT(ipstat.ips_fragdropped++);
@@ -426,13 +431,12 @@
 {
 	register struct ipasfrag *q, *p;
 
-	for (q = (struct ipasfrag *) fp->ipq_next; q != (struct ipasfrag *)fp;
-	    q = p) {
-		p = (struct ipasfrag *) q->ipf_next;
+	for (q = fp->frag_link.next; q != (struct ipasfrag*)&fp->frag_link; q = p) {
+		p = q->ipf_next;
 		ip_deq(q);
 		m_freem(dtom(q));
 	}
-	remque_32(fp);
+	remque(&fp->ip_link);
 	(void) m_free(dtom(fp));
 }
 
@@ -445,10 +449,10 @@
 {
 	DEBUG_CALL("ip_enq");
 	DEBUG_ARG("prev = %lx", (long)prev);
-	p->ipf_prev = (ipasfragp_32) prev;
+	p->ipf_prev =  prev;
 	p->ipf_next = prev->ipf_next;
-	((struct ipasfrag *)(prev->ipf_next))->ipf_prev = (ipasfragp_32) p;
-	prev->ipf_next = (ipasfragp_32) p;
+	((struct ipasfrag *)(prev->ipf_next))->ipf_prev = p;
+	prev->ipf_next = p;
 }
 
 /*
@@ -469,20 +473,21 @@
 void
 ip_slowtimo()
 {
-	register struct ipq *fp;
+    struct qlink *l;
 
 	DEBUG_CALL("ip_slowtimo");
 
-	fp = (struct ipq *) ipq.next;
-	if (fp == 0)
+    l = ipq.ip_link.next;
+
+	if (l == 0)
 	   return;
 
-	while (fp != &ipq) {
-		--fp->ipq_ttl;
-		fp = (struct ipq *) fp->next;
-		if (((struct ipq *)(fp->prev))->ipq_ttl == 0) {
+	while (l != &ipq.ip_link) {
+        struct ipq *fp = container_of(l, struct ipq, ip_link);
+        l = l->next;
+		if (--fp->ipq_ttl == 0) {
 			STAT(ipstat.ips_fragtimeout++);
-			ip_freef((struct ipq *) fp->prev);
+			ip_freef(fp);
 		}
 	}
 }

Modified: trunk/slirp/misc.c
===================================================================
--- trunk/slirp/misc.c	2009-01-13 19:47:10 UTC (rev 6287)
+++ trunk/slirp/misc.c	2009-01-13 19:48:42 UTC (rev 6288)
@@ -83,39 +83,6 @@
             our_addr.s_addr = loopback_addr.s_addr;
 }
 
-#if SIZEOF_CHAR_P == 8
-
-struct quehead_32 {
-	u_int32_t qh_link;
-	u_int32_t qh_rlink;
-};
-
-inline void
-insque_32(a, b)
-	void *a;
-	void *b;
-{
-	register struct quehead_32 *element = (struct quehead_32 *) a;
-	register struct quehead_32 *head = (struct quehead_32 *) b;
-	element->qh_link = head->qh_link;
-	head->qh_link = (u_int32_t)element;
-	element->qh_rlink = (u_int32_t)head;
-	((struct quehead_32 *)(element->qh_link))->qh_rlink
-	= (u_int32_t)element;
-}
-
-inline void
-remque_32(a)
-	void *a;
-{
-	register struct quehead_32 *element = (struct quehead_32 *) a;
-	((struct quehead_32 *)(element->qh_link))->qh_rlink = element->qh_rlink;
-	((struct quehead_32 *)(element->qh_rlink))->qh_link = element->qh_link;
-	element->qh_rlink = 0;
-}
-
-#endif /* SIZEOF_CHAR_P == 8 */
-
 struct quehead {
 	struct quehead *qh_link;
 	struct quehead *qh_rlink;

Modified: trunk/slirp/slirp.c
===================================================================
--- trunk/slirp/slirp.c	2009-01-13 19:47:10 UTC (rev 6287)
+++ trunk/slirp/slirp.c	2009-01-13 19:48:42 UTC (rev 6288)
@@ -262,7 +262,7 @@
 		 * in the fragment queue, or there are TCP connections active
 		 */
 		do_slowtimo = ((tcb.so_next != &tcb) ||
-			       ((struct ipasfrag *)&ipq != (struct ipasfrag *)ipq.next));
+                (&ipq.ip_link != ipq.ip_link.next));
 
 		for (so = tcb.so_next; so != &tcb; so = so_next) {
 			so_next = so->so_next;

Modified: trunk/slirp/slirp.h
===================================================================
--- trunk/slirp/slirp.h	2009-01-13 19:47:10 UTC (rev 6287)
+++ trunk/slirp/slirp.h	2009-01-13 19:48:42 UTC (rev 6288)
@@ -266,14 +266,6 @@
 
 void lprint _P((const char *, ...));
 
-#if SIZEOF_CHAR_P == 4
-# define insque_32 insque
-# define remque_32 remque
-#else
- void insque_32 _P((void *, void *));
- void remque_32 _P((void *));
-#endif
-
 #ifndef _WIN32
 #include <netdb.h>
 #endif

Modified: trunk/slirp/tcp_input.c
===================================================================
--- trunk/slirp/tcp_input.c	2009-01-13 19:47:10 UTC (rev 6287)
+++ trunk/slirp/tcp_input.c	2009-01-13 19:48:42 UTC (rev 6288)
@@ -71,7 +71,7 @@
 #ifdef TCP_ACK_HACK
 #define TCP_REASS(tp, ti, m, so, flags) {\
        if ((ti)->ti_seq == (tp)->rcv_nxt && \
-           (tp)->seg_next == (tcpiphdrp_32)(tp) && \
+           tcpfrag_list_empty(tp) && \
            (tp)->t_state == TCPS_ESTABLISHED) {\
                if (ti->ti_flags & TH_PUSH) \
                        tp->t_flags |= TF_ACKNOW; \
@@ -94,7 +94,7 @@
 #else
 #define	TCP_REASS(tp, ti, m, so, flags) { \
 	if ((ti)->ti_seq == (tp)->rcv_nxt && \
-	    (tp)->seg_next == (tcpiphdrp_32)(tp) && \
+        tcpfrag_list_empty(tp) && \
 	    (tp)->t_state == TCPS_ESTABLISHED) { \
 		tp->t_flags |= TF_DELACK; \
 		(tp)->rcv_nxt += (ti)->ti_len; \
@@ -134,8 +134,8 @@
 	/*
 	 * Find a segment which begins after this one does.
 	 */
-	for (q = (struct tcpiphdr *)tp->seg_next; q != (struct tcpiphdr *)tp;
-	    q = (struct tcpiphdr *)q->ti_next)
+	for (q = tcpfrag_list_first(tp); !tcpfrag_list_end(q, tp);
+            q = tcpiphdr_next(q))
 		if (SEQ_GT(q->ti_seq, ti->ti_seq))
 			break;
 
@@ -144,9 +144,9 @@
 	 * our data already.  If so, drop the data from the incoming
 	 * segment.  If it provides all of our data, drop us.
 	 */
-	if ((struct tcpiphdr *)q->ti_prev != (struct tcpiphdr *)tp) {
+	if (!tcpfrag_list_end(tcpiphdr_prev(q), tp)) {
 		register int i;
-		q = (struct tcpiphdr *)q->ti_prev;
+		q = tcpiphdr_prev(q);
 		/* conversion to int (in i) handles seq wraparound */
 		i = q->ti_seq + q->ti_len - ti->ti_seq;
 		if (i > 0) {
@@ -166,36 +166,36 @@
 			ti->ti_len -= i;
 			ti->ti_seq += i;
 		}
-		q = (struct tcpiphdr *)(q->ti_next);
+		q = tcpiphdr_next(q);
 	}
 	STAT(tcpstat.tcps_rcvoopack++);
 	STAT(tcpstat.tcps_rcvoobyte += ti->ti_len);
-	REASS_MBUF(ti) = (mbufp_32) m;		/* XXX */
+	ti->ti_mbuf = m;
 
 	/*
 	 * While we overlap succeeding segments trim them or,
 	 * if they are completely covered, dequeue them.
 	 */
-	while (q != (struct tcpiphdr *)tp) {
+	while (!tcpfrag_list_end(q, tp)) {
 		register int i = (ti->ti_seq + ti->ti_len) - q->ti_seq;
 		if (i <= 0)
 			break;
 		if (i < q->ti_len) {
 			q->ti_seq += i;
 			q->ti_len -= i;
-			m_adj((struct mbuf *) REASS_MBUF(q), i);
+			m_adj(q->ti_mbuf, i);
 			break;
 		}
-		q = (struct tcpiphdr *)q->ti_next;
-		m = (struct mbuf *) REASS_MBUF((struct tcpiphdr *)q->ti_prev);
-		remque_32((void *)(q->ti_prev));
+		q = tcpiphdr_next(q);
+		m = tcpiphdr_prev(q)->ti_mbuf;
+		remque(tcpiphdr2qlink(tcpiphdr_prev(q)));
 		m_freem(m);
 	}
 
 	/*
 	 * Stick new segment in its place.
 	 */
-	insque_32(ti, (void *)(q->ti_prev));
+	insque(tcpiphdr2qlink(ti), tcpiphdr2qlink(tcpiphdr_prev(q)));
 
 present:
 	/*
@@ -204,17 +204,17 @@
 	 */
 	if (!TCPS_HAVEESTABLISHED(tp->t_state))
 		return (0);
-	ti = (struct tcpiphdr *) tp->seg_next;
-	if (ti == (struct tcpiphdr *)tp || ti->ti_seq != tp->rcv_nxt)
+	ti = tcpfrag_list_first(tp);
+	if (tcpfrag_list_end(ti, tp) || ti->ti_seq != tp->rcv_nxt)
 		return (0);
 	if (tp->t_state == TCPS_SYN_RECEIVED && ti->ti_len)
 		return (0);
 	do {
 		tp->rcv_nxt += ti->ti_len;
 		flags = ti->ti_flags & TH_FIN;
-		remque_32(ti);
-		m = (struct mbuf *) REASS_MBUF(ti); /* XXX */
-		ti = (struct tcpiphdr *)ti->ti_next;
+		remque(tcpiphdr2qlink(ti));
+		m = ti->ti_mbuf;
+		ti = tcpiphdr_next(ti);
 /*		if (so->so_state & SS_FCANTRCVMORE) */
 		if (so->so_state & SS_FCANTSENDMORE)
 			m_freem(m);
@@ -302,7 +302,8 @@
 	 * Checksum extended TCP header and data.
 	 */
 	tlen = ((struct ip *)ti)->ip_len;
-	ti->ti_next = ti->ti_prev = 0;
+	tcpiphdr2qlink(ti)->next = tcpiphdr2qlink(ti)->prev = 0;
+    memset(&ti->ti_i.ih_mbuf, 0 , sizeof(struct mbuf_ptr));
 	ti->ti_x1 = 0;
 	ti->ti_len = htons((u_int16_t)tlen);
 	len = sizeof(struct ip ) + tlen;
@@ -560,7 +561,7 @@
 				return;
 			}
 		} else if (ti->ti_ack == tp->snd_una &&
-		    tp->seg_next == (tcpiphdrp_32)tp &&
+		    tcpfrag_list_empty(tp) &&
 		    ti->ti_len <= sbspace(&so->so_rcv)) {
 			/*
 			 * this is a pure, in-sequence data packet

Modified: trunk/slirp/tcp_subr.c
===================================================================
--- trunk/slirp/tcp_subr.c	2009-01-13 19:47:10 UTC (rev 6287)
+++ trunk/slirp/tcp_subr.c	2009-01-13 19:48:42 UTC (rev 6288)
@@ -73,7 +73,7 @@
 	struct socket *so = tp->t_socket;
 	register struct tcpiphdr *n = &tp->t_template;
 
-	n->ti_next = n->ti_prev = 0;
+	n->ti_mbuf = NULL;
 	n->ti_x1 = 0;
 	n->ti_pr = IPPROTO_TCP;
 	n->ti_len = htons(sizeof (struct tcpiphdr) - sizeof (struct ip));
@@ -156,7 +156,7 @@
 	tlen += sizeof (struct tcpiphdr);
 	m->m_len = tlen;
 
-	ti->ti_next = ti->ti_prev = 0;
+	ti->ti_mbuf = 0;
 	ti->ti_x1 = 0;
 	ti->ti_seq = htonl(seq);
 	ti->ti_ack = htonl(ack);
@@ -196,7 +196,7 @@
 		return ((struct tcpcb *)0);
 
 	memset((char *) tp, 0, sizeof(struct tcpcb));
-	tp->seg_next = tp->seg_prev = (tcpiphdrp_32)tp;
+	tp->seg_next = tp->seg_prev = (struct tcpiphdr*)tp;
 	tp->t_maxseg = TCP_MSS;
 
 	tp->t_flags = TCP_DO_RFC1323 ? (TF_REQ_SCALE|TF_REQ_TSTMP) : 0;
@@ -272,11 +272,11 @@
 	DEBUG_ARG("tp = %lx", (long )tp);
 
 	/* free the reassembly queue, if any */
-	t = (struct tcpiphdr *) tp->seg_next;
-	while (t != (struct tcpiphdr *)tp) {
-		t = (struct tcpiphdr *)t->ti_next;
-		m = (struct mbuf *) REASS_MBUF((struct tcpiphdr *)t->ti_prev);
-		remque_32((struct tcpiphdr *) t->ti_prev);
+	t = tcpfrag_list_first(tp);
+	while (!tcpfrag_list_end(t, tp)) {
+		t = tcpiphdr_next(t);
+		m = tcpiphdr_prev(t)->ti_mbuf;
+		remque(tcpiphdr2qlink(tcpiphdr_prev(t)));
 		m_freem(m);
 	}
 	/* It's static */

Modified: trunk/slirp/tcp_var.h
===================================================================
--- trunk/slirp/tcp_var.h	2009-01-13 19:47:10 UTC (rev 6287)
+++ trunk/slirp/tcp_var.h	2009-01-13 19:48:42 UTC (rev 6288)
@@ -40,18 +40,12 @@
 #include "tcpip.h"
 #include "tcp_timer.h"
 
-#if SIZEOF_CHAR_P == 4
- typedef struct tcpiphdr *tcpiphdrp_32;
-#else
- typedef u_int32_t tcpiphdrp_32;
-#endif
-
 /*
  * Tcp control block, one per tcp; fields:
  */
 struct tcpcb {
-	tcpiphdrp_32 seg_next;	/* sequencing queue */
-	tcpiphdrp_32 seg_prev;
+	struct tcpiphdr *seg_next;	/* sequencing queue */
+	struct tcpiphdr *seg_prev;
 	short	t_state;		/* state of this connection */
 	short	t_timer[TCPT_NTIMERS];	/* tcp timers */
 	short	t_rxtshift;		/* log(2) of rexmt exp. backoff */
@@ -170,21 +164,6 @@
 #define	TCP_REXMTVAL(tp) \
 	(((tp)->t_srtt >> TCP_RTT_SHIFT) + (tp)->t_rttvar)
 
-/* XXX
- * We want to avoid doing m_pullup on incoming packets but that
- * means avoiding dtom on the tcp reassembly code.  That in turn means
- * keeping an mbuf pointer in the reassembly queue (since we might
- * have a cluster).  As a quick hack, the source & destination
- * port numbers (which are no longer needed once we've located the
- * tcpcb) are overlayed with an mbuf pointer.
- */
-#if SIZEOF_CHAR_P == 4
-typedef struct mbuf *mbufp_32;
-#else
-typedef u_int32_t mbufp_32;
-#endif
-#define REASS_MBUF(ti) (*(mbufp_32 *)&((ti)->ti_t))
-
 #ifdef LOG_ENABLED
 /*
  * TCP statistics.

Modified: trunk/slirp/tcpip.h
===================================================================
--- trunk/slirp/tcpip.h	2009-01-13 19:47:10 UTC (rev 6287)
+++ trunk/slirp/tcpip.h	2009-01-13 19:48:42 UTC (rev 6288)
@@ -44,8 +44,7 @@
 	struct 	ipovly ti_i;		/* overlaid ip structure */
 	struct	tcphdr ti_t;		/* tcp header */
 };
-#define	ti_next		ti_i.ih_next
-#define	ti_prev		ti_i.ih_prev
+#define	ti_mbuf		ti_i.ih_mbuf.mptr
 #define	ti_x1		ti_i.ih_x1
 #define	ti_pr		ti_i.ih_pr
 #define	ti_len		ti_i.ih_len
@@ -62,6 +61,14 @@
 #define	ti_sum		ti_t.th_sum
 #define	ti_urp		ti_t.th_urp
 
+#define tcpiphdr2qlink(T) ((struct qlink*)(((char*)(T)) - sizeof(struct qlink)))
+#define qlink2tcpiphdr(Q) ((struct tcpiphdr*)(((char*)(Q)) + sizeof(struct qlink)))
+#define tcpiphdr_next(T) qlink2tcpiphdr(tcpiphdr2qlink(T)->next)
+#define tcpiphdr_prev(T) qlink2tcpiphdr(tcpiphdr2qlink(T)->prev)
+#define tcpfrag_list_first(T) qlink2tcpiphdr((T)->seg_next)
+#define tcpfrag_list_end(F, T) (tcpiphdr2qlink(F) == (struct qlink*)(T))
+#define tcpfrag_list_empty(T) ((T)->seg_next == (struct tcpiphdr*)(T))
+
 /*
  * Just a clean way to get to the first byte
  * of the packet

Modified: trunk/slirp/udp.c
===================================================================
--- trunk/slirp/udp.c	2009-01-13 19:47:10 UTC (rev 6287)
+++ trunk/slirp/udp.c	2009-01-13 19:48:42 UTC (rev 6288)
@@ -136,8 +136,7 @@
 	 * Checksum extended UDP header and data.
 	 */
 	if (UDPCKSUM && uh->uh_sum) {
-	  ((struct ipovly *)ip)->ih_next = 0;
-	  ((struct ipovly *)ip)->ih_prev = 0;
+      memset(&((struct ipovly *)ip)->ih_mbuf, 0, sizeof(struct mbuf_ptr));
 	  ((struct ipovly *)ip)->ih_x1 = 0;
 	  ((struct ipovly *)ip)->ih_len = uh->uh_ulen;
 	  /* keep uh_sum for ICMP reply
@@ -283,7 +282,7 @@
 	 * and addresses and length put into network format.
 	 */
 	ui = mtod(m, struct udpiphdr *);
-	ui->ui_next = ui->ui_prev = 0;
+    memset(&ui->ui_i.ih_mbuf, 0 , sizeof(struct mbuf_ptr));
 	ui->ui_x1 = 0;
 	ui->ui_pr = IPPROTO_UDP;
 	ui->ui_len = htons(m->m_len - sizeof(struct ip)); /* + sizeof (struct udphdr)); */

Modified: trunk/slirp/udp.h
===================================================================
--- trunk/slirp/udp.h	2009-01-13 19:47:10 UTC (rev 6287)
+++ trunk/slirp/udp.h	2009-01-13 19:48:42 UTC (rev 6288)
@@ -60,8 +60,7 @@
 	        struct  ipovly ui_i;            /* overlaid ip structure */
 	        struct  udphdr ui_u;            /* udp header */
 };
-#define ui_next         ui_i.ih_next
-#define ui_prev         ui_i.ih_prev
+#define ui_mbuf         ui_i.ih_mbuf.mptr
 #define ui_x1           ui_i.ih_x1
 #define ui_pr           ui_i.ih_pr
 #define ui_len          ui_i.ih_len

                 reply	other threads:[~2009-01-13 19:48 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=E1LMpFi-0004jl-OJ@cvs.savannah.gnu.org \
    --to=blauwirbel@gmail.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).