struct connection *proxy_create(struct context *ctx, char *host, int port) { struct connection *proxy; int fd = socket_create_server(host, port); if (fd == -1) return NULL; logger(INFO, "serve at %s:%d", host, port); proxy = malloc(sizeof(struct connection)); proxy->ctx = ctx; proxy->fd = fd; proxy->ready = ready; mbuf_queue_init(&proxy->buf_queue); return proxy; }
struct tcp_pcb * tcp_passive_open(struct tcp_listen_pcb * mux, struct iphdr * iph, struct tcphdr * th, unsigned int optlen) { struct tcp_pcb * tp; struct route * rt; int new_head; int cond; new_head = mux->t_head + 1; if (new_head == mux->t_max) new_head = 0; if (mux->t_tail == new_head) { DCC_LOG(LOG_WARNING, "backlog limit"); return NULL; } if ((cond = thinkos_cond_alloc()) < 0) { DCC_LOG(LOG_WARNING, "thinkos_cond_alloc()"); return NULL; } if ((tp = tcp_pcb_new(&__tcp__.active)) == NULL) { DCC_LOG(LOG_WARNING, "tcp_pcb_new() failed!"); return NULL; } /* Set up the new PCB. */ tp->t_lport = th->th_dport; tp->t_laddr = iph->daddr; tp->t_fport = th->th_sport; tp->t_faddr = iph->saddr; tp->t_cond = cond; /* * TODO: max queue size... */ mbuf_queue_init(&tp->rcv_q); mbuf_queue_init(&tp->snd_q); if ((rt = __route_lookup(tp->t_faddr)) == NULL) { DCC_LOG(LOG_WARNING, "no route to host"); tp->t_maxseg = tcp_defmss; } else { /* default mss to the network interface mtu. */ tp->t_route = rt; tp->t_maxseg = rt->rt_ifn->if_mtu - (sizeof(struct tcphdr) + sizeof(struct iphdr)); } if (tp->t_maxseg > tcp_maxmss) tp->t_maxseg = tcp_maxmss; /* TODO: calculate the amount of space in receive window */ // tp->rcv_wnd = MIN(tcp_maxrcv, tcp_maxwin); /* advertised window */ // tp->t_adv_wnd = 0; if (optlen) tcp_parse_options(tp, th, th->th_opt, optlen); /* update the sequence numbers */ tp->rcv_nxt = ntohl(th->th_seq) + 1; tp->snd_seq = (++__tcp__.iss << 20); tp->snd_off = 0; tp->snd_max = 0; /* set the connection-establishment timer to 75 seconds */ tp->t_conn_tmr = tcp_conn_est_tmo; tp->snd_wnd = ntohs(th->th_win); DCC_LOG2(LOG_INFO, "maxseg=%d snd_wnd=%d", tp->t_maxseg, tp->snd_wnd); /* TODO: initialization of receive urgent pointer */ tp->t_state = TCPS_SYN_RCVD; DCC_LOG3(LOG_INFO, "<%05x> %I:%d [SYN_RCVD]", (int)tp, tp->t_faddr, ntohs(tp->t_fport)); /* XXX: don't respond now - the upper layer must call the tcp_accept() function to send back the SYNC and finish handshaking. */ tp->t_flags = TF_ACKNOW; /* insert into backlog */ mux->t_backlog[mux->t_head] = tp; mux->t_head = new_head; thinkos_sem_post(mux->t_sem); return tp; }