CS 3214 Computer Systems Lecture 24 Godmar Back Announcements • Project 5 due Dec 8 • Exercise 10 handed out • Exercise 11 coming before Thanksgiving CS 3214 Fall 2010 Some of these slides are substantially derived from slides provided by Jim Kurose & Keith Ross. Copyright on this material is held by Kurose & Ross. Used with permission. The textbook is Computer Networking: A Top Down Approach Featuring the Internet Jim Kurose, Keith Ross, Addison-Wesley, July 2004 Part 2 NETWORKING CS 3214 Fall 2010 Socket Programming UDP & TCP Network Socket Programming Socket: (narrow definition:) a door between application process and end-end-transport protocol (UDP or TCP) controlled by application developer controlled by operating system process process socket Stack w/ buffers, variables internet socket Stack w/ buffers, variables host or server host or server CS 3214 Fall 2010 controlled by application developer controlled by operating system Socket Programming socket Socket API • introduced in BSD 4.1 UNIX, 1981 • explicitly created, used, released by apps • used for both local and remote communication CS 3214 Fall 2010 a host-local, application-created, OS-controlled interface (a “door”) into which application process can both send and receive messages to/from another application process BSD Socket API • API – Application Programming Interface – Provides access to services – Specified in C language – Implemented on many platforms in one way or the other • (Windows: WinSock2, CSocket MFC classes for BSD-like look) • Sockets (in Unix) are file descriptors – General idea: writing to the socket is sending data to network, reading from socket is receiving data – Good because read(2), write(2), close(2) and others (select(2), poll(2), ioctl(2), SIGIO, fcntl(2)) can be reused – Bad because suggest orthogonality if where there is none • Other languages provide separate mapping, often thin veneers over BSD sockets (e.g., java.net.Socket) CS 3214 Fall 2010 Addressing • For UDP/IP or TCP/IP socket communication, generally need 4 parameters: – – – – Source Identifier (32-bit IP Address) Source Port (16-bit) Destination Identifier (32-bit IP Address) Destination Port (16-bit) • Notice that the relationship of “local” and “remote” (also called “peer”) to source/destination depends on direction of communication • Note: – UDP uses only Destination (IP+Port) for demultiplexing – TCP uses Source + Destination • (quadruple: Src IP, Src Port, Dst IP, Dest Port) CS 3214 Fall 2010 223.1.1.2 Addressing in IP • IP address interfaces, not hosts • Sets of interfaces form subnets 223.1.1.1 223.1.1.4 223.1.1.3 223.1.9.2 223.1.7.1 – Subnets share common prefix • Route to CIDR-ized subnet addresses 223.1.9.1 223.1.8.1 – a.b.c.d/x • Within subnet, reach 223.1.2.1 destination directly 223.1.7.2 223.1.8.2 223.1.2.6 223.1.3.27 223.1.2.2 CS 3214 Fall 2010 223.1.3.1 223.1.3.2 Internet R1 Ethernet LAN 1 60 Machines 191.23.25.193 PPP Link 2 191.23.25.192/30 191.23.25.197 Subnet address: 191.23.25.128/26 Default gateway: 191.23.25.129 R2 191.23.25.194 PPP Link 1 191.23.25.129 191.23.25.196/30 191.23.25.198 R3 Ethernet LAN 2 120 Machines 191.23.25.1 Subnet address: 191.23.25.0/25 Default gateway: 191.23.25.1 CS 3214 Fall 2010 UDP Sockets: Overview socket() socket() connect() bind() (optional) send() recv() acts like acts like sendto() recvfrom() recvfrom() sendto() Client Server CS 3214 Fall 2010 socket(2) int socket(int domain, int type, int protocol) • domain: PF_INET, PF_UNIX, PF_INET6, …. • type: SOCK_DGRAM (for UDP), SOCK_STREAM (for TCP), … • protocol: – 0 for Unspecified (or IPPROTO_UDP or IPPROTO_TCP) • returns integer file descriptor – entirely between process and OS – no network actions involved whatsoever • man pages: ip(7), udp(7), tcp(7), socket(2), socket (7), unix(7) – type “man 2 socket”, “man 7 socket” CS 3214 Fall 2010 bind(2) int bind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen) • sockfd: return by socket() • my_addr: “socket address” • addrlen – length of address (address is variable-sized data structure) • “binds” socket to (local) address specified – This affects network protocol namespace, but no information is transmitted over network – Typically: one socket per port, exception: multicast CS 3214 Fall 2010 How are addresses represented? struct sockaddr { /* GENERIC TYPE, should be “abstract” */ sa_family_t sa_family; /* address family */ char sa_data[14]; /* address data */ }; /* This is the concrete “subtype” for IPv4 */ struct sockaddr_in { sa_family_t sin_family; /* address family: AF_INET */ u_int16_t sin_port; /* port in network byte order */ struct in_addr sin_addr; /* internet address */ }; /* Internet IPv4 address. */ struct in_addr { u_int32_t s_addr; }; /* address in network byte order */ CS 3214 Fall 2010 More on bind(2) • Address specified is the “local” address – Which is destination for receive and source for sends. • sin_addr.s_addr useful for “multi-homed” hosts, otherwise use INADDR_ANY • sin_port may be zero if any port would do – Use getsockname() to retrieve assigned port • s_addr and sin_port are specified in network byte order – This convention holds throughout socket API • getaddrinfo() prepares suitable structs CS 3214 Fall 2010 Common Pitfalls (1) • Network vs. Host Byte order – Network order is big endian, most-significant byte first – Host order may be either big or little: little endian on x86 – Use ntohs(), ntohl(), htons(), htonl() to convert 16-bit (“short”) and 32-bit (“long”) values portably – Never convert addresses/ports in sockaddr_in structures in place • Not as much an issue in languages that hide data representation (e.g., Java) CS 3214 Fall 2010 Common Pitfalls (2) • Pay attention to “length” parameters • Example int getsockname(int s, struct sockaddr *name, socklen_t *namelen); • namelen here is not OUT, its INOUT – aka value-result – You know what socket it is, the OS doesn’t! • Always check return codes! CS 3214 Fall 2010 sendto(2), recvfrom(2) ssize_t sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen); ssize_t recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen); • s, buf, len as in read/write • flags: MSG_OOB, MSG_PEEK – mostly 0 • to/from are of type struct sockaddr_in – These are remote/peer addresses: where did the packet come from, where should it be sent to • NB: fromlen is value-result! CS 3214 Fall 2010 UDP & connect(2) Then what does connect() do??? • No notion of connections in UDP – connect(2) can be used to tell OS “default destination” for future sends • Then can use send(2) and write(2) instead of sendto(2), or can omit the destination address in sendto(2) • What does “ECONNREFUSED” mean for UDP? – Courtesy extended by other nodes which send ICMP packet saying “no one’s listening for UDP packets at the port number you sent it to” – OS relayed this information to UDP application CS 3214 Fall 2010 UDP Demultiplexing S: 10.0.0.2:3045 D: 10.0.0.1:80 socket() Payload sendto(10.0.0.1:80) socket() bind(*, 80) S: S:10.0.0.2:3045 10.0.0.2:??? S: 10.0.0.1:80 10.0.0.2 recvfrom(&from) from:10.0.0.2:3045 S: 10.0.0.3:512 D: 10.0.0.1:80 recvfrom(&from) from:10.0.0.3:512 Payload S: 10.0.0.1:53 recvfrom(&from) from:10.0.0.3:512 10.0.0.1 S: 10.0.0.3:512 bind(*, 53) S: 10.0.0.3:512 D: 10.0.0.1:53 10.0.0.3 Payload CS 3214 Fall 2010 bind(10.0.0.3,512) TCP: Overview RFCs: 793, 1122, 1323, 2018, 2581 • • • • socket door point-to-point: – one sender, one receiver reliable, in-order byte stream: – no “message boundaries” pipelined: – transmission proceeds even while partially unack’ed data send & receive buffers application writes data application reads data TCP send buffer TCP receive buffer • full duplex data: – bi-directional data flow in same connection • connection-oriented: – handshaking (exchange of control msgs) init’s sender, receiver state before data exchange • flow controlled: – sender will not overwhelm socket door receiver segment CS 3214 Fall 2010 TCP Sockets • Provide reliable byte-stream abstraction – In-order, reliable delivery of bytes – Bounded buffer abstraction with flow control • Send may block if receiver application has not drained the buffer • Connection-oriented – Client must connect(2) – Server performs “passive open” using accept(2) CS 3214 Fall 2010 TCP Sockets: Overview socket() listen() socket() connect() accept() bind() write() read() read() write() Left side: client Right side: server connection setup connection shutdown close() close() CS 3214 Fall 2010 connect(2) int connect(int sockfd, const struct sockaddr *peeraddr, int addrlen) • sockfd: returned by socket() • peeraddr: peer’s address (type sockaddr_in) • this call initiates hand-shake with server CS 3214 Fall 2010 listen(2), accept(2) int listen(int s, int backlog) int accept(int s, struct sockaddr *addr, int *addrlen); • addr: accepted peer’s (aka client) address – of type sockaddr_in • listen() must precede accept – No network traffic, but informs OS to start queuing connection requests • accept() returns new socket – But does not assign new port – why not? CS 3214 Fall 2010 TCP Demultiplexing socket() bind(*, 80) listen(5) 10.0.0.1:80 accept() S: 10.0.0.1:80 D: 10.0.0.2:3045 connect(10.0.0.1,80) socket() S: 10.0.0.2:3045 ??? D: 10.0.0.1:80 S: 10.0.0.2:2047 D: 10.0.0.1:80 10.0.0.2 S: 10.0.0.1:80 D: 10.0.0.2:2047 S: 10.0.0.1:80 D: 10.0.0.3:512 10.0.0.1 bind(10.0.0.3,512) S: 10.0.0.3:512 D: 10.0.0.1:80 10.0.0.3 connect(10.0.0.1,80) CS 3214 Fall 2010 Utility Functions Those shown in gray are IPv4 specific and thus deprecated. in_addr_t inet_addr(const char *cp); char *inet_ntoa(struct in_addr in); int gethostname(char *name, size_t len); int getpeername(int s, struct sockaddr *name, socklen_t *namelen); int getsockname(int s, struct sockaddr *name, socklen_t *namelen); int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen); int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen); struct hostent *gethostbyname(const char *name); struct hostent *gethostbyaddr(const char *addr, int len, int type); int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res); void freeaddrinfo(struct addrinfo *res); CS 3214 Fall 2010 struct hostent struct hostent { char *h_name; char **h_aliases; int h_addrtype; int h_length; char **h_addr_list; } Deprecated Use getaddrinfo(3) instead /* official name of host */ /* alias list */ /* host address type */ /* length of address */ /* list of addresses */ Note: IPv4 addresses, *h_addr_list points to array of long (32-bit) Struct hostent *hent = gethostbyname(hostname); If (hent == 0) { herror(hostname); exit(-1); } addr = ((long*)*hent->h_addr_list)[0]; extracts first IP for host. As always, in network order! CS 3214 Fall 2010 Common Pitfalls (3) • What is wrong with this code? struct sockaddr_in server1addr; struct sockaddr_in server2addr; /* not shown: initialize server1addr, server2addr */ printf(“using server 1 at %s and server 2 at %s\n”, inet_ntoa(serveraddr1.sin_addr), inet_ntoa(serveraddr2.sin_addr)); Beware of statically allocated buffers! Don’t use in new code! Use alternatives where available: inet_ntop, getaddrinfo, etc. CS 3214 Fall 2010 Java Binding • Does not expose byte order • gethostbyname()/getaddrinfo() is hidden (use a “String” as a hostname to get default 1st IP address) • Does not expose bind/listen directly • Use different types for different sockets: – DatagramSocket, Socket, ServerSocket • Does not expose universal file descriptor • Hides IPv4/IPv6 behind InetAddress superclass CS 3214 Fall 2010 Protocol Independent Socket Programming • Client + server code should be unaware of which version of IP is used • Use getaddrinfo() to obtain information about suitable address family and addresses – For servers to bind to (IPv4, or IPv6, or both) – For clients to connect to (based on DNS name or specified address notation); based on RFC 3484 ordering • Use getnameinfo() to transform addresses in printable form • See http://www.akkadia.org/drepper/userapiipv6.html for details CS 3214 Fall 2010