Klaus Demo nginx / 4e17b93
Multiple addresses in "listen". Previously only one address was used by the listen directive handler even if host name resolved to multiple addresses. Now a separate listening socket is created for each address. Roman Arutyunyan 1 year, 8 months ago
11 changed file(s) with 308 addition(s) and 459 deletion(s). Raw diff Collapse all Expand all
1111 static ngx_int_t ngx_parse_unix_domain_url(ngx_pool_t *pool, ngx_url_t *u);
1212 static ngx_int_t ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u);
1313 static ngx_int_t ngx_parse_inet6_url(ngx_pool_t *pool, ngx_url_t *u);
14 static ngx_int_t ngx_inet_add_addr(ngx_pool_t *pool, ngx_url_t *u,
15 struct sockaddr *sockaddr, socklen_t socklen, ngx_uint_t total);
1416
1517
1618 in_addr_t
779781 static ngx_int_t
780782 ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u)
781783 {
782 u_char *p, *host, *port, *last, *uri, *args;
783 size_t len;
784 ngx_int_t n;
785 struct sockaddr_in *sin;
786 #if (NGX_HAVE_INET6)
787 struct sockaddr_in6 *sin6;
788 #endif
784 u_char *host, *port, *last, *uri, *args;
785 size_t len;
786 ngx_int_t n;
787 struct sockaddr_in *sin;
789788
790789 u->socklen = sizeof(struct sockaddr_in);
791790 sin = (struct sockaddr_in *) &u->sockaddr;
863862
864863 u->port = (in_port_t) n;
865864 sin->sin_port = htons((in_port_t) n);
865 sin->sin_addr.s_addr = INADDR_ANY;
866866
867867 u->port_text.len = last - host;
868868 u->port_text.data = host;
869869
870870 u->wildcard = 1;
871871
872 return NGX_OK;
872 return ngx_inet_add_addr(pool, u, &u->sockaddr.sockaddr,
873 u->socklen, 1);
873874 }
874875 }
875876 }
892893 if (u->listen && len == 1 && *host == '*') {
893894 sin->sin_addr.s_addr = INADDR_ANY;
894895 u->wildcard = 1;
895 return NGX_OK;
896 return ngx_inet_add_addr(pool, u, &u->sockaddr.sockaddr, u->socklen, 1);
896897 }
897898
898899 sin->sin_addr.s_addr = ngx_inet_addr(host, len);
903904 u->wildcard = 1;
904905 }
905906
906 u->naddrs = 1;
907
908 u->addrs = ngx_pcalloc(pool, sizeof(ngx_addr_t));
909 if (u->addrs == NULL) {
910 return NGX_ERROR;
911 }
912
913 sin = ngx_pcalloc(pool, sizeof(struct sockaddr_in));
914 if (sin == NULL) {
915 return NGX_ERROR;
916 }
917
918 ngx_memcpy(sin, &u->sockaddr, sizeof(struct sockaddr_in));
919
920 u->addrs[0].sockaddr = (struct sockaddr *) sin;
921 u->addrs[0].socklen = sizeof(struct sockaddr_in);
922
923 p = ngx_pnalloc(pool, u->host.len + sizeof(":65535") - 1);
924 if (p == NULL) {
925 return NGX_ERROR;
926 }
927
928 u->addrs[0].name.len = ngx_sprintf(p, "%V:%d",
929 &u->host, u->port) - p;
930 u->addrs[0].name.data = p;
931
932 return NGX_OK;
907 return ngx_inet_add_addr(pool, u, &u->sockaddr.sockaddr, u->socklen, 1);
933908 }
934909
935910 if (u->no_resolve) {
943918 u->family = u->addrs[0].sockaddr->sa_family;
944919 u->socklen = u->addrs[0].socklen;
945920 ngx_memcpy(&u->sockaddr, u->addrs[0].sockaddr, u->addrs[0].socklen);
946
947 switch (u->family) {
948
949 #if (NGX_HAVE_INET6)
950 case AF_INET6:
951 sin6 = (struct sockaddr_in6 *) &u->sockaddr;
952
953 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
954 u->wildcard = 1;
955 }
956
957 break;
958 #endif
959
960 default: /* AF_INET */
961 sin = (struct sockaddr_in *) &u->sockaddr;
962
963 if (sin->sin_addr.s_addr == INADDR_ANY) {
964 u->wildcard = 1;
965 }
966
967 break;
968 }
921 u->wildcard = ngx_inet_wildcard(&u->sockaddr.sockaddr);
969922
970923 return NGX_OK;
971924 }
10601013 }
10611014
10621015 u->family = AF_INET6;
1063 u->naddrs = 1;
1064
1065 u->addrs = ngx_pcalloc(pool, sizeof(ngx_addr_t));
1066 if (u->addrs == NULL) {
1067 return NGX_ERROR;
1068 }
1069
1070 sin6 = ngx_pcalloc(pool, sizeof(struct sockaddr_in6));
1071 if (sin6 == NULL) {
1072 return NGX_ERROR;
1073 }
1074
1075 ngx_memcpy(sin6, &u->sockaddr, sizeof(struct sockaddr_in6));
1076
1077 u->addrs[0].sockaddr = (struct sockaddr *) sin6;
1078 u->addrs[0].socklen = sizeof(struct sockaddr_in6);
1079
1080 p = ngx_pnalloc(pool, u->host.len + sizeof(":65535") - 1);
1081 if (p == NULL) {
1082 return NGX_ERROR;
1083 }
1084
1085 u->addrs[0].name.len = ngx_sprintf(p, "%V:%d",
1086 &u->host, u->port) - p;
1087 u->addrs[0].name.data = p;
1088
1089 return NGX_OK;
1016
1017 return ngx_inet_add_addr(pool, u, &u->sockaddr.sockaddr, u->socklen, 1);
10901018
10911019 #else
10921020
11031031 ngx_int_t
11041032 ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
11051033 {
1106 u_char *p, *host;
1107 size_t len;
1108 in_port_t port;
1109 ngx_uint_t i;
1110 struct addrinfo hints, *res, *rp;
1111 struct sockaddr_in *sin;
1112 struct sockaddr_in6 *sin6;
1113
1114 port = htons(u->port);
1034 u_char *host;
1035 ngx_uint_t n;
1036 struct addrinfo hints, *res, *rp;
11151037
11161038 host = ngx_alloc(u->host.len + 1, pool->log);
11171039 if (host == NULL) {
11351057
11361058 ngx_free(host);
11371059
1138 for (i = 0, rp = res; rp != NULL; rp = rp->ai_next) {
1060 for (n = 0, rp = res; rp != NULL; rp = rp->ai_next) {
11391061
11401062 switch (rp->ai_family) {
11411063
11471069 continue;
11481070 }
11491071
1150 i++;
1151 }
1152
1153 if (i == 0) {
1072 n++;
1073 }
1074
1075 if (n == 0) {
11541076 u->err = "host not found";
11551077 goto failed;
11561078 }
11571079
11581080 /* MP: ngx_shared_palloc() */
11591081
1160 u->addrs = ngx_pcalloc(pool, i * sizeof(ngx_addr_t));
1161 if (u->addrs == NULL) {
1162 goto failed;
1163 }
1164
1165 u->naddrs = i;
1166
1167 i = 0;
1168
11691082 /* AF_INET addresses first */
11701083
11711084 for (rp = res; rp != NULL; rp = rp->ai_next) {
11741087 continue;
11751088 }
11761089
1177 sin = ngx_pcalloc(pool, rp->ai_addrlen);
1178 if (sin == NULL) {
1090 if (ngx_inet_add_addr(pool, u, rp->ai_addr, rp->ai_addrlen, n)
1091 != NGX_OK)
1092 {
11791093 goto failed;
11801094 }
1181
1182 ngx_memcpy(sin, rp->ai_addr, rp->ai_addrlen);
1183
1184 sin->sin_port = port;
1185
1186 u->addrs[i].sockaddr = (struct sockaddr *) sin;
1187 u->addrs[i].socklen = rp->ai_addrlen;
1188
1189 len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1;
1190
1191 p = ngx_pnalloc(pool, len);
1192 if (p == NULL) {
1193 goto failed;
1194 }
1195
1196 len = ngx_sock_ntop((struct sockaddr *) sin, rp->ai_addrlen, p, len, 1);
1197
1198 u->addrs[i].name.len = len;
1199 u->addrs[i].name.data = p;
1200
1201 i++;
12021095 }
12031096
12041097 for (rp = res; rp != NULL; rp = rp->ai_next) {
12071100 continue;
12081101 }
12091102
1210 sin6 = ngx_pcalloc(pool, rp->ai_addrlen);
1211 if (sin6 == NULL) {
1103 if (ngx_inet_add_addr(pool, u, rp->ai_addr, rp->ai_addrlen, n)
1104 != NGX_OK)
1105 {
12121106 goto failed;
12131107 }
1214
1215 ngx_memcpy(sin6, rp->ai_addr, rp->ai_addrlen);
1216
1217 sin6->sin6_port = port;
1218
1219 u->addrs[i].sockaddr = (struct sockaddr *) sin6;
1220 u->addrs[i].socklen = rp->ai_addrlen;
1221
1222 len = NGX_INET6_ADDRSTRLEN + sizeof("[]:65535") - 1;
1223
1224 p = ngx_pnalloc(pool, len);
1225 if (p == NULL) {
1226 goto failed;
1227 }
1228
1229 len = ngx_sock_ntop((struct sockaddr *) sin6, rp->ai_addrlen, p,
1230 len, 1);
1231
1232 u->addrs[i].name.len = len;
1233 u->addrs[i].name.data = p;
1234
1235 i++;
12361108 }
12371109
12381110 freeaddrinfo(res);
12491121 ngx_int_t
12501122 ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
12511123 {
1252 u_char *p, *host;
1253 size_t len;
1254 in_port_t port;
1255 in_addr_t in_addr;
1256 ngx_uint_t i;
1124 u_char *host;
1125 ngx_uint_t i, n;
12571126 struct hostent *h;
1258 struct sockaddr_in *sin;
1127 struct sockaddr_in sin;
12591128
12601129 /* AF_INET only */
12611130
1262 port = htons(u->port);
1263
1264 in_addr = ngx_inet_addr(u->host.data, u->host.len);
1265
1266 if (in_addr == INADDR_NONE) {
1131 ngx_memzero(&sin, sizeof(struct sockaddr_in));
1132
1133 sin.sin_family = AF_INET;
1134 sin.sin_addr.s_addr = ngx_inet_addr(u->host.data, u->host.len);
1135
1136 if (sin.sin_addr.s_addr == INADDR_NONE) {
12671137 host = ngx_alloc(u->host.len + 1, pool->log);
12681138 if (host == NULL) {
12691139 return NGX_ERROR;
12801150 return NGX_ERROR;
12811151 }
12821152
1283 for (i = 0; h->h_addr_list[i] != NULL; i++) { /* void */ }
1153 for (n = 0; h->h_addr_list[n] != NULL; n++) { /* void */ }
12841154
12851155 /* MP: ngx_shared_palloc() */
12861156
1287 u->addrs = ngx_pcalloc(pool, i * sizeof(ngx_addr_t));
1157 for (i = 0; i < n; i++) {
1158 sin.sin_addr.s_addr = *(in_addr_t *) (h->h_addr_list[i]);
1159
1160 if (ngx_inet_add_addr(pool, u, (struct sockaddr *) &sin,
1161 sizeof(struct sockaddr_in), n)
1162 != NGX_OK)
1163 {
1164 return NGX_ERROR;
1165 }
1166 }
1167
1168 } else {
1169
1170 /* MP: ngx_shared_palloc() */
1171
1172 if (ngx_inet_add_addr(pool, u, (struct sockaddr *) &sin,
1173 sizeof(struct sockaddr_in), 1)
1174 != NGX_OK)
1175 {
1176 return NGX_ERROR;
1177 }
1178 }
1179
1180 return NGX_OK;
1181 }
1182
1183 #endif /* NGX_HAVE_GETADDRINFO && NGX_HAVE_INET6 */
1184
1185
1186 static ngx_int_t
1187 ngx_inet_add_addr(ngx_pool_t *pool, ngx_url_t *u, struct sockaddr *sockaddr,
1188 socklen_t socklen, ngx_uint_t total)
1189 {
1190 u_char *p;
1191 size_t len;
1192 ngx_addr_t *addr;
1193 struct sockaddr *sa;
1194
1195 if (u->addrs == NULL) {
1196 u->addrs = ngx_palloc(pool, total * sizeof(ngx_addr_t));
12881197 if (u->addrs == NULL) {
12891198 return NGX_ERROR;
12901199 }
1291
1292 u->naddrs = i;
1293
1294 for (i = 0; i < u->naddrs; i++) {
1295
1296 sin = ngx_pcalloc(pool, sizeof(struct sockaddr_in));
1297 if (sin == NULL) {
1298 return NGX_ERROR;
1299 }
1300
1301 sin->sin_family = AF_INET;
1302 sin->sin_port = port;
1303 sin->sin_addr.s_addr = *(in_addr_t *) (h->h_addr_list[i]);
1304
1305 u->addrs[i].sockaddr = (struct sockaddr *) sin;
1306 u->addrs[i].socklen = sizeof(struct sockaddr_in);
1307
1308 len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1;
1309
1310 p = ngx_pnalloc(pool, len);
1311 if (p == NULL) {
1312 return NGX_ERROR;
1313 }
1314
1315 len = ngx_sock_ntop((struct sockaddr *) sin,
1316 sizeof(struct sockaddr_in), p, len, 1);
1317
1318 u->addrs[i].name.len = len;
1319 u->addrs[i].name.data = p;
1320 }
1321
1322 } else {
1323
1324 /* MP: ngx_shared_palloc() */
1325
1326 u->addrs = ngx_pcalloc(pool, sizeof(ngx_addr_t));
1327 if (u->addrs == NULL) {
1328 return NGX_ERROR;
1329 }
1330
1331 sin = ngx_pcalloc(pool, sizeof(struct sockaddr_in));
1332 if (sin == NULL) {
1333 return NGX_ERROR;
1334 }
1335
1336 u->naddrs = 1;
1337
1338 sin->sin_family = AF_INET;
1339 sin->sin_port = port;
1340 sin->sin_addr.s_addr = in_addr;
1341
1342 u->addrs[0].sockaddr = (struct sockaddr *) sin;
1343 u->addrs[0].socklen = sizeof(struct sockaddr_in);
1344
1345 p = ngx_pnalloc(pool, u->host.len + sizeof(":65535") - 1);
1346 if (p == NULL) {
1347 return NGX_ERROR;
1348 }
1349
1350 u->addrs[0].name.len = ngx_sprintf(p, "%V:%d",
1351 &u->host, ntohs(port)) - p;
1352 u->addrs[0].name.data = p;
1353 }
1200 }
1201
1202 sa = ngx_pcalloc(pool, socklen);
1203 if (sa == NULL) {
1204 return NGX_ERROR;
1205 }
1206
1207 ngx_memcpy(sa, sockaddr, socklen);
1208
1209 ngx_inet_set_port(sa, u->port);
1210
1211 switch (sa->sa_family) {
1212
1213 #if (NGX_HAVE_INET6)
1214 case AF_INET6:
1215 len = NGX_INET6_ADDRSTRLEN + sizeof("[]:65536") - 1;
1216 break;
1217 #endif
1218
1219 default: /* AF_INET */
1220 len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1;
1221 }
1222
1223 p = ngx_pnalloc(pool, len);
1224 if (p == NULL) {
1225 return NGX_ERROR;
1226 }
1227
1228 len = ngx_sock_ntop(sa, socklen, p, len, 1);
1229
1230 addr = &u->addrs[u->naddrs++];
1231
1232 addr->sockaddr = sa;
1233 addr->socklen = socklen;
1234
1235 addr->name.len = len;
1236 addr->name.data = p;
13541237
13551238 return NGX_OK;
13561239 }
1357
1358 #endif /* NGX_HAVE_GETADDRINFO && NGX_HAVE_INET6 */
13591240
13601241
13611242 ngx_int_t
14941375 break;
14951376 }
14961377 }
1378
1379
1380 ngx_uint_t
1381 ngx_inet_wildcard(struct sockaddr *sa)
1382 {
1383 struct sockaddr_in *sin;
1384 #if (NGX_HAVE_INET6)
1385 struct sockaddr_in6 *sin6;
1386 #endif
1387
1388 switch (sa->sa_family) {
1389
1390 case AF_INET:
1391 sin = (struct sockaddr_in *) sa;
1392
1393 if (sin->sin_addr.s_addr == INADDR_ANY) {
1394 return 1;
1395 }
1396
1397 break;
1398
1399 #if (NGX_HAVE_INET6)
1400
1401 case AF_INET6:
1402 sin6 = (struct sockaddr_in6 *) sa;
1403
1404 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
1405 return 1;
1406 }
1407
1408 break;
1409
1410 #endif
1411 }
1412
1413 return 0;
1414 }
124124 struct sockaddr *sa2, socklen_t slen2, ngx_uint_t cmp_port);
125125 in_port_t ngx_inet_get_port(struct sockaddr *sa);
126126 void ngx_inet_set_port(struct sockaddr *sa, in_port_t port);
127 ngx_uint_t ngx_inet_wildcard(struct sockaddr *sa);
127128
128129
129130 #endif /* _NGX_INET_H_INCLUDED_ */
11561156 }
11571157 }
11581158
1159 sa = &lsopt->sockaddr.sockaddr;
1159 sa = lsopt->sockaddr;
11601160 p = ngx_inet_get_port(sa);
11611161
11621162 port = cmcf->ports->elts;
12081208
12091209 for (i = 0; i < port->addrs.nelts; i++) {
12101210
1211 if (ngx_cmp_sockaddr(&lsopt->sockaddr.sockaddr, lsopt->socklen,
1212 &addr[i].opt.sockaddr.sockaddr,
1211 if (ngx_cmp_sockaddr(lsopt->sockaddr, lsopt->socklen,
1212 addr[i].opt.sockaddr,
12131213 addr[i].opt.socklen, 0)
12141214 != NGX_OK)
12151215 {
12381238
12391239 if (addr[i].opt.set) {
12401240 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1241 "duplicate listen options for %s", addr[i].opt.addr);
1241 "duplicate listen options for %V",
1242 &addr[i].opt.addr_text);
12421243 return NGX_ERROR;
12431244 }
12441245
12511252
12521253 if (default_server) {
12531254 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1254 "a duplicate default server for %s", addr[i].opt.addr);
1255 "a duplicate default server for %V",
1256 &addr[i].opt.addr_text);
12551257 return NGX_ERROR;
12561258 }
12571259
13041306 if (lsopt->http2 && lsopt->ssl) {
13051307 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
13061308 "nginx was built with OpenSSL that lacks ALPN "
1307 "and NPN support, HTTP/2 is not enabled for %s",
1308 lsopt->addr);
1309 "and NPN support, HTTP/2 is not enabled for %V",
1310 &lsopt->addr_text);
13091311 }
13101312
13111313 #endif
13531355 for (i = 0; i < addr->servers.nelts; i++) {
13541356 if (server[i] == cscf) {
13551357 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1356 "a duplicate listen %s", addr->opt.addr);
1358 "a duplicate listen %V",
1359 &addr->opt.addr_text);
13571360 return NGX_ERROR;
13581361 }
13591362 }
14701473
14711474 if (rc == NGX_DECLINED) {
14721475 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
1473 "invalid server name or wildcard \"%V\" on %s",
1474 &name[n].name, addr->opt.addr);
1476 "invalid server name or wildcard \"%V\" on %V",
1477 &name[n].name, &addr->opt.addr_text);
14751478 return NGX_ERROR;
14761479 }
14771480
14781481 if (rc == NGX_BUSY) {
14791482 ngx_log_error(NGX_LOG_WARN, cf->log, 0,
1480 "conflicting server name \"%V\" on %s, ignored",
1481 &name[n].name, addr->opt.addr);
1483 "conflicting server name \"%V\" on %V, ignored",
1484 &name[n].name, &addr->opt.addr_text);
14821485 }
14831486 }
14841487 }
16991702 ngx_http_core_loc_conf_t *clcf;
17001703 ngx_http_core_srv_conf_t *cscf;
17011704
1702 ls = ngx_create_listening(cf, &addr->opt.sockaddr.sockaddr,
1703 addr->opt.socklen);
1705 ls = ngx_create_listening(cf, addr->opt.sockaddr, addr->opt.socklen);
17041706 if (ls == NULL) {
17051707 return NULL;
17061708 }
17901792
17911793 for (i = 0; i < hport->naddrs; i++) {
17921794
1793 sin = &addr[i].opt.sockaddr.sockaddr_in;
1795 sin = (struct sockaddr_in *) addr[i].opt.sockaddr;
17941796 addrs[i].addr = sin->sin_addr.s_addr;
17951797 addrs[i].conf.default_server = addr[i].default_server;
17961798 #if (NGX_HTTP_SSL)
18551857
18561858 for (i = 0; i < hport->naddrs; i++) {
18571859
1858 sin6 = &addr[i].opt.sockaddr.sockaddr_in6;
1860 sin6 = (struct sockaddr_in6 *) addr[i].opt.sockaddr;
18591861 addrs6[i].addr6 = sin6->sin6_addr;
18601862 addrs6[i].conf.default_server = addr[i].default_server;
18611863 #if (NGX_HTTP_SSL)
27142714 {
27152715 char *rv;
27162716 void *mconf;
2717 size_t len;
2718 u_char *p;
27172719 ngx_uint_t i;
27182720 ngx_conf_t pcf;
27192721 ngx_http_module_t *module;
28012803 if (rv == NGX_CONF_OK && !cscf->listen) {
28022804 ngx_memzero(&lsopt, sizeof(ngx_http_listen_opt_t));
28032805
2804 sin = &lsopt.sockaddr.sockaddr_in;
2806 p = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in));
2807 if (p == NULL) {
2808 return NGX_CONF_ERROR;
2809 }
2810
2811 lsopt.sockaddr = (struct sockaddr *) p;
2812
2813 sin = (struct sockaddr_in *) p;
28052814
28062815 sin->sin_family = AF_INET;
28072816 #if (NGX_WIN32)
28242833 #endif
28252834 lsopt.wildcard = 1;
28262835
2827 (void) ngx_sock_ntop(&lsopt.sockaddr.sockaddr, lsopt.socklen,
2828 lsopt.addr, NGX_SOCKADDR_STRLEN, 1);
2836 len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1;
2837
2838 p = ngx_pnalloc(cf->pool, len);
2839 if (p == NULL) {
2840 return NGX_CONF_ERROR;
2841 }
2842
2843 lsopt.addr_text.data = p;
2844 lsopt.addr_text.len = ngx_sock_ntop(lsopt.sockaddr, lsopt.socklen, p,
2845 len, 1);
28292846
28302847 if (ngx_http_add_listen(cf, cscf, &lsopt) != NGX_OK) {
28312848 return NGX_CONF_ERROR;
37783795
37793796 ngx_memzero(&lsopt, sizeof(ngx_http_listen_opt_t));
37803797
3781 ngx_memcpy(&lsopt.sockaddr.sockaddr, &u.sockaddr, u.socklen);
3782
3783 lsopt.socklen = u.socklen;
37843798 lsopt.backlog = NGX_LISTEN_BACKLOG;
37853799 lsopt.rcvbuf = -1;
37863800 lsopt.sndbuf = -1;
37903804 #if (NGX_HAVE_TCP_FASTOPEN)
37913805 lsopt.fastopen = -1;
37923806 #endif
3793 lsopt.wildcard = u.wildcard;
37943807 #if (NGX_HAVE_INET6)
37953808 lsopt.ipv6only = 1;
37963809 #endif
3797
3798 (void) ngx_sock_ntop(&lsopt.sockaddr.sockaddr, lsopt.socklen, lsopt.addr,
3799 NGX_SOCKADDR_STRLEN, 1);
38003810
38013811 for (n = 2; n < cf->args->nelts; n++) {
38023812
39223932
39233933 if (ngx_strncmp(value[n].data, "ipv6only=o", 10) == 0) {
39243934 #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
3925 struct sockaddr *sa;
3926
3927 sa = &lsopt.sockaddr.sockaddr;
3928
3929 if (sa->sa_family == AF_INET6) {
3930
3931 if (ngx_strcmp(&value[n].data[10], "n") == 0) {
3932 lsopt.ipv6only = 1;
3933
3934 } else if (ngx_strcmp(&value[n].data[10], "ff") == 0) {
3935 lsopt.ipv6only = 0;
3936
3937 } else {
3938 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3939 "invalid ipv6only flags \"%s\"",
3940 &value[n].data[9]);
3941 return NGX_CONF_ERROR;
3942 }
3943
3944 lsopt.set = 1;
3945 lsopt.bind = 1;
3935 if (ngx_strcmp(&value[n].data[10], "n") == 0) {
3936 lsopt.ipv6only = 1;
3937
3938 } else if (ngx_strcmp(&value[n].data[10], "ff") == 0) {
3939 lsopt.ipv6only = 0;
39463940
39473941 } else {
39483942 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3949 "ipv6only is not supported "
3950 "on addr \"%s\", ignored", lsopt.addr);
3943 "invalid ipv6only flags \"%s\"",
3944 &value[n].data[9]);
3945 return NGX_CONF_ERROR;
39513946 }
3947
3948 lsopt.set = 1;
3949 lsopt.bind = 1;
39523950
39533951 continue;
39543952 #else
41054103 return NGX_CONF_ERROR;
41064104 }
41074105
4108 if (ngx_http_add_listen(cf, cscf, &lsopt) == NGX_OK) {
4109 return NGX_CONF_OK;
4110 }
4111
4112 return NGX_CONF_ERROR;
4106 for (n = 0; n < u.naddrs; n++) {
4107 lsopt.sockaddr = u.addrs[n].sockaddr;
4108 lsopt.socklen = u.addrs[n].socklen;
4109 lsopt.addr_text = u.addrs[n].name;
4110 lsopt.wildcard = ngx_inet_wildcard(lsopt.sockaddr);
4111
4112 if (ngx_http_add_listen(cf, cscf, &lsopt) != NGX_OK) {
4113 return NGX_CONF_ERROR;
4114 }
4115 }
4116
4117 return NGX_CONF_OK;
41134118 }
41144119
41154120
6464
6565
6666 typedef struct {
67 ngx_sockaddr_t sockaddr;
67 struct sockaddr *sockaddr;
6868 socklen_t socklen;
69 ngx_str_t addr_text;
6970
7071 unsigned set:1;
7172 unsigned default_server:1;
99100 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
100101 char *accept_filter;
101102 #endif
102
103 u_char addr[NGX_SOCKADDR_STRLEN + 1];
104103 } ngx_http_listen_opt_t;
105104
106105
230230 ngx_mail_conf_port_t *port;
231231 ngx_mail_conf_addr_t *addr;
232232
233 sa = &listen->sockaddr.sockaddr;
233 sa = listen->sockaddr;
234234 p = ngx_inet_get_port(sa);
235235
236236 port = ports->elts;
315315 continue;
316316 }
317317
318 ls = ngx_create_listening(cf, &addr[i].opt.sockaddr.sockaddr,
318 ls = ngx_create_listening(cf, addr[i].opt.sockaddr,
319319 addr[i].opt.socklen);
320320 if (ls == NULL) {
321321 return NGX_CONF_ERROR;
383383 ngx_mail_add_addrs(ngx_conf_t *cf, ngx_mail_port_t *mport,
384384 ngx_mail_conf_addr_t *addr)
385385 {
386 u_char *p;
387 size_t len;
388386 ngx_uint_t i;
389387 ngx_mail_in_addr_t *addrs;
390388 struct sockaddr_in *sin;
391 u_char buf[NGX_SOCKADDR_STRLEN];
392389
393390 mport->addrs = ngx_pcalloc(cf->pool,
394391 mport->naddrs * sizeof(ngx_mail_in_addr_t));
400397
401398 for (i = 0; i < mport->naddrs; i++) {
402399
403 sin = &addr[i].opt.sockaddr.sockaddr_in;
400 sin = (struct sockaddr_in *) addr[i].opt.sockaddr;
404401 addrs[i].addr = sin->sin_addr.s_addr;
405402
406403 addrs[i].conf.ctx = addr[i].opt.ctx;
407404 #if (NGX_MAIL_SSL)
408405 addrs[i].conf.ssl = addr[i].opt.ssl;
409406 #endif
410
411 len = ngx_sock_ntop(&addr[i].opt.sockaddr.sockaddr, addr[i].opt.socklen,
412 buf, NGX_SOCKADDR_STRLEN, 1);
413
414 p = ngx_pnalloc(cf->pool, len);
415 if (p == NULL) {
416 return NGX_ERROR;
417 }
418
419 ngx_memcpy(p, buf, len);
420
421 addrs[i].conf.addr_text.len = len;
422 addrs[i].conf.addr_text.data = p;
407 addrs[i].conf.addr_text = addr[i].opt.addr_text;
423408 }
424409
425410 return NGX_OK;
432417 ngx_mail_add_addrs6(ngx_conf_t *cf, ngx_mail_port_t *mport,
433418 ngx_mail_conf_addr_t *addr)
434419 {
435 u_char *p;
436 size_t len;
437420 ngx_uint_t i;
438421 ngx_mail_in6_addr_t *addrs6;
439422 struct sockaddr_in6 *sin6;
440 u_char buf[NGX_SOCKADDR_STRLEN];
441423
442424 mport->addrs = ngx_pcalloc(cf->pool,
443425 mport->naddrs * sizeof(ngx_mail_in6_addr_t));
449431
450432 for (i = 0; i < mport->naddrs; i++) {
451433
452 sin6 = &addr[i].opt.sockaddr.sockaddr_in6;
434 sin6 = (struct sockaddr_in6 *) addr[i].opt.sockaddr;
453435 addrs6[i].addr6 = sin6->sin6_addr;
454436
455437 addrs6[i].conf.ctx = addr[i].opt.ctx;
456438 #if (NGX_MAIL_SSL)
457439 addrs6[i].conf.ssl = addr[i].opt.ssl;
458440 #endif
459
460 len = ngx_sock_ntop(&addr[i].opt.sockaddr.sockaddr, addr[i].opt.socklen,
461 buf, NGX_SOCKADDR_STRLEN, 1);
462
463 p = ngx_pnalloc(cf->pool, len);
464 if (p == NULL) {
465 return NGX_ERROR;
466 }
467
468 ngx_memcpy(p, buf, len);
469
470 addrs6[i].conf.addr_text.len = len;
471 addrs6[i].conf.addr_text.data = p;
441 addrs6[i].conf.addr_text = addr[i].opt.addr_text;
472442 }
473443
474444 return NGX_OK;
2626
2727
2828 typedef struct {
29 ngx_sockaddr_t sockaddr;
29 struct sockaddr *sockaddr;
3030 socklen_t socklen;
31 ngx_str_t addr_text;
3132
3233 /* server ctx */
3334 ngx_mail_conf_ctx_t *ctx;
296296
297297 ngx_str_t *value, size;
298298 ngx_url_t u;
299 ngx_uint_t i, m;
300 ngx_mail_listen_t *ls;
299 ngx_uint_t i, n, m;
300 ngx_mail_listen_t *ls, *als;
301301 ngx_mail_module_t *module;
302302 ngx_mail_core_main_conf_t *cmcf;
303303
322322
323323 cmcf = ngx_mail_conf_get_module_main_conf(cf, ngx_mail_core_module);
324324
325 ls = cmcf->listen.elts;
326
327 for (i = 0; i < cmcf->listen.nelts; i++) {
328
329 if (ngx_cmp_sockaddr(&ls[i].sockaddr.sockaddr, ls[i].socklen,
330 (struct sockaddr *) &u.sockaddr, u.socklen, 1)
331 != NGX_OK)
332 {
333 continue;
334 }
335
336 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
337 "duplicate \"%V\" address and port pair", &u.url);
338 return NGX_CONF_ERROR;
339 }
340
341 ls = ngx_array_push(&cmcf->listen);
325 ls = ngx_array_push_n(&cmcf->listen, u.naddrs);
342326 if (ls == NULL) {
343327 return NGX_CONF_ERROR;
344328 }
345329
346330 ngx_memzero(ls, sizeof(ngx_mail_listen_t));
347331
348 ngx_memcpy(&ls->sockaddr.sockaddr, &u.sockaddr, u.socklen);
349
350 ls->socklen = u.socklen;
351332 ls->backlog = NGX_LISTEN_BACKLOG;
352333 ls->rcvbuf = -1;
353334 ls->sndbuf = -1;
354 ls->wildcard = u.wildcard;
355335 ls->ctx = cf->ctx;
356336
357337 #if (NGX_HAVE_INET6)
433413
434414 if (ngx_strncmp(value[i].data, "ipv6only=o", 10) == 0) {
435415 #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
436 size_t len;
437 u_char buf[NGX_SOCKADDR_STRLEN];
438
439 if (ls->sockaddr.sockaddr.sa_family == AF_INET6) {
440
441 if (ngx_strcmp(&value[i].data[10], "n") == 0) {
442 ls->ipv6only = 1;
443
444 } else if (ngx_strcmp(&value[i].data[10], "ff") == 0) {
445 ls->ipv6only = 0;
446
447 } else {
448 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
449 "invalid ipv6only flags \"%s\"",
450 &value[i].data[9]);
451 return NGX_CONF_ERROR;
452 }
453
454 ls->bind = 1;
416 if (ngx_strcmp(&value[i].data[10], "n") == 0) {
417 ls->ipv6only = 1;
418
419 } else if (ngx_strcmp(&value[i].data[10], "ff") == 0) {
420 ls->ipv6only = 0;
455421
456422 } else {
457 len = ngx_sock_ntop(&ls->sockaddr.sockaddr, ls->socklen, buf,
458 NGX_SOCKADDR_STRLEN, 1);
459
460423 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
461 "ipv6only is not supported "
462 "on addr \"%*s\", ignored", len, buf);
463 }
464
424 "invalid ipv6only flags \"%s\"",
425 &value[i].data[9]);
426 return NGX_CONF_ERROR;
427 }
428
429 ls->bind = 1;
465430 continue;
466431 #else
467432 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
587552 return NGX_CONF_ERROR;
588553 }
589554
555 als = cmcf->listen.elts;
556
557 for (n = 0; n < u.naddrs; n++) {
558 ls[n] = ls[0];
559
560 ls[n].sockaddr = u.addrs[n].sockaddr;
561 ls[n].socklen = u.addrs[n].socklen;
562 ls[n].addr_text = u.addrs[n].name;
563 ls[n].wildcard = ngx_inet_wildcard(ls[n].sockaddr);
564
565 for (i = 0; i < cmcf->listen.nelts - u.naddrs + n; i++) {
566
567 if (ngx_cmp_sockaddr(als[i].sockaddr, als[i].socklen,
568 ls[n].sockaddr, ls[n].socklen, 1)
569 != NGX_OK)
570 {
571 continue;
572 }
573
574 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
575 "duplicate \"%V\" address and port pair",
576 &ls[n].addr_text);
577 return NGX_CONF_ERROR;
578 }
579 }
580
590581 return NGX_CONF_OK;
591582 }
592583
386386 ngx_stream_conf_port_t *port;
387387 ngx_stream_conf_addr_t *addr;
388388
389 sa = &listen->sockaddr.sockaddr;
389 sa = listen->sockaddr;
390390 p = ngx_inet_get_port(sa);
391391
392392 port = ports->elts;
475475 continue;
476476 }
477477
478 ls = ngx_create_listening(cf, &addr[i].opt.sockaddr.sockaddr,
478 ls = ngx_create_listening(cf, addr[i].opt.sockaddr,
479479 addr[i].opt.socklen);
480480 if (ls == NULL) {
481481 return NGX_CONF_ERROR;
550550 ngx_stream_add_addrs(ngx_conf_t *cf, ngx_stream_port_t *stport,
551551 ngx_stream_conf_addr_t *addr)
552552 {
553 u_char *p;
554 size_t len;
555553 ngx_uint_t i;
556554 struct sockaddr_in *sin;
557555 ngx_stream_in_addr_t *addrs;
558 u_char buf[NGX_SOCKADDR_STRLEN];
559556
560557 stport->addrs = ngx_pcalloc(cf->pool,
561558 stport->naddrs * sizeof(ngx_stream_in_addr_t));
567564
568565 for (i = 0; i < stport->naddrs; i++) {
569566
570 sin = &addr[i].opt.sockaddr.sockaddr_in;
567 sin = (struct sockaddr_in *) addr[i].opt.sockaddr;
571568 addrs[i].addr = sin->sin_addr.s_addr;
572569
573570 addrs[i].conf.ctx = addr[i].opt.ctx;
575572 addrs[i].conf.ssl = addr[i].opt.ssl;
576573 #endif
577574 addrs[i].conf.proxy_protocol = addr[i].opt.proxy_protocol;
578
579 len = ngx_sock_ntop(&addr[i].opt.sockaddr.sockaddr, addr[i].opt.socklen,
580 buf, NGX_SOCKADDR_STRLEN, 1);
581
582 p = ngx_pnalloc(cf->pool, len);
583 if (p == NULL) {
584 return NGX_ERROR;
585 }
586
587 ngx_memcpy(p, buf, len);
588
589 addrs[i].conf.addr_text.len = len;
590 addrs[i].conf.addr_text.data = p;
575 addrs[i].conf.addr_text = addr[i].opt.addr_text;
591576 }
592577
593578 return NGX_OK;
600585 ngx_stream_add_addrs6(ngx_conf_t *cf, ngx_stream_port_t *stport,
601586 ngx_stream_conf_addr_t *addr)
602587 {
603 u_char *p;
604 size_t len;
605588 ngx_uint_t i;
606589 struct sockaddr_in6 *sin6;
607590 ngx_stream_in6_addr_t *addrs6;
608 u_char buf[NGX_SOCKADDR_STRLEN];
609591
610592 stport->addrs = ngx_pcalloc(cf->pool,
611593 stport->naddrs * sizeof(ngx_stream_in6_addr_t));
617599
618600 for (i = 0; i < stport->naddrs; i++) {
619601
620 sin6 = &addr[i].opt.sockaddr.sockaddr_in6;
602 sin6 = (struct sockaddr_in6 *) addr[i].opt.sockaddr;
621603 addrs6[i].addr6 = sin6->sin6_addr;
622604
623605 addrs6[i].conf.ctx = addr[i].opt.ctx;
625607 addrs6[i].conf.ssl = addr[i].opt.ssl;
626608 #endif
627609 addrs6[i].conf.proxy_protocol = addr[i].opt.proxy_protocol;
628
629 len = ngx_sock_ntop(&addr[i].opt.sockaddr.sockaddr, addr[i].opt.socklen,
630 buf, NGX_SOCKADDR_STRLEN, 1);
631
632 p = ngx_pnalloc(cf->pool, len);
633 if (p == NULL) {
634 return NGX_ERROR;
635 }
636
637 ngx_memcpy(p, buf, len);
638
639 addrs6[i].conf.addr_text.len = len;
640 addrs6[i].conf.addr_text.data = p;
610 addrs6[i].conf.addr_text = addr[i].opt.addr_text;
641611 }
642612
643613 return NGX_OK;
4040
4141
4242 typedef struct {
43 ngx_sockaddr_t sockaddr;
43 struct sockaddr *sockaddr;
4444 socklen_t socklen;
45 ngx_str_t addr_text;
4546
4647 /* server ctx */
4748 ngx_stream_conf_ctx_t *ctx;
576576
577577 ngx_str_t *value, size;
578578 ngx_url_t u;
579 ngx_uint_t i, backlog;
579 ngx_uint_t i, n, backlog;
580580 ngx_stream_listen_t *ls, *als;
581581 ngx_stream_core_main_conf_t *cmcf;
582582
601601
602602 cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module);
603603
604 ls = ngx_array_push(&cmcf->listen);
604 ls = ngx_array_push_n(&cmcf->listen, u.naddrs);
605605 if (ls == NULL) {
606606 return NGX_CONF_ERROR;
607607 }
608608
609609 ngx_memzero(ls, sizeof(ngx_stream_listen_t));
610610
611 ngx_memcpy(&ls->sockaddr.sockaddr, &u.sockaddr, u.socklen);
612
613 ls->socklen = u.socklen;
614611 ls->backlog = NGX_LISTEN_BACKLOG;
615612 ls->rcvbuf = -1;
616613 ls->sndbuf = -1;
617614 ls->type = SOCK_STREAM;
618 ls->wildcard = u.wildcard;
619615 ls->ctx = cf->ctx;
620616
621617 #if (NGX_HAVE_INET6)
687683
688684 if (ngx_strncmp(value[i].data, "ipv6only=o", 10) == 0) {
689685 #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
690 size_t len;
691 u_char buf[NGX_SOCKADDR_STRLEN];
692
693 if (ls->sockaddr.sockaddr.sa_family == AF_INET6) {
694
695 if (ngx_strcmp(&value[i].data[10], "n") == 0) {
696 ls->ipv6only = 1;
697
698 } else if (ngx_strcmp(&value[i].data[10], "ff") == 0) {
699 ls->ipv6only = 0;
700
701 } else {
702 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
703 "invalid ipv6only flags \"%s\"",
704 &value[i].data[9]);
705 return NGX_CONF_ERROR;
706 }
707
708 ls->bind = 1;
686 if (ngx_strcmp(&value[i].data[10], "n") == 0) {
687 ls->ipv6only = 1;
688
689 } else if (ngx_strcmp(&value[i].data[10], "ff") == 0) {
690 ls->ipv6only = 0;
709691
710692 } else {
711 len = ngx_sock_ntop(&ls->sockaddr.sockaddr, ls->socklen, buf,
712 NGX_SOCKADDR_STRLEN, 1);
713
714693 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
715 "ipv6only is not supported "
716 "on addr \"%*s\", ignored", len, buf);
694 "invalid ipv6only flags \"%s\"",
695 &value[i].data[9]);
696 return NGX_CONF_ERROR;
717697 }
718698
699 ls->bind = 1;
719700 continue;
720701 #else
721702 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
881862
882863 als = cmcf->listen.elts;
883864
884 for (i = 0; i < cmcf->listen.nelts - 1; i++) {
885 if (ls->type != als[i].type) {
886 continue;
887 }
888
889 if (ngx_cmp_sockaddr(&als[i].sockaddr.sockaddr, als[i].socklen,
890 &ls->sockaddr.sockaddr, ls->socklen, 1)
891 != NGX_OK)
892 {
893 continue;
894 }
895
896 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
897 "duplicate \"%V\" address and port pair", &u.url);
898 return NGX_CONF_ERROR;
865 for (n = 0; n < u.naddrs; n++) {
866 ls[n] = ls[0];
867
868 ls[n].sockaddr = u.addrs[n].sockaddr;
869 ls[n].socklen = u.addrs[n].socklen;
870 ls[n].addr_text = u.addrs[n].name;
871 ls[n].wildcard = ngx_inet_wildcard(ls[n].sockaddr);
872
873 for (i = 0; i < cmcf->listen.nelts - u.naddrs + n; i++) {
874 if (ls[n].type != als[i].type) {
875 continue;
876 }
877
878 if (ngx_cmp_sockaddr(als[i].sockaddr, als[i].socklen,
879 ls[n].sockaddr, ls[n].socklen, 1)
880 != NGX_OK)
881 {
882 continue;
883 }
884
885 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
886 "duplicate \"%V\" address and port pair",
887 &ls[n].addr_text);
888 return NGX_CONF_ERROR;
889 }
899890 }
900891
901892 return NGX_CONF_OK;