========= General ========= - We don't support any protocol other than TCP/IP. - We're strictly a client-side implementation. - Overall priorities are: code simplicity / compactness performance resource consumption - Adjustable configuration parameters are stored in global variables with 'cfg' name prefix. =================== Buffer management =================== - There are two kinds of packets: regular packets allocated out of pool memory, and DMA packets allocated inside contiguous physical page - We maintain a few lookaside lists for smaller-sized regular packets. - DMA packets are fixed size, ~half a page and large enough to hold an Ethernet frame. - When packets are passed around, the callee takes over the ownership of the packet. When the callee is done with the packet, it calls CompletePacket to dispose of it. Exception to this rule will be explicitly noted. ============ Interfaces ============ - Each interface has only one IP address. - Interfaces supported: Ethernet PPP over USB serial modem PPP over Ethernet loopback - Ethernet: receive both Ethernet and IEEE 802.3 frames send Ethernet frames only assume we hear our own broadcast/multicast transmissions - Default ARP configuration parameters: positive ARP cache entry timeout = 10min negative ARP cache entry timeout = 1min ARP request retry count = 2 ======== IP Layer ======== - We implement "Strong End-System" model, i.e. when a datagram arrives on an interface, the destination address must match that interface's address (or an approriate broadcast / multicast address) - We only support the all-1's form of broadcast addresses. - We do NOT support fragmentation on outgoing datagrams. - The default size limit for reassembled datagrams is 2048 bytes and the default reassembly timeout period is 60sec. - By default, the maximum number of datagrams that can be reassembled simultaneously is 4. - Subnet-directed broadcast are not received locally. ======= Winsock ======= - Our socket handles are not file handles, i.e. you can NOT call Read/WriteFile APIs on them. - Only limited validatation is performed on socket handles passed into the API calls. If app passes in a random handle value, the resulting behavior will be undefined. - Overlapped completion routines are not supported. - Since our socket handles are not file handles, apps can NOT call CancelIO API to cancel outstanding overlapped I/O requests. Apps must call WSACancelOverlappedIO function instead. - We claim to support the following Winsock versions: 1.0, 1.1 2.0, 2.1, 2.2 - But we don't support 1.x blocking hooks, i.e. the following calls are not supported: WSASetBlockingHook WSAUnhookBlockingHook WSACancelBlockingCall WSAIsBlocking - Following calls from Winsock 2 are NOT supported: WSAAsyncGetHostByAddr WSAAsyncGetHostByName WSAAsyncGetProtoByName WSAAsyncGetProtoByNumber WSAAsyncGetServByName WSAAsyncGetServByPort WSAAsyncSelect WSACancelAsyncRequest WSADuplicateSocket WSAGetQOSByName WSAJoinLeaf WSAProviderConfigChange WSARecvDisconnect WSASendDisconnect WSAHtonl WSAHtons WSANtohl WSANtohs WSAAddressToString WSAStringToAddress WSASocket WSAAccept WSAConnect WSAIoctl WSAEventSelect WSAEnumProtocols WSAEnumNetworkEvents WSALookupServiceBegin WSALookupServiceNext WSALookupServiceEnd WSAInstallServiceClass WSARemoveServiceClass WSAGetServiceClassInfo WSAEnumNameSpaceProviders WSAGetServiceClassNameByClassId WSASetService - closesocket always return immediately. If SO_LINGER is on and timeout is non-zero, we use the graceful close semantics (i.e. as if SO_DONTLINGER is on). - For send calls, we don't support MSG_OOB and MSG_PARTIAL flags and ignore MSG_DONTROUTE. - For recv calls, we don't support MSG_OOB and MSB_PARTIAL flags. MSG_PEEK flag is supported for datagram sockets. - For WSARecv calls, we do not support more than one buffers. - We do not support more than one outstanding overlapped I/O requests. - We don't allow multiple threads to use the same socket handle simultanenously. If two threads try to use the same socket handle at the same time, the first one succeeds and the second one fails with a busy error. ===================== Directory Structure ===================== inc common include files phy PHY (Ethernet transceiver) code in ROM lib common library functions enet Ethernet interface driver modem modem driver ppp PPP interface driver ip IP/ICMP/IGMP code tcp TCP/UDP code dhcp DHCP client code dns DNS client code winsock Winsock code, and everytying is built into XNET.DLL http lightweight HTTP client library test test programs ====== Issues ====== - need to pass TCP related ICMP messages from IP layer to TCP layer - path MTU discovery - dead gateway detection - implement TCP urgent data? - support source route IP options for TCP connections? - do receive work in a separate system thread instead of at DISPATCH_LEVEL? ======================================= Winsock API Parameter Validation RIPs ======================================= bind: name != NULL namelen >= sizeof(struct sockaddr) name->sin_family == AF_INET connect: same as bind listen: socket must be a TCP socket accept: socket must be a TCP socket either addr == NULL, or addrlen != NULL and addrlen >= sizeof(struct sockaddr) getsockname: name != NULL namelen != NULL *namelen >= sizeof(struct sockaddr) getpeername: same as getsockname gethostbyaddr: addr != NULL len >= sizeof(struct in_addr) type == AF_INET gethostbyname: name != NULL getservbyname: name != NULL getprotobyname: name != NULL GetBestIpAddress addr != NULL recv: either len > 0 and buf != NULL, or len == 0 WSARecv: dwBufferCount == 1 lpBuffers != NULL ether lpBuffers->len > 0 and lpBuffers->buf != NULL, or lpBuffers->len == 0 lpNumberOfBytesRecvd != NULL lpFlags != NULL lpCompletionRoutine == NULL recvfrom: either len > 0 and buf != NULL, or len == 0 either from == NULL, or fromlen != NULL and *fromlen >= sizeof(struct sockaddr) WSARecvFrom: same as WSARecv, and either from == NULL, or fromlen != NULL and *fromlen >= sizeof(struct sockaddr) WSAGetOverlappedResult: lpOverlapped != NULL lpcbTransfer != NULL lpdwFlags != NULL send: either len > 0 and buf != NULL, or len == 0 flags == 0 WSASend: dwBufferCount > 0 lpBuffers != NULL for each WSABUF either len > 0 and buf != NULL, or len == 0 lpNumberOfBytesSent != NULL dwFlags == 0 lpCompletionRoutine == NULL sendto: either len > 0 and buf != NULL, or len == 0 flags == 0 either to == NULL, or tolen >= sizeof(struct sockaddr) WSASendTo: same as WSASend, and either lpTo == NULL, or iToLen >= sizeof(struct sockaddr) shutdown: how must be one of the following values: SD_RECEIVE SD_SEND SD_BOTH WSAStartup: lpWSAData != NULL inet_addr: cp != NULL setsockopt: optval != NULL optlen > 0 additional requirements for specific options: SO_LINGER: optlen >= sizeof(LINGER) SO_ERROR: SO_RCVTIMEO: SO_SNDTIMEO: SO_RCVBUF: SO_SNDBUF: optlen >= sizeof(INT) SO_MULTICASTIF: optlen >= sizeof(struct in_addr) SO_ADD_MEMBERSHIP: SO_DROP_MEMBERSHIP: optlen >= sizeof(struct ip_mreq) getsockopt: optval != NULL optlen != NULL *optlen > 0 additional requirements for specific options: same as setsockopt ioctlsocket: argp != NULL