- register struct ucb *up;
- register struct th *t;
- register struct mbuf *m;
-COUNT(T_CLOSE);
-
- up = tp->t_ucb;
-
- tp->t_init = tp->t_rexmt = tp->t_rexmttl = tp->t_persist =
- tp->t_finack = 0;
-
- /* delete tcb */
-
- if (tp->t_tcb_prev == NULL)
- netcb.n_tcb_head = tp->t_tcb_next;
- else
- tp->t_tcb_prev->t_tcb_next = tp->t_tcb_next;
- if (tp->t_tcb_next == NULL)
- netcb.n_tcb_tail = tp->t_tcb_prev;
- else
- tp->t_tcb_next->t_tcb_prev = tp->t_tcb_prev;
-
- /* free all data on receive and send buffers */
-
- for (t = tp->t_rcv_next; t != (struct th *)tp; t = t->t_next)
- m_freem(dtom(t));
-
- if (up->uc_rbuf != NULL) {
- m_freem(up->uc_rbuf);
- up->uc_rbuf = NULL;
- }
- if (up->uc_sbuf != NULL) {
- m_freem(up->uc_sbuf);
- up->uc_sbuf = NULL;
- }
- for (m = tp->t_rcv_unack; m != NULL; m = m->m_act) {
- m_freem(m);
- tp->t_rcv_unack = NULL;
- }
- m = dtom(tp);
- m->m_off = 0;
- m_free(m);
- up->uc_tcb = NULL;
-
- /* lower buffer allocation and decrement host entry */
-
- netcb.n_lowat -= up->uc_snd + up->uc_rcv + 2;
- netcb.n_hiwat = 2 * netcb.n_lowat;
- if (up->uc_host != NULL) {
- h_free(up->uc_host);
- up->uc_host = NULL;
- }
-
- /* if user has initiated close (via close call), delete ucb
- entry, otherwise just wakeup so user can issue close call */
-
- if (tp->tc_flags&TC_USR_ABORT)
- up->uc_proc = NULL;
- else
- to_user(up, state);
+ register struct tcpcb *tp;
+ struct inpcb *inp;
+ int error;
+
+ error = in_pcbattach(so, &tcb,
+ tcp_sendspace, tcp_recvspace, (struct sockaddr_in *)sa);
+ if (error)
+ return (error);
+ inp = (struct inpcb *)so->so_pcb;
+ tp = tcp_newtcpcb(inp);
+ if (so->so_options & SO_ACCEPTCONN) {
+ if (tp == 0) {
+ in_pcbdetach(inp);
+ return (ENOBUFS);
+ }
+ tp->t_state = TCPS_LISTEN;
+ } else
+ tp->t_state = TCPS_CLOSED;
+ return (0);