Fix a memory leak
[reactos.git] / reactos / drivers / lib / oskittcp / oskittcp / tcp_output.c
index 75f0950..5f51c92 100644 (file)
@@ -66,6 +66,8 @@
 extern struct mbuf *m_copypack();
 #endif
 
+#define IS_LOOPBACK_ADDR(addr) \
+  ((ntohl(addr) & IN_CLASSA_NET) == (IN_LOOPBACKNET << IN_CLASSA_NSHIFT))
 
 /*
  * Tcp output routine: figure out what should be sent and send it.
@@ -84,6 +86,9 @@ tcp_output(tp)
        int idle, sendalot;
        struct rmxp_tao *taop;
        struct rmxp_tao tao_noncached;
+#ifdef __REACTOS__
+       struct mbuf *n;
+#endif
 
        OS_DbgPrint(OSK_MID_TRACE,("Called\n"));
 
@@ -215,8 +220,8 @@ again:
        win = sbspace(&so->so_rcv);
 
        /*
-        * Sender silly window avoidance.  If connection is idle
-        * and can send all data, a maximum segment,
+        * Sender silly window avoidance.  If connection is idle or using
+        * the loopback interface and can send all data, a maximum segment,
         * at least a maximum default-size segment do it,
         * or are forced, do it; otherwise don't bother.
         * If peer's buffer is tiny, then send
@@ -227,7 +232,8 @@ again:
        if (len) {
                if (len == tp->t_maxseg)
                        goto send;
-               if ((idle || tp->t_flags & TF_NODELAY) &&
+               if ((idle || tp->t_flags & TF_NODELAY ||
+                     IS_LOOPBACK_ADDR(tp->t_inpcb->inp_laddr.s_addr)) &&
                    (tp->t_flags & TF_NOPUSH) == 0 &&
                    len + off >= so->so_snd.sb_cc)
                        goto send;
@@ -719,8 +725,8 @@ send:
          * 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 
+         * 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__
@@ -728,6 +734,18 @@ send:
 #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;
+           MFREE(m, n);
+           m = n;
+       }
+#endif
     }
        if (error) {
 out:
@@ -780,7 +798,7 @@ void
 tcp_setpersist(tp)
        register struct tcpcb *tp;
 {
-       register t = ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1;
+       register int t = ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1;
 
        if (tp->t_timer[TCPT_REXMT])
                panic("tcp_output REXMT");