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_destroy_connection(amqp_connection_state_t state) { int s = state->sockfd; empty_amqp_pool(&state->frame_pool); empty_amqp_pool(&state->decoding_pool); free(state->outbound_buffer.bytes); free(state->sock_inbound_buffer.bytes); free(state); if (s >= 0 && amqp_socket_close(s) < 0) return -amqp_socket_error(); else return 0; }
int amqp_destroy_connection(amqp_connection_state_t state) { int status = AMQP_STATUS_OK; if (state) { int i; for (i = 0; i < POOL_TABLE_SIZE; ++i) { amqp_pool_table_entry_t *entry = state->pool_table[i]; while (NULL != entry) { amqp_pool_table_entry_t *todelete = entry; empty_amqp_pool(&entry->pool); entry = entry->next; free(todelete); } } free(state->outbound_buffer.bytes); free(state->sock_inbound_buffer.bytes); status = amqp_socket_close(state->socket); free(state); } return status; }
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; }
void amqp_set_socket(amqp_connection_state_t state, amqp_socket_t *socket) { amqp_socket_close(state->socket); state->socket = socket; }
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; }