moonbridge
diff moonbridge_io.c @ 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 |
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