private static err_t Connected(object arg, tcp_pcb tpcb, err_t err) { TcpCep _this = (TcpCep)arg; if (err != err_t.ERR_OK) { err = _this.m_lwIP.tcp.tcp_close(tpcb); return(err); } Task wtask = null; foreach (Task task in _this.m_SendTaskQueue) { if ((task.rtsk.tskwait != TSKWAIT.TTW_TCP) || (task.rtsk.wid != _this.m_CepID)) { continue; } wtask = task; break; } if (wtask != null) { _this.m_SendTaskQueue.Remove(wtask); _this.NewSession(tpcb); wtask.ReleaseWait(); } return(err_t.ERR_OK); }
/** * This is the Nagle algorithm: try to combine user data to send as few TCP * segments as possible. Only send if * - no previously transmitted data on the connection remains unacknowledged or * - the tcp_pcb.TF_NODELAY flag is set (nagle algorithm turned off for this pcb) or * - the only unsent segment is at least pcb.mss bytes long (or there is more * than one unsent segment - with lwIP, this can happen although unsent.len < mss) * - or if we are in fast-retransmit (tcp_pcb.TF_INFR) */ public static bool tcp_do_output_nagle(tcp_pcb tpcb) { return((tpcb.unacked == null) || ((tpcb.flags & (tcp_pcb.TF_NODELAY | tcp_pcb.TF_INFR)) != 0) || ((tpcb.unsent != null) && ((tpcb.unsent.next != null) || (tpcb.unsent.len >= tpcb.mss))) /*|| * ((tcp_sndbuftpcb == 0) || (tcp_sndqueuelentpcb >= opt.TCP_SND_QUEUELEN))*/ ); }
public void NewSession(tcp_pcb pcb) { m_TPcb = pcb; tcp.tcp_arg(pcb, this); tcp.tcp_recv(pcb, RecvData); tcp.tcp_sent(pcb, SentData); tcp.tcp_err(pcb, Error); }
public TcpCep(ID tcpid, ref T_TCP_CCEP pk_ctcp, Nucleus pNucleus, lwip lwip) { m_CepID = tcpid; m_ctcp = pk_ctcp; m_Nucleus = pNucleus; m_lwIP = lwip; m_Pcb = m_lwIP.tcp.tcp_new(); tcp.tcp_arg(m_Pcb, this); tcp.tcp_err(m_Pcb, Error); }
private err_t SentData(object arg, tcp_pcb tpcb, ushort space) { err_t err = err_t.ERR_OK; int rest = space; int pos = m_SendPos; pointer buf = m_SendPBuf; int len = m_SendLen; if (buf != null) { int tmp = rest; if (tmp > len) { tmp = len; } err = m_lwIP.tcp.tcp_write(m_TPcb, new pointer(buf, pos), (ushort)tmp, 0); if (err != err_t.ERR_OK) { return(err); } pos += tmp; rest -= tmp; if (pos == len) { pos = 0; buf = null; len = 0; } } m_SendPBuf = buf; m_SendPos = pos; m_SendLen = len; if ((m_SendPBuf == null) && (rest > 0)) { if (m_SendTaskQueue.First != null) { Task task = m_SendTaskQueue.First.Value; m_SendTaskQueue.RemoveFirst(); task.ReleaseWait(); } } return(err); }
private static err_t Accepting(object arg, tcp_pcb newpcb, err_t err) { TcpRep _this = (TcpRep)arg; _this.m_TcpCep.NewSession(newpcb); _this.m_AcceptQueue.AddLast(newpcb); if (_this.m_TskQueue.First != null) { Task task = _this.m_TskQueue.First.Value; _this.m_TskQueue.RemoveFirst(); if (!task.ReleaseWait()) { return(err_t.ERR_WOULDBLOCK); } } return(err); }
private static err_t RecvData(object arg, tcp_pcb tpcb, pbuf p, err_t err) { TcpCep _this = (TcpCep)arg; if (p == null) { _this.NetworkToHost(null); return(err_t.ERR_OK); } if (err != err_t.ERR_OK) { _this.m_lwIP.pbuf_free(p); return(err); } _this.NetworkToHost(p); _this.m_lwIP.tcp.tcp_recved(tpcb, p.tot_len); return(err_t.ERR_OK); }
public err_t tcp_output_nagle(tcp_pcb tpcb) { return(tcp_do_output_nagle(tpcb) ? tcp_output(tpcb) : err_t.ERR_OK); }
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); }
internal ER Accept(tcp_pcb_listen pcb, TcpCep cep, T_IPV4EP p_dstaddr, TMO tmout) { ER ret; m_Pcb = pcb; m_TcpCep = cep; tcp.tcp_accept(pcb, Accepting); Task task = m_Nucleus.GetTask(ID.TSK_SELF); if ((tmout != 0) && (task == null)) { return(ER.E_CTX); } //if (p_dstaddr == null) // return ER.E_PAR; if ((m_TskQueue.First == null) && (m_AcceptQueue.First != null)) { m_NewPcb = m_AcceptQueue.First.Value; m_AcceptQueue.RemoveFirst(); p_dstaddr.ipaddr = lwip.lwip_ntohl(m_NewPcb.remote_ip.addr); p_dstaddr.portno = lwip.lwip_ntohs(m_NewPcb.remote_port); } else { if (task == null) { return(ER.E_TMOUT); } if (tmout == 0) { return(ER.E_TMOUT); } ret = task.Wait(m_TskQueue, TSKWAIT.TTW_ACP, m_RepID, tmout); switch (ret) { case ER.E_OK: if (m_AcceptQueue.First == null) { return(ER.E_RLWAI); } m_NewPcb = m_AcceptQueue.First.Value; m_AcceptQueue.RemoveFirst(); p_dstaddr.ipaddr = lwip.lwip_ntohl(m_NewPcb.remote_ip.addr); p_dstaddr.portno = lwip.lwip_ntohs(m_NewPcb.remote_port); break; case ER.E_TMOUT: return(ER.E_TMOUT); default: return(ER.E_RLWAI); } } return(ER.E_OK); }