# HG changeset patch # User jbe # Date 1428527589 -7200 # Node ID 06d965df8a0c1ecdfa0e391a979783bbab669c8f # Parent 8fce76ef321f1c4237b351571361372ea702999b Moved local/remote address extraction/formatting to I/O library diff -r 8fce76ef321f -r 06d965df8a0c moonbridge.c --- a/moonbridge.c Wed Apr 08 20:38:18 2015 +0200 +++ b/moonbridge.c Wed Apr 08 23:13:09 2015 +0200 @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -843,7 +842,7 @@ } if (controlmsg == MOONBR_COMMAND_TERMINATE) break; listener = moonbr_child_receive_pointer(MOONBR_FD_CONTROL); - if (fd) moonbr_io_pushhandle(L, fd, controlmsg == MOONBR_SOCKETTYPE_NETWORK); + if (fd) moonbr_io_pushhandle(L, fd); lua_rawgetp(L, LUA_REGISTRYINDEX, moonbr_luakey_connect_func(pool)); if (!fd) { lua_newtable(L); @@ -854,69 +853,6 @@ lua_setfield(L, -2, "interval"); } else { lua_pushvalue(L, -2); - if (listener->proto == MOONBR_PROTO_TCP6) { - struct sockaddr_in6 addr; - char addrstrbuf[INET6_ADDRSTRLEN]; - const char *addrstr; - socklen_t addr_len = sizeof(struct sockaddr_in6); - if (getsockname(fd, (struct sockaddr *)&addr, &addr_len)) { - moonbr_child_log_errno("Could not get local IP address/port"); - } else { - addrstr = inet_ntop(AF_INET6, addr.sin6_addr.s6_addr, addrstrbuf, sizeof(addrstrbuf)); - if (!addrstr) { - moonbr_child_log_errno("Could not format local IP address"); - } else { - lua_pushstring(L, addrstr); - lua_setfield(L, -2, "local_ip6"); - } - lua_pushinteger(L, ntohs(addr.sin6_port)); - lua_setfield(L, -2, "local_tcpport"); - } - if (getpeername(fd, (struct sockaddr *)&addr, &addr_len)) { - moonbr_child_log_errno("Could not get remote IP address/port"); - } else { - addrstr = inet_ntop(AF_INET6, addr.sin6_addr.s6_addr, addrstrbuf, sizeof(addrstrbuf)); - if (!addrstr) { - moonbr_child_log_errno("Could not format remote IP address"); - } else { - lua_pushstring(L, addrstr); - lua_setfield(L, -2, "remote_ip6"); - } - lua_pushinteger(L, ntohs(addr.sin6_port)); - lua_setfield(L, -2, "remote_tcpport"); - } - } else if (listener->proto == MOONBR_PROTO_TCP4) { - struct sockaddr_in addr; - char addrstrbuf[INET_ADDRSTRLEN]; - const char *addrstr; - socklen_t addr_len = sizeof(struct sockaddr_in); - if (getsockname(fd, (struct sockaddr *)&addr, &addr_len)) { - moonbr_child_log_errno("Could not get local IP address/port"); - } else { - addrstr = inet_ntop(AF_INET, &addr.sin_addr.s_addr, addrstrbuf, sizeof(addrstrbuf)); - if (!addrstr) { - moonbr_child_log_errno("Could not format local IP address"); - } else { - lua_pushstring(L, addrstr); - lua_setfield(L, -2, "local_ip4"); - } - lua_pushinteger(L, ntohs(addr.sin_port)); - lua_setfield(L, -2, "local_tcpport"); - } - if (getpeername(fd, (struct sockaddr *)&addr, &addr_len)) { - moonbr_child_log_errno("Could not get remote IP address/port"); - } else { - addrstr = inet_ntop(AF_INET, &addr.sin_addr.s_addr, addrstrbuf, sizeof(addrstrbuf)); - if (!addrstr) { - moonbr_child_log_errno("Could not format remote IP address"); - } else { - lua_pushstring(L, addrstr); - lua_setfield(L, -2, "remote_ip4"); - } - lua_pushinteger(L, ntohs(addr.sin_port)); - lua_setfield(L, -2, "remote_tcpport"); - } - } } if (lua_pcall(L, 1, 1, 1)) { fprintf(stderr, "Error in \"connect\" function: %s\n", lua_tostring(L, -1)); diff -r 8fce76ef321f -r 06d965df8a0c moonbridge_io.c --- a/moonbridge_io.c Wed Apr 08 20:38:18 2015 +0200 +++ b/moonbridge_io.c Wed Apr 08 23:13:09 2015 +0200 @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -29,7 +30,8 @@ typedef struct { int fd; - int isnetwork; + int issock; + sa_family_t addrfam; int finished; int closed; int nonblocking; @@ -78,7 +80,7 @@ static void moonbr_io_handle_set_linger(lua_State *L, moonbr_io_handle_t *handle, int timeout) { struct linger lingerval = { 0, }; - if (!handle->isnetwork) return; + if (!handle->issock) return; if (timeout >= 0) { lingerval.l_onoff = 1; lingerval.l_linger = timeout; @@ -94,7 +96,10 @@ static void moonbr_io_handle_set_nopush(lua_State *L, moonbr_io_handle_t *handle, int nopush) { #if defined(TCP_NOPUSH) || defined(TCP_CORK) - if (!handle->isnetwork || handle->nopush == nopush) return; + if ( + !(handle->addrfam == AF_INET6 || handle->addrfam == AF_INET) || + handle->nopush == nopush + ) return; #if defined(TCP_NOPUSH) if (setsockopt(handle->fd, IPPROTO_TCP, TCP_NOPUSH, &nopush, sizeof(nopush))) { #elif defined(TCP_CORK) @@ -387,7 +392,7 @@ } } handle->finished = 1; - if (handle->isnetwork) { + if (handle->addrfam == AF_INET6 || handle->addrfam == AF_INET) { if (shutdown(handle->fd, SHUT_WR)) { moonbr_io_errmsg(); lua_pushnil(L); @@ -470,11 +475,23 @@ } } -void moonbr_io_pushhandle(lua_State *L, int fd, int isnetwork) { +void moonbr_io_pushhandle(lua_State *L, int fd) { moonbr_io_handle_t *handle; + struct sockaddr addr; + socklen_t addrlen; handle = lua_newuserdata(L, sizeof(moonbr_io_handle_t)); handle->fd = fd; - handle->isnetwork = isnetwork; + addrlen = sizeof(addr); + if (getsockname(fd, &addr, &addrlen)) { + if (errno != ENOTSOCK) { + moonbr_io_errmsg(); + luaL_error(L, "Unexpected error when examining socket: %s", errmsg); + } + handle->issock = 0; + } else { + handle->issock = 1; + handle->addrfam = addr.sa_family; + } handle->finished = 0; handle->closed = 0; handle->nonblocking = -1; @@ -496,6 +513,85 @@ lua_newtable(L); lua_setfield(L, -2, "writequeue"); lua_newtable(L); // public + if (handle->addrfam == AF_INET6) { + struct sockaddr_in6 addr_in6; + char addrstrbuf[INET6_ADDRSTRLEN]; + const char *addrstr; + addrlen = sizeof(addr_in6); + if (getsockname(fd, (struct sockaddr *)&addr_in6, &addrlen)) { + moonbr_io_errmsg(); + luaL_error(L, "Could not determine local IP address/port: %s", errmsg); + } + if (addrlen > sizeof(addr_in6)) { + luaL_error(L, "Could not determine local IP address/port: buffer size exceeded"); + } + addrstr = inet_ntop(AF_INET6, addr_in6.sin6_addr.s6_addr, addrstrbuf, sizeof(addrstrbuf)); + if (!addrstr) { + moonbr_io_errmsg(); + luaL_error(L, "Could not format local IP address: %s", errmsg); + } else { + lua_pushstring(L, addrstr); + lua_setfield(L, -2, "local_ip6"); + } + lua_pushinteger(L, ntohs(addr_in6.sin6_port)); + lua_setfield(L, -2, "local_tcpport"); + if (getpeername(fd, (struct sockaddr *)&addr_in6, &addrlen)) { + moonbr_io_errmsg(); + luaL_error(L, "Could not determine remote IP address/port: %s", errmsg); + } + if (addrlen > sizeof(addr_in6)) { + luaL_error(L, "Could not determine remote IP address/port: buffer size exceeded"); + } + addrstr = inet_ntop(AF_INET6, addr_in6.sin6_addr.s6_addr, addrstrbuf, sizeof(addrstrbuf)); + if (!addrstr) { + moonbr_io_errmsg(); + luaL_error(L, "Could not format remote IP address: %s", errmsg); + } else { + lua_pushstring(L, addrstr); + lua_setfield(L, -2, "remote_ip6"); + } + lua_pushinteger(L, ntohs(addr_in6.sin6_port)); + lua_setfield(L, -2, "remote_tcpport"); + } else if (handle->addrfam == AF_INET) { + struct sockaddr_in addr_in; + char addrstrbuf[INET_ADDRSTRLEN]; + const char *addrstr; + addrlen = sizeof(addr_in); + if (getsockname(fd, (struct sockaddr *)&addr_in, &addrlen)) { + moonbr_io_errmsg(); + luaL_error(L, "Could not determine local IP address/port: %s", errmsg); + } + if (addrlen > sizeof(addr_in)) { + luaL_error(L, "Could not determine local IP address/port: buffer size exceeded"); + } + addrstr = inet_ntop(AF_INET, &addr_in.sin_addr.s_addr, addrstrbuf, sizeof(addrstrbuf)); + if (!addrstr) { + moonbr_io_errmsg(); + luaL_error(L, "Could not format local IP address: %s", errmsg); + } else { + lua_pushstring(L, addrstr); + lua_setfield(L, -2, "local_ip4"); + } + lua_pushinteger(L, ntohs(addr_in.sin_port)); + lua_setfield(L, -2, "local_tcpport"); + if (getpeername(fd, (struct sockaddr *)&addr_in, &addrlen)) { + moonbr_io_errmsg(); + luaL_error(L, "Could not determine remote IP address/port: %s", errmsg); + } + if (addrlen > sizeof(addr_in)) { + luaL_error(L, "Could not determine remote IP address/port: buffer size exceeded"); + } + addrstr = inet_ntop(AF_INET, &addr_in.sin_addr.s_addr, addrstrbuf, sizeof(addrstrbuf)); + if (!addrstr) { + moonbr_io_errmsg(); + luaL_error(L, "Could not format remote IP address: %s", errmsg); + } else { + lua_pushstring(L, addrstr); + lua_setfield(L, -2, "remote_ip4"); + } + lua_pushinteger(L, ntohs(addr_in.sin_port)); + lua_setfield(L, -2, "remote_tcpport"); + } luaL_getmetatable(L, MOONBR_IO_HANDLE_PUBLIC_MT_REGKEY); lua_setmetatable(L, -2); lua_setfield(L, -2, "public"); @@ -579,7 +675,7 @@ return 2; } } - moonbr_io_pushhandle(L, sock, 1); + moonbr_io_pushhandle(L, sock); return 1; } diff -r 8fce76ef321f -r 06d965df8a0c moonbridge_io.h --- a/moonbridge_io.h Wed Apr 08 20:38:18 2015 +0200 +++ b/moonbridge_io.h Wed Apr 08 23:13:09 2015 +0200 @@ -1,5 +1,5 @@ -void moonbr_io_pushhandle(lua_State *L, int fd, int useshutdown); +void moonbr_io_pushhandle(lua_State *L, int fd); void moonbr_io_closehandle(lua_State *L, int idx, int reset); int moonbr_io_tcpconnect(lua_State *L); int moonbr_io_tcpconnect_nb(lua_State *L);