|
Lines 262-267
resolve_host(const char *name, int port, int logerr, char *cname, size_t clen)
Link Here
|
| 262 |
} |
262 |
} |
| 263 |
|
263 |
|
| 264 |
/* |
264 |
/* |
|
|
265 |
* Attempt to resolve a numeric host address / port to a single address. |
| 266 |
* Returns a canonical address string. |
| 267 |
* Returns NULL on failure. |
| 268 |
* NB. this function must operate with a options having undefined members. |
| 269 |
*/ |
| 270 |
static struct addrinfo * |
| 271 |
resolve_addr(const char *name, int port, char *caddr, size_t clen) |
| 272 |
{ |
| 273 |
char addr[NI_MAXHOST], strport[NI_MAXSERV]; |
| 274 |
struct addrinfo hints, *res; |
| 275 |
int gaierr; |
| 276 |
|
| 277 |
if (port <= 0) |
| 278 |
port = default_ssh_port(); |
| 279 |
snprintf(strport, sizeof strport, "%u", port); |
| 280 |
memset(&hints, 0, sizeof(hints)); |
| 281 |
hints.ai_family = options.address_family == -1 ? |
| 282 |
AF_UNSPEC : options.address_family; |
| 283 |
hints.ai_socktype = SOCK_STREAM; |
| 284 |
hints.ai_flags = AI_NUMERICHOST|AI_NUMERICSERV; |
| 285 |
if ((gaierr = getaddrinfo(name, strport, &hints, &res)) != 0) { |
| 286 |
debug2("%s: could not resolve name %.100s as address: %s", |
| 287 |
__func__, name, ssh_gai_strerror(gaierr)); |
| 288 |
return NULL; |
| 289 |
} |
| 290 |
if (res == NULL) { |
| 291 |
debug("%s: getaddrinfo %.100s returned no addresses", |
| 292 |
__func__, name); |
| 293 |
return NULL; |
| 294 |
} |
| 295 |
if (res->ai_next != NULL) { |
| 296 |
debug("%s: getaddrinfo %.100s returned multiple addresses", |
| 297 |
__func__, name); |
| 298 |
freeaddrinfo(res); |
| 299 |
return NULL; |
| 300 |
} |
| 301 |
if ((gaierr = getnameinfo(res->ai_addr, res->ai_addrlen, |
| 302 |
addr, sizeof(addr), NULL, 0, NI_NUMERICHOST)) != 0) { |
| 303 |
debug("%s: Could not format address for name %.100s: %s", |
| 304 |
__func__, name, ssh_gai_strerror(gaierr)); |
| 305 |
freeaddrinfo(res); |
| 306 |
return NULL; |
| 307 |
} |
| 308 |
if (strlcpy(caddr, addr, clen) >= clen) { |
| 309 |
error("%s: host \"%s\" addr \"%s\" too long (max %lu)", |
| 310 |
__func__, name, addr, (u_long)clen); |
| 311 |
if (clen > 0) |
| 312 |
*caddr = '\0'; |
| 313 |
freeaddrinfo(res); |
| 314 |
return NULL; |
| 315 |
} |
| 316 |
return res; |
| 317 |
} |
| 318 |
|
| 319 |
/* |
| 265 |
* Check whether the cname is a permitted replacement for the hostname |
320 |
* Check whether the cname is a permitted replacement for the hostname |
| 266 |
* and perform the replacement if it is. |
321 |
* and perform the replacement if it is. |
| 267 |
* NB. this function must operate with a options having undefined members. |
322 |
* NB. this function must operate with a options having undefined members. |
|
Lines 325-330
resolve_canonicalize(char **hostp, int port)
Link Here
|
| 325 |
options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS) |
380 |
options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS) |
| 326 |
return NULL; |
381 |
return NULL; |
| 327 |
|
382 |
|
|
|
383 |
/* Try numeric hostnames first */ |
| 384 |
if ((addrs = resolve_addr(*hostp, port, |
| 385 |
cname_target, sizeof(cname_target))) != NULL) { |
| 386 |
debug2("%s: hostname %.100s is address", __func__, *hostp); |
| 387 |
if (strcasecmp(*hostp, cname_target) != 0) { |
| 388 |
debug2("%s: canonicalised address \"%s\" => \"%s\"", |
| 389 |
__func__, *hostp, cname_target); |
| 390 |
free(*hostp); |
| 391 |
*hostp = xstrdup(cname_target); |
| 392 |
} |
| 393 |
return addrs; |
| 394 |
} |
| 395 |
|
| 328 |
/* Don't apply canonicalization to sufficiently-qualified hostnames */ |
396 |
/* Don't apply canonicalization to sufficiently-qualified hostnames */ |
| 329 |
ndots = 0; |
397 |
ndots = 0; |
| 330 |
for (cp = *hostp; *cp != '\0'; cp++) { |
398 |
for (cp = *hostp; *cp != '\0'; cp++) { |