internal memp memp_malloc(memp_t type) { memp memp; switch (type) { #if LWIP_RAW case memp_t.MEMP_RAW_PCB: memp = new raw_pcb(this); break; #endif #if LWIP_UDP case memp_t.MEMP_UDP_PCB: memp = new udp_pcb(this); break; #endif #if LWIP_TCP case memp_t.MEMP_TCP_PCB: memp = new tcp_pcb(this); break; case memp_t.MEMP_TCP_PCB_LISTEN: memp = new tcp_pcb_listen(this); break; case memp_t.MEMP_TCP_SEG: memp = new tcp_seg(this); break; #endif #if IP_REASSEMBLY case memp_t.MEMP_REASSDATA: memp = new ip_reassdata(this); break; case memp_t.MEMP_FRAG_PBUF: memp = new frag_pbuf(this); break; #endif #if LWIP_NETCONN case memp_t.MEMP_NETBUF: memp = new netbuf(this); break; case memp_t.MEMP_NETCONN: memp = new netconn(this); break; #endif #if false //!NO_SYS case memp_t.MEMP_TCPIP_MSG_API: memp = new tcpip_msg(this); break; case memp_t.MEMP_TCPIP_MSG_INPKT: memp = new tcpip_msg(this); break; #endif #if LWIP_ARP && ARP_QUEUEING case memp_t.MEMP_ARP_QUEUE: memp = new etharp_q_entry(this); break; #endif #if LWIP_IGMP case memp_t.MEMP_IGMP_GROUP: memp = new igmp_group(this); break; #endif #if false //(!NO_SYS || (NO_SYS && !NO_SYS_NO_TIMERS)) case memp_t.MEMP_SYS_TIMEOUT: memp = new sys_timeo(this); break; #endif #if LWIP_SNMP case memp_t.MEMP_SNMP_ROOTNODE: memp = new mib_list_rootnode(this); break; case memp_t.MEMP_SNMP_NODE: memp = new mib_list_node(this); break; case memp_t.MEMP_SNMP_VARBIND: memp = new snmp_varbind(this); break; case memp_t.MEMP_SNMP_VALUE: memp = new snmp_value(this); break; #endif #if LWIP_DNS && LWIP_SOCKET case memp_t.MEMP_NETDB: memp = new netdb(this); break; #endif #if LWIP_DNS && DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC case memp_t.MEMP_LOCALHOSTLIST: memp = new local_hostlist_entry(this); break; #endif #if PPP_SUPPORT && PPPOE_SUPPORT case memp_t.MEMP_PPPOE_IF: memp = new pppoe_softc(this); break; #endif default: throw new InvalidOperationException(); } memp._type = type; memp_heap.AddLast(memp); return memp; }
/** * Called by tcp_input() when a segment arrives for a listening * connection (from tcp_input()). * * @param pcb the tcp_pcb_listen for which a segment arrived * @return err_t.ERR_OK if the segment was processed * another err_t on error * * @note the return value is not (yet?) used in tcp_input() * @note the segment which arrived is saved in global variables, therefore only the pcb * involved is passed as a parameter to this function */ private err_t tcp_listen_input(tcp_pcb_listen pcb) { tcp_pcb npcb; err_t rc; if ((flags & tcp.TCP_RST) != 0) { /* An incoming RST should be ignored. Return. */ return err_t.ERR_OK; } /* In the tcp_state.LISTEN state, we check for incoming SYN segments, creates a new PCB, and responds with a SYN|ACK. */ if ((flags & tcp.TCP_ACK) != 0) { /* For incoming segments with the ACK flag set, respond with a RST. */ lwip.LWIP_DEBUGF(opt.TCP_RST_DEBUG, "tcp_listen_input: ACK in tcp_state.LISTEN, sending reset\n"); tcp_rst(ackno, seqno + tcplen, lwip.ip_current_dest_addr(), lwip.ip_current_src_addr(), tcphdr.dest, tcphdr.src); } else if ((flags & tcp.TCP_SYN) != 0) { lwip.LWIP_DEBUGF(opt.TCP_DEBUG, "TCP connection request {0} . {1}.\n", tcphdr.src, tcphdr.dest); #if TCP_LISTEN_BACKLOG if (pcb.accepts_pending >= pcb.backlog) { lwip.LWIP_DEBUGF(opt.TCP_DEBUG, "tcp_listen_input: listen backlog exceeded for port {0}\n", tcphdr.dest); return err_t.ERR_ABRT; } #endif // TCP_LISTEN_BACKLOG npcb = tcp_alloc(pcb.prio); /* If a new PCB could not be created (probably due to lack of memory), we don't do anything, but rely on the sender will retransmit the SYN at a time when we have more memory available. */ if (npcb == null) { lwip.LWIP_DEBUGF(opt.TCP_DEBUG, "tcp_listen_input: could not allocate PCB\n"); ++lwip.lwip_stats.tcp.memerr; return err_t.ERR_MEM; } #if TCP_LISTEN_BACKLOG pcb.accepts_pending++; #endif // TCP_LISTEN_BACKLOG /* Set up the new PCB. */ ip_addr.ip_addr_copy(npcb.local_ip, lwip.current_iphdr_dest); npcb.local_port = pcb.local_port; ip_addr.ip_addr_copy(npcb.remote_ip, lwip.current_iphdr_src); npcb.remote_port = tcphdr.src; npcb.state = tcp_state.SYN_RCVD; npcb.rcv_nxt = seqno + 1; npcb.rcv_ann_right_edge = npcb.rcv_nxt; npcb.snd_wnd = tcphdr.wnd; npcb.snd_wnd_max = tcphdr.wnd; npcb.ssthresh = npcb.snd_wnd; npcb.snd_wl1 = seqno - 1;/* initialise to seqno-1 to force window update */ npcb.callback_arg = pcb.callback_arg; #if LWIP_CALLBACK_API npcb.accept = pcb.accept; #endif // LWIP_CALLBACK_API /* inherit socket options */ npcb.so_options = (byte)(pcb.so_options & sof.SOF_INHERITED); /* Register the new PCB so that we can begin receiving segments for it. */ TCP_REG_ACTIVE(npcb); /* Parse any options in the SYN. */ tcp_parseopt(npcb); #if TCP_CALCULATE_EFF_SEND_MSS npcb.mss = tcp_eff_send_mss(npcb.mss, npcb.remote_ip); #endif // TCP_CALCULATE_EFF_SEND_MSS //snmp.snmp_inc_tcppassiveopens(); /* Send a SYN|ACK together with the MSS option. */ rc = tcp_enqueue_flags(npcb, tcp.TCP_SYN | tcp.TCP_ACK); if (rc != err_t.ERR_OK) { tcp_abandon(npcb, 0); return rc; } return tcp_output(npcb); } return err_t.ERR_OK; }