233
223
mgmt_log("Bad or missing proxy.config.lm.sem_id value; using default id %d\n", MGMT_SEMID_DEFAULT);
234
224
mgmt_sync_key = MGMT_SEMID_DEFAULT;
236
ink_strncpy(pserver_path, system_runtime_dir, sizeof(pserver_path));
226
ink_strlcpy(pserver_path, system_runtime_dir, sizeof(pserver_path));
241
for (int i = 0; i < MAX_PROXY_SERVER_PORTS; i++) {
242
proxy_server_port[i] = proxy_server_fd[i] = -1;
243
memset((void *) proxy_server_port_attributes[i], 0, MAX_ATTR_LEN);
247
230
RecInt http_enabled = REC_readInteger("proxy.config.http.enabled", &found);
248
231
ink_debug_assert(found);
249
232
if (http_enabled && found) {
250
int port = (int) REC_readInteger("proxy.config.http.server_port", &found);
252
proxy_server_port[pnum] = port;
253
char *main_server_port_attributes = (char *) REC_readString("proxy.config.http.server_port_attr", &found);
254
ink_strncpy((char *) proxy_server_port_attributes[pnum],
255
main_server_port_attributes, sizeof(proxy_server_port_attributes[pnum]));
256
xfree(main_server_port_attributes);
261
// Check to see if we are running SSL term
262
RecInt ssl_term_enabled = REC_readInteger("proxy.config.ssl.enabled", &found);
264
if (found && ssl_term_enabled) {
266
RecInt ssl_term_port = REC_readInteger("proxy.config.ssl.server_port", &found);
269
proxy_server_port[pnum] = ssl_term_port;
270
ink_strncpy((char *) proxy_server_port_attributes[pnum], "S", sizeof(proxy_server_port_attributes[pnum]));
275
// Read other ports to be listened on
276
char *proxy_server_other_ports = REC_readString("proxy.config.http.server_other_ports", &found);
277
if (proxy_server_other_ports) {
280
cport = ink_strtok_r(proxy_server_other_ports, " ", &last);
281
for (; pnum < MAX_PROXY_SERVER_PORTS && cport; pnum++) {
282
const char *attr = "X";
284
for (int j = 0; cport[j]; j++) {
285
if (cport[j] == ':') {
287
attr = &cport[j + 1];
291
int port_no = atoi(cport);
293
proxy_server_port[pnum] = port_no;
294
ink_strncpy((char *) proxy_server_port_attributes[pnum], attr, sizeof(proxy_server_port_attributes[pnum]));
296
Debug("lm", "[LocalManager::LocalManager] Adding port (%s, %d, '%s')\n", cport, port_no, attr);
297
cport = ink_strtok_r(NULL, " ", &last);
300
if (pnum == MAX_PROXY_SERVER_PORTS && cport) {
301
Debug("lm", "[LocalManager::LocalManager] Unable to listen on all other ports,"
302
" max number of other ports exceeded(max == %d)\n", MAX_PROXY_SERVER_PORTS);
304
xfree(proxy_server_other_ports);
306
// Bind proxy ports to incoming_ip_to_bind
307
char *incoming_ip_to_bind_str = REC_readString("proxy.local.incoming_ip_to_bind", &found);
308
if (found && incoming_ip_to_bind_str != NULL) {
309
proxy_server_incoming_ip_to_bind_str = incoming_ip_to_bind_str;
311
proxy_server_incoming_ip_to_bind_str = NULL;
233
HttpProxyPort::loadConfig(m_proxy_ports);
235
HttpProxyPort::loadDefaultIfEmpty(m_proxy_ports);
237
// Get the default IP binding values.
238
RecHttpLoadIp("proxy.local.incoming_ip_to_bind", m_inbound_ip4, m_inbound_ip6);
313
240
config_path = REC_readString("proxy.config.config_dir", &found);
314
241
char *absolute_config_path = Layout::get()->relative(config_path);
242
ats_free(config_path);
316
243
if (access(absolute_config_path, R_OK) == -1) {
317
config_path = xstrdup(system_config_directory);
244
config_path = ats_strdup(system_config_directory);
318
245
if (access(config_path, R_OK) == -1) {
319
246
mgmt_elog("[LocalManager::LocalManager] unable to access() directory '%s': %d, %s\n",
320
247
config_path, errno, strerror(errno));
358
285
env_prep = REC_readString("proxy.config.env_prep", &found);
359
286
// Calculate configured bin_path from the prefix
360
287
char *absolute_bin_path = Layout::get()->relative(bin_path);
362
289
bin_path = absolute_bin_path;
363
290
// Calculate proxy_binary from the absolute bin_path
364
291
absolute_proxy_binary = Layout::relative_to(absolute_bin_path, proxy_binary);
366
293
if (access(absolute_proxy_binary, R_OK | X_OK) == -1) {
367
294
// Try 'Layout::bindir' directory
368
xfree(absolute_proxy_binary);
295
ats_free(absolute_proxy_binary);
369
296
absolute_proxy_binary = Layout::relative_to(Layout::get()->bindir, proxy_binary);
370
297
// coverity[fs_check_call]
371
298
if (access(absolute_proxy_binary, R_OK | X_OK) == -1) {
414
341
intrName = REC_readString("proxy.config.cluster.ethernet_interface", &found);
415
342
ink_assert(intrName != NULL);
417
found = mgmt_getAddrForIntr(intrName, &cluster_addr);
344
found = mgmt_getAddrForIntr(intrName, &cluster_ip.sa);
418
345
if (found == false) {
419
346
mgmt_fatal(stderr, "[LocalManager::initCCom] Unable to find network interface %s. Exiting...\n", intrName);
347
} else if (!ats_is_ip4(&cluster_ip)) {
348
mgmt_fatal(stderr, "[LocalManager::initCCom] Unable to find IPv4 network interface %s. Exiting...\n", intrName);
422
clusterAddrStr = inet_ntoa(cluster_addr);
351
ats_ip_ntop(&cluster_ip, clusterAddrStr, sizeof(clusterAddrStr));
423
352
Debug("ccom", "Cluster Interconnect is %s : %s\n", intrName, clusterAddrStr);
425
354
// This an awful hack but I could not come up with a better way to
437
366
// Set the cluster ip addr variable so that proxy can read it
438
367
// and flush it to disk
439
368
const size_t envBuf_size = strlen(envVar) + strlen(clusterAddrStr) + 1;
440
envBuf = (char *) xmalloc(envBuf_size);
441
ink_strncpy(envBuf, envVar, envBuf_size);
442
strncat(envBuf, clusterAddrStr, envBuf_size - strlen(envBuf) - 1);
369
envBuf = (char *)ats_malloc(envBuf_size);
370
ink_strlcpy(envBuf, envVar, envBuf_size);
371
ink_strlcat(envBuf, clusterAddrStr, envBuf_size);
443
372
ink_release_assert(putenv(envBuf) == 0);
445
ccom = new ClusterCom(cluster_addr.s_addr, hostname, port, addr, sport, pserver_path);
446
virt_map = new VMap(intrName, cluster_addr.s_addr, &lmgmt->ccom->mutex);
374
ccom = new ClusterCom(ats_ip4_addr_cast(&cluster_ip), hostname, port, addr, sport, pserver_path);
375
virt_map = new VMap(intrName, ats_ip4_addr_cast(&cluster_ip), &lmgmt->ccom->mutex);
447
376
virt_map->downAddrs(); // Just to be safe
448
377
ccom->establishChannels();
457
384
* initMgmtProcessServer()
458
* - On UNIX, this function sets up the server socket that proxy processes connect to.
459
* - On WIN32, named pipes are used instead.
385
* sets up the server socket that proxy processes connect to.
462
388
LocalManager::initMgmtProcessServer()
1080
1000
RecSetRecordInt("proxy.node.restarts.proxy.restart_count", proxy_launch_count);
1082
1002
int res, i = 0, n;
1083
char real_proxy_options[2048], *options[32], *last, *tok;
1003
char real_proxy_options[TS_ARG_MAX], *options[32], *last, *tok;
1004
bool open_ports_p = false;
1085
1006
snprintf(real_proxy_options, sizeof(real_proxy_options), "%s", proxy_options);
1086
1007
n = strlen(real_proxy_options);
1088
1009
// Check if we need to pass down port/fd information to
1090
if (proxy_server_fd[0] != -1) {
1091
snprintf(&real_proxy_options[n], sizeof(real_proxy_options) - n, " -A");
1010
// traffic_server by seeing if there are any open ports.
1011
for ( int i = 0, limit = m_proxy_ports.length()
1012
; !open_ports_p && i < limit
1015
if (ts::NO_FD != m_proxy_ports[i].m_fd) open_ports_p = true;
1018
bool need_comma_p = false;
1019
snprintf(&real_proxy_options[n], sizeof(real_proxy_options) - n, " --httpport ");
1092
1020
n = strlen(real_proxy_options);
1093
// Handle some syntax issues
1094
if (proxy_server_fd[0] != -1) {
1095
snprintf(&real_proxy_options[n], sizeof(real_proxy_options) - n, ",");
1096
n = strlen(real_proxy_options);
1098
// Fill in the rest of the fd's
1099
if (proxy_server_fd[0] != -1) {
1100
snprintf(&real_proxy_options[n], sizeof(real_proxy_options) - n,
1101
"%d:%s", proxy_server_fd[0], (char*)proxy_server_port_attributes[0]);
1102
n = strlen(real_proxy_options);
1103
for (i = 1; i<MAX_PROXY_SERVER_PORTS && proxy_server_fd[i]> 0; i++) {
1104
snprintf(&real_proxy_options[n], sizeof(real_proxy_options) - n,
1105
",%d:%s", proxy_server_fd[i], (char*)proxy_server_port_attributes[i]);
1021
for ( int i = 0, limit = m_proxy_ports.length() ; i < limit ; ++i ) {
1022
HttpProxyPort& p = m_proxy_ports[i];
1023
if (ts::NO_FD != p.m_fd) {
1024
if (need_comma_p) real_proxy_options[n++] = ',';
1025
need_comma_p = true;
1026
p.print(real_proxy_options+n, sizeof(real_proxy_options)-n);
1106
1027
n = strlen(real_proxy_options);
1146
1078
// We are not already bound, bind the port
1147
for (int i = 0; i < MAX_PROXY_SERVER_PORTS; i++) {
1148
if (proxy_server_port[i] != -1) {
1149
if (proxy_server_fd[i] < 0) {
1150
int domain = AF_INET;
1151
int type = SOCK_STREAM;
1152
bool transparent = false;
1154
switch (*proxy_server_port_attributes[i]) {
1156
// D is for DNS proxy, udp only
1159
case '>': // in-bound (client side) transparent
1160
case '=': // fully transparent
1167
switch (*(proxy_server_port_attributes[i] + 1)) {
1175
proxy_server_fd[i] = bindProxyPort(proxy_server_port[i], proxy_server_incoming_ip_to_bind_str, domain, transparent, type);
1178
if (*proxy_server_port_attributes[i] != 'D') {
1179
if ((listen(proxy_server_fd[i], 1024)) < 0) {
1180
mgmt_fatal(stderr, "[LocalManager::listenForProxy] Unable to listen on socket: %d\n", proxy_server_port[i]);
1182
mgmt_log(stderr, "[LocalManager::listenForProxy] Listening on port: %d\n", proxy_server_port[i]);
1079
for ( int i = 0, n = lmgmt->m_proxy_ports.length() ; i < n ; ++i ) {
1080
HttpProxyPort& p = lmgmt->m_proxy_ports[i];
1081
if (ts::NO_FD == p.m_fd) {
1082
this->bindProxyPort(p);
1085
// read backlong configuration value and overwrite the default value if found
1088
RecInt config_backlog = REC_readInteger("proxy.config.net.listen_backlog", &found);
1090
backlog = config_backlog;
1093
if ((listen(p.m_fd, backlog)) < 0) {
1094
mgmt_fatal(stderr, "[LocalManager::listenForProxy] Unable to listen on socket: %d\n", p.m_port);
1096
mgmt_log(stderr, "[LocalManager::listenForProxy] Listening on port: %d\n", p.m_port);
1259
1167
* bindProxyPort()
1260
1168
* Function binds the accept port of the proxy
1261
* Also, type specifies udp or tcp
1264
bindProxyPort(int proxy_port, char *incoming_ip_to_bind_str, int domain, bool transparent, int type)
1171
LocalManager::bindProxyPort(HttpProxyPort& port)
1267
int proxy_port_fd = -1;
1268
struct addrinfo hints;
1269
struct addrinfo *result = NULL;
1270
char proxy_port_str[8] = {'\0'};
1273
1175
#if !TS_USE_POSIX_CAP
1274
1176
bool privBoost = false;
1275
1177
uid_t euid = geteuid();
1276
1178
uid_t saved_euid = 0;
1278
if (proxy_port < 1024 && euid != 0) {
1180
if (port.m_port < 1024 && euid != 0) {
1279
1181
if (restoreRootPriv(&saved_euid) == false) {
1280
1182
mgmt_elog(stderr, "[bindProxyPort] Unable to get root priviledges to bind port %d. euid is %d. Exiting\n",
1284
1186
privBoost = true;
1289
1191
/* Setup reliable connection, for large config changes */
1290
if ((proxy_port_fd = socket(domain, type, 0)) < 0) {
1192
if ((port.m_fd = socket(port.m_family, SOCK_STREAM, 0)) < 0) {
1291
1193
mgmt_elog(stderr, "[bindProxyPort] Unable to create socket : %s\n", strerror(errno));
1294
if (domain == AF_INET6) {
1295
if (setsockopt(proxy_port_fd, IPPROTO_IPV6, IPV6_V6ONLY, ON, sizeof(int)) < 0) {
1296
mgmt_elog(stderr, "[bindProxyPort] Unable to set socket options: %d : %s\n", proxy_port, strerror(errno));
1299
if (setsockopt(proxy_port_fd, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(int)) < 0) {
1300
mgmt_elog(stderr, "[bindProxyPort] Unable to set socket options: %d : %s\n", proxy_port, strerror(errno));
1197
if (port.m_type == HttpProxyPort::TRANSPORT_DEFAULT) {
1198
int should_filter_int = 0;
1200
should_filter_int = REC_readInteger("proxy.config.net.defer_accept", &found);
1201
if (found && should_filter_int > 0) {
1202
#if defined(SOL_FILTER) && defined(FIL_ATTACH)
1203
(void)setsockopt(port.m_fd, SOL_FILTER, FIL_ATTACH, "httpfilt", 9);
1208
if (port.m_family == AF_INET6) {
1209
if (setsockopt(port.m_fd, IPPROTO_IPV6, IPV6_V6ONLY, SOCKOPT_ON, sizeof(int)) < 0) {
1210
mgmt_elog(stderr, "[bindProxyPort] Unable to set socket options: %d : %s\n", port.m_port, strerror(errno));
1213
if (setsockopt(port.m_fd, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(int)) < 0) {
1214
mgmt_elog(stderr, "[bindProxyPort] Unable to set socket options: %d : %s\n", port.m_port, strerror(errno));
1218
if (port.m_inbound_transparent_p) {
1305
1219
#if TS_USE_TPROXY
1306
int transparent_value = 1;
1307
Debug("http_tproxy", "Listen port %d inbound transparency enabled.\n", proxy_port);
1308
if (setsockopt(proxy_port_fd, SOL_IP, TS_IP_TRANSPARENT, &transparent_value, sizeof(transparent_value)) == -1) {
1220
Debug("http_tproxy", "Listen port %d inbound transparency enabled.\n", port.m_port);
1221
if (setsockopt(port.m_fd, SOL_IP, TS_IP_TRANSPARENT, &one, sizeof(one)) == -1) {
1309
1222
mgmt_elog(stderr, "[bindProxyPort] Unable to set transparent socket option [%d] %s\n", errno, strerror(errno));
1317
snprintf(proxy_port_str, sizeof(proxy_port_str), "%d", proxy_port);
1318
memset(&hints, 0, sizeof(hints));
1319
hints.ai_family = domain;
1320
hints.ai_socktype = type;
1321
hints.ai_flags = AI_PASSIVE;
1323
err = getaddrinfo(incoming_ip_to_bind_str, proxy_port_str, &hints, &result);
1325
mgmt_elog(stderr, "[bindProxyPort] Unable to get address info: %s : %s\n", incoming_ip_to_bind_str, gai_strerror(err));
1329
if((bind(proxy_port_fd, result->ai_addr, result->ai_addrlen)) < 0) {
1330
mgmt_elog(stderr, "[bindProxyPort] Unable to bind socket: %d : %s\n", proxy_port, strerror(errno));
1334
freeaddrinfo(result);
1336
Debug("lm", "[bindProxyPort] Successfully bound proxy port %d\n", proxy_port);
1231
if (port.m_inbound_ip.isValid()) {
1232
ip.assign(port.m_inbound_ip);
1233
} else if (AF_INET6 == port.m_family) {
1234
if (m_inbound_ip6.isValid()) ip.assign(m_inbound_ip6);
1235
else ip.setToAnyAddr(AF_INET6);
1236
} else if (AF_INET == port.m_family) {
1237
if (m_inbound_ip4.isValid()) ip.assign(m_inbound_ip4);
1238
else ip.setToAnyAddr(AF_INET);
1240
mgmt_elog(stderr, "[bindProxyPort] Proxy port with invalid address type %d\n", port.m_family);
1243
ip.port() = htons(port.m_port);
1244
if (bind(port.m_fd, &ip.sa, ats_ip_size(&ip)) < 0) {
1245
mgmt_elog(stderr, "[bindProxyPort] Unable to bind socket: %d : %s\n", port.m_port, strerror(errno));
1249
Debug("lm", "[bindProxyPort] Successfully bound proxy port %d\n", port.m_port);
1338
1251
#if !TS_USE_POSIX_CAP
1339
if (proxy_port < 1024 && euid != 0) {
1252
if (port.m_port < 1024 && euid != 0) {
1340
1253
if (privBoost == true) {
1341
1254
if (removeRootPriv(saved_euid) == false) {
1342
1255
mgmt_elog(stderr, "[bindProxyPort] Unable to reset permissions to euid %d. Exiting...\n", getuid());