int amqp_open_socket(char const *hostname, int portnumber) { int sockfd, res; struct sockaddr_in addr; struct hostent *he; int one = 1; /* used as a buffer by setsockopt below */ res = amqp_socket_init(); if (res) return res; he = gethostbyname(hostname); if (he == NULL) return -ERROR_GETHOSTBYNAME_FAILED; addr.sin_family = AF_INET; addr.sin_port = htons(portnumber); addr.sin_addr.s_addr = * (uint32_t *) he->h_addr_list[0]; sockfd = socket(PF_INET, SOCK_STREAM, 0); if (sockfd == -1) return -amqp_socket_error(); if (amqp_socket_setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one)) < 0 || connect(sockfd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { res = -amqp_socket_error(); amqp_socket_close(sockfd); return res; } return sockfd; }
int amqp_open_socket(char const *hostname, int portnumber) { struct addrinfo hint; struct addrinfo *address_list; struct addrinfo *addr; char portnumber_string[33]; int sockfd = -1; int last_error = 0; int one = 1; /* for setsockopt */ if (0 != (last_error = amqp_socket_init())) return last_error; memset(&hint, 0, sizeof(hint)); hint.ai_family = PF_UNSPEC; /* PF_INET or PF_INET6 */ hint.ai_socktype = SOCK_STREAM; hint.ai_protocol = IPPROTO_TCP; (void)sprintf(portnumber_string, "%d", portnumber); last_error = getaddrinfo(hostname, portnumber_string, &hint, &address_list); if (last_error != 0) { return -ERROR_GETHOSTBYNAME_FAILED; } for (addr = address_list; addr; addr = addr->ai_next) { /* This cast is to squash warnings on Win64, see: http://stackoverflow.com/questions/1953639/is-it-safe-to-cast-socket-to-int-under-win64 */ sockfd = (int)socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); if (-1 == sockfd) { last_error = -amqp_socket_error(); continue; } /* Set SO_RCVTIMEO and SO_SNDTIMEO on socket */ struct timeval timeout; timeout.tv_sec = 2; timeout.tv_usec = 0; if (0 != amqp_socket_setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) ) { last_error = -amqp_socket_error(); amqp_socket_close(sockfd); continue; } if (0 != amqp_socket_setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)) ) { last_error = -amqp_socket_error(); amqp_socket_close(sockfd); continue; } #ifdef DISABLE_SIGPIPE_WITH_SETSOCKOPT if (0 != amqp_socket_setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &one, sizeof(one))) { last_error = -amqp_socket_error(); amqp_socket_close(sockfd); continue; } #endif /* DISABLE_SIGPIPE_WITH_SETSOCKOPT */ if (0 != amqp_socket_setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one)) || 0 != connect(sockfd, addr->ai_addr, addr->ai_addrlen)) { last_error = -amqp_socket_error(); amqp_socket_close(sockfd); continue; } else { last_error = 0; break; } } freeaddrinfo(address_list); if (last_error != 0) { return last_error; } return sockfd; }
int amqp_open_socket(char const *hostname, int portnumber, int timeout) { int sockfd, res; struct sockaddr_in addr; struct hostent *he; int one = 1; /* used as a buffer by setsockopt below */ int orig_flags; res = amqp_socket_init(); if (res) return res; he = gethostbyname(hostname); if (he == NULL) return -ERROR_GETHOSTBYNAME_FAILED; addr.sin_family = AF_INET; addr.sin_port = htons(portnumber); addr.sin_addr.s_addr = * (uint32_t *) he->h_addr_list[0]; sockfd = socket(PF_INET, SOCK_STREAM, 0); if (sockfd == -1) return -amqp_socket_error(); if (timeout > 0) { orig_flags = fcntl(sockfd, F_GETFL,0); res = fcntl(sockfd, F_SETFL, orig_flags | O_NONBLOCK); if (res != 0) { amqp_socket_close(sockfd); return res; } } if (amqp_socket_setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one)) < 0) { res = -amqp_socket_error(); amqp_socket_close(sockfd); return res; } if (timeout <= 0) { if (connect(sockfd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { res = -amqp_socket_error(); amqp_socket_close(sockfd); return res; } return sockfd; } else { int err = 0; while (1) { res = connect(sockfd, (struct sockaddr *) &addr, sizeof(addr)); if (res == 0) { /* success! */ break; } switch(errno) { case EALREADY: case EINPROGRESS: { res = _amqp_poll(sockfd, POLLOUT|POLLIN|POLLHUP|POLLERR, timeout, &err); if (res == AMQP_POLL_SUCCESS) { /* try again */ continue; } /* timeout exceeded or an error occured */ amqp_socket_close(sockfd); goto out_loop; } case EINTR: continue; default: res = errno; amqp_socket_close(sockfd); goto out_loop; } } out_loop: if (res == AMQP_POLL_TIMEOUT) { amqp_socket_close(sockfd); return -ERROR_CONNECTION_TIMED_OUT; } else if (res == AMQP_POLL_FAILURE) { amqp_socket_close(sockfd); return -err | ERROR_CATEGORY_OS; } } if (timeout > 0) { int fd_flags; fd_flags = fcntl(sockfd, F_GETFL,0); res = fcntl(sockfd, F_SETFL, orig_flags); if (res != 0) { amqp_socket_close(sockfd); return res; } } return sockfd; }