Beispiel #1
0
/*
 * Function:    BWLAddrByLocalControl
 *
 * Description:    
 *              Wrapper for some I2Addr functions on the
 *              control socket.
 *
 * In Args:    
 *
 * Out Args:    
 *
 * Scope:    
 * Returns:    
 * Side Effect:    
 */
I2Addr
BWLAddrByLocalControl(
        BWLControl  cntrl
        )
{
    struct sockaddr *saddr;
    socklen_t       saddrlen;

    if(!cntrl->local_addr ||
            !(saddr = I2AddrSAddr(cntrl->local_addr,&saddrlen))){
        return NULL;
    }

    return I2AddrBySAddr(BWLContextErrHandle(cntrl->ctx),
            saddr,saddrlen,
            I2AddrSocktype(cntrl->local_addr),
            I2AddrProtocol(cntrl->local_addr));
}
Beispiel #2
0
int main(int argc, char** argv) {
  int c;
  int sockfd, newsockfd;
  int federated = 0, debug = 0, max_ttl = 10;
  time_t tt;
  socklen_t clilen;
  char* srcname = NULL;
  char* listenport = LISTEN_PORT;
  int conn_options = 0;

  char *ErLogFileName = BASEDIR
      "/"ERLOGFILE;
  char *AcLogFileName = BASEDIR
      "/"ACLOGFILE;
  struct sockaddr_storage cli_addr;
  I2Addr listenaddr = NULL;
  Allowed* ptr;

#ifdef AF_INET6
#define GETOPT_LONG_INET6(x) "46"x
#else
#define GETOPT_LONG_INET6(x) x
#endif

  while ((c = getopt_long(argc, argv, GETOPT_LONG_INET6("dhl:e:p:t:Ff:b:sS:v"),
                          long_options, 0)) != -1) {
    switch (c) {
      case '4':
        conn_options |= OPT_IPV4_ONLY;
        break;
      case '6':
        conn_options |= OPT_IPV6_ONLY;
        break;
      case 'd':
        debug++;
        break;
      case 'h':
        www_long_usage("ANL/Internet2 NDT version " VERSION " (fakewww)");
        break;
      case 'v':
        printf("ANL/Internet2 NDT version %s (fakewww)\n", VERSION);
        exit(0);
        break;
      case 'l':
        AcLogFileName = optarg;
        break;
      case 'e':
        ErLogFileName = optarg;
        break;
      case 'p':
        listenport = optarg;
        break;
      case 't':
        max_ttl = atoi(optarg);
        break;
      case 'F':
        federated = 1;
        break;
      case 'f':
        ptr = malloc(sizeof(Allowed));
        ptr->filename = optarg;
        ptr->next = a_root;
        a_root = ptr;
        break;
      case 'b':
        basedir = optarg;
        break;
      case 's':
        usesyslog = 1;
        break;
      case 'S':
        SysLogFacility = optarg;
        break;
      case 301:
        DefaultTree = optarg;
        break;
#ifdef AF_INET6
      case 302:
        DefaultTree6 = optarg;
        break;
#endif
      case '?':
        short_usage(argv[0], "");
        break;
    }
  }

  if (optind < argc) {
    short_usage(argv[0], "Unrecognized non-option elements");
  }

  log_init(argv[0], debug);

  if (SysLogFacility != NULL) {
    int i = 0;
    while (facilitynames[i].c_name) {
      if (strcmp(facilitynames[i].c_name, SysLogFacility) == 0) {
        syslogfacility = facilitynames[i].c_val;
        break;
      }
      ++i;
    }
    if (facilitynames[i].c_name == NULL) {
      log_println(
          0,
          "Warning: Unknown syslog facility [%s] --> using default (%d)",
          SysLogFacility, syslogfacility);
      SysLogFacility = NULL;
    }
  }

  if (DefaultTree == NULL) {
    snprintf(dtfn, sizeof(dtfn), "%s/%s", BASEDIR, DFLT_TREE);
    DefaultTree = dtfn;
  }

#ifdef AF_INET6
  if (DefaultTree6 == NULL) {
    snprintf(dt6fn, sizeof(dtfn), "%s/%s", BASEDIR, DFLT_TREE6);
    DefaultTree6 = dt6fn;
  }
#endif

  /*
   * Bind our local address so that the client can send to us.
   */
  if (srcname && !(listenaddr = I2AddrByNode(get_errhandle(), srcname))) {
    err_sys("server: Invalid source address specified");
  }
  if ((listenaddr = CreateListenSocket(listenaddr, listenport, conn_options,
                                       0)) == NULL) {
    err_sys("server: CreateListenSocket failed");
  }
  sockfd = I2AddrFD(listenaddr);

  tt = time(0);
  log_println(1, "%15.15s fakewww server started (NDT version %s)",
              ctime(&tt) + 4, VERSION);
  log_println(1, "\tport = %d", I2AddrPort(listenaddr));
  log_println(1, "\tfederated mode = %s", (federated == 1) ? "on" : "off");
  log_println(1, "\taccess log = %s\n\terror log = %s", AcLogFileName,
              ErLogFileName);
  log_println(1, "\tbasedir = %s", basedir);
  if (usesyslog) {
    log_println(1, "\tsyslog facility = %s (%d)",
                SysLogFacility ? SysLogFacility : "default", syslogfacility);
  }
  log_println(1, "\tdebug level set to %d", debug);

  logErLog(ErLogFileName, &tt, "notice",
           "fakewww server started (NDT version %s)", VERSION);
  logErLog(ErLogFileName, &tt, "notice", "\tport = %d",
           I2AddrPort(listenaddr));
  logErLog(ErLogFileName, &tt, "notice", "\tfederated mode = %s",
           (federated == 1) ? "on" : "off");
  logErLog(ErLogFileName, &tt, "notice", "\taccess log = %s", AcLogFileName);
  logErLog(ErLogFileName, &tt, "notice", "\terror log = %s", ErLogFileName);
  logErLog(ErLogFileName, &tt, "notice", "\tbasedir = %s", basedir);
  if (usesyslog) {
    logErLog(ErLogFileName, &tt, "notice", "\tsyslog facility = %s (%d)",
             SysLogFacility ? SysLogFacility : "default", syslogfacility);
  }
  logErLog(ErLogFileName, &tt, "notice", "\tdebug level set to %d", debug);

  if (usesyslog == 1)
    syslog(LOG_FACILITY | LOG_INFO, "Fakewww (ver %s) process started",
           VERSION);
  signal(SIGCHLD, reap); /* get rid of zombies */

  /*
   * Wait for a connection from a client process.
   * This is an example of a concurrent server.
   */

  for (;;) {
    clilen = sizeof(cli_addr);
    newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
    if (newsockfd < 0) {
      if (errno == EINTR)
        continue; /*sig child */
      err_sys("Fakewww server: accept error");
    }

    if (fork() == 0) { /* child */
      I2Addr caddr = I2AddrBySAddr(get_errhandle(),
                                   (struct sockaddr *) &cli_addr, clilen, 0, 0);
      alarm(300); /* kill child off after 5 minutes, should never happen */
      close(sockfd);
      dowww(newsockfd, caddr, listenport, AcLogFileName, ErLogFileName,
            federated, max_ttl);
      exit(0);
    }
    close(newsockfd);
  }
}
Beispiel #3
0
static int OpenSocket(I2Addr addr, char* serv, int family, int options) {
  int fd = -1;
  int return_code = 0;

  struct addrinfo *fai = NULL;
  if (!(fai = I2AddrAddrInfo(addr, NULL, serv))) {
    return -2;
  }

  // Attempt to connect to one of the chosen addresses.
  struct addrinfo* ai = NULL;
  for (ai = fai; ai; ai = ai->ai_next) {
    if (ai->ai_family != family)
      continue;

    // create socket with obtained address domain, socket type and protocol
    fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);

    // socket create failed. Abandon further activities using this socket
    if (fd < 0)
      continue;

    // allow sockets to reuse local address while binding unless there
    // is an active listener. If unable to set this option, indicate failure
    int on = 1;
    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) != 0) {
      return_code = -2;
      goto failsock;
    }
    // end trying to set socket option to reuse local address

#ifdef AF_INET6
#ifdef IPV6_V6ONLY
    if (family == AF_INET6 && (options & OPT_IPV6_ONLY)) {
      on = 1;
      // the IPv6 version socket option setup
      if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) != 0) {
        return_code = -2;
        goto failsock;
      }
    }
#endif
#endif

    // try to bind to address
    if (bind(fd, ai->ai_addr, ai->ai_addrlen) == 0) {  // successful
      // set values in "addr" structure
      if (!I2AddrSetSAddr(addr, ai->ai_addr, ai->ai_addrlen) ||
          !I2AddrSetProtocol(addr, ai->ai_protocol) ||
          !I2AddrSetSocktype(addr, ai->ai_socktype)) {
        log_println(1, "OpenSocket: Unable to set saddr in address record");
        return_code = -1;
        goto failsock;
      }
      // set port if not already done, else return -1
      if (!I2AddrPort(addr)) {
        struct sockaddr_storage tmp_addr;
        socklen_t tmp_addr_len = sizeof(tmp_addr);
        I2Addr tmpAddr;
        if (getsockname(fd, (struct sockaddr*) &tmp_addr,
                        &tmp_addr_len)) {
          log_println(1, "OpenSocket: Unable to getsockname in address record");
          return_code = -1;
          goto failsock;
        }
        tmpAddr = I2AddrBySAddr(
            get_errhandle(), (struct sockaddr*) &tmp_addr, tmp_addr_len, 0, 0);
        I2AddrSetPort(addr, I2AddrPort(tmpAddr));
        I2AddrFree(tmpAddr);
      }
      // save socket file descriptor
      if (!I2AddrSetFD(addr, fd, True)) {
        log_println(1, "OpenSocket: Unable to set file descriptor in address "
                    "record");
        return_code = -1;
        goto failsock;
      }
      // end setting values in "addr" structure

      break;
    }

    // Address is indicated as being in use. Display actual socket options to
    // user and return
    if (errno == EADDRINUSE) {
      /* RAC debug statemement 10/11/06 */
      socklen_t onSize = sizeof(on);
      getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, &onSize);
      log_println(1, "bind(%d) failed: Address already in use given as the "
                  "reason, getsockopt() returned %d", fd, on);
    } else {
      log_println(1, "bind(%d) failed: %s", fd, strerror(errno));
    }
    return_code = -1;
    goto failsock;
  }

  return fd;

  // If opening socket failed, print error, and try to close socket
  // file-descriptor.
 failsock:
  while ((close(fd) < 0) && (errno == EINTR)) { }
  return return_code;
}
Beispiel #4
0
static int
OpenSocket(I2Addr addr, char* serv, int options)
{
  struct addrinfo *fai;
  struct addrinfo *ai;
  int             on;
  socklen_t       onSize;
  int             fd=-1;

  if (!(fai = I2AddrAddrInfo(addr, NULL, serv))) {
    return -2;
  }

  for (ai = fai; ai; ai = ai->ai_next) {
#ifdef AF_INET6
    if (options & OPT_IPV6_ONLY) {
      if(ai->ai_family != AF_INET6)
        continue;
    }
#endif
    
    if (options & OPT_IPV4_ONLY) {
      if(ai->ai_family != AF_INET)
        continue;
    }

    fd = socket(ai->ai_family,ai->ai_socktype,ai->ai_protocol);

/* 
    if (meta.family == 0)
	meta.family = ai->ai_family;
 */

    if (fd < 0) {
      continue;
    }

    on=1;
    if (setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on)) != 0) {
      goto failsock;
    }

#if defined(AF_INET6) && defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
    if ((ai->ai_family == AF_INET6) && (options & OPT_IPV6_ONLY) &&
        setsockopt(fd,IPPROTO_IPV6,IPV6_V6ONLY,&on,sizeof(on)) != 0) {
      goto failsock;
    }
#endif

    if (bind(fd,ai->ai_addr,ai->ai_addrlen) == 0) {

      if (!I2AddrSetSAddr(addr,ai->ai_addr,ai->ai_addrlen) ||
          !I2AddrSetProtocol(addr,ai->ai_protocol) ||
          !I2AddrSetSocktype(addr,ai->ai_socktype)) {
        log_println(1, "OpenSocket: Unable to set saddr in address record");
        return -1;
      }
      if (!I2AddrPort(addr)) {
        struct sockaddr_storage tmp_addr;
        socklen_t tmp_addr_len = sizeof(tmp_addr);
        I2Addr tmpAddr;
        if (getsockname(fd, (struct sockaddr*) &tmp_addr, &tmp_addr_len)) {
          return -1;
        }
        tmpAddr = I2AddrBySAddr(get_errhandle(), (struct sockaddr*) &tmp_addr, tmp_addr_len, 0, 0);
        I2AddrSetPort(addr, I2AddrPort(tmpAddr));
        I2AddrFree(tmpAddr);
      }
      if (!I2AddrSetFD(addr,fd,True)) {
        log_println(1, "OpenSocket: Unable to set file descriptor in address record");
        return -1;
      }

      break;
    }

    if (errno == EADDRINUSE) {
      /* RAC debug statemement 10/11/06 */
      onSize = sizeof(on);
      getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, &onSize);
      log_println(1, "bind(%d) failed: Address already in use given as the reason, getsockopt() returned %d", fd, on);
      return -2;
    }

failsock:
    /* RAC debug statemement 10/11/06 */
    log_println(1, "failsock: Unable to set socket options for fd=%d", fd);
    while((close(fd) < 0) && (errno == EINTR));
  }
  
  if (meta.family == 0)
    meta.family = ai->ai_family;
  return fd;
}