50
Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len; /* length of structure (16) */ sa_family_t sin_family; /* AF_INET */ in_port_t sin_port; /* 16-bit TCP/UDP port number */ /* network byte ordered */ struct in_addr sin_addr; /* 32-bit IPv4 address */ /*network byte ordered*/ char sin_zero[8]; /* unused */ }; data structure – not exchanged between <netinet/in.h>

Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

Embed Size (px)

Citation preview

Page 1: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

Ipv4 Socket Address Structure

struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */

/* network byte ordered */ };

struct sockaddr_in { uint8_t sin_len; /* length of structure (16) */ sa_family_t sin_family; /* AF_INET */ in_port_t sin_port; /* 16-bit TCP/UDP port number

*/ /* network byte ordered */ struct in_addr sin_addr; /* 32-bit IPv4 address */

/*network byte ordered*/ char sin_zero[8]; /* unused */ };

data structure – not exchanged between hosts<netinet/in.h>

Page 2: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */

/* network byte ordered */ };

struct sockaddr_in { uint8_t sin_len; /* length of structure (16) */ sa_family_t sin_family; /* AF_INET */ in_port_t sin_port; /* 16-bit TCP/UDP port number

*/ /* network byte ordered */ struct in_addr sin_addr; /* 32-bit IPv4 address */

/*network byte ordered*/ char sin_zero[8]; /* unused */ };

Generic Socket Address Structure Passed as reference Prior to void definition

Page 3: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

Generic Socket Address Structure

int bind(int, struct sockaddr *, sock_len_t);

Page 4: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

Ipv6 Socket Address Structure

struct in6_addr { uint8_t s6_addr[16]; /* 128-bit IPv6 address */

/* network byte ordered */ };

#define SIN6_LEN /* required for compile-time tests */

struct sockaddr_in6 { uint8_t sin6_len; /* length of this struct (28) */ sa_family_t sin6_family; /* AF_INET6 */ in_port_t sin6_port; /* transport layer port# */

/* network byte ordered */ uint32_t sin6_flowinfo; /* flow information, undefined */ struct in6_addr sin6_addr; /* IPv6 address */

/* network byte ordered */ uint32_t sin6_scope_id; /* set of interfaces for a scope */ };

Page 5: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

Value-Results arguments bind, connect, sento

Page 6: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

Value-Result arguments Kernel to the process, size can change accept, recvfrom, getsockname,

getpeername

Fixed size data structure Kernel informs how

much information was

stored

Page 7: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

Socket Address Structures

Page 8: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

Byte ordering functions

Page 9: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

Internet Protocols

Network byte order → big-endian TCP Port: 16 bits Ipv4 address: 32 bits

# include <netinet/in.h>uint16_t htons(uint16_t host16bitvalue) ;uint32_t htonl(uint32_t host32bitvalue) ;

Both return: value in network byte order

uint16_t ntohs(uint16_t net16bitvalue) ;uint32_t ntohl(uint32_t net32bitvalue) ;

Both return: value in host byte order

Page 10: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

Byte manipulation function

Operates on multibyte fileds, without interpreting the data, and without asuming that the data is a null-terminated C string

bzero, bcopy, bcmp memset, memcpy, memcmp

Page 11: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

Address convertion function

Converts an ASCII string into network byte ordered binary values

#include <arpa/inet.h>

int inet_aton(const char *strptr, struct in_addr *addrptr);Returns: 1 if string was valid, 0 on error

in_addr_t inet_addr(const char *strptr);Returns: 32-bit binary network byte ordered IPv4 address;

INADDR_NONE if error

char *inet_ntoa(struct in_addr inaddr);Returns: pointer to dotted-decimal string

Page 12: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

Address convertion function

Page 13: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

read, write

It may read/write less than needed due to finite buffer → call function

Only if write is nonblocking

Page 14: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

read, writelib/readn.c 1 #include "unp.h" 2 ssize_t /* Read "n" bytes from a descriptor. */ 3 readn(int fd, void *vptr, size_t n) 4 { 5 size_t nleft; 6 ssize_t nread; 7 char *ptr; 8 ptr = vptr; 9 nleft = n; 10 while (nleft > 0) { 11 if ( (nread = read(fd, ptr, nleft)) < 0) { 12 if (errno == EINTR) 13 nread = 0; /* and call read() again */ 14 else 15 return (-1); 16 } else if (nread == 0) 17 break; /* EOF */ 18 nleft -= nread; 19 ptr += nread; 20 } 21 return (n - nleft); /* return >= 0 */ 22 }

Page 15: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

read, writelib/writen.c1 #include "unp.h" 2 ssize_t /* Write "n" bytes to a descriptor. */ 3 writen(int fd, const void *vptr, size_t n) 4 { 5 size_t nleft; 6 ssize_t nwritten; 7 const char *ptr; 8 ptr = vptr; 9 nleft = n; 10 while (nleft > 0) { 11 if ( (nwritten = write(fd, ptr, nleft)) <= 0) { 12 if (nwritten < 0 && errno == EINTR) 13 nwritten = 0; /* and call write() again */ 14 else 15 return (-1); /* error */ 16 } 17 nleft -= nwritten; 18 ptr += nwritten; 19 } 20 return (n); 21 }

Page 16: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

read, write1 # include "unp.h" 2 static int read_cnt; 3 static char *read_ptr; 4 static char read_buf[MAXLINE]; 5 static ssize_t 6 my_read(int fd, char *ptr) 7 { 8 if (read_cnt <= 0) { 9 again: 10 if ( (read_cnt = read(fd, read_buf, sizeof(read_buf))) < 0) { 11 if (errno == EINTR) 12 goto again; 13 return (-1); 14 } else if (read_cnt == 0) 15 return (0); 16 read_ptr = read_buf; 17 } 18 read_cnt--; 19 *ptr = *read_ptr++; 20 return (1); 21 }

Page 17: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

22 ssize_t 23 readline(int fd, void *vptr, size_t maxlen) 24 { 25 ssize_t n, rc; 26 char c, *ptr; 27 ptr = vptr; 28 for (n = 1; n < maxlen; n++) { 29 if ( (rc = my_read(fd, &c)) == 1) { 30 *ptr++ = c; 31 if (c == '\n') 32 break; /* newline is stored, like fgets() */ 33 } else if (rc == 0) { 34 *ptr = 0; 35 return (n - 1); /* EOF, n - 1 bytes were read */ 36 } else 37 return (-1); /* error, errno set by read() */ 38 } 39 *ptr = 0; /* null terminate like fgets() */ 40 return (n); 41 } 42 ssize_t 43 readlinebuf(void **vptrptr) 44 { 45 if (read_cnt) 46 *vptrptr = read_ptr; 47 return (read_cnt); 48 }

read, write

Page 18: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

isfdtype It checks whether the descriptor is a socket

descriptor

Page 19: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

Socket functions for elementary TCP client-server

Page 20: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

The socket API

Function socket

int socket ( int family, int type, int protocol) return > 0 if OK, -1 if error

Returns socket descriptor (small positive integer), similar to UNIX file descriptor, to be used perform functions on the socket such as read, write and close

Page 21: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

socket

#include <sys/socket.h>

int socket (int family, int type, int protocol);Returns: non-negative descriptor if OK, -1 on error

Page 22: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

Socket Function

Parameters:

family: specifies the protocol family:

AF_INET – for IPv4

AF_INET6 – for IPv6

AF_UNIX ou AF_LOCAL - Unix domain socket

type: specifies transport protocol:

SOCK_STREAM: stream socket for TCP

SOCK_DGRAM: datagram socket for UDP

protocol: usually set to zero

Page 23: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

Combination of interest

Family Type

AF_INET SOCK_STREAM SOCK_DGRAM

AF_UNIX SOCK_STREAM SOCK_DGRAM

Exemple: sockfd = socket(AF_INET, SOCK_STREAM, 0),

creates an IPv4 socket to be used by TCP

socket Function

Page 24: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

int connect ( int sockfd, const struct sockaddr *servaddr, int addrlen)

return 0 if OK, -1 if error, Used for establishing a connection:three-way

handshake sockfd: return parameter of socket() servaddr: data structure initiated with remote socket

identifications (remote IP address, remote port number) For a client TCP, it is not necessary to perform bind: the

kernel chooses the local port ephemeral port number and the source IP number if necessary

Chosen in a way to avoid conflict of use of port number

Connect Function

Page 25: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

connect

errors timeout – erro ETIMEDOUT, 75 seconds,

configurable If the answer to a SYN segment is an RST one

– error ECONNREFUSED – no process listening to the port

Destination unreachable (ICMP), soft error, tries for 75 seconds (4.4 BSD)

#include <sys/socket.h>

int connect(int sockfd, const struct sockaddr *servaddr, socklen_t addrlen);Returns: 0 if OK, -1 on error

Page 26: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

int bind(int sockfd, (struct sockaddr)* myaddr, int socklen)

return 0 if OK, -1 if error

bind a local protocol address given by the structure myaddr to a socket (sockfd)

The application can let the kernel chooses the IP address and the port number;

Bind Function

Page 27: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

If a host has more than one IP, then the kernel can choose one

Ephemeral port numbers are chosen to avoid conflict with other socket

To let the kernel chooses the IP address the constant INADDR_ANY should be assigned to the IP address myaddr

To let the kernel chooses an ephemeral port number the constant zero should be set to the corresponding field of myaddr:*myaddr.sin_port = 0;*myaddr.sin_addr.s_addr = INADDR_ANY

Page 28: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

bind

Bind performed by TCP server restricts the socket to receiving incoming client connection destined only to that IP address

#include <sys/socket.h>

int bind (int sockfd, const struct sockaddr *myaddr, socklen_t addrlen);Returns: 0 if OK, -1 on error

Page 29: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

bind

No cliente, kernel faz o bind com o endereço IP da interface

Page 30: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

Listen Function

An active (client) socket is one that called connect com o socket, starting a 3-way handshake with a remote host;

An applications (server) which calls listen, makes an unconnected socket a passive one meaning that the kernel must accept incoming connection requests directed to this socket.

CLOSED → LISTEN

Clients call connect while servers call listen followed by accept The backlog parameter indicates the total size of two queues: the complete queue

(ESTABLISHED state) and the incomplete connection queue (SYN_RVCD state)

int listen (int sockfd, (struct sockaddr) * myaddr, int backlog)

return 0 if OK, -1 if error

Page 31: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

listen

Page 32: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

listen

Page 33: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

listen

Page 34: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

listen

Page 35: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

accept Function

Called by a TCP server to return the next completed connection from the front of the completed connection queue. If the queue is empty the process is oput to sleep

int accept (int sockfd, (struct sockaddr) * cliaddr, int * socklen)

returns nonnegative descriptor if OK, -1 if error

aadrlen is a value-result argument and it returns the size of the structure pointed to by cliaddr, i.e., the number of bytes stored by the kernel in the socket address structure.

Page 36: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

fork - exec

Fork is called once but it returns twice. The return value tell the process whether it is a parent or a child

It returns once to the calling process (parent) with a return value that is the process ID of the newly created process (child)

It returns once in the child, with a return value of zero (0) All the descriptors opened by the parent before the fork

are shared with the child after the fork. connected sockts aer an accept and a fork is shared with

the Two uses of fork: a process makes a copy of itself (fork)

and a process executes another program (fork e exec)

# include <unistd.h>pid_t fork(void);

Returns: 0 in child, process ID of child in parent, -1 on error

Page 37: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

fork - exec

#include <unistd.h>

int execl (const char *pathname, const char *arg0, ... /* (char *) 0 */ );

int execv (const char *pathname, char *const argv[ ]);

int execle (const char *pathname, const char *arg0, .../* (char *) 0, char *const envp[ ] */ );

int execve (const char *pathname, char *const argv[ ], char *const envp[ ]);

int execlp (const char *filename, const char *arg0, ... /* (char *) 0 */ );

int execvp (const char *filename, char *const argv[ ]);

All six return: -1 on error, no return on success

Page 38: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

fork - exec

Page 39: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

Concurrent server

Concurrent server (iterative server) – one server, several connections. Concurrent server serves several active connections.

Server performers a fork to create a child to handle the client request

After accept, the server calls fork and the child serves the client (on connfd, the connected socket) and the parent waits for another connection (on listenfd, the listening socket)

Page 40: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

Concurrent server

Connect returns a brand new socket descriptor for the connection to be established with the TCP client.

The return of a connect makes a socket a connected socket.

On closing a socket only the specific connection (socket) is closed, the server remains listening to new socket connection request

Page 41: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

Concurrent server

A close performed by the server does not imply in terminating the connection, a FYN is sent only when the number of reference to the descriptor in the file table is zero – when a child is created the number of reference is incremented by one.

If a server does not close the socket none of the children connections will be closed since the number of reference will never be zero and server runs out of descriptor

Page 42: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

Concurrent server

pid_t pid; int listenfd, connfd;

listenfd = Socket( ... ); /* fill in sockaddr_in{ } with server's well-known port */

Bind(listenfd, ... ); Listen(listenfd, LISTENQ);

for ( ; ; ) { connfd = Accept (listenfd, ... ); /* probably blocks */

if( (pid = Fork()) == 0) { Close(listenfd); /* child closes listening socket */ doit(connfd); /* process the request */ Close(connfd); /* done with this client */ exit(0); /* child terminates */

}

Close(connfd); /* parent closes connected socket */ }

Page 43: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

Concurrent server

Page 44: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

Concurrent server

Page 45: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

Concurrent server

Page 46: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

close

SHUTDOWN used instead to force the termination of a connection

#include <unistd.h>

int close (int sockfd);Returns: 0 if OK, -1 on error

Page 47: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

getsockname and getpeername

Returns the protocol address either local or remote

usos: connect not followed by bind After calling bind with 0 srgument TCP server performs a bind in a wildcard port

#include <sys/socket.h>

int getsockname(int sockfd, struct sockaddr *localaddr, socklen_t *addrlen);

int getpeername(int sockfd, struct sockaddr *peeraddr, socklen_t *addrlen);Returns: 0 if OK, -1 on error

Page 48: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

getsocketname and getpeername

lib/sockfd_to_family.c1 #include "unp.h" 2 int 3 sockfd_to_family(int sockfd) 4 { 5 struct sockaddr_storage ss; 6 socklen_t len; 7 len = sizeof(ss); 8 if (getsockname(sockfd, (SA *) &ss, &len) < 0) 9 return (-1); 10 return (ss.ss_family); 11 }

Page 49: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

TCP ports and concurrent servers

multihomed – one-or-any any-wildcard

Page 50: Ipv4 Socket Address Structure struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */ /* network byte ordered */ }; struct sockaddr_in { uint8_t sin_len;

TCP ports and concurrent servers