X-Git-Url: http://nitlanguage.org diff --git a/lib/libevent.nit b/lib/libevent.nit index 9cbe38e..36de40f 100644 --- a/lib/libevent.nit +++ b/lib/libevent.nit @@ -22,18 +22,25 @@ module libevent is pkgconfig("libevent") in "C header" `{ - #include - #include - #include - #include - #include - #include #include #include `} in "C" `{ + #include + #include + #include + #include + #include + + #include + #include + #include + #include + +// Protect callbacks for compatibility with light FFI +#ifdef Connection_decr_ref // Callback forwarded to 'Connection.write_callback' static void c_write_cb(struct bufferevent *bev, Connection ctx) { Connection_write_callback(ctx); @@ -54,10 +61,12 @@ in "C" `{ // Callback forwarded to 'ConnectionFactory.accept_connection' static void accept_connection_cb(struct evconnlistener *listener, evutil_socket_t fd, - struct sockaddr *address, int socklen, ConnectionFactory ctx) + struct sockaddr *addrin, int socklen, ConnectionFactory ctx) { - ConnectionFactory_accept_connection(ctx, listener, fd, address, socklen); + ConnectionFactory_accept_connection(ctx, listener, fd, addrin, socklen); } +#endif + `} # Structure to hold information and state for a Libevent dispatch loop. @@ -346,6 +355,10 @@ extern class ConnectionListener `{ struct evconnlistener * `} struct hostent *hostent = gethostbyname(address); + if (!hostent) { + return NULL; + } + memset(&sin, 0, sizeof(sin)); sin.sin_family = hostent->h_addrtype; sin.sin_port = htons(port); @@ -388,17 +401,26 @@ class ConnectionFactory # Accept a connection on `listener` # # By default, it creates a new NativeBufferEvent and calls `spawn_connection`. - fun accept_connection(listener: ConnectionListener, fd: Int, address: Pointer, socklen: Int) + fun accept_connection(listener: ConnectionListener, fd: Int, addrin: Pointer, socklen: Int) do var base = listener.base var bev = new NativeBufferEvent.socket(base, fd, bev_opt_close_on_free) - var conn = spawn_connection(bev) + + # Human representation of remote client address + var addr_len = 46 # Longest possible IPv6 address + null byte + var addr_buf = new NativeString(addr_len) + addr_buf = addrin_to_address(addrin, addr_buf, addr_len) + var addr = if addr_buf.address_is_null then + "Unknown address" + else addr_buf.to_s + + var conn = spawn_connection(bev, addr) bev.enable ev_read|ev_write bev.setcb conn end # Create a new `Connection` object for `buffer_event` - fun spawn_connection(buffer_event: NativeBufferEvent): Connection + fun spawn_connection(buffer_event: NativeBufferEvent, address: String): Connection do return new Connection(buffer_event) end @@ -412,4 +434,19 @@ class ConnectionFactory end return listener end + + # Put string representation of source `address` into `buf` + private fun addrin_to_address(address: Pointer, buf: NativeString, buf_len: Int): NativeString `{ + struct sockaddr *addrin = (struct sockaddr*)address; + + if (addrin->sa_family == AF_INET) { + struct in_addr *src = &((struct sockaddr_in*)addrin)->sin_addr; + return (char *)inet_ntop(addrin->sa_family, src, buf, buf_len); + } + else if (addrin->sa_family == AF_INET6) { + struct in6_addr *src = &((struct sockaddr_in6*)addrin)->sin6_addr; + return (char *)inet_ntop(addrin->sa_family, src, buf, buf_len); + } + return NULL; + `} end