-/* Sockutils.c
+/* SockUtil.c
*
* Copyright (C) 2004 Simone Piccardi
*
*/
/***************************************************************
*
- * File SockUtils.c
+ * File SockUtil.c
* Routines for socket operations.
*
* Define routines for socket handling
*
* Author: S. Piccardi
*
- * $Id$
- *
***************************************************************/
-#include <sys/types.h>
-#include <stdio.h> /* standard I/O functions */
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <arpa/inet.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>
+#include <sys/types.h> /* primitive system data types */
+#include <stdio.h> /* standard I/O library */
+#include <unistd.h> /* unix standard library */
+#include <string.h> /* C strings library */
+#include <errno.h> /* error definitions and routines */
+#include <sys/socket.h> /* socket constants, types and functions */
+#include <arpa/inet.h> /* IP addresses conversion utilities */
+#include <netdb.h> /* C resolver library */
#include "macros.h"
/**************************************************************************
* Author: Simone Piccardi
* Dec. 2004
*
- * $Id$
- *
**************************************************************************/
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)
{
* Author: Simone Piccardi
* Dec. 2004
*
- * $Id$
- *
****************************************************************/
int sockbind(char *host, char *serv, int prot, int type)
{
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; /* ok, we are binded! */
+ }
+ freeaddrinfo(save); /* done, release memory */
+ return sock;
+}