09.11.2016 Views

Foundations of Python Network Programming 978-1-4302-3004-5

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

CHAPTER 2 ■ UDP<br />

How do clients learn the IP addresses and ports to which they should connect? There are generally<br />

three ways:<br />

• Convention: Many port numbers have been designated as the <strong>of</strong>ficial, well-known<br />

ports for specific services by the IANA, the Internet Assigned Numbers Authority.<br />

That is why we expected DNS to run at UDP port 53 in the foregoing example.<br />

• Automatic configuration: Often the IP addresses <strong>of</strong> critical services like DNS are<br />

learned when a computer first connects to a network, if a protocol like DHCP is<br />

used. By combining these IP addresses with well-known port numbers, programs<br />

can reach these essential services.<br />

• Manual configuration: For all <strong>of</strong> the situations that are not covered by the<br />

previous two cases, some other scheme will have to deliver an IP address or the<br />

corresponding hostname.<br />

There are all kinds <strong>of</strong> ways that IP addresses and port numbers can be provided manually: asking a<br />

user to type a hostname; reading one from a configuration file; or learning the address from another<br />

service. There was, once, even a movement afoot to popularize a portmap daemon on Unix machines<br />

that would always live at port 2049 and answer questions about what ports other running programs were<br />

listening on!<br />

When making decisions about defining port numbers, like 53 for the DNS, the IANA thinks <strong>of</strong> them<br />

as falling into three ranges—and this applies to both UDP and TCP port numbers:<br />

• “Well-Known Ports” (0–1023) are for the most important and widely-used<br />

protocols. On many Unix-like operating systems, normal user programs cannot<br />

use these ports, which prevented troublesome undergraduates on multi-user<br />

machines from running programs to masquerade as important system services.<br />

Today the same protections apply when hosting companies hand out commandline<br />

Linux accounts.<br />

• “Registered Ports” (1024–49151) are not usually treated as special by operating<br />

systems—any user can write a program that grabs port 5432 and pretends to be a<br />

PostgreSQL database, for example—but they can be registered by the IANA for<br />

specific protocols, and the IANA recommends that you avoid using them for<br />

anything but their assigned protocol.<br />

• The remaining port numbers (49152–65535) are free for any use. They, as we shall<br />

see, are the pool on which modern operating systems draw in order to generate<br />

random port numbers when a client does not care what port it is assigned.<br />

When you craft programs that accept port numbers from user input like the command line or<br />

configuration files, it is friendly to allow not just numeric port numbers but to let users type humanreadable<br />

names for well-known ports. These names are standard, and are available through the<br />

getservbyname() call supported by <strong>Python</strong>’s standard socket module. If we want to ask where the<br />

Domain Name Service lives, we could have found out this way:<br />

>>> import socket<br />

>>> socket.getservbyname('domain')<br />

53<br />

As we will see in Chapter 4, port names can also be decoded by the more complicated getaddrinfo()<br />

function, which also lives in the socket module.<br />

The database <strong>of</strong> well-known service names is usually kept in the file /etc/services on Unix<br />

machines, which you can peruse at your leisure. The lower end <strong>of</strong> the file, in particular, is littered with<br />

ancient protocols that still have reserved numbers despite not having had an actual packet addressed to<br />

18

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!