[nginx] GeoIP: introduced ngx_http_geoip_sockaddr() helper.

Maxim Dounin mdounin at mdounin.ru
Sat Dec 13 22:12:41 UTC 2025


details:   http://freenginx.org/hg/nginx/rev/6967497b5555
branches:  
changeset: 9446:6967497b5555
user:      Maxim Dounin <mdounin at mdounin.ru>
date:      Sun Dec 14 01:11:13 2025 +0300
description:
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.

diffstat:

 src/http/modules/ngx_http_geoip_module.c |  89 ++++++++++++++++---------------
 src/stream/ngx_stream_geoip_module.c     |  26 +++-----
 2 files changed, 57 insertions(+), 58 deletions(-)

diffs (224 lines):

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