=========
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