Project

General

Profile

Download (8.08 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
	if (is_array($config['gateways']['settings'])) {
97
		$a_settings = &$config['gateways']['settings'];
98
	} else {
99
		$a_settings['latencylow'] = "200";
100
		$a_settings['latencyhigh'] = "500";
101
		$a_settings['losslow'] = "10";
102
		$a_settings['losshigh'] = "20";
103
	}
104

    
105
	/* kill apinger process */
106
	if(is_process_running("apinger"))
107
		mwexec("/usr/bin/killall apinger", true);
108

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

    
143
EOD;
144

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

    
153
			if(is_array($vspool['servers'])) {
154
				foreach ($vspool['servers'] as $lbsvr) {
155
					$lbsvr_split=split("\|", $lbsvr);
156
					$a_addresses[] = "$lbsvr_split[1]";
157
				}
158
			}
159
		}
160
		$a_addresses = array_unique($a_addresses);
161

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

    
174
		foreach ($a_pool as $vspool) {
175
			if ($vspool['type'] != "gateway") {
176
				continue;
177
			}
178

    
179
			if(is_array($vspool['servers'])) {
180
				foreach ($vspool['servers'] as $lbsvr) {
181
					$lbsvr_split=split("\|", $lbsvr);
182

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

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

    
217
	if(!is_process_running("apinger") && (!empty($a_addresses))) {
218
		if (is_dir("{$g['tmp_path']}"))
219
			chmod("{$g['tmp_path']}", 01777);
220
		if (is_dir("{$g['vardb_path']}/rrd"))
221
			chown("{$g['vardb_path']}/rrd", "nobody");
222
		/* start a new apinger process */
223
		mwexec_bg("/usr/local/sbin/apinger -c {$g['varetc_path']}/apinger.conf");
224
	}
225
	
226
}
227

    
228
/* return the status of the apinger targets as a array */
229
function return_apinger_status() {
230
	global $config;
231
	global $g;
232

    
233
	$apingerstatus = array();
234
	if(is_readable("{$g['tmp_path']}/apinger.status"))
235
		$apingerstatus = file("{$g['tmp_path']}/apinger.status");
236

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

    
267
?>
(23-23/27)