/* * 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)); }
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); } }
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; }
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; }