1/*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24#include <stdio.h>
25#include <fcntl.h>
26#include <ctype.h>
27#include <stdlib.h>
28#include <string.h>
29#include <netdb.h>
30#include <paths.h>
31#include <unistd.h>
32#include <arpa/inet.h>
33#include <ifaddrs.h>
34#include <net/if.h>
35#include <netinet/in.h>
36#include <sys/ioctl.h>
37#include <sys/socket.h>
38#include <sys/queue.h>
39#include <sys/wait.h>
40#include <sys/stat.h>
41#include <sys/param.h>
42#include <sys/kern_event.h>
43#include <arpa/inet.h>
44#include <sys/un.h>
45
46#include <net/if_var.h>
47
48#include <netinet/in_var.h>
49#include <mach/mach_time.h>
50
51#include <CoreFoundation/CoreFoundation.h>
52#include <SystemConfiguration/SystemConfiguration.h>
53
54#include "vpnoptions.h"
55#include "vpnplugins.h"
56#include "vpnd.h"
57
58#define VPN_ADDR_DELETE 0x1
59
60struct vpn_address {
61    TAILQ_ENTRY(vpn_address)	next;
62    int				pid;
63    int				flags;
64    char 			ip_address[16];
65};
66
67#define LB_MAX_SLAVE_AGE	10
68#define LB_IPCONFIG_TIMEOUT 60
69
70struct lb_slave {
71    TAILQ_ENTRY(lb_slave)	next;
72    struct sockaddr_in server_address;
73    int				age;
74	struct in_addr	redirect_address;
75    u_int16_t 		max_connection;
76	u_int16_t 		cur_connection;
77	u_int32_t 		ratio;
78};
79
80enum {
81	HEALTH_UNKNOWN = -1,
82	HEALTH_OK,
83	HEALTH_SICK,
84	HEALTH_DEAD
85};
86
87// ----------------------------------------------------------------------------
88//	Private Globals
89// ----------------------------------------------------------------------------
90static int			listen_sockfd = -1;
91static int			lb_sockfd = -1;
92static int			evt_sockfd = -1;
93static int			health_sockfd = -1;
94static int			health_state = HEALTH_UNKNOWN;
95static struct vpn_channel 	the_vpn_channel;
96
97static double	 		timeScaleSeconds;	/* scale factor for machine absolute time to seconds */
98static double	 		timeScaleMicroSeconds;	/* scale factor for machine absolute time to microseconds */
99
100/* load balancing state information */
101int					lb_is_started = 0;		// is load balancing currently started ?
102int					lb_is_master = 0;		// are we currently the master ?
103struct sockaddr_in	lb_master_address;	// address of a master, as discovered by the slave
104TAILQ_HEAD(, lb_slave) 	lb_slaves_list; // list opf slaves, as discoverd by the master server
105u_int16_t			lb_cur_connections = 0;		// nb of connections currently active
106u_int16_t			lb_max_connections = 0;		// max number of connections
107struct lb_slave		*lb_next_slave = 0; // next slave to redirect the call to
108int					lb_ipconfig_time = 0; // ip config confirmation timer
109
110
111
112TAILQ_HEAD(, vpn_address) 	save_address_list;
113TAILQ_HEAD(, vpn_address) 	free_address_list;
114TAILQ_HEAD(, vpn_address) 	child_list;
115
116// ----------------------------------------------------------------------------
117//	Function Prototypes
118// ----------------------------------------------------------------------------
119extern int got_sig_chld(void);
120extern int got_sig_hup(void);
121extern int got_sig_usr1(void);
122extern int got_terminate(void);
123
124static pid_t fork_child(int fdSocket);
125static int reap_children(void);
126static int terminate_children(void);
127static int getabsolutetime(struct timeval *timenow);
128static void determine_next_slave(struct vpn_params* params);
129int start_load_balancing(struct vpn_params *params, fd_set *out_fds, int *out_fdmax);
130int stop_load_balancing(struct vpn_params *params,  fd_set *out_fds);
131
132
133// ----------------------------------------------------------------------------
134//	init_address_lists
135// ----------------------------------------------------------------------------
136void init_address_lists(void)
137{
138    TAILQ_INIT(&free_address_list);
139    TAILQ_INIT(&save_address_list);
140    TAILQ_INIT(&child_list);
141	TAILQ_INIT(&lb_slaves_list);
142
143	lb_max_connections = 0;
144	lb_cur_connections = 0;
145}
146
147// ----------------------------------------------------------------------------
148//	add_address
149// ----------------------------------------------------------------------------
150int add_address(char* ip_address)
151{
152    struct vpn_address *address_slot;
153    int		size;
154
155    if ((size = strlen(ip_address) + 1) > 16)
156        return -1;
157
158    address_slot = (struct vpn_address*)malloc(sizeof(struct vpn_address));
159    if (address_slot == 0)
160        return -1;
161
162	lb_max_connections++;
163
164    /* %%%% this address stuff needs to be redone for IPv6 addresses */
165    memcpy(address_slot->ip_address, ip_address, strlen(ip_address) + 1);
166    address_slot->flags = 0;
167    TAILQ_INSERT_TAIL(&free_address_list, address_slot, next);
168
169    return 0;
170}
171
172// ----------------------------------------------------------------------------
173//	add_address_range
174// ----------------------------------------------------------------------------
175int add_address_range(char* ip_addr_start, char* ip_addr_end)
176{
177    struct in_addr	start_addr;
178    struct in_addr	end_addr;
179    struct in_addr	cur_addr;
180    char		addr_str[16];
181    char		*ip_addr;
182
183    if (!ip_addr_end)
184        return add_address(ip_addr_start);
185    if (inet_pton(AF_INET, ip_addr_start, &start_addr) < 1)
186        return -1;
187    if (inet_pton(AF_INET, ip_addr_end, &end_addr) < 1)
188        return -1;
189	start_addr.s_addr = ntohl(start_addr.s_addr);
190	end_addr.s_addr = ntohl(end_addr.s_addr);
191    if (start_addr.s_addr > end_addr.s_addr)
192        return -1;
193    if (start_addr.s_addr == end_addr.s_addr)
194        return add_address(ip_addr_start);
195
196    for (; start_addr.s_addr <= end_addr.s_addr; start_addr.s_addr++) {
197		cur_addr = start_addr;
198		cur_addr.s_addr = htonl(cur_addr.s_addr);
199        if ((ip_addr = (char*)inet_ntop(AF_INET, &cur_addr, addr_str, 16))) {
200            if (add_address(ip_addr))
201                return -1;
202        } else
203            return -1;
204    }
205
206    return 0;
207}
208
209// ----------------------------------------------------------------------------
210//	begin_address_update
211// ----------------------------------------------------------------------------
212void begin_address_update(void)
213{
214    struct vpn_address *address_slot;
215
216    // copy the free addresses to the save list
217	while ((address_slot = (struct vpn_address*)TAILQ_FIRST(&free_address_list))) {
218        TAILQ_REMOVE(&free_address_list, address_slot, next);
219        TAILQ_INSERT_TAIL(&save_address_list, address_slot, next);
220    }
221
222}
223
224// ----------------------------------------------------------------------------
225//	cancel_address_update
226// ----------------------------------------------------------------------------
227void cancel_address_update(void)
228{
229    struct vpn_address *address_slot;
230
231    // remove any new addresses
232	while ((address_slot = (struct vpn_address*)TAILQ_FIRST(&free_address_list))) {
233        TAILQ_REMOVE(&free_address_list, address_slot, next);
234        free(address_slot);
235		lb_max_connections--;
236    }
237
238    // copy the free addresses back from the save list
239	while ((address_slot = (struct vpn_address*)TAILQ_FIRST(&save_address_list))) {
240        TAILQ_REMOVE(&save_address_list, address_slot, next);
241        TAILQ_INSERT_TAIL(&free_address_list, address_slot, next);
242    }
243}
244
245// ----------------------------------------------------------------------------
246//	apply_address_update
247// ----------------------------------------------------------------------------
248void apply_address_update(void)
249{
250    struct vpn_address *address_slot;
251    struct vpn_address *child_address;
252
253    // remove the old free addresses
254	while ((address_slot = (struct vpn_address*)TAILQ_FIRST(&save_address_list))) {
255        TAILQ_REMOVE(&save_address_list, address_slot, next);
256        free(address_slot);
257		lb_max_connections--;
258    }
259
260    // search the child address list and match up with new addresses
261    // kill children using invalid addresses
262    TAILQ_FOREACH(child_address, &child_list, next) {
263        child_address->flags |= VPN_ADDR_DELETE;
264        TAILQ_FOREACH(address_slot, &free_address_list, next) {
265            if (!strcmp(child_address->ip_address, address_slot->ip_address)) {
266                TAILQ_REMOVE(&free_address_list, address_slot, next);	// address match - remove from free list
267                free(address_slot);
268				lb_max_connections--;
269                child_address->flags &= ~VPN_ADDR_DELETE;		// don't kill child
270                break;
271            }
272        }
273        if (child_address->flags & VPN_ADDR_DELETE)
274            while (kill(child_address->pid, SIGTERM) < 0)
275                if (errno != EINTR) {
276                    vpnlog(LOG_ERR, "VPND: error terminating child - err = %s\n", strerror(errno));
277                    break;
278                }
279    }
280
281	vpnlog(LOG_DEBUG, "address list updated\n");
282
283    reap_children();
284
285}
286
287
288// ----------------------------------------------------------------------------
289//	address_avail
290// ----------------------------------------------------------------------------
291int address_avail(void)
292{
293    return (TAILQ_FIRST(&free_address_list) != 0);
294}
295
296//-----------------------------------------------------------------------------
297//	init_plugin
298//-----------------------------------------------------------------------------
299int init_plugin(struct vpn_params *params)
300{
301    char		path[MAXPATHLEN], name[MAXPATHLEN], *p;
302    CFBundleRef		pluginbdl, bdl;
303    CFURLRef		pluginurl, url;
304    int 		(*start)(struct vpn_channel*, CFBundleRef, CFBundleRef, int debug, int log_verbose) = 0;
305    bool		isPPP;
306    int 		len, err = -1;
307
308	bzero(&the_vpn_channel, sizeof(struct vpn_channel));
309	if (params->plugin_path == 0) {
310		err = add_builtin_plugin(params, &the_vpn_channel);
311		if (err)
312			vpnlog(LOG_ERR, "Cannot initialize built-in channel\n");
313        return err;
314    }
315
316    len = strlen(params->plugin_path);
317    if (len > 4 && !strcmp(&params->plugin_path[len - 4], ".ppp"))
318        isPPP = 1;
319    else if (len > 4 && !strcmp(&params->plugin_path[len - 4], ".vpn"))
320        isPPP = 0;
321    else {
322        vpnlog(LOG_ERR, "Plugin ''%s' has an incorrect suffix (must end with '.ppp' or '.vpn')\n", params->plugin_path);
323        return -1;
324    }
325
326    if (params->plugin_path[0] == '/') {
327        strlcpy(path, params->plugin_path, sizeof(path));
328        for (p = &params->plugin_path[len - 1]; *p != '/'; p--);
329        strncpy(name, p + 1, strlen(p) - 5);
330        *(name + (strlen(p) - 5)) = 0;
331    }
332    else {
333        strlcpy(path, PLUGINS_DIR, sizeof(path));
334        strlcat(path, params->plugin_path, sizeof(path));
335        strlcpy(name, params->plugin_path, sizeof(name) - 4); // leave space for .vpn
336		*(name + len - 4) = 0;
337    }
338
339    vpnlog(LOG_NOTICE, "Loading plugin %s\n", path);
340
341    if ((url = CFURLCreateFromFileSystemRepresentation(NULL, (UInt8 *)path, strlen(path), TRUE))) {
342        if ((bdl =  CFBundleCreate(NULL, url))) {
343
344            if (isPPP) {
345                if ((pluginurl = CFBundleCopyBuiltInPlugInsURL(bdl))) {
346                    strlcat(path, "/", sizeof(path));
347                    CFURLGetFileSystemRepresentation(pluginurl, 0, (UInt8 *)(path+strlen(path)), MAXPATHLEN-strlen(path));
348                    CFRelease(pluginurl);
349                    strlcat(path, "/", sizeof(path));
350                    strlcat(path, name, sizeof(path));
351                    strlcat(path, ".vpn", sizeof(path));
352
353                    if ((pluginurl = CFURLCreateFromFileSystemRepresentation(NULL, (UInt8 *)path, strlen(path), TRUE))) {
354
355                        if ((pluginbdl =  CFBundleCreate(NULL, pluginurl))) {
356
357                            // load the executable from the vpn plugin
358                            if (CFBundleLoadExecutable(pluginbdl)
359                                && (start = CFBundleGetFunctionPointerForName(pluginbdl, CFSTR("start"))))
360                                err = (*start)(&the_vpn_channel, pluginbdl, bdl, params->debug, params->log_verbose);
361
362                            CFRelease(pluginbdl);
363                        }
364                        CFRelease(pluginurl);
365                   }
366                }
367            }
368            else {
369                // load the default executable
370                if (CFBundleLoadExecutable(bdl)
371                    && (start = CFBundleGetFunctionPointerForName(bdl, CFSTR("start"))))
372                    err = (*start)(&the_vpn_channel, bdl, NULL, params->debug, params->log_verbose);
373            }
374
375            CFRelease(bdl);
376        }
377        CFRelease(url);
378    }
379
380    if (err) {
381        vpnlog(LOG_ERR, "Unable to load plugin (error = %d)\n", err);
382        return -1;
383    }
384
385    if (the_vpn_channel.listen == 0 || the_vpn_channel.accept == 0
386            || the_vpn_channel.refuse == 0 || the_vpn_channel.close == 0) {
387        vpnlog(LOG_ERR, "Plugin channel not properly initialized\n");
388        return -1;
389    }
390
391    //vpnlog(LOG_INFO, "Plugin loaded\n");
392
393    return 0;
394}
395
396// ----------------------------------------------------------------------------
397//	get_plugin_args
398// ----------------------------------------------------------------------------
399int get_plugin_args(struct vpn_params* params, int reload)
400{
401
402    /* get any extra params from the plugin */
403    if (the_vpn_channel.get_pppd_args)
404        if (the_vpn_channel.get_pppd_args(params, reload))
405            return -1;
406
407	// Load Balancing is only supported for L2TP/IPSec protocol
408	if (params->lb_enable && !the_vpn_channel.lb_redirect) {
409        vpnlog(LOG_ERR, "Plugin does not support Load Balancing\n");
410		params->lb_enable = 0;
411	}
412
413    return 0;
414}
415
416// ----------------------------------------------------------------------------
417//	call the ipconfig command
418// ----------------------------------------------------------------------------
419int call_ipconfig(char *command, char *interface, struct in_addr *address, int timeout)
420{
421
422	int pid, exitcode = -1, status;
423	char str[32], str1[32];
424
425
426    if ((pid = fork()) < 0)
427        return 1;
428
429    if (pid == 0) {
430		int i;
431		for (i = getdtablesize() - 1; i >= 0; i--) close(i);
432		open("/dev/null", O_RDWR, 0);
433		dup(0);
434		dup(0);
435		inet_ntop(AF_INET, address, str, sizeof(str));
436		snprintf(str1, sizeof(str1), "%d", timeout);
437        execle("/usr/sbin/ipconfig", "ipconfig",  command, interface, "FAILOVER", str, "255.255.255.255", str1, (char *)0, (char *)0);
438        exit(1);
439    }
440
441    while (waitpid(pid, &status, 0) < 0) {
442        if (errno == EINTR)
443            continue;
444       return 1;
445    }
446
447	exitcode = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
448
449	if (exitcode)
450		vpnlog(LOG_ERR, "Unable to configure IP Failover Service (error %d)\n", exitcode);
451
452    return exitcode;
453}
454
455// ----------------------------------------------------------------------------
456//	configure/unconfigure failover
457// ----------------------------------------------------------------------------
458int configure_failover(char *interface, struct in_addr *address, int timeout)
459{
460	int err = -1;
461
462	err = call_ipconfig("setservice", interface, address, timeout);
463	if (err)
464		vpnlog(LOG_ERR, "Unable to configure IP Failover Service (error %d)\n", err);
465
466    return err;
467}
468
469// ----------------------------------------------------------------------------
470//	delete load balancing pool address
471// ----------------------------------------------------------------------------
472int unconfigure_failover(char *interface, struct in_addr *address)
473{
474	int err = -1;
475
476	err = call_ipconfig("removeservice", interface, address, 0);
477	if (err)
478		vpnlog(LOG_ERR, "Unable to unconfigure IP Failover Service (error %d)\n", err);
479
480    return err;
481}
482
483// ----------------------------------------------------------------------------
484//	health_check
485// ----------------------------------------------------------------------------
486int health_check(struct vpn_params *params, int event, fd_set *out_fds, int *out_fdmax)
487{
488	int fd = health_sockfd, err, ret = 0;
489
490	err = the_vpn_channel.health_check(&fd, event);
491
492	/* check if health socket has changed */
493	if (fd != health_sockfd) {
494		if (health_sockfd != -1)
495			FD_CLR(health_sockfd, out_fds);
496		health_sockfd = fd;
497		if (health_sockfd != -1) {
498			FD_SET(health_sockfd, out_fds);
499			if (*out_fdmax <= health_sockfd)
500				*out_fdmax = health_sockfd + 1;
501		}
502	}
503
504	switch (err) {
505		case 0:
506			if (health_state == HEALTH_SICK) {
507				vpnlog(LOG_ERR, "Health control check: server is back to normal...\n");
508				// feeling better...
509				if (params->lb_enable) {
510					if (start_load_balancing(params, out_fds, out_fdmax) < 0)
511						ret = -1;
512				}
513			}
514			health_state = HEALTH_OK;
515			break;
516
517		case -2:
518			if (health_state == HEALTH_OK) {
519				vpnlog(LOG_ERR, "Health control check: server is sick...\n");
520			}
521			health_state = HEALTH_SICK;
522
523			if (lb_is_started)
524				stop_load_balancing(params, out_fds);
525			break;
526
527		default:
528		case -1:
529			health_state = HEALTH_DEAD;
530			vpnlog(LOG_ERR, "Health control check: server is dead...\n");
531			ret = -1;
532			break;
533	}
534
535	return ret;
536}
537
538// ----------------------------------------------------------------------------
539//	start load balancing
540// ----------------------------------------------------------------------------
541int start_load_balancing(struct vpn_params *params, fd_set *out_fds, int *out_fdmax)
542{
543	struct sockaddr_in	listen_addr;
544	fd_set fds = *out_fds;
545	int fdmax = *out_fdmax;
546	struct kev_request	kev_req;
547
548	if (lb_is_started)
549		return 0;
550
551    	// Load Balancing is only supported for L2TP/IPSec protocol
552	if (params->lb_enable && !the_vpn_channel.lb_redirect) {
553        vpnlog(LOG_ERR, "Plugin does not support Load Balancing\n");
554		params->lb_enable = 0;
555	}
556
557
558	evt_sockfd = socket(PF_SYSTEM, SOCK_RAW, SYSPROTO_EVENT);
559	if (evt_sockfd < 0) {
560		vpnlog(LOG_ERR, "Unable to create event socket (errno = %d)\n", errno);
561		goto fail;
562	}
563
564	FD_SET(evt_sockfd, &fds);
565	if (fdmax <= evt_sockfd)
566		fdmax = evt_sockfd + 1;
567
568	kev_req.vendor_code = KEV_VENDOR_APPLE;
569	kev_req.kev_class = KEV_NETWORK_CLASS;
570	kev_req.kev_subclass = KEV_INET_SUBCLASS;
571	ioctl(evt_sockfd, SIOCSKEVFILT, &kev_req);
572
573	lb_sockfd = socket(PF_INET, SOCK_DGRAM, 0);
574	if (lb_sockfd < 0) {
575		vpnlog(LOG_ERR, "Unable to create load balancing socket (errno = %d)\n", errno);
576		goto fail;
577	}
578
579	FD_SET(lb_sockfd, &fds);
580	if (fdmax <= lb_sockfd)
581		fdmax = lb_sockfd + 1;
582
583	bzero(&listen_addr, sizeof(listen_addr));
584	listen_addr.sin_family = PF_INET;
585	listen_addr.sin_addr.s_addr = htonl(INADDR_ANY);
586	listen_addr.sin_port = params->lb_port;
587
588	if (bind(lb_sockfd, (struct sockaddr*)&listen_addr, sizeof(listen_addr)) < 0 ){
589		vpnlog(LOG_ERR, "Unable to bind load balancing socket (errno = %d)\n", errno);
590		goto fail;
591	}
592
593	// set master address
594	bzero(&lb_master_address, sizeof(lb_master_address));
595	lb_master_address.sin_family = AF_INET;
596	lb_master_address.sin_len = sizeof(lb_master_address);
597	lb_master_address.sin_addr = params->lb_cluster_address;
598	lb_master_address.sin_port = params->lb_port;
599
600	configure_failover(params->lb_interface, &params->lb_cluster_address, LB_IPCONFIG_TIMEOUT);
601	lb_ipconfig_time = LB_IPCONFIG_TIMEOUT - 10;
602
603	lb_is_master = find_address(&lb_master_address, params->lb_interface);
604
605	*out_fds = fds;
606	*out_fdmax = fdmax;
607	lb_is_started = 1;
608	lb_next_slave = 0;
609	vpnlog(LOG_NOTICE, "Load Balancing: Started\n");
610
611	return 0;
612
613fail:
614	if (evt_sockfd >= 0) {
615		close(evt_sockfd);
616		evt_sockfd = -1;
617	}
618	if (lb_sockfd >= 0) {
619		close(lb_sockfd);
620		lb_sockfd = -1;
621	}
622	return -1;
623}
624
625// ----------------------------------------------------------------------------
626//	stop load balancing
627// ----------------------------------------------------------------------------
628int stop_load_balancing(struct vpn_params *params,  fd_set *out_fds)
629{
630
631	if (!lb_is_started)
632		return 0;
633
634	if (evt_sockfd >= 0) {
635		FD_CLR(evt_sockfd, out_fds);
636		close(evt_sockfd);
637		evt_sockfd = -1;
638	}
639	if (lb_sockfd >= 0) {
640		FD_CLR(lb_sockfd, out_fds);
641		close(lb_sockfd);
642		lb_sockfd = -1;
643	}
644
645	unconfigure_failover(params->lb_interface, &params->lb_cluster_address);
646
647	lb_is_master = 0;
648	lb_is_started = 0;
649	lb_next_slave = 0;
650
651	vpnlog(LOG_NOTICE, "Load Balancing: Stopped\n");
652
653	return 0;
654}
655
656// ----------------------------------------------------------------------------
657//	determine which slave takes next call
658// ----------------------------------------------------------------------------
659static void determine_next_slave(struct vpn_params *params)
660{
661	struct lb_slave *slave, *oldslave;
662	u_int32_t			a;
663
664	oldslave = lb_next_slave;
665
666	// determine the server that will take the next call
667	lb_next_slave = TAILQ_FIRST(&lb_slaves_list);
668	TAILQ_FOREACH(slave, &lb_slaves_list, next)	{
669		if (slave->ratio < lb_next_slave->ratio)
670			lb_next_slave = slave;
671	}
672
673	// and inform racoon about the redirection
674	if (lb_next_slave && lb_next_slave != oldslave) {
675
676		a = ntohl(lb_next_slave->redirect_address.s_addr);
677		vpnlog(LOG_NOTICE, "Load Balancing: Next call will be redirected to slave with IP address %d.%d.%d.%d. Current slave load %d/%d.\n",
678			a >> 24 & 0xFF, a >> 16 & 0xFF, a >> 8 & 0xFF, a & 0xFF, lb_next_slave->cur_connection, lb_next_slave->max_connection);
679
680		if (the_vpn_channel.lb_redirect) {
681			the_vpn_channel.lb_redirect(&params->lb_cluster_address, &lb_next_slave->redirect_address);
682		}
683	}
684
685}
686
687#define LB_MSG_TYPE_UPDATE	1
688
689struct lb_message {
690
691// header
692	u_int16_t	type;
693	u_int16_t	len;
694	u_int8_t	version;
695	u_int8_t	reserved1;
696	u_int16_t	reserved2;
697
698// version 1
699	u_int32_t 		redirect_address;	 //ip v4
700	u_int16_t 		max_connection;     // 100
701	u_int16_t 		cur_connection;		// 50
702	u_int32_t 		reserved3;
703	u_int32_t 		reserved4;
704
705};
706
707// ----------------------------------------------------------------------------
708//	accept_connections
709// ----------------------------------------------------------------------------
710void accept_connections(struct vpn_params* params)
711{
712
713    pid_t				pid_child;
714    fd_set				fds, fds_save;
715    char				addr_str[32];
716    int					i, child_sockfd, fdmax, err, hastimeout;
717    struct vpn_address	*address_slot;
718	struct sockaddr_in	addr;
719	socklen_t			addrlen;
720	size_t				datalen;
721	char				data[1000];
722	struct timeval		timenow, timeout, timeend;
723	struct lb_message	*lbmsg;
724	u_int16_t			lbmsgtype;
725	struct lb_slave		*slave;
726	u_int32_t			a;
727
728    FD_ZERO(&fds_save);
729	fdmax = 0;
730
731	/*
732		open the new connection listening socket
733	*/
734    listen_sockfd = 0;
735	if (the_vpn_channel.listen)
736		listen_sockfd = the_vpn_channel.listen();		// initialize the plugin and get listen socket
737
738    if (listen_sockfd < 0) {
739        vpnlog(LOG_ERR, "Unable to initialize vpn plugin\n");
740        goto fail;
741    }
742
743    if (listen_sockfd) {
744		FD_SET(listen_sockfd, &fds_save);
745		if (fdmax <= listen_sockfd)
746			fdmax = listen_sockfd + 1;
747	}
748
749	/*
750		health monitoring
751	*/
752    health_sockfd = -1;
753
754	/*
755		start the load balancing
756	*/
757	if (params->lb_enable) {
758		if (start_load_balancing(params, &fds_save, &fdmax) < 0) {
759			goto fail;
760		}
761	}
762
763	hastimeout = lb_is_started || the_vpn_channel.health_check;
764
765	if (hastimeout) {
766		getabsolutetime(&timeend);
767		timeend.tv_sec += 1; // timeout immediatly
768	}
769
770    /*
771		loop - listening for connection requests and other events
772	*/
773    while (!got_terminate()) {
774
775		if (hastimeout) {
776			getabsolutetime(&timenow);
777			timeout.tv_sec = timeend.tv_sec > timenow.tv_sec ? timeend.tv_sec - timenow.tv_sec : 0;
778			timeout.tv_usec = timeend.tv_usec - timenow.tv_usec;
779			if (timeout.tv_usec < 0) {
780				timeout.tv_usec += 1000000;
781				timeout.tv_sec -= 1;
782			}
783			if (timeout.tv_sec < 0)
784				timeout.tv_sec = timeout.tv_usec = 0;
785
786		}
787
788		fds = fds_save;
789        i = select(fdmax, &fds, NULL, NULL, hastimeout ? &timeout : 0);
790
791		// --------------- file descriptor selected --------------
792        if (i > 0) {
793
794			/* event on new kernel event socket */
795            if (lb_is_started && FD_ISSET (evt_sockfd, &fds)) {
796				char                 	buf[256];
797				struct kern_event_msg	*ev_msg;
798				struct kev_in_data     	*inetdata;
799
800				if (recv(evt_sockfd, &buf, sizeof(buf), 0) != -1) {
801					ev_msg = (struct kern_event_msg *) &buf;
802					switch (ev_msg->event_code) {
803						case KEV_INET_NEW_ADDR:
804							inetdata = (struct kev_in_data *) &ev_msg->event_data[0];
805							if (inetdata->ia_addr.s_addr == params->lb_cluster_address.s_addr) {
806								// our master address has been assigned. we are now the master server
807								vpnlog(LOG_NOTICE, "Load Balancing: Cluster address assigned. Server is becoming master...\n");
808								lb_is_master = 1;
809							}
810							break;
811						case KEV_INET_ADDR_DELETED:
812							inetdata = (struct kev_in_data *) &ev_msg->event_data[0];
813							if (inetdata->ia_addr.s_addr == params->lb_cluster_address.s_addr) {
814								// our master address has been deleted. we are not master anymore
815								vpnlog(LOG_NOTICE, "Load Balancing: Cluster address deleted. Server is no longer master...\n");
816								lb_is_master = 0;
817								while ((slave = TAILQ_FIRST(&lb_slaves_list))) {
818									TAILQ_REMOVE(&lb_slaves_list, slave, next);
819									free(slave);
820								}
821							}
822							break;
823
824					}
825				}
826			}
827
828			/* event on load balancing socket */
829            if (lb_is_started && FD_ISSET (lb_sockfd, &fds)) {
830
831				addrlen = sizeof(addr);
832				datalen = recvfrom (lb_sockfd, data, sizeof(data) - 1, 0, (struct sockaddr*)&addr, &addrlen);
833				if (datalen > 0) {
834
835					data[datalen] = 0;
836					lbmsg = (struct lb_message *)data;
837					lbmsgtype = ntohs(lbmsg->type);
838
839					if (lb_is_master && lbmsgtype == LB_MSG_TYPE_UPDATE) {
840
841						// search for slave in the list
842						TAILQ_FOREACH(slave, &lb_slaves_list, next)	{
843							if (slave->server_address.sin_addr.s_addr == addr.sin_addr.s_addr)
844								break;
845						}
846						if (!slave) {
847							slave = malloc(sizeof(struct lb_slave));
848							if (slave == 0) {
849								vpnlog(LOG_ERR, "cannot allocate memory for slave server.\n");
850								break;
851							}
852
853							a = ntohl(addr.sin_addr.s_addr);
854							vpnlog(LOG_NOTICE, "Load Balancing: Slave server appeared with IP address %d.%d.%d.%d\n", a >> 24 & 0xFF, a >> 16 & 0xFF, a >> 8 & 0xFF, a & 0xFF);
855							bcopy(&addr, &slave->server_address, sizeof(addr));
856							TAILQ_INSERT_TAIL(&lb_slaves_list, slave, next);
857
858						}
859
860						slave->age = LB_MAX_SLAVE_AGE;
861						slave->redirect_address.s_addr = lbmsg->redirect_address;
862						slave->max_connection = ntohs(lbmsg->max_connection);
863						slave->cur_connection = ntohs(lbmsg->cur_connection);
864						slave->ratio = (lbmsg->cur_connection < lbmsg->max_connection) ? (lbmsg->cur_connection * 1000)/lbmsg->max_connection : 1000;
865						a = ntohl(lbmsg->redirect_address);
866//						vpnlog(LOG_DEBUG, "Load Balancing: Slave server update. Redirection address is %d.%d.%d.%d, current load is %d/%d\n",
867//							a >> 24 & 0xFF, a >> 16 & 0xFF, a >> 8 & 0xFF, a & 0xFF, slave->cur_connection, slave->max_connection);
868
869						determine_next_slave(params);
870					}
871				}
872			}
873
874			/* event on health control socket */
875            if (health_sockfd != -1 && FD_ISSET (health_sockfd, &fds)) {
876				err = health_check(params, 1, &fds_save, &fdmax);
877				if (err < 0)
878					goto fail;
879			}
880
881			/* event on new connection listening socket */
882            if (FD_ISSET (listen_sockfd, &fds)) {
883
884                address_slot = (struct vpn_address*)TAILQ_FIRST(&free_address_list);
885                if (address_slot == 0) {
886                    if ((child_sockfd = the_vpn_channel.refuse()) < 0) {
887                        vpnlog(LOG_ERR, "Error while refusing incoming call %s\n", strerror(errno));
888                        continue;
889                    }
890                } else {
891                    if ((child_sockfd = the_vpn_channel.accept()) < 0) {
892                        vpnlog(LOG_ERR, "Error accepting incoming call %s\n", strerror(errno));
893                        continue;
894                    }
895                }
896                if (child_sockfd == 0)
897                    continue;
898                // Turn this connection over to a child.
899                while ((pid_child = fork_child(child_sockfd)) < 0) {
900                    if (errno != EINTR) {
901                        vpnlog(LOG_ERR, "Error during fork = %s\n", strerror(errno));
902                        goto fail;
903                    } else if (got_terminate())
904                        goto fail;
905                }
906                if (pid_child && address_slot) {			// parent
907                    vpnlog(LOG_NOTICE, "Incoming call... Address given to client = %s\n", address_slot->ip_address);
908                    TAILQ_REMOVE(&free_address_list, address_slot, next);
909                    address_slot->pid = pid_child;
910                    TAILQ_INSERT_TAIL(&child_list, address_slot, next);
911					lb_cur_connections++;
912                } else if (address_slot) {
913                    // child
914                    snprintf(addr_str, sizeof(addr_str), ":%s", address_slot->ip_address);
915                    params->exec_args[params->next_arg_index] = addr_str;	// setup ip address in arg list
916                    params->exec_args[params->next_arg_index + 1] = 0;		// make sure arg list end with zero
917                    execve(PATH_PPPD, params->exec_args, NULL);			// launch it
918
919                    /* not reached except if there is an error */
920                    vpnlog(LOG_ERR, "execve failed during exec of /usr/sbin/pppd\nARGUMENTS\n");
921                    for (i = 1; i < MAXARG && i < params->next_arg_index; i++) {
922                        if (params->exec_args[i])
923                            vpnlog(LOG_DEBUG, "%d :  %s\n", i, params->exec_args[i]);
924                    }
925                    vpnlog(LOG_DEBUG, "\n");
926
927                    exit(1);
928                }
929            }
930        }
931
932		// --------------- timeout expired --------------
933		else if (i == 0) {
934
935			// check health
936			if (the_vpn_channel.health_check) {
937				err = health_check(params, 0, &fds_save, &fdmax);
938				if (err < 0)
939					goto fail;
940			}
941
942			if (lb_is_started) {
943				// update the master every second
944
945				lbmsg = (struct lb_message *)data;
946				bzero(lbmsg, sizeof(struct lb_message));
947				lbmsg->type = htons(LB_MSG_TYPE_UPDATE);
948				lbmsg->len = htons(sizeof(*lbmsg));
949
950				// fill in actual load balancing data
951				lbmsg->redirect_address = params->lb_redirect_address.s_addr;
952				lbmsg->max_connection = htons(lb_max_connections);
953				lbmsg->cur_connection = htons(lb_cur_connections);
954
955				a = ntohl(params->lb_redirect_address.s_addr);
956	//			vpnlog(LOG_DEBUG, "Load Balancing: Sending update to master server. Updating my master. Redirection address is %d.%d.%d.%d, current load is %d/%d\n",
957	//							a >> 24 & 0xFF, a >> 16 & 0xFF, a >> 8 & 0xFF, a & 0xFF, lb_cur_connections, lb_max_connections);
958
959				if (sendto(lb_sockfd, data, sizeof(*lbmsg), 0, (struct sockaddr*)&lb_master_address, sizeof(lb_master_address)) < 0) {
960					vpnlog(LOG_ERR, "Load balancing: failed to send update (%s)", strerror(errno));
961				}
962
963				// if we are a master, check on slave age
964				if (lb_is_master) {
965
966					TAILQ_FOREACH(slave, &lb_slaves_list, next)	{
967						if (--slave->age == 0) {
968							a = ntohl(slave->server_address.sin_addr.s_addr);
969							vpnlog(LOG_NOTICE, "Load Balancing: Slave server with IP address %d.%d.%d.%d disappeared\n", a >> 24 & 0xFF, a >> 16 & 0xFF, a >> 8 & 0xFF, a & 0xFF);
970							TAILQ_REMOVE(&lb_slaves_list, slave, next);
971							if (slave == lb_next_slave) {
972								lb_next_slave = 0;
973								determine_next_slave(params);
974							}
975							free(slave);
976						}
977					}
978				}
979
980				lb_ipconfig_time--;
981				if (lb_ipconfig_time <= 0) {
982					configure_failover(params->lb_interface, &params->lb_cluster_address, LB_IPCONFIG_TIMEOUT);
983					lb_ipconfig_time = LB_IPCONFIG_TIMEOUT - 10;
984				}
985			}
986
987			getabsolutetime(&timeend);
988			timeend.tv_sec += 1; // 1 second probes
989
990		}
991		// --------------- error or interrupt --------------
992		else {
993            if (errno != EINTR) {
994                vpnlog(LOG_ERR, "Unexpected result from select - err = %s\n", strerror(errno));
995
996                goto fail;
997            }
998        }
999
1000		if (got_sig_chld())
1001			reap_children();
1002		if (got_sig_usr1())
1003			toggle_debug();
1004		if (got_sig_hup()) {
1005
1006			if (lb_is_started)
1007				stop_load_balancing(params, &fds_save);
1008
1009			update_prefs();
1010
1011			// restart load balancing
1012			if (params->lb_enable) {
1013				if (start_load_balancing(params, &fds_save, &fdmax) < 0)
1014					goto fail;
1015			}
1016		}
1017    }
1018
1019fail:
1020	if (lb_is_started)
1021		stop_load_balancing(params, &fds_save);
1022    if (the_vpn_channel.close)
1023		the_vpn_channel.close();
1024    terminate_children();
1025}
1026
1027
1028
1029//-----------------------------------------------------------------------------
1030//	fork_child
1031//-----------------------------------------------------------------------------
1032static pid_t fork_child(int fdSocket)
1033{
1034    register pid_t	pidChild = 0 ;
1035    int 		i;
1036
1037    errno = 0 ;
1038
1039    switch (pidChild = fork ()) {
1040        case 0:		// in child
1041            break ;
1042        case -1:	// error
1043            syslog(LOG_ERR, "fork() failed: %m") ;
1044            /* FALLTHRU */
1045        default:	// parent
1046            close (fdSocket) ;
1047            return pidChild ;
1048    }
1049
1050    for (i = getdtablesize() - 1; i >= 0; i--)
1051        if (i != fdSocket)
1052            close(i);
1053    dup2 (fdSocket, STDIN_FILENO) ;
1054    open("/dev/null", O_RDWR, 0);
1055    open("/dev/null", O_RDWR, 0);
1056    close (fdSocket) ;
1057
1058    return pidChild ;
1059}
1060
1061
1062//-----------------------------------------------------------------------------
1063//	reap_children
1064//-----------------------------------------------------------------------------
1065static int reap_children(void)
1066{
1067
1068    int pid, status;
1069    struct vpn_address *address_slot;
1070
1071    if (!TAILQ_FIRST(&child_list))
1072        return 0;
1073
1074    /* loop on waitpid collecting children and freeing the addresses */
1075    while ((pid = waitpid(-1, &status, WNOHANG)) != -1 && pid != 0) {
1076        // find the child in the child list - remove it and free the address
1077        // back to the free address list
1078        TAILQ_FOREACH(address_slot, &child_list, next)	{
1079            if (address_slot->pid == pid) {
1080                vpnlog(LOG_NOTICE, "   --> Client with address = %s has hungup\n", address_slot->ip_address);
1081                TAILQ_REMOVE(&child_list, address_slot, next);
1082				lb_cur_connections--;
1083                if (address_slot->flags & VPN_ADDR_DELETE) { // address no longer valid?
1084                    free(address_slot);
1085					lb_max_connections--;
1086				}
1087                else {
1088                    TAILQ_INSERT_TAIL(&free_address_list, address_slot, next);
1089				}
1090                if (WIFSIGNALED(status))
1091                    vpnlog(LOG_WARNING, "Child process (pid %d) terminated with signal %d", pid, WTERMSIG(status));
1092                break;
1093            }
1094        }
1095    }
1096
1097    if (pid == -1)
1098		if (errno != EINTR) {
1099	    //syslog(LOG_ERR, "Error waiting for child process: %m");
1100            return -1;
1101        }
1102    return 0;
1103}
1104
1105//-----------------------------------------------------------------------------
1106//	terminate_children
1107//-----------------------------------------------------------------------------
1108static int terminate_children(void)
1109{
1110
1111    struct vpn_address *child;
1112
1113    /* loop on waitpid collecting children and freeing the addresses */
1114    while ((child = (struct vpn_address*)TAILQ_FIRST(&child_list))) {
1115        while (kill(child->pid, SIGTERM) < 0)
1116            if (errno != EINTR) {
1117                vpnlog(LOG_ERR, "Error terminating child - err = %s\n", strerror(errno));
1118                break;
1119            }
1120    	TAILQ_REMOVE(&child_list, child, next);
1121		lb_cur_connections--;
1122        TAILQ_INSERT_TAIL(&free_address_list, child, next);
1123    }
1124
1125    return 0;
1126}
1127
1128/* -----------------------------------------------------------------------------
1129get mach asbolute time, for timeout purpose independent of date changes
1130----------------------------------------------------------------------------- */
1131int getabsolutetime(struct timeval *timenow)
1132{
1133    double	now;
1134
1135    if (timeScaleSeconds == 0) {
1136		mach_timebase_info_data_t   timebaseInfo;
1137		if (mach_timebase_info(&timebaseInfo) == KERN_SUCCESS) {	// returns scale factor for ns
1138			timeScaleMicroSeconds = ((double) timebaseInfo.numer / (double) timebaseInfo.denom) / 1000;
1139			timeScaleSeconds = timeScaleMicroSeconds / 1000000;
1140		}
1141        else
1142			return -1;
1143    }
1144
1145    now = mach_absolute_time();
1146    timenow->tv_sec = now * timeScaleSeconds;
1147    timenow->tv_usec =  (now * timeScaleMicroSeconds) - ((double)timenow->tv_sec * 1000000);
1148    return 0;
1149}
1150
1151