diff options
author | Christian Grothoff <christian@grothoff.org> | 2018-07-01 19:38:06 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2018-07-01 19:38:06 +0200 |
commit | d409018c1da52d051bf2e95cd97a73e72cb5accd (patch) | |
tree | ae9865b0fe7c57f6553c8a8afc3706142e9595ef /src/gns/nss | |
parent | dd68d665e140970c7d9dfd899fbdd4fefacb54a7 (diff) | |
download | gnunet-d409018c1da52d051bf2e95cd97a73e72cb5accd.tar.gz gnunet-d409018c1da52d051bf2e95cd97a73e72cb5accd.zip |
move gnunet-timeout to src/util/, fix issues related to #5375
Diffstat (limited to 'src/gns/nss')
-rw-r--r-- | src/gns/nss/nss_gns.c | 269 | ||||
-rw-r--r-- | src/gns/nss/nss_gns_query.c | 25 | ||||
-rw-r--r-- | src/gns/nss/nss_gns_query.h | 30 |
3 files changed, 172 insertions, 152 deletions
diff --git a/src/gns/nss/nss_gns.c b/src/gns/nss/nss_gns.c index 9c9233d35..58aab47fd 100644 --- a/src/gns/nss/nss_gns.c +++ b/src/gns/nss/nss_gns.c | |||
@@ -54,121 +54,126 @@ | |||
54 | * @return a nss_status code | 54 | * @return a nss_status code |
55 | */ | 55 | */ |
56 | enum nss_status | 56 | enum nss_status |
57 | _nss_gns_gethostbyname2_r( | 57 | _nss_gns_gethostbyname2_r(const char *name, |
58 | const char *name, | 58 | int af, |
59 | int af, | 59 | struct hostent *result, |
60 | struct hostent * result, | 60 | char *buffer, |
61 | char *buffer, | 61 | size_t buflen, |
62 | size_t buflen, | 62 | int *errnop, |
63 | int *errnop, | 63 | int *h_errnop) |
64 | int *h_errnop) { | 64 | { |
65 | 65 | struct userdata u; | |
66 | struct userdata u; | 66 | enum nss_status status = NSS_STATUS_UNAVAIL; |
67 | enum nss_status status = NSS_STATUS_UNAVAIL; | 67 | int i; |
68 | int i; | 68 | size_t address_length; |
69 | size_t address_length, l, idx, astart; | 69 | size_t l; |
70 | 70 | size_t idx; | |
71 | if (af == AF_UNSPEC) | 71 | size_t astart; |
72 | |||
73 | if (af == AF_UNSPEC) | ||
72 | #ifdef NSS_IPV6_ONLY | 74 | #ifdef NSS_IPV6_ONLY |
73 | af = AF_INET6; | 75 | af = AF_INET6; |
74 | #else | 76 | #else |
75 | af = AF_INET; | 77 | af = AF_INET; |
76 | #endif | 78 | #endif |
77 | 79 | ||
78 | #ifdef NSS_IPV4_ONLY | 80 | #ifdef NSS_IPV4_ONLY |
79 | if (af != AF_INET) | 81 | if (af != AF_INET) |
80 | #elif NSS_IPV6_ONLY | 82 | #elif NSS_IPV6_ONLY |
81 | if (af != AF_INET6) | 83 | if (af != AF_INET6) |
82 | #else | 84 | #else |
83 | if (af != AF_INET && af != AF_INET6) | 85 | if ( (af != AF_INET) && |
86 | (af != AF_INET6) ) | ||
84 | #endif | 87 | #endif |
85 | { | 88 | { |
86 | *errnop = EINVAL; | 89 | *errnop = EINVAL; |
87 | *h_errnop = NO_RECOVERY; | 90 | *h_errnop = NO_RECOVERY; |
88 | 91 | ||
89 | goto finish; | 92 | goto finish; |
90 | } | 93 | } |
91 | |||
92 | address_length = af == AF_INET ? sizeof(ipv4_address_t) : sizeof(ipv6_address_t); | ||
93 | if (buflen < | ||
94 | sizeof(char*)+ /* alias names */ | ||
95 | strlen(name)+1) { /* official name */ | ||
96 | |||
97 | *errnop = ERANGE; | ||
98 | *h_errnop = NO_RECOVERY; | ||
99 | status = NSS_STATUS_TRYAGAIN; | ||
100 | |||
101 | goto finish; | ||
102 | } | ||
103 | |||
104 | u.count = 0; | ||
105 | u.data_len = 0; | ||
106 | |||
107 | i = gns_resolve_name(af, name, &u); | ||
108 | if (-3 == i) | ||
109 | { | ||
110 | status = NSS_STATUS_NOTFOUND; | ||
111 | goto finish; | ||
112 | } | ||
113 | if (-2 == i) | ||
114 | { | ||
115 | status = NSS_STATUS_UNAVAIL; | ||
116 | goto finish; | ||
117 | } | ||
118 | if ( (-1 == i) || | ||
119 | (u.count == 0) ) | ||
120 | { | ||
121 | *errnop = ETIMEDOUT; | ||
122 | *h_errnop = HOST_NOT_FOUND; | ||
123 | status = NSS_STATUS_NOTFOUND; | ||
124 | goto finish; | ||
125 | } | ||
126 | |||
127 | |||
128 | /* Alias names */ | ||
129 | *((char**) buffer) = NULL; | ||
130 | result->h_aliases = (char**) buffer; | ||
131 | idx = sizeof(char*); | ||
132 | |||
133 | /* Official name */ | ||
134 | strcpy(buffer+idx, name); | ||
135 | result->h_name = buffer+idx; | ||
136 | idx += strlen(name)+1; | ||
137 | |||
138 | ALIGN(idx); | ||
139 | |||
140 | result->h_addrtype = af; | ||
141 | result->h_length = address_length; | ||
142 | |||
143 | /* Check if there's enough space for the addresses */ | ||
144 | if (buflen < idx+u.data_len+sizeof(char*)*(u.count+1)) { | ||
145 | *errnop = ERANGE; | ||
146 | *h_errnop = NO_RECOVERY; | ||
147 | status = NSS_STATUS_TRYAGAIN; | ||
148 | goto finish; | ||
149 | } | ||
150 | 94 | ||
95 | address_length = (af == AF_INET) ? sizeof(ipv4_address_t) : sizeof(ipv6_address_t); | ||
96 | if (buflen < | ||
97 | sizeof(char*)+ /* alias names */ | ||
98 | strlen(name)+1) | ||
99 | { /* official name */ | ||
100 | *errnop = ERANGE; | ||
101 | *h_errnop = NO_RECOVERY; | ||
102 | status = NSS_STATUS_TRYAGAIN; | ||
103 | |||
104 | goto finish; | ||
105 | } | ||
106 | u.count = 0; | ||
107 | u.data_len = 0; | ||
108 | i = gns_resolve_name (af, | ||
109 | name, | ||
110 | &u); | ||
111 | if (-3 == i) | ||
112 | { | ||
113 | status = NSS_STATUS_NOTFOUND; | ||
114 | goto finish; | ||
115 | } | ||
116 | if (-2 == i) | ||
117 | { | ||
118 | status = NSS_STATUS_UNAVAIL; | ||
119 | goto finish; | ||
120 | } | ||
121 | if ( (-1 == i) || | ||
122 | (u.count == 0) ) | ||
123 | { | ||
124 | *errnop = ETIMEDOUT; | ||
125 | *h_errnop = HOST_NOT_FOUND; | ||
126 | status = NSS_STATUS_NOTFOUND; | ||
127 | goto finish; | ||
128 | } | ||
129 | /* Alias names */ | ||
130 | *((char**) buffer) = NULL; | ||
131 | result->h_aliases = (char**) buffer; | ||
132 | idx = sizeof(char*); | ||
133 | |||
134 | /* Official name */ | ||
135 | strcpy (buffer+idx, | ||
136 | name); | ||
137 | result->h_name = buffer+idx; | ||
138 | idx += strlen (name)+1; | ||
139 | |||
140 | ALIGN(idx); | ||
141 | |||
142 | result->h_addrtype = af; | ||
143 | result->h_length = address_length; | ||
144 | |||
145 | /* Check if there's enough space for the addresses */ | ||
146 | if (buflen < idx+u.data_len+sizeof(char*)*(u.count+1)) | ||
147 | { | ||
148 | *errnop = ERANGE; | ||
149 | *h_errnop = NO_RECOVERY; | ||
150 | status = NSS_STATUS_TRYAGAIN; | ||
151 | goto finish; | ||
152 | } | ||
151 | /* Addresses */ | 153 | /* Addresses */ |
152 | astart = idx; | 154 | astart = idx; |
153 | l = u.count*address_length; | 155 | l = u.count*address_length; |
154 | if (0 != l) | 156 | if (0 != l) |
155 | memcpy(buffer+astart, &u.data, l); | 157 | memcpy (buffer+astart, |
156 | /* address_length is a multiple of 32bits, so idx is still aligned | 158 | &u.data, |
157 | * correctly */ | 159 | l); |
158 | idx += l; | 160 | /* address_length is a multiple of 32bits, so idx is still aligned |
159 | 161 | * correctly */ | |
160 | /* Address array address_length is always a multiple of 32bits */ | 162 | idx += l; |
161 | for (i = 0; i < u.count; i++) | 163 | |
162 | ((char**) (buffer+idx))[i] = buffer+astart+address_length*i; | 164 | /* Address array address_length is always a multiple of 32bits */ |
163 | ((char**) (buffer+idx))[i] = NULL; | 165 | for (i = 0; i < u.count; i++) |
164 | result->h_addr_list = (char**) (buffer+idx); | 166 | ((char**) (buffer+idx))[i] = buffer+astart+address_length*i; |
165 | 167 | ((char**) (buffer+idx))[i] = NULL; | |
166 | status = NSS_STATUS_SUCCESS; | 168 | result->h_addr_list = (char**) (buffer+idx); |
169 | |||
170 | status = NSS_STATUS_SUCCESS; | ||
167 | 171 | ||
168 | finish: | 172 | finish: |
169 | return status; | 173 | return status; |
170 | } | 174 | } |
171 | 175 | ||
176 | |||
172 | /** | 177 | /** |
173 | * The gethostbyname hook executed by nsswitch | 178 | * The gethostbyname hook executed by nsswitch |
174 | * | 179 | * |
@@ -176,29 +181,28 @@ finish: | |||
176 | * @param result the result hostent | 181 | * @param result the result hostent |
177 | * @param buffer the result buffer | 182 | * @param buffer the result buffer |
178 | * @param buflen length of the buffer | 183 | * @param buflen length of the buffer |
179 | * @param errnop idk | 184 | * @param errnop[out] the low-level error code to return to the application |
180 | * @param h_errnop idk | 185 | * @param h_errnop idk |
181 | * @return a nss_status code | 186 | * @return a nss_status code |
182 | */ | 187 | */ |
183 | enum nss_status | 188 | enum nss_status |
184 | _nss_gns_gethostbyname_r ( | 189 | _nss_gns_gethostbyname_r (const char *name, |
185 | const char *name, | 190 | struct hostent *result, |
186 | struct hostent *result, | 191 | char *buffer, |
187 | char *buffer, | 192 | size_t buflen, |
188 | size_t buflen, | 193 | int *errnop, |
189 | int *errnop, | 194 | int *h_errnop) |
190 | int *h_errnop) { | 195 | { |
191 | 196 | return _nss_gns_gethostbyname2_r (name, | |
192 | return _nss_gns_gethostbyname2_r( | 197 | AF_UNSPEC, |
193 | name, | 198 | result, |
194 | AF_UNSPEC, | 199 | buffer, |
195 | result, | 200 | buflen, |
196 | buffer, | 201 | errnop, |
197 | buflen, | 202 | h_errnop); |
198 | errnop, | ||
199 | h_errnop); | ||
200 | } | 203 | } |
201 | 204 | ||
205 | |||
202 | /** | 206 | /** |
203 | * The gethostbyaddr hook executed by nsswitch | 207 | * The gethostbyaddr hook executed by nsswitch |
204 | * We can't do this so we always return NSS_STATUS_UNAVAIL | 208 | * We can't do this so we always return NSS_STATUS_UNAVAIL |
@@ -209,23 +213,22 @@ _nss_gns_gethostbyname_r ( | |||
209 | * @param result the result hostent | 213 | * @param result the result hostent |
210 | * @param buffer the result buffer | 214 | * @param buffer the result buffer |
211 | * @param buflen length of the buffer | 215 | * @param buflen length of the buffer |
212 | * @param errnop idk | 216 | * @param errnop[out] the low-level error code to return to the application |
213 | * @param h_errnop idk | 217 | * @param h_errnop idk |
214 | * @return NSS_STATUS_UNAVAIL | 218 | * @return NSS_STATUS_UNAVAIL |
215 | */ | 219 | */ |
216 | enum nss_status | 220 | enum nss_status |
217 | _nss_gns_gethostbyaddr_r( | 221 | _nss_gns_gethostbyaddr_r (const void* addr, |
218 | const void* addr, | 222 | int len, |
219 | int len, | 223 | int af, |
220 | int af, | 224 | struct hostent *result, |
221 | struct hostent *result, | 225 | char *buffer, |
222 | char *buffer, | 226 | size_t buflen, |
223 | size_t buflen, | 227 | int *errnop, |
224 | int *errnop, | 228 | int *h_errnop) |
225 | int *h_errnop) { | 229 | { |
226 | 230 | *errnop = EINVAL; | |
227 | *errnop = EINVAL; | 231 | *h_errnop = NO_RECOVERY; |
228 | *h_errnop = NO_RECOVERY; | 232 | //NOTE we allow to leak this into DNS so no NOTFOUND |
229 | //NOTE we allow to leak this into DNS so no NOTFOUND | 233 | return NSS_STATUS_UNAVAIL; |
230 | return NSS_STATUS_UNAVAIL; | ||
231 | } | 234 | } |
diff --git a/src/gns/nss/nss_gns_query.c b/src/gns/nss/nss_gns_query.c index 094e25ed5..867ead624 100644 --- a/src/gns/nss/nss_gns_query.c +++ b/src/gns/nss/nss_gns_query.c | |||
@@ -11,7 +11,7 @@ | |||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Affero General Public License for more details. | 13 | Affero General Public License for more details. |
14 | 14 | ||
15 | You should have received a copy of the GNU Affero General Public License | 15 | You should have received a copy of the GNU Affero General Public License |
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | */ | 17 | */ |
@@ -48,14 +48,16 @@ gns_resolve_name (int af, | |||
48 | { | 48 | { |
49 | if (-1 == asprintf (&cmd, | 49 | if (-1 == asprintf (&cmd, |
50 | "%s -t AAAA -u %s\n", | 50 | "%s -t AAAA -u %s\n", |
51 | "gnunet-gns -r", name)) | 51 | "gnunet-gns -r", |
52 | name)) | ||
52 | return -1; | 53 | return -1; |
53 | } | 54 | } |
54 | else | 55 | else |
55 | { | 56 | { |
56 | if (-1 == asprintf (&cmd, | 57 | if (-1 == asprintf (&cmd, |
57 | "%s %s\n", | 58 | "%s %s\n", |
58 | "gnunet-gns -r -u", name)) | 59 | "gnunet-gns -r -u", |
60 | name)) | ||
59 | return -1; | 61 | return -1; |
60 | } | 62 | } |
61 | if (NULL == (p = popen (cmd, "r"))) | 63 | if (NULL == (p = popen (cmd, "r"))) |
@@ -63,7 +65,9 @@ gns_resolve_name (int af, | |||
63 | free (cmd); | 65 | free (cmd); |
64 | return -1; | 66 | return -1; |
65 | } | 67 | } |
66 | while (NULL != fgets (line, sizeof(line), p)) | 68 | while (NULL != fgets (line, |
69 | sizeof(line), | ||
70 | p)) | ||
67 | { | 71 | { |
68 | if (u->count >= MAX_ENTRIES) | 72 | if (u->count >= MAX_ENTRIES) |
69 | break; | 73 | break; |
@@ -72,7 +76,9 @@ gns_resolve_name (int af, | |||
72 | line[strlen(line)-1] = '\0'; | 76 | line[strlen(line)-1] = '\0'; |
73 | if (AF_INET == af) | 77 | if (AF_INET == af) |
74 | { | 78 | { |
75 | if (inet_pton(af, line, &(u->data.ipv4[u->count]))) | 79 | if (inet_pton(af, |
80 | line, | ||
81 | &u->data.ipv4[u->count])) | ||
76 | { | 82 | { |
77 | u->count++; | 83 | u->count++; |
78 | u->data_len += sizeof(ipv4_address_t); | 84 | u->data_len += sizeof(ipv4_address_t); |
@@ -86,7 +92,9 @@ gns_resolve_name (int af, | |||
86 | } | 92 | } |
87 | else if (AF_INET6 == af) | 93 | else if (AF_INET6 == af) |
88 | { | 94 | { |
89 | if (inet_pton(af, line, &(u->data.ipv6[u->count]))) | 95 | if (inet_pton(af, |
96 | line, | ||
97 | &u->data.ipv6[u->count])) | ||
90 | { | 98 | { |
91 | u->count++; | 99 | u->count++; |
92 | u->data_len += sizeof(ipv6_address_t); | 100 | u->data_len += sizeof(ipv6_address_t); |
@@ -105,7 +113,10 @@ gns_resolve_name (int af, | |||
105 | if (4 == ret) | 113 | if (4 == ret) |
106 | return -2; /* not for GNS */ | 114 | return -2; /* not for GNS */ |
107 | if (3 == ret) | 115 | if (3 == ret) |
108 | return -3; /* timeout */ | 116 | return -3; /* timeout -> not found */ |
117 | if ( (2 == ret) || (1 == ret) ) | ||
118 | return -2; /* launch failure -> service unavailable */ | ||
109 | return 0; | 119 | return 0; |
110 | } | 120 | } |
121 | |||
111 | /* end of nss_gns_query.c */ | 122 | /* end of nss_gns_query.c */ |
diff --git a/src/gns/nss/nss_gns_query.h b/src/gns/nss/nss_gns_query.h index bb04f9004..48cab4b22 100644 --- a/src/gns/nss/nss_gns_query.h +++ b/src/gns/nss/nss_gns_query.h | |||
@@ -11,7 +11,7 @@ | |||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Affero General Public License for more details. | 13 | Affero General Public License for more details. |
14 | 14 | ||
15 | You should have received a copy of the GNU Affero General Public License | 15 | You should have received a copy of the GNU Affero General Public License |
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | */ | 17 | */ |
@@ -26,25 +26,30 @@ | |||
26 | /* Maximum number of entries to return */ | 26 | /* Maximum number of entries to return */ |
27 | #define MAX_ENTRIES 16 | 27 | #define MAX_ENTRIES 16 |
28 | 28 | ||
29 | typedef struct { | 29 | typedef struct |
30 | uint32_t address; | 30 | { |
31 | uint32_t address; | ||
31 | } ipv4_address_t; | 32 | } ipv4_address_t; |
32 | 33 | ||
33 | typedef struct { | 34 | |
34 | uint8_t address[16]; | 35 | typedef struct |
36 | { | ||
37 | uint8_t address[16]; | ||
35 | } ipv6_address_t; | 38 | } ipv6_address_t; |
36 | 39 | ||
37 | 40 | ||
38 | struct userdata { | 41 | struct userdata |
42 | { | ||
39 | int count; | 43 | int count; |
40 | int data_len; /* only valid when doing reverse lookup */ | 44 | int data_len; /* only valid when doing reverse lookup */ |
41 | union { | 45 | union { |
42 | ipv4_address_t ipv4[MAX_ENTRIES]; | 46 | ipv4_address_t ipv4[MAX_ENTRIES]; |
43 | ipv6_address_t ipv6[MAX_ENTRIES]; | 47 | ipv6_address_t ipv6[MAX_ENTRIES]; |
44 | char *name[MAX_ENTRIES]; | 48 | char *name[MAX_ENTRIES]; |
45 | } data; | 49 | } data; |
46 | }; | 50 | }; |
47 | 51 | ||
52 | |||
48 | /** | 53 | /** |
49 | * Wrapper function that uses gnunet-gns cli tool to resolve | 54 | * Wrapper function that uses gnunet-gns cli tool to resolve |
50 | * an IPv4/6 address. | 55 | * an IPv4/6 address. |
@@ -54,8 +59,9 @@ struct userdata { | |||
54 | * @param u the userdata (result struct) | 59 | * @param u the userdata (result struct) |
55 | * @return -1 on error else 0 | 60 | * @return -1 on error else 0 |
56 | */ | 61 | */ |
57 | int gns_resolve_name(int af, | 62 | int |
58 | const char *name, | 63 | gns_resolve_name(int af, |
59 | struct userdata *userdata); | 64 | const char *name, |
65 | struct userdata *userdata); | ||
60 | 66 | ||
61 | #endif | 67 | #endif |