moonbridge
diff moonbridge_io.c @ 107:06d965df8a0c
Moved local/remote address extraction/formatting to I/O library
author | jbe |
---|---|
date | Wed Apr 08 23:13:09 2015 +0200 (2015-04-08) |
parents | 8fce76ef321f |
children | 110493d29f90 |
line diff
1.1 --- a/moonbridge_io.c Wed Apr 08 20:38:18 2015 +0200 1.2 +++ b/moonbridge_io.c Wed Apr 08 23:13:09 2015 +0200 1.3 @@ -9,6 +9,7 @@ 1.4 #include <fcntl.h> 1.5 #include <netinet/in.h> 1.6 #include <netinet/tcp.h> 1.7 +#include <arpa/inet.h> 1.8 #include <sys/types.h> 1.9 #include <netdb.h> 1.10 1.11 @@ -29,7 +30,8 @@ 1.12 1.13 typedef struct { 1.14 int fd; 1.15 - int isnetwork; 1.16 + int issock; 1.17 + sa_family_t addrfam; 1.18 int finished; 1.19 int closed; 1.20 int nonblocking; 1.21 @@ -78,7 +80,7 @@ 1.22 1.23 static void moonbr_io_handle_set_linger(lua_State *L, moonbr_io_handle_t *handle, int timeout) { 1.24 struct linger lingerval = { 0, }; 1.25 - if (!handle->isnetwork) return; 1.26 + if (!handle->issock) return; 1.27 if (timeout >= 0) { 1.28 lingerval.l_onoff = 1; 1.29 lingerval.l_linger = timeout; 1.30 @@ -94,7 +96,10 @@ 1.31 1.32 static void moonbr_io_handle_set_nopush(lua_State *L, moonbr_io_handle_t *handle, int nopush) { 1.33 #if defined(TCP_NOPUSH) || defined(TCP_CORK) 1.34 - if (!handle->isnetwork || handle->nopush == nopush) return; 1.35 + if ( 1.36 + !(handle->addrfam == AF_INET6 || handle->addrfam == AF_INET) || 1.37 + handle->nopush == nopush 1.38 + ) return; 1.39 #if defined(TCP_NOPUSH) 1.40 if (setsockopt(handle->fd, IPPROTO_TCP, TCP_NOPUSH, &nopush, sizeof(nopush))) { 1.41 #elif defined(TCP_CORK) 1.42 @@ -387,7 +392,7 @@ 1.43 } 1.44 } 1.45 handle->finished = 1; 1.46 - if (handle->isnetwork) { 1.47 + if (handle->addrfam == AF_INET6 || handle->addrfam == AF_INET) { 1.48 if (shutdown(handle->fd, SHUT_WR)) { 1.49 moonbr_io_errmsg(); 1.50 lua_pushnil(L); 1.51 @@ -470,11 +475,23 @@ 1.52 } 1.53 } 1.54 1.55 -void moonbr_io_pushhandle(lua_State *L, int fd, int isnetwork) { 1.56 +void moonbr_io_pushhandle(lua_State *L, int fd) { 1.57 moonbr_io_handle_t *handle; 1.58 + struct sockaddr addr; 1.59 + socklen_t addrlen; 1.60 handle = lua_newuserdata(L, sizeof(moonbr_io_handle_t)); 1.61 handle->fd = fd; 1.62 - handle->isnetwork = isnetwork; 1.63 + addrlen = sizeof(addr); 1.64 + if (getsockname(fd, &addr, &addrlen)) { 1.65 + if (errno != ENOTSOCK) { 1.66 + moonbr_io_errmsg(); 1.67 + luaL_error(L, "Unexpected error when examining socket: %s", errmsg); 1.68 + } 1.69 + handle->issock = 0; 1.70 + } else { 1.71 + handle->issock = 1; 1.72 + handle->addrfam = addr.sa_family; 1.73 + } 1.74 handle->finished = 0; 1.75 handle->closed = 0; 1.76 handle->nonblocking = -1; 1.77 @@ -496,6 +513,85 @@ 1.78 lua_newtable(L); 1.79 lua_setfield(L, -2, "writequeue"); 1.80 lua_newtable(L); // public 1.81 + if (handle->addrfam == AF_INET6) { 1.82 + struct sockaddr_in6 addr_in6; 1.83 + char addrstrbuf[INET6_ADDRSTRLEN]; 1.84 + const char *addrstr; 1.85 + addrlen = sizeof(addr_in6); 1.86 + if (getsockname(fd, (struct sockaddr *)&addr_in6, &addrlen)) { 1.87 + moonbr_io_errmsg(); 1.88 + luaL_error(L, "Could not determine local IP address/port: %s", errmsg); 1.89 + } 1.90 + if (addrlen > sizeof(addr_in6)) { 1.91 + luaL_error(L, "Could not determine local IP address/port: buffer size exceeded"); 1.92 + } 1.93 + addrstr = inet_ntop(AF_INET6, addr_in6.sin6_addr.s6_addr, addrstrbuf, sizeof(addrstrbuf)); 1.94 + if (!addrstr) { 1.95 + moonbr_io_errmsg(); 1.96 + luaL_error(L, "Could not format local IP address: %s", errmsg); 1.97 + } else { 1.98 + lua_pushstring(L, addrstr); 1.99 + lua_setfield(L, -2, "local_ip6"); 1.100 + } 1.101 + lua_pushinteger(L, ntohs(addr_in6.sin6_port)); 1.102 + lua_setfield(L, -2, "local_tcpport"); 1.103 + if (getpeername(fd, (struct sockaddr *)&addr_in6, &addrlen)) { 1.104 + moonbr_io_errmsg(); 1.105 + luaL_error(L, "Could not determine remote IP address/port: %s", errmsg); 1.106 + } 1.107 + if (addrlen > sizeof(addr_in6)) { 1.108 + luaL_error(L, "Could not determine remote IP address/port: buffer size exceeded"); 1.109 + } 1.110 + addrstr = inet_ntop(AF_INET6, addr_in6.sin6_addr.s6_addr, addrstrbuf, sizeof(addrstrbuf)); 1.111 + if (!addrstr) { 1.112 + moonbr_io_errmsg(); 1.113 + luaL_error(L, "Could not format remote IP address: %s", errmsg); 1.114 + } else { 1.115 + lua_pushstring(L, addrstr); 1.116 + lua_setfield(L, -2, "remote_ip6"); 1.117 + } 1.118 + lua_pushinteger(L, ntohs(addr_in6.sin6_port)); 1.119 + lua_setfield(L, -2, "remote_tcpport"); 1.120 + } else if (handle->addrfam == AF_INET) { 1.121 + struct sockaddr_in addr_in; 1.122 + char addrstrbuf[INET_ADDRSTRLEN]; 1.123 + const char *addrstr; 1.124 + addrlen = sizeof(addr_in); 1.125 + if (getsockname(fd, (struct sockaddr *)&addr_in, &addrlen)) { 1.126 + moonbr_io_errmsg(); 1.127 + luaL_error(L, "Could not determine local IP address/port: %s", errmsg); 1.128 + } 1.129 + if (addrlen > sizeof(addr_in)) { 1.130 + luaL_error(L, "Could not determine local IP address/port: buffer size exceeded"); 1.131 + } 1.132 + addrstr = inet_ntop(AF_INET, &addr_in.sin_addr.s_addr, addrstrbuf, sizeof(addrstrbuf)); 1.133 + if (!addrstr) { 1.134 + moonbr_io_errmsg(); 1.135 + luaL_error(L, "Could not format local IP address: %s", errmsg); 1.136 + } else { 1.137 + lua_pushstring(L, addrstr); 1.138 + lua_setfield(L, -2, "local_ip4"); 1.139 + } 1.140 + lua_pushinteger(L, ntohs(addr_in.sin_port)); 1.141 + lua_setfield(L, -2, "local_tcpport"); 1.142 + if (getpeername(fd, (struct sockaddr *)&addr_in, &addrlen)) { 1.143 + moonbr_io_errmsg(); 1.144 + luaL_error(L, "Could not determine remote IP address/port: %s", errmsg); 1.145 + } 1.146 + if (addrlen > sizeof(addr_in)) { 1.147 + luaL_error(L, "Could not determine remote IP address/port: buffer size exceeded"); 1.148 + } 1.149 + addrstr = inet_ntop(AF_INET, &addr_in.sin_addr.s_addr, addrstrbuf, sizeof(addrstrbuf)); 1.150 + if (!addrstr) { 1.151 + moonbr_io_errmsg(); 1.152 + luaL_error(L, "Could not format remote IP address: %s", errmsg); 1.153 + } else { 1.154 + lua_pushstring(L, addrstr); 1.155 + lua_setfield(L, -2, "remote_ip4"); 1.156 + } 1.157 + lua_pushinteger(L, ntohs(addr_in.sin_port)); 1.158 + lua_setfield(L, -2, "remote_tcpport"); 1.159 + } 1.160 luaL_getmetatable(L, MOONBR_IO_HANDLE_PUBLIC_MT_REGKEY); 1.161 lua_setmetatable(L, -2); 1.162 lua_setfield(L, -2, "public"); 1.163 @@ -579,7 +675,7 @@ 1.164 return 2; 1.165 } 1.166 } 1.167 - moonbr_io_pushhandle(L, sock, 1); 1.168 + moonbr_io_pushhandle(L, sock); 1.169 return 1; 1.170 } 1.171