Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Just use raw close() for discard #70

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions contrib/ruby/test/client_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,18 @@ def test_close_terminate_parent_connection
assert_match "TRILOGY_CLOSED_CONNECTION", error.message
end

def test_discard_closes_connection
client = new_tcp_client

assert_equal [1], client.query("SELECT 1").to_a.first

client.discard!

assert_raises Trilogy::ConnectionClosed do
client.query("SELECT 1")
end
end

def test_discard_doesnt_terminate_parent_connection
skip("Fork isn't supported on this platform") unless Process.respond_to?(:fork)

Expand Down
2 changes: 2 additions & 0 deletions inc/trilogy/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ typedef struct trilogy_sock_t {
int (*wait_cb)(struct trilogy_sock_t *self, trilogy_wait_t wait);
int (*shutdown_cb)(struct trilogy_sock_t *self);
int (*close_cb)(struct trilogy_sock_t *self);
int (*discard_cb)(struct trilogy_sock_t *self);
int (*fd_cb)(struct trilogy_sock_t *self);

trilogy_sockopt_t opts;
Expand All @@ -102,6 +103,7 @@ static inline int trilogy_sock_wait_write(trilogy_sock_t *sock) { return sock->w
static inline int trilogy_sock_shutdown(trilogy_sock_t *sock) { return sock->shutdown_cb(sock); }

static inline int trilogy_sock_close(trilogy_sock_t *sock) { return sock->close_cb(sock); }
static inline int trilogy_sock_discard(trilogy_sock_t *sock) { return sock->discard_cb(sock); }

static inline int trilogy_sock_fd(trilogy_sock_t *sock) { return sock->fd_cb(sock); }

Expand Down
1 change: 1 addition & 0 deletions src/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -768,6 +768,7 @@ int trilogy_discard(trilogy_conn_t *conn)
{
int rc = trilogy_sock_discard(conn->socket);
if (rc == TRILOGY_OK) {
conn->socket = NULL;
trilogy_free(conn);
}
return rc;
Expand Down
41 changes: 16 additions & 25 deletions src/socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ static int _cb_raw_close(trilogy_sock_t *_sock)
return rc;
}

// Close and discard are the same for a raw socket
#define _cb_raw_discard _cb_raw_close

static int _cb_raw_shutdown(trilogy_sock_t *_sock) { return shutdown(trilogy_sock_fd(_sock), SHUT_RDWR); }

static int set_nonblocking_fd(int sock)
Expand Down Expand Up @@ -235,6 +238,7 @@ trilogy_sock_t *trilogy_sock_new(const trilogy_sockopt_t *opts)
sock->base.wait_cb = _cb_wait;
sock->base.shutdown_cb = _cb_raw_shutdown;
sock->base.close_cb = _cb_raw_close;
sock->base.discard_cb = _cb_raw_discard;
sock->base.fd_cb = _cb_raw_fd;
sock->base.opts = *opts;

Expand Down Expand Up @@ -347,6 +351,7 @@ static int _cb_ssl_shutdown(trilogy_sock_t *_sock)
sock->base.write_cb = _cb_raw_write;
sock->base.shutdown_cb = _cb_raw_shutdown;
sock->base.close_cb = _cb_raw_close;
sock->base.discard_cb = _cb_raw_discard;
sock->ssl = NULL;

return _cb_raw_shutdown(_sock);
Expand All @@ -363,6 +368,16 @@ static int _cb_ssl_close(trilogy_sock_t *_sock)
return _cb_raw_close(_sock);
}

static int _cb_ssl_discard(trilogy_sock_t *_sock) {
struct trilogy_sock *sock = (struct trilogy_sock *)_sock;
if (sock->ssl != NULL) {
// unlike close, we do not want to send SSL_shutdown
SSL_free(sock->ssl);
sock->ssl = NULL;
}
return _cb_raw_close(_sock);
}

#if OPENSSL_VERSION_NUMBER >= 0x1010000fL

static int trilogy_tls_version_map[] = {0, TLS1_VERSION, TLS1_1_VERSION, TLS1_2_VERSION
Expand Down Expand Up @@ -614,35 +629,11 @@ int trilogy_sock_upgrade_ssl(trilogy_sock_t *_sock)
sock->base.write_cb = _cb_ssl_write;
sock->base.shutdown_cb = _cb_ssl_shutdown;
sock->base.close_cb = _cb_ssl_close;
sock->base.discard_cb = _cb_ssl_discard;
return TRILOGY_OK;

fail:
SSL_free(sock->ssl);
sock->ssl = NULL;
return TRILOGY_OPENSSL_ERR;
}

int trilogy_sock_discard(trilogy_sock_t *_sock)
{
struct trilogy_sock *sock = (struct trilogy_sock *)_sock;

if (sock->fd < 0) {
return TRILOGY_OK;
}

int null_fd = open("/dev/null", O_RDWR | O_CLOEXEC);
if (null_fd < 0) {
return TRILOGY_SYSERR;
}

if (dup2(null_fd, sock->fd) < 0) {
close(null_fd);
return TRILOGY_SYSERR;
}

if (close(null_fd) < 0) {
return TRILOGY_SYSERR;
}

return TRILOGY_OK;
}