Use getaddrinfo() to resolve source address.

This commit is contained in:
Sam Hocevar 2021-02-14 08:44:49 +01:00
parent c9de417f2e
commit b7fcf65a97
2 changed files with 25 additions and 16 deletions

View File

@ -212,6 +212,9 @@ static void clearConfiguration(void) {
free(srv->fromHost); free(srv->fromHost);
free(srv->toHost); free(srv->toHost);
freeaddrinfo(srv->fromAddrInfo); freeaddrinfo(srv->fromAddrInfo);
if (srv->sourceAddrInfo) {
freeaddrinfo(srv->sourceAddrInfo);
}
} }
/* Free memory associated with previous set. */ /* Free memory associated with previous set. */
free(seInfo); free(seInfo);
@ -265,13 +268,6 @@ void addServer(char *bindAddress, char *bindPort, int bindProtocol,
.serverTimeout = serverTimeout, .serverTimeout = serverTimeout,
}; };
si.sourceAddr.s_addr = INADDR_ANY;
if (sourceAddress && getAddress(sourceAddress, &si.sourceAddr) < 0) {
fprintf(stderr, "rinetd: host %s could not be resolved.\n",
sourceAddress);
exit(1);
}
/* Make a server socket */ /* Make a server socket */
struct addrinfo hints = struct addrinfo hints =
{ {
@ -324,6 +320,21 @@ void addServer(char *bindAddress, char *bindPort, int bindProtocol,
break; break;
} }
/* Resolve source address if applicable */
if (sourceAddress) {
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC,
hints.ai_protocol = connectProtocol,
hints.ai_socktype = getSocketType(connectProtocol),
ret = getaddrinfo(sourceAddress, NULL, &hints, &servinfo);
if (ret != 0) {
fprintf(stderr, "rinetd: getaddrinfo error: %s\n", gai_strerror(ret));
exit(1);
}
si.sourceAddrInfo = servinfo;
}
if (getAddress(connectAddress, &si.localAddr) < 0) { if (getAddress(connectAddress, &si.localAddr) < 0) {
/* Warn -- don't exit. */ /* Warn -- don't exit. */
syslog(LOG_ERR, "host %s could not be resolved.\n", syslog(LOG_ERR, "host %s could not be resolved.\n",
@ -745,15 +756,13 @@ static void handleAccept(ServerInfo const *srv)
if (srv->toProtocol == IPPROTO_TCP) if (srv->toProtocol == IPPROTO_TCP)
setSocketDefaults(cnx->local.fd); setSocketDefaults(cnx->local.fd);
/* Bind the local socket even if we use connect() later, so that /* Bind the local socket even though we use connect() later, so that
we can specify a source address. */ we can specify a source address. */
memset(&saddr, 0, sizeof(struct sockaddr_in)); if (srv->sourceAddrInfo) {
saddr.sin_family = AF_INET; if (bind(cnx->local.fd, srv->sourceAddrInfo->ai_addr,
memcpy(&saddr.sin_addr, &srv->sourceAddr, sizeof(struct in_addr)); srv->sourceAddrInfo->ai_addrlen) == SOCKET_ERROR) {
saddr.sin_port = 0; syslog(LOG_ERR, "bind(): %m\n");
if (bind(cnx->local.fd, (struct sockaddr *)&saddr, }
sizeof(saddr)) == SOCKET_ERROR) {
syslog(LOG_ERR, "bind(): %m\n");
} }
memset(&saddr, 0, sizeof(struct sockaddr_in)); memset(&saddr, 0, sizeof(struct sockaddr_in));

View File

@ -31,7 +31,7 @@ struct _server_info {
/* In network order, for network purposes */ /* In network order, for network purposes */
struct in_addr localAddr; struct in_addr localAddr;
uint16_t localPort; uint16_t localPort;
struct in_addr sourceAddr; struct addrinfo *sourceAddrInfo;
/* In ASCII and local byte order, for logging purposes */ /* In ASCII and local byte order, for logging purposes */
char *fromHost, *toHost; char *fromHost, *toHost;