~ubuntu-branches/ubuntu/wily/trafficserver/wily

« back to all changes in this revision

Viewing changes to mgmt/LocalManager.cc

  • Committer: Package Import Robot
  • Author(s): Adam Conrad
  • Date: 2012-12-17 22:28:16 UTC
  • mfrom: (5.1.8 raring-proposed)
  • Revision ID: package-import@ubuntu.com-20121217222816-7xwjsx5k76zkb63d
Tags: 3.2.0-1ubuntu1
* Revert FreeBSD strerror_r() fixes that give errors with glibc 2.16.
* Apply patch from Konstantinos Margaritis to define barriers on ARM.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/** @file
2
2
 
3
 
  A brief file description
 
3
  The Local Manager process of the management system.
4
4
 
5
5
  @section license License
6
6
 
21
21
  limitations under the License.
22
22
 */
23
23
 
24
 
/*
25
 
 *
26
 
 * LocalManager.cc
27
 
 * - The Local Manager process of the management system.
28
 
 * - The main loop has been migrated to Main.cc
29
 
 *
30
 
 *
31
 
 */
32
24
 
33
25
#include "libts.h"
34
26
#include "ink_platform.h"
43
35
#include <sys/capability.h>
44
36
#endif
45
37
 
46
 
int bindProxyPort(int, char*, int, bool, int);
47
 
 
48
38
bool
49
39
LocalManager::SetForDup(void *hIOCPort, long lTProcId, void *hTh)
50
40
{
163
153
        mgmt_log(stderr, "[LocalManager::clearStats] Unlink of %s failed : %s\n", REC_RAW_STATS_FILE, strerror(errno));
164
154
      }
165
155
    }
166
 
    xfree(statsPath);
 
156
    ats_free(statsPath);
167
157
  }
168
158
}
169
159
 
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;
235
225
  }
236
 
  ink_strncpy(pserver_path, system_runtime_dir, sizeof(pserver_path));
 
226
  ink_strlcpy(pserver_path, system_runtime_dir, sizeof(pserver_path));
237
227
 
238
228
  virt_map = NULL;
239
229
 
240
 
 
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);
244
 
  }
245
 
 
246
 
  int pnum = 0;
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);
251
 
    if (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);
257
 
      pnum++;
258
 
    }
259
 
  }
260
 
 
261
 
  // Check to see if we are running SSL term
262
 
  RecInt ssl_term_enabled = REC_readInteger("proxy.config.ssl.enabled", &found);
263
 
  ink_assert(found);
264
 
  if (found && ssl_term_enabled) {
265
 
    // Get the SSL port
266
 
    RecInt ssl_term_port = REC_readInteger("proxy.config.ssl.server_port", &found);
267
 
    ink_assert(found);
268
 
    if (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]));
271
 
      pnum++;
272
 
    }
273
 
  }
274
 
 
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) {
278
 
    char *last, *cport;
279
 
 
280
 
    cport = ink_strtok_r(proxy_server_other_ports, " ", &last);
281
 
    for (; pnum < MAX_PROXY_SERVER_PORTS && cport; pnum++) {
282
 
      const char *attr = "X";
283
 
 
284
 
      for (int j = 0; cport[j]; j++) {
285
 
        if (cport[j] == ':') {
286
 
          cport[j] = '\0';
287
 
          attr = &cport[j + 1];
288
 
        }
289
 
      }
290
 
 
291
 
      int port_no = atoi(cport);
292
 
 
293
 
      proxy_server_port[pnum] = port_no;
294
 
      ink_strncpy((char *) proxy_server_port_attributes[pnum], attr, sizeof(proxy_server_port_attributes[pnum]));
295
 
 
296
 
      Debug("lm", "[LocalManager::LocalManager] Adding port (%s, %d, '%s')\n", cport, port_no, attr);
297
 
      cport = ink_strtok_r(NULL, " ", &last);
298
 
    }
299
 
 
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);
303
 
    }
304
 
    xfree(proxy_server_other_ports);
305
 
  }
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;
310
 
  } else {
311
 
    proxy_server_incoming_ip_to_bind_str = NULL;
312
 
  }
 
233
    HttpProxyPort::loadConfig(m_proxy_ports);
 
234
  }
 
235
  HttpProxyPort::loadDefaultIfEmpty(m_proxy_ports);
 
236
 
 
237
  // Get the default IP binding values.
 
238
  RecHttpLoadIp("proxy.local.incoming_ip_to_bind", m_inbound_ip4, m_inbound_ip6);
 
239
 
313
240
  config_path = REC_readString("proxy.config.config_dir", &found);
314
241
  char *absolute_config_path = Layout::get()->relative(config_path);
315
 
  xfree(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);
361
 
  xfree(bin_path);
 
288
  ats_free(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);
365
292
 
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) {
400
327
LocalManager::initCCom(int port, char *addr, int sport)
401
328
{
402
329
  bool found;
403
 
  struct in_addr cluster_addr;  // ip addr of the cluster interface
404
 
  char *clusterAddrStr;         // cluster ip addr as a String
 
330
  IpEndpoint cluster_ip;    // ip addr of the cluster interface
 
331
  ip_text_buffer clusterAddrStr;         // cluster ip addr as a String
405
332
  char *intrName;               // Name of the interface we are to use
406
333
  char hostname[1024];          // hostname of this machine
407
334
  const char envVar[] = "PROXY_CLUSTER_ADDR=";
414
341
  intrName = REC_readString("proxy.config.cluster.ethernet_interface", &found);
415
342
  ink_assert(intrName != NULL);
416
343
 
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);
420
349
  }
421
350
 
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);
424
353
 
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);
444
373
 
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();
 
378
  ats_free(intrName);
449
379
 
450
 
  if (intrName) {
451
 
    xfree(intrName);
452
 
  }
453
380
  return;
454
381
}
455
382
 
456
383
/*
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.
460
386
 */
461
387
void
462
388
LocalManager::initMgmtProcessServer()
483
409
 
484
410
  memset(&serv_addr, 0, sizeof(serv_addr));
485
411
  serv_addr.sun_family = AF_UNIX;
486
 
  ink_strncpy(serv_addr.sun_path, fpath, sizeof(serv_addr.sun_path));
 
412
  ink_strlcpy(serv_addr.sun_path, fpath, sizeof(serv_addr.sun_path));
487
413
#if defined(darwin) || defined(freebsd)
488
414
  servlen = sizeof(struct sockaddr_un);
489
415
#else
738
664
      // stype is an enum type, so cast to an int* to avoid warnings. /leif
739
665
      int tokens = sscanf(data_raw, "%255s %d %255s", var_name, (int *) &stype, var_value);
740
666
      if (tokens != 3) {
741
 
        stype = INVALID;
 
667
        stype = MGMT_INVALID;
742
668
      }
743
669
      switch (stype) {
744
 
      case INK_INT:
 
670
      case MGMT_INT:
745
671
        RecSetRecordInt(var_name, ink_atoi64(var_value));
746
672
        break;
747
 
      case INK_COUNTER:
748
 
      case INK_FLOAT:
749
 
      case INK_STRING:
750
 
      case INVALID:
 
673
      case MGMT_COUNTER:
 
674
      case MGMT_FLOAT:
 
675
      case MGMT_STRING:
 
676
      case MGMT_INVALID:
751
677
      default:
752
678
        mgmt_elog(stderr,
753
679
                  "[LocalManager::handleMgmtMsgFromProcesses] " "Invalid plugin set-config msg '%s'\n", data_raw);
832
758
      if (lmgmt->virt_map) {
833
759
        lmgmt->virt_map->downAddrs();   /* Down all known addrs to be safe */
834
760
      }
835
 
      for (int i = 0; i < MAX_PROXY_SERVER_PORTS; i++) {
836
 
        if (proxy_server_fd[i] != -1) { // Close the socket
837
 
          close_socket(proxy_server_fd[i]);
838
 
          proxy_server_fd[i] = -1;
839
 
        }
840
 
      }
 
761
      this->closeProxyPorts();
841
762
      break;
842
763
    }
843
764
  case MGMT_EVENT_RESTART:
874
795
                "Invalid 'data_raw' for MGMT_EVENT_CONFIG_FILE_UPDATE\n");
875
796
      ink_assert(false);
876
797
    }
877
 
    xfree(fname);
 
798
    ats_free(fname);
878
799
    break;
879
800
  }
880
801
 
958
879
{
959
880
  MgmtMessageHdr *mh;
960
881
 
961
 
  mh = (MgmtMessageHdr *) xmalloc(sizeof(MgmtMessageHdr) + data_len);
 
882
  mh = (MgmtMessageHdr *)ats_malloc(sizeof(MgmtMessageHdr) + data_len);
962
883
  mh->msg_id = msg_id;
963
884
  mh->data_len = data_len;
964
885
  memcpy((char *) mh + sizeof(MgmtMessageHdr), data_raw, data_len);
1007
928
      Debug("lm", "[TrafficManager] ==> Sending signal event '%d'\n", mh->msg_id);
1008
929
      lmgmt->sendMgmtMsgToProcesses(mh);
1009
930
    }
1010
 
 
1011
 
    xfree(mh);
 
931
    ats_free(mh);
1012
932
  }
1013
933
}
1014
934
 
1080
1000
    RecSetRecordInt("proxy.node.restarts.proxy.restart_count", proxy_launch_count);
1081
1001
  } else {
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;
1084
1005
 
1085
1006
    snprintf(real_proxy_options, sizeof(real_proxy_options), "%s", proxy_options);
1086
1007
    n = strlen(real_proxy_options);
1087
1008
 
1088
1009
    // Check if we need to pass down port/fd information to
1089
 
    // traffic_server
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
 
1013
            ; ++i
 
1014
    )
 
1015
      if (ts::NO_FD != m_proxy_ports[i].m_fd) open_ports_p = true;
 
1016
 
 
1017
    if (open_ports_p) {
 
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);
1097
 
      }
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);
1107
1028
        }
1108
1029
      }
1111
1032
    Debug("lm", "[LocalManager::startProxy] Launching %s with options '%s'\n",
1112
1033
          absolute_proxy_binary, real_proxy_options);
1113
1034
 
1114
 
    for (i = 0; i < 32; i++)
1115
 
      options[i] = NULL;
 
1035
    ink_zero(options);
1116
1036
    options[0] = absolute_proxy_binary;
1117
1037
    i = 1;
1118
1038
    tok = ink_strtok_r(real_proxy_options, " ", &last);
1119
1039
    options[i++] = tok;
1120
1040
    while (i < 32 && (tok = ink_strtok_r(NULL, " ", &last))) {
 
1041
      Debug("lm", "opt %d = '%s'\n", i, tok);
1121
1042
      options[i++] = tok;
1122
1043
    }
1123
1044
 
1132
1053
  return true;
1133
1054
}
1134
1055
 
1135
 
 
 
1056
/** Close all open ports.
 
1057
 */
 
1058
void
 
1059
LocalManager::closeProxyPorts() {
 
1060
  for ( int i = 0, n = lmgmt->m_proxy_ports.length() ; i < n ; ++i ) {
 
1061
    HttpProxyPort& p = lmgmt->m_proxy_ports[i];
 
1062
    if (ts::NO_FD != p.m_fd) {
 
1063
      close_socket(p.m_fd);
 
1064
      p.m_fd = ts::NO_FD;
 
1065
    }
 
1066
  }
 
1067
}
1136
1068
/*
1137
1069
 * listenForProxy()
1138
1070
 *  Function listens on the accept port of the proxy, so users aren't dropped.
1144
1076
    return;
1145
1077
 
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;
1153
 
 
1154
 
        switch (*proxy_server_port_attributes[i]) {
1155
 
        case 'D':
1156
 
          // D is for DNS proxy, udp only
1157
 
          type = SOCK_DGRAM;
1158
 
          break;
1159
 
        case '>': // in-bound (client side) transparent
1160
 
        case '=': // fully transparent
1161
 
          transparent = true;
1162
 
          break;
1163
 
        default:
1164
 
          type = SOCK_STREAM;
1165
 
        }
1166
 
 
1167
 
        switch (*(proxy_server_port_attributes[i] + 1)) {
1168
 
        case '6':
1169
 
          domain = AF_INET6;
1170
 
          break;
1171
 
        default:
1172
 
          domain = AF_INET;
1173
 
        }
1174
 
 
1175
 
        proxy_server_fd[i] = bindProxyPort(proxy_server_port[i], proxy_server_incoming_ip_to_bind_str, domain, transparent, type);
1176
 
      }
1177
 
 
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]);
1181
 
        }
1182
 
        mgmt_log(stderr, "[LocalManager::listenForProxy] Listening on port: %d\n", proxy_server_port[i]);
1183
 
      } else {
1184
 
        break;
1185
 
      }
1186
 
    }
 
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);
 
1083
    }
 
1084
 
 
1085
    // read backlong configuration value and overwrite the default value if found
 
1086
    int backlog = 1024;
 
1087
    bool found;
 
1088
    RecInt config_backlog = REC_readInteger("proxy.config.net.listen_backlog", &found);
 
1089
    if (found) {
 
1090
      backlog = config_backlog;
 
1091
    }
 
1092
 
 
1093
    if ((listen(p.m_fd, backlog)) < 0) {
 
1094
      mgmt_fatal(stderr, "[LocalManager::listenForProxy] Unable to listen on socket: %d\n", p.m_port);
 
1095
    }
 
1096
    mgmt_log(stderr, "[LocalManager::listenForProxy] Listening on port: %d\n", p.m_port);
1187
1097
  }
1188
1098
  return;
1189
1099
}
1221
1131
//
1222
1132
//    - Returns true on success
1223
1133
//      and false on failure
1224
 
//    - no-op on WIN32
1225
1134
bool
1226
1135
removeRootPriv(uid_t euid)
1227
1136
{
1238
1147
//
1239
1148
//    - Returns true on success
1240
1149
//      and false on failure
1241
 
//    - no-op on WIN32
1242
1150
bool
1243
1151
restoreRootPriv(uid_t *old_euid)
1244
1152
{
1258
1166
/*
1259
1167
 * bindProxyPort()
1260
1168
 *  Function binds the accept port of the proxy
1261
 
 *  Also, type specifies udp or tcp
1262
1169
 */
1263
 
int
1264
 
bindProxyPort(int proxy_port, char *incoming_ip_to_bind_str, int domain, bool transparent, int type)
 
1170
void
 
1171
LocalManager::bindProxyPort(HttpProxyPort& port)
1265
1172
{
1266
1173
  int one = 1;
1267
 
  int proxy_port_fd = -1;
1268
 
  struct addrinfo hints;
1269
 
  struct addrinfo *result = NULL;
1270
 
  char proxy_port_str[8] = {'\0'};
1271
 
  int err = 0;
1272
1174
 
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;
1277
1179
 
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",
1281
 
                proxy_port, euid);
 
1183
                port.m_port, euid);
1282
1184
      _exit(0);
1283
1185
    } else {
1284
1186
      privBoost = true;
1287
1189
#endif
1288
1190
 
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));
1292
1194
    _exit(1);
1293
1195
  }
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));
1297
 
    }
1298
 
  }
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));
 
1196
 
 
1197
  if (port.m_type == HttpProxyPort::TRANSPORT_DEFAULT) {
 
1198
    int should_filter_int = 0;
 
1199
    bool found;
 
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);
 
1204
#endif
 
1205
    }
 
1206
  }
 
1207
 
 
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));
 
1211
    }
 
1212
  }
 
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));
1301
1215
    _exit(1);
1302
1216
  }
1303
1217
 
1304
 
  if (transparent) {
 
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));
1310
1223
      _exit(1);
1311
1224
    }
1314
1227
#endif
1315
1228
  }
1316
1229
 
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;
1322
 
 
1323
 
  err = getaddrinfo(incoming_ip_to_bind_str, proxy_port_str, &hints, &result);
1324
 
  if (err != 0) {
1325
 
    mgmt_elog(stderr, "[bindProxyPort] Unable to get address info: %s : %s\n", incoming_ip_to_bind_str, gai_strerror(err));
1326
 
    _exit(1);
1327
 
  }
1328
 
 
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));
1331
 
    _exit(1);
1332
 
  }
1333
 
 
1334
 
  freeaddrinfo(result);
1335
 
 
1336
 
  Debug("lm", "[bindProxyPort] Successfully bound proxy port %d\n", proxy_port);
 
1230
  IpEndpoint ip;
 
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);
 
1239
  } else {
 
1240
    mgmt_elog(stderr, "[bindProxyPort] Proxy port with invalid address type %d\n", port.m_family);
 
1241
    _exit(1);
 
1242
  }
 
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));
 
1246
    _exit(1);
 
1247
  }
 
1248
 
 
1249
  Debug("lm", "[bindProxyPort] Successfully bound proxy port %d\n", port.m_port);
1337
1250
 
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());
1345
1258
    }
1346
1259
  }
1347
1260
#endif
1348
 
  return proxy_port_fd;
1349
1261
}
1350
1262
 
1351
1263
void