- 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)
- tcb_head = tp->t_tcb_next;
- else
- tp->t_tcb_prev->t_tcb_next = tp->t_tcb_next;
- if (tp->t_tcb_next == NULL)
- 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;
- }
- up->uc_rcc = 0;
- if (up->uc_sbuf != NULL) {
- m_freem(up->uc_sbuf);
- up->uc_sbuf = NULL;
- }
- up->uc_ssize = 0;
- for (m = tp->t_rcv_unack; m != NULL; m = m->m_act) {
- m_freem(m);
- tp->t_rcv_unack = NULL;
- }
- if (up->uc_template) {
- m_free(dtom(up->uc_template));
- up->uc_template = 0;
- }
- wmemfree((caddr_t)tp, 1024);
- up->uc_tcb = NULL;
-
- /* lower buffer allocation and decrement host entry */
-
- mbstat.m_lowat -= up->uc_snd + (up->uc_rhiwat/MSIZE) + 2;
- mbstat.m_hiwat = 2 * mbstat.m_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);