getpeer
[unix-history] / usr / src / sys / netinet / tcp_usrreq.c
index 2af59fb..51a7a44 100644 (file)
@@ -1,4 +1,4 @@
-/*     tcp_usrreq.c    1.76    83/05/12        */
+/*     tcp_usrreq.c    1.81    83/07/25        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
@@ -29,6 +29,7 @@
  */
 extern char *tcpstates[];
 struct tcpcb *tcp_newtcpcb();
  */
 extern char *tcpstates[];
 struct tcpcb *tcp_newtcpcb();
+int    tcpsenderrors;
 
 /*
  * Process a TCP user request for TCP tb.  If this is a send request
 
 /*
  * Process a TCP user request for TCP tb.  If this is a send request
@@ -36,10 +37,10 @@ struct      tcpcb *tcp_newtcpcb();
  * (called from the software clock routine), then timertype tells which timer.
  */
 /*ARGSUSED*/
  * (called from the software clock routine), then timertype tells which timer.
  */
 /*ARGSUSED*/
-tcp_usrreq(so, req, m, nam)
+tcp_usrreq(so, req, m, nam, rights)
        struct socket *so;
        int req;
        struct socket *so;
        int req;
-       struct mbuf *m, *nam;
+       struct mbuf *m, *nam, *rights;
 {
        register struct inpcb *inp = sotoinpcb(so);
        register struct tcpcb *tp;
 {
        register struct inpcb *inp = sotoinpcb(so);
        register struct tcpcb *tp;
@@ -47,6 +48,10 @@ tcp_usrreq(so, req, m, nam)
        int error = 0;
        int ostate;
 
        int error = 0;
        int ostate;
 
+       if (rights && rights->m_len) {
+               splx(s);
+               return (EINVAL);
+       }
        /*
         * When a TCP is attached to a socket, then there will be
         * a (struct inpcb) pointed at by the socket, and this
        /*
         * When a TCP is attached to a socket, then there will be
         * a (struct inpcb) pointed at by the socket, and this
@@ -147,6 +152,13 @@ tcp_usrreq(so, req, m, nam)
                error = tcp_output(tp);
                break;
 
                error = tcp_output(tp);
                break;
 
+       /*
+        * Create a TCP connection between two sockets.
+        */
+       case PRU_CONNECT2:
+               error = EOPNOTSUPP;
+               break;
+
        /*
         * Initiate disconnect from peer.
         * If connection never passed embryonic stage, just drop;
        /*
         * Initiate disconnect from peer.
         * If connection never passed embryonic stage, just drop;
@@ -205,8 +217,11 @@ tcp_usrreq(so, req, m, nam)
                        tp->snd_end = tp->snd_una + so->so_snd.sb_cc;
 #endif
                error = tcp_output(tp);
                        tp->snd_end = tp->snd_una + so->so_snd.sb_cc;
 #endif
                error = tcp_output(tp);
-               if (error == ENOBUFS)           /* XXX */
-                       error = 0;              /* XXX */
+               if (error) {            /* XXX fix to use other path */
+                       if (error == ENOBUFS)           /* XXX */
+                               error = 0;              /* XXX */
+                       tcpsenderrors++;
+               }
                break;
 
        /*
                break;
 
        /*
@@ -257,6 +272,10 @@ tcp_usrreq(so, req, m, nam)
                in_setsockaddr(inp, nam);
                break;
 
                in_setsockaddr(inp, nam);
                break;
 
+       case PRU_PEERADDR:
+               in_setpeeraddr(inp, nam);
+               break;
+
        /*
         * TCP slow timer went off; going through this
         * routine for tracing's sake.
        /*
         * TCP slow timer went off; going through this
         * routine for tracing's sake.
@@ -312,7 +331,7 @@ bad:
 /*
  * Initiate (or continue) disconnect.
  * If embryonic state, just send reset (once).
 /*
  * Initiate (or continue) disconnect.
  * If embryonic state, just send reset (once).
- * If not in ``let data drain'' option, just drop.
+ * If in ``let data drain'' option and linger null, just drop.
  * Otherwise (hard), mark socket disconnecting and drop
  * current input data; switch states based on user close, and
  * send segment to peer (with FIN).
  * Otherwise (hard), mark socket disconnecting and drop
  * current input data; switch states based on user close, and
  * send segment to peer (with FIN).
@@ -325,7 +344,7 @@ tcp_disconnect(tp)
 
        if (tp->t_state < TCPS_ESTABLISHED)
                tp = tcp_close(tp);
 
        if (tp->t_state < TCPS_ESTABLISHED)
                tp = tcp_close(tp);
-       else if (so->so_linger == 0)
+       else if ((so->so_options & SO_LINGER) && so->so_linger == 0)
                tp = tcp_drop(tp, 0);
        else {
                soisdisconnecting(so);
                tp = tcp_drop(tp, 0);
        else {
                soisdisconnecting(so);
@@ -354,6 +373,7 @@ tcp_usrclosed(tp)
 
        switch (tp->t_state) {
 
 
        switch (tp->t_state) {
 
+       case TCPS_CLOSED:
        case TCPS_LISTEN:
        case TCPS_SYN_SENT:
                tp->t_state = TCPS_CLOSED;
        case TCPS_LISTEN:
        case TCPS_SYN_SENT:
                tp->t_state = TCPS_CLOSED;