1 /*
2 * libwebsockets - small server side websockets and web server implementation
3 *
4 * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
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 #include "private-lib-core.h"
26
27 #if defined(LWS_WITH_MBEDTLS)
28 #if defined(LWS_HAVE_MBEDTLS_NET_SOCKETS)
29 #include "mbedtls/net_sockets.h"
30 #else
31 #include "mbedtls/net.h"
32 #endif
33 #endif
34
35 int
lws_plat_pipe_create(struct lws * wsi)36 lws_plat_pipe_create(struct lws *wsi)
37 {
38 return 1;
39 }
40
41 int
lws_plat_pipe_signal(struct lws * wsi)42 lws_plat_pipe_signal(struct lws *wsi)
43 {
44 return 1;
45 }
46
47 void
lws_plat_pipe_close(struct lws * wsi)48 lws_plat_pipe_close(struct lws *wsi)
49 {
50 }
51
52 int
lws_send_pipe_choked(struct lws * wsi)53 lws_send_pipe_choked(struct lws *wsi)
54 {
55 struct lws *wsi_eff;
56
57 #if defined(LWS_WITH_HTTP2)
58 wsi_eff = lws_get_network_wsi(wsi);
59 #else
60 wsi_eff = wsi;
61 #endif
62
63 /* the fact we checked implies we avoided back-to-back writes */
64 wsi_eff->could_have_pending = 0;
65
66 /* treat the fact we got a truncated send pending as if we're choked */
67 if (lws_has_buffered_out(wsi_eff)
68 #if defined(LWS_WITH_HTTP_STREAM_COMPRESSION)
69 || wsi->http.comp_ctx.buflist_comp ||
70 wsi->http.comp_ctx.may_have_more
71 #endif
72 )
73 return 1;
74
75 /* okay to send another packet without blocking */
76
77 return 0;
78 }
79
80 int
lws_poll_listen_fd(struct lws_pollfd * fd)81 lws_poll_listen_fd(struct lws_pollfd *fd)
82 {
83 // return poll(fd, 1, 0);
84
85 return 0;
86 }
87
88
89 int
_lws_plat_service_tsi(struct lws_context * context,int timeout_ms,int tsi)90 _lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi)
91 {
92 lws_usec_t timeout_us = timeout_ms * LWS_US_PER_MS;
93 struct lws_context_per_thread *pt;
94 int n = -1, m, c, a = 0;
95 //char buf;
96
97 /* stay dead once we are dead */
98
99 if (!context)
100 return 1;
101
102 pt = &context->pt[tsi];
103
104 if (timeout_ms < 0)
105 timeout_ms = 0;
106 else
107 timeout_ms = 2000000000;
108
109 if (!pt->service_tid_detected && context->vhost_list) {
110 struct lws _lws;
111
112 memset(&_lws, 0, sizeof(_lws));
113 _lws.context = context;
114
115 pt->service_tid = context->vhost_list->protocols[0].callback(
116 &_lws, LWS_CALLBACK_GET_THREAD_ID, NULL, NULL, 0);
117 pt->service_tid_detected = 1;
118 }
119
120 /*
121 * is there anybody with pending stuff that needs service forcing?
122 */
123 if (lws_service_adjust_timeout(context, 1, tsi)) {
124 again:
125 a = 0;
126 if (timeout_us) {
127 lws_usec_t us;
128
129 lws_pt_lock(pt, __func__);
130 /* don't stay in poll wait longer than next hr timeout */
131 us = __lws_sul_service_ripe(pt->pt_sul_owner,
132 LWS_COUNT_PT_SUL_OWNERS,
133 lws_now_usecs());
134 if (us && us < timeout_us)
135 timeout_us = us;
136
137 lws_pt_unlock(pt);
138 }
139
140 n = poll(pt->fds, pt->fds_count, timeout_us / LWS_US_PER_MS);
141
142 m = 0;
143
144 if (pt->context->tls_ops &&
145 pt->context->tls_ops->fake_POLLIN_for_buffered)
146 m = pt->context->tls_ops->fake_POLLIN_for_buffered(pt);
147
148 if (/*!pt->ws.rx_draining_ext_list && */!m && !n) /* nothing to do */
149 return 0;
150 } else
151 a = 1;
152
153 m = lws_service_flag_pending(context, tsi);
154 if (m)
155 c = -1; /* unknown limit */
156 else
157 if (n < 0) {
158 if (LWS_ERRNO != LWS_EINTR)
159 return -1;
160 return 0;
161 } else
162 c = n;
163
164 /* any socket with events to service? */
165 for (n = 0; n < (int)pt->fds_count && c; n++) {
166 if (!pt->fds[n].revents)
167 continue;
168
169 c--;
170 #if 0
171 if (pt->fds[n].fd == pt->dummy_pipe_fds[0]) {
172 if (read(pt->fds[n].fd, &buf, 1) != 1)
173 lwsl_err("Cannot read from dummy pipe.");
174 continue;
175 }
176 #endif
177 m = lws_service_fd_tsi(context, &pt->fds[n], tsi);
178 if (m < 0)
179 return -1;
180 /* if something closed, retry this slot */
181 if (m)
182 n--;
183 }
184
185 if (a)
186 goto again;
187
188 return 0;
189 }
190
191 int
lws_plat_service(struct lws_context * context,int timeout_ms)192 lws_plat_service(struct lws_context *context, int timeout_ms)
193 {
194 return _lws_plat_service_tsi(context, timeout_ms, 0);
195 }
196
197 int
lws_plat_set_socket_options(struct lws_vhost * vhost,int fd,int unix_skt)198 lws_plat_set_socket_options(struct lws_vhost *vhost, int fd, int unix_skt)
199 {
200 return 0;
201 }
202
203
204 int
lws_plat_write_cert(struct lws_vhost * vhost,int is_key,int fd,void * buf,size_t len)205 lws_plat_write_cert(struct lws_vhost *vhost, int is_key, int fd, void *buf,
206 size_t len)
207 {
208 return 1;
209 }
210
211
212 /* cast a struct sockaddr_in6 * into addr for ipv6 */
213
214 int
lws_interface_to_sa(int ipv6,const char * ifname,struct sockaddr_in * addr,size_t addrlen)215 lws_interface_to_sa(int ipv6, const char *ifname, struct sockaddr_in *addr,
216 size_t addrlen)
217 {
218 return -1;
219 }
220
221 void
lws_plat_insert_socket_into_fds(struct lws_context * context,struct lws * wsi)222 lws_plat_insert_socket_into_fds(struct lws_context *context, struct lws *wsi)
223 {
224 struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
225
226 pt->fds[pt->fds_count++].revents = 0;
227 }
228
229 void
lws_plat_delete_socket_from_fds(struct lws_context * context,struct lws * wsi,int m)230 lws_plat_delete_socket_from_fds(struct lws_context *context,
231 struct lws *wsi, int m)
232 {
233 struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
234
235 pt->fds_count--;
236 }
237
238 int
lws_plat_change_pollfd(struct lws_context * context,struct lws * wsi,struct lws_pollfd * pfd)239 lws_plat_change_pollfd(struct lws_context *context,
240 struct lws *wsi, struct lws_pollfd *pfd)
241 {
242 return 0;
243 }
244
245 const char *
lws_plat_inet_ntop(int af,const void * src,char * dst,socklen_t cnt)246 lws_plat_inet_ntop(int af, const void *src, char *dst, socklen_t cnt)
247 {
248 //return inet_ntop(af, src, dst, cnt);
249 return "lws_plat_inet_ntop";
250 }
251
252 int
lws_plat_inet_pton(int af,const char * src,void * dst)253 lws_plat_inet_pton(int af, const char *src, void *dst)
254 {
255 //return inet_pton(af, src, dst);
256 return 1;
257 }
258
259 int
lws_plat_set_socket_options_ip(int fd,uint8_t pri,unsigned int lws_flags)260 lws_plat_set_socket_options_ip(int fd, uint8_t pri, unsigned int lws_flags)
261 {
262 return 0;
263 }
264
265 int
lws_plat_vhost_tls_client_ctx_init(struct lws_vhost * vhost)266 lws_plat_vhost_tls_client_ctx_init(struct lws_vhost *vhost)
267 {
268 return 0;
269 }
270
271 #if defined(LWS_WITH_MBEDTLS)
272 int
lws_plat_mbedtls_net_send(void * ctx,const uint8_t * buf,size_t len)273 lws_plat_mbedtls_net_send(void *ctx, const uint8_t *buf, size_t len)
274 {
275 int fd = ((mbedtls_net_context *) ctx)->fd;
276 int ret;
277
278 if (fd < 0)
279 return MBEDTLS_ERR_NET_INVALID_CONTEXT;
280
281 ret = write(fd, buf, len);
282 if (ret >= 0)
283 return ret;
284
285 if (errno == EAGAIN || errno == EWOULDBLOCK)
286 return MBEDTLS_ERR_SSL_WANT_WRITE;
287
288 if (errno == EPIPE || errno == ECONNRESET)
289 return MBEDTLS_ERR_NET_CONN_RESET;
290
291 if( errno == EINTR )
292 return MBEDTLS_ERR_SSL_WANT_WRITE;
293
294 return MBEDTLS_ERR_NET_SEND_FAILED;
295 }
296
297 int
lws_plat_mbedtls_net_recv(void * ctx,unsigned char * buf,size_t len)298 lws_plat_mbedtls_net_recv(void *ctx, unsigned char *buf, size_t len)
299 {
300 int fd = ((mbedtls_net_context *) ctx)->fd;
301 int ret;
302
303 if (fd < 0)
304 return MBEDTLS_ERR_NET_INVALID_CONTEXT;
305
306 ret = (int)read(fd, buf, len);
307 if (ret >= 0)
308 return ret;
309
310 if (errno == EAGAIN || errno == EWOULDBLOCK)
311 return MBEDTLS_ERR_SSL_WANT_READ;
312
313 if (errno == EPIPE || errno == ECONNRESET)
314 return MBEDTLS_ERR_NET_CONN_RESET;
315
316 if (errno == EINTR)
317 return MBEDTLS_ERR_SSL_WANT_READ;
318
319 return MBEDTLS_ERR_NET_RECV_FAILED;
320 }
321
322 #endif
323