Project

General

Profile

Download (8.34 KB) Statistics
| Branch: | Tag: | Revision:
1 3ad6d3bb Bill Marquette
<?php
2 577c9191 Bill Marquette
/* $Id$ */
3 3ad6d3bb Bill Marquette
/*
4 17623ab5 Bill Marquette
  vslb.inc
5
  Copyright (C) 2005-2008 Bill Marquette
6
  All rights reserved.
7 3ad6d3bb Bill Marquette
8 17623ab5 Bill Marquette
  Redistribution and use in source and binary forms, with or without
9
  modification, are permitted provided that the following conditions are met:
10 3ad6d3bb Bill Marquette
11 17623ab5 Bill Marquette
  1. Redistributions of source code must retain the above copyright notice,
12
  this list of conditions and the following disclaimer.
13 3ad6d3bb Bill Marquette
14 17623ab5 Bill Marquette
  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 3ad6d3bb Bill Marquette
18 17623ab5 Bill Marquette
  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 3ad6d3bb Bill Marquette
29 17623ab5 Bill Marquette
 */
30 3ad6d3bb Bill Marquette
31 50d86c13 Bill Marquette
/* DISABLE_PHP_LINT_CHECKING */
32
33 3ad6d3bb Bill Marquette
/* include all configuration functions */
34
require_once("functions.inc");
35
require_once("pkg-utils.inc");
36
require_once("notices.inc");
37
38 50d86c13 Bill Marquette
class Monitor {
39
	private $conf = array();
40
	function __construct($config) {
41
		$this->conf = $config;
42
	}
43
44
	public function p() {
45
		return "check {$this->get('proto')}";
46
	}
47
	private function get($var) {
48
		return isset($this->$var) ? $this->$var : "";
49
	}
50
	protected function config($element) {
51
		return isset($this->conf[$element]) ? $this->conf[$element] : "";
52
	}
53
}
54
55
class TCPMonitor extends Monitor {
56
	protected $proto = 'tcp';
57
}
58
59
class SSLMonitor extends Monitor {
60
	protected $proto = 'ssl';
61
}
62
63
class ICMPMonitor extends Monitor {
64
	protected $proto = 'icmp';
65
}
66
67
class HTTPMonitor extends Monitor {
68
	protected $proto = 'http';
69
	function __construct($config) {
70
		parent::__construct($config);
71
	}
72
	public function p() {
73
		$method = ($this->code() != "") ? $this->code() : $this->digest();
74
		return "check {$this->proto} {$this->path()} {$this->host()} {$method}";
75
	}
76
77
	private function path() {
78
		return $this->config('path') != "" ? "'{$this->config('path')}'" : "";
79
	}
80
81
	private function host() {
82
		return $this->config('host') != "" ? "host {$this->config('host')}" : "";
83
	}
84
85
	private function code() {
86
		return $this->config('code') != "" ? "code {$this->config('code')}" : "";
87
	}
88
89
	private function digest() {
90
		return $this->config('digest') != "" ? "digest {$this->config('digest')}" : "";
91
	}
92
}
93
94
class HTTPSMonitor extends HTTPMonitor {
95
	protected $proto = 'https';
96
}
97
98
class SendMonitor extends Monitor {
99
	private $proto = 'send';
100
	function __construct($config) {
101
		parent::__construct($config);
102
	}
103
	public function p() {
104
		return "check {$this->proto} {$this->data()} expect {$this->pattern()} {$this->ssl()}";
105
	}
106
107
108
	private function data() {
109
		return $this->config('send') != "" ? "{$this->config('send')}" : "";
110
	}
111
112
	private function pattern() {
113
		return $this->config('expect') != "" ? "{$this->config('expect')}" : "";
114
	}
115
116
	private function ssl() {
117
		return $this->config('ssl') == true ? "ssl" : "";
118
	}
119
}
120
121 0919224f Bill Marquette
function echo_lbaction($action) {
122
  global $config;
123
  
124
  // Index actions by name
125
  $actions_a = array();
126
  for ($i=0; isset($config['load_balancer']['lbaction'][$i]); $i++)
127
		$actions_a[$config['load_balancer']['lbaction'][$i]['name']] = $config['load_balancer']['lbaction'][$i];
128
129
  $ret = "";
130
  $ret .=  "{$actions_a[$action]['direction']} {$actions_a[$action]['type']} {$actions_a[$action]['action']}";
131
  switch($actions_a[$action]['action']) {
132
    case 'append': {
133
      $ret .= " \"{$actions_a[$action]['options']['value']}\" to \"{$actions_a[$action]['options']['akey']}\"";
134
      break;
135
    }
136
    case 'change': {
137
      $ret .= " \"{$actions_a[$action]['options']['akey']}\" to \"{$actions_a[$action]['options']['value']}\"";
138
      break;
139
    }
140
    case 'expect': {
141
      $ret .= " \"{$actions_a[$action]['options']['value']}\" from \"{$actions_a[$action]['options']['akey']}\"";
142
      break;
143
    }
144
    case 'filter': {
145
      $ret .= " \"{$actions_a[$action]['options']['value']}\" from \"{$actions_a[$action]['options']['akey']}\"";
146
      break;
147
    }
148
    case 'hash': {
149
      $ret .= " \"{$actions_a[$action]['options']['akey']}\"";
150
      break;
151
    }
152
    case 'log': {
153
      $ret .= " \"{$actions_a[$action]['options']['akey']}\"";
154
      break;
155
    }
156
  }
157
  return $ret;
158
}
159 50d86c13 Bill Marquette
160 17623ab5 Bill Marquette
function relayd_configure() {
161
  global $config, $g;
162
163 a825c6f7 Bill Marquette
  $vs_a = $config['load_balancer']['virtual_server'];
164
  $pool_a = $config['load_balancer']['lbpool'];
165
  $protocol_a = $config['load_balancer']['lbprotocol'];
166 17623ab5 Bill Marquette
167 50d86c13 Bill Marquette
  $check_a = array();
168
169 52bd375c Bill Marquette
  foreach ((array)$config['load_balancer']['monitor_type'] as $type) {
170 50d86c13 Bill Marquette
    switch($type['type']) {
171
      case 'icmp': {
172
        $mon = new ICMPMonitor($type['options']);
173
	break;
174
      }
175
      case 'tcp': {
176
        $mon = new TCPMonitor($type['options']);
177
	break;
178
      }
179
      case 'http': {
180
        $mon = new HTTPMonitor($type['options']);
181
	break;
182
      }
183
      case 'https': {
184
        $mon = new HTTPSMonitor($type['options']);
185
	break;
186
      }
187
      case 'send': {
188
        $mon = new SendMonitor($type['options']);
189
	break;
190
      }
191
    }
192
    $check_a[$type['name']] = $mon->p();
193
  }
194
195
196 17623ab5 Bill Marquette
  $fd = fopen("{$g['varetc_path']}/relayd.conf", "w");
197
198
  /* reindex pools by name as we loop through the pools array */
199
  $pools = array();
200
  /* Virtual server pools */
201
  if(is_array($pool_a)) {
202
    for ($i = 0; isset($pool_a[$i]); $i++) {
203
      if(is_array($pool_a[$i]['servers'])) {
204
        $srvtxt = implode(", ", $pool_a[$i]['servers']);
205
        $conf .= "table <{$pool_a[$i]['name']}> { $srvtxt }\n";
206
        /* Index by name for easier fetching when we loop through the virtual servers */
207
        $pools[$pool_a[$i]['name']] = $pool_a[$i];
208
      }
209
    }
210
  }
211 0919224f Bill Marquette
  if(is_array($protocol_a)) {
212
    for ($i = 0; isset($protocol_a[$i]); $i++) {
213 ab9c7767 Bill Marquette
      $proto = "{$protocol_a[$i]['type']} protocol \"{$protocol_a[$i]['name']}\" {\n";
214 0919224f Bill Marquette
      if(is_array($protocol_a[$i]['lbaction'])) {
215 ab9c7767 Bill Marquette
        if($protocol_a[$i]['lbaction'][0] == "") {
216
          continue;
217
        }
218 0919224f Bill Marquette
        for ($a = 0; isset($protocol_a[$i]['lbaction'][$a]); $a++) {
219 ab9c7767 Bill Marquette
          $proto .= "  " . echo_lbaction($protocol_a[$i]['lbaction'][$a]) . "\n";
220 0919224f Bill Marquette
        }
221
      }
222 ab9c7767 Bill Marquette
      $proto .= "}\n";
223
      $conf .= $proto;
224 0919224f Bill Marquette
    }
225
  }
226 17623ab5 Bill Marquette
  if(is_array($vs_a)) {
227
    for ($i = 0; isset($vs_a[$i]); $i++) {
228 0919224f Bill Marquette
      switch($vs_a[$i]['mode']) {
229
        case 'redirect': {
230
          $conf .= "redirect \"{$vs_a[$i]['name']}\" {\n";
231
          $conf .= "  listen on {$vs_a[$i]['ipaddr']} port {$vs_a[$i]['port']}\n";
232
          $conf .= "  forward to <{$vs_a[$i]['pool']}> port {$pools[$vs_a[$i]['pool']]['port']} {$check_a[$pools[$vs_a[$i]['pool']]['monitor']]} timeout 1000\n";
233
234 43b01df4 Bill Marquette
          # sitedown MUST use the same port as the primary pool - sucks, but it's a relayd thing
235 0919224f Bill Marquette
          if (isset($vs_a[$i]['sitedown']) &&  $vs_a[$i]['sitedown'] != "")
236 aeb90d90 Bill Marquette
            $conf .= "  forward to <{$vs_a[$i]['sitedown']}> port {$pools[$vs_a[$i]['pool']]['port']} {$check_a[$pools[$vs_a[$i]['pool']]['monitor']]} timeout 1000\n";
237 0919224f Bill Marquette
          $conf .= "}\n";
238
          break;
239
        }
240
        case 'relay': {
241
          $conf .= "relay \"{$vs_a[$i]['name']}\" {\n";
242
          $conf .= "  listen on {$vs_a[$i]['ipaddr']} port {$vs_a[$i]['port']}\n";
243
          $conf .= "  protocol \"{$vs_a[$i]['relay_protocol']}\"\n";
244
          $conf .= "  forward to <{$vs_a[$i]['pool']}> port {$pools[$vs_a[$i]['pool']]['port']} {$check_a[$pools[$vs_a[$i]['pool']]['monitor']]} timeout 1000\n";
245
246
          if (isset($vs_a[$i]['sitedown']) &&  $vs_a[$i]['sitedown'] != "")
247
            $conf .= "  forward to <{$vs_a[$i]['sitedown']}> port {$pools[$vs_a[$i]['pool']]['port']} {$check_a[$pools[$vs_a[$i]['pool']]['monitor']]} timeout 1000\n";
248
          $conf .= "}\n";
249
          break;
250
        }
251
      }
252 17623ab5 Bill Marquette
    }
253
  }
254
  fwrite($fd, $conf);
255
  fclose($fd);
256
257 651d99c5 Bill Marquette
  if (is_process_running('relayd: parent')) {
258 a32a06ad Bill Marquette
    /*
259
     * XXX: Something breaks our control connection with relayd and makes relayctl stop working
260
     * rule reloads are the current suspect
261
     * mwexec('/usr/local/bin/relayctl stop');
262
     */
263
     mwexec('pkill relayd');
264 17623ab5 Bill Marquette
  }
265 3eb583e6 Seth Mos
  if (! empty($vs_a)) {
266
    mwexec("/usr/local/sbin/relayd -f {$g['varetc_path']}/relayd.conf");
267
  }
268 3ad6d3bb Bill Marquette
}
269
270 651d99c5 Bill Marquette
?>