From e53dfcbdbed04cad690823ce5def521fea7b5483 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 12 Mar 2018 15:28:33 +0100 Subject: 4s timeout when connecting to server; send error to client on failure --- client.c | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) (limited to 'client.c') diff --git a/client.c b/client.c index 2fbc560..41cda25 100644 --- a/client.c +++ b/client.c @@ -13,7 +13,7 @@ #define MAX_SEND_BUFFER 150000 static void client_haveIn(epoll_client_t *client); -static void client_haveOut(epoll_client_t *client); +static BOOL client_haveOut(epoll_client_t *client); void client_free(epoll_client_t *client) { @@ -38,7 +38,9 @@ void client_callback(void *data, int haveIn, int haveOut, int doCleanup) if (client->ssl == NULL) { // Plain connection if (haveIn) client_haveIn(client); - if (haveOut) client_haveOut(client); + if (haveOut || client->kill) { + if (client_haveOut(client)) return; + } if (client->kill) { //printf("Client gone (2).\n"); client_free(client); @@ -57,7 +59,7 @@ void client_callback(void *data, int haveIn, int haveOut, int doCleanup) } // Since we don't know if the incoming data is just wrapped application data or ssl protocol stuff, we always call both client_haveIn(client); - client_haveOut(client); + if (client_haveOut(client)) return; if (client->kill) { //printf("Client gone (3).\n"); client_free(client); @@ -127,9 +129,15 @@ static void client_haveIn(epoll_client_t *client) } } -static void client_haveOut(epoll_client_t *client) +/** + * Send any queued data. + * Returns TRUE if anything has been sent, or the socket + * buffer is currently full (EAGAIN, non-blocking mode) + */ +static BOOL client_haveOut(epoll_client_t *client) { client->writeBlocked = FALSE; + if (client->sbPos >= client->sbFill) return FALSE; while (client->sbPos < client->sbFill) { const int tosend = client->sbFill - client->sbPos; ssize_t ret; @@ -137,11 +145,11 @@ static void client_haveOut(epoll_client_t *client) // Plain ret = write(client->fd, client->sendBuffer + client->sbPos, tosend); if (ret < 0 && errno == EINTR) continue; - if (ret < 0 && errno == EAGAIN) return; + if (ret < 0 && errno == EAGAIN) return TRUE; if (ret <= 0) { printf("[Proxy] Cannot send to client (ret=%d, errno=%d)\n", (int)ret, errno); client->kill = TRUE; - return; + return FALSE; } } else { // SSL @@ -150,12 +158,12 @@ static void client_haveOut(epoll_client_t *client) int err = SSL_get_error(client->ssl, ret); if (SSL_BLOCKED(err)) { client->writeBlocked = TRUE; - return; // Blocking + return TRUE; // Blocking } printf("[Proxy] SSL cannot send to client (ret=%d, err=%d)\n", (int)ret, err); ERR_print_errors_fp(stdout); client->kill = TRUE; - return; // Closed + return FALSE; // Closed } } client->sbPos += ret; @@ -164,12 +172,13 @@ static void client_haveOut(epoll_client_t *client) client->sbFill -= client->sbPos; client->sbPos = 0; } - if (client->ssl == NULL && ret != tosend) return; // Sent less than requested -> buffer full, epoll will trigger us again + if (client->ssl == NULL && ret != tosend) return TRUE; // Sent less than requested -> buffer full, epoll will trigger us again } client->sbPos = client->sbFill = 0; if (client->ssl == NULL && client->sbLen > MAX_SEND_BUFFER / 2) { helper_realloc(&client->sendBuffer, &client->sbLen, 8000, "client_haveOut"); } + return TRUE; } BOOL client_send(epoll_client_t *client, const char *buffer, size_t len, const BOOL cork) @@ -221,3 +230,12 @@ BOOL client_send(epoll_client_t *client, const char *buffer, size_t len, const B return TRUE; } +BOOL client_searchResultError(epoll_client_t *client, const unsigned long messageId, const int code, const char *message) +{ + const size_t doneLen = fmt_ldapsearchresultdone(NULL, code, "", message, ""); + const size_t doneHeaderLen = fmt_ldapmessage(NULL, messageId, SearchResultDone, doneLen); + char buffer[doneLen + doneHeaderLen]; + fmt_ldapsearchresultdone(buffer + doneHeaderLen, code, "", message, ""); + fmt_ldapmessage(buffer, messageId, SearchResultDone, doneLen); + return client_send(client, buffer, doneHeaderLen + doneLen, FALSE); +} -- cgit v1.2.3-55-g7522