1 /* IOSockets.h - IOMultiplexer v2
2 * Copyright (C) 2014 Philipp Kreil (pk910)
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "IODNSAddress.struct.h"
23 struct IOSocketBuffer {
25 size_t bufpos, buflen;
28 #ifndef _IOHandler_internals
29 #include "IOHandler.h"
34 struct IOSocketBuffer;
35 struct IOSSLDescriptor;
42 void (*add)(struct _IOSocket *iosock);
43 void (*remove)(struct _IOSocket *iosock);
44 void (*update)(struct _IOSocket *iosock);
45 void (*loop)(struct timeval *timeout);
46 void (*cleanup)(void);
50 extern struct IOEngine engine_select; /* select system call (should always be useable) */
51 extern struct IOEngine engine_kevent;
52 extern struct IOEngine engine_epoll;
53 extern struct IOEngine engine_win32;
56 /* _IOSocket linked list */
57 extern struct _IOSocket *iosocket_first;
58 extern struct _IOSocket *iosocket_last;
60 /* _IOSocket socket_flags */
61 #define IOSOCKETFLAG_ACTIVE 0x00000001
62 #define IOSOCKETFLAG_LISTENING 0x00000002
63 #define IOSOCKETFLAG_IPV6SOCKET 0x00000004
64 #define IOSOCKETFLAG_INCOMING 0x00000008 /* incoming (accepted) connection */
65 #define IOSOCKETFLAG_CONNECTING 0x00000010
66 #define IOSOCKETFLAG_SHUTDOWN 0x00000020 /* disconnect pending */
67 #define IOSOCKETFLAG_DEAD 0x00000040 /* socket dead (disconnected) */
68 #define IOSOCKETFLAG_RECONNECT_IPV4 0x00000080 /* possible fallback to ipv4 connect if ipv6 fails */
71 #define IOSOCKETFLAG_PENDING_BINDDNS 0x00000100
72 #define IOSOCKETFLAG_PENDING_DESTDNS 0x00000200
73 #define IOSOCKETFLAG_DNSDONE_BINDDNS 0x00000400
74 #define IOSOCKETFLAG_DNSDONE_DESTDNS 0x00000800
75 #define IOSOCKETFLAG_DNSERROR 0x00001000
78 #define IOSOCKETFLAG_SSLSOCKET 0x00002000 /* use ssl after connecting */
79 #define IOSOCKETFLAG_SSL_HANDSHAKE 0x00004000 /* SSL Handshake in progress */
80 #define IOSOCKETFLAG_SSL_WANTWRITE 0x00008000 /* ssl module wants write access */
81 #define IOSOCKETFLAG_SSL_READHS 0x00010000 /* ssl read rehandshake */
82 #define IOSOCKETFLAG_SSL_WRITEHS 0x00020000 /* ssl write rehandshake */
83 #define IOSOCKETFLAG_SSL_ESTABLISHED 0x00040000 /* ssl connection established */
85 /* WANT_READ / WANT_WRITE override */
86 #define IOSOCKETFLAG_OVERRIDE_WANT_RW 0x00080000
87 #define IOSOCKETFLAG_OVERRIDE_WANT_R 0x00100000
88 #define IOSOCKETFLAG_OVERRIDE_WANT_W 0x00200000
90 /* Parent descriptors */
91 #define IOSOCKETFLAG_PARENT_PUBLIC 0x10000000
92 #define IOSOCKETFLAG_PARENT_DNSENGINE 0x20000000
93 /* reserved flags for additional descriptor types? */
95 struct IOSocketDNSLookup {
96 unsigned int bindlookup : 1;
98 struct _IOSocket *iosocket;
99 struct _IODNSQuery *query;
100 struct IODNSResult *result;
106 unsigned int socket_flags : 32;
109 struct IODNSAddress addr;
110 struct IOSocketDNSLookup *addrlookup;
113 struct IODNSAddress addr;
114 struct IOSocketDNSLookup *addrlookup;
117 unsigned int port : 16;
119 struct IOSocketBuffer readbuf;
120 struct IOSocketBuffer writebuf;
122 struct IOSSLDescriptor *sslnode;
126 struct _IOSocket *next, *prev;
129 void _init_sockets();
130 void iosocket_loop(int usec);
131 void iosocket_lookup_callback(struct IOSocketDNSLookup *lookup, struct IODNSEvent *event);
132 void iosocket_events_callback(struct _IOSocket *iosock, int readable, int writeable);
134 #define iosocket_wants_reads(IOSOCK) \
136 ((IOSOCK->socket_flags & (IOSOCKETFLAG_SSL_READHS | IOSOCKETFLAG_SSL_WRITEHS)) && !(IOSOCK->socket_flags & IOSOCKETFLAG_SSL_WANTWRITE)) || \
137 (!(IOSOCK->socket_flags & IOSOCKETFLAG_OVERRIDE_WANT_RW) || \
138 (IOSOCK->socket_flags & (IOSOCKETFLAG_OVERRIDE_WANT_RW | IOSOCKETFLAG_OVERRIDE_WANT_R) == (IOSOCKETFLAG_OVERRIDE_WANT_RW | IOSOCKETFLAG_OVERRIDE_WANT_R)) \
140 #define iosocket_wants_writes(IOSOCK) \
142 (IOSOCK->socket_flags & (IOSOCKETFLAG_SSL_READHS | IOSOCKETFLAG_SSL_WRITEHS | IOSOCKETFLAG_SSL_WANTWRITE) > IOSOCKETFLAG_SSL_WANTWRITE) || \
143 (!(IOSOCK->socket_flags & IOSOCKETFLAG_OVERRIDE_WANT_RW) && (IOSOCK->writebuf.bufpos || (IOSOCK->socket_flags & IOSOCKETFLAG_CONNECTING))) || \
144 (IOSOCK->socket_flags & (IOSOCKETFLAG_OVERRIDE_WANT_RW | IOSOCKETFLAG_OVERRIDE_WANT_W) == (IOSOCKETFLAG_OVERRIDE_WANT_RW | IOSOCKETFLAG_OVERRIDE_WANT_W)) \
149 struct IOSocketEvent;
151 #define IOSOCKET_CALLBACK(NAME) void NAME(struct IOSocketEvent *event)
152 typedef IOSOCKET_CALLBACK(iosocket_callback);
154 enum IOSocketStatus {
155 IOSOCKET_CLOSED, /* descriptor is dead (socket waiting for removal or timer) */
156 IOSOCKET_LISTENING, /* descriptor is waiting for connections (server socket) */
157 IOSOCKET_CONNECTING, /* descriptor is waiting for connection approval (connecting client socket) */
158 IOSOCKET_CONNECTED, /* descriptor is connected (connected client socket) */
159 IOSOCKET_SSLHANDSHAKE /* descriptor is waiting for ssl (handshake) */
162 enum IOSocketEventType {
163 IOSOCKETEVENT_IGNORE,
164 IOSOCKETEVENT_RECV, /* client socket received something (read_lines == 1 => recv_str valid; read_lines == 0 => recv_buf valid) */
165 IOSOCKETEVENT_CONNECTED, /* client socket connected successful */
166 IOSOCKETEVENT_NOTCONNECTED, /* client socket could not connect (errid valid) */
167 IOSOCKETEVENT_CLOSED, /* client socket lost connection (errid valid) */
168 IOSOCKETEVENT_ACCEPT, /* server socket accepted new connection (accept_socket valid) */
169 IOSOCKETEVENT_DNSFAILED /* failed to lookup DNS information (recv_str contains error message) */
175 enum IOSocketStatus status;
178 int parse_delimiter : 1;
179 int parse_empty : 1; /* parse "empty" lines (only if parse_delimiter is set) */
180 unsigned char delimiters[IOSOCKET_PARSE_DELIMITERS_COUNT];
183 iosocket_callback *callback;
186 struct IOSocketEvent {
187 enum IOSocketEventType type;
188 struct IOSocket *socket;
191 struct IOSocketBuffer *recv_buf;
193 struct IOSocket *accept_socket;
198 #define IOSOCKET_ADDR_IPV4 0x01
199 #define IOSOCKET_ADDR_IPV6 0x02 /* overrides IOSOCKET_ADDR_IPV4 */
200 #define IOSOCKET_PROTO_UDP 0x04
202 struct IOSocket *iosocket_connect(const char *hostname, unsigned int port, int ssl, const char *bindhost, iosocket_callback *callback);
203 struct IOSocket *iosocket_connect_flags(const char *hostname, unsigned int port, int ssl, const char *bindhost, iosocket_callback *callback, int flags);
204 struct IOSocket *iosocket_listen(const char *hostname, unsigned int port, iosocket_callback *callback);
205 struct IOSocket *iosocket_listen_flags(const char *hostname, unsigned int port, iosocket_callback *callback, int flags);
206 struct IOSocket *iosocket_listen_ssl(const char *hostname, unsigned int port, const char *certfile, const char *keyfile, iosocket_callback *callback);
207 struct IOSocket *iosocket_listen_ssl_flags(const char *hostname, unsigned int port, const char *certfile, const char *keyfile, iosocket_callback *callback, int flags);
208 void iosocket_write(struct IOSocket *iosocket, const char *line);
209 void iosocket_send(struct IOSocket *iosocket, const char *data, size_t datalen);
210 void iosocket_printf(struct IOSocket *iosocket, const char *text, ...);
211 void iosocket_close(struct IOSocket *iosocket);