/* tcp_usrreq.c 1.44 81/12/20 */
#include "../h/socketvar.h"
#include "../h/protosw.h"
#include "../net/in_pcb.h"
#include "../net/in_systm.h"
#include "../net/ip_var.h"
#include "../net/tcp_fsm.h"
#include "../net/tcp_seq.h"
#include "../net/tcp_timer.h"
#include "../net/tcp_var.h"
#include "../net/tcpip.h"
#include "../net/tcp_debug.h"
extern char *tcpstates
[];
struct tcpcb
*tcp_newtcpcb();
* Process a TCP user request for tcp tb. If this is a send request
* then m is the mbuf chain of send data. If this is a timer expiration
* (called from the software clock routine), then timertype tells which timer.
tcp_usrreq(so
, req
, m
, addr
)
register struct inpcb
*inp
= sotoinpcb(so
);
register struct tcpcb
*tp
;
* Make sure attached. If not,
* only PRU_ATTACH is valid.
if (inp
== 0 && req
!= PRU_ATTACH
) {
tcp_acounts
[tp
->t_state
][req
]++;
error
= in_pcbattach(so
, &tcb
, 2048, 2048, (struct sockaddr_in
*)addr
);
inp
= (struct inpcb
*)so
->so_pcb
;
if (so
->so_options
& SO_ACCEPTCONN
) {
tp
->t_state
= TCPS_LISTEN
;
tp
->t_state
= TCPS_CLOSED
;
error
= in_pcbconnect(inp
, (struct sockaddr_in
*)addr
);
tp
->t_template
= tcp_template(tp
);
inp
->inp_ppcb
= (caddr_t
)tp
;
tp
->t_state
= TCPS_SYN_SENT
;
tp
->t_timer
[TCPT_KEEP
] = TCPTV_KEEP
;
tp
->iss
= tcp_iss
; tcp_iss
+= TCP_ISSINCR
/2;
*(struct sockaddr
*)addr
= so
->so_addr
;
if (tp
->t_state
< TCPS_ESTABLISHED
)
else if ((so
->so_state
& SO_LETDATADRAIN
) == 0)
sbappend(&so
->so_snd
, m
);
if (tp->t_flags & TF_PUSH)
tp->snd_end = tp->snd_una + so->so_snd.sb_cc;
if (tp
->t_flags
& TF_URG
)
tp
->snd_up
= tp
->snd_una
+ so
->so_snd
.sb_cc
+ 1;
tcp_drop(tp
, ECONNABORTED
);
tcp_timers(tp
, (int)addr
);
req
|= (int)addr
<< 8; /* for debug's sake */
if (tp
&& (so
->so_options
& SO_DEBUG
))
tcp_trace(TA_USER
, ostate
, tp
, (struct tcpiphdr
*)0, req
);
tp
->t_state
= TCPS_CLOSED
;
tp
->t_state
= TCPS_FIN_WAIT_1
;
tp
->t_state
= TCPS_LAST_ACK
;