• No results found

9 IP: Multicast Processing (IGMP)

10 UDP: User Datagrams

10.4 UDP Output Processing

10.4 UDP Output Processing

Before an application program can communicate using UDP, it needs a local UDP port number. Servers, which use well-known ports, request a specific port assignment from the operating system. Usually, clients do not need a specific port — they can use an arbitrary port number. However, because our system demultiplexes using only destination port numbers, a client must be assigned a unique port number. Procedure udpnxtp generates a UDP port number that is not in use.

/* udpnxtp.c - udpnxtp */

#include <conf.h>

#include <kernel.h>

#include <network.h>

* udpnxtp - return the next available UDP local "port" number

* N.B.: assumes udpmutex HELD

*/

unsigned short udpnxtp() {

static unsigned short lastport = ULPORT;

Bool inuse = TRUE;

struct upq *pup;

int i;

while (inuse) { lastport++;

if (lastport == 0) lastport = ULPORT;

inuse = FALSE;

for (i=0; !inuse && i<UPPS ; i++) { pup = &upqs[i];

inuse = pup->up_valid && pup->up_port == lastport;

}

}

return lastport;

}

To generate an unused port number, udpnxtp First increments the global counter lastport. It then iterates through the set of UDP input queues to see if any application program has already been assigned lastport. Usually, the iteration does not find a match, and udpnxtp returns lastport to the caller. If it does find a match, udpnxtp increments lastport and tries again.

10.4.1 Sending A UDP Datagram

When an application program generates UDP output, it transfers control to the operating system and eventually calls procedure udpsend to send the UDP datagram.

/* udpsend.c - udpsend */

#include <conf.h>

#include <kernel.h>

#include <network.h>

#include <igmp.h>

* udpsend - send one UDP datagram to a given IP address

*/

int udpsend(IPaddr fip, u_short fport, u_short lport, struct ep *pep, unsigned datalen, Bool docksum)

Ipaddr fip;

unsigned short fport, lport;

struct ep *pep;

int datalen;

Bool docksum;

{

struct ip *pip = (struct ip *) pep->ep_data;

struct udp *pudp = (struct udp *) pip->ip_data;

struct route *prt, *rtget();

struct hg *phg, hglookup();

int ttl;

pudp->u_src = lport;

pudp->u_dst = fport;

pudp->u_len = U_HLEN+datalen;

pudp->u_cksum = 0;

udph2net(pudp);

if (docksum) {

prt = rtget(fip, RTF_LOCAL);

if (prt == NULL) { IpOutNoRoutes++;

freebuf(pep);

return SYSERR;

}

blkcopy(pip->ip_dst, fip, IP_ALEN);

if (prt->rt_ifnum == NI_LOCAL)

blkcopy(pip->ip_src, pip->ip_dst, IP_ALEN);

else

blkcopy(pip->ip_src, nif[prt->rt_ifnum].ni_ip, IP_ALEN);

rtfree(prt);

pudp->u_cksum = udpcksum(pip);

if (pudp->u_cksum == 0) pudp->u_cksum = ~0;

}

UdpOutDatagrams++;

if (IP_CLASSD(fip)) {

wait(HostGroup.hi_mutex);

phg = hglookup(NI_PRIMARY, fip);

if (phg)

ttl = phg->hg_ttl;

else

ttl = 1;

signal(HostGroup.hi_mutex);

}

return ipsend(fip, pep, U_HLEN+datalen, IPT_UDP, IPP_NORMAL, ttl);

}

Because gateways have multiple network connections, they have multiple IP addresses. Before udpsend can compute the UDP checksum, it needs to know which address IP will use as the source address for the IP datagram that carries the message. To find out, udpsend calls procedure rtget, passing it the destination IP address as an argument. Once it determines a route, udpsend extracts the network interface, from which it obtains the IP datagram source address.

Once it has computed the source address for the IP datagram, udpsend fills in the remaining fields of the UDP header, calls udpcksum to compute the checksum, and calls ipsend to pass the resulting IP datagram to IP for routing and transmission.

10.5 Summary

UDP provides both pairwise communication between peer programs and many-one communication between clients and a server. While the two basic styles of demultiplexing both support clients and servers, each has advantages and disadvantages.

The example code demultiplexes using only the destination protocol port number, and makes the creation of servers trivial. To help support clients, the system includes a procedure that generates a unique (unused) protocol port number on demand.

Both UDP input and UDP output are straightforward. The IP process executes the UDP input procedure, which demultiplexes datagrams and deposits each on a queue associated with the destination protocol port. Application programs allocate a port used for transmission and then call the output procedures to create and send UDP datagrams.

The UDP checksum includes fields from a pseudo-header that are used to verify that the IP datagram carrying UDP contained the correct IP source and destination addresses. For input, UDP can obtain values for pseudo-header fields from the IP datagram that carries the UDP message. For output, the pseudo-header processing complicates the UDP checksum computation because it forces UDP to determine which address IP will use as the source address for the datagram.

10.6 FOR FURTHER STUDY

Postel [RFC 768] defines the UDP protocol and specifies the message format. The host requirements document [RFC 1122] provides further clarification. Leffler, McKusick, Karels, and Quarterman [1989] presents details of the BSD UNIX implementation.

10.7 EXERCISES

1. Read the RFC carefully to determine whether all pseudo-header fields used to verify the UDP checksum must be taken from the IP datagram that carries the UDP datagram. Can constants ever be used? Explain.

2. Read the 4BSD UNIX documentation. Which style of demultiplexing does it use?

3. Does your local system allow you to specify the size of a UDP input queue? If so, how can you choose a reasonable size?

4. Look at udpcksum carefully. What does it do if the computed checksum happens to be zero? Why?

5. Explain why udpnxtp skips ports between 0 and ULPORT (2050) when it generates a local port number.

6. How many UDP ports does a typical timesharing system use simultaneously?

How many does a typical scientific workstation use?

7. Our example code uses sequential search to find a UDP port for demultiplexing. Devise a hashing scheme that lowers lookup time. Will your scheme ever increase lookup time? (Hint: consider the previous exercise).

11 TCP: Data Structures And