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