Commit 1c5b4d8f authored by venaas's avatar venaas Committed by venaas

added tcp and udp listen directives

git-svn-id: https://svn.testnett.uninett.no/radsecproxy/trunk@60 e88ac4ed-0b26-0410-9574-a7f39faa03bf
parent 85acbc23
......@@ -61,6 +61,8 @@ static int server_udp_count = 0;
static int server_tls_count = 0;
static int server_count = 0;
static struct peer *tcp_server_listen;
static struct peer *udp_server_listen;
static struct replyq udp_server_replyq;
static int udp_server_sock = -1;
static pthread_mutex_t *ssl_locks;
......@@ -190,12 +192,13 @@ void printauth(char *s, unsigned char *t) {
printf("\n");
}
int resolvepeer(struct peer *peer) {
int resolvepeer(struct peer *peer, int ai_flags) {
struct addrinfo hints, *addrinfo;
memset(&hints, 0, sizeof(hints));
hints.ai_socktype = (peer->type == 'T' ? SOCK_STREAM : SOCK_DGRAM);
hints.ai_family = AF_UNSPEC;
hints.ai_flags = ai_flags;
if (getaddrinfo(peer->host, peer->port, &hints, &addrinfo)) {
err("resolvepeer: can't resolve %s port %s", peer->host, peer->port);
return 0;
......@@ -226,6 +229,25 @@ int connecttoserver(struct addrinfo *addrinfo) {
return s;
}
int bindtoaddr(struct addrinfo *addrinfo) {
int s, on = 1;
struct addrinfo *res;
for (res = addrinfo; res; res = res->ai_next) {
s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (s < 0) {
err("bindtoaddr: socket failed");
continue;
}
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
if (!bind(s, res->ai_addr, res->ai_addrlen))
return s;
err("bindtoaddr: bind failed");
close(s);
}
return -1;
}
/* returns the client with matching address, or NULL */
/* if client argument is not NULL, we only check that one client */
struct client *find_client(char type, struct sockaddr *addr, struct client *client) {
......@@ -1379,11 +1401,11 @@ void *udpserverrd(void *arg) {
struct client *fr;
pthread_t udpserverwrth;
if ((udp_server_sock = bindport(SOCK_DGRAM, options.udpserverport)) < 0) {
if ((udp_server_sock = bindtoaddr(udp_server_listen->addrinfo)) < 0) {
printf("udpserverrd: socket/bind failed\n");
exit(1);
}
printf("udpserverrd: listening on UDP port %s\n", options.udpserverport);
printf("udpserverrd: listening for UDP on host %s port %s\n", udp_server_listen->host, udp_server_listen->port);
if (pthread_create(&udpserverwrth, NULL, udpserverwr, NULL))
errx("pthread_create failed");
......@@ -1500,18 +1522,20 @@ int tlslistener() {
size_t fromlen = sizeof(from);
struct client *client;
if ((s = bindport(SOCK_STREAM, DEFAULT_TLS_PORT)) < 0) {
if ((s = bindtoaddr(tcp_server_listen->addrinfo)) < 0) {
printf("tlslistener: socket/bind failed\n");
exit(1);
}
listen(s, 0);
printf("listening for incoming TLS on port %s\n", DEFAULT_TLS_PORT);
printf("listening for incoming TCP on address %s port %s\n", tcp_server_listen->host, tcp_server_listen->port);
for (;;) {
snew = accept(s, (struct sockaddr *)&from, &fromlen);
if (snew < 0)
errx("accept failed");
if (snew < 0) {
err("accept failed");
continue;
}
printf("incoming TLS connection from %s\n", addr2string((struct sockaddr *)&from, fromlen));
client = find_client('T', (struct sockaddr *)&from, NULL);
......@@ -1730,8 +1754,8 @@ void getconfig(const char *serverfile, const char *clientfile) {
}
}
if ((serverfile && !resolvepeer(&server->peer)) ||
(clientfile && !resolvepeer(&client->peer))) {
if ((serverfile && !resolvepeer(&server->peer, 0)) ||
(clientfile && !resolvepeer(&client->peer, 0))) {
printf("failed to resolve host %s port %s, exiting\n", peer->host, peer->port);
exit(1);
}
......@@ -1773,6 +1797,33 @@ void getconfig(const char *serverfile, const char *clientfile) {
fclose(f);
}
struct peer *server_create(char type) {
struct peer *server;
char *conf;
server = malloc(sizeof(struct peer));
if (!server)
errx("malloc failed");
memset(server, 0, sizeof(struct peer));
server->type = type;
conf = (type == 'T' ? options.listentcp : options.listenudp);
if (conf) {
parsehostport(conf, server);
if (!strcmp(server->host, "*")) {
free(server->host);
server->host = NULL;
}
} else if (type == 'T')
server->port = stringcopy(DEFAULT_TLS_PORT, 0);
else
server->port = stringcopy(options.udpserverport ? options.udpserverport : DEFAULT_UDP_PORT, 0);
if (!resolvepeer(server, AI_PASSIVE)) {
printf("failed to resolve host %s port %s, exiting\n", server->host, server->port);
exit(1);
}
return server;
}
void getmainconfig(const char *configfile) {
FILE *f;
char line[1024];
......@@ -1826,14 +1877,18 @@ void getmainconfig(const char *configfile) {
options.udpserverport = stringcopy(val, 0);
continue;
}
if (!strcasecmp(opt, "ListenUDP")) {
options.listenudp = stringcopy(val, 0);
continue;
}
if (!strcasecmp(opt, "ListenTCP")) {
options.listentcp = stringcopy(val, 0);
continue;
}
printf("error in %s, unknown option %s\n", configfile, opt);
exit(1);
}
fclose(f);
if (!options.udpserverport)
options.udpserverport = stringcopy(DEFAULT_UDP_PORT, 0);
}
#if 0
......@@ -1871,9 +1926,11 @@ int main(int argc, char **argv) {
/* pthread_attr_init(&joinable); */
/* pthread_attr_setdetachstate(&joinable, PTHREAD_CREATE_JOINABLE); */
if (client_udp_count)
if (client_udp_count) {
udp_server_listen = server_create('U');
if (pthread_create(&udpserverth, NULL /*&joinable*/, udpserverrd, NULL))
errx("pthread_create failed");
}
if (client_tls_count || server_tls_count)
ssl_ctx = ssl_init();
......@@ -1882,8 +1939,10 @@ int main(int argc, char **argv) {
if (pthread_create(&servers[i].clientth, NULL, clientwr, (void *)&servers[i]))
errx("pthread_create failed");
if (client_tls_count)
if (client_tls_count) {
tcp_server_listen = server_create('T');
return tlslistener();
}
/* just hang around doing nothing, anything to do here? */
for (;;)
......
......@@ -12,5 +12,9 @@ TLSCertificateKeyFile /etc/hostcertkey/host.example.com.key.pem
# Optionally specify password if key is encrypted (not very secure)
TLSCertificateKeyPassword follow the white rabbit
# You can optionally specify a non-standard UDP port to listen
#UDPServerPort 1814
# You can optionally specify addresses and ports to listen on
# Max one of each, below are just multiple examples
#ListenUDP *:1814
#listenUDP localhost
#listenTCP 10.10.10.10:2084
#ListenTCP [2001:700:1:7:215:f2ff:fe35:307d]:2084
......@@ -54,6 +54,8 @@ struct options {
char *tlscertificatekeyfile;
char *tlscertificatekeypassword;
char *udpserverport;
char *listenudp;
char *listentcp;
};
/* requests that our client will send */
......
......@@ -83,33 +83,6 @@ char *addr2string(struct sockaddr *addr, socklen_t len) {
return addr_buf[i];
}
int bindport(int type, char *port) {
struct addrinfo hints, *res0, *res;
int s, one = 1;
memset(&hints, 0, sizeof(hints));
hints.ai_socktype = type;
hints.ai_family = AF_UNSPEC;
hints.ai_flags = AI_PASSIVE;
if (getaddrinfo(NULL, port, &hints, &res0) != 0) {
err("bindport: can't resolve port %s", port);
return -1;
}
for (res = res0; res; res = res->ai_next) {
s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (s >= 0) {
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
if (bind(s, res->ai_addr, res->ai_addrlen) == 0)
break;
close(s);
s = -1;
}
}
freeaddrinfo(res0);
return s;
}
int connectport(int type, char *host, char *port) {
struct addrinfo hints, *res0, *res;
int s;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment