1 /* 2 * Copyright (c) 2020 Andri Yngvason 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 13 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 * PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 #include "config.h" 18 #include "sys/queue.h" 19 #include "rcbuf.h" 20 21 #include <stdint.h> 22 23 #ifdef ENABLE_TLS 24 #include <gnutls/gnutls.h> 25 #endif 26 27 enum stream_state { 28 STREAM_STATE_NORMAL = 0, 29 STREAM_STATE_CLOSED, 30 #ifdef ENABLE_TLS 31 STREAM_STATE_TLS_HANDSHAKE, 32 STREAM_STATE_TLS_READY, 33 #endif 34 }; 35 36 enum stream_status { 37 STREAM_READY = 0, 38 STREAM_CLOSED, 39 }; 40 41 enum stream_req_status { 42 STREAM_REQ_DONE = 0, 43 STREAM_REQ_FAILED, 44 }; 45 46 enum stream_event { 47 STREAM_EVENT_READ, 48 STREAM_EVENT_REMOTE_CLOSED, 49 }; 50 51 struct stream; 52 53 typedef void (*stream_event_fn)(struct stream*, enum stream_event); 54 typedef void (*stream_req_fn)(void*, enum stream_req_status); 55 56 struct stream_req { 57 struct rcbuf* payload; 58 stream_req_fn on_done; 59 void* userdata; 60 TAILQ_ENTRY(stream_req) link; 61 }; 62 63 TAILQ_HEAD(stream_send_queue, stream_req); 64 65 struct stream { 66 enum stream_state state; 67 68 int fd; 69 struct aml_handler* handler; 70 stream_event_fn on_event; 71 void* userdata; 72 73 struct stream_send_queue send_queue; 74 75 #ifdef ENABLE_TLS 76 gnutls_session_t tls_session; 77 #endif 78 79 uint32_t bytes_sent; 80 uint32_t bytes_received; 81 }; 82 83 struct stream* stream_new(int fd, stream_event_fn on_event, void* userdata); 84 int stream_close(struct stream* self); 85 void stream_destroy(struct stream* self); 86 ssize_t stream_read(struct stream* self, void* dst, size_t size); 87 int stream_write(struct stream* self, const void* payload, size_t len, 88 stream_req_fn on_done, void* userdata); 89 int stream_send(struct stream* self, struct rcbuf* payload, 90 stream_req_fn on_done, void* userdata); 91 92 #ifdef ENABLE_TLS 93 int stream_upgrade_to_tls(struct stream* self, void* context); 94 #endif 95