X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=sources%2FSockUtil.c;h=af3a3f7c59990b0ff43853efd16ece5dc3549ac0;hp=c861144a5d25480bae7efa4b5fa6758bdd14e95e;hb=b72f6c959549091bc7d5d5a55d8486c446ec2aaf;hpb=5a12d423b85ac5decb966bc3c3a797b3ad9a7a3f diff --git a/sources/SockUtil.c b/sources/SockUtil.c index c861144..af3a3f7 100644 --- a/sources/SockUtil.c +++ b/sources/SockUtil.c @@ -1,4 +1,4 @@ -/* Sockutils.c +/* SockUtil.c * * Copyright (C) 2004 Simone Piccardi * @@ -18,26 +18,22 @@ */ /*************************************************************** * - * File SockUtils.c + * File SockUtil.c * Routines for socket operations. * * Define routines for socket handling * * Author: S. Piccardi * - * $Id$ - * ***************************************************************/ -#include -#include /* standard I/O functions */ -#include -#include -#include -#include -#include -#include -#include -#include +#include /* primitive system data types */ +#include /* standard I/O library */ +#include /* unix standard library */ +#include /* C strings library */ +#include /* error definitions and routines */ +#include /* socket constants, types and functions */ +#include /* IP addresses conversion utilities */ +#include /* C resolver library */ #include "macros.h" /************************************************************************** @@ -50,8 +46,6 @@ * Author: Simone Piccardi * Dec. 2004 * - * $Id$ - * **************************************************************************/ char *ip_ntop(struct addrinfo *addr, char *dst, socklen_t cnt) { @@ -59,12 +53,18 @@ char *ip_ntop(struct addrinfo *addr, char *dst, socklen_t cnt) char * ret; struct sockaddr_in *ip4; struct sockaddr_in6 *ip6; - if (addr->ai_family == PF_INET) { + switch (addr->ai_family) { + case PF_INET: ip4 = (struct sockaddr_in *) addr->ai_addr; ret = inet_ntop(ip4->sin_family, &ip4->sin_addr, dst, cnt); - } else { + break; + case PF_INET6: ip6 = (struct sockaddr_in6 *) addr->ai_addr; ret = inet_ntop(ip6->sin6_family, &ip6->sin6_addr, dst, cnt); + break; + default: + ret = NULL; + errno = EAFNOSUPPORT; } return ret; } @@ -76,8 +76,6 @@ char *ip_ntop(struct addrinfo *addr, char *dst, socklen_t cnt) * Author: Simone Piccardi * Dec. 2004 * - * $Id$ - * ****************************************************************/ int sockconn(char *host, char *serv, int prot, int type) { @@ -86,45 +84,44 @@ int sockconn(char *host, char *serv, int prot, int type) int sock; /* initialize hint structure */ memset(&hint, 0, sizeof(struct addrinfo)); - hint.ai_family = PF_UNSPEC; /* generic address (IPv4 or IPv6) */ - hint.ai_protocol = prot; /* protocol */ - hint.ai_socktype = type; /* socket type */ + hint.ai_family = PF_UNSPEC; /* generic address (IPv4 or IPv6) */ + hint.ai_protocol = prot; /* protocol */ + hint.ai_socktype = type; /* socket type */ res = getaddrinfo(host, serv, &hint, &addr); /* calling getaddrinfo */ if (res != 0) { /* on error exit */ fprintf(stderr, "sockconn: resolution failed:"); // fprintf(stderr, "host %s, service %s, protocol %d", host, serv, prot); fprintf(stderr, " %s\n", gai_strerror(res)); - errno = 0; /* clear errno */ + errno = 0; /* clear errno */ return -1; } - /* loop on possible addresses */ save = addr; - while (addr != NULL) { + while (addr != NULL) { /* loop on possible addresses */ /* get a socket */ sock = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); - if (sock < 0) { - if (addr->ai_next != NULL) { - addr=addr->ai_next; - continue; - } else { + if (sock < 0) { /* on error */ + if (addr->ai_next != NULL) { /* if other addresses */ + addr=addr->ai_next; /* take next */ + continue; /* restart cycle */ + } else { /* else stop */ perror("sockconn: cannot create socket"); return sock; } } /* connect the socket */ if ( (res = connect(sock, addr->ai_addr, addr->ai_addrlen) < 0)) { - if (addr->ai_next != NULL) { - addr=addr->ai_next; - close(sock); - continue; - } else { + if (addr->ai_next != NULL) { /* if other addresses */ + addr=addr->ai_next; /* take next */ + close(sock); /* close socket */ + continue; /* restart cycle */ + } else { /* else stop */ perror("sockconn: cannot connect"); close(sock); return res; } - } else break; + } else break; /* ok, we are connected! */ } - freeaddrinfo(save); /* done, release memory */ + freeaddrinfo(save); /* done, release memory */ return sock; } /**************************************************************** @@ -135,8 +132,6 @@ int sockconn(char *host, char *serv, int prot, int type) * Author: Simone Piccardi * Dec. 2004 * - * $Id$ - * ****************************************************************/ int sockbind(char *host, char *serv, int prot, int type) { @@ -146,47 +141,110 @@ int sockbind(char *host, char *serv, int prot, int type) char buf[INET6_ADDRSTRLEN]; /* initialize hint structure */ memset(&hint, 0, sizeof(struct addrinfo)); - hint.ai_flags = AI_PASSIVE; /* address for binding */ - hint.ai_family = PF_UNSPEC; /* generic address (IPv4 or IPv6) */ - hint.ai_protocol = prot; /* protocol */ - hint.ai_socktype = type; /* socket type */ + hint.ai_flags = AI_PASSIVE; /* address for binding */ + hint.ai_family = PF_UNSPEC; /* generic address (IPv4 or IPv6) */ + hint.ai_protocol = prot; /* protocol */ + hint.ai_socktype = type; /* socket type */ res = getaddrinfo(host, serv, &hint, &addr); /* calling getaddrinfo */ if (res != 0) { /* on error exit */ fprintf(stderr, "sockbind: resolution failed:"); // fprintf(stderr, "host %s, service %s, protocol %d", host, serv, prot); fprintf(stderr, " %s\n", gai_strerror(res)); - errno = 0; /* clear errno */ + errno = 0; /* clear errno */ return -1; } - /* loop on possible addresses */ - save = addr; - while (addr != NULL) { + save = addr; /* saving for freeaddrinfo */ + while (addr != NULL) { /* loop on possible addresses */ /* get a socket */ sock = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); - if (sock < 0) { - if (addr->ai_next != NULL) { - addr=addr->ai_next; - continue; - } else { - perror("sockconn: cannot create socket"); + if (sock < 0) { /* on error */ + if (addr->ai_next != NULL) { /* if other addresses */ + addr=addr->ai_next; /* take next */ + continue; /* restart cycle */ + } else { /* else stop */ + perror("sockbind: cannot create socket"); return sock; } } /* connect the socket */ printf("Indirizzo %s\n", ip_ntop(addr, buf, sizeof(buf))); - ; if ( (res = bind(sock, addr->ai_addr, addr->ai_addrlen)) < 0) { - if (addr->ai_next != NULL) { - addr=addr->ai_next; + if (addr->ai_next != NULL) { /* if other addresses */ + addr=addr->ai_next; /* take next */ + close(sock); /* close socket */ + continue; /* restart cycle */ + } else { /* else stop */ + perror("sockbind: cannot connect"); close(sock); - continue; - } else { - perror("sockconn: cannot connect"); + return res; + } + } else break; /* ok, we are binded! */ + } + freeaddrinfo(save); /* done, release memory */ + return sock; +} +/**************************************************************** + * + * Routine sockbindopt + * Return a binded socket given hostname, service, and socket type + * Issue a SO_REUSEADDR on the socket before binding on reuse value. + * + * Author: Simone Piccardi + * Mar. 2005 + * + ****************************************************************/ +int sockbindopt(char *host, char *serv, int prot, int type, int reuse) +{ + struct addrinfo hint, *addr, *save; + int res; + int sock; + char buf[INET6_ADDRSTRLEN]; + /* initialize hint structure */ + memset(&hint, 0, sizeof(struct addrinfo)); + hint.ai_flags = AI_PASSIVE; /* address for binding */ + hint.ai_family = PF_UNSPEC; /* generic address (IPv4 or IPv6) */ + hint.ai_protocol = prot; /* protocol */ + hint.ai_socktype = type; /* socket type */ + res = getaddrinfo(host, serv, &hint, &addr); /* calling getaddrinfo */ + if (res != 0) { /* on error exit */ + fprintf(stderr, "sockbind: resolution failed:"); +// fprintf(stderr, "host %s, service %s, protocol %d", host, serv, prot); + fprintf(stderr, " %s\n", gai_strerror(res)); + errno = 0; /* clear errno */ + return -1; + } + save = addr; /* saving for freeaddrinfo */ + while (addr != NULL) { /* loop on possible addresses */ + /* get a socket */ + sock = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); + if (sock < 0) { /* on error */ + if (addr->ai_next != NULL) { /* if other addresses */ + addr=addr->ai_next; /* take next */ + continue; /* restart cycle */ + } else { /* else stop */ + perror("sockbind: cannot create socket"); + return sock; + } + } + /* connect the socket */ + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, + &reuse, sizeof(reuse))) { + printf("error on socket options\n"); + return -1; + } + printf("Indirizzo %s\n", ip_ntop(addr, buf, sizeof(buf))); + if ( (res = bind(sock, addr->ai_addr, addr->ai_addrlen)) < 0) { + if (addr->ai_next != NULL) { /* if other addresses */ + addr=addr->ai_next; /* take next */ + close(sock); /* close socket */ + continue; /* restart cycle */ + } else { /* else stop */ + perror("sockbind: cannot connect"); close(sock); return res; } - } else break; + } else break; /* ok, we are binded! */ } - freeaddrinfo(save); /* done, release memory */ + freeaddrinfo(save); /* done, release memory */ return sock; }