- Merge aicom-network-branch (still without the NDIS stuff)
authorCameron Gutman <aicommander@gmail.com>
Thu, 28 Jan 2010 00:24:00 +0000 (00:24 +0000)
committerCameron Gutman <aicommander@gmail.com>
Thu, 28 Jan 2010 00:24:00 +0000 (00:24 +0000)
 - Fixes some nasty bugs and hacks in our TCP implementation

svn path=/trunk/; revision=45291

12 files changed:
reactos/lib/drivers/ip/transport/tcp/event.c
reactos/lib/drivers/oskittcp/include/freebsd/src/sys/sys/malloc.h
reactos/lib/drivers/oskittcp/include/freebsd/src/sys/sys/proc.h
reactos/lib/drivers/oskittcp/include/osenv.h [new file with mode: 0644]
reactos/lib/drivers/oskittcp/oskittcp.rbuild
reactos/lib/drivers/oskittcp/oskittcp/interface.c
reactos/lib/drivers/oskittcp/oskittcp/ip_output.c
reactos/lib/drivers/oskittcp/oskittcp/osenv.c [new file with mode: 0644]
reactos/lib/drivers/oskittcp/oskittcp/sleep.c
reactos/lib/drivers/oskittcp/oskittcp/tcp_output.c
reactos/lib/drivers/oskittcp/oskittcp/tcp_subr.c
reactos/lib/drivers/oskittcp/oskittcp/uipc_mbuf.c

index 3b42a75..9badd7b 100644 (file)
@@ -24,11 +24,14 @@ int TCPSocketState(void *ClientData,
                NewState & SEL_ACCEPT  ? 'A' : 'a',
                NewState & SEL_WRITE   ? 'W' : 'w'));
 
+    /* If this socket is missing its socket context, that means that it
+     * has been created as a new connection in sonewconn but not accepted
+     * yet. We can safely ignore event notifications on these sockets.
+     * Once they are accepted, they will get a socket context and we will 
+     * be able to process them.
+     */
     if (!Connection)
-    {
-        //ASSERT(FALSE);
         return 0;
-    }
 
     TI_DbgPrint(DEBUG_TCP,("Called: NewState %x (Conn %x) (Change %x)\n",
                NewState, Connection,
index ae4a946..bde211c 100644 (file)
@@ -36,7 +36,7 @@
 #ifndef _SYS_MALLOC_H_
 #define        _SYS_MALLOC_H_
 
-#ifndef OSKIT
+#if !defined(OSKIT) || defined(__REACTOS__)
 #define KMEMSTATS
 #endif
 
@@ -288,7 +288,6 @@ struct kmembuckets {
 #define        MALLOC(space, cast, size, type, flags) \
        (space) = (cast)fbsd_malloc((u_long)(size), __FILE__, __LINE__, type, flags)
 #define FREE(addr, type) fbsd_free((caddr_t)(addr), __FILE__, __LINE__, type)
-
 #else /* do not collect statistics */
 #define        MALLOC(space, cast, size, type, flags) { \
        register struct kmembuckets *kbp = &bucket[BUCKETINDX(size)]; \
index 1032408..087d2dd 100644 (file)
 #include <sys/socketvar.h>
 
 #ifdef OSKIT
+#ifndef __REACTOS__
 #include <oskit/dev/dev.h>
+#else
+#include <osenv.h>
+#endif
 #endif
 
 /*
diff --git a/reactos/lib/drivers/oskittcp/include/osenv.h b/reactos/lib/drivers/oskittcp/include/osenv.h
new file mode 100644 (file)
index 0000000..bb5dca2
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef OSENV_H
+#define OSENV_H
+
+static __inline void osenv_intr_enable(void) {}
+static __inline void osenv_intr_disable(void) {}
+
+void oskit_bufio_addref(void *buf);
+void oskit_bufio_release(void *buf);
+void* oskit_bufio_create(int len);
+void oskit_bufio_map(void *srcbuf, void**dstbuf, int off, int len);
+
+#define osenv_sleeprec_t void*
+
+#endif
index f67e415..c6332f2 100644 (file)
@@ -3,6 +3,7 @@
 <module name="oskittcp" type="staticlibrary">
        <define name="__NTDRIVER__"/>
        <define name="KERNEL"/>
+       <define name="OSKIT"/>
        <include base="oskittcp">include/freebsd</include>
        <include base="oskittcp">include/freebsd/sys/include</include>
        <include base="oskittcp">include/freebsd/src/sys</include>
@@ -22,6 +23,7 @@
                <file>ip_output.c</file>
                <file>kern_clock.c</file>
                <file>kern_subr.c</file>
+               <file>osenv.c</file>
                <file>param.c</file>
                <file>radix.c</file>
                <file>random.c</file>
index 315f6ff..3c589e7 100644 (file)
@@ -48,8 +48,6 @@ void fbsd_free( void *data, char *file, unsigned line, ... ) {
 void InitOskitTCP() {
     OS_DbgPrint(OSK_MID_TRACE,("Init Called\n"));
     KeInitializeSpinLock(&OSKLock);
-    OS_DbgPrint(OSK_MID_TRACE,("MB Init\n"));
-    mbinit();
     OS_DbgPrint(OSK_MID_TRACE,("Rawip Init\n"));
     rip_init();
     raw_init();
@@ -403,7 +401,7 @@ int OskitTCPAccept( void *socket,
 
        so->so_state |= SS_NBIO | SS_ISCONNECTED;
         so->so_q = so->so_q0 = NULL;
-        so->so_qlen = 0;
+        so->so_qlen = so->so_q0len = 0;
         so->so_head = 0;
         so->so_connection = context;
 
index bca8fb0..25f8be9 100644 (file)
@@ -393,6 +393,7 @@ sendit:
                error = OtcpEvent.PacketSend( OtcpEvent.ClientData,
                                              (OSK_PCHAR)new_m->m_data, new_m->m_len );
                m_free( new_m );
+               m_freem( m );
                goto done;
            }
 #else
@@ -532,6 +533,7 @@ sendorfree:
            error = OtcpEvent.PacketSend( OtcpEvent.ClientData,
                                          (OSK_PCHAR)new_m->m_data, new_m->m_len );
            m_free( new_m );
+           m_freem( m );
        }
 
        OS_DbgPrint(OSK_MID_TRACE,("Error from upper layer: %d\n", error));
diff --git a/reactos/lib/drivers/oskittcp/oskittcp/osenv.c b/reactos/lib/drivers/oskittcp/oskittcp/osenv.c
new file mode 100644 (file)
index 0000000..d29fa5f
--- /dev/null
@@ -0,0 +1,45 @@
+#include "oskittcp.h"
+
+unsigned oskit_freebsd_cpl;
+
+/* We have to store a reference count somewhere so we
+ * don't free a buffer being referenced in another mbuf.
+ * I just decided to add an extra char to the beginning of
+ * the buffer and store the reference count there. I doubt the ref count
+ * will ever even get close to 0xFF so we should be ok. Remember that
+ * only one thread can ever be inside oskit due to OSKLock so this should
+ * be safe.
+ */
+
+void oskit_bufio_addref(void *buf)
+{
+   unsigned char* fullbuf = ((unsigned char*)buf) - sizeof(char);
+
+#if DBG
+   if (fullbuf[0] == 0xFF)
+       panic("oskit_bufio_addref: ref count overflow");
+#endif
+
+   fullbuf[0]++;
+}
+void oskit_bufio_release(void *buf)
+{
+   unsigned char* fullbuf = ((unsigned char*)buf) - sizeof(char);
+
+   if (--fullbuf[0] == 0)
+       free(fullbuf, 0);
+}
+void* oskit_bufio_create(int len)
+{
+   unsigned char* fullbuf = malloc(len + sizeof(char), __FILE__, __LINE__);
+   if (fullbuf == NULL)
+       return NULL;
+
+   fullbuf[0] = 1;
+
+   return (void*)(fullbuf + sizeof(char));
+}
+void oskit_bufio_map(void *srcbuf, void**dstbuf, int off, int len)
+{
+   *dstbuf = srcbuf;
+}
index 5cfcdb4..e6779fd 100644 (file)
@@ -91,53 +91,3 @@ void clock_init()
        /* Start a clock we can use for timeouts */
 }
 
-
-extern unsigned bio_imask;     /* group of interrupts masked with splbio() */
-extern unsigned cpl;           /* current priority level mask */
-extern volatile unsigned idelayed;     /* interrupts to become pending */
-extern volatile unsigned ipending;     /* active interrupts masked by cpl */
-extern unsigned net_imask;     /* group of interrupts masked with splimp() */
-extern unsigned stat_imask;    /* interrupts masked with splstatclock() */
-extern unsigned tty_imask;     /* group of interrupts masked with spltty() */
-
-/*
- * ipending has to be volatile so that it is read every time it is accessed
- * in splx() and spl0(), but we don't want it to be read nonatomically when
- * it is changed.  Pretending that ipending is a plain int happens to give
- * suitable atomic code for "ipending |= constant;".
- */
-#define        setdelayed()    (*(unsigned *)&ipending |= loadandclear(&idelayed))
-#define        setsoftast()    (*(unsigned *)&ipending |= SWI_AST_PENDING)
-#define        setsoftclock()  (*(unsigned *)&ipending |= SWI_CLOCK_PENDING)
-#define        setsoftnet()    (*(unsigned *)&ipending |= SWI_NET_PENDING)
-#define        setsofttty()    (*(unsigned *)&ipending |= SWI_TTY_PENDING)
-
-#define        schedsofttty()  (*(unsigned *)&idelayed |= SWI_TTY_PENDING)
-
-#define        GENSPL(name, set_cpl) \
-static __inline int name(void)                 \
-{                                              \
-       unsigned x;                             \
-                                               \
-       __asm __volatile("" : : : "memory");    \
-       x = cpl;                                \
-       set_cpl;                                \
-       return (x);                             \
-}
-
-void splz(void) {
-    OS_DbgPrint(OSK_MID_TRACE,("Called SPLZ\n"));
-}
-
-/*
- * functions to save and restore the current cpl
- */
-void save_cpl(unsigned *x)
-{
-    *x = cpl;
-}
-
-void restore_cpl(unsigned x)
-{
-    cpl = x;
-}
index 422306b..1e9e431 100644 (file)
@@ -707,39 +707,9 @@ send:
            && !(rt->rt_rmx.rmx_locks & RTV_MTU)) {
                ((struct ip *)ti)->ip_off |= IP_DF;
        }
-#endif
-        /*
-         * XXX: It seems that osktittcp expects that packets are
-         * synchronously processed. The current implementation feeds
-         * oskittcp with the packets asynchronously. That's not a
-         * problem normally when the packets are transfered over
-         * network, but it starts to be a problem when it comes to
-         * loopback packets.
-         * The ACK bits are set in tcp_input which calls tcp_output and
-         * expects them to be cleared before further processing.
-         * Instead tcp_output calls ip_output which produces a packet
-         * and ends up in tcp_input and we're stuck in infinite loop.
-         * Normally the flags are masked out at the end of this function
-         * and the incomming packets are processed then, but since
-         * currently the loopback packet is delivered during the
-         * ip_output call, the function end is never reached...
-         */
-#ifdef __REACTOS__
-       tp->t_flags &= ~(TF_ACKNOW|TF_DELACK);
 #endif
        error = ip_output(m, tp->t_inpcb->inp_options, &tp->t_inpcb->inp_route,
                          so->so_options & SO_DONTROUTE, 0);
-#ifdef __REACTOS__
-       /* We allocated m, so we are responsible for freeing it. If the mbuf
-           contains a pointer to an external datablock, we (or rather, m_copy)
-           didn't allocate it but pointed it to the data to send. So we have
-           to cheat a little bit and keep M_FREE from freeing the external
-           data block */
-       while (NULL != m) {
-           m->m_flags &= ~M_EXT;
-           m = m_free(m);
-       }
-#endif
     }
        if (error) {
 out:
index e3557ee..4632b68 100644 (file)
@@ -163,7 +163,6 @@ tcp_respond(tp, ti, m, ack, seq, flags)
        tcp_seq ack, seq;
        int flags;
 {
-       struct mbuf *n;
        register int tlen;
        int win = 0;
        struct route *ro = 0;
@@ -222,18 +221,6 @@ tcp_respond(tp, ti, m, ack, seq, flags)
                tcp_trace(TA_OUTPUT, 0, tp, ti, 0);
 #endif
        (void) ip_output(m, NULL, ro, 0, NULL);
-#ifdef __REACTOS__
-       /* We allocated m, so we are responsible for freeing it. If the mbuf
-           contains a pointer to an external datablock, we (or rather, m_copy)
-           didn't allocate it but pointed it to the data to send. So we have
-           to cheat a little bit and keep M_FREE from freeing the external
-           data block */
-       while (NULL != m) {
-           m->m_flags &= ~M_EXT;
-           MFREE(m, n);
-           m = n;
-       }
-#endif
 }
 
 /*
index 082dd0b..e05d4ee 100644 (file)
@@ -663,7 +663,7 @@ extpacket:
        return (n);
 }
 
-#ifndef OSKIT
+#if !defined(OSKIT) || defined(__REACTOS__)
 /* currently not OS Kit approved, and shouldn't be needed in the first place */
 
 /*