[PATCH 4 of 6] GeoIP: introduced ngx_http_geoip_sockaddr() helper

Maxim Dounin mdounin at mdounin.ru
Wed Dec 3 16:31:08 UTC 2025


# HG changeset patch
# User Maxim Dounin <mdounin at mdounin.ru>
# Date 1764576372 -10800
#      Mon Dec 01 11:06:12 2025 +0300
# Node ID 9be164cc80e638557db1f1c6614202b540359ae6
# Parent  3fb3fd326c10849df11fa637bf8de2eedec6fb46
GeoIP: introduced ngx_http_geoip_sockaddr() helper.

Such a helper function will be needed for further use with libmaxminddb,
where sockaddr is used for both IPv4 and IPv6 lookups.  It also reduces
amount of code duplication.

Stream module counterpart, where direct use of s->connection->sockaddr
is sufficient, is adjusted similarly to match the code, but without
introducing a helper function.

diff --git a/src/http/modules/ngx_http_geoip_module.c b/src/http/modules/ngx_http_geoip_module.c
--- a/src/http/modules/ngx_http_geoip_module.c
+++ b/src/http/modules/ngx_http_geoip_module.c
@@ -78,6 +78,8 @@ static u_long ngx_http_geoip_addr(ngx_ht
 static geoipv6_t ngx_http_geoip_addr_v6(ngx_http_request_t *r,
     ngx_http_geoip_conf_t *gcf);
 #endif
+static struct sockaddr *ngx_http_geoip_sockaddr(ngx_http_request_t *r,
+    ngx_http_geoip_conf_t *gcf);
 
 static ngx_int_t ngx_http_geoip_add_variables(ngx_conf_t *cf);
 static void *ngx_http_geoip_create_conf(ngx_conf_t *cf);
@@ -521,29 +523,19 @@ ngx_http_geoip_get_city_record(ngx_http_
 static u_long
 ngx_http_geoip_addr(ngx_http_request_t *r, ngx_http_geoip_conf_t *gcf)
 {
-    ngx_addr_t           addr;
-    ngx_table_elt_t     *xfwd;
+    struct sockaddr     *sockaddr;
     struct sockaddr_in  *sin;
 
-    addr.sockaddr = r->connection->sockaddr;
-    addr.socklen = r->connection->socklen;
-    /* addr.name = r->connection->addr_text; */
-
-    xfwd = r->headers_in.x_forwarded_for;
-
-    if (xfwd != NULL && gcf->proxies != NULL) {
-        (void) ngx_http_get_forwarded_addr(r, &addr, xfwd, NULL,
-                                           gcf->proxies, gcf->proxy_recursive);
-    }
+    sockaddr = ngx_http_geoip_sockaddr(r, gcf);
 
 #if (NGX_HAVE_INET6)
 
-    if (addr.sockaddr->sa_family == AF_INET6) {
+    if (sockaddr->sa_family == AF_INET6) {
         u_char           *p;
         in_addr_t         inaddr;
         struct in6_addr  *inaddr6;
 
-        inaddr6 = &((struct sockaddr_in6 *) addr.sockaddr)->sin6_addr;
+        inaddr6 = &((struct sockaddr_in6 *) sockaddr)->sin6_addr;
 
         if (IN6_IS_ADDR_V4MAPPED(inaddr6)) {
             p = inaddr6->s6_addr;
@@ -559,11 +551,11 @@ ngx_http_geoip_addr(ngx_http_request_t *
 
 #endif
 
-    if (addr.sockaddr->sa_family != AF_INET) {
+    if (sockaddr->sa_family != AF_INET) {
         return INADDR_NONE;
     }
 
-    sin = (struct sockaddr_in *) addr.sockaddr;
+    sin = (struct sockaddr_in *) sockaddr;
     return ntohl(sin->sin_addr.s_addr);
 }
 
@@ -573,13 +565,48 @@ ngx_http_geoip_addr(ngx_http_request_t *
 static geoipv6_t
 ngx_http_geoip_addr_v6(ngx_http_request_t *r, ngx_http_geoip_conf_t *gcf)
 {
-    ngx_addr_t            addr;
-    ngx_table_elt_t      *xfwd;
     in_addr_t             addr4;
     struct in6_addr       addr6;
+    struct sockaddr      *sockaddr;
     struct sockaddr_in   *sin;
     struct sockaddr_in6  *sin6;
 
+    sockaddr = ngx_http_geoip_sockaddr(r, gcf);
+
+    switch (sockaddr->sa_family) {
+
+    case AF_INET:
+        /* Produce IPv4-mapped IPv6 address. */
+        sin = (struct sockaddr_in *) sockaddr;
+        addr4 = ntohl(sin->sin_addr.s_addr);
+
+        ngx_memzero(&addr6, sizeof(struct in6_addr));
+        addr6.s6_addr[10] = 0xff;
+        addr6.s6_addr[11] = 0xff;
+        addr6.s6_addr[12] = addr4 >> 24;
+        addr6.s6_addr[13] = addr4 >> 16;
+        addr6.s6_addr[14] = addr4 >> 8;
+        addr6.s6_addr[15] = addr4;
+        return addr6;
+
+    case AF_INET6:
+        sin6 = (struct sockaddr_in6 *) sockaddr;
+        return sin6->sin6_addr;
+
+    default:
+        return in6addr_any;
+    }
+}
+
+#endif
+
+
+static struct sockaddr *
+ngx_http_geoip_sockaddr(ngx_http_request_t *r, ngx_http_geoip_conf_t *gcf)
+{
+    ngx_addr_t        addr;
+    ngx_table_elt_t  *xfwd;
+
     addr.sockaddr = r->connection->sockaddr;
     addr.socklen = r->connection->socklen;
     /* addr.name = r->connection->addr_text; */
@@ -591,33 +618,9 @@ ngx_http_geoip_addr_v6(ngx_http_request_
                                            gcf->proxies, gcf->proxy_recursive);
     }
 
-    switch (addr.sockaddr->sa_family) {
-
-    case AF_INET:
-        /* Produce IPv4-mapped IPv6 address. */
-        sin = (struct sockaddr_in *) addr.sockaddr;
-        addr4 = ntohl(sin->sin_addr.s_addr);
-
-        ngx_memzero(&addr6, sizeof(struct in6_addr));
-        addr6.s6_addr[10] = 0xff;
-        addr6.s6_addr[11] = 0xff;
-        addr6.s6_addr[12] = addr4 >> 24;
-        addr6.s6_addr[13] = addr4 >> 16;
-        addr6.s6_addr[14] = addr4 >> 8;
-        addr6.s6_addr[15] = addr4;
-        return addr6;
-
-    case AF_INET6:
-        sin6 = (struct sockaddr_in6 *) addr.sockaddr;
-        return sin6->sin6_addr;
-
-    default:
-        return in6addr_any;
-    }
+    return addr.sockaddr;
 }
 
-#endif
-
 
 static ngx_int_t
 ngx_http_geoip_add_variables(ngx_conf_t *cf)
diff --git a/src/stream/ngx_stream_geoip_module.c b/src/stream/ngx_stream_geoip_module.c
--- a/src/stream/ngx_stream_geoip_module.c
+++ b/src/stream/ngx_stream_geoip_module.c
@@ -499,21 +499,19 @@ ngx_stream_geoip_get_city_record(ngx_str
 static u_long
 ngx_stream_geoip_addr(ngx_stream_session_t *s, ngx_stream_geoip_conf_t *gcf)
 {
-    ngx_addr_t           addr;
+    struct sockaddr     *sockaddr;
     struct sockaddr_in  *sin;
 
-    addr.sockaddr = s->connection->sockaddr;
-    addr.socklen = s->connection->socklen;
-    /* addr.name = s->connection->addr_text; */
+    sockaddr = s->connection->sockaddr;
 
 #if (NGX_HAVE_INET6)
 
-    if (addr.sockaddr->sa_family == AF_INET6) {
+    if (sockaddr->sa_family == AF_INET6) {
         u_char           *p;
         in_addr_t         inaddr;
         struct in6_addr  *inaddr6;
 
-        inaddr6 = &((struct sockaddr_in6 *) addr.sockaddr)->sin6_addr;
+        inaddr6 = &((struct sockaddr_in6 *) sockaddr)->sin6_addr;
 
         if (IN6_IS_ADDR_V4MAPPED(inaddr6)) {
             p = inaddr6->s6_addr;
@@ -529,11 +527,11 @@ ngx_stream_geoip_addr(ngx_stream_session
 
 #endif
 
-    if (addr.sockaddr->sa_family != AF_INET) {
+    if (sockaddr->sa_family != AF_INET) {
         return INADDR_NONE;
     }
 
-    sin = (struct sockaddr_in *) addr.sockaddr;
+    sin = (struct sockaddr_in *) sockaddr;
     return ntohl(sin->sin_addr.s_addr);
 }
 
@@ -543,21 +541,19 @@ ngx_stream_geoip_addr(ngx_stream_session
 static geoipv6_t
 ngx_stream_geoip_addr_v6(ngx_stream_session_t *s, ngx_stream_geoip_conf_t *gcf)
 {
-    ngx_addr_t            addr;
     in_addr_t             addr4;
     struct in6_addr       addr6;
+    struct sockaddr      *sockaddr;
     struct sockaddr_in   *sin;
     struct sockaddr_in6  *sin6;
 
-    addr.sockaddr = s->connection->sockaddr;
-    addr.socklen = s->connection->socklen;
-    /* addr.name = s->connection->addr_text; */
+    sockaddr = s->connection->sockaddr;
 
-    switch (addr.sockaddr->sa_family) {
+    switch (sockaddr->sa_family) {
 
     case AF_INET:
         /* Produce IPv4-mapped IPv6 address. */
-        sin = (struct sockaddr_in *) addr.sockaddr;
+        sin = (struct sockaddr_in *) sockaddr;
         addr4 = ntohl(sin->sin_addr.s_addr);
 
         ngx_memzero(&addr6, sizeof(struct in6_addr));
@@ -570,7 +566,7 @@ ngx_stream_geoip_addr_v6(ngx_stream_sess
         return addr6;
 
     case AF_INET6:
-        sin6 = (struct sockaddr_in6 *) addr.sockaddr;
+        sin6 = (struct sockaddr_in6 *) sockaddr;
         return sin6->sin6_addr;
 
     default:



More information about the nginx-devel mailing list