char *basic_get(amqp_connection_state_t connection_state_, const char *queue_name_, uint64_t *out_body_size_) { amqp_rpc_reply_t rpc_reply; amqp_time_t deadline; struct timeval timeout = { 5, 0 }; int time_rc = amqp_time_from_now(&deadline, &timeout); assert(time_rc == AMQP_STATUS_OK); do { rpc_reply = amqp_basic_get(connection_state_, fixed_channel_id, amqp_cstring_bytes(queue_name_), /*no_ack*/ 1); } while (rpc_reply.reply_type == AMQP_RESPONSE_NORMAL && rpc_reply.reply.id == AMQP_BASIC_GET_EMPTY_METHOD && amqp_time_has_past(deadline) == AMQP_STATUS_OK); assert(rpc_reply.reply_type == AMQP_RESPONSE_NORMAL); assert(rpc_reply.reply.id == AMQP_BASIC_GET_OK_METHOD); amqp_message_t message; rpc_reply = amqp_read_message(connection_state_, fixed_channel_id, &message, 0); assert(rpc_reply.reply_type == AMQP_RESPONSE_NORMAL); char *body = malloc(message.body.len); memcpy(body, message.body.bytes, message.body.len); *out_body_size_ = message.body.len; amqp_destroy_message(&message); return body; }
static int amqp_ssl_socket_open(void *base, const char *host, int port, struct timeval *timeout) { struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base; long result; int status; amqp_time_t deadline; X509 *cert; BIO *bio; if (-1 != self->sockfd) { return AMQP_STATUS_SOCKET_INUSE; } ERR_clear_error(); self->ssl = SSL_new(self->ctx); if (!self->ssl) { self->internal_error = ERR_peek_error(); status = AMQP_STATUS_SSL_ERROR; goto exit; } status = amqp_time_from_now(&deadline, timeout); if (AMQP_STATUS_OK != status) { return status; } self->sockfd = amqp_open_socket_inner(host, port, deadline); if (0 > self->sockfd) { status = self->sockfd; self->internal_error = amqp_os_socket_error(); self->sockfd = -1; goto error_out1; } bio = BIO_new(amqp_openssl_bio()); if (!bio) { status = AMQP_STATUS_NO_MEMORY; goto error_out2; } BIO_set_fd(bio, self->sockfd, BIO_NOCLOSE); SSL_set_bio(self->ssl, bio, bio); start_connect: status = SSL_connect(self->ssl); if (status != 1) { self->internal_error = SSL_get_error(self->ssl, status); switch (self->internal_error) { case SSL_ERROR_WANT_READ: status = amqp_poll(self->sockfd, AMQP_SF_POLLIN, deadline); break; case SSL_ERROR_WANT_WRITE: status = amqp_poll(self->sockfd, AMQP_SF_POLLOUT, deadline); break; default: status = AMQP_STATUS_SSL_CONNECTION_FAILED; } if (AMQP_STATUS_OK == status) { goto start_connect; } goto error_out2; } cert = SSL_get_peer_certificate(self->ssl); if (self->verify_peer) { if (!cert) { self->internal_error = 0; status = AMQP_STATUS_SSL_PEER_VERIFY_FAILED; goto error_out3; } result = SSL_get_verify_result(self->ssl); if (X509_V_OK != result) { self->internal_error = result; status = AMQP_STATUS_SSL_PEER_VERIFY_FAILED; goto error_out4; } } if (self->verify_hostname) { if (!cert) { self->internal_error = 0; status = AMQP_STATUS_SSL_HOSTNAME_VERIFY_FAILED; goto error_out3; } if (AMQP_HVR_MATCH_FOUND != amqp_ssl_validate_hostname(host, cert)) { self->internal_error = 0; status = AMQP_STATUS_SSL_HOSTNAME_VERIFY_FAILED; goto error_out4; } } X509_free(cert); self->internal_error = 0; status = AMQP_STATUS_OK; exit: return status; error_out4: X509_free(cert); error_out3: SSL_shutdown(self->ssl); error_out2: amqp_os_socket_close(self->sockfd); self->sockfd = -1; error_out1: SSL_free(self->ssl); self->ssl = NULL; goto exit; }