SOCKET os_socket_tcp_connect(CHAR *host, USHORT port, BOOL nonblocking) { SOCKADDR_IN target; SOCKET s; HOSTENT *hostinfo; CHAR *ip; s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if(inet_addr(host) == INADDR_NONE) { hostinfo = gethostbyname(host); if(hostinfo) { ip = inet_ntoa (*(struct in_addr *)*hostinfo->h_addr_list); } else { ip = "0.0.0.0"; } } else { ip = host; } target.sin_family = AF_INET; target.sin_addr.s_addr = inet_addr(ip); target.sin_port = htons(port); os_socket_set_nonblocking(s, nonblocking); if(connect(s,(struct sockaddr *)&target,sizeof(target)) != 0 && !nonblocking) { //Has Error! dprintf("[os_socket_tcp_connect] FAIL to connect %s:%d\r\n", ip, port); closesocket(s); return 0; } else { //dprintf("[os_socket_tcp_connect] succeed to connect %s:%d\r\n", ip, port); return s; } }
/** *Creates a nonblocking IPv6 socket *@param sin sockaddr_in6 struct. Used for bind(2). *@return the FD of the socket or -1 on error. */ int os_getsocket6(const char *if_name, uint16_t port, int bufspace, union olsr_sockaddr *bindto) { struct sockaddr_in6 sin6; int on; int sock = socket(AF_INET6, SOCK_DGRAM, 0); if (sock < 0) { OLSR_ERROR(LOG_NETWORKING, "Cannot open socket for OLSR PDUs (%s)\n", strerror(errno)); olsr_exit(EXIT_FAILURE); } #ifdef IPV6_V6ONLY on = 1; if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0) { OLSR_WARN(LOG_NETWORKING, "Cannot set socket for OLSR PDUs to ipv6 only (%s)\n", strerror(errno)); } #endif //#ifdef SO_BROADCAST /* if (setsockopt(sock, SOL_SOCKET, SO_MULTICAST, &on, sizeof(on)) < 0) { perror("setsockopt"); syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m"); close(sock); return (-1); } */ //#endif #ifdef SO_RCVBUF if(bufspace > 0) { for (on = bufspace;; on -= 1024) { if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &on, sizeof(on)) == 0) { OLSR_DEBUG(LOG_NETWORKING, "Set socket buffer space to %d\n", on); break; } if (on <= 8 * 1024) { OLSR_WARN(LOG_NETWORKING, "Could not set a socket buffer space for OLSR PDUs (%s)\n", strerror(errno)); break; } } } #endif on = 1; if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) { OLSR_ERROR(LOG_NETWORKING, "Cannot reuse address for socket for OLSR PDUs (%s)\n", strerror(errno)); close(sock); olsr_exit(EXIT_FAILURE); } /* * we are abusing "on" here. The value is 1 which is our intended * hop limit value. */ if (setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &on, sizeof(on)) < 0) { OLSR_ERROR(LOG_NETWORKING, "Cannot set multicast hops to 1 for socket for OLSR PDUs (%s)\n", strerror(errno)); close(sock); olsr_exit(EXIT_FAILURE); } /* * WHEN USING KERNEL 2.6 THIS MUST HAPPEN PRIOR TO THE PORT BINDING!!!! */ /* Bind to device */ if (bind_socket_to_device(sock, if_name) < 0) { OLSR_ERROR(LOG_NETWORKING, "Cannot bind socket for OLSR PDUs to interface %s: %s (%d)\n", if_name, strerror(errno), errno); close(sock); olsr_exit(EXIT_FAILURE); } if (bindto == NULL) { memset(&sin6, 0, sizeof(sin6)); sin6.sin6_family = AF_INET6; sin6.sin6_port = htons(port); bindto = (union olsr_sockaddr *)&sin6; } if (bind(sock, &bindto->std, sizeof(*bindto)) < 0) { OLSR_ERROR(LOG_NETWORKING, "Cannot bind socket for OLSR PDUs (%s)\n", strerror(errno)); close(sock); olsr_exit(EXIT_FAILURE); } os_socket_set_nonblocking(sock); return sock; }
/** *Creates a nonblocking broadcast socket. *@param sa sockaddr struct. Used for bind(2). *@return the FD of the socket or -1 on error. */ int os_getsocket4(const char *if_name, uint16_t port, int bufspace, union olsr_sockaddr *bindto) { struct sockaddr_in sin4; int on; int sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) { OLSR_ERROR(LOG_NETWORKING, "Cannot open socket for OLSR PDUs (%s)\n", strerror(errno)); olsr_exit(EXIT_FAILURE); } on = 1; #ifdef SO_BROADCAST if (bindto) { if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0) { OLSR_ERROR(LOG_NETWORKING, "Cannot set socket for OLSR PDUs to broadcast mode (%s)\n", strerror(errno)); close(sock); olsr_exit(EXIT_FAILURE); } } #endif if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) { OLSR_ERROR(LOG_NETWORKING, "Cannot reuse address for OLSR PDUs (%s)\n", strerror(errno)); close(sock); olsr_exit(EXIT_FAILURE); } #ifdef SO_RCVBUF if(bufspace > 0) { for (on = bufspace;; on -= 1024) { if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &on, sizeof(on)) == 0) { OLSR_DEBUG(LOG_NETWORKING, "Set socket buffer space to %d\n", on); break; } if (on <= 8 * 1024) { OLSR_WARN(LOG_NETWORKING, "Could not set a socket buffer space for OLSR PDUs (%s)\n", strerror(errno)); break; } } } #endif /* * WHEN USING KERNEL 2.6 THIS MUST HAPPEN PRIOR TO THE PORT BINDING!!!! */ /* Bind to device */ if (bind_socket_to_device(sock, if_name) < 0) { OLSR_ERROR(LOG_NETWORKING, "Cannot bind socket for OLSR PDUs to interface %s: %s (%d)\n", if_name, strerror(errno), errno); close(sock); olsr_exit(EXIT_FAILURE); } if (bindto == NULL) { memset(&sin4, 0, sizeof(sin4)); sin4.sin_family = AF_INET; sin4.sin_port = htons(port); sin4.sin_addr.s_addr = 0; bindto = (union olsr_sockaddr *)&sin4; } if (bind(sock, &bindto->std, sizeof(*bindto)) < 0) { #if !defined(REMOVE_LOG_ERROR) struct ipaddr_str buf; #endif OLSR_ERROR(LOG_NETWORKING, "Could not bind socket for OLSR PDUs to %s/%d: %s (%d)\n", inet_ntop(AF_INET, &sin4.sin_addr, buf.buf, sizeof(buf)), port, strerror(errno), errno); close(sock); olsr_exit(EXIT_FAILURE); } os_socket_set_nonblocking(sock); return sock; }