* Do a send by putting data in output queue and updating urgent * marker if URG set. Possibly send more data. Unlike the other * pru_*() routines, the mbuf chains are our responsibility. We * must either enqueue them or free them. The other pru_* routines * generally are caller-frees. */
| 1001 | * generally are caller-frees. |
| 1002 | */ |
| 1003 | static int |
| 1004 | tcp_usr_send(struct socket *so, int flags, struct mbuf *m, |
| 1005 | struct sockaddr *nam, struct mbuf *control, struct thread *td) |
| 1006 | { |
| 1007 | struct epoch_tracker et; |
| 1008 | int error = 0; |
| 1009 | struct inpcb *inp = NULL; |
| 1010 | struct tcpcb *tp = NULL; |
| 1011 | #ifdef INET |
| 1012 | #ifdef INET6 |
| 1013 | struct sockaddr_in sin; |
| 1014 | #endif |
| 1015 | struct sockaddr_in *sinp = NULL; |
| 1016 | #endif |
| 1017 | #ifdef INET6 |
| 1018 | int isipv6 = 0; |
| 1019 | #endif |
| 1020 | u_int8_t incflagsav; |
| 1021 | u_char vflagsav; |
| 1022 | bool restoreflags; |
| 1023 | TCPDEBUG0; |
| 1024 | |
| 1025 | /* |
| 1026 | * We require the pcbinfo "read lock" if we will close the socket |
| 1027 | * as part of this call. |
| 1028 | */ |
| 1029 | NET_EPOCH_ENTER(et); |
| 1030 | inp = sotoinpcb(so); |
| 1031 | KASSERT(inp != NULL, ("tcp_usr_send: inp == NULL")); |
| 1032 | INP_WLOCK(inp); |
| 1033 | vflagsav = inp->inp_vflag; |
| 1034 | incflagsav = inp->inp_inc.inc_flags; |
| 1035 | restoreflags = false; |
| 1036 | if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) { |
| 1037 | if (control) |
| 1038 | m_freem(control); |
| 1039 | /* |
| 1040 | * In case of PRUS_NOTREADY, tcp_usr_ready() is responsible |
| 1041 | * for freeing memory. |
| 1042 | */ |
| 1043 | if (m && (flags & PRUS_NOTREADY) == 0) |
| 1044 | m_freem(m); |
| 1045 | error = ECONNRESET; |
| 1046 | goto out; |
| 1047 | } |
| 1048 | tp = intotcpcb(inp); |
| 1049 | if (flags & PRUS_OOB) { |
| 1050 | if ((error = tcp_pru_options_support(tp, PRUS_OOB)) != 0) { |
| 1051 | if (control) |
| 1052 | m_freem(control); |
| 1053 | if (m && (flags & PRUS_NOTREADY) == 0) |
| 1054 | m_freem(m); |
| 1055 | goto out; |
| 1056 | } |
| 1057 | } |
| 1058 | TCPDEBUG1(); |
| 1059 | if (nam != NULL && tp->t_state < TCPS_SYN_SENT) { |
| 1060 | switch (nam->sa_family) { |
nothing calls this directly
no test coverage detected