1 | /* |
2 | * libwebsockets - small server side websockets and web server implementation |
3 | * |
4 | * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com> |
5 | * |
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
7 | * of this software and associated documentation files (the "Software"), to |
8 | * deal in the Software without restriction, including without limitation the |
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
10 | * sell copies of the Software, and to permit persons to whom the Software is |
11 | * furnished to do so, subject to the following conditions: |
12 | * |
13 | * The above copyright notice and this permission notice shall be included in |
14 | * all copies or substantial portions of the Software. |
15 | * |
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
21 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
22 | * IN THE SOFTWARE. |
23 | */ |
24 | |
25 | /** \defgroup sock-adopt Socket adoption helpers |
26 | * ##Socket adoption helpers |
27 | * |
28 | * When integrating with an external app with its own event loop, these can |
29 | * be used to accept connections from someone else's listening socket. |
30 | * |
31 | * When using lws own event loop, these are not needed. |
32 | */ |
33 | ///@{ |
34 | |
35 | /** |
36 | * lws_adopt_socket() - adopt foreign socket as if listen socket accepted it |
37 | * for the default vhost of context. |
38 | * |
39 | * \param context: lws context |
40 | * \param accept_fd: fd of already-accepted socket to adopt |
41 | * |
42 | * Either returns new wsi bound to accept_fd, or closes accept_fd and |
43 | * returns NULL, having cleaned up any new wsi pieces. |
44 | * |
45 | * LWS adopts the socket in http serving mode, it's ready to accept an upgrade |
46 | * to ws or just serve http. |
47 | */ |
48 | LWS_VISIBLE LWS_EXTERN struct lws * |
49 | lws_adopt_socket(struct lws_context *context, lws_sockfd_type accept_fd); |
50 | /** |
51 | * lws_adopt_socket_vhost() - adopt foreign socket as if listen socket accepted |
52 | * it for vhost |
53 | * |
54 | * \param vh: lws vhost |
55 | * \param accept_fd: fd of already-accepted socket to adopt |
56 | * |
57 | * Either returns new wsi bound to accept_fd, or closes accept_fd and |
58 | * returns NULL, having cleaned up any new wsi pieces. |
59 | * |
60 | * LWS adopts the socket in http serving mode, it's ready to accept an upgrade |
61 | * to ws or just serve http. |
62 | */ |
63 | LWS_VISIBLE LWS_EXTERN struct lws * |
64 | lws_adopt_socket_vhost(struct lws_vhost *vh, lws_sockfd_type accept_fd); |
65 | |
66 | typedef enum { |
67 | LWS_ADOPT_RAW_FILE_DESC = 0, /* convenience constant */ |
68 | LWS_ADOPT_HTTP = 1, /* flag: absent implies RAW */ |
69 | LWS_ADOPT_SOCKET = 2, /* flag: absent implies file */ |
70 | LWS_ADOPT_ALLOW_SSL = 4, /* flag: use tls */ |
71 | LWS_ADOPT_FLAG_UDP = 16, /* flag: socket is UDP */ |
72 | LWS_ADOPT_FLAG_RAW_PROXY = 32, /* flag: raw proxy */ |
73 | |
74 | LWS_ADOPT_RAW_SOCKET_UDP = LWS_ADOPT_SOCKET | LWS_ADOPT_FLAG_UDP, |
75 | } lws_adoption_type; |
76 | |
77 | typedef union { |
78 | lws_sockfd_type sockfd; |
79 | lws_filefd_type filefd; |
80 | } lws_sock_file_fd_type; |
81 | |
82 | #if defined(LWS_ESP_PLATFORM) |
83 | #include <lwip/sockets.h> |
84 | #endif |
85 | |
86 | typedef union { |
87 | #if defined(LWS_WITH_IPV6) |
88 | struct sockaddr_in6 sa6; |
89 | #else |
90 | #if defined(LWS_ESP_PLATFORM) |
91 | uint8_t _pad_sa6[28]; |
92 | #endif |
93 | #endif |
94 | struct sockaddr_in sa4; |
95 | } lws_sockaddr46; |
96 | |
97 | #define sa46_sockaddr(_sa46) ((struct sockaddr *)(_sa46)) |
98 | |
99 | #if defined(LWS_WITH_IPV6) |
100 | #define sa46_socklen(_sa46) (socklen_t)((_sa46)->sa4.sin_family == AF_INET ? \ |
101 | sizeof(struct sockaddr_in) : \ |
102 | sizeof(struct sockaddr_in6)) |
103 | #define sa46_sockport(_sa46, _sp) { if ((_sa46)->sa4.sin_family == AF_INET) \ |
104 | (_sa46)->sa4.sin_port = (_sp); else \ |
105 | (_sa46)->sa6.sin6_port = (_sp); } |
106 | #define sa46_address(_sa46) ((uint8_t *)((_sa46)->sa4.sin_family == AF_INET ? \ |
107 | &_sa46->sa4.sin_addr : &_sa46->sa6.sin6_addr )) |
108 | #else |
109 | #define sa46_socklen(_sa46) (socklen_t)sizeof(struct sockaddr_in) |
110 | #define sa46_sockport(_sa46, _sp) (_sa46)->sa4.sin_port = (_sp) |
111 | #define sa46_address(_sa46) (uint8_t *)&_sa46->sa4.sin_addr |
112 | #endif |
113 | |
114 | #define sa46_address_len(_sa46) ((_sa46)->sa4.sin_family == AF_INET ? 4 : 16) |
115 | |
116 | #if defined(LWS_WITH_UDP) |
117 | struct lws_udp { |
118 | lws_sockaddr46 sa46; |
119 | lws_sockaddr46 sa46_pending; |
120 | uint8_t connected:1; |
121 | }; |
122 | #endif |
123 | |
124 | /** |
125 | * lws_adopt_descriptor_vhost() - adopt foreign socket or file descriptor |
126 | * if socket descriptor, should already have been accepted from listen socket |
127 | * |
128 | * \param vh: lws vhost |
129 | * \param type: OR-ed combinations of lws_adoption_type flags |
130 | * \param fd: union with either .sockfd or .filefd set |
131 | * \param vh_prot_name: NULL or vh protocol name to bind raw connection to |
132 | * \param parent: NULL or struct lws to attach new_wsi to as a child |
133 | * |
134 | * Either returns new wsi bound to accept_fd, or closes accept_fd and |
135 | * returns NULL, having cleaned up any new wsi pieces. |
136 | * |
137 | * If LWS_ADOPT_SOCKET is set, LWS adopts the socket in http serving mode, it's |
138 | * ready to accept an upgrade to ws or just serve http. |
139 | * |
140 | * parent may be NULL, if given it should be an existing wsi that will become the |
141 | * parent of the new wsi created by this call. |
142 | */ |
143 | LWS_VISIBLE LWS_EXTERN struct lws * |
144 | lws_adopt_descriptor_vhost(struct lws_vhost *vh, lws_adoption_type type, |
145 | lws_sock_file_fd_type fd, const char *vh_prot_name, |
146 | struct lws *parent); |
147 | |
148 | typedef struct lws_adopt_desc { |
149 | struct lws_vhost *vh; /**< vhost the wsi should belong to */ |
150 | lws_adoption_type type; /**< OR-ed combinations of lws_adoption_type flags */ |
151 | lws_sock_file_fd_type fd; /**< union with either .sockfd or .filefd set */ |
152 | const char *vh_prot_name; /**< NULL or vh protocol name to bind raw connection to */ |
153 | struct lws *parent; /**< NULL or struct lws to attach new_wsi to as a child */ |
154 | void *opaque; /**< opaque pointer to set on created wsi */ |
155 | const char *fi_wsi_name; /**< NULL, or Fault Injection inheritence filter for wsi=string/ context faults */ |
156 | } lws_adopt_desc_t; |
157 | |
158 | /** |
159 | * lws_adopt_descriptor_vhost_via_info() - adopt foreign socket or file descriptor |
160 | * if socket descriptor, should already have been accepted from listen socket |
161 | * |
162 | * \param info: the struct containing the parameters |
163 | * |
164 | * - vh: lws vhost |
165 | * - type: OR-ed combinations of lws_adoption_type flags |
166 | * - fd: union with either .sockfd or .filefd set |
167 | * - vh_prot_name: NULL or vh protocol name to bind raw connection to |
168 | * - parent: NULL or struct lws to attach new_wsi to as a child |
169 | * - opaque: opaque pointer to set on created wsi |
170 | * |
171 | * Either returns new wsi bound to accept_fd, or closes accept_fd and |
172 | * returns NULL, having cleaned up any new wsi pieces. |
173 | * |
174 | * If LWS_ADOPT_SOCKET is set, LWS adopts the socket in http serving mode, it's |
175 | * ready to accept an upgrade to ws or just serve http. |
176 | * |
177 | * parent may be NULL, if given it should be an existing wsi that will become the |
178 | * parent of the new wsi created by this call. |
179 | */ |
180 | LWS_VISIBLE LWS_EXTERN struct lws * |
181 | lws_adopt_descriptor_vhost_via_info(const lws_adopt_desc_t *info); |
182 | |
183 | /** |
184 | * lws_adopt_socket_readbuf() - adopt foreign socket and first rx as if listen socket accepted it |
185 | * for the default vhost of context. |
186 | * \param context: lws context |
187 | * \param accept_fd: fd of already-accepted socket to adopt |
188 | * \param readbuf: NULL or pointer to data that must be drained before reading from |
189 | * accept_fd |
190 | * \param len: The length of the data held at \p readbuf |
191 | * |
192 | * Either returns new wsi bound to accept_fd, or closes accept_fd and |
193 | * returns NULL, having cleaned up any new wsi pieces. |
194 | * |
195 | * LWS adopts the socket in http serving mode, it's ready to accept an upgrade |
196 | * to ws or just serve http. |
197 | * |
198 | * If your external code did not already read from the socket, you can use |
199 | * lws_adopt_socket() instead. |
200 | * |
201 | * This api is guaranteed to use the data at \p readbuf first, before reading from |
202 | * the socket. |
203 | * |
204 | * \p readbuf is limited to the size of the ah rx buf, currently 2048 bytes. |
205 | */ |
206 | LWS_VISIBLE LWS_EXTERN struct lws * |
207 | lws_adopt_socket_readbuf(struct lws_context *context, lws_sockfd_type accept_fd, |
208 | const char *readbuf, size_t len); |
209 | /** |
210 | * lws_adopt_socket_vhost_readbuf() - adopt foreign socket and first rx as if listen socket |
211 | * accepted it for vhost. |
212 | * \param vhost: lws vhost |
213 | * \param accept_fd: fd of already-accepted socket to adopt |
214 | * \param readbuf: NULL or pointer to data that must be drained before reading from accept_fd |
215 | * \param len: The length of the data held at \p readbuf |
216 | * |
217 | * Either returns new wsi bound to accept_fd, or closes accept_fd and |
218 | * returns NULL, having cleaned up any new wsi pieces. |
219 | * |
220 | * LWS adopts the socket in http serving mode, it's ready to accept an upgrade |
221 | * to ws or just serve http. |
222 | * |
223 | * If your external code did not already read from the socket, you can use |
224 | * lws_adopt_socket() instead. |
225 | * |
226 | * This api is guaranteed to use the data at \p readbuf first, before reading from |
227 | * the socket. |
228 | * |
229 | * \p readbuf is limited to the size of the ah rx buf, currently 2048 bytes. |
230 | */ |
231 | LWS_VISIBLE LWS_EXTERN struct lws * |
232 | lws_adopt_socket_vhost_readbuf(struct lws_vhost *vhost, |
233 | lws_sockfd_type accept_fd, const char *readbuf, |
234 | size_t len); |
235 | |
236 | #define LWS_CAUDP_BIND (1 << 0) |
237 | #define LWS_CAUDP_BROADCAST (1 << 1) |
238 | #define LWS_CAUDP_PF_PACKET (1 << 2) |
239 | |
240 | #if defined(LWS_WITH_UDP) |
241 | /** |
242 | * lws_create_adopt_udp() - create, bind and adopt a UDP socket |
243 | * |
244 | * \param vhost: lws vhost |
245 | * \param ads: NULL or address to do dns lookup on |
246 | * \param port: UDP port to bind to, -1 means unbound |
247 | * \param flags: 0 or LWS_CAUDP_NO_BIND |
248 | * \param protocol_name: Name of protocol on vhost to bind wsi to |
249 | * \param ifname: NULL, for network interface name to bind socket to |
250 | * \param parent_wsi: NULL or parent wsi new wsi will be a child of |
251 | * \param opaque: set created wsi opaque ptr to this |
252 | * \param retry_policy: NULL for vhost default policy else wsi specific policy |
253 | * \param fi_wsi_name: NULL, or string to inherit Fault Injection rules in |
254 | * form "wsi=string/rule". "wsi/rule" faults will be |
255 | * automatically applied as well. It's done at creation |
256 | * time so the rules can, eg, inject faults related to |
257 | * creation. |
258 | * |
259 | * Either returns new wsi bound to accept_fd, or closes accept_fd and |
260 | * returns NULL, having cleaned up any new wsi pieces. |
261 | * */ |
262 | LWS_VISIBLE LWS_EXTERN struct lws * |
263 | lws_create_adopt_udp(struct lws_vhost *vhost, const char *ads, int port, |
264 | int flags, const char *protocol_name, const char *ifname, |
265 | struct lws *parent_wsi, void *opaque, |
266 | const lws_retry_bo_t *retry_policy, const char *fi_wsi_name); |
267 | #endif |
268 | |
269 | |
270 | |
271 | ///@} |
272 | |