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);

Impressum / About Us