Project

General

Profile

Download (7.9 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/* $Id$ */
3
/*
4
	vslb.inc
5
    Copyright (C) 2005 Bill Marquette
6
	All rights reserved.
7

    
8
	Redistribution and use in source and binary forms, with or without
9
	modification, are permitted provided that the following conditions are met:
10

    
11
	1. Redistributions of source code must retain the above copyright notice,
12
	   this list of conditions and the following disclaimer.
13

    
14
	2. Redistributions in binary form must reproduce the above copyright
15
	   notice, this list of conditions and the following disclaimer in the
16
	   documentation and/or other materials provided with the distribution.
17

    
18
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
19
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
22
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
	POSSIBILITY OF SUCH DAMAGE.
28

    
29
*/
30

    
31
/* include all configuration functions */
32
require_once("functions.inc");
33
require_once("pkg-utils.inc");
34
require_once("notices.inc");
35

    
36
function slbd_configure() {
37
	global $config, $g;
38
	
39
	$a_vs = &$config['load_balancer']['virtual_server'];
40
	$a_pool = &$config['load_balancer']['lbpool'];
41

    
42
	$should_start=0;
43

    
44
	$fd = fopen("{$g['varetc_path']}/slbd.conf", "w");
45

    
46
	/* Virtual server pools */
47
	if(is_array($a_vs)) {
48
		foreach ($a_vs as $vsent) {
49
			if ($vsent['desc'] == "")
50
				$slbdconf .= "{$vsent['name']}:\\\n";
51
			else
52
				$slbdconf .= "{$vsent['name']}|{$vsent['desc']}:\\\n";
53
	
54
			/* pool name */
55
			$slbdconf .= "\t:poolname={$vsent['name']}:\\\n";
56
			/* remove pool status files so we don't end up with a mismatch */
57
			if(file_exists("{$g['tmp_path']}/{$vsent['name']}.pool"))
58
				unlink("{$g['tmp_path']}/{$vsent['name']}.pool");
59
			/* virtual IP */
60
			$slbdconf .= "\t:vip={$vsent['ipaddr']}:\\\n";
61
			/* virtual port */
62
			$slbdconf .= "\t:vip-port={$vsent['port']}:\\\n";
63
			if($vsent['port'] <> "" and $vsent['sitedown'] <> "") {
64
				/* fallback IP */
65
				$slbdconf .= "\t:sitedown={$vsent['sitedown']}:\\\n";
66
				/* fallback port */
67
				$slbdconf .= "\t:sitedown-port={$vsent['port']}:\\\n";
68
			}
69
			for ($i = 0; isset($config['load_balancer']['lbpool'][$i]); $i++) {
70
				if ($config['load_balancer']['lbpool'][$i]['name'] == $vsent['pool']) {
71
					$svrcnt = 0;
72
					$svrtxt = "";
73
					$svrtxt = "\t:service-port={$config['load_balancer']['lbpool'][$i]['port']}:\\\n";
74
					if($config['load_balancer']['lbpool'])
75
						if(is_array($config['load_balancer']['lbpool'][$i]['servers']))
76
							foreach ($config['load_balancer']['lbpool'][$i]['servers'] as $lbsvr) {
77
								$svrtxt .= "\t:{$svrcnt}={$lbsvr}:\\\n";
78
								$svrcnt++;
79
							}
80
					$slbdconf .= "\t:method=round-robin:\\\n";
81
					$slbdconf .= "\t:services={$svrcnt}:\\\n";
82
					$slbdconf .= $svrtxt;
83
					if($config['load_balancer']['lbpool'][$i]['monitor'] == "ICMP") {
84
						$slbdconf .= "\t:ping:\n";
85
					} else {
86
						$slbdconf .= "\t:tcppoll:send=:expect=:\n";
87
					}
88
				}
89
			}
90
			
91
			$should_start=1;
92
		}
93
	}
94

    
95
	/* Gateway Pools */
96
	$a_settings['latencylow'] = "200";
97
	$a_settings['latencyhigh'] = "500";
98
	$a_settings['losslow'] = "10";
99
	$a_settings['losshigh'] = "20";
100

    
101
	/* kill apinger process */
102
	if(is_process_running("apinger"))
103
		mwexec("/usr/bin/killall apinger", true);
104

    
105
	$fda = fopen("{$g['varetc_path']}/apinger.conf", "w");
106
	$apingerconfig = <<<EOD
107
# pfSense apinger configuration file. Automatically Generated!
108
user "nobody"
109
group "nobody"
110
pid_file "{$g['varrun_path']}/apinger.pid"
111
status {
112
	file "/tmp/apinger.status"
113
	interval 10s
114
}
115
alarm default { 
116
	command on "/usr/bin/touch /tmp/filter_dirty"
117
	command off "/usr/bin/touch /tmp/filter_dirty"
118
	combine 10s
119
}
120
alarm down "down" {
121
	time 10s
122
}
123
alarm delay "delay" {
124
	delay_low {$a_settings['latencylow']}ms
125
	delay_high {$a_settings['latencyhigh']}ms
126
}
127
alarm loss "loss" {
128
	percent_low {$a_settings['losslow']}
129
	percent_high {$a_settings['losshigh']}
130
}
131
target default {
132
	interval 1s
133
	avg_delay_samples 10
134
	avg_loss_samples 50
135
	avg_loss_delay_samples 20
136
	alarms "down","delay","loss"
137
}
138

    
139
EOD;
140

    
141
	/* loop all pools to create configuration */
142
	if(is_array($a_pool)) {
143
		/* create a list of unique IP addresses */
144
		$a_addresses = array();
145
		foreach ($a_pool as $vspool) {
146
			if ($vspool['type'] != "gateway")
147
				continue;
148

    
149
			if(is_array($vspool['servers'])) {
150
				foreach ($vspool['servers'] as $lbsvr) {
151
					$lbsvr_split=split("\|", $lbsvr);
152
					$a_addresses[] = "$lbsvr_split[1]";
153
				}
154
			}
155
		}
156
		$a_addresses = array_unique($a_addresses);
157

    
158
		/* add static routes for each gateway with their monitor IP */
159
		if(!empty($a_addresses)) {
160
			foreach($a_addresses as $address) {
161
				$apingerconfig .= "target \"{$address}\" {\n";
162
				$apingerconfig .= "	description \"{$address}\"\n";
163
				$apingerconfig .= "}\n";
164
				$apingerconfig .= "\n";
165
			}
166
			fwrite($fda, $apingerconfig);
167
			fclose($fda);
168
		}
169

    
170
		foreach ($a_pool as $vspool) {
171
			if ($vspool['type'] != "gateway") {
172
				continue;
173
			}
174

    
175
			if(is_array($vspool['servers'])) {
176
				foreach ($vspool['servers'] as $lbsvr) {
177
					$lbsvr_split=split("\|", $lbsvr);
178

    
179
					/* Add static routes to the monitor IPs */
180
					$int = convert_friendly_interface_to_real_interface_name($lbsvr_split[0]);
181
					$gateway = get_interface_gateway($int);
182
					$int_ip = find_interface_ip($int);
183
					if($int_ip == "0.0.0.0") {
184
						/*   DHCP Corner case.  If DHCP is down, we delete the route then
185
						 *   there is a chance the monitor ip gateway will go out the link
186
						 *   that is up.
187
						 */
188
						mwexec("/sbin/route delete -host {$lbsvr_split[1]} 2>&1", true);
189
						mwexec("/sbin/route add -host {$lbsvr_split[1]} 127.0.0.1 2>&1", true);
190
					} else {
191
						mwexec("/sbin/route delete -host {$lbsvr_split[1]} 2>&1", true);
192
						mwexec("/sbin/route add -host {$lbsvr_split[1]} {$gateway} 2>&1", true);
193
					}
194
				}
195
			}
196
		}
197
	}
198

    
199
        if($should_start == 1) {
200
                fwrite($fd, $slbdconf);
201
                fclose($fd);
202
                mwexec("/usr/bin/killall -9 slbd", true);
203
                sleep(2);
204
                /* startup slbd pointing it's config at /var/etc/slbd.conf with a polling interval of 5 seconds */
205
                mwexec("/usr/local/sbin/slbd -c{$g['varetc_path']}/slbd.conf -r5000");
206
        } else {
207
                mwexec("/usr/bin/killall -9 slbd", true);
208
                fclose($fd);
209
        }
210

    
211
	if(!is_process_running("apinger") && (!empty($a_addresses))) {
212
		if (is_dir("{$g['tmp_path']}"))
213
			chmod("{$g['tmp_path']}", 01777);
214
		if (is_dir("{$g['vardb_path']}/rrd"))
215
			chown("{$g['vardb_path']}/rrd", "nobody");
216
		/* start a new apinger process */
217
		mwexec_bg("/usr/local/sbin/apinger -c {$g['varetc_path']}/apinger.conf");
218
	}
219
	
220
}
221

    
222
/* return the status of the apinger targets as a array */
223
function return_apinger_status() {
224
	global $config;
225
	global $g;
226

    
227
	$apingerstatus = array();
228
	if(is_readable("{$g['tmp_path']}/apinger.status"))
229
		$apingerstatus = file("{$g['tmp_path']}/apinger.status");
230

    
231
	$status = array();
232
	foreach($apingerstatus as $line) {
233
		$fields = explode(":", $line);
234
		switch($fields[0]) {
235
			case "Target":
236
				$target = trim($fields[1]);
237
				$status[$target] = array();
238
				$status[$target]['monitor'] = $target;
239
				break;
240
			case "Description":
241
	 			$status[$target]['name'] = trim($fields[1]);
242
				break;
243
			case "Last reply received":
244
				$status[$target]['lastcheck'] = trim($fields[1]) .":". trim($fields[2]) .":". 
245
trim($fields[3]);
246
				break;
247
			case "Average delay":
248
				$status[$target]['delay'] = trim($fields[1]);
249
				break;
250
			case "Average packet loss":
251
				$status[$target]['loss'] = trim($fields[1]);
252
				break;
253
			case "Active alarms":
254
				$status[$target]['status'] = trim($fields[1]);
255
				break;
256
		}
257
	}
258
	return($status);
259
}
260

    
261
?>
(23-23/27)