Better C proxy host resolution.

Use getaddrinfo instead of gethostbyname.
This commit is contained in:
Joel Martin 2010-06-16 13:11:07 -05:00
parent f2898eabd3
commit b0696c4473
2 changed files with 32 additions and 21 deletions

View File

@ -12,8 +12,8 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <netdb.h>
#include <openssl/err.h> #include <openssl/err.h>
#include <openssl/ssl.h> #include <openssl/ssl.h>
#include <resolv.h> /* base64 encode/decode */ #include <resolv.h> /* base64 encode/decode */
@ -55,6 +55,30 @@ void fatal(char *msg)
exit(1); exit(1);
} }
/* resolve host with also IP address parsing */
int resolve_host(struct in_addr *sin_addr, const char *hostname)
{
if (!inet_aton(hostname, sin_addr)) {
struct addrinfo *ai, *cur;
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
if (getaddrinfo(hostname, NULL, &hints, &ai))
return -1;
for (cur = ai; cur; cur = cur->ai_next) {
if (cur->ai_family == AF_INET) {
*sin_addr = ((struct sockaddr_in *)cur->ai_addr)->sin_addr;
freeaddrinfo(ai);
return 0;
}
}
freeaddrinfo(ai);
return -1;
}
return 0;
}
/* /*
* SSL Wrapper Code * SSL Wrapper Code
*/ */
@ -331,7 +355,6 @@ void start_server(int listen_port,
char *listen_host) { char *listen_host) {
int lsock, csock, clilen, sopt = 1, i; int lsock, csock, clilen, sopt = 1, i;
struct sockaddr_in serv_addr, cli_addr; struct sockaddr_in serv_addr, cli_addr;
struct hostent *lhost;
ws_ctx_t *ws_ctx; ws_ctx_t *ws_ctx;
/* Initialize buffers */ /* Initialize buffers */
@ -355,15 +378,8 @@ void start_server(int listen_port,
if ((listen_host == NULL) || (listen_host[0] == '\0')) { if ((listen_host == NULL) || (listen_host[0] == '\0')) {
serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_addr.s_addr = INADDR_ANY;
} else { } else {
lhost = gethostbyname(listen_host); if (resolve_host(&serv_addr.sin_addr, listen_host) < -1) {
if (lhost == NULL) { fatal("Could not resolve listen address");
fatal("Could not resolve self address");
}
bcopy((char *) lhost->h_addr,
(char *) &serv_addr.sin_addr.s_addr,
lhost->h_length);
for (i=0; i < strlen(lhost->h_addr); i++) {
printf("%d: %d\n", i, lhost->h_addr[i]);
} }
} }

View File

@ -193,7 +193,6 @@ void do_proxy(ws_ctx_t *ws_ctx, int target) {
void proxy_handler(ws_ctx_t *ws_ctx) { void proxy_handler(ws_ctx_t *ws_ctx) {
int tsock = 0; int tsock = 0;
struct sockaddr_in taddr; struct sockaddr_in taddr;
struct hostent *thost;
printf("Connecting to: %s:%d\n", target_host, target_port); printf("Connecting to: %s:%d\n", target_host, target_port);
@ -202,19 +201,15 @@ void proxy_handler(ws_ctx_t *ws_ctx) {
error("Could not create target socket"); error("Could not create target socket");
return; return;
} }
thost = gethostbyname(target_host);
if (thost == NULL) {
error("Could not resolve server");
close(tsock);
return;
}
bzero((char *) &taddr, sizeof(taddr)); bzero((char *) &taddr, sizeof(taddr));
taddr.sin_family = AF_INET; taddr.sin_family = AF_INET;
bcopy((char *) thost->h_addr,
(char *) &taddr.sin_addr.s_addr,
thost->h_length);
taddr.sin_port = htons(target_port); taddr.sin_port = htons(target_port);
/* Resolve target address */
if (resolve_host(&taddr.sin_addr, target_host) < -1) {
fatal("Could not resolve target address");
}
if (connect(tsock, (struct sockaddr *) &taddr, sizeof(taddr)) < 0) { if (connect(tsock, (struct sockaddr *) &taddr, sizeof(taddr)) < 0) {
error("Could not connect to target"); error("Could not connect to target");
close(tsock); close(tsock);