From: Alan T. DeKok Date: Sun, 3 Jun 2018 17:30:31 +0000 (-0400) Subject: add "written" argument to app_io->write X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=deeba765179422371504aeaaeff1319b835dbfa6;p=thirdparty%2Ffreeradius-server.git add "written" argument to app_io->write so that we can do partial writes in the network code, instead of relying on every application to re-implement it --- diff --git a/src/lib/io/io.h b/src/lib/io/io.h index 8a1141f351a..bfdd2fd139a 100644 --- a/src/lib/io/io.h +++ b/src/lib/io/io.h @@ -211,21 +211,27 @@ typedef ssize_t (*fr_io_data_read_t)(void *instance, void **packet_ctx, fr_time_ * write packets to the transport context. The data may or may not * go out to the network right away. * - * If the writer returns LESS THAN buffer_len, that's a special case - * saying "I took saved the data, but the socket wasn't ready, so you - * need to call me again at a later point". + * If the write function does a partial write, it should return a + * value smaller than buffer_len to indicate this. The network + * functions will then pass that value to a subsequent write call, in + * the "written" argument. + * + * The reason for this odd API is that read/write should be writing + * *packets*, not raw streams of bytes. This API allows the "buffer" + * parameter to always contain a full packet. * * @param[in] instance the context for this function * @param[in] packet_ctx Request specific data. * @param[in] request_time when the original request was received * @param[in] buffer the buffer where the raw packet will be written from * @param[in] buffer_len the length of the buffer + * @param[in] written total number of bytes written in previous calls for this packet. * @return * - <0 on error * - >=0 length of the data read or written. */ typedef ssize_t (*fr_io_data_write_t)(void *instance, void *packet_ctx, fr_time_t request_time, - uint8_t *buffer, size_t buffer_len); + uint8_t *buffer, size_t buffer_len, size_t written); /** Inject data into a socket. * diff --git a/src/lib/io/master.c b/src/lib/io/master.c index 724a3f97e61..89764fb5745 100644 --- a/src/lib/io/master.c +++ b/src/lib/io/master.c @@ -1807,8 +1807,8 @@ static void packet_expiry_timer(fr_event_list_t *el, struct timeval *now, void * } } -static ssize_t mod_write(void *instance, void *packet_ctx, - fr_time_t request_time, uint8_t *buffer, size_t buffer_len) +static ssize_t mod_write(void *instance, void *packet_ctx, fr_time_t request_time, + uint8_t *buffer, size_t buffer_len, size_t written) { fr_io_instance_t *inst; fr_io_connection_t *connection; @@ -1871,7 +1871,7 @@ static ssize_t mod_write(void *instance, void *packet_ctx, */ packet_len = inst->app_io->write(app_io_instance, track, request_time, - buffer, buffer_len); + buffer, buffer_len, written); if (packet_len > 0) { rad_assert(buffer_len == (size_t) packet_len); MEM(track->reply = talloc_memdup(track, buffer, buffer_len)); diff --git a/src/lib/io/network.c b/src/lib/io/network.c index 83569a55572..b955749b387 100644 --- a/src/lib/io/network.c +++ b/src/lib/io/network.c @@ -600,7 +600,8 @@ static void fr_network_write(UNUSED fr_event_list_t *el, UNUSED int sockfd, UNUS rad_assert(listen == cd->listen); rcode = listen->app_io->write(listen->app_io_instance, cd->packet_ctx, - cd->reply.request_time, cd->m.data, cd->m.data_size); + cd->reply.request_time, + cd->m.data, cd->m.data_size, 0); if (rcode < 0) { /* @@ -1198,7 +1199,8 @@ static void fr_network_post_event(UNUSED fr_event_list_t *el, UNUSED struct time * that NAKs are not written to the network. */ rcode = listen->app_io->write(listen->app_io_instance, cd->packet_ctx, - cd->reply.request_time, cd->m.data, cd->m.data_size); + cd->reply.request_time, + cd->m.data, cd->m.data_size, 0); if (rcode < 0) { if (errno == EWOULDBLOCK) { if (fr_event_fd_insert(nr, nr->el, s->fd, diff --git a/src/modules/proto_control/proto_control_tcp.c b/src/modules/proto_control/proto_control_tcp.c index 73e3e2001b9..9fc157b9dfa 100644 --- a/src/modules/proto_control/proto_control_tcp.c +++ b/src/modules/proto_control/proto_control_tcp.c @@ -149,8 +149,8 @@ static ssize_t mod_read(void *instance, UNUSED void **packet_ctx, fr_time_t **re } -static ssize_t mod_write(void *instance, void *packet_ctx, - UNUSED fr_time_t request_time, uint8_t *buffer, size_t buffer_len) +static ssize_t mod_write(void *instance, void *packet_ctx, UNUSED fr_time_t request_time, + uint8_t *buffer, size_t buffer_len, UNUSED size_t written) { proto_control_tcp_t *inst = talloc_get_type_abort(instance, proto_control_tcp_t); fr_io_track_t *track = talloc_get_type_abort(packet_ctx, fr_io_track_t); diff --git a/src/modules/proto_detail/proto_detail_file.c b/src/modules/proto_detail/proto_detail_file.c index 2767f1b0d3b..616d949e2ec 100644 --- a/src/modules/proto_detail/proto_detail_file.c +++ b/src/modules/proto_detail/proto_detail_file.c @@ -83,12 +83,12 @@ static int mod_decode(void const *instance, REQUEST *request, uint8_t *const dat return inst->parent->work_io->decode(inst->parent->work_io_instance, request, data, data_len); } -static ssize_t mod_write(void *instance, void *packet_ctx, - fr_time_t request_time, uint8_t *buffer, size_t buffer_len) +static ssize_t mod_write(void *instance, void *packet_ctx, fr_time_t request_time, + uint8_t *buffer, size_t buffer_len, size_t written) { proto_detail_file_t const *inst = talloc_get_type_abort_const(instance, proto_detail_file_t); - return inst->parent->work_io->write(inst->parent->work_io_instance, packet_ctx, request_time, buffer, buffer_len); + return inst->parent->work_io->write(inst->parent->work_io_instance, packet_ctx, request_time, buffer, buffer_len, written); } static void mod_vnode_extend(void *instance, UNUSED uint32_t fflags) diff --git a/src/modules/proto_detail/proto_detail_work.c b/src/modules/proto_detail/proto_detail_work.c index cef502e36ca..043699d8bdf 100644 --- a/src/modules/proto_detail/proto_detail_work.c +++ b/src/modules/proto_detail/proto_detail_work.c @@ -556,8 +556,8 @@ static void work_retransmit(UNUSED fr_event_list_t *el, UNUSED struct timeval *n #endif } -static ssize_t mod_write(void *instance, void *packet_ctx, - fr_time_t request_time, uint8_t *buffer, size_t buffer_len) +static ssize_t mod_write(void *instance, void *packet_ctx, fr_time_t request_time, + uint8_t *buffer, size_t buffer_len, UNUSED size_t written) { proto_detail_work_t *inst = talloc_get_type_abort(instance, proto_detail_work_t); fr_detail_entry_t *track = packet_ctx; diff --git a/src/modules/proto_dhcpv4/proto_dhcpv4_udp.c b/src/modules/proto_dhcpv4/proto_dhcpv4_udp.c index 0255fcb200c..b70c66e88a8 100644 --- a/src/modules/proto_dhcpv4/proto_dhcpv4_udp.c +++ b/src/modules/proto_dhcpv4/proto_dhcpv4_udp.c @@ -211,8 +211,8 @@ static ssize_t mod_read(void *instance, void **packet_ctx, fr_time_t **recv_time } -static ssize_t mod_write(void *instance, void *packet_ctx, - UNUSED fr_time_t request_time, uint8_t *buffer, size_t buffer_len) +static ssize_t mod_write(void *instance, void *packet_ctx, UNUSED fr_time_t request_time, + uint8_t *buffer, size_t buffer_len, UNUSED size_t written) { proto_dhcpv4_udp_t *inst = talloc_get_type_abort(instance, proto_dhcpv4_udp_t); fr_io_track_t *track = talloc_get_type_abort(packet_ctx, fr_io_track_t); diff --git a/src/modules/proto_radius/proto_radius_tcp.c b/src/modules/proto_radius/proto_radius_tcp.c index cc82b9bd214..133e24ff28c 100644 --- a/src/modules/proto_radius/proto_radius_tcp.c +++ b/src/modules/proto_radius/proto_radius_tcp.c @@ -203,8 +203,8 @@ static ssize_t mod_read(void *instance, UNUSED void **packet_ctx, fr_time_t **re } -static ssize_t mod_write(void *instance, void *packet_ctx, - UNUSED fr_time_t request_time, uint8_t *buffer, size_t buffer_len) +static ssize_t mod_write(void *instance, void *packet_ctx, UNUSED fr_time_t request_time, + uint8_t *buffer, size_t buffer_len, UNUSED size_t written) { proto_radius_tcp_t *inst = talloc_get_type_abort(instance, proto_radius_tcp_t); fr_io_track_t *track = talloc_get_type_abort(packet_ctx, fr_io_track_t); diff --git a/src/modules/proto_radius/proto_radius_udp.c b/src/modules/proto_radius/proto_radius_udp.c index fc0420f2110..c2b9ce3faba 100644 --- a/src/modules/proto_radius/proto_radius_udp.c +++ b/src/modules/proto_radius/proto_radius_udp.c @@ -193,8 +193,8 @@ static ssize_t mod_read(void *instance, void **packet_ctx, fr_time_t **recv_time } -static ssize_t mod_write(void *instance, void *packet_ctx, - UNUSED fr_time_t request_time, uint8_t *buffer, size_t buffer_len) +static ssize_t mod_write(void *instance, void *packet_ctx, UNUSED fr_time_t request_time, + uint8_t *buffer, size_t buffer_len, UNUSED size_t written) { proto_radius_udp_t *inst = talloc_get_type_abort(instance, proto_radius_udp_t); fr_io_track_t *track = talloc_get_type_abort(packet_ctx, fr_io_track_t); diff --git a/src/modules/proto_vmps/proto_vmps_udp.c b/src/modules/proto_vmps/proto_vmps_udp.c index 97dc6c6596b..5f9eda4f337 100644 --- a/src/modules/proto_vmps/proto_vmps_udp.c +++ b/src/modules/proto_vmps/proto_vmps_udp.c @@ -196,8 +196,8 @@ static ssize_t mod_read(void *instance, void **packet_ctx, fr_time_t **recv_time } -static ssize_t mod_write(void *instance, void *packet_ctx, - UNUSED fr_time_t request_time, uint8_t *buffer, size_t buffer_len) +static ssize_t mod_write(void *instance, void *packet_ctx, UNUSED fr_time_t request_time, + uint8_t *buffer, size_t buffer_len, UNUSED size_t written) { proto_vmps_udp_t *inst = talloc_get_type_abort(instance, proto_vmps_udp_t); fr_io_track_t *track = talloc_get_type_abort(packet_ctx, fr_io_track_t); diff --git a/src/tests/util/radius_schedule_test.c b/src/tests/util/radius_schedule_test.c index 416dad6630a..0aa090c0add 100644 --- a/src/tests/util/radius_schedule_test.c +++ b/src/tests/util/radius_schedule_test.c @@ -159,7 +159,7 @@ static ssize_t test_read(void *ctx, UNUSED void **packet_ctx, fr_time_t **recv_t static ssize_t test_write(void *ctx, UNUSED void *packet_ctx, UNUSED fr_time_t request_time, - uint8_t *buffer, size_t buffer_len) + uint8_t *buffer, size_t buffer_len, UNUSED size_t written) { ssize_t data_size; fr_listen_test_t *io_ctx = talloc_get_type_abort(ctx, fr_listen_test_t);