|
Lines 267-272
ssh_kill_proxy_command(void)
Link Here
|
| 267 |
kill(proxy_command_pid, SIGHUP); |
267 |
kill(proxy_command_pid, SIGHUP); |
| 268 |
} |
268 |
} |
| 269 |
|
269 |
|
|
|
270 |
static int |
| 271 |
set_v6_bindpref(int sock, const char *op) |
| 272 |
{ |
| 273 |
#if defined(IPV6_ADDR_PREFERENCES) && defined(IPV6_PREFER_SRC_PUBLIC) && \ |
| 274 |
defined(IPV6_PREFER_SRC_TMP) && defined(IPV6_PREFER_SRC_PUBTMP_DEFAULT) |
| 275 |
int val, add, del; |
| 276 |
socklen_t len = sizeof(val); |
| 277 |
|
| 278 |
if (strcasecmp(op, "public") == 0) { |
| 279 |
add = IPV6_PREFER_SRC_PUBLIC; |
| 280 |
del = IPV6_PREFER_SRC_TMP|IPV6_PREFER_SRC_PUBTMP_DEFAULT; |
| 281 |
} else if (strcasecmp(op, "temp") == 0) { |
| 282 |
add = IPV6_PREFER_SRC_TMP; |
| 283 |
del = IPV6_PREFER_SRC_PUBLIC|IPV6_PREFER_SRC_PUBTMP_DEFAULT; |
| 284 |
} else |
| 285 |
return 0; |
| 286 |
|
| 287 |
debug("%s: setting IPV6_ADDR_PREFERENCES to %s", __func__, op); |
| 288 |
|
| 289 |
if (getsockopt(sock, IPPROTO_IPV6, IPV6_ADDR_PREFERENCES, |
| 290 |
&val, &len) != 0) { |
| 291 |
debug("%s: getsockopt: %s", __func__, strerror(errno)); |
| 292 |
return -1; |
| 293 |
} |
| 294 |
val = (val & ~del) | add; |
| 295 |
if (setsockopt(sock, IPPROTO_IPV6, IPV6_ADDR_PREFERENCES, |
| 296 |
&val, len) != 0) { |
| 297 |
debug("%s: getsockopt: %s", __func__, strerror(errno)); |
| 298 |
return -1; |
| 299 |
} |
| 300 |
return 1; |
| 301 |
#else |
| 302 |
/* Silently eat public/temp operations on hosts that lack support */ |
| 303 |
if (strcasecmp(op, "public") == 0 || strcasecmp(op, "temp") == 0) |
| 304 |
return 1; |
| 305 |
return 0; |
| 306 |
#endif |
| 307 |
} |
| 308 |
|
| 270 |
/* |
309 |
/* |
| 271 |
* Creates a (possibly privileged) socket for use as the ssh connection. |
310 |
* Creates a (possibly privileged) socket for use as the ssh connection. |
| 272 |
*/ |
311 |
*/ |
|
Lines 275-280
ssh_create_socket(int privileged, struct addrinfo *ai)
Link Here
|
| 275 |
{ |
314 |
{ |
| 276 |
int sock, r, gaierr; |
315 |
int sock, r, gaierr; |
| 277 |
struct addrinfo hints, *res = NULL; |
316 |
struct addrinfo hints, *res = NULL; |
|
|
317 |
const char *bind_address = options.bind_address; |
| 278 |
|
318 |
|
| 279 |
sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); |
319 |
sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); |
| 280 |
if (sock < 0) { |
320 |
if (sock < 0) { |
|
Lines 283-301
ssh_create_socket(int privileged, struct addrinfo *ai)
Link Here
|
| 283 |
} |
323 |
} |
| 284 |
fcntl(sock, F_SETFD, FD_CLOEXEC); |
324 |
fcntl(sock, F_SETFD, FD_CLOEXEC); |
| 285 |
|
325 |
|
|
|
326 |
/* Support for IPV6_ADDR_PREFERENCES if present */ |
| 327 |
if (ai->ai_family == AF_INET6 && bind_address != NULL) { |
| 328 |
if (set_v6_bindpref(sock, bind_address) != 0) { |
| 329 |
/* Skip explicit bind(2) below */ |
| 330 |
bind_address = NULL; |
| 331 |
} |
| 332 |
} |
| 333 |
|
| 286 |
/* Bind the socket to an alternative local IP address */ |
334 |
/* Bind the socket to an alternative local IP address */ |
| 287 |
if (options.bind_address == NULL && !privileged) |
335 |
if (bind_address == NULL && !privileged) |
| 288 |
return sock; |
336 |
return sock; |
| 289 |
|
337 |
|
| 290 |
if (options.bind_address) { |
338 |
if (bind_address) { |
| 291 |
memset(&hints, 0, sizeof(hints)); |
339 |
memset(&hints, 0, sizeof(hints)); |
| 292 |
hints.ai_family = ai->ai_family; |
340 |
hints.ai_family = ai->ai_family; |
| 293 |
hints.ai_socktype = ai->ai_socktype; |
341 |
hints.ai_socktype = ai->ai_socktype; |
| 294 |
hints.ai_protocol = ai->ai_protocol; |
342 |
hints.ai_protocol = ai->ai_protocol; |
| 295 |
hints.ai_flags = AI_PASSIVE; |
343 |
hints.ai_flags = AI_PASSIVE; |
| 296 |
gaierr = getaddrinfo(options.bind_address, NULL, &hints, &res); |
344 |
gaierr = getaddrinfo(bind_address, NULL, &hints, &res); |
| 297 |
if (gaierr) { |
345 |
if (gaierr) { |
| 298 |
error("getaddrinfo: %s: %s", options.bind_address, |
346 |
error("getaddrinfo: %s: %s", bind_address, |
| 299 |
ssh_gai_strerror(gaierr)); |
347 |
ssh_gai_strerror(gaierr)); |
| 300 |
close(sock); |
348 |
close(sock); |
| 301 |
return -1; |
349 |
return -1; |
|
Lines 316-323
ssh_create_socket(int privileged, struct addrinfo *ai)
Link Here
|
| 316 |
} |
364 |
} |
| 317 |
} else { |
365 |
} else { |
| 318 |
if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) { |
366 |
if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) { |
| 319 |
error("bind: %s: %s", options.bind_address, |
367 |
error("bind: %s: %s", bind_address, strerror(errno)); |
| 320 |
strerror(errno)); |
|
|
| 321 |
fail: |
368 |
fail: |
| 322 |
close(sock); |
369 |
close(sock); |
| 323 |
freeaddrinfo(res); |
370 |
freeaddrinfo(res); |