moonbridge

changeset 256:ff7eea59be93

Bugfix: Do not throw (hard) Lua error in moonbr_io_handle_set_nonblocking, moonbr_io_handle_set_linger, and moonbr_io_handle_set_nopush (may cause Lua error on connection reset)
author jbe
date Sun Sep 18 00:59:31 2016 +0200 (2016-09-18)
parents a22a6c19457f
children 77a7ca00ad34
files moonbridge_io.c
line diff
     1.1 --- a/moonbridge_io.c	Sat Sep 17 22:08:35 2016 +0200
     1.2 +++ b/moonbridge_io.c	Sun Sep 18 00:59:31 2016 +0200
     1.3 @@ -128,82 +128,45 @@
     1.4      return lua_gettop(L); \
     1.5    }
     1.6  
     1.7 -static void moonbr_io_handle_set_nonblocking(lua_State *L, moonbr_io_handle_t *handle, int nonblocking) {
     1.8 +static int moonbr_io_handle_set_nonblocking(lua_State *L, moonbr_io_handle_t *handle, int nonblocking) {
     1.9    int flags;
    1.10 -  if (handle->nonblocking == nonblocking) return;
    1.11 +  if (handle->nonblocking == nonblocking) return 0;
    1.12    flags = fcntl(handle->fd, F_GETFL, 0);
    1.13 -  if (flags == -1) {
    1.14 -    moonbr_io_errmsg();
    1.15 -#ifdef MOONBR_IO_USE_TLS
    1.16 -    if (handle->tls) tls_close(handle->tls);
    1.17 -#endif
    1.18 -    close(handle->fd);
    1.19 -    handle->fd = -1;
    1.20 -    handle->closed = 1;
    1.21 -    luaL_error(L, "Unexpected error in fcntl call: %s", errmsg);
    1.22 -  }
    1.23 +  if (flags == -1) return -1;
    1.24    if (nonblocking) flags |= O_NONBLOCK;
    1.25    else flags &= ~O_NONBLOCK;
    1.26 -  if (fcntl(handle->fd, F_SETFL, flags) == -1) {
    1.27 -    moonbr_io_errmsg();
    1.28 -#ifdef MOONBR_IO_USE_TLS
    1.29 -    if (handle->tls) tls_close(handle->tls);
    1.30 -#endif
    1.31 -    close(handle->fd);
    1.32 -    handle->fd = -1;
    1.33 -    handle->closed = 1;
    1.34 -    luaL_error(L, "Unexpected error in fcntl call: %s", errmsg);
    1.35 -  }
    1.36 +  if (fcntl(handle->fd, F_SETFL, flags) == -1) return -1;
    1.37    handle->nonblocking = nonblocking;
    1.38 +  return 0;
    1.39  }
    1.40  
    1.41 -static void moonbr_io_handle_set_linger(lua_State *L, moonbr_io_handle_t *handle, int timeout) {
    1.42 +static int moonbr_io_handle_set_linger(lua_State *L, moonbr_io_handle_t *handle, int timeout) {
    1.43    struct linger lingerval = { 0, };
    1.44 -  if (!handle->issock) return;
    1.45 +  if (!handle->issock) return 0;
    1.46    if (timeout >= 0) {
    1.47      lingerval.l_onoff = 1;
    1.48      lingerval.l_linger = timeout;
    1.49    }
    1.50 -  if (setsockopt(handle->fd, SOL_SOCKET, SO_LINGER, &lingerval, sizeof(lingerval))) {
    1.51 -    moonbr_io_errmsg();
    1.52 -#ifdef MOONBR_IO_USE_TLS
    1.53 -    if (handle->tls) tls_close(handle->tls);
    1.54 -#endif
    1.55 -    close(handle->fd);
    1.56 -    handle->fd = -1;
    1.57 -    handle->closed = 1;
    1.58 -    luaL_error(L, "Unexpected error while setting SO_LINGER with setsockopt: %s", errmsg);
    1.59 -  }
    1.60 +  if (setsockopt(handle->fd, SOL_SOCKET, SO_LINGER, &lingerval, sizeof(lingerval))) return -1;
    1.61 +  return 0;
    1.62  }
    1.63  
    1.64 -static inline void moonbr_io_handle_set_nopush(lua_State *L, moonbr_io_handle_t *handle, int nopush) {
    1.65 +static inline int moonbr_io_handle_set_nopush(lua_State *L, moonbr_io_handle_t *handle, int nopush) {
    1.66  #if defined(TCP_NOPUSH) || defined(TCP_CORK)
    1.67    if (
    1.68      !(handle->addrfam == AF_INET6 || handle->addrfam == AF_INET) ||
    1.69      handle->nopush == nopush
    1.70 -  ) return;
    1.71 +  ) return 0;
    1.72  #if defined(TCP_NOPUSH)
    1.73 -  if (setsockopt(handle->fd, IPPROTO_TCP, TCP_NOPUSH, &nopush, sizeof(nopush))) {
    1.74 +  if (setsockopt(handle->fd, IPPROTO_TCP, TCP_NOPUSH, &nopush, sizeof(nopush))) return -1;
    1.75  #elif defined(TCP_CORK)
    1.76 -  if (setsockopt(handle->fd, IPPROTO_TCP, TCP_CORK, &nopush, sizeof(nopush))) {
    1.77 -#endif
    1.78 -    moonbr_io_errmsg();
    1.79 -#ifdef MOONBR_IO_USE_TLS
    1.80 -    if (handle->tls) tls_close(handle->tls);
    1.81 +  if (setsockopt(handle->fd, IPPROTO_TCP, TCP_CORK, &nopush, sizeof(nopush))) return -1;
    1.82  #endif
    1.83 -    close(handle->fd);
    1.84 -    handle->fd = -1;
    1.85 -    handle->closed = 1;
    1.86 -#if defined(TCP_NOPUSH)
    1.87 -    luaL_error(L, "Unexpected error while setting TCP_NOPUSH with setsockopt: %s", errmsg);
    1.88 -#elif defined(TCP_CORK)
    1.89 -    luaL_error(L, "Unexpected error while setting TCP_CORK with setsockopt: %s", errmsg);
    1.90 -#endif
    1.91 -  }
    1.92    handle->nopush = nopush;
    1.93  #else
    1.94  #warning Neither TCP_NOPUSH nor TCP_CORK is available
    1.95  #endif
    1.96 +  return 0;
    1.97  }
    1.98  
    1.99  static int moonbr_io_read_impl(lua_State *L, int nonblocking, int drain) {
   1.100 @@ -239,7 +202,12 @@
   1.101      return 2;
   1.102    }
   1.103    handle->readerr = 1;
   1.104 -  moonbr_io_handle_set_nonblocking(L, handle, nonblocking);
   1.105 +  if (moonbr_io_handle_set_nonblocking(L, handle, nonblocking)) {
   1.106 +    moonbr_io_errmsg();
   1.107 +    lua_pushnil(L);
   1.108 +    lua_pushstring(L, errmsg);
   1.109 +    return 2;
   1.110 +  }
   1.111    if (!drain) luaL_buffinit(L, &luabuf);
   1.112    while (1) {
   1.113      remaining = -1;
   1.114 @@ -540,7 +508,12 @@
   1.115      return 2;
   1.116    }
   1.117    handle->writeerr = 1;
   1.118 -  moonbr_io_handle_set_nonblocking(L, handle, nonblocking);
   1.119 +  if (moonbr_io_handle_set_nonblocking(L, handle, nonblocking)) {
   1.120 +    moonbr_io_errmsg();
   1.121 +    lua_pushnil(L);
   1.122 +    lua_pushstring(L, errmsg);
   1.123 +    return 2;
   1.124 +  }
   1.125    top = lua_gettop(L);
   1.126    lua_getuservalue(L, 1);
   1.127    lua_getfield(L, -1, "writequeue");
   1.128 @@ -575,7 +548,12 @@
   1.129          handle->writeqoff += MOONBR_IO_WRITEBUFLEN - handle->writebufin;
   1.130          handle->writebufin = MOONBR_IO_WRITEBUFLEN;
   1.131          while (handle->writebufout < MOONBR_IO_WRITEBUFLEN) {
   1.132 -          moonbr_io_handle_set_nopush(L, handle, 1);
   1.133 +          if (moonbr_io_handle_set_nopush(L, handle, 1)) {
   1.134 +            moonbr_io_errmsg();
   1.135 +            lua_pushnil(L);
   1.136 +            lua_pushstring(L, errmsg);
   1.137 +            return 2;
   1.138 +          }
   1.139  #ifdef MOONBR_IO_USE_TLS
   1.140            moonbr_io_write_tls(
   1.141              handle->writebuf + handle->writebufout,
   1.142 @@ -602,7 +580,12 @@
   1.143              if (handle->flushedleft) {
   1.144                if (written >= handle->flushedleft) {
   1.145                  handle->flushedleft = 0;
   1.146 -                moonbr_io_handle_set_nopush(L, handle, 0);
   1.147 +                if (moonbr_io_handle_set_nopush(L, handle, 0)) {
   1.148 +                  moonbr_io_errmsg();
   1.149 +                  lua_pushnil(L);
   1.150 +                  lua_pushstring(L, errmsg);
   1.151 +                  return 2;
   1.152 +                }
   1.153                } else {
   1.154                  handle->flushedleft -= written;
   1.155                }
   1.156 @@ -619,7 +602,12 @@
   1.157      lua_rawseti(L, -2, handle->writeqout++);
   1.158    }
   1.159    while (handle->flushedleft) {
   1.160 -    moonbr_io_handle_set_nopush(L, handle, 1);
   1.161 +    if (moonbr_io_handle_set_nopush(L, handle, 1)) {
   1.162 +      moonbr_io_errmsg();
   1.163 +      lua_pushnil(L);
   1.164 +      lua_pushstring(L, errmsg);
   1.165 +      return 2;
   1.166 +    }
   1.167  #ifdef MOONBR_IO_USE_TLS
   1.168      moonbr_io_write_tls(
   1.169        handle->writebuf + handle->writebufout,
   1.170 @@ -646,7 +634,12 @@
   1.171        if (handle->flushedleft) {
   1.172          if (written >= handle->flushedleft) {
   1.173            handle->flushedleft = 0;
   1.174 -          moonbr_io_handle_set_nopush(L, handle, 0);
   1.175 +          if (moonbr_io_handle_set_nopush(L, handle, 0)) {
   1.176 +            moonbr_io_errmsg();
   1.177 +            lua_pushnil(L);
   1.178 +            lua_pushstring(L, errmsg);
   1.179 +            return 2;
   1.180 +          }
   1.181          } else {
   1.182            handle->flushedleft -= written;
   1.183          }
   1.184 @@ -795,18 +788,12 @@
   1.185        lua_pushvalue(L, 1);
   1.186        if (lua_pcall(L, 1, 2, 0)) {
   1.187          handle->closed = 1;
   1.188 -#ifdef MOONBR_IO_USE_TLS
   1.189 -        if (handle->tls) tls_close(handle->tls);
   1.190 -#endif
   1.191          close(handle->fd);
   1.192          handle->fd = -1;
   1.193          lua_error(L);
   1.194        }
   1.195        handle->closed = 1;
   1.196        if (!lua_toboolean(L, -2)) {
   1.197 -#ifdef MOONBR_IO_USE_TLS
   1.198 -        if (handle->tls) tls_close(handle->tls);
   1.199 -#endif
   1.200          close(handle->fd);
   1.201          handle->fd = -1;
   1.202          return 2;
   1.203 @@ -814,7 +801,14 @@
   1.204      } else {
   1.205        handle->closed = 1;
   1.206      }
   1.207 -    moonbr_io_handle_set_linger(L, handle, -1);
   1.208 +    if (moonbr_io_handle_set_linger(L, handle, -1)) {
   1.209 +      moonbr_io_errmsg();
   1.210 +      close(handle->fd);
   1.211 +      handle->fd = -1;
   1.212 +      lua_pushnil(L);
   1.213 +      lua_pushstring(L, errmsg);
   1.214 +      return 2;
   1.215 +    }
   1.216    } else {
   1.217      handle->closed = 1;
   1.218    }
   1.219 @@ -916,7 +910,11 @@
   1.220    handle->tlshandshake = 0;
   1.221  #endif
   1.222    handle->fd = *fd;  /* required for set_linger call */
   1.223 -  moonbr_io_handle_set_linger(L, handle, 0);
   1.224 +  if (moonbr_io_handle_set_linger(L, handle, 0)) {
   1.225 +    moonbr_io_errmsg();
   1.226 +    handle->fd = -1;
   1.227 +    luaL_error(L, "Unexpected error while setting SO_LINGER with setsockopt: %s", errmsg);
   1.228 +  }
   1.229    handle->fd = -1;  /* avoid closing incomplete handle */
   1.230    luaL_setmetatable(L, MOONBR_IO_HANDLE_MT_REGKEY);
   1.231    lua_newtable(L);  // uservalue

Impressum / About Us