360 likes | 724 Views
Socket Options. Ch.7: Socket Options. getsockopt and setsockopt functions Check options and obtain default values Generic socket options IPv4 socket options IPv6 socket options TCP socket options fcntl function Summary. getsockopt and setsockopt Functions. #include <sys/socket.h>
E N D
Ch.7: Socket Options • getsockopt and setsockopt functions • Check options and obtain default values • Generic socket options • IPv4 socket options • IPv6 socket options • TCP socket options • fcntl function • Summary
getsockopt and setsockopt Functions #include <sys/socket.h> int getsockopt (int sockfd, int level, int optname, void *optval, socklen_t *optlen); int setsockopt (int sockfd, int level, int optname, const void *optval, socklen_t optlen); Both return: 0 if OK, -1 if error Types of options: flag and value Levels: Generic -- SOL_SOCKET IP -- IPPROTO_IP ICMPv6 -- IPPROTO_OCMPV6 IPv6 -- IPPROTO_IPV6 TCP -- IPPROTO_TCP
Check Options and Obtain Default Values • Program declaration: • declare union of possible option values • define printing function prototypes • define sock_opt structure, initialize sock_opt[ ] array • Check and print options: • create TCP socket, go through all options • call getsockopt • print option’s default value
Declaration for Socket Options (see figure 7.2) • Program to Check and Print Socket Options (see figure 7.3 and 7.4)
pp. 195 Fig. 7.3 Sockopt/checkopts.c #include "unp.h" #include <netinet/tcp.h> /* for TCP_xxx defines */ union val { int i_val; long l_val; struct linger linger_val; struct timeval timeval_val; } val; static char *sock_str_flag(union val *, int); static char *sock_str_int(union val *, int); static char *sock_str_linger(union val *, int); static char *sock_str_timeval(union val *, int); struct sock_opts { const char *opt_str; int opt_level; int opt_name; char *(*opt_val_str)(union val *, int); } sock_opts[] = { { "SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, sock_str_flag }, { "SO_DEBUG", SOL_SOCKET, SO_DEBUG, sock_str_flag }, { "SO_DONTROUTE", SOL_SOCKET, SO_DONTROUTE, sock_str_flag }, { "SO_ERROR", SOL_SOCKET, SO_ERROR, sock_str_int }, { "SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, sock_str_flag }, { "SO_LINGER", SOL_SOCKET, SO_LINGER, sock_str_linger }, { "SO_OOBINLINE", SOL_SOCKET, SO_OOBINLINE, sock_str_flag }, { "SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, sock_str_int }, { "SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, sock_str_int }, { "SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, sock_str_int }, { "SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, sock_str_int }, { "SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, sock_str_timeval }, { "SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, sock_str_timeval }, { "SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, sock_str_flag } }
pp. 196 Fig. 7.4 Sockopt/checkopts.c main(int argc, char **argv) { int fd; socklen_t len; struct sock_opts *ptr; for (ptr = sock_opts; ptr->opt_str != NULL; ptr++) { printf("%s: ", ptr->opt_str); if (ptr->opt_val_str == NULL) printf("(undefined)\n"); else { switch(ptr->opt_level) { case SOL_SOCKET: case IPPROTO_IP: case IPPROTO_TCP: fd = Socket(AF_INET, SOCK_STREAM, 0); break; #ifdef IPV6 case IPPROTO_IPV6: fd = Socket(AF_INET6, SOCK_STREAM, 0); break; #endif #ifdef IPPROTO_SCTP case IPPROTO_SCTP: fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); break; #endif default: err_quit("Can't create fd for level %d\n", ptr->opt_level); } len = sizeof(val); if (getsockopt(fd, ptr->opt_level, ptr->opt_name, &val, &len) == -1) { err_ret("getsockopt error"); } else { printf("default = %s\n", (*ptr->opt_val_str)(&val, len)); } close(fd);
static char *sock_str_flag(union val *, int);static char *sock_str_int(union val *, int);static char *sock_str_linger(union val *, int);static char *sock_str_timeval(union val *, int); pp. 197 Fig. 7.5 Sockopt/checkopts.c static char strres[128]; static char * sock_str_flag(union val *ptr, int len) { /* *INDENT-OFF* */ if (len != sizeof(int)) snprintf(strres, sizeof(strres), "size (%d) not sizeof(int)", len); else snprintf(strres, sizeof(strres), "%s", (ptr->i_val == 0) ? "off" : "on"); return(strres); /* *INDENT-ON* */ }
Generic Socket Options • SO_BROADCAST: permit sending of broadcast datagram, only on broadcast links • SO_DEBUG: enable debug tracing of packets sent or received by TCP socket, trpt program to examine the kernel circular buffer • SO_DONTROUTE: bypass routing table lookup, used by routing daemons (routed and gated) in case the routing table is incorrect
SO_Error Socket Options • when error occurs on a socket, the protocol module sets a variable named so_error for that socket. • Process can obtain the value of so_error by fetching the SO_ERROR socket option– It call get pending error. • The process can be immediately notified of the error in one of two ways • If the process is blocked in a call to select on the socket • If the process is using signal-driven I/O, the SIGIO signal is generated for either the process or the process group • If so_error is nonzero when the process calls read • If there is no data to return, read returns -1 with errno set to the value of so_error • If there is data queued for the socket, that data is returned • If so_error is nonzero when the process calls write, -1 is returned with errno set to the value of so_error
SO_KEEPALIVE Socket Option • 當任一方超過兩小時未交換資料,TCP會自動 發keepalive probe給對方 • 如果對方TCP回應ack,應用程式不受任何影響。 • 如果對方回應RST,此socket close且 so_error = ECONNRESET • 如果對方沒回應,so_error = ETIMEOUT • 如收到ICMP unreachable, so_error = EHOSTUNREACH
SO-LINGER Socket Options • •SO_LINGER: • Specify how the close function operates for a connection-oriented protocol • default, close returns immediately, but if there is any data still remaining in the socket send buffer, the system will try to deliver the data to the peer • linger on TCP close if data in socket send buffer, linger structure passed Default: l_onoff = 0 close returns immediately
Default operation of close:it returns immediately client server write data Data queued by TCP Close close returns FIN Ack of data and FIN Application reads queued data and FIN close FIN Ack of data and FIN
When l_onoff = 0 Data雖已送出,但不確定 對方是否收到
When l_onoff = 1 Andl_linger = 0 • TCP discards any data still remaining in the socket send buffer, and sends an RST to the peer • Not the normal four-packet connection termination sequence • This avoids TCP’s TIME_WAIT state, which may cause problems.
An Alternative: Call shutdown followed by a read waits until receive the peer’s FINInstead of close
Another Alternative: UsingApplication-Level Acknowledgement char ack; Write(sockfd, data, nbytes); n = Read(sockfd, &ack, 1); client server nbytes = Read(sockfd, buff, sizeof(buff)); /* server 確定已收妥全部資料*/ Write(sockfd, “”, 1);
Generic Socket Options (Cont.) • SO_OOBINLINE: leave received out-of-band data inline in the normal input queue • SO_RCVBUF/SO_SNDBUF: socket receive / send buffer size, TCP default: 8192-61440, UDP default: 40000/9000 • SO_RCVLOWAT/ SO_SNDLOWAT: receive / send buffer low water mark for select to return
Generic Socket Options (Cont.) • SO_RCVTIMEO/SO_SNDTIMEO: receive / send timeout for socket read/write • SO_REUSEADDR/SO_REUSEPORT: allow local address reuse for TCP server restart, IP alias, UDP duplicate binding for multicasting • SO_TYPE: get socket type, SOCK_STREAM or SOCK_DGRAM • SO_USELOOPBACK: applies only to routing socket; gets copy of what it sends
815Generic Socket Options (Cont.)•SO_RCVTIMEO/SO_SNDTIMEO: receive / sendtimeout for socket read/write•SO_REUSEADDR/SO_REUSEPORT: allow localaddress reuse for TCP server restart, IP alias,UDP duplicate binding for multicasting•SO_TYPE: get socket type, SOCK_STREAM orSOCK_DGRAM•SO_USELOOPBACK: applies only to routingsocket; gets copy of what it sends16IPv4 Socket Options • •IP_HDRINCL: If set, we must build our own IP header for all the datagrams that we send on the raw socket. • Normally the kernel builds the IP header • e.g. traceroute builds own IP header on a raw socket
IPv4 Socket Options (Cont.) • IP_OPTIONS: specify socket options like source route, timestamp, record route, etc. • IP_RECVSTADDR: return destination IP address of a received UDP datagram by recvmsg (Ch. 8) • IP_RECVIF: return received interface index for a received UDP datagram by recvmsg
IP Socket Options (Cont.) type of service • IP_TOS: set IP TOS field of outgoing packets for TCP/UDP socket, TOS: IPTOS_LOWDELAY / THROUGHPUT, RELIABILITY / LOWCOST • IP_TTL: set and fetch the default TTL for outgoing packets, 64 for TCP/UDP sockets, 255 for raw sockets, used in traceroute • IP_MULTICAST_IF, IP_MULTICAST_TTL, IP_MULTICAST_LOOP,IP_ADD_MEMBERSHIPIPI IP_DROP_MEMBERSHIP (Sec. 19.5)
IPv6 Socket Options • ICMP6_FILTER: fetch and set icmp6_filter structure specifying message types to pass • IPV6_ADDFORM: change address format of socket between IPv4 and IPv6 • IPV6_CHECKSUM: offset of checksum field for raw socket • IPV6_DSTOPTS: return destination options of received datagram by recvmsg • IPV6_HOPLIMIT: return hop limit of received datagrams by recvmsg
IPv6 Socket Options (Cont.) • IPV6_HOPOPS: return hop-by-hop options of received datagrams by recvmsg • IPV6_NEXTHOP: specify next hop address as a socket address structure for a datagram • IPV6_PKTINFO: return packet info, dest • IPv6 address and arriving interface, of
IPv6 Socket Options (Cont.) • IPV6_PKTOPTIONS: specify socket options of TCP socket (UDP uses recvmsg and sendmsg) • IPV6_RTHDR: receive routing header (source route) • IPV6_UNICAST_HOPS: ~ IP_TTL • IPV6_MULTICAST_IF/HOPS/LOOP, IPV6_ADD/DROP_MEMBERSHIP (Sec. 19.5)
TCP Socket Options • TCP_KEEPALIVE: seconds between probes • TCP_MAXRT: TCP max retx time • TCP_MAXSEG: TCP max segment size • TCP_NODELAY: disable Nagle algorithm, to reduce the number of small packets • TCP_STDURG: interpretation of TCP’s urgent pointer, used with out-of-band data
fcntl Function Two flags that affect a socket: (fetch by F_GETFL, set by F_SETFL) O_NONBLOCK (nonblocking I/O) O_ASYNC (signal-driven I/O notification) To set a flag : fetch OR/AND~ set
fcntl Function (Cont.) • Two signals, SIGIO and SIGURG, are sent to the socket owner (process ID or process group ID) only if the socket is assigned an owner by F_SETOWN command. • fcntl commands to set or get socket owner: F_SETOWN, F_GETOWN
Summary • Commonly used socket options: SO_KEEPALIVE, SO_RCVBUF, SO_SNDBUF, SO_REUSEADDR • SO_REUSEADDR set in TCP server before calling bind • SO_LINGER gives more control over when close returns and forces RST to be sent • SO_RCVBUF/SO_SNDBUF for bulk data transfer across long fat pipes