Merge pull request #142 from astiob/select-bugs

Fix several bugs in sslh-select
This commit is contained in:
yrutschle 2017-12-16 19:51:23 +01:00 committed by GitHub
commit 7808a3a766
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 18 additions and 12 deletions

View File

@ -6,6 +6,7 @@
#define SYSLOG_NAMES #define SYSLOG_NAMES
#define _GNU_SOURCE #define _GNU_SOURCE
#include <stddef.h>
#include <stdarg.h> #include <stdarg.h>
#include <grp.h> #include <grp.h>
@ -283,17 +284,19 @@ int connect_addr(struct connection *cnx, int fd_from)
int defer_write(struct queue *q, void* data, int data_size) int defer_write(struct queue *q, void* data, int data_size)
{ {
char *p; char *p;
ptrdiff_t data_offset = q->deferred_data - q->begin_deferred_data;
if (verbose) if (verbose)
fprintf(stderr, "**** writing deferred on fd %d\n", q->fd); fprintf(stderr, "**** writing deferred on fd %d\n", q->fd);
p = realloc(q->begin_deferred_data, q->deferred_data_size + data_size); p = realloc(q->begin_deferred_data, data_offset + q->deferred_data_size + data_size);
if (!p) { if (!p) {
perror("realloc"); perror("realloc");
exit(1); exit(1);
} }
q->deferred_data = q->begin_deferred_data = p; q->begin_deferred_data = p;
p += q->deferred_data_size; q->deferred_data = p + data_offset;
p += data_offset + q->deferred_data_size;
q->deferred_data_size += data_size; q->deferred_data_size += data_size;
memcpy(p, data, data_size); memcpy(p, data, data_size);

View File

@ -61,9 +61,9 @@ int tidy_connection(struct connection *cnx, fd_set *fds, fd_set *fds2)
if (verbose) if (verbose)
fprintf(stderr, "closing fd %d\n", cnx->q[i].fd); fprintf(stderr, "closing fd %d\n", cnx->q[i].fd);
close(cnx->q[i].fd);
FD_CLR(cnx->q[i].fd, fds); FD_CLR(cnx->q[i].fd, fds);
FD_CLR(cnx->q[i].fd, fds2); FD_CLR(cnx->q[i].fd, fds2);
close(cnx->q[i].fd);
if (cnx->q[i].deferred_data) if (cnx->q[i].deferred_data)
free(cnx->q[i].deferred_data); free(cnx->q[i].deferred_data);
} }
@ -93,11 +93,16 @@ int accept_new_connection(int listen_socket, struct connection *cnx[], int* cnx_
in_socket = accept(listen_socket, 0, 0); in_socket = accept(listen_socket, 0, 0);
CHECK_RES_RETURN(in_socket, "accept"); CHECK_RES_RETURN(in_socket, "accept");
if (!fd_is_in_range(in_socket)) if (!fd_is_in_range(in_socket)) {
close(in_socket);
return -1; return -1;
}
res = set_nonblock(in_socket); res = set_nonblock(in_socket);
if (res == -1) return -1; if (res == -1) {
close(in_socket);
return -1;
}
/* Find an empty slot */ /* Find an empty slot */
for (free = 0; (free < *cnx_size) && ((*cnx)[free].q[0].fd != -1); free++) { for (free = 0; (free < *cnx_size) && ((*cnx)[free].q[0].fd != -1); free++) {
@ -109,6 +114,7 @@ int accept_new_connection(int listen_socket, struct connection *cnx[], int* cnx_
new = realloc(*cnx, (*cnx_size + cnx_num_alloc) * sizeof((*cnx)[0])); new = realloc(*cnx, (*cnx_size + cnx_num_alloc) * sizeof((*cnx)[0]));
if (!new) { if (!new) {
log_message(LOG_ERR, "unable to realloc -- dropping connection\n"); log_message(LOG_ERR, "unable to realloc -- dropping connection\n");
close(in_socket);
return -1; return -1;
} }
*cnx = new; *cnx = new;
@ -140,9 +146,9 @@ int connect_queue(struct connection *cnx, fd_set *fds_r, fd_set *fds_w)
flush_deferred(q); flush_deferred(q);
if (q->deferred_data) { if (q->deferred_data) {
FD_SET(q->fd, fds_w); FD_SET(q->fd, fds_w);
} else { FD_CLR(cnx->q[0].fd, fds_r);
FD_SET(q->fd, fds_r);
} }
FD_SET(q->fd, fds_r);
return q->fd; return q->fd;
} else { } else {
tidy_connection(cnx, fds_r, fds_w); tidy_connection(cnx, fds_r, fds_w);
@ -248,15 +254,12 @@ void main_loop(int listen_sockets[], int num_addr_listen)
for (i = 0; i < num_addr_listen; i++) { for (i = 0; i < num_addr_listen; i++) {
if (FD_ISSET(listen_sockets[i], &readfds)) { if (FD_ISSET(listen_sockets[i], &readfds)) {
in_socket = accept_new_connection(listen_sockets[i], &cnx, &num_cnx); in_socket = accept_new_connection(listen_sockets[i], &cnx, &num_cnx);
if (in_socket != -1)
num_probing++;
if (in_socket > 0) { if (in_socket > 0) {
num_probing++;
FD_SET(in_socket, &fds_r); FD_SET(in_socket, &fds_r);
if (in_socket >= max_fd) if (in_socket >= max_fd)
max_fd = in_socket + 1;; max_fd = in_socket + 1;;
} }
FD_CLR(listen_sockets[i], &readfds);
} }
} }