62 |
62 |
63 |
63 |
64 #include "../daemon/vfs.h" |
64 #include "../daemon/vfs.h" |
65 #include "io.h" |
65 #include "io.h" |
66 #include "pool.h" |
66 #include "pool.h" |
|
67 #include "../daemon/event.h" |
67 #include "ucx/utils.h" |
68 #include "ucx/utils.h" |
68 |
69 |
69 IOStream native_io_funcs = { |
70 IOStream native_io_funcs = { |
70 (io_write_f)net_sys_write, |
71 (io_write_f)net_sys_write, |
71 (io_writev_f)net_sys_writev, |
72 (io_writev_f)net_sys_writev, |
72 (io_read_f)net_sys_read, |
73 (io_read_f)net_sys_read, |
73 (io_sendfile_f)NET_SYS_SENDFILE, |
74 (io_sendfile_f)NET_SYS_SENDFILE, |
74 (io_close_f)net_sys_close, |
75 (io_close_f)net_sys_close, |
75 NULL |
76 NULL, |
|
77 (io_setmode_f)net_sys_setmode, |
|
78 (io_poll_f)net_sys_poll, |
|
79 0 |
76 }; |
80 }; |
77 |
81 |
78 IOStream http_io_funcs = { |
82 IOStream http_io_funcs = { |
79 (io_write_f)net_http_write, |
83 (io_write_f)net_http_write, |
80 (io_writev_f)net_http_writev, |
84 (io_writev_f)net_http_writev, |
81 (io_read_f)net_http_read, |
85 (io_read_f)net_http_read, |
82 (io_sendfile_f)net_http_sendfile, |
86 (io_sendfile_f)net_http_sendfile, |
83 (io_close_f)net_http_close, |
87 (io_close_f)net_http_close, |
84 (io_finish_f)net_http_finish |
88 (io_finish_f)net_http_finish, |
|
89 (io_setmode_f)net_http_setmode, |
|
90 (io_poll_f)net_http_poll, |
|
91 0 |
85 }; |
92 }; |
86 |
93 |
87 IOStream ssl_io_funcs = { |
94 IOStream ssl_io_funcs = { |
88 (io_write_f)net_ssl_write, |
95 (io_write_f)net_ssl_write, |
89 (io_writev_f)net_ssl_writev, |
96 (io_writev_f)net_ssl_writev, |
90 (io_read_f)net_ssl_read, |
97 (io_read_f)net_ssl_read, |
91 NULL, |
98 NULL, |
92 (io_close_f)net_ssl_close, |
99 (io_close_f)net_ssl_close, |
93 (io_finish_f)net_ssl_finish |
100 (io_finish_f)net_ssl_finish, |
|
101 (io_setmode_f)net_ssl_setmode, |
|
102 (io_poll_f)net_ssl_poll, |
|
103 0 |
94 }; |
104 }; |
95 |
105 |
96 |
106 |
97 /* |
107 /* |
98 * SysStream implementation |
108 * SysStream implementation |
168 |
178 |
169 void net_sys_close(SysStream *st) { |
179 void net_sys_close(SysStream *st) { |
170 close(st->fd); |
180 close(st->fd); |
171 } |
181 } |
172 |
182 |
|
183 void net_sys_setmode(SysStream *st, int mode) { |
|
184 int flags; |
|
185 if (-1 == (flags = fcntl(st->fd, F_GETFL, 0))) { |
|
186 flags = 0; |
|
187 } |
|
188 if(mode == IO_MODE_BLOCKING) { |
|
189 if (fcntl(st->fd, F_SETFL, flags & ~O_NONBLOCK) != 0) { |
|
190 perror("fcntl"); |
|
191 // TODO: error |
|
192 } |
|
193 } else if(mode == IO_MODE_NONBLOCKING) { |
|
194 if (fcntl(st->fd, F_SETFL, flags | O_NONBLOCK) != 0) { |
|
195 perror("fcntl"); |
|
196 // TODO: error |
|
197 } |
|
198 } |
|
199 } |
|
200 |
|
201 int net_sys_poll(SysStream *st, EventHandler *ev, int events, Event *cb) { |
|
202 switch(events) { |
|
203 default: return -1; |
|
204 case IO_POLL_NONE: return ev_remove_poll(ev, st->fd); |
|
205 case IO_POLL_IN: return ev_pollin(ev, st->fd, cb); |
|
206 case IO_POLL_OUT: return ev_pollout(ev, st->fd, cb); |
|
207 case IO_POLL_IN | IO_POLL_OUT: return -1; // TODO: implement |
|
208 } |
|
209 } |
|
210 |
173 #elif defined(XP_WIN32) |
211 #elif defined(XP_WIN32) |
174 |
212 |
175 ssize_t net_sys_write(SysStream *st, void *buf, size_t nbytes) { |
213 ssize_t net_sys_write(SysStream *st, void *buf, size_t nbytes) { |
176 int ret = send(st->fd, buf, nbytes, 0); |
214 int ret = send(st->fd, buf, nbytes, 0); |
177 if(ret == SOCKET_ERROR) { |
215 if(ret == SOCKET_ERROR) { |
285 if(st->chunked_enc) { |
323 if(st->chunked_enc) { |
286 st->fd->write(st->fd, "0\r\n\r\n", 5); |
324 st->fd->write(st->fd, "0\r\n\r\n", 5); |
287 } |
325 } |
288 } |
326 } |
289 |
327 |
|
328 void net_http_setmode(HttpStream *st, int mode) { |
|
329 st->fd->setmode(st->fd, mode); |
|
330 } |
|
331 |
|
332 int net_http_poll(HttpStream *st, EventHandler *ev, int events, Event *cb) { |
|
333 return st->fd->poll(st->fd, ev, events, cb); |
|
334 } |
|
335 |
290 |
336 |
291 /* |
337 /* |
292 * SSLStream implementation |
338 * SSLStream implementation |
293 */ |
339 */ |
294 |
340 |
339 |
385 |
340 void net_ssl_finish(SSLStream *st) { |
386 void net_ssl_finish(SSLStream *st) { |
341 |
387 |
342 } |
388 } |
343 |
389 |
|
390 void net_ssl_setmode(SSLStream *st, int mode) { |
|
391 int flags; |
|
392 if (-1 == (flags = fcntl(SSL_get_fd(st->ssl), F_GETFL, 0))) { |
|
393 flags = 0; |
|
394 } |
|
395 if(mode == IO_MODE_BLOCKING) { |
|
396 if (fcntl(SSL_get_fd(st->ssl), F_SETFL, flags & ~O_NONBLOCK) != 0) { |
|
397 perror("fcntl"); |
|
398 // TODO: error |
|
399 } |
|
400 } else if(mode == IO_MODE_NONBLOCKING) { |
|
401 if (fcntl(SSL_get_fd(st->ssl), F_SETFL, flags | O_NONBLOCK) != 0) { |
|
402 perror("fcntl"); |
|
403 // TODO: error |
|
404 } |
|
405 } |
|
406 } |
|
407 |
|
408 int net_ssl_poll(SSLStream *st, EventHandler *ev, int events, Event *cb) { |
|
409 int fd = SSL_get_fd(st->ssl); |
|
410 switch(events) { |
|
411 default: return -1; |
|
412 case IO_POLL_NONE: return ev_remove_poll(ev, fd); |
|
413 case IO_POLL_IN: return ev_pollin(ev, fd, cb); |
|
414 case IO_POLL_OUT: return ev_pollout(ev, fd, cb); |
|
415 case IO_POLL_IN | IO_POLL_OUT: return -1; // TODO: implement |
|
416 } |
|
417 } |
344 |
418 |
345 /* -------------------- public nsapi network functions -------------------- */ |
419 /* -------------------- public nsapi network functions -------------------- */ |
346 |
420 |
347 ssize_t net_read(SYS_NETFD fd, void *buf, size_t nbytes) { |
421 ssize_t net_read(SYS_NETFD fd, void *buf, size_t nbytes) { |
348 ssize_t r = ((IOStream*)fd)->read(fd, buf, nbytes); |
422 ssize_t r = ((IOStream*)fd)->read(fd, buf, nbytes); |
349 if(r == 0) { |
423 if(r == 0) { |
350 return IO_EOF; |
424 return IO_EOF; |
|
425 } else if(r < 0) { |
|
426 ((IOStream*)fd)->io_errno = errno; |
|
427 return IO_ERROR; |
351 } |
428 } |
352 return r; |
429 return r; |
353 } |
430 } |
354 |
431 |
355 ssize_t net_write(SYS_NETFD fd, void *buf, size_t nbytes) { |
432 ssize_t net_write(SYS_NETFD fd, void *buf, size_t nbytes) { |
356 ssize_t r = ((IOStream*)fd)->write(fd, buf, nbytes); |
433 ssize_t r = ((IOStream*)fd)->write(fd, buf, nbytes); |
357 if(r < 0) { |
434 if(r < 0) { |
|
435 ((IOStream*)fd)->io_errno = errno; |
358 return IO_ERROR; |
436 return IO_ERROR; |
359 } |
437 } |
360 return r; |
438 return r; |
361 } |
439 } |
362 |
440 |
363 ssize_t net_writev(SYS_NETFD fd, struct iovec *iovec, int iovcnt) { |
441 ssize_t net_writev(SYS_NETFD fd, struct iovec *iovec, int iovcnt) { |
364 ssize_t r = ((IOStream*)fd)->writev(fd, iovec, iovcnt); |
442 ssize_t r = ((IOStream*)fd)->writev(fd, iovec, iovcnt); |
365 if(r < 0) { |
443 if(r < 0) { |
|
444 ((IOStream*)fd)->io_errno = errno; |
366 return IO_ERROR; |
445 return IO_ERROR; |
367 } |
446 } |
368 return r; |
447 return r; |
369 } |
448 } |
370 |
449 |
373 va_start(arg, format); |
452 va_start(arg, format); |
374 sstr_t buf = ucx_vasprintf(ucx_default_allocator(), format, arg); |
453 sstr_t buf = ucx_vasprintf(ucx_default_allocator(), format, arg); |
375 ssize_t r = net_write(fd, buf.ptr, buf.length); |
454 ssize_t r = net_write(fd, buf.ptr, buf.length); |
376 free(buf.ptr); |
455 free(buf.ptr); |
377 va_end(arg); |
456 va_end(arg); |
|
457 if(r < 0) { |
|
458 ((IOStream*)fd)->io_errno = errno; |
|
459 } |
378 return r; |
460 return r; |
379 } |
461 } |
380 |
462 |
381 ssize_t net_sendfile(SYS_NETFD fd, sendfiledata *sfd) { |
463 ssize_t net_sendfile(SYS_NETFD fd, sendfiledata *sfd) { |
382 IOStream *out = fd; |
464 IOStream *out = fd; |
383 if(out->sendfile && sfd->fd && sfd->fd->fd != -1) { |
465 if(out->sendfile && sfd->fd && sfd->fd->fd != -1) { |
384 ssize_t r = out->sendfile(fd, sfd); |
466 ssize_t r = out->sendfile(fd, sfd); |
385 if(r < 0) { |
467 if(r < 0) { |
|
468 out->io_errno = errno; |
386 return IO_ERROR; |
469 return IO_ERROR; |
387 } |
470 } |
|
471 return r; |
388 } else { |
472 } else { |
389 // stream/file does not support sendfile |
473 // stream/file does not support sendfile |
390 // do regular copy |
474 // do regular copy |
391 return net_fallback_sendfile(out, sfd); |
475 return net_fallback_sendfile(out, sfd); |
392 } |
476 } |
393 return IO_ERROR; |
|
394 } |
477 } |
395 |
478 |
396 // private |
479 // private |
397 ssize_t net_fallback_sendfile(IOStream *fd, sendfiledata *sfd) { |
480 ssize_t net_fallback_sendfile(IOStream *fd, sendfiledata *sfd) { |
398 char *buf = malloc(4096); |
481 char *buf = malloc(4096); |