diff --git a/l2tpns.c b/l2tpns.c index a80589d..4787d87 100644 --- a/l2tpns.c +++ b/l2tpns.c @@ -253,6 +253,8 @@ struct Tstats *_statistics = NULL; struct Tringbuffer *ringbuffer = NULL; #endif +static int initlacudp(int *pudpfd, in_addr_t ip_dest, uint16_t port_dest); +static int initudp(int * pudpfd, in_addr_t ip_bind, in_addr_t ip_dest, uint16_t port_dest); static int setupif(int ifidx, uint32_t mru, int config_addr); static ssize_t rtnetlink_send(struct nlmsghdr *nh); static ssize_t genetlink_send(struct nlmsghdr *nh); @@ -1655,7 +1657,7 @@ static int setupif(int ifidx, uint32_t mru, int config_addr) } // set up LAC UDP ports -static void initlacudp(void) +static int initlacudp(int *pudpfd, in_addr_t ip_dest, uint16_t port_dest) { int on = 1; struct sockaddr_in addr; @@ -1665,17 +1667,30 @@ static void initlacudp(void) addr.sin_family = AF_INET; addr.sin_port = htons(config->bind_portremotelns); addr.sin_addr.s_addr = config->bind_address_remotelns; - udplacfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - setsockopt(udplacfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); + *pudpfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + setsockopt(*pudpfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); { - int flags = fcntl(udplacfd, F_GETFL, 0); - fcntl(udplacfd, F_SETFL, flags | O_NONBLOCK); + int flags = fcntl(*pudpfd, F_GETFL, 0); + fcntl(*pudpfd, F_SETFL, flags | O_NONBLOCK); } - if (bind(udplacfd, (struct sockaddr *) &addr, sizeof(addr)) < 0) + if (bind(*pudpfd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { LOG(0, 0, 0, "Error in UDP REMOTE LNS bind: %s\n", strerror(errno)); - exit(1); + close(*pudpfd); + return -1; } + if (ip_dest) + { + addr.sin_port = port_dest; + addr.sin_addr.s_addr = ip_dest; + if (connect(*pudpfd, (struct sockaddr *) &addr, sizeof(addr)) < 0) + { + LOG(2, 0, 0, "Error in UDP REMOTE LNS connect: %s\n", strerror(errno)); + close(*pudpfd); + return -1; + } + } + return 0; } // set up control ports @@ -1719,7 +1734,7 @@ static void initdae(void) } // set up UDP ports -static void initudp(int * pudpfd, in_addr_t ip_bind) +static int initudp(int * pudpfd, in_addr_t ip_bind, in_addr_t ip_dest, uint16_t port_dest) { int on = 1; struct sockaddr_in addr; @@ -1738,8 +1753,21 @@ static void initudp(int * pudpfd, in_addr_t ip_bind) if (bind((*pudpfd), (struct sockaddr *) &addr, sizeof(addr)) < 0) { LOG(0, 0, 0, "Error in UDP bind: %s\n", strerror(errno)); - exit(1); + close(*pudpfd); + return -1; } + if (ip_dest) + { + addr.sin_port = port_dest; + addr.sin_addr.s_addr = ip_dest; + if (connect((*pudpfd), (struct sockaddr *) &addr, sizeof(addr)) < 0) + { + LOG(2, 0, 0, "Error in UDP connect: %s\n", strerror(errno)); + close(*pudpfd); + return -1; + } + } + return 0; } // @@ -6061,8 +6089,12 @@ int main(int argc, char *argv[]) } config->nbudpfd = config->nbmultiaddress; for (i = 0; i < config->nbudpfd; i++) - initudp(&udpfd[i], config->bind_n_address[i]); - initlacudp(); + { + if (initudp(&udpfd[i], config->bind_n_address[i], 0, 0) < 0) + exit(1); + } + if (initlacudp(&udplacfd, 0, 0) < 0) + exit(1); config->indexlacudpfd = config->nbudpfd; udpfd[config->indexlacudpfd] = udplacfd; config->nbudpfd++;