Deleted
Added
nxt_sockaddr.c (2154:68987edde84a) | nxt_sockaddr.c (2175:e83cff38d672) |
---|---|
1 2/* 3 * Copyright (C) Igor Sysoev 4 * Copyright (C) NGINX, Inc. 5 */ 6 7#include <nxt_main.h> 8 9 10#if (NXT_INET6) 11static u_char *nxt_inet6_ntop(u_char *addr, u_char *buf, u_char *end); 12#endif 13 14static nxt_sockaddr_t *nxt_sockaddr_unix_parse(nxt_mp_t *mp, nxt_str_t *addr); 15static nxt_sockaddr_t *nxt_sockaddr_inet6_parse(nxt_mp_t *mp, nxt_str_t *addr); 16static nxt_sockaddr_t *nxt_sockaddr_inet_parse(nxt_mp_t *mp, nxt_str_t *addr); 17 | 1 2/* 3 * Copyright (C) Igor Sysoev 4 * Copyright (C) NGINX, Inc. 5 */ 6 7#include <nxt_main.h> 8 9 10#if (NXT_INET6) 11static u_char *nxt_inet6_ntop(u_char *addr, u_char *buf, u_char *end); 12#endif 13 14static nxt_sockaddr_t *nxt_sockaddr_unix_parse(nxt_mp_t *mp, nxt_str_t *addr); 15static nxt_sockaddr_t *nxt_sockaddr_inet6_parse(nxt_mp_t *mp, nxt_str_t *addr); 16static nxt_sockaddr_t *nxt_sockaddr_inet_parse(nxt_mp_t *mp, nxt_str_t *addr); 17 |
18static nxt_int_t nxt_job_sockaddr_unix_parse(nxt_job_sockaddr_parse_t *jbs); 19static nxt_int_t nxt_job_sockaddr_inet6_parse(nxt_job_sockaddr_parse_t *jbs); 20static nxt_int_t nxt_job_sockaddr_inet_parse(nxt_job_sockaddr_parse_t *jbs); | |
21 | 18 |
22 | |
23nxt_sockaddr_t * 24nxt_sockaddr_cache_alloc(nxt_event_engine_t *engine, nxt_listen_socket_t *ls) 25{ 26 size_t size; 27 uint8_t hint; 28 nxt_sockaddr_t *sa; 29 30 hint = NXT_EVENT_ENGINE_NO_MEM_HINT; --- 397 unchanged lines hidden (view full) --- 428 return 0; 429 } 430 431 return 1; 432 } 433} 434 435 | 19nxt_sockaddr_t * 20nxt_sockaddr_cache_alloc(nxt_event_engine_t *engine, nxt_listen_socket_t *ls) 21{ 22 size_t size; 23 uint8_t hint; 24 nxt_sockaddr_t *sa; 25 26 hint = NXT_EVENT_ENGINE_NO_MEM_HINT; --- 397 unchanged lines hidden (view full) --- 424 return 0; 425 } 426 427 return 1; 428 } 429} 430 431 |
436size_t 437nxt_sockaddr_ntop(nxt_sockaddr_t *sa, u_char *buf, u_char *end, nxt_bool_t port) 438{ 439 u_char *p; 440 441 switch (sa->u.sockaddr.sa_family) { 442 443 case AF_INET: 444 p = (u_char *) &sa->u.sockaddr_in.sin_addr; 445 446 if (port) { 447 p = nxt_sprintf(buf, end, "%ud.%ud.%ud.%ud:%d", 448 p[0], p[1], p[2], p[3], 449 ntohs(sa->u.sockaddr_in.sin_port)); 450 } else { 451 p = nxt_sprintf(buf, end, "%ud.%ud.%ud.%ud", 452 p[0], p[1], p[2], p[3]); 453 } 454 455 return p - buf; 456 | |
457#if (NXT_INET6) 458 | 432#if (NXT_INET6) 433 |
459 case AF_INET6: 460 p = buf; 461 462 if (port) { 463 *p++ = '['; 464 } 465 466 p = nxt_inet6_ntop(sa->u.sockaddr_in6.sin6_addr.s6_addr, p, end); 467 468 if (port) { 469 p = nxt_sprintf(p, end, "]:%d", 470 ntohs(sa->u.sockaddr_in6.sin6_port)); 471 } 472 473 return p - buf; 474#endif 475 476#if (NXT_HAVE_UNIX_DOMAIN) 477 478 case AF_UNIX: 479 480#if (NXT_LINUX) 481 482 p = (u_char *) sa->u.sockaddr_un.sun_path; 483 484 if (p[0] == '\0') { 485 size_t length; 486 487 /* Linux abstract socket address has no trailing zero. */ 488 489 length = sa->socklen - offsetof(struct sockaddr_un, sun_path) - 1; 490 p = nxt_sprintf(buf, end, "unix:\\0%*s", length, p + 1); 491 492 } else { 493 p = nxt_sprintf(buf, end, "unix:%s", p); 494 } 495 496#else /* !(NXT_LINUX) */ 497 498 p = nxt_sprintf(buf, end, "unix:%s", sa->u.sockaddr_un.sun_path); 499 500#endif 501 502 return p - buf; 503 504#endif /* NXT_HAVE_UNIX_DOMAIN */ 505 506 default: 507 return 0; 508 } 509} 510 511 512#if (NXT_INET6) 513 | |
514static u_char * 515nxt_inet6_ntop(u_char *addr, u_char *buf, u_char *end) 516{ 517 u_char *p; 518 size_t zero_groups, last_zero_groups, ipv6_bytes; 519 nxt_uint_t i, zero_start, last_zero_start; 520 521 const size_t max_inet6_length = --- 322 unchanged lines hidden (view full) --- 844 sa->u.sockaddr_in.sin_family = AF_INET; 845 sa->u.sockaddr_in.sin_addr.s_addr = inaddr; 846 sa->u.sockaddr_in.sin_port = htons((in_port_t) port); 847 848 return sa; 849} 850 851 | 434static u_char * 435nxt_inet6_ntop(u_char *addr, u_char *buf, u_char *end) 436{ 437 u_char *p; 438 size_t zero_groups, last_zero_groups, ipv6_bytes; 439 nxt_uint_t i, zero_start, last_zero_start; 440 441 const size_t max_inet6_length = --- 322 unchanged lines hidden (view full) --- 764 sa->u.sockaddr_in.sin_family = AF_INET; 765 sa->u.sockaddr_in.sin_addr.s_addr = inaddr; 766 sa->u.sockaddr_in.sin_port = htons((in_port_t) port); 767 768 return sa; 769} 770 771 |
852void 853nxt_job_sockaddr_parse(nxt_job_sockaddr_parse_t *jbs) 854{ 855 u_char *p; 856 size_t length; 857 nxt_int_t ret; 858 nxt_work_handler_t handler; 859 860 nxt_job_set_name(&jbs->resolve.job, "job sockaddr parse"); 861 862 length = jbs->addr.length; 863 p = jbs->addr.start; 864 865 if (length > 6 && nxt_memcmp(p, "unix:", 5) == 0) { 866 ret = nxt_job_sockaddr_unix_parse(jbs); 867 868 } else if (length != 0 && *p == '[') { 869 ret = nxt_job_sockaddr_inet6_parse(jbs); 870 871 } else { 872 ret = nxt_job_sockaddr_inet_parse(jbs); 873 } 874 875 switch (ret) { 876 877 case NXT_OK: 878 handler = jbs->resolve.ready_handler; 879 break; 880 881 case NXT_ERROR: 882 handler = jbs->resolve.error_handler; 883 break; 884 885 default: /* NXT_AGAIN */ 886 return; 887 } 888 889 nxt_job_return(jbs->resolve.job.task, &jbs->resolve.job, handler); 890} 891 892 893static nxt_int_t 894nxt_job_sockaddr_unix_parse(nxt_job_sockaddr_parse_t *jbs) 895{ 896#if (NXT_HAVE_UNIX_DOMAIN) 897 size_t length, socklen; 898 u_char *path; 899 nxt_mp_t *mp; 900 nxt_sockaddr_t *sa; 901 902 /* 903 * Actual sockaddr_un length can be lesser or even larger than defined 904 * struct sockaddr_un length (see comment in nxt_socket.h). So 905 * limit maximum Unix domain socket address length by defined sun_path[] 906 * length because some OSes accept addresses twice larger than defined 907 * struct sockaddr_un. Also reserve space for a trailing zero to avoid 908 * ambiguity, since many OSes accept Unix domain socket addresses 909 * without a trailing zero. 910 */ 911 const size_t max_len = sizeof(struct sockaddr_un) 912 - offsetof(struct sockaddr_un, sun_path) - 1; 913 914 /* cutting "unix:" */ 915 length = jbs->addr.length - 5; 916 path = jbs->addr.start + 5; 917 918 if (length > max_len) { 919 nxt_thread_log_error(jbs->resolve.log_level, 920 "unix domain socket \"%V\" name is too long", 921 &jbs->addr); 922 return NXT_ERROR; 923 } 924 925 socklen = offsetof(struct sockaddr_un, sun_path) + length + 1; 926 927#if (NXT_LINUX) 928 929 /* 930 * Linux unix(7): 931 * 932 * abstract: an abstract socket address is distinguished by the fact 933 * that sun_path[0] is a null byte ('\0'). The socket's address in 934 * this namespace is given by the additional bytes in sun_path that 935 * are covered by the specified length of the address structure. 936 * (Null bytes in the name have no special significance.) 937 */ 938 if (path[0] == '\0') { 939 socklen--; 940 } 941 942#endif 943 944 mp = jbs->resolve.job.mem_pool; 945 946 jbs->resolve.sockaddrs = nxt_mp_alloc(mp, sizeof(void *)); 947 948 if (nxt_fast_path(jbs->resolve.sockaddrs != NULL)) { 949 sa = nxt_sockaddr_alloc(mp, socklen, jbs->addr.length); 950 951 if (nxt_fast_path(sa != NULL)) { 952 jbs->resolve.count = 1; 953 jbs->resolve.sockaddrs[0] = sa; 954 955 sa->u.sockaddr_un.sun_family = AF_UNIX; 956 nxt_memcpy(sa->u.sockaddr_un.sun_path, path, length); 957 958 return NXT_OK; 959 } 960 } 961 962 return NXT_ERROR; 963 964#else /* !(NXT_HAVE_UNIX_DOMAIN) */ 965 966 nxt_thread_log_error(jbs->resolve.log_level, 967 "unix domain socket \"%V\" is not supported", 968 &jbs->addr); 969 return NXT_ERROR; 970 971#endif 972} 973 974 975static nxt_int_t 976nxt_job_sockaddr_inet6_parse(nxt_job_sockaddr_parse_t *jbs) 977{ 978#if (NXT_INET6) 979 u_char *p, *addr, *addr_end; 980 size_t length; 981 nxt_mp_t *mp; 982 nxt_int_t port; 983 nxt_sockaddr_t *sa; 984 struct in6_addr *in6_addr; 985 986 length = jbs->addr.length - 1; 987 addr = jbs->addr.start + 1; 988 989 addr_end = nxt_memchr(addr, ']', length); 990 991 if (addr_end == NULL) { 992 goto invalid_address; 993 } 994 995 mp = jbs->resolve.job.mem_pool; 996 997 jbs->resolve.sockaddrs = nxt_mp_alloc(mp, sizeof(void *)); 998 999 if (nxt_slow_path(jbs->resolve.sockaddrs == NULL)) { 1000 return NXT_ERROR; 1001 } 1002 1003 sa = nxt_sockaddr_alloc(mp, sizeof(struct sockaddr_in6), 1004 NXT_INET6_ADDR_STR_LEN); 1005 1006 if (nxt_slow_path(sa == NULL)) { 1007 return NXT_ERROR; 1008 } 1009 1010 jbs->resolve.count = 1; 1011 jbs->resolve.sockaddrs[0] = sa; 1012 1013 in6_addr = &sa->u.sockaddr_in6.sin6_addr; 1014 1015 if (nxt_inet6_addr(in6_addr, addr, addr_end - addr) != NXT_OK) { 1016 goto invalid_address; 1017 } 1018 1019 p = addr_end + 1; 1020 length = (addr + length) - p; 1021 1022 if (length == 0) { 1023 jbs->no_port = 1; 1024 port = jbs->resolve.port; 1025 goto found; 1026 } 1027 1028 if (*p == ':') { 1029 port = nxt_int_parse(p + 1, length - 1); 1030 1031 if (port >= 1 && port <= 65535) { 1032 port = htons((in_port_t) port); 1033 goto found; 1034 } 1035 } 1036 1037 nxt_thread_log_error(jbs->resolve.log_level, 1038 "invalid port in \"%V\"", &jbs->addr); 1039 1040 return NXT_ERROR; 1041 1042found: 1043 1044 sa->u.sockaddr_in6.sin6_family = AF_INET6; 1045 sa->u.sockaddr_in6.sin6_port = (in_port_t) port; 1046 1047 if (IN6_IS_ADDR_UNSPECIFIED(in6_addr)) { 1048 jbs->wildcard = 1; 1049 } 1050 1051 return NXT_OK; 1052 1053invalid_address: 1054 1055 nxt_thread_log_error(jbs->resolve.log_level, 1056 "invalid IPv6 address in \"%V\"", &jbs->addr); 1057 return NXT_ERROR; 1058 1059#else 1060 1061 nxt_thread_log_error(jbs->resolve.log_level, 1062 "IPv6 socket \"%V\" is not supported", &jbs->addr); 1063 return NXT_ERROR; 1064 1065#endif 1066} 1067 1068 1069static nxt_int_t 1070nxt_job_sockaddr_inet_parse(nxt_job_sockaddr_parse_t *jbs) 1071{ 1072 u_char *p, *host; 1073 size_t length; 1074 nxt_mp_t *mp; 1075 nxt_int_t port; 1076 in_addr_t addr; 1077 nxt_sockaddr_t *sa; 1078 1079 addr = INADDR_ANY; 1080 1081 length = jbs->addr.length; 1082 host = jbs->addr.start; 1083 1084 p = nxt_memchr(host, ':', length); 1085 1086 if (p == NULL) { 1087 1088 /* single value port, address, or host name */ 1089 1090 port = nxt_int_parse(host, length); 1091 1092 if (port > 0) { 1093 if (port > 65535) { 1094 goto invalid_port; 1095 } 1096 1097 /* "*:XX" */ 1098 port = htons((in_port_t) port); 1099 jbs->resolve.port = (in_port_t) port; 1100 1101 } else { 1102 jbs->no_port = 1; 1103 1104 addr = nxt_inet_addr(host, length); 1105 1106 if (addr == INADDR_NONE) { 1107 jbs->resolve.name.length = length; 1108 jbs->resolve.name.start = host; 1109 1110 nxt_job_resolve(&jbs->resolve); 1111 return NXT_AGAIN; 1112 } 1113 1114 /* "x.x.x.x" */ 1115 port = jbs->resolve.port; 1116 } 1117 1118 } else { 1119 1120 /* x.x.x.x:XX or host:XX */ 1121 1122 p++; 1123 length = (host + length) - p; 1124 port = nxt_int_parse(p, length); 1125 1126 if (port < 1 || port > 65535) { 1127 goto invalid_port; 1128 } 1129 1130 port = htons((in_port_t) port); 1131 1132 length = (p - 1) - host; 1133 1134 if (length != 1 || host[0] != '*') { 1135 addr = nxt_inet_addr(host, length); 1136 1137 if (addr == INADDR_NONE) { 1138 jbs->resolve.name.length = length; 1139 jbs->resolve.name.start = host; 1140 jbs->resolve.port = (in_port_t) port; 1141 1142 nxt_job_resolve(&jbs->resolve); 1143 return NXT_AGAIN; 1144 } 1145 1146 /* "x.x.x.x:XX" */ 1147 } 1148 } 1149 1150 mp = jbs->resolve.job.mem_pool; 1151 1152 jbs->resolve.sockaddrs = nxt_mp_alloc(mp, sizeof(void *)); 1153 if (nxt_slow_path(jbs->resolve.sockaddrs == NULL)) { 1154 return NXT_ERROR; 1155 } 1156 1157 sa = nxt_sockaddr_alloc(mp, sizeof(struct sockaddr_in), 1158 NXT_INET_ADDR_STR_LEN); 1159 1160 if (nxt_fast_path(sa != NULL)) { 1161 jbs->resolve.count = 1; 1162 jbs->resolve.sockaddrs[0] = sa; 1163 1164 jbs->wildcard = (addr == INADDR_ANY); 1165 1166 sa->u.sockaddr_in.sin_family = AF_INET; 1167 sa->u.sockaddr_in.sin_port = (in_port_t) port; 1168 sa->u.sockaddr_in.sin_addr.s_addr = addr; 1169 1170 return NXT_OK; 1171 } 1172 1173 return NXT_ERROR; 1174 1175invalid_port: 1176 1177 nxt_thread_log_error(jbs->resolve.log_level, 1178 "invalid port in \"%V\"", &jbs->addr); 1179 1180 return NXT_ERROR; 1181} 1182 1183 | |
1184in_addr_t 1185nxt_inet_addr(u_char *buf, size_t length) 1186{ 1187 u_char c, *end; 1188 in_addr_t addr; 1189 nxt_uint_t digit, octet, dots; 1190 1191 if (nxt_slow_path(*(buf + length - 1) == '.')) { --- 195 unchanged lines hidden --- | 772in_addr_t 773nxt_inet_addr(u_char *buf, size_t length) 774{ 775 u_char c, *end; 776 in_addr_t addr; 777 nxt_uint_t digit, octet, dots; 778 779 if (nxt_slow_path(*(buf + length - 1) == '.')) { --- 195 unchanged lines hidden --- |