Siksha Sarovar

Siksha Sarovar (sikshasarovar.com) is a free educational web application that helps students in India learn programming and prepare for academic and competitive exams. The platform offers structured coding courses (C, C++, Python, Java, HTML, CSS, PHP, Power BI, AI, Machine Learning, Data Science), complete university curriculum notes for BCA/MCA students with previous year question papers, Class 10 and Class 12 CBSE/HBSE school notes, and dedicated preparation material for SSC, UPSC, Banking, Railway and other government exams. Browsing the site is completely free and requires no account. Users may optionally sign in with Google solely to save their learning progress, quiz scores and personal preferences across devices.

Privacy Policy | Terms of Service | Contact Siksha Sarovar | About Siksha Sarovar

v4.0.9 · PWA
Siksha Sarovar logo
Siksha Sarovar
Your Learning Universe

Siksha Sarovar is a free e-learning platform for coding courses, BCA university notes and competitive exam preparation. Optional Google sign-in saves your learning progress across devices.

Initializing knowledge base…
Compiling modules 0%

Unit 3: Broadcasting — One-to-All on the LAN & Race Conditions

Lesson 11 of 15 in the free Network Programming notes on Siksha Sarovar, written by Rohit Jangra.

3.1 The four addressing modes

ModeDeliverySupport
Unicastone sender → one receivereverywhere
Broadcastone → all hosts on a subnetIPv4 only (IPv6 dropped it)
Multicastone → all subscribed hostsIPv4 optional, IPv6 mandatory (next lesson)
Anycastone → nearest of a setrouting-level (DNS roots)

3.2 Broadcast addresses

  • Limited broadcast: 255.255.255.255 — all hosts on the local link; never forwarded by routers. Used when you don't yet know your own network (DHCP's first cry).
  • Subnet-directed broadcast: host bits all-1 for a subnet, e.g. 192.168.1.255 for 192.168.1.0/24. Routers can be configured to forward — but are universally told not to (smurf-attack history).

At the link layer an IPv4 broadcast rides an Ethernet frame to ff:ff:ff:ff:ff:ffevery NIC on the segment passes it up; every host pays the interrupt, which is broadcast's fundamental cost (and why multicast exists).

Who uses broadcast: ARP (the question "who has 192.168.1.7?" is a broadcast), DHCP (client has no address yet), NTP/routing daemons on LANs, service discovery ("is there a server here?").

3.3 Sending: SO_BROADCAST and dg_cli with broadcasting

The kernel refuses to sendto a broadcast address unless the program explicitly declares intent:

const int on = 1;
setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));

dest.sin_family = AF_INET;
dest.sin_port   = htons(13);                       /* daytime */
inet_pton(AF_INET, "192.168.1.255", &dest.sin_addr);
sendto(sockfd, "", 1, 0, (struct sockaddr *)&dest, sizeof(dest));

(Without the option: EACCES.) One datagram, many replies: broadcast a daytime query and every host's server answers — the client must loop in recvfrom with a timeout, printing each reply and its source address:

/* dg_cli with broadcasting: collect replies until 5 quiet seconds */
sendto(sockfd, sendline, n, 0, (SA *)&dest, sizeof(dest));
for (;;) {
    fd_set rset; FD_ZERO(&rset); FD_SET(sockfd, &rset);
    struct timeval tv = {5, 0};
    if (select(sockfd+1, &rset, NULL, NULL, &tv) == 0) break;  /* done */
    len = sizeof(from);
    n = recvfrom(sockfd, recvline, MAXLINE, 0, (SA *)&from, &len);
    printf("from %s: %s", inet_ntop(AF_INET, &from.sin_addr, str, sizeof(str)), recvline);
}

Note what changed from the unicast client: you can't use a connected UDP socket (replies come from many addresses), and "how long do I wait?" has no right answer — a timeout heuristic ends the collection.

3.4 Race conditions — the signal version of this story

The classic alternative timeout (SIGALRM) hides a race condition — and this syllabus point generalises far beyond broadcasting:

/* BUGGY timeout pattern */
signal(SIGALRM, recvfrom_alarm);
alarm(5);
n = recvfrom(sockfd, ...);        /* RACE: if the alarm fires BETWEEN     */
alarm(0);                          /* alarm(5) and recvfrom, the signal    */
                                   /* is consumed early and recvfrom      */
                                   /* blocks FOREVER                       */

The window is tiny — which makes the bug worse: it strikes once a month in production. The three repairs, in increasing elegance:

  1. pselect — atomically unblock a signal and wait: block SIGALRM, set the flag handler, then pselect with the original mask; the unblock+wait is one atomic kernel operation. (sigsetjmp/siglongjmp is the older equivalent escape.)
  2. select with a timeout instead of signals (the code in §3.3) — no signals, no race.
  3. Self-pipe trick — handler writes a byte to a pipe; select watches the pipe and the socket: turns signals into descriptors.

Definition for the exam: a race condition exists when the correctness of a program depends on the relative timing of events outside its control (signal delivery vs syscall entry here). Cures are always the same family: make check-and-wait atomic, or funnel the asynchronous event into the synchronous wait set.

3.5 Unicast vs broadcast on the wire — the frame-level comparison

"Compare unicast and broadcast delivery of a UDP datagram" expects the layered trace, not just definitions. Send the same daytime query both ways on a 50-host Ethernet:

StageUnicast (to 192.168.1.7)Broadcast (to 192.168.1.255)
frame destination7's MAC (via ARP)ff:ff:ff:ff:ff:ff
NICs that pass it upexactly one — others filter in hardwareall 50 — broadcast bypasses the MAC filter
IP layer on each hostn/a (never seen)all 50 check: am I in 192.168.1.0/24? deliver up
UDP layerone host demultiplexes to port 13hosts with port 13 open deliver; the other ~45 drop it — after paying the interrupt + IP processing
repliesonemany, staggered

The bolded cell is the syllabus point "broadcast loads every host": the cost is paid by hosts that don't even run the service — work done in software, above the NIC, for nothing. Multicast (next lesson) pushes the filtering back down into the NIC. Note also that broadcast is inherently UDP/ICMP-only: TCP's 4-tuple names exactly two endpoints, so a TCP broadcast is a contradiction.

3.6 The two canonical broadcast users, traced

ARP (the protocol below your sockets): before the unicast above can even be framed, the sender must learn 7's MAC. It broadcasts "who has 192.168.1.7?" — every host processes it; only 7 replies (unicast) with its MAC; the sender caches it (arp -a shows the cache). ARP is the proof that broadcast is foundational: every unicast conversation on a LAN begins with one broadcast.

DHCP (the bootstrap problem): a booting client has no IP address at all — it cannot unicast, cannot even fill in a sane source. It broadcasts DISCOVER from 0.0.0.0:68 to 255.255.255.255:67; servers OFFER; client REQUESTs (still broadcast — other servers must see the choice); server ACKs. Broadcast is the only possible transport for "I don't know who I am or who you are" — say that sentence and the marks follow.

3.7 pselect, precisely

Since §3.4 names it as the proper fix, give its signature and the two differences from select:

int pselect(int maxfdp1, fd_set *rset, fd_set *wset, fd_set *eset,
            const struct timespec *timeout,    /* nanoseconds, and const! */
            const sigset_t *sigmask);          /* THE new argument */

Inside the kernel, pselect atomically performs: install sigmask → wait → restore the old mask. The race-free pattern: block SIGALRM in the main flow; let the handler just set a flag; call pselect with a mask that unblocks SIGALRM only for the duration of the wait. The signal can now arrive only while the process is actually waiting — the gap between "check the flag" and "go to sleep" has been welded shut. That one-sentence mechanism ("unblock and wait are a single atomic kernel operation") is the whole answer to "how does pselect fix the race?".

Exam pointers

  • "Distinguish unicast, broadcast, multicast, anycast" — §3.1's table plus one named user of each (TCP / ARP+DHCP / IPTV+MBone / DNS root servers).
  • "Why does broadcasting require SO_BROADCAST?" — deliberate friction: a typo'd address or a misconfigured netmask shouldn't accidentally interrupt every host on the subnet; the kernel demands an explicit declaration of intent (EACCES otherwise).
  • "Explain the race condition in the timeout version of dg_cli" — the buggy code, the exact window (between alarm() and recvfrom entering the kernel), the consequence (block forever), then the three fixes ranked. State the general definition verbatim at the end.
  • Short answer: why can't a broadcast client use a connected UDP socket? (Replies arrive from many source addresses; a connected socket filters all but one.)

Check yourself

  1. 255.255.255.255 vs 192.168.1.255 — which crosses routers, which needs you to know your subnet, and which does DHCP use first?
  2. A 200-host LAN runs one broadcast-based discovery query per second from each host. Describe the per-host cost — including hosts that don't participate in the protocol.
  3. Why does the broadcast daytime client need a select timeout where the unicast one didn't? What ends the reply collection?
  4. Place the race: between which two lines of the buggy code must the alarm fire to cause the hang? Why does smallness make the bug worse?
  5. Sketch how the self-pipe trick converts a signal into something select can wait on. Which general cure family does it belong to?