- register struct ucb *up;
-COUNT(T_OPEN);
-
- /* enqueue the tcb */
-
- if (netcb.n_tcb_head == NULL) {
- netcb.n_tcb_head = tp;
- netcb.n_tcb_tail = tp;
- } else {
- tp->t_tcb_next = netcb.n_tcb_head;
- netcb.n_tcb_head->t_tcb_prev = tp;
- netcb.n_tcb_head = tp;
- }
-
- /* initialize non-zero tcb fields */
-
- tp->t_rcv_next = (struct th *)tp;
- tp->t_rcv_prev = (struct th *)tp;
- tp->t_xmtime = T_REXMT;
- tp->snd_end = tp->seq_fin = tp->snd_nxt = tp->snd_hi =
- tp->snd_una = tp->iss = netcb.n_iss;
- tp->snd_off = tp->iss + 1;
- netcb.n_iss += (ISSINCR >> 1) + 1;
-
- /* set timeout for open */
-
- up = tp->t_ucb;
- tp->t_init = (up->uc_timeo != 0 ? up->uc_timeo :
- (mode == ACTIVE ? T_INIT : 0));
- up->uc_timeo = 0; /* overlays uc_ssize */
-}
-
-t_close(tp, state)
- register struct tcb *tp;
- short state;
-{
- 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;
- }
- 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;
- }
- 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_rhiwat/MSIZE) + 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);