diff --git a/.github/workflows/configure_make_check.yml b/.github/workflows/configure_make_check.yml index 84ab579..2dbd6d5 100644 --- a/.github/workflows/configure_make_check.yml +++ b/.github/workflows/configure_make_check.yml @@ -27,7 +27,7 @@ jobs: # Dependencies: #------------------------------------ - name: Checkout libbsat - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: 'andrew-canaday/libbsat' path: 'libbsat' @@ -50,7 +50,7 @@ jobs: # Checkout, configure, make, run tests, and make dist for libyimmo: #-------------------------------------------------------------------- - name: Checkout libyimmo - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: ${{ github.repository }} path: 'libyimmo' diff --git a/.github/workflows/create_release_on_tag.yml b/.github/workflows/create_release_on_tag.yml index 94b67f5..04fd135 100644 --- a/.github/workflows/create_release_on_tag.yml +++ b/.github/workflows/create_release_on_tag.yml @@ -31,7 +31,7 @@ jobs: # Dependencies: #------------------------------------ - name: Checkout libbsat - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: 'andrew-canaday/libbsat' path: 'libbsat' @@ -57,7 +57,7 @@ jobs: # - signing #-------------------------------------------------------------------- - name: Checkout libyimmo - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 repository: ${{ github.repository }} diff --git a/.github/workflows/server-tests.yml b/.github/workflows/server-tests.yml index 0671e1e..ddea30d 100644 --- a/.github/workflows/server-tests.yml +++ b/.github/workflows/server-tests.yml @@ -17,7 +17,7 @@ jobs: IMAGE_NAME: "ghcr.io/${{ github.repository }}-ci:${{ github.ref_name }}" steps: - name: Checkout libyimmo - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: ${{ github.repository }} path: 'libyimmo' @@ -64,7 +64,7 @@ jobs: IMAGE_NAME: "ghcr.io/${{ github.repository }}-ci:${{ github.ref_name }}" steps: - name: Checkout libyimmo - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: ${{ github.repository }} path: 'libyimmo' @@ -140,7 +140,7 @@ jobs: IMAGE_NAME: "ghcr.io/${{ github.repository }}-ci:${{ github.ref_name }}" steps: - name: Checkout libyimmo - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: ${{ github.repository }} path: 'libyimmo' @@ -191,7 +191,7 @@ jobs: IMAGE_NAME: "ghcr.io/${{ github.repository }}-ci:${{ github.ref_name }}" steps: - name: Checkout libyimmo - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: ${{ github.repository }} path: 'libyimmo' @@ -262,7 +262,7 @@ jobs: IMAGE_NAME: "ghcr.io/${{ github.repository }}-ci:${{ github.ref_name }}" steps: - name: Checkout libyimmo - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: ${{ github.repository }} path: 'libyimmo' diff --git a/.github/workflows/valgrind.yml b/.github/workflows/valgrind.yml index cc388f1..01d5e88 100644 --- a/.github/workflows/valgrind.yml +++ b/.github/workflows/valgrind.yml @@ -31,7 +31,7 @@ jobs: # Dependencies: #------------------------------------ - name: Checkout libbsat - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: 'andrew-canaday/libbsat' path: 'libbsat' @@ -54,7 +54,7 @@ jobs: # Build libyimmo: #-------------------------------------------------------------------- - name: Checkout libyimmo - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: ${{ github.repository }} path: 'libyimmo' diff --git a/src/core/ymo_conn.c b/src/core/ymo_conn.c index bbc2c5b..270226c 100644 --- a/src/core/ymo_conn.c +++ b/src/core/ymo_conn.c @@ -26,12 +26,6 @@ #include #include -#if YMO_ENABLE_TLS -#include -#include -#include -#endif /* YMO_ENABLE_TLS */ - #include "yimmo.h" #include "ymo_log.h" #include "ymo_conn.h" @@ -210,53 +204,7 @@ ymo_status_t ymo_conn_send_buckets( #if !(YMO_ENABLE_TLS) return ymo_net_send_buckets(conn->fd, head_p); #else - /* HACK HACK HACK HACK - * TODO: add ymo_net_send_tls or similar to ymo_net. - */ - ymo_status_t status = YMO_OKAY; - - if( !conn->ssl ) { - return ymo_net_send_buckets(conn->fd, head_p); - } - - ymo_bucket_t* cur = *head_p; - size_t bytes_sent = 0; - - do { - int send_rc = SSL_write_ex(conn->ssl, - (const char*)(cur->data + cur->bytes_sent), - cur->len - cur->bytes_sent, - &bytes_sent); - - if( send_rc > 0 ) { - cur->bytes_sent += bytes_sent; - - if( cur->bytes_sent < cur->len ) { - status = EAGAIN; - break; - } - ymo_bucket_t* done = cur; - cur = cur->next; - ymo_bucket_free(done); - } else { - int ssl_err = SSL_get_error(conn->ssl, send_rc); - if( YMO_SSL_WANT_RW(ssl_err) ) { - ymo_log_debug("SSL buffering on write to %i", conn->fd); - status = EAGAIN; - break; - } else { - ymo_log_debug( - "SSL write for connection on fd %i " - "failed error code %i: (%s)", - conn->fd, ssl_err, ERR_reason_error_string(ssl_err)); - status = ECONNABORTED; - break; - } - } - } while( cur ); - - *head_p = cur; - return status; + return ymo_net_send_buckets_tls(conn->ssl, conn->fd, head_p); #endif /* YMO_ENABLE_TLS */ } diff --git a/src/core/ymo_net.c b/src/core/ymo_net.c index 9412ca9..46dae7e 100644 --- a/src/core/ymo_net.c +++ b/src/core/ymo_net.c @@ -33,6 +33,13 @@ #include #endif /* HAVE_DECL_SENDFILE */ +#if YMO_ENABLE_TLS +#include +#include +#include +#endif /* YMO_ENABLE_TLS */ + + #include "yimmo.h" #include "ymo_util.h" #include "ymo_log.h" @@ -164,6 +171,59 @@ ymo_status_t ymo_net_send_buckets(int fd, ymo_bucket_t** head_p) } +#if YMO_ENABLE_TLS +/** Send buckets over the wire using TLS. */ +ymo_status_t ymo_net_send_buckets_tls(SSL* ssl, int fd, ymo_bucket_t** head) +{ + ymo_status_t status = YMO_OKAY; + + if( !ssl ) { + return ymo_net_send_buckets(fd, head); + } + + ymo_bucket_t* cur = *head; + size_t bytes_sent = 0; + + do { + int send_rc = SSL_write_ex(ssl, + (const char*)(cur->data + cur->bytes_sent), + cur->len - cur->bytes_sent, + &bytes_sent); + + if( send_rc > 0 ) { + cur->bytes_sent += bytes_sent; + + if( cur->bytes_sent < cur->len ) { + status = EAGAIN; + break; + } + ymo_bucket_t* done = cur; + cur = cur->next; + ymo_bucket_free(done); + } else { + int ssl_err = SSL_get_error(ssl, send_rc); + if( YMO_SSL_WANT_RW(ssl_err) ) { + ymo_log_debug("SSL buffering on write to %i", fd); + status = EAGAIN; + break; + } else { + ymo_log_debug( + "SSL write for connection on fd %i " + "failed error code %i: (%s)", + fd, ssl_err, ERR_reason_error_string(ssl_err)); + status = ECONNABORTED; + break; + } + } + } while( cur ); + + *head = cur; + return status; +} + + +#endif /* YMO_ENABLE_TLS */ + #if YMO_BUCKET_FROM_FILE == YMO_BUCKET_SENDFILE static ymo_status_t ymo_net_bucket_sendfile(int fd, ymo_bucket_t** head_p) { diff --git a/src/core/ymo_net.h b/src/core/ymo_net.h index f5d7a01..adc5199 100644 --- a/src/core/ymo_net.h +++ b/src/core/ymo_net.h @@ -39,6 +39,11 @@ #include #endif /* HAVE_SYS_IOCTL_H */ +#if YMO_ENABLE_TLS +#include +#endif /* YMO_ENABLE_TLS */ + + #include "yimmo.h" #include "ymo_log.h" #include "ymo_bucket.h" @@ -115,6 +120,13 @@ */ ymo_status_t ymo_net_send_buckets(int fd, ymo_bucket_t** head); +#if YMO_ENABLE_TLS +/** Send a bucket chain over the socket given by ``fd``. + */ +ymo_status_t ymo_net_send_buckets_tls(SSL* ssl, int fd, ymo_bucket_t** head); +#endif /* YMO_ENABLE_TLS */ + + /**--------------------------------------------------------------- * Socket Trait Functions *---------------------------------------------------------------*/ diff --git a/src/core/ymo_queue.c b/src/core/ymo_queue.c index dcd6564..b1da4cc 100644 --- a/src/core/ymo_queue.c +++ b/src/core/ymo_queue.c @@ -279,9 +279,7 @@ const ymo_queue_node_t* ymo_queue_tail(ymo_queue_t* queue) } -/** Remove an item from the queue: - * TODO: clean up branching - **/ +/** Remove an item from the queue: */ ymo_status_t ymo_queue_remove(ymo_queue_t* queue, ymo_queue_node_t** node_ptr) { ymo_queue_node_t* node = *node_ptr; diff --git a/src/protocol/http/test/test_hdr_table.c b/src/protocol/http/test/test_hdr_table.c index ec81ecb..2a83b95 100644 --- a/src/protocol/http/test/test_hdr_table.c +++ b/src/protocol/http/test/test_hdr_table.c @@ -429,7 +429,11 @@ static int test_collisions() } } - ymo_log_debug("Total collisions: %zu\n", no_collisions); + ymo_log_debug("Total collisions: %zu over the following %zu headers", + no_collisions, no_hdrs); + for( size_t i = 0; i < no_hdrs; i++ ) { + ymo_log_debug(" ✅ %s (%i)", LOTS_OF_HEADERS[i], hdr_ids[i]); + } ymo_assert(no_collisions == 0); YMO_TAP_PASS(__func__); } diff --git a/src/protocol/http/ymo_http_hdr_table.c b/src/protocol/http/ymo_http_hdr_table.c index d78780d..47f3524 100644 --- a/src/protocol/http/ymo_http_hdr_table.c +++ b/src/protocol/http/ymo_http_hdr_table.c @@ -86,11 +86,17 @@ ymo_http_hdr_id_t ymo_http_hdr_hash( } -#endif /* HAVE_FUNC_ATTRIBUTE_WEAK */ +__attribute__((YMO_FUNC_PURE_P weak)) +int ymo_http_hdr_cmp( + ymo_http_hdr_table_node_t* current, + const char*hdr, + ymo_http_hdr_id_t h_id) +{ + return current->h_id == h_id; +} -/* TODO: allow override for this too / optional strcmp, at least! */ -#define YMO_HTTP_HDR_CMP(current, hdr, h_id) \ - current->h_id == h_id + +#endif /* HAVE_FUNC_ATTRIBUTE_WEAK */ ymo_http_hdr_table_t* ymo_http_hdr_table_create() { @@ -350,8 +356,11 @@ const char* ymo_http_hdr_table_get_id( ymo_http_hdr_id_t index = h_id % YMO_HDR_TABLE_BUCKET_SIZE; ymo_http_hdr_table_node_t* current = table->bucket[index]; while( current ) { - /* TODO: compare strings to ensure it's not just hash collision. */ - if( YMO_HTTP_HDR_CMP(current, hdr, h_id) ) { + /* TODO: compare strings to ensure it's not just hash collision. + * + * NOTE: this means we probably need to pass in the const char* anyway. + */ + if( YMO_HTTP_HDR_CMP(current, NULL, h_id) ) { if( !current->buffer ) { data = current->value; } else { diff --git a/src/protocol/http/ymo_http_hdr_table.h b/src/protocol/http/ymo_http_hdr_table.h index a4afc73..65bffe4 100644 --- a/src/protocol/http/ymo_http_hdr_table.h +++ b/src/protocol/http/ymo_http_hdr_table.h @@ -46,13 +46,22 @@ # define YMO_HDR_HASH_CH ymo_http_hdr_hash_ch # define YMO_HTTP_HDR_HASH_INIT ymo_http_hdr_hash_init -/** Default hash function used by header table. - * - */ +/** Default hash initialization function used by header table. */ YMO_FUNC_PURE ymo_http_hdr_id_t ymo_http_hdr_hash_init(void); + +/** Default string hash function used by header table. */ YMO_FUNC_PURE ymo_http_hdr_id_t ymo_http_hdr_hash(const char* str_in, size_t* len); + +/** Default char hash function used by header table (i.e. given a hash and a + * character, compute the updated hash). */ YMO_FUNC_PURE ymo_http_hdr_id_t ymo_http_hdr_hash_ch(ymo_http_hdr_id_t h, char c); +/** Default hash item comparison function used by header table. */ +YMO_FUNC_PURE_P int ymo_http_hdr_cmp( + ymo_http_hdr_table_node_t* current, + const char*hdr, + ymo_http_hdr_id_t h_id); + #else /*---------------------------------------------------------------------------* @@ -60,17 +69,30 @@ YMO_FUNC_PURE ymo_http_hdr_id_t ymo_http_hdr_hash_ch(ymo_http_hdr_id_t h, char c *--------------------------------------------------------------------------*/ # define YMO_HTTP_HDR_HASH_OVERRIDE_METHOD "preproc" # ifndef YMO_HDR_HASH_FN +/** Hash function definition used to override hash function in the absence + * of weak linking facilities. + */ # define YMO_HDR_HASH_FN ymo_http_hdr_hash_283_5 # endif /* YMO_HDR_HASH_FN */ # ifndef YMO_HDR_HASH_CH +/** Char hash function used by header table (i.e. given a hash and a + * character, compute the updated hash) used in the absence of weak links. */ # define YMO_HDR_HASH_CH(h,c) ((h*283) + (c & 0xdf)) # endif /* YMO_HDR_HASH_CH */ # ifndef YMO_HTTP_HDR_HASH_INIT +/** Default hash initialization function used by header table in the absence + * of weak links. */ # define YMO_HTTP_HDR_HASH_INIT() 5 # endif /* YMO_HTTP_HDR_HASH_INIT */ +/** Default hash item comparison function used by header table used when weak + * links are not available.*/ +# ifndef YMO_HTTP_HDR_CMP +# define YMO_HTTP_HDR_CMP ymo_http_hdr_cmp +# endif /* YMO_HTTP_HDR_CMP */ + __attribute__((YMO_FUNC_PURE_P, YMO_FUNC_UNUSED_A)) static inline ymo_http_hdr_id_t ymo_http_hdr_hash_283_5( const char* str_in, size_t* len) @@ -89,6 +111,16 @@ static inline ymo_http_hdr_id_t ymo_http_hdr_hash_283_5( } +__attribute__((YMO_FUNC_PURE_P, YMO_FUNC_UNUSED_A)) +static inline int ymo_http_hdr_cmp( + ymo_http_hdr_table_node_t* current, + const char*hdr, + ymo_http_hdr_id_t h_id) +{ + return current->h_id == h_id; +} + + #endif /* HAVE_FUNC_ATTRIBUTE_WEAK && YMO_HTTP_HDR_HASH_ALLOW_WEAK */ diff --git a/uncrustify.cfg b/uncrustify.cfg index c0fc073..bfca06a 100644 --- a/uncrustify.cfg +++ b/uncrustify.cfg @@ -1,4 +1,4 @@ -# Uncrustify-0.72.0_f +# Uncrustify-0.77.1_f 2024/06/09 # # General options