diff --git a/src/AsyncSocket.h b/src/AsyncSocket.h index 3c991f93e..1d8fc9fed 100644 --- a/src/AsyncSocket.h +++ b/src/AsyncSocket.h @@ -219,10 +219,15 @@ struct AsyncSocket { /* Returns the remote IP address or empty string on failure */ std::string_view getRemoteAddress() { +#ifdef UWS_REMOTE_ADDRESS_USERSPACE + AsyncSocketData *data = getAsyncSocketData(); + return std::string_view(data->remoteAddress, (unsigned int) data->remoteAddressLength); +#else static thread_local char buf[16]; int ipLength = 16; us_socket_remote_address(SSL, (us_socket_t *) this, buf, &ipLength); return std::string_view(buf, (unsigned int) ipLength); +#endif } /* Returns the text representation of IP */ diff --git a/src/AsyncSocketData.h b/src/AsyncSocketData.h index 5d24667e6..1259ea68b 100644 --- a/src/AsyncSocketData.h +++ b/src/AsyncSocketData.h @@ -74,6 +74,12 @@ struct AsyncSocketData { /* This will do for now */ BackPressure buffer; +#ifdef UWS_REMOTE_ADDRESS_USERSPACE + /* Cache for remote address, populated on socket open */ + char remoteAddress[16]; + int remoteAddressLength = 0; +#endif + /* Allow move constructing us */ AsyncSocketData(BackPressure &&backpressure) : buffer(std::move(backpressure)) { diff --git a/src/HttpContext.h b/src/HttpContext.h index f2002d940..dfc900a4c 100644 --- a/src/HttpContext.h +++ b/src/HttpContext.h @@ -69,13 +69,27 @@ struct HttpContext { /* Init the HttpContext by registering libusockets event handlers */ HttpContext *init() { /* Handle socket connections */ - us_socket_context_on_open(SSL, getSocketContext(), [](us_socket_t *s, int /*is_client*/, char */*ip*/, int /*ip_length*/) { + us_socket_context_on_open(SSL, getSocketContext(), [](us_socket_t *s, int /*is_client*/, char *ip, int ip_length) { /* Any connected socket should timeout until it has a request */ us_socket_timeout(SSL, s, HTTP_IDLE_TIMEOUT_S); /* Init socket ext */ new (us_socket_ext(SSL, s)) HttpResponseData; +#ifdef UWS_REMOTE_ADDRESS_USERSPACE + /* Copy remote address into per-socket cache for later retrieval */ + AsyncSocketData *asyncSocketData = (AsyncSocketData *) us_socket_ext(SSL, s); + if (ip_length > 0 && ip_length <= 16) { + memcpy(asyncSocketData->remoteAddress, ip, (size_t) ip_length); + asyncSocketData->remoteAddressLength = ip_length; + } else { + asyncSocketData->remoteAddressLength = 0; + } +#else + (void) ip; + (void) ip_length; +#endif + /* Call filter */ HttpContextData *httpContextData = getSocketContextDataS(s); for (auto &f : httpContextData->filterHandlers) {