Revision · 23CS7PCNWP · Units 1 and 2
Everything, on one page
Every number, name, state and prototype worth having in your head walking in. Built to print — the button in the bar gives you clean sheets with nothing interactive on them.
The numbers
The ones that get asked directly.
Sizes and limits
- Max IPv4 datagram
- 65,535 (incl. header)
- Max IPv6 datagram
- 65,575 (incl. 40-byte header)
- Ethernet MTU
- 1,500
- Min link MTU, IPv4
- 68
- Min link MTU, IPv6
- 1,280
- Min reassembly, IPv4
- 576
- Min reassembly, IPv6
- 1,500
- Typical IPv4 MSS
- 1,460 (1500 − 20 − 20)
- Max advertised window
- 65,535 (16-bit field)
- With window scale
- 65,535 × 2¹⁴ ≈ 1 GB
Structure sizes
- sockaddr_in
- 16 bytes
- sockaddr_in6
- 28 bytes
- sockaddr
- 16 bytes
- sockaddr_storage
- 128 bytes (typical)
- in_addr
- 4 bytes (32-bit)
- in6_addr
- 16 bytes (128-bit)
- INET_ADDRSTRLEN
- 16
- INET6_ADDRSTRLEN
- 46
Times
- TIME_WAIT
- 2MSL — 1 to 4 minutes
- MSL, RFC 1122
- 2 minutes
- MSL, Berkeley
- 30 seconds
- Max hop limit / TTL
- 255
- connect timeout
- ~75 seconds
- Incomplete-queue timeout
- 75 seconds
- Data retransmit give-up
- 12 tries, ~9 minutes
- SO_KEEPALIVE idle
- 2 hours
- init SIGTERM → SIGKILL
- 5–20 seconds
- Delayed ACK
- up to 200 ms
Port ranges (IANA)
- 0 – 1023
- Well-known · IANA-assigned · Unix reserved
- 1024 – 49151
- Registered · listed, not controlled
- 49152 – 65535
- Dynamic / private · ephemeral
FTP 21 · daytime 13 · HTTP 80 · TFTP UDP 69 · book's SERV_PORT 9877. 49152 = ¾ of 65536.
Counts to quote
- TCP states
- 11
- TCP handshake
- 3 packets
- TCP teardown
- 4 packets
- SCTP handshake
- 4 packets
- SCTP shutdown
- 3 packets
- Process → kernel fns
- 3
- Kernel → process fns
- 4
- Conversion functions
- 5
- Inherited socket options
- 11
- TCP overhead, 1 req/reply
- 8 segments (vs 2 for UDP)
The calls
Prototypes, in the order you use them.
Elementary TCP
int socket(int family, int type,
int protocol);
int connect(int sockfd,
const struct sockaddr *servaddr,
socklen_t addrlen);
int bind(int sockfd,
const struct sockaddr *myaddr,
socklen_t addrlen);
int listen(int sockfd, int backlog);
int accept(int sockfd,
struct sockaddr *cliaddr,
socklen_t *addrlen);
int close(int sockfd);
Server: socket → bind → listen → accept. Client: socket → connect.
Names, options, processes
int getsockname(int sockfd,
struct sockaddr *localaddr,
socklen_t *addrlen);
int getpeername(int sockfd,
struct sockaddr *peeraddr,
socklen_t *addrlen);
int getsockopt(int sockfd, int level,
int optname, void *optval,
socklen_t *optlen);
int setsockopt(int sockfd, int level,
int optname, const void *optval,
socklen_t optlen);
pid_t fork(void);
pid_t wait(int *statloc);
pid_t waitpid(pid_t pid, int *statloc,
int options);
Byte order and conversion
uint16_t htons(uint16_t); /* h→n, 16 */
uint32_t htonl(uint32_t); /* h→n, 32 */
uint16_t ntohs(uint16_t); /* n→h, 16 */
uint32_t ntohl(uint32_t); /* n→h, 32 */
int inet_aton(const char *,
struct in_addr *);
in_addr_t inet_addr(const char *);
char *inet_ntoa(struct in_addr);
int inet_pton(int family,
const char *, void *);
const char *inet_ntop(int family,
const void *, char *, size_t);
Test inet_pton with <= 0.
htonl for the address, htons for the port.
Byte manipulation
| Job | BSD | ANSI |
|---|---|---|
| zero | bzero(d,n) | memset(d,0,n) |
| copy | bcopy(s,d,n) | memcpy(d,s,n) |
| compare | bcmp(a,b,n) | memcmp(a,b,n) |
Argument order reverses. bcmp = equal / not equal;
memcmp = <, =, >.
Return values that catch people
- read → 0
- EOF: peer sent FIN. Not an error.
- read → −1
- Error. Check
errno. - read short
- Normal. Loop — use
readn. - inet_aton
- 1 = OK, 0 = error
- inet_pton
- 1 OK, 0 bad string, −1 error
- inet_ntop
- pointer, or NULL
- fork
- 0 in child, PID in parent
- accept
- NEW descriptor
- errno EINTR
- Interrupted — restart the call
The diagrams
Interactive here; they print as their final complete frame.
The states, the options, the errors
11 TCP states
CLOSED | start and end |
LISTEN | passive open done |
SYN_SENT | active open, SYN sent |
SYN_RCVD | SYN+ACK sent, awaiting 3rd |
ESTABLISHED | data transfer |
FIN_WAIT_1 | active close, FIN sent |
FIN_WAIT_2 | our FIN ACKed, half-closed |
CLOSE_WAIT | passive close, awaiting our close |
CLOSING | simultaneous close only |
LAST_ACK | passive close, awaiting final ACK |
TIME_WAIT | active closer waits 2MSL |
Normal paths
Client
CLOSED → SYN_SENT → ESTABLISHED
→ FIN_WAIT_1 → FIN_WAIT_2
→ TIME_WAIT → CLOSED
Server
CLOSED → LISTEN → SYN_RCVD
→ ESTABLISHED → CLOSE_WAIT
→ LAST_ACK → CLOSED
TIME_WAIT — the two reasons
- Reliable full-duplex close. If the final ACK is lost the peer resends its FIN, so this end must keep state to resend the ACK — otherwise it would answer with an RST, read as an error.
- Let old duplicates expire. Stops an old segment reaching a new incarnation of the same socket pair.
2MSL = one MSL out, one MSL back. Only the active-close end waits.
Value-result — the 3 and the 4
Process → kernel (plain value):
bind · connect · sendto
Kernel → process (value-result):
accept · recvfrom · getsockname · getpeername
In: how big the buffer is, so the kernel does not overrun it.
Out: how much it actually stored. Also getsockopt and
select's middle three.
Q2(c) — the five options
| Option | Level | Kind | Type |
|---|---|---|---|
IP_TTL | IPPROTO_IP | value | int |
SO_BROADCAST | SOL_SOCKET | flag | int |
TCP_MAXSEG | IPPROTO_TCP | value | int |
IPV6_DONTFRAG | IPPROTO_IPV6 | flag | int |
SO_LINGER | SOL_SOCKET | value | linger{} |
Flag = on/off, int. Value = carries a value of the stated type.
SO_LINGER — three cases
| onoff | linger | close does |
|---|---|---|
| 0 | — | returns at once (default) |
| ≠0 | 0 | abort: discard data, send RST, no TIME_WAIT |
| ≠0 | ≠0 | sleep until ACKed or time expires (then EWOULDBLOCK, data discarded) |
11 inherited options
SO_DEBUG · SO_DONTROUTE · SO_KEEPALIVE · SO_LINGER · SO_OOBINLINE · SO_RCVBUF · SO_RCVLOWAT · SO_SNDBUF · SO_SNDLOWAT · TCP_MAXSEG · TCP_NODELAY
Set them on the listening socket — the connected socket is made by
the kernel during the handshake, before accept returns.
Server host goes away
| Case | Sends | Client sees |
|---|---|---|
| crash | nothing | ETIMEDOUT (~9 min) |
| crash+reboot | RST | ECONNRESET |
| shutdown | FIN | read → 0 |
| router says no | ICMP | EHOSTUNREACH |
FIN = goodbye. RST = denial. Silence = 9 minutes of retries.
connect errors
- ETIMEDOUT
- no reply · ~75 s
- ECONNREFUSED
- RST · hard error
- EHOSTUNREACH
- ICMP · soft error
- ENETUNREACH
- ICMP · soft error
RST is generated when: a SYN arrives for a port with no listener; TCP aborts a connection; a segment arrives for a connection that does not exist.
Signals
- SIGCHLD
- child died · default IGNORED → zombies
- SIGPIPE
- wrote to a socket that got an RST → EPIPE
- SIGTERM
- shutdown · catchable
- SIGKILL
- not catchable, not ignorable
- SIGSTOP
- not catchable, not ignorable
while ((pid = waitpid(-1, &stat,
WNOHANG)) > 0)
; /* loop: signals aren't queued */
The two listen queues
- Incomplete
- SYN arrived ·
SYN_RCVD - Completed
- handshake done ·
ESTABLISHED
SYN → incomplete → (3rd segment) → completed → accept takes the
first. Timeout on incomplete: 75 s. Sum bounded by backlog.
Creation is automatic — the server process is not involved.
TCP vs SCTP
| TCP | SCTP | |
|---|---|---|
| open | 3 | 4 |
| close | 4 | 3 |
| addresses | 1 | many |
| streams | 1 | many |
| boundaries | no | yes |
| half-close | yes | no |
| TIME_WAIT | yes | no |
| state on 1st pkt | allocated | cookie |
SCTP: INIT → INIT-ACK(cookie) → COOKIE-ECHO → COOKIE-ACK. Close: SHUTDOWN → SHUTDOWN-ACK → SHUTDOWN-COMPLETE.
Traps
The specific things that cost marks.
Byte order
htonlfor the 32-bit address,htonsfor the 16-bit port. Not the other way round.- "s" and "l" mean 16-bit and 32-bit, not
shortandlong. Under LP64 alongis 64 bits. ntohsbefore printing a port fromaccept.- On a big-endian machine these are null macros — omitting them is a bug that hides.
Structures
bzerothe structure first —sin_zeroandsin_lenare never assigned by you.- Every socket call needs the
(SA *)cast. sockaddris 16 bytes;sockaddr_in6is 28 — which is whysockaddr_storageexists.- Reset
len = sizeof(addr)inside the accept loop.
Streams
- TCP has no record boundaries. One write ≠ one read.
- A short count is not an error — loop, or use
readn/writen. readreturning 0 is EOF, not failure.fgetskeeps the newline — strip it beforestrlen.- Never write a raw
structdown a socket: byte order and padding differ.
Concurrency
- Child closes
listenfd; parent closesconnfd. closeonly decrements — the FIN goes when the count hits 0.- Catch
SIGCHLDand reap in a loop withWNOHANG. - Then handle
EINTRfromaccept— but never restartconnect.
Deprecated / wrong answers
inet_addr— cannot express255.255.255.255. Useinet_atonorinet_pton.inet_ntoa— returns static memory, not re-entrant.SO_LINGERwith 0 to dodge TIME_WAIT — useSO_REUSEADDR. RFC 1337.sprintf— usesnprintf.backlogis not the number of clients.
Terminology
- active open
- connect() — the client
- passive open
- listen() — the server
- active close
- closed first → TIME_WAIT
- passive close
- received FIN → CLOSE_WAIT
- socket
- one IP + one port
- socket pair
- the four-tuple
- incarnation
- a new connection, same four-tuple
- wandering duplicate
- packet lost in a routing loop
- association
- SCTP's word for a connection
- long fat pipe
- high bandwidth or long delay
The paper
2026 format — 50 marks.
Structure
| Part | Level | Marks |
|---|---|---|
| I | Remember / Understand answer all · 5 + 5 | 10 |
| II | Apply 2a compulsory, then 2b OR 2c | 20 |
| III | Design / Analyze whole of Q3 OR whole of Q4 · 8 + 6 + 6 | 20 |
Part II is programs. Part III is all-or-nothing — you cannot mix 3a with 4b.
Where everything is
Chapter map
- Ch 1
- OSI · Unix standards · client/server
- Ch 2
- TCP/UDP/SCTP · handshakes · TIME_WAIT · ports · buffers
- Ch 3
- Address structures · value-result · byte order · conversions
- Ch 4
- socket/bind/listen/accept · fork · getsockname
- Ch 5
- Echo pair · signals · zombies · host failures
- Ch 7
- get/setsockopt · every option family
- Format
- The 2026 format — 50 marks, three Bloom levels
- Paper
- Internals-1 2025, solved
- Practice
- 20 probable questions