v_count => v_usecount; v_lastr is being used; v_mounton is gone;
[unix-history] / usr / src / sys / netinet / tcp_output.c
index 7ce322d..1b69eb5 100644 (file)
@@ -1,13 +1,25 @@
 /*
 /*
- * Copyright (c) 1982, 1986 Regents of the University of California.
- * All rights reserved.  The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
+ * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
+ * All rights reserved.
  *
  *
- *     @(#)tcp_output.c        7.11 (Berkeley) %G%
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *     @(#)tcp_output.c        7.18 (Berkeley) %G%
  */
 
 #include "param.h"
 #include "systm.h"
  */
 
 #include "param.h"
 #include "systm.h"
+#include "malloc.h"
 #include "mbuf.h"
 #include "protosw.h"
 #include "socket.h"
 #include "mbuf.h"
 #include "protosw.h"
 #include "socket.h"
@@ -42,7 +54,7 @@ tcp_output(tp)
        register struct tcpcb *tp;
 {
        register struct socket *so = tp->t_inpcb->inp_socket;
        register struct tcpcb *tp;
 {
        register struct socket *so = tp->t_inpcb->inp_socket;
-       register int len, win;
+       register long len, win;
        struct mbuf *m0;
        int off, flags, error;
        register struct mbuf *m;
        struct mbuf *m0;
        int off, flags, error;
        register struct mbuf *m;
@@ -61,7 +73,7 @@ tcp_output(tp)
 again:
        sendalot = 0;
        off = tp->snd_nxt - tp->snd_una;
 again:
        sendalot = 0;
        off = tp->snd_nxt - tp->snd_una;
-       win = MIN(tp->snd_wnd, tp->snd_cwnd);
+       win = min(tp->snd_wnd, tp->snd_cwnd);
 
        /*
         * If in persist timeout with window of 0, send 1 byte.
 
        /*
         * If in persist timeout with window of 0, send 1 byte.
@@ -78,7 +90,7 @@ again:
                }
        }
 
                }
        }
 
-       len = MIN(so->so_snd.sb_cc, win) - off;
+       len = min(so->so_snd.sb_cc, win) - off;
        flags = tcp_outflags[tp->t_state];
 
        if (len < 0) {
        flags = tcp_outflags[tp->t_state];
 
        if (len < 0) {
@@ -204,11 +216,13 @@ send:
         * be transmitted, and initialize the header from
         * the template for sends on this connection.
         */
         * be transmitted, and initialize the header from
         * the template for sends on this connection.
         */
-       MGET(m, M_DONTWAIT, MT_HEADER);
+       MGETHDR(m, M_DONTWAIT, MT_HEADER);
        if (m == NULL)
                return (ENOBUFS);
        if (m == NULL)
                return (ENOBUFS);
-       m->m_off = MMAXOFF - sizeof (struct tcpiphdr);
+       m->m_data += max_linkhdr;
        m->m_len = sizeof (struct tcpiphdr);
        m->m_len = sizeof (struct tcpiphdr);
+       m->m_pkthdr.rcvif = (struct ifnet *)0;
+       ti = mtod(m, struct tcpiphdr *);
        if (len) {
                if (tp->t_force && len == 1)
                        tcpstat.tcps_sndprobe++;
        if (len) {
                if (tp->t_force && len == 1)
                        tcpstat.tcps_sndprobe++;
@@ -219,9 +233,10 @@ send:
                        tcpstat.tcps_sndpack++;
                        tcpstat.tcps_sndbyte += len;
                }
                        tcpstat.tcps_sndpack++;
                        tcpstat.tcps_sndbyte += len;
                }
-               m->m_next = m_copy(so->so_snd.sb_mb, off, len);
-               if (m->m_next == 0)
-                       len = 0;
+               if (len <= MHLEN - sizeof (struct tcpiphdr) - max_linkhdr) {
+                       if (m->m_next == 0)
+                               len = 0;
+               }
        } else if (tp->t_flags & TF_ACKNOW)
                tcpstat.tcps_sndacks++;
        else if (flags & (TH_SYN|TH_FIN|TH_RST))
        } else if (tp->t_flags & TF_ACKNOW)
                tcpstat.tcps_sndacks++;
        else if (flags & (TH_SYN|TH_FIN|TH_RST))
@@ -231,7 +246,6 @@ send:
        else
                tcpstat.tcps_sndwinup++;
 
        else
                tcpstat.tcps_sndwinup++;
 
-       ti = mtod(m, struct tcpiphdr *);
        if (tp->t_template == 0)
                panic("tcp_output");
        bcopy((caddr_t)tp->t_template, (caddr_t)ti, sizeof (struct tcpiphdr));
        if (tp->t_template == 0)
                panic("tcp_output");
        bcopy((caddr_t)tp->t_template, (caddr_t)ti, sizeof (struct tcpiphdr));
@@ -254,7 +268,7 @@ send:
        if (flags & TH_SYN && (tp->t_flags & TF_NOOPT) == 0) {
                u_short mss;
 
        if (flags & TH_SYN && (tp->t_flags & TF_NOOPT) == 0) {
                u_short mss;
 
-               mss = MIN(so->so_rcv.sb_hiwat / 2, tcp_mss(tp));
+               mss = min(so->so_rcv.sb_hiwat / 2, tcp_mss(tp));
                if (mss > IP_MSS - sizeof(struct tcpiphdr)) {
                        opt = tcp_initopt;
                        optlen = sizeof (tcp_initopt);
                if (mss > IP_MSS - sizeof(struct tcpiphdr)) {
                        opt = tcp_initopt;
                        optlen = sizeof (tcp_initopt);
@@ -286,10 +300,14 @@ send:
         * Calculate receive window.  Don't shrink window,
         * but avoid silly window syndrome.
         */
         * Calculate receive window.  Don't shrink window,
         * but avoid silly window syndrome.
         */
-       if (win < so->so_rcv.sb_hiwat / 4 && win < tp->t_maxseg)
+       if (win < (long)(so->so_rcv.sb_hiwat / 4) && win < (long)tp->t_maxseg)
                win = 0;
                win = 0;
-       if (win < (int)(tp->rcv_adv - tp->rcv_nxt))
-               win = (int)(tp->rcv_adv - tp->rcv_nxt);
+       if (win > IP_MAXPACKET)
+               win = IP_MAXPACKET;
+       if (win < (long)(tp->rcv_adv - tp->rcv_nxt))
+               win = (long)(tp->rcv_adv - tp->rcv_nxt);
+       if (win > IP_MAXPACKET)
+               win = IP_MAXPACKET;
        ti->ti_win = htons((u_short)win);
        if (SEQ_GT(tp->snd_up, tp->snd_nxt)) {
                ti->ti_urp = htons((u_short)(tp->snd_up - tp->snd_nxt));
        ti->ti_win = htons((u_short)win);
        if (SEQ_GT(tp->snd_up, tp->snd_nxt)) {
                ti->ti_urp = htons((u_short)(tp->snd_up - tp->snd_nxt));
@@ -317,7 +335,8 @@ send:
        if (len + optlen)
                ti->ti_len = htons((u_short)(sizeof(struct tcphdr) +
                    optlen + len));
        if (len + optlen)
                ti->ti_len = htons((u_short)(sizeof(struct tcphdr) +
                    optlen + len));
-       ti->ti_sum = in_cksum(m, sizeof (struct tcpiphdr) + (int)optlen + len);
+       ti->ti_sum = in_cksum(m,
+           (int)(sizeof (struct tcpiphdr) + (int)optlen + len));
 
        /*
         * In transmit state, time the transmission and arrange for
 
        /*
         * In transmit state, time the transmission and arrange for
@@ -380,11 +399,23 @@ send:
         * send to IP level.
         */
        ((struct ip *)ti)->ip_len = sizeof (struct tcpiphdr) + optlen + len;
         * send to IP level.
         */
        ((struct ip *)ti)->ip_len = sizeof (struct tcpiphdr) + optlen + len;
+       if (m->m_flags & M_PKTHDR)
+               m->m_pkthdr.len = ((struct ip *)ti)->ip_len;
        ((struct ip *)ti)->ip_ttl = TCP_TTL;
        ((struct ip *)ti)->ip_ttl = TCP_TTL;
+#if BSD>=43
        error = ip_output(m, tp->t_inpcb->inp_options, &tp->t_inpcb->inp_route,
            so->so_options & SO_DONTROUTE);
        error = ip_output(m, tp->t_inpcb->inp_options, &tp->t_inpcb->inp_route,
            so->so_options & SO_DONTROUTE);
-       if (error)
+#else
+       error = ip_output(m, (struct mbuf *)0, &tp->t_inpcb->inp_route, 
+                         so->so_options & SO_DONTROUTE);
+#endif
+       if (error) {
+               if (error == ENOBUFS) {
+                       tcp_quench(tp->t_inpcb);
+                       return (0);
+               }
                return (error);
                return (error);
+       }
        tcpstat.tcps_sndtotal++;
 
        /*
        tcpstat.tcps_sndtotal++;
 
        /*