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  

Impressum / About Us