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.
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"));
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
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;
* 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__
#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:
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");