Mercurial > dropbear
comparison netio.c @ 1464:ad637c9e0f6f
Server chosen tcpfwd ports (#43)
Server chosen tcpfwd ports
author | houseofkodai <karthik@houseofkodai.in> |
---|---|
date | Thu, 25 Jan 2018 19:51:41 +0530 |
parents | 06d52bcb8094 |
children | f7a53832501d |
comparison
equal
deleted
inserted
replaced
1463:a3479d0d7e79 | 1464:ad637c9e0f6f |
---|---|
346 strerror(errno)); | 346 strerror(errno)); |
347 #endif | 347 #endif |
348 | 348 |
349 } | 349 } |
350 | 350 |
351 /* from openssh/canohost.c avoid premature-optimization */ | |
352 int get_sock_port(int sock) { | |
353 struct sockaddr_storage from; | |
354 socklen_t fromlen; | |
355 char strport[NI_MAXSERV]; | |
356 int r; | |
357 | |
358 /* Get IP address of client. */ | |
359 fromlen = sizeof(from); | |
360 memset(&from, 0, sizeof(from)); | |
361 if (getsockname(sock, (struct sockaddr *)&from, &fromlen) < 0) { | |
362 TRACE(("getsockname failed: %d", errno)) | |
363 return 0; | |
364 } | |
365 | |
366 /* Work around Linux IPv6 weirdness */ | |
367 if (from.ss_family == AF_INET6) | |
368 fromlen = sizeof(struct sockaddr_in6); | |
369 | |
370 /* Non-inet sockets don't have a port number. */ | |
371 if (from.ss_family != AF_INET && from.ss_family != AF_INET6) | |
372 return 0; | |
373 | |
374 /* Return port number. */ | |
375 if ((r = getnameinfo((struct sockaddr *)&from, fromlen, NULL, 0, | |
376 strport, sizeof(strport), NI_NUMERICSERV)) != 0) { | |
377 TRACE(("netio.c/get_sock_port/getnameinfo NI_NUMERICSERV failed: %d", r)) | |
378 } | |
379 return atoi(strport); | |
380 } | |
381 | |
351 /* Listen on address:port. | 382 /* Listen on address:port. |
352 * Special cases are address of "" listening on everything, | 383 * Special cases are address of "" listening on everything, |
353 * and address of NULL listening on localhost only. | 384 * and address of NULL listening on localhost only. |
354 * Returns the number of sockets bound on success, or -1 on failure. On | 385 * Returns the number of sockets bound on success, or -1 on failure. On |
355 * failure, if errstring wasn't NULL, it'll be a newly malloced error | 386 * failure, if errstring wasn't NULL, it'll be a newly malloced error |
398 } | 429 } |
399 TRACE(("leave dropbear_listen: failed resolving")) | 430 TRACE(("leave dropbear_listen: failed resolving")) |
400 return -1; | 431 return -1; |
401 } | 432 } |
402 | 433 |
434 /* | |
435 * when listening on server-assigned-port 0 | |
436 * the assigned ports may differ for address families (v4/v6) | |
437 * causing problems for tcpip-forward | |
438 * caller can do a get_socket_address to discover assigned-port | |
439 * hence, use same port for all address families | |
440 */ | |
441 u_int16_t *allocated_lport_p = 0; | |
442 int allocated_lport = 0; | |
403 | 443 |
404 nsock = 0; | 444 nsock = 0; |
405 for (res = res0; res != NULL && nsock < sockcount; | 445 for (res = res0; res != NULL && nsock < sockcount; |
406 res = res->ai_next) { | 446 res = res->ai_next) { |
447 | |
448 if (allocated_lport > 0) { | |
449 if (AF_INET == res->ai_family) { | |
450 allocated_lport_p = &((struct sockaddr_in *)res->ai_addr)->sin_port; | |
451 } else if (AF_INET6 == res->ai_family) { | |
452 allocated_lport_p = &((struct sockaddr_in6 *)res->ai_addr)->sin6_port; | |
453 } | |
454 *allocated_lport_p = htons(allocated_lport); | |
455 } | |
407 | 456 |
408 /* Get a socket */ | 457 /* Get a socket */ |
409 socks[nsock] = socket(res->ai_family, res->ai_socktype, | 458 socks[nsock] = socket(res->ai_family, res->ai_socktype, |
410 res->ai_protocol); | 459 res->ai_protocol); |
411 | 460 |
447 if (listen(sock, DROPBEAR_LISTEN_BACKLOG) < 0) { | 496 if (listen(sock, DROPBEAR_LISTEN_BACKLOG) < 0) { |
448 err = errno; | 497 err = errno; |
449 close(sock); | 498 close(sock); |
450 TRACE(("listen() failed")) | 499 TRACE(("listen() failed")) |
451 continue; | 500 continue; |
501 } | |
502 | |
503 if (0 == allocated_lport) { | |
504 allocated_lport = get_sock_port(sock); | |
452 } | 505 } |
453 | 506 |
454 *maxfd = MAX(*maxfd, sock); | 507 *maxfd = MAX(*maxfd, sock); |
455 | 508 |
456 nsock++; | 509 nsock++; |