Mercurial > hg > nginx
comparison src/core/ngx_resolver.c @ 5475:07dd5bd222ac
Changed resolver API to use ngx_addr_t.
author | Ruslan Ermilov <ru@nginx.com> |
---|---|
date | Fri, 06 Dec 2013 14:30:27 +0400 |
parents | b43b02bb54db |
children | 950c9ed3e66f |
comparison
equal
deleted
inserted
replaced
5474:b43b02bb54db | 5475:07dd5bd222ac |
---|---|
86 static void *ngx_resolver_alloc(ngx_resolver_t *r, size_t size); | 86 static void *ngx_resolver_alloc(ngx_resolver_t *r, size_t size); |
87 static void *ngx_resolver_calloc(ngx_resolver_t *r, size_t size); | 87 static void *ngx_resolver_calloc(ngx_resolver_t *r, size_t size); |
88 static void ngx_resolver_free(ngx_resolver_t *r, void *p); | 88 static void ngx_resolver_free(ngx_resolver_t *r, void *p); |
89 static void ngx_resolver_free_locked(ngx_resolver_t *r, void *p); | 89 static void ngx_resolver_free_locked(ngx_resolver_t *r, void *p); |
90 static void *ngx_resolver_dup(ngx_resolver_t *r, void *src, size_t size); | 90 static void *ngx_resolver_dup(ngx_resolver_t *r, void *src, size_t size); |
91 static in_addr_t *ngx_resolver_rotate(ngx_resolver_t *r, in_addr_t *src, | 91 static ngx_addr_t *ngx_resolver_export(ngx_resolver_t *r, in_addr_t *src, |
92 ngx_uint_t n); | 92 ngx_uint_t n, ngx_uint_t rotate); |
93 static u_char *ngx_resolver_log_error(ngx_log_t *log, u_char *buf, size_t len); | 93 static u_char *ngx_resolver_log_error(ngx_log_t *log, u_char *buf, size_t len); |
94 | 94 |
95 | 95 |
96 ngx_resolver_t * | 96 ngx_resolver_t * |
97 ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, ngx_uint_t n) | 97 ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, ngx_uint_t n) |
279 if (addr != INADDR_NONE) { | 279 if (addr != INADDR_NONE) { |
280 temp->resolver = r; | 280 temp->resolver = r; |
281 temp->state = NGX_OK; | 281 temp->state = NGX_OK; |
282 temp->naddrs = 1; | 282 temp->naddrs = 1; |
283 temp->addrs = &temp->addr; | 283 temp->addrs = &temp->addr; |
284 temp->addr = addr; | 284 temp->addr.sockaddr = (struct sockaddr *) &temp->sin; |
285 temp->addr.socklen = sizeof(struct sockaddr_in); | |
286 ngx_memzero(&temp->sin, sizeof(struct sockaddr_in)); | |
287 temp->sin.sin_family = AF_INET; | |
288 temp->sin.sin_addr.s_addr = addr; | |
285 temp->quick = 1; | 289 temp->quick = 1; |
286 | 290 |
287 return temp; | 291 return temp; |
288 } | 292 } |
289 } | 293 } |
415 | 419 |
416 static ngx_int_t | 420 static ngx_int_t |
417 ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx) | 421 ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx) |
418 { | 422 { |
419 uint32_t hash; | 423 uint32_t hash; |
420 in_addr_t addr, *addrs; | |
421 ngx_int_t rc; | 424 ngx_int_t rc; |
422 ngx_uint_t naddrs; | 425 ngx_uint_t naddrs; |
426 ngx_addr_t *addrs; | |
423 ngx_resolver_ctx_t *next; | 427 ngx_resolver_ctx_t *next; |
424 ngx_resolver_node_t *rn; | 428 ngx_resolver_node_t *rn; |
425 | 429 |
426 hash = ngx_crc32_short(ctx->name.data, ctx->name.len); | 430 hash = ngx_crc32_short(ctx->name.data, ctx->name.len); |
427 | 431 |
443 | 447 |
444 if (naddrs) { | 448 if (naddrs) { |
445 | 449 |
446 /* NGX_RESOLVE_A answer */ | 450 /* NGX_RESOLVE_A answer */ |
447 | 451 |
448 if (naddrs != 1) { | 452 if (naddrs == 1) { |
449 addr = 0; | 453 addrs = NULL; |
450 addrs = ngx_resolver_rotate(r, rn->u.addrs, naddrs); | 454 |
455 } else { | |
456 addrs = ngx_resolver_export(r, rn->u.addrs, naddrs, 1); | |
451 if (addrs == NULL) { | 457 if (addrs == NULL) { |
452 return NGX_ERROR; | 458 return NGX_ERROR; |
453 } | 459 } |
454 | |
455 } else { | |
456 addr = rn->u.addr; | |
457 addrs = NULL; | |
458 } | 460 } |
459 | 461 |
460 ctx->next = rn->waiting; | 462 ctx->next = rn->waiting; |
461 rn->waiting = NULL; | 463 rn->waiting = NULL; |
462 | 464 |
463 /* unlock name mutex */ | 465 /* unlock name mutex */ |
464 | 466 |
465 do { | 467 do { |
466 ctx->state = NGX_OK; | 468 ctx->state = NGX_OK; |
467 ctx->naddrs = naddrs; | 469 ctx->naddrs = naddrs; |
468 ctx->addrs = (naddrs == 1) ? &ctx->addr : addrs; | 470 |
469 ctx->addr = addr; | 471 if (addrs == NULL) { |
472 ctx->addrs = &ctx->addr; | |
473 ctx->addr.sockaddr = (struct sockaddr *) &ctx->sin; | |
474 ctx->addr.socklen = sizeof(struct sockaddr_in); | |
475 ngx_memzero(&ctx->sin, sizeof(struct sockaddr_in)); | |
476 ctx->sin.sin_family = AF_INET; | |
477 ctx->sin.sin_addr.s_addr = rn->u.addr; | |
478 | |
479 } else { | |
480 ctx->addrs = addrs; | |
481 } | |
482 | |
470 next = ctx->next; | 483 next = ctx->next; |
471 | 484 |
472 ctx->handler(ctx); | 485 ctx->handler(ctx); |
473 | 486 |
474 ctx = next; | 487 ctx = next; |
475 } while (ctx); | 488 } while (ctx); |
476 | 489 |
477 if (addrs) { | 490 if (addrs != NULL) { |
491 ngx_resolver_free(r, addrs->sockaddr); | |
478 ngx_resolver_free(r, addrs); | 492 ngx_resolver_free(r, addrs); |
479 } | 493 } |
480 | 494 |
481 return NGX_OK; | 495 return NGX_OK; |
482 } | 496 } |
624 | 638 |
625 return NGX_ERROR; | 639 return NGX_ERROR; |
626 } | 640 } |
627 | 641 |
628 | 642 |
643 /* AF_INET only */ | |
644 | |
629 ngx_int_t | 645 ngx_int_t |
630 ngx_resolve_addr(ngx_resolver_ctx_t *ctx) | 646 ngx_resolve_addr(ngx_resolver_ctx_t *ctx) |
631 { | 647 { |
632 u_char *name; | 648 u_char *name; |
649 in_addr_t addr; | |
633 ngx_resolver_t *r; | 650 ngx_resolver_t *r; |
651 struct sockaddr_in *sin; | |
634 ngx_resolver_node_t *rn; | 652 ngx_resolver_node_t *rn; |
635 | 653 |
636 r = ctx->resolver; | 654 r = ctx->resolver; |
637 | 655 |
638 ctx->addr = ntohl(ctx->addr); | 656 if (ctx->addr.sockaddr->sa_family != AF_INET) { |
657 return NGX_ERROR; | |
658 } | |
659 | |
660 sin = (struct sockaddr_in *) ctx->addr.sockaddr; | |
661 addr = ntohl(sin->sin_addr.s_addr); | |
639 | 662 |
640 /* lock addr mutex */ | 663 /* lock addr mutex */ |
641 | 664 |
642 rn = ngx_resolver_lookup_addr(r, ctx->addr); | 665 rn = ngx_resolver_lookup_addr(r, addr); |
643 | 666 |
644 if (rn) { | 667 if (rn) { |
645 | 668 |
646 if (rn->valid >= ngx_time()) { | 669 if (rn->valid >= ngx_time()) { |
647 | 670 |
692 rn = ngx_resolver_alloc(r, sizeof(ngx_resolver_node_t)); | 715 rn = ngx_resolver_alloc(r, sizeof(ngx_resolver_node_t)); |
693 if (rn == NULL) { | 716 if (rn == NULL) { |
694 goto failed; | 717 goto failed; |
695 } | 718 } |
696 | 719 |
697 rn->node.key = ctx->addr; | 720 rn->node.key = addr; |
698 rn->query = NULL; | 721 rn->query = NULL; |
699 | 722 |
700 ngx_rbtree_insert(&r->addr_rbtree, &rn->node); | 723 ngx_rbtree_insert(&r->addr_rbtree, &rn->node); |
701 } | 724 } |
702 | 725 |
763 | 786 |
764 return NGX_ERROR; | 787 return NGX_ERROR; |
765 } | 788 } |
766 | 789 |
767 | 790 |
791 /* AF_INET only */ | |
792 | |
768 void | 793 void |
769 ngx_resolve_addr_done(ngx_resolver_ctx_t *ctx) | 794 ngx_resolve_addr_done(ngx_resolver_ctx_t *ctx) |
770 { | 795 { |
771 in_addr_t addr; | 796 in_addr_t addr; |
772 ngx_resolver_t *r; | 797 ngx_resolver_t *r; |
773 ngx_resolver_ctx_t *w, **p; | 798 ngx_resolver_ctx_t *w, **p; |
799 struct sockaddr_in *sin; | |
774 ngx_resolver_node_t *rn; | 800 ngx_resolver_node_t *rn; |
801 | |
802 if (ctx->addr.sockaddr->sa_family != AF_INET) { | |
803 return; | |
804 } | |
805 | |
806 sin = (struct sockaddr_in *) ctx->addr.sockaddr; | |
807 addr = ntohl(sin->sin_addr.s_addr); | |
775 | 808 |
776 r = ctx->resolver; | 809 r = ctx->resolver; |
777 | 810 |
778 ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0, | 811 ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0, |
779 "resolve addr done: %i", ctx->state); | 812 "resolve addr done: %i", ctx->state); |
784 | 817 |
785 /* lock addr mutex */ | 818 /* lock addr mutex */ |
786 | 819 |
787 if (ctx->state == NGX_AGAIN || ctx->state == NGX_RESOLVE_TIMEDOUT) { | 820 if (ctx->state == NGX_AGAIN || ctx->state == NGX_RESOLVE_TIMEDOUT) { |
788 | 821 |
789 rn = ngx_resolver_lookup_addr(r, ctx->addr); | 822 rn = ngx_resolver_lookup_addr(r, addr); |
790 | 823 |
791 if (rn) { | 824 if (rn) { |
792 p = &rn->waiting; | 825 p = &rn->waiting; |
793 w = rn->waiting; | 826 w = rn->waiting; |
794 | 827 |
801 | 834 |
802 p = &w->next; | 835 p = &w->next; |
803 w = w->next; | 836 w = w->next; |
804 } | 837 } |
805 } | 838 } |
806 | |
807 addr = ntohl(ctx->addr); | |
808 | 839 |
809 ngx_log_error(NGX_LOG_ALERT, r->log, 0, | 840 ngx_log_error(NGX_LOG_ALERT, r->log, 0, |
810 "could not cancel %ud.%ud.%ud.%ud resolving", | 841 "could not cancel %ud.%ud.%ud.%ud resolving", |
811 (addr >> 24) & 0xff, (addr >> 16) & 0xff, | 842 (addr >> 24) & 0xff, (addr >> 16) & 0xff, |
812 (addr >> 8) & 0xff, addr & 0xff); | 843 (addr >> 8) & 0xff, addr & 0xff); |
1175 char *err; | 1206 char *err; |
1176 u_char *cname; | 1207 u_char *cname; |
1177 size_t len; | 1208 size_t len; |
1178 int32_t ttl; | 1209 int32_t ttl; |
1179 uint32_t hash; | 1210 uint32_t hash; |
1180 in_addr_t addr, *addrs; | 1211 in_addr_t *addr; |
1181 ngx_str_t name; | 1212 ngx_str_t name; |
1213 ngx_addr_t *addrs; | |
1182 ngx_uint_t type, class, qident, naddrs, a, i, n, start; | 1214 ngx_uint_t type, class, qident, naddrs, a, i, n, start; |
1183 ngx_resolver_an_t *an; | 1215 ngx_resolver_an_t *an; |
1184 ngx_resolver_ctx_t *ctx, *next; | 1216 ngx_resolver_ctx_t *ctx, *next; |
1185 ngx_resolver_node_t *rn; | 1217 ngx_resolver_node_t *rn; |
1186 | 1218 |
1245 return; | 1277 return; |
1246 } | 1278 } |
1247 | 1279 |
1248 i = ans; | 1280 i = ans; |
1249 naddrs = 0; | 1281 naddrs = 0; |
1250 addr = 0; | |
1251 addrs = NULL; | |
1252 cname = NULL; | 1282 cname = NULL; |
1253 ttl = 0; | 1283 ttl = 0; |
1254 | 1284 |
1255 for (a = 0; a < nan; a++) { | 1285 for (a = 0; a < nan; a++) { |
1256 | 1286 |
1317 | 1347 |
1318 if (i + 4 > last) { | 1348 if (i + 4 > last) { |
1319 goto short_response; | 1349 goto short_response; |
1320 } | 1350 } |
1321 | 1351 |
1322 addr = htonl((buf[i] << 24) + (buf[i + 1] << 16) | |
1323 + (buf[i + 2] << 8) + (buf[i + 3])); | |
1324 | |
1325 naddrs++; | 1352 naddrs++; |
1326 | 1353 |
1327 break; | 1354 break; |
1328 | 1355 |
1329 case NGX_RESOLVE_CNAME: | 1356 case NGX_RESOLVE_CNAME: |
1350 naddrs, cname, ttl); | 1377 naddrs, cname, ttl); |
1351 | 1378 |
1352 if (naddrs) { | 1379 if (naddrs) { |
1353 | 1380 |
1354 if (naddrs == 1) { | 1381 if (naddrs == 1) { |
1355 rn->u.addr = addr; | 1382 addr = &rn->u.addr; |
1383 rn->naddrs = 1; | |
1356 | 1384 |
1357 } else { | 1385 } else { |
1358 | 1386 addr = ngx_resolver_alloc(r, naddrs * sizeof(in_addr_t)); |
1359 addrs = ngx_resolver_alloc(r, naddrs * sizeof(in_addr_t)); | 1387 if (addr == NULL) { |
1388 goto failed; | |
1389 } | |
1390 | |
1391 rn->u.addrs = addr; | |
1392 rn->naddrs = (u_short) naddrs; | |
1393 } | |
1394 | |
1395 n = 0; | |
1396 i = ans; | |
1397 | |
1398 for (a = 0; a < nan; a++) { | |
1399 | |
1400 for ( ;; ) { | |
1401 | |
1402 if (buf[i] & 0xc0) { | |
1403 i += 2; | |
1404 break; | |
1405 } | |
1406 | |
1407 if (buf[i] == 0) { | |
1408 i++; | |
1409 break; | |
1410 } | |
1411 | |
1412 i += 1 + buf[i]; | |
1413 } | |
1414 | |
1415 an = (ngx_resolver_an_t *) &buf[i]; | |
1416 | |
1417 type = (an->type_hi << 8) + an->type_lo; | |
1418 len = (an->len_hi << 8) + an->len_lo; | |
1419 | |
1420 i += sizeof(ngx_resolver_an_t); | |
1421 | |
1422 if (type == NGX_RESOLVE_A) { | |
1423 | |
1424 addr[n] = htonl((buf[i] << 24) + (buf[i + 1] << 16) | |
1425 + (buf[i + 2] << 8) + (buf[i + 3])); | |
1426 | |
1427 if (++n == naddrs) { | |
1428 break; | |
1429 } | |
1430 } | |
1431 | |
1432 i += len; | |
1433 } | |
1434 | |
1435 if (naddrs == 1) { | |
1436 addrs = NULL; | |
1437 | |
1438 } else { | |
1439 addrs = ngx_resolver_export(r, rn->u.addrs, naddrs, 0); | |
1360 if (addrs == NULL) { | 1440 if (addrs == NULL) { |
1361 goto failed; | 1441 goto failed; |
1362 } | 1442 } |
1363 | 1443 } |
1364 n = 0; | |
1365 i = ans; | |
1366 | |
1367 for (a = 0; a < nan; a++) { | |
1368 | |
1369 for ( ;; ) { | |
1370 | |
1371 if (buf[i] & 0xc0) { | |
1372 i += 2; | |
1373 break; | |
1374 } | |
1375 | |
1376 if (buf[i] == 0) { | |
1377 i++; | |
1378 break; | |
1379 } | |
1380 | |
1381 i += 1 + buf[i]; | |
1382 } | |
1383 | |
1384 an = (ngx_resolver_an_t *) &buf[i]; | |
1385 | |
1386 type = (an->type_hi << 8) + an->type_lo; | |
1387 len = (an->len_hi << 8) + an->len_lo; | |
1388 | |
1389 i += sizeof(ngx_resolver_an_t); | |
1390 | |
1391 if (type == NGX_RESOLVE_A) { | |
1392 | |
1393 addrs[n++] = htonl((buf[i] << 24) + (buf[i + 1] << 16) | |
1394 + (buf[i + 2] << 8) + (buf[i + 3])); | |
1395 | |
1396 if (n == naddrs) { | |
1397 break; | |
1398 } | |
1399 } | |
1400 | |
1401 i += len; | |
1402 } | |
1403 | |
1404 rn->u.addrs = addrs; | |
1405 | |
1406 addrs = ngx_resolver_dup(r, rn->u.addrs, | |
1407 naddrs * sizeof(in_addr_t)); | |
1408 if (addrs == NULL) { | |
1409 goto failed; | |
1410 } | |
1411 } | |
1412 | |
1413 rn->naddrs = (u_short) naddrs; | |
1414 | 1444 |
1415 ngx_queue_remove(&rn->queue); | 1445 ngx_queue_remove(&rn->queue); |
1416 | 1446 |
1417 rn->valid = ngx_time() + (r->valid ? r->valid : ttl); | 1447 rn->valid = ngx_time() + (r->valid ? r->valid : ttl); |
1418 rn->expire = ngx_time() + r->expire; | 1448 rn->expire = ngx_time() + r->expire; |
1426 | 1456 |
1427 while (next) { | 1457 while (next) { |
1428 ctx = next; | 1458 ctx = next; |
1429 ctx->state = NGX_OK; | 1459 ctx->state = NGX_OK; |
1430 ctx->naddrs = naddrs; | 1460 ctx->naddrs = naddrs; |
1431 ctx->addrs = (naddrs == 1) ? &ctx->addr : addrs; | 1461 |
1432 ctx->addr = addr; | 1462 if (addrs == NULL) { |
1463 ctx->addrs = &ctx->addr; | |
1464 ctx->addr.sockaddr = (struct sockaddr *) &ctx->sin; | |
1465 ctx->addr.socklen = sizeof(struct sockaddr_in); | |
1466 ngx_memzero(&ctx->sin, sizeof(struct sockaddr_in)); | |
1467 ctx->sin.sin_family = AF_INET; | |
1468 ctx->sin.sin_addr.s_addr = rn->u.addr; | |
1469 | |
1470 } else { | |
1471 ctx->addrs = addrs; | |
1472 } | |
1473 | |
1433 next = ctx->next; | 1474 next = ctx->next; |
1434 | 1475 |
1435 ctx->handler(ctx); | 1476 ctx->handler(ctx); |
1436 } | 1477 } |
1437 | 1478 |
1438 if (naddrs > 1) { | 1479 if (addrs != NULL) { |
1480 ngx_resolver_free(r, addrs->sockaddr); | |
1439 ngx_resolver_free(r, addrs); | 1481 ngx_resolver_free(r, addrs); |
1440 } | 1482 } |
1441 | 1483 |
1442 ngx_resolver_free(r, rn->query); | 1484 ngx_resolver_free(r, rn->query); |
1443 rn->query = NULL; | 1485 rn->query = NULL; |
1916 static ngx_int_t | 1958 static ngx_int_t |
1917 ngx_resolver_create_addr_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx) | 1959 ngx_resolver_create_addr_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx) |
1918 { | 1960 { |
1919 u_char *p, *d; | 1961 u_char *p, *d; |
1920 size_t len; | 1962 size_t len; |
1963 in_addr_t addr; | |
1921 ngx_int_t n; | 1964 ngx_int_t n; |
1922 ngx_uint_t ident; | 1965 ngx_uint_t ident; |
1923 ngx_resolver_hdr_t *query; | 1966 ngx_resolver_hdr_t *query; |
1967 struct sockaddr_in *sin; | |
1968 | |
1969 if (ctx->addr.sockaddr->sa_family != AF_INET) { | |
1970 return NGX_ERROR; | |
1971 } | |
1924 | 1972 |
1925 len = sizeof(ngx_resolver_hdr_t) | 1973 len = sizeof(ngx_resolver_hdr_t) |
1926 + sizeof(".255.255.255.255.in-addr.arpa.") - 1 | 1974 + sizeof(".255.255.255.255.in-addr.arpa.") - 1 |
1927 + sizeof(ngx_resolver_qs_t); | 1975 + sizeof(ngx_resolver_qs_t); |
1928 | 1976 |
1948 query->nns_hi = 0; query->nns_lo = 0; | 1996 query->nns_hi = 0; query->nns_lo = 0; |
1949 query->nar_hi = 0; query->nar_lo = 0; | 1997 query->nar_hi = 0; query->nar_lo = 0; |
1950 | 1998 |
1951 p += sizeof(ngx_resolver_hdr_t); | 1999 p += sizeof(ngx_resolver_hdr_t); |
1952 | 2000 |
2001 sin = (struct sockaddr_in *) ctx->addr.sockaddr; | |
2002 addr = ntohl(sin->sin_addr.s_addr); | |
2003 | |
1953 for (n = 0; n < 32; n += 8) { | 2004 for (n = 0; n < 32; n += 8) { |
1954 d = ngx_sprintf(&p[1], "%ud", (ctx->addr >> n) & 0xff); | 2005 d = ngx_sprintf(&p[1], "%ud", (addr >> n) & 0xff); |
1955 *p = (u_char) (d - &p[1]); | 2006 *p = (u_char) (d - &p[1]); |
1956 p = d; | 2007 p = d; |
1957 } | 2008 } |
1958 | 2009 |
1959 /* query type "PTR", IN query class */ | 2010 /* query type "PTR", IN query class */ |
2165 | 2216 |
2166 return dst; | 2217 return dst; |
2167 } | 2218 } |
2168 | 2219 |
2169 | 2220 |
2170 static in_addr_t * | 2221 static ngx_addr_t * |
2171 ngx_resolver_rotate(ngx_resolver_t *r, in_addr_t *src, ngx_uint_t n) | 2222 ngx_resolver_export(ngx_resolver_t *r, in_addr_t *src, ngx_uint_t n, |
2172 { | 2223 ngx_uint_t rotate) |
2173 void *dst, *p; | 2224 { |
2174 ngx_uint_t j; | 2225 ngx_addr_t *dst; |
2175 | 2226 ngx_uint_t i, j; |
2176 dst = ngx_resolver_alloc(r, n * sizeof(in_addr_t)); | 2227 struct sockaddr_in *sin; |
2177 | 2228 |
2229 dst = ngx_resolver_calloc(r, n * sizeof(ngx_addr_t)); | |
2178 if (dst == NULL) { | 2230 if (dst == NULL) { |
2179 return dst; | 2231 return NULL; |
2180 } | 2232 } |
2181 | 2233 |
2182 j = ngx_random() % n; | 2234 sin = ngx_resolver_calloc(r, n * sizeof(struct sockaddr_in)); |
2183 | 2235 |
2184 if (j == 0) { | 2236 if (sin == NULL) { |
2185 ngx_memcpy(dst, src, n * sizeof(in_addr_t)); | 2237 ngx_resolver_free(r, dst); |
2186 return dst; | 2238 return NULL; |
2187 } | 2239 } |
2188 | 2240 |
2189 p = ngx_cpymem(dst, &src[j], (n - j) * sizeof(in_addr_t)); | 2241 j = rotate ? ngx_random() % n : 0; |
2190 ngx_memcpy(p, src, j * sizeof(in_addr_t)); | 2242 |
2243 for (i = 0; i < n; i++) { | |
2244 dst[i].sockaddr = (struct sockaddr *) &sin[i]; | |
2245 dst[i].socklen = sizeof(struct sockaddr_in); | |
2246 sin[i].sin_family = AF_INET; | |
2247 sin[i].sin_addr.s_addr = src[j++]; | |
2248 | |
2249 if (j == n) { | |
2250 j = 0; | |
2251 } | |
2252 } | |
2191 | 2253 |
2192 return dst; | 2254 return dst; |
2193 } | 2255 } |
2194 | 2256 |
2195 | 2257 |