Allow dynamic port specification.
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@3349 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
124
kdc/connect.c
124
kdc/connect.c
@@ -40,6 +40,84 @@
|
|||||||
|
|
||||||
RCSID("$Id$");
|
RCSID("$Id$");
|
||||||
|
|
||||||
|
struct port_desc{
|
||||||
|
int family;
|
||||||
|
int type;
|
||||||
|
int port;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct port_desc *ports;
|
||||||
|
static int num_ports;
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_port(const char *port_str, const char *protocol)
|
||||||
|
{
|
||||||
|
struct servent *sp;
|
||||||
|
int type;
|
||||||
|
int port;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
sp = getservbyname(port_str, protocol);
|
||||||
|
if(sp){
|
||||||
|
port = sp->s_port;
|
||||||
|
}else{
|
||||||
|
char *end;
|
||||||
|
port = htons(strtol(port_str, &end, 0));
|
||||||
|
if(end == port_str)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(strcmp(protocol, "udp") == 0)
|
||||||
|
type = SOCK_DGRAM;
|
||||||
|
else if(strcmp(protocol, "tcp") == 0)
|
||||||
|
type = SOCK_STREAM;
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
for(i = 0; i < num_ports; i++){
|
||||||
|
if(ports[i].type == type && ports[i].port == port)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ports = realloc(ports, (num_ports + 1) * sizeof(*ports));
|
||||||
|
ports[num_ports].family = AF_INET;
|
||||||
|
ports[num_ports].type = type;
|
||||||
|
ports[num_ports].port = port;
|
||||||
|
num_ports++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
parse_ports(char *str)
|
||||||
|
{
|
||||||
|
char *pos = NULL;
|
||||||
|
char *p;
|
||||||
|
p = strtok_r(str, " \t", &pos);
|
||||||
|
while(p){
|
||||||
|
if(strcmp(p, "+") == 0){
|
||||||
|
add_port("kerberos", "udp");
|
||||||
|
add_port("kerberos", "tcp");
|
||||||
|
add_port("kerberos-sec", "udp");
|
||||||
|
add_port("kerberos-sec", "tcp");
|
||||||
|
add_port("kerberos-iv", "udp");
|
||||||
|
add_port("kerberos-iv", "tcp");
|
||||||
|
if(enable_http)
|
||||||
|
add_port("http", "tcp");
|
||||||
|
#ifdef KASERVER
|
||||||
|
add_port("7004", "udp");
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
char *q = strchr(p, '/');
|
||||||
|
if(q){
|
||||||
|
*q = 0;
|
||||||
|
*q++;
|
||||||
|
add_port(p, q);
|
||||||
|
}else {
|
||||||
|
add_port(p, "udp");
|
||||||
|
add_port(p, "tcp");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p = strtok_r(NULL, " \t", &pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct descr {
|
struct descr {
|
||||||
int s;
|
int s;
|
||||||
int type;
|
int type;
|
||||||
@@ -50,22 +128,22 @@ struct descr {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
init_socket(struct descr *d, int type, int port)
|
init_socket(struct descr *d, int family, int type, int port)
|
||||||
{
|
{
|
||||||
struct sockaddr_in sin;
|
struct sockaddr_in sin;
|
||||||
memset(d, 0, sizeof(*d));
|
memset(d, 0, sizeof(*d));
|
||||||
d->s = socket(AF_INET, type, 0);
|
d->s = socket(family, type, 0);
|
||||||
if(d->s < 0){
|
if(d->s < 0){
|
||||||
krb5_warn(context, errno, "socket(AF_INET, %d, 0)", type);
|
krb5_warn(context, errno, "socket(%d, %d, 0)", family, type);
|
||||||
d->s = -1;
|
d->s = -1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
d->type = type;
|
d->type = type;
|
||||||
memset(&sin, 0, sizeof(sin));
|
memset(&sin, 0, sizeof(sin));
|
||||||
sin.sin_family = AF_INET;
|
sin.sin_family = AF_INET;
|
||||||
sin.sin_port = htons(port);
|
sin.sin_port = port;
|
||||||
if(bind(d->s, (struct sockaddr*)&sin, sizeof(sin)) < 0){
|
if(bind(d->s, (struct sockaddr*)&sin, sizeof(sin)) < 0){
|
||||||
krb5_warn(context, errno, "bind(%d)", port);
|
krb5_warn(context, errno, "bind(%d)", ntohs(port));
|
||||||
close(d->s);
|
close(d->s);
|
||||||
d->s = -1;
|
d->s = -1;
|
||||||
return;
|
return;
|
||||||
@@ -78,23 +156,23 @@ init_socket(struct descr *d, int type, int port)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
init_sockets(struct descr **d)
|
init_sockets(struct descr **desc)
|
||||||
{
|
{
|
||||||
int nsockets = 4;
|
int i;
|
||||||
|
struct descr *d = NULL;
|
||||||
#ifdef KASERVER
|
int num = 0;
|
||||||
nsockets++;
|
parse_ports(port_str);
|
||||||
#endif
|
for (i = 0; i < num_ports; i++){
|
||||||
|
d = realloc(d, (num + 1) * sizeof(*d));
|
||||||
*d = malloc(nsockets * sizeof(**d));
|
init_socket(&d[num], ports[i].family, ports[i].type, ports[i].port);
|
||||||
init_socket(*d + 0, SOCK_DGRAM, 88);
|
if(d[num].s != -1){
|
||||||
init_socket(*d + 1, SOCK_DGRAM, 750);
|
kdc_log(5, "listening to port %u/%s", ntohs(ports[i].port),
|
||||||
init_socket(*d + 2, SOCK_STREAM, 88);
|
(ports[i].type == SOCK_STREAM) ? "tcp" : "udp"); /* XXX */
|
||||||
init_socket(*d + 3, SOCK_STREAM, 750);
|
num++;
|
||||||
#ifdef KASERVER
|
}
|
||||||
init_socket(*d + 4, SOCK_DGRAM, 7004);
|
}
|
||||||
#endif
|
*desc = d;
|
||||||
return nsockets;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -282,8 +360,7 @@ handle_tcp(struct descr *d, int index, int min_free)
|
|||||||
n = 0;
|
n = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef HTTP
|
else if(enable_http && strncmp(d[index].buf, "GET ", 4) == 0 &&
|
||||||
else if(strncmp(d[index].buf, "GET ", 4) == 0 &&
|
|
||||||
strncmp(d[index].buf + d[index].len - 4, "\r\n\r\n", 4) == 0){
|
strncmp(d[index].buf + d[index].len - 4, "\r\n\r\n", 4) == 0){
|
||||||
char *s, *p, *t;
|
char *s, *p, *t;
|
||||||
void *data;
|
void *data;
|
||||||
@@ -330,7 +407,6 @@ handle_tcp(struct descr *d, int index, int min_free)
|
|||||||
n = 0;
|
n = 0;
|
||||||
free(data);
|
free(data);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
if(n == 0){
|
if(n == 0){
|
||||||
do_request(d[index].buf, d[index].len,
|
do_request(d[index].buf, d[index].len,
|
||||||
d[index].s, (struct sockaddr*)&from, from_len);
|
d[index].s, (struct sockaddr*)&from, from_len);
|
||||||
|
Reference in New Issue
Block a user