void Connection::send(const void *data, size_t datalen) { if (mFd < 0) { ErrorPrint("[send] send error! socket uninited or shuted!"); return; } if (mConnStatus != ConnStatus_Connected) { ErrorPrint("[send] can't send data in such status(%d)", mConnStatus); return; } const char *ptr = (const char *)data; if (tryFlushRemainPacket()) { int sentlen = ::send(mFd, data, datalen, 0); // int sentlen = -1; errno = EAGAIN; if ((size_t)sentlen == datalen) return; if (sentlen > 0) { ptr += sentlen; datalen -= sentlen; } } if (checkSocketErrors()) return; cachePacket(ptr, datalen); tryRegWriteEvent(); // 注册发送缓冲区可写事件 }
/*----------------------------------------------------------------------------- * Method: void handleForward * * determines what interface to send a packet out of *---------------------------------------------------------------------------*/ void handleForward( struct sr_instance* sr, uint8_t* packet, unsigned int len, char* interface ) { struct ip* ipHdr = (struct ip*)(packet+14); struct sr_rt* rtptr = sr->routing_table; int cachedEntry; /* loop through rtable for the next hop with the packet's destination ip */ while (rtptr) { if (rtptr->dest.s_addr == ipHdr->ip_dst.s_addr) break; else rtptr = rtptr->next; } /* if not in our rtable, send it out eth0 to the intarwebz */ if (!rtptr) { rtptr = sr->routing_table; // eth0 if ((cachedEntry = arpSearchCache(rtptr->gw.s_addr)) > -1) { forwardPacket(sr, packet, len, rtptr->interface, arpReturnEntryMac(cachedEntry)); } else { cachePacket(sr, packet, len, rtptr); } } /* look through arp cache for mac matching the ip destination. if we have it, * forward our packet. otherwise, cache the packet and wait for an arp reply * to tell us the correct mac address */ if ((cachedEntry = arpSearchCache(rtptr->gw.s_addr)) > -1) { forwardPacket(sr, packet, len, rtptr->interface, arpReturnEntryMac(cachedEntry)); } else { cachePacket(sr, packet, len, rtptr); } }