moonbridge
changeset 250:28bffa2af1ec
Perform TLS handshake in :read and :write methods and store TLS_WANT_POLLIN, TLS_WANT_POLLOUT in handle structure
author | jbe |
---|---|
date | Fri Aug 26 23:15:56 2016 +0200 (2016-08-26) |
parents | 53962483bf1c |
children | f3988723732a |
files | moonbridge_io.c |
line diff
1.1 --- a/moonbridge_io.c Fri Aug 26 22:04:08 2016 +0200 1.2 +++ b/moonbridge_io.c Fri Aug 26 23:15:56 2016 +0200 1.3 @@ -83,7 +83,9 @@ 1.4 char readbuf[MOONBR_IO_READBUFLEN]; 1.5 char writebuf[MOONBR_IO_WRITEBUFLEN]; 1.6 #ifdef MOONBR_IO_USE_TLS 1.7 - struct tls *tls, *servertls; 1.8 + struct tls *tls; 1.9 + struct tls *servertls; 1.10 + int tlshandshake; 1.11 #endif 1.12 } moonbr_io_handle_t; 1.13 1.14 @@ -277,15 +279,34 @@ 1.15 handle->readbufout = 0; 1.16 #ifdef MOONBR_IO_USE_TLS 1.17 if (handle->tls) { 1.18 - do bytesread = tls_read(handle->tls, handle->readbuf, MOONBR_IO_READBUFLEN); 1.19 - while (!nonblocking && (bytesread == TLS_WANT_POLLIN || bytesread == TLS_WANT_POLLOUT)); 1.20 - if (bytesread == TLS_WANT_POLLIN || bytesread == TLS_WANT_POLLOUT) { 1.21 - errno = EAGAIN; 1.22 - } else if (bytesread < 0) { 1.23 - lua_pushnil(L); 1.24 - lua_pushstring(L, tls_error(handle->tls)); 1.25 - return 2; 1.26 - } 1.27 + do { 1.28 + if (!handle->tlshandshake) { 1.29 + do bytesread = tls_handshake(handle->tls); 1.30 + while (!nonblocking && (bytesread == TLS_WANT_POLLIN || bytesread == TLS_WANT_POLLOUT)); 1.31 + if (bytesread == TLS_WANT_POLLIN || bytesread == TLS_WANT_POLLOUT) { 1.32 + handle->tlshandshake = bytesread; 1.33 + errno = EAGAIN; 1.34 + break; 1.35 + } 1.36 + if (bytesread < 0) { 1.37 + lua_pushnil(L); 1.38 + lua_pushstring(L, tls_error(handle->tls)); 1.39 + return 2; 1.40 + } 1.41 + handle->tlshandshake = 1; 1.42 + } 1.43 + do bytesread = tls_read(handle->tls, handle->readbuf, MOONBR_IO_READBUFLEN); 1.44 + while (!nonblocking && (bytesread == TLS_WANT_POLLIN || bytesread == TLS_WANT_POLLOUT)); 1.45 + if (bytesread == TLS_WANT_POLLIN || bytesread == TLS_WANT_POLLOUT) { 1.46 + errno = EAGAIN; 1.47 + break; 1.48 + } 1.49 + if (bytesread < 0) { 1.50 + lua_pushnil(L); 1.51 + lua_pushstring(L, tls_error(handle->tls)); 1.52 + return 2; 1.53 + } 1.54 + } while (0); 1.55 } 1.56 else 1.57 #endif 1.58 @@ -452,6 +473,41 @@ 1.59 1.60 moonbr_io_yield_wrapper(moonbr_io_drain_yield, moonbr_io_drain_call); 1.61 1.62 +#ifdef MOONBR_IO_USE_TLS 1.63 +#define moonbr_io_write_tls(buf, buflen) \ 1.64 + if (handle->tls) { \ 1.65 + do { \ 1.66 + if (!handle->tlshandshake) { \ 1.67 + do written = tls_handshake(handle->tls); \ 1.68 + while (!nonblocking && (written == TLS_WANT_POLLIN || written == TLS_WANT_POLLOUT)); \ 1.69 + if (written == TLS_WANT_POLLIN || written == TLS_WANT_POLLOUT) { \ 1.70 + handle->tlshandshake = written; \ 1.71 + errno = EAGAIN; \ 1.72 + break; \ 1.73 + } \ 1.74 + if (written < 0) { \ 1.75 + lua_pushnil(L); \ 1.76 + lua_pushstring(L, tls_error(handle->tls)); \ 1.77 + return 2; \ 1.78 + } \ 1.79 + handle->tlshandshake = 1; \ 1.80 + } \ 1.81 + do written = tls_write(handle->tls, (buf), (buflen)); \ 1.82 + while (!nonblocking && (written == TLS_WANT_POLLIN || written == TLS_WANT_POLLOUT)); \ 1.83 + if (written == TLS_WANT_POLLIN || written == TLS_WANT_POLLOUT) { \ 1.84 + errno = EAGAIN; \ 1.85 + break; \ 1.86 + } \ 1.87 + if (written < 0) { \ 1.88 + lua_pushnil(L); \ 1.89 + lua_pushstring(L, tls_error(handle->tls)); \ 1.90 + return 2; \ 1.91 + } \ 1.92 + } while (0); \ 1.93 + } \ 1.94 + else 1.95 +#endif 1.96 + 1.97 static int moonbr_io_write_impl(lua_State *L, int nonblocking, int flush) { 1.98 moonbr_io_handle_t *handle; 1.99 int i, top; 1.100 @@ -504,18 +560,10 @@ 1.101 while (handle->writebufout < MOONBR_IO_WRITEBUFLEN) { 1.102 moonbr_io_handle_set_nopush(L, handle, 1); 1.103 #ifdef MOONBR_IO_USE_TLS 1.104 - if (handle->tls) { 1.105 - do written = tls_write(handle->tls, handle->writebuf + handle->writebufout, MOONBR_IO_WRITEBUFLEN - handle->writebufout); 1.106 - while (!nonblocking && (written == TLS_WANT_POLLIN || written == TLS_WANT_POLLOUT)); 1.107 - if (written == TLS_WANT_POLLIN || written == TLS_WANT_POLLOUT) { 1.108 - errno = EAGAIN; 1.109 - } else if (written < 0) { 1.110 - lua_pushnil(L); 1.111 - lua_pushstring(L, tls_error(handle->tls)); 1.112 - return 2; 1.113 - } 1.114 - } 1.115 - else 1.116 + moonbr_io_write_tls( 1.117 + handle->writebuf + handle->writebufout, 1.118 + MOONBR_IO_WRITEBUFLEN - handle->writebufout 1.119 + ) 1.120 #endif 1.121 written = write( 1.122 handle->fd, 1.123 @@ -556,18 +604,10 @@ 1.124 while (handle->flushedleft) { 1.125 moonbr_io_handle_set_nopush(L, handle, 1); 1.126 #ifdef MOONBR_IO_USE_TLS 1.127 - if (handle->tls) { 1.128 - do written = tls_write(handle->tls, handle->writebuf + handle->writebufout, handle->writebufin - handle->writebufout); 1.129 - while (!nonblocking && (written == TLS_WANT_POLLIN || written == TLS_WANT_POLLOUT)); 1.130 - if (written == TLS_WANT_POLLIN || written == TLS_WANT_POLLOUT) { 1.131 - errno = EAGAIN; 1.132 - } else if (written < 0) { 1.133 - lua_pushnil(L); 1.134 - lua_pushstring(L, tls_error(handle->tls)); 1.135 - return 2; 1.136 - } 1.137 - } 1.138 - else 1.139 + moonbr_io_write_tls( 1.140 + handle->writebuf + handle->writebufout, 1.141 + handle->writebufin - handle->writebufout 1.142 + ) 1.143 #endif 1.144 written = write( 1.145 handle->fd, 1.146 @@ -844,6 +884,7 @@ 1.147 #ifdef MOONBR_IO_USE_TLS 1.148 handle->tls = NULL; 1.149 handle->servertls = NULL; 1.150 + handle->tlshandshake = 0; 1.151 #endif 1.152 handle->fd = *fd; /* required for set_linger call */ 1.153 moonbr_io_handle_set_linger(L, handle, 0); 1.154 @@ -1583,10 +1624,34 @@ 1.155 1.156 moonbr_io_yield_wrapper(moonbr_io_wait_yield, moonbr_io_wait_call); 1.157 1.158 +#ifdef MOONBR_IO_USE_TLS 1.159 +#define moonbr_io_poll_tls() \ 1.160 + if (!handle->tlshandshake) { \ 1.161 + lua_pushboolean(L, 1); \ 1.162 + return 1; \ 1.163 + } \ 1.164 + if (handle->tlshandshake == TLS_WANT_POLLIN) { \ 1.165 + if (fd < 0) { \ 1.166 + lua_pushboolean(L, 1); \ 1.167 + return 1; \ 1.168 + } \ 1.169 + FD_SET(fd, &readfds); \ 1.170 + if (fd+1 > nfds) nfds = fd+1; \ 1.171 + continue; \ 1.172 + } \ 1.173 + if (handle->tlshandshake == TLS_WANT_POLLOUT) { \ 1.174 + if (fd < 0) { \ 1.175 + lua_pushboolean(L, 1); \ 1.176 + return 1; \ 1.177 + } \ 1.178 + FD_SET(fd, &writefds); \ 1.179 + if (fd+1 > nfds) nfds = fd+1; \ 1.180 + continue; \ 1.181 + } \ 1.182 + while (0) 1.183 +#endif 1.184 + 1.185 static int moonbr_io_poll(lua_State *L) { 1.186 -#if MOONBR_IO_USE_TLS 1.187 - // TODO: tls_handshake must probably not be called when handshake has been completed 1.188 -#endif 1.189 moonbr_io_handle_t *handle; 1.190 moonbr_io_listener_t *listener; 1.191 int fd, isnum; 1.192 @@ -1606,16 +1671,7 @@ 1.193 if (handle->closed) luaL_error(L, "Attempt to poll a closed connection"); 1.194 fd = handle->fd; 1.195 #if MOONBR_IO_USE_TLS 1.196 - if (handle->tls && tls_handshake(handle->tls) == TLS_WANT_POLLOUT) { 1.197 - if (fd < 0) { 1.198 - // TODO? 1.199 - lua_pushboolean(L, 1); 1.200 - return 1; 1.201 - } 1.202 - FD_SET(fd, &writefds); 1.203 - if (fd+1 > nfds) nfds = fd+1; 1.204 - continue; 1.205 - } 1.206 + moonbr_io_poll_tls(); 1.207 #endif 1.208 if ( 1.209 fd < 0 || /* fake EOF to simulate shutdown if fd < 0 */ 1.210 @@ -1650,11 +1706,7 @@ 1.211 if (handle->finished) luaL_error(L, "Attempt to write-poll a finished connection"); 1.212 fd = handle->fd; 1.213 #if MOONBR_IO_USE_TLS 1.214 - if (handle->tls && tls_handshake(handle->tls) == TLS_WANT_POLLIN) { 1.215 - FD_SET(fd, &readfds); 1.216 - if (fd+1 > nfds) nfds = fd+1; 1.217 - continue; 1.218 - } 1.219 + moonbr_io_poll_tls(); 1.220 #endif 1.221 } else { 1.222 listener = luaL_testudata(L, -2, MOONBR_IO_LISTENER_MT_REGKEY);