qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] fix 64 bit issue in slirp


From: Gleb Natapov
Subject: [Qemu-devel] [PATCH] fix 64 bit issue in slirp
Date: Mon, 12 Jan 2009 16:28:07 +0200

Signed-off-by: Gleb Natapov <address@hidden>

diff --git a/slirp/ip.h b/slirp/ip.h
index a8cdb0d..3079f90 100644
--- a/slirp/ip.h
+++ b/slirp/ip.h
@@ -183,35 +183,31 @@ struct    ip_timestamp {
 
 #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;
-#else
-typedef u_int32_t caddr32_t;
-#endif
-#endif
-
-#if SIZEOF_CHAR_P == 4
-typedef struct ipq *ipqp_32;
-typedef struct ipasfrag *ipasfragp_32;
+struct mbuf_ptr {
+       struct mbuf *mptr;
+       uint32_t dummy;
+};
 #else
-typedef caddr32_t ipqp_32;
-typedef caddr32_t ipasfragp_32;
+struct mbuf_ptr {
+       struct mbuf *mptr;
+};
 #endif
+struct qlink {
+       void *next, *prev;
+};
 
 /*
  * 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 @@ struct ipovly {
  * 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.
diff --git a/slirp/ip_input.c b/slirp/ip_input.c
index 73cb00e..116ee45 100644
--- a/slirp/ip_input.c
+++ b/slirp/ip_input.c
@@ -43,6 +43,7 @@
  */
 
 #include <slirp.h>
+#include <osdep.h>
 #include "ip_icmp.h"
 
 #ifdef LOG_ENABLED
@@ -51,7 +52,7 @@ struct ipstat ipstat;
 
 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 @@ static void ip_deq(register struct ipasfrag *p);
 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 @@ ip_input(m)
         */
        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_input(m)
                 */
                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 @@ ip_input(m)
                 * 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 @@ bad:
        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 @@ bad:
  * 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 @@ ip_reass(register struct ipasfrag *ip, register struct 
ipq *fp)
          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 @@ ip_reass(register struct ipasfrag *ip, register struct ipq 
*fp)
        /*
         * 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 @@ ip_reass(register struct ipasfrag *ip, register struct ipq 
*fp)
         * 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 @@ ip_reass(register struct ipasfrag *ip, register struct 
ipq *fp)
         * 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 @@ insert:
         * 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 @@ insert:
         * 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 @@ insert:
        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 @@ ip_freef(struct ipq *fp)
 {
        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 @@ ip_enq(register struct ipasfrag *p, register struct 
ipasfrag *prev)
 {
        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 @@ ip_deq(register struct ipasfrag *p)
 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);
                }
        }
 }
diff --git a/slirp/misc.c b/slirp/misc.c
index 1ec8b55..f558b3c 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -83,39 +83,6 @@ getouraddr()
             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;
diff --git a/slirp/slirp.c b/slirp/slirp.c
index c1361ab..43a8965 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -261,7 +261,7 @@ void slirp_select_fill(int *pnfds,
                 * 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;
diff --git a/slirp/slirp.h b/slirp/slirp.h
index 3002e0b..d57fb12 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -266,14 +266,6 @@ void if_start _P((struct ttys *));
 
 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
diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c
index 408875e..f324adb 100644
--- a/slirp/tcp_input.c
+++ b/slirp/tcp_input.c
@@ -71,7 +71,7 @@ tcp_seq tcp_iss;                /* tcp initial send seq # */
 #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 @@ tcp_seq tcp_iss;                /* tcp initial send seq # */
 #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 @@ tcp_reass(register struct tcpcb *tp, register struct 
tcpiphdr *ti,
        /*
         * 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 @@ tcp_reass(register struct tcpcb *tp, register struct 
tcpiphdr *ti,
         * 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 @@ tcp_reass(register struct tcpcb *tp, register struct 
tcpiphdr *ti,
                        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 @@ present:
         */
        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 @@ tcp_input(m, iphlen, inso)
         * 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 @@ findso:
                                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
diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index 12abebe..b0b72e4 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -73,7 +73,7 @@ tcp_template(tp)
        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 @@ tcp_respond(tp, ti, m, ack, seq, flags)
        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 @@ tcp_newtcpcb(so)
                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 @@ tcp_close(tp)
        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 */
diff --git a/slirp/tcp_var.h b/slirp/tcp_var.h
index 82380f9..99d18fd 100644
--- a/slirp/tcp_var.h
+++ b/slirp/tcp_var.h
@@ -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 @@ struct tcpcb {
 #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.
diff --git a/slirp/tcpip.h b/slirp/tcpip.h
index 82708b0..b98cdb3 100644
--- a/slirp/tcpip.h
+++ b/slirp/tcpip.h
@@ -44,8 +44,7 @@ struct tcpiphdr {
        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 @@ struct tcpiphdr {
 #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
diff --git a/slirp/udp.c b/slirp/udp.c
index ca353b7..c992618 100644
--- a/slirp/udp.c
+++ b/slirp/udp.c
@@ -136,8 +136,7 @@ udp_input(m, iphlen)
         * 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 @@ int udp_output2(struct socket *so, struct mbuf *m,
         * 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)); */
diff --git a/slirp/udp.h b/slirp/udp.h
index 4f69b09..e2ca546 100644
--- a/slirp/udp.h
+++ b/slirp/udp.h
@@ -60,8 +60,7 @@ struct udpiphdr {
                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
--
                        Gleb.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]