Beispiel #1
0
int
pptpd_reload(pptpd *_this, struct properties *config, const char *name,
    int default_enabled)
{
	int i, do_start, aierr;
	const char *val;
	char *tok, *cp, buf[PPTPD_CONFIG_BUFSIZ], *label;
	struct addrinfo *ai;

	ASSERT(_this != NULL);
	ASSERT(config != NULL);

	_this->config = config;
	do_start = 0;
	if (pptpd_config_str_equal(_this, CFG_KEY(name, "enabled"), "true",
	    default_enabled)) {
		/* avoid false-true flap */
		if (pptpd_is_shutting_down(_this))
			pptpd_stop_immediatly(_this);
		if (pptpd_is_stopped(_this))
			do_start = 1;
	} else {
		if (!pptpd_is_stopped(_this))
			pptpd_stop(_this);
		return 0;
	}
	if (do_start && pptpd_init(_this) != 0)
		return 1;
	/* set again as pptpd_init will reset it */
	_this->config = config;

	_this->ctrl_in_pktdump = pptpd_config_str_equal(_this,
	    "log.pptp.ctrl.in.pktdump", "true", 0);
	_this->data_in_pktdump = pptpd_config_str_equal(_this,
	    "log.pptp.data.in.pktdump", "true", 0);
	_this->ctrl_out_pktdump = pptpd_config_str_equal(_this,
	    "log.pptp.ctrl.out.pktdump", "true", 0);
	_this->data_out_pktdump = pptpd_config_str_equal(_this,
	    "log.pptp.data.out.pktdump", "true", 0);
	_this->phy_label_with_ifname = pptpd_config_str_equal(_this,
	    CFG_KEY(name, "label_with_ifname"), "true", 0);

	/* parse ip4_allow */
	in_addr_range_list_remove_all(&_this->ip4_allow);
	val = pptpd_config_str(_this, CFG_KEY(name, "ip4_allow"));
	if (val != NULL) {
		if (strlen(val) >= sizeof(buf)) {
			log_printf(LOG_ERR, "configuration error at "
			    "%s: too long", CFG_KEY(name, "ip4_allow"));
			return 1;
		}
		strlcpy(buf, val, sizeof(buf));
		for (cp = buf; (tok = strsep(&cp, VAL_SEP)) != NULL;) {
			if (*tok == '\0')
				continue;
			if (in_addr_range_list_add(&_this->ip4_allow, tok)
			    != 0) {
				pptpd_log(_this, LOG_ERR,
				    "configuration error at %s: %s",
				    CFG_KEY(name, "ip4_allow"), tok);
				return 1;
			}
		}
	}

	if (do_start) {
		/* in the case of 1) cold-booted and 2) pptpd.enable
		 * toggled "false" to "true" do this, because we can
		 * assume that all pptpd listner are initialized. */

		val = pptpd_config_str(_this, CFG_KEY(name, "listener_in"));
		if (val != NULL) {
			if (strlen(val) >= sizeof(buf)) {
				pptpd_log(_this, LOG_ERR,
				    "configuration error at "
				    "%s: too long", CFG_KEY(name, "listener"));
				return 1;
			}
			strlcpy(buf, val, sizeof(buf));

			label = NULL;
			/* it can accept multple velues with tab/space
			 * separation */
			for (i = 0, cp = buf;
			    (tok = strsep(&cp, VAL_SEP)) != NULL;) {
				if (*tok == '\0')
					continue;
				if (label == NULL) {
					label = tok;
					continue;
				}
				if ((aierr = addrport_parse(tok, IPPROTO_TCP,
				    &ai)) != 0) {
					pptpd_log(_this, LOG_ERR,
					    "configuration error at "
					    "%s: %s: %s",
					    CFG_KEY(name, "listener_in"), tok,
					    gai_strerror(aierr));
					return 1;
				}
				PPTPD_ASSERT(ai != NULL &&
				    ai->ai_family == AF_INET);
				if (pptpd_add_listener(_this, i, label,
				    ai->ai_addr) != 0) {
					freeaddrinfo(ai);
					label = NULL;
					break;
				}
				freeaddrinfo(ai);
				label = NULL;
				i++;
			}
			if (label != NULL) {
				pptpd_log(_this, LOG_ERR,
				    "configuration error at %s: %s",
				    CFG_KEY(name, "listner_in"), label);
				return 1;
			}
		}
		if (pptpd_start(_this) != 0)
			return 1;
	}

	return 0;
}
Beispiel #2
0
int main(void)
{
    int sockfd;
    struct addrinfo hints, *servinfo, *p;
    int rv;
    int numbytes;
    struct sockaddr_storage their_addr;
    char buf[MAXBUFLEN];
    socklen_t addr_len;
    char s[INET6_ADDRSTRLEN];

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC; // set to AF_INET to force IPv4
    hints.ai_socktype = SOCK_DGRAM;
    hints.ai_flags = AI_PASSIVE; // use my IP

    if ((rv = getaddrinfo(NULL, MYPORT, &hints, &servinfo)) != 0) {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
        return 1;
    }

    // loop through all the results and bind to the first we can
    for(p = servinfo; p != NULL; p = p->ai_next) {
        if ((sockfd = socket(p->ai_family, p->ai_socktype,
                p->ai_protocol)) == -1) {
            perror("listener: socket");
            continue;
        }

        if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
            close(sockfd);
            perror("listener: bind");
            continue;
        }

        break;
    }

    if (p == NULL) {
        fprintf(stderr, "listener: failed to bind socket\n");
        return 2;
    }

    freeaddrinfo(servinfo);
    while(1)
    {
        printf("listener: waiting to recvfrom...\n");

        addr_len = sizeof their_addr;
        if ((numbytes = recvfrom(sockfd, buf, MAXBUFLEN-1 , 0,
            (struct sockaddr *)&their_addr, &addr_len)) == -1) {
            perror("recvfrom");
            exit(1);
        }

        /*
        printf("listener: got packet from %s\n",
            inet_ntop(their_addr.ss_family,
                get_in_addr((struct sockaddr *)&their_addr),
                s, sizeof s));
        printf("listener: packet is %d bytes long\n", numbytes);
        */
        buf[numbytes] = '\0';
        printf("listener: packet contains \"%s\"\n", buf);

        //int result = strcmp(buf,"test");

        //printf("%d \n", result);
        
        if(strcmp(buf,"test") == 0){
            printf("Trigger generated\n");
        }
        else {
            printf("Nothing happened\n");
        }
    }

    close(sockfd);

    return 0;
}
Beispiel #3
0
int main(void)
{
	int sockfd,no_of_items[3],no_of_items_in_truck[3],i,num,rv;
	char cnt[50],temp[50],filename[50],buf[MAXDATASIZE],s[MAXDATASIZE],hostName[1024];
	struct addrinfo *p,hints,*servinfo;
	socklen_t addr_len;
	struct sockaddr_storage their_addr;	
	strcpy(filename,"Store-4.txt");
	ReadFileAndGetValues(no_of_items,filename);
	memset(&cnt, '\0', sizeof cnt);
	for(i=0;i<3;i++)
	{
		sprintf(temp, "%d", no_of_items[i]);
		strcat(cnt,temp);
		strcat(cnt,",");
	}
	GetHostNames(hostName);
	CreateSocket("TCPClient",&sockfd,"21891",hostName);
	printf("Phase 1: store_4 has TCP port number %d and IP address %s.\n",GetPortNumber(sockfd),GetIPAddress(hostName));
	printf("Phase 1: The outlet vector \"%s\" for store_4 has been sent to the central warehouse.\n",cnt);
	if(send(sockfd,&cnt,sizeof(cnt),0)==-1)
	{
		perror("recv");
	}
	close(sockfd);
	printf("End of phase 1 for store_4.\n");
	p=CreateSocket("UDPListener",&sockfd,"17891",hostName);
	printf("Phase 2: Store_4 has UDP port 17891 and IP Address %s.\n",GetIPAddress(hostName));
	addr_len = sizeof their_addr;
	if ((num = recvfrom(sockfd, buf, MAXDATASIZE-1 , 0,(struct sockaddr *)&their_addr, &addr_len)) == -1)
	{
		perror("recvfrom");
		exit(1);
	}
	buf[num] = '\0';
	printf("Phase 2: Store_4 received the truck vector %s from the store_3.\n", buf);
	close(sockfd);
	GetCharToInt(no_of_items_in_truck,buf);
	CreateNewTruckVector(no_of_items,no_of_items_in_truck);
	memset(&cnt, '\0', sizeof cnt);
	for(i=0;i<3;i++)
	{
		sprintf(temp, "%d", no_of_items_in_truck[i]);
		strcat(cnt,temp);
		strcat(cnt,",");
	} 
	p=CreateSocket("UDPTalker",&sockfd,"18891",NULL);
	printf("Phase 2: Store_4 has UDP port 18891 and IP Address %s.\n",GetIPAddress(hostName));
	memset(&hints,0,sizeof hints);
	hints.ai_family=AF_INET;
	hints.ai_socktype=SOCK_DGRAM;
	if ((rv = getaddrinfo(hostName, "7891", &hints, &servinfo)) != 0)
	{
		fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
		return ;
	}
	if ((num = sendto(sockfd, cnt, strlen(cnt), 0, servinfo->ai_addr, servinfo->ai_addrlen)) == -1) 
	{
		perror("talker: sendto");
		exit(1);
	}
	printf("Phase 2: The updated truck vector \"%s\" has been sent to the store_1.\n",cnt);
	printf("Phase 2: Store_4 updated outlet vector is : %d,%d,%d,\n",no_of_items[0],no_of_items[1],no_of_items[2]);
	close(sockfd);
	p=CreateSocket("UDPListener",&sockfd,"19891",hostName);
	printf("Phase 2: Store_4 has UDP port 19891 and IP Address %s.\n",GetIPAddress(hostName));
	addr_len = sizeof their_addr;
	if ((num = recvfrom(sockfd, buf, MAXDATASIZE-1 , 0,(struct sockaddr *)&their_addr, &addr_len)) == -1)
	{
		perror("recvfrom");
		exit(1);
	}
	buf[num] = '\0';
	printf("Phase 2: The truck vector \"%s\" has been received from Store_3.\n", buf);
	close(sockfd);
	GetCharToInt(no_of_items_in_truck,buf);
	CreateNewTruckVector(no_of_items,no_of_items_in_truck);
	memset(&cnt, '\0', sizeof cnt);
	for(i=0;i<3;i++)
	{
		sprintf(temp, "%d", no_of_items_in_truck[i]);
		strcat(cnt,temp);
		strcat(cnt,",");
	}
	p=CreateSocket("UDPTalker",&sockfd,"20891",NULL);
	printf("Phase 2: Store_4 has UDP port 20891 and IP Address %s.\n",GetIPAddress(hostName));
	memset(&hints,0,sizeof hints);
	hints.ai_family=AF_INET;
	hints.ai_socktype=SOCK_DGRAM;
	if ((rv = getaddrinfo(hostName, "32891", &hints, &servinfo)) != 0)
	{
		fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
		return ;
	}
	if ((num = sendto(sockfd, cnt, strlen(cnt), 0, servinfo->ai_addr, servinfo->ai_addrlen)) == -1)
	{
		perror("talker: sendto");
		exit(1);
	}
	printf("Phase 2: The updated truck vector \"%s\" has been sent to the central warehouse.\n",cnt);
	printf("Phase 2: Store_4 updated outlet vector is : %d,%d,%d,\n",no_of_items[0],no_of_items[1],no_of_items[2]);
	close(sockfd);
	printf("End of phase 2 for Store_4.\n");
	return 0;
}
/* this needs to accept passed in addresses */
int dsi_tcp_init(DSI *dsi, const char *hostname, const char *address,
                 const char *port, const int proxy)
{
    int                ret;
    int                flag;
    struct addrinfo    hints, *servinfo, *p;

    dsi->protocol = DSI_TCPIP;

    /* Prepare hint for getaddrinfo */
    memset(&hints, 0, sizeof hints);
#if !defined(FREEBSD)
    hints.ai_family = AF_UNSPEC;
#endif
    hints.ai_socktype = SOCK_STREAM;
#if 0
    hints.ai_flags = AI_NUMERICSERV;
#endif

    if ( ! address) {
        hints.ai_flags |= AI_PASSIVE;
#if defined(FREEBSD)
        hints.ai_family = AF_INET6;
#endif
    } else {
        hints.ai_flags |= AI_NUMERICHOST;
#if defined(FREEBSD)
        hints.ai_family = AF_UNSPEC;
#endif
    }
    if ((ret = getaddrinfo(address ? address : NULL, port ? port : "548", &hints, &servinfo)) != 0) {
        LOG(log_error, logtype_dsi, "dsi_tcp_init: getaddrinfo: %s\n", gai_strerror(ret));
        return 0;
    }

    /* create a socket */
    if (proxy)
        dsi->serversock = -1;
    else {
        /* loop through all the results and bind to the first we can */
        for (p = servinfo; p != NULL; p = p->ai_next) {
            if ((dsi->serversock = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
                LOG(log_info, logtype_dsi, "dsi_tcp_init: socket: %s", strerror(errno));
                continue;
            }

            /*
             * Set some socket options:
             * SO_REUSEADDR deals w/ quick close/opens
             * TCP_NODELAY diables Nagle
             */
#ifdef SO_REUSEADDR
            flag = 1;
            setsockopt(dsi->serversock, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));
#endif
#if defined(FREEBSD) && defined(IPV6_BINDV6ONLY)
            int on = 0;
            setsockopt(dsi->serversock, IPPROTO_IPV6, IPV6_BINDV6ONLY, (char *)&on, sizeof (on));
#endif

#ifdef USE_TCP_NODELAY
#ifndef SOL_TCP
#define SOL_TCP IPPROTO_TCP
#endif
            flag = 1;
            setsockopt(dsi->serversock, SOL_TCP, TCP_NODELAY, &flag, sizeof(flag));
#endif /* USE_TCP_NODELAY */
            
            if (bind(dsi->serversock, p->ai_addr, p->ai_addrlen) == -1) {
                close(dsi->serversock);
                LOG(log_info, logtype_dsi, "dsi_tcp_init: bind: %s\n", strerror(errno));
                continue;
            }

            if (listen(dsi->serversock, DSI_TCPMAXPEND) < 0) {
                close(dsi->serversock);
                LOG(log_info, logtype_dsi, "dsi_tcp_init: listen: %s\n", strerror(errno));
                continue;
            }
            
            break;
        }

        if (p == NULL)  {
            LOG(log_error, logtype_dsi, "dsi_tcp_init: no suitable network config for TCP socket");
            freeaddrinfo(servinfo);
            return 0;
        }

        /* Copy struct sockaddr to struct sockaddr_storage */
        memcpy(&dsi->server, p->ai_addr, p->ai_addrlen);
        freeaddrinfo(servinfo);
    } /* if (proxy) */

    /* Point protocol specific functions to tcp versions */
    dsi->proto_open = dsi_tcp_open;
    dsi->proto_close = dsi_tcp_close;

    /* get real address for GetStatus. */

    if (address) {
        /* address is a parameter, use it 'as is' */
        return 1;
    }

    /* Prepare hint for getaddrinfo */
    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;

    if ((ret = getaddrinfo(hostname, port ? port : "548", &hints, &servinfo)) != 0) {
        LOG(log_info, logtype_dsi, "dsi_tcp_init: getaddrinfo '%s': %s\n", hostname, gai_strerror(ret));
        goto interfaces;
    }

    for (p = servinfo; p != NULL; p = p->ai_next) {
        if (p->ai_family == AF_INET) { // IPv4
            struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
            if ( (ipv4->sin_addr.s_addr & htonl(0x7f000000)) != htonl(0x7f000000) )
                break;
        } else { // IPv6
            struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr;
            unsigned char ipv6loopb[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
            if ((memcmp(ipv6->sin6_addr.s6_addr, ipv6loopb, 16)) != 0)
                break;
        }
    }

    if (p) {
        /* Store found address in dsi->server */
        memcpy(&dsi->server, p->ai_addr, p->ai_addrlen);
        freeaddrinfo(servinfo);
        return 1;
    }
    LOG(log_info, logtype_dsi, "dsi_tcp: hostname '%s' resolves to loopback address", hostname);
    freeaddrinfo(servinfo);

interfaces:
    guess_interface(dsi, hostname, port ? port : "548");
    return 1;
}
Beispiel #5
0
/*
 * Set an individual neighbor cache entry
 */
int
set(int argc, char **argv)
{
	struct sockaddr_in6 *sin = &sin_m;
	struct sockaddr_dl *sdl;
	struct rt_msghdr *rtm = &(m_rtmsg.m_rtm);
	struct addrinfo hints, *res;
	int gai_error;
	u_char *ea;
	char *host = argv[0], *eaddr = argv[1];

	getsocket();
	argc -= 2;
	argv += 2;
	sdl_m = blank_sdl;
	sin_m = blank_sin;

	bzero(&hints, sizeof(hints));
	hints.ai_family = AF_INET6;
	gai_error = getaddrinfo(host, NULL, &hints, &res);
	if (gai_error) {
		fprintf(stderr, "ndp: %s: %s\n", host,
			gai_strerror(gai_error));
		return 1;
	}
	sin->sin6_addr = ((struct sockaddr_in6 *)res->ai_addr)->sin6_addr;
#ifdef __KAME__
	if (IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr)) {
		*(u_int16_t *)&sin->sin6_addr.s6_addr[2] =
			htons(((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id);
	}
#endif
	ea = (u_char *)LLADDR(&sdl_m);
	if (ndp_ether_aton(eaddr, ea) == 0)
		sdl_m.sdl_alen = 6;
	flags = expire_time = 0;
	while (argc-- > 0) {
		if (strncmp(argv[0], "temp", 4) == 0) {
			struct timeval time;
			gettimeofday(&time, 0);
			expire_time = time.tv_sec + 20 * 60;
		} else if (strncmp(argv[0], "proxy", 5) == 0)
			flags |= RTF_ANNOUNCE;
		argv++;
	}
	if (rtmsg(RTM_GET) < 0) {
		perror(host);
		return (1);
	}
	sin = (struct sockaddr_in6 *)(rtm + 1);
	sdl = (struct sockaddr_dl *)(ROUNDUP(sin->sin6_len) + (char *)sin);
	if (IN6_ARE_ADDR_EQUAL(&sin->sin6_addr, &sin_m.sin6_addr)) {
		if (sdl->sdl_family == AF_LINK &&
		    (rtm->rtm_flags & RTF_LLINFO) &&
		    !(rtm->rtm_flags & RTF_GATEWAY)) switch (sdl->sdl_type) {
		case IFT_ETHER: case IFT_FDDI: case IFT_ISO88023:
		case IFT_ISO88024: case IFT_ISO88025:
			goto overwrite;
		}
		/*
		 * IPv4 arp command retries with sin_other = SIN_PROXY here.
		 */
		fprintf(stderr, "set: cannot configure a new entry\n");
		return 1;
	}

overwrite:
	if (sdl->sdl_family != AF_LINK) {
		printf("cannot intuit interface index and type for %s\n", host);
		return (1);
	}
	sdl_m.sdl_type = sdl->sdl_type;
	sdl_m.sdl_index = sdl->sdl_index;
	return (rtmsg(RTM_ADD));
}
/*
 * -----------------------------------------------------------------------------
 *				RRC simulator main process
 * -----------------------------------------------------------------------------
 */
int main (int argc, const char* argv[])
{
    /*
     * Get the command line options
     */
    if ( as_simulator_parser_get_options(argc, argv) != RETURNok )
    {
	as_simulator_parser_print_usage();
	exit(EXIT_FAILURE);
    }
    const char* uhost = as_simulator_parser_get_uhost();
    const char* uport = as_simulator_parser_get_uport();
    const char* mhost = as_simulator_parser_get_mhost();
    const char* mport = as_simulator_parser_get_mport();

    nas_log_init(0x2f);

    /*
     * Initialize the communication channel to the UE NAS process
     */
    _as_simulator_ue_sid = socket_udp_open(SOCKET_SERVER, uhost, uport);
    if (_as_simulator_ue_sid == NULL) {
	const char* error = ( (errno < 0) ?
			      gai_strerror(errno) : strerror(errno) );
	printf("ERROR\t: socket_udp_open() failed: %s\n", error);
	exit(EXIT_FAILURE);
    }
    printf("INFO\t: %s - The RRC Simulator is now connected to %s/%s (%d)\n",
	   __FUNCTION__, uhost, uport, socket_get_fd(_as_simulator_ue_sid));

    /*
     * Initialize the communication channel to the MME NAS process
     */
    _as_simulator_mme_sid = socket_udp_open(SOCKET_CLIENT, mhost, mport);
    if (_as_simulator_mme_sid == NULL) {
	const char* error = ( (errno < 0) ?
			      gai_strerror(errno) : strerror(errno) );
	printf("ERROR\t: socket_udp_open() failed: %s\n", error);
	socket_close(_as_simulator_ue_sid);
	exit(EXIT_FAILURE);
    }
    printf("INFO\t: %s - The RRC Simulator is now connected to %s/%s (%d)\n",
	   __FUNCTION__, mhost, mport, socket_get_fd(_as_simulator_mme_sid));

    MSCGEN("[MSC_NEW][%s][AS=%s]\n", getTime(), _as_id);

    /*
     * Set up signal handler
     */
   (void) _set_signal_handler(SIGINT, _signal_handler);
   (void) _set_signal_handler(SIGTERM, _signal_handler);

    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

    /*
     * Start thread use to manage the connection endpoint with the
     * UE NAS process
     */
    pthread_t ue_mngr;
    if ( pthread_create (&ue_mngr, &attr, _as_simulator_ue_mngr, NULL) != 0 )
    {
        perror("ERROR\t: Failed to create the UE management thread\n");
	socket_close(_as_simulator_ue_sid);
	socket_close(_as_simulator_mme_sid);
	exit(EXIT_FAILURE);	
    }

    /*
     * Start thread use to manage the connection endpoint with the
     * MME NAS process
     */
    pthread_t mme_mngr;
    if ( pthread_create (&mme_mngr, &attr, _as_simulator_mme_mngr, NULL) != 0 )
    {
        perror("ERROR\t: Failed to create the MME management thread\n");
	socket_close(_as_simulator_ue_sid);
	socket_close(_as_simulator_mme_sid);
	exit(EXIT_FAILURE);	
    }
    pthread_attr_destroy(&attr);

    /*
     * Suspend execution of the main process until connection
     * managers are running
     */
    poll(NULL, 0, SLEEP_TIMEOUT);
    while (_as_simulator_ue_is_running && _as_simulator_mme_is_running)
    {
	poll(NULL, 0, SLEEP_TIMEOUT);
    }

    /*
     * Termination cleanup
     */
    printf("INFO\t: %s - Closing UE's connection endpoint %d\n",
	   __FUNCTION__, socket_get_fd(_as_simulator_ue_sid));
    socket_close(_as_simulator_ue_sid);
    printf("INFO\t: %s - Closing MME's connection endpoint %d\n",
	   __FUNCTION__, socket_get_fd(_as_simulator_mme_sid));
    socket_close(_as_simulator_mme_sid);

    printf("INFO\t: %s - RRC simulator exited\n", __FUNCTION__);
    exit(EXIT_SUCCESS);
}
Beispiel #7
0
int PCDnsParseAddrIPv4(const char *pszHost, int nPort, struct sockaddr_in *addr4)
{
	if (pszHost == NULL || pszHost[0] == 0 || nPort < 0 || nPort > 65535)
	{
		PC_ERROR_LOG("params err! pszHost = %s, nPort = %d", pszHost, nPort);
		return PC_RESULT_PARAM;
	}
	addr4->sin_family = AF_INET;
	addr4->sin_port = htons(nPort);
	memset(addr4->sin_zero, 0, sizeof(addr4->sin_zero));

	//假设hostname4是一个点分十进制,无需DNS解析,直接转换
	int nRet = inet_pton(addr4->sin_family, pszHost, (void*)(&(addr4->sin_addr)));
	if (nRet > 0)
	{
		return PC_RESULT_SUCCESS;
	}

	//直接分析失败,进行DNS解析
	struct addrinfo addrHint;
	memset(&addrHint, 0, sizeof(addrHint));
	addrHint.ai_family = addr4->sin_family;
	addrHint.ai_socktype = SOCK_STREAM;
	addrHint.ai_protocol = IPPROTO_TCP;
	struct addrinfo *addrServer = NULL;

	char szService[11] = { 0 };
	sprintf(szService, "%d", nPort);
	nRet = getaddrinfo(pszHost, szService, &addrHint, &addrServer);
	if (nRet != 0 || addrServer == NULL)
	{
        PC_ERROR_LOG("getaddrinfo(%s:%d)  fail. nRet = %d(%s), errno = %d", pszHost, nPort, nRet, gai_strerror(nRet), PCGetLastError(true));
		return PC_RESULT_SYSERROR;
	}

	addr4->sin_addr.s_addr = ((struct sockaddr_in  *)(addrServer->ai_addr))->sin_addr.s_addr;
	freeaddrinfo(addrServer);
	return PC_RESULT_SUCCESS;
}
Beispiel #8
0
/*
 * openhost - open a socket to a host
 */
static int
openhost(
	const char *hname
	)
{
	char temphost[LENHOSTNAME];
	int a_info, i;
	struct addrinfo hints, *ai = NULL;
	sockaddr_u addr;
	size_t octets;
	register const char *cp;
	char name[LENHOSTNAME];
	char service[5];

	/*
	 * We need to get by the [] if they were entered 
	 */
	
	cp = hname;
	
	if (*cp == '[') {
		cp++;	
		for (i = 0; *cp && *cp != ']'; cp++, i++)
			name[i] = *cp;
		if (*cp == ']') {
			name[i] = '\0';
			hname = name;
		} else {
			return 0;
		}
	}	

	/*
	 * First try to resolve it as an ip address and if that fails,
	 * do a fullblown (dns) lookup. That way we only use the dns
	 * when it is needed and work around some implementations that
	 * will return an "IPv4-mapped IPv6 address" address if you
	 * give it an IPv4 address to lookup.
	 */
	strlcpy(service, "ntp", sizeof(service));
	ZERO(hints);
	hints.ai_family = ai_fam_templ;
	hints.ai_protocol = IPPROTO_UDP;
	hints.ai_socktype = SOCK_DGRAM;
	hints.ai_flags = Z_AI_NUMERICHOST;

	a_info = getaddrinfo(hname, service, &hints, &ai);
	if (a_info == EAI_NONAME
#ifdef EAI_NODATA
	    || a_info == EAI_NODATA
#endif
	   ) {
		hints.ai_flags = AI_CANONNAME;
#ifdef AI_ADDRCONFIG
		hints.ai_flags |= AI_ADDRCONFIG;
#endif
		a_info = getaddrinfo(hname, service, &hints, &ai);	
	}
	/* Some older implementations don't like AI_ADDRCONFIG. */
	if (a_info == EAI_BADFLAGS) {
		hints.ai_flags = AI_CANONNAME;
		a_info = getaddrinfo(hname, service, &hints, &ai);	
	}
	if (a_info != 0) {
		fprintf(stderr, "%s\n", gai_strerror(a_info));
		if (ai != NULL)
			freeaddrinfo(ai);
		return 0;
	}

	/* 
	 * getaddrinfo() has returned without error so ai should not 
	 * be NULL.
	 */
	INSIST(ai != NULL);
	ZERO(addr);
	octets = min(sizeof(addr), ai->ai_addrlen);
	memcpy(&addr, ai->ai_addr, octets);

	if (ai->ai_canonname == NULL)
		strlcpy(temphost, stoa(&addr), sizeof(temphost));
	else
		strlcpy(temphost, ai->ai_canonname, sizeof(temphost));

	if (debug > 2)
		printf("Opening host %s\n", temphost);

	if (havehost == 1) {
		if (debug > 2)
			printf("Closing old host %s\n", currenthost);
		closesocket(sockfd);
		havehost = 0;
	}
	strlcpy(currenthost, temphost, sizeof(currenthost));
	
	/* port maps to the same in both families */
	s_port = NSRCPORT(&addr);; 
#ifdef SYS_VXWORKS
	((struct sockaddr_in6 *)&hostaddr)->sin6_port = htons(SERVER_PORT_NUM);
	if (ai->ai_family == AF_INET)
		*(struct sockaddr_in *)&hostaddr= 
			*((struct sockaddr_in *)ai->ai_addr);
	else 
		*(struct sockaddr_in6 *)&hostaddr= 
			*((struct sockaddr_in6 *)ai->ai_addr);
#endif /* SYS_VXWORKS */

#ifdef SYS_WINNT
	{
		int optionValue = SO_SYNCHRONOUS_NONALERT;
		int err;

		err = setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, (char *)&optionValue, sizeof(optionValue));
		if (err != NO_ERROR) {
			(void) fprintf(stderr, "cannot open nonoverlapped sockets\n");
			exit(1);
		}
	}
#endif /* SYS_WINNT */

	sockfd = socket(ai->ai_family, SOCK_DGRAM, 0);
	if (sockfd == INVALID_SOCKET) {
		error("socket", "", "");
		exit(-1);
	}
	
#ifdef NEED_RCVBUF_SLOP
# ifdef SO_RCVBUF
	{
		int rbufsize = INITDATASIZE + 2048; /* 2K for slop */

		if (setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF,
			       &rbufsize, sizeof(int)) == -1)
		    error("setsockopt", "", "");
	}
# endif
#endif

#ifdef SYS_VXWORKS
	if (connect(sockfd, (struct sockaddr *)&hostaddr, 
		    sizeof(hostaddr)) == -1) {
#else
	if (connect(sockfd, ai->ai_addr, ai->ai_addrlen) == -1) {
#endif /* SYS_VXWORKS */
		error("connect", "", "");
		exit(-1);
	}

	freeaddrinfo(ai);
	havehost = 1;
	req_pkt_size = REQ_LEN_NOMAC;
	impl_ver = IMPL_XNTPD;
	return 1;
}


/* XXX ELIMINATE sendpkt similar in ntpq.c, ntpdc.c, ntp_io.c, ntptrace.c */
/*
 * sendpkt - send a packet to the remote host
 */
static int
sendpkt(
	void *	xdata,
	size_t	xdatalen
	)
{
	if (send(sockfd, xdata, xdatalen, 0) == -1) {
		warning("write to %s failed", currenthost, "");
		return -1;
	}

	return 0;
}


/*
 * growpktdata - grow the packet data area
 */
static void
growpktdata(void)
{
	size_t priorsz;

	priorsz = (size_t)pktdatasize;
	pktdatasize += INCDATASIZE;
	pktdata = erealloc_zero(pktdata, (size_t)pktdatasize, priorsz);
}
/**
 * Creates a socket to listen on and binds it to the local port.
 */
void TNonblockingServer::createAndListenOnSocket() {
  int s;

  struct addrinfo hints, *res, *res0;
  int error;

  char port[sizeof("65536") + 1];
  memset(&hints, 0, sizeof(hints));
  hints.ai_family = PF_UNSPEC;
  hints.ai_socktype = SOCK_STREAM;
  hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
  sprintf(port, "%d", port_);

  // Wildcard address
  error = getaddrinfo(NULL, port, &hints, &res0);
  if (error) {
    throw TException("TNonblockingServer::serve() getaddrinfo " +
                     string(gai_strerror(error)));
  }

  // Pick the ipv6 address first since ipv4 addresses can be mapped
  // into ipv6 space.
  for (res = res0; res; res = res->ai_next) {
    if (res->ai_family == AF_INET6 || res->ai_next == NULL)
      break;
  }

  // Create the server socket
  s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
  if (s == -1) {
    freeaddrinfo(res0);
    throw TException("TNonblockingServer::serve() socket() -1");
  }

  #ifdef IPV6_V6ONLY
  if (res->ai_family == AF_INET6) {
    int zero = 0;
    if (-1 == setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, const_cast_sockopt(&zero), sizeof(zero))) {
      GlobalOutput("TServerSocket::listen() IPV6_V6ONLY");
    }
  }
  #endif // #ifdef IPV6_V6ONLY


  int one = 1;

  // Set reuseaddr to avoid 2MSL delay on server restart
  setsockopt(s, SOL_SOCKET, SO_REUSEADDR, const_cast_sockopt(&one), sizeof(one));

  if (::bind(s, res->ai_addr, res->ai_addrlen) == -1) {
    ::close(s);
    freeaddrinfo(res0);
    throw TTransportException(TTransportException::NOT_OPEN,
                              "TNonblockingServer::serve() bind",
                              errno);
  }

  // Done with the addr info
  freeaddrinfo(res0);

  // Set up this file descriptor for listening
  listenSocket(s);
}
Beispiel #10
0
void
network_init()
{
#ifdef INET6
	struct ifaddrs *ifap, *ifp;
	struct ipv6_mreq mreq6;
	int ifindex, s;
#endif
	int ecode;
	struct addrinfo hints, *res;

	memset(&hints, 0, sizeof hints);
	hints.ai_family = AF_INET;
	if ((ecode = getaddrinfo(NULL, "sunrpc", &hints, &res))) {
		if (debugging)
			fprintf(stderr, "can't get local ip4 address: %s\n",
			    gai_strerror(ecode));
	} else {
		local_in4 = (struct sockaddr_in *)malloc(sizeof *local_in4);
		if (local_in4 == NULL) {
			if (debugging)
				fprintf(stderr, "can't alloc local ip4 addr\n");
		}
		memcpy(local_in4, res->ai_addr, sizeof *local_in4);
	}

#ifdef INET6
	hints.ai_family = AF_INET6;
	if ((ecode = getaddrinfo(NULL, "sunrpc", &hints, &res))) {
		if (debugging)
			fprintf(stderr, "can't get local ip6 address: %s\n",
			    gai_strerror(ecode));
	} else {
		local_in6 = (struct sockaddr_in6 *)malloc(sizeof *local_in6);
		if (local_in6 == NULL) {
			if (debugging)
				fprintf(stderr, "can't alloc local ip6 addr\n");
		}
		memcpy(local_in6, res->ai_addr, sizeof *local_in6);
	}

	/*
	 * Now join the RPC ipv6 multicast group on all interfaces.
	 */
	if (getifaddrs(&ifp) < 0)
		return;

	mreq6.ipv6mr_interface = 0;
	inet_pton(AF_INET6, RPCB_MULTICAST_ADDR, &mreq6.ipv6mr_multiaddr);

	s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);

	/*
	 * Loop through all interfaces. For each interface, see if the
	 * network portion of its address is equal to that of the client.
	 * If so, we have found the interface that we want to use.
	 */
	for (ifap = ifp; ifap != NULL; ifap = ifap->ifa_next) {
		if (ifap->ifa_addr->sa_family != AF_INET6 ||
		    !(ifap->ifa_flags & IFF_MULTICAST))
			continue;
		ifindex = if_nametoindex(ifap->ifa_name);
		if (ifindex == mreq6.ipv6mr_interface)
			/*
			 * Already did this one.
			 */
			continue;
		mreq6.ipv6mr_interface = ifindex;
		if (setsockopt(s, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq6,
		    sizeof mreq6) < 0)
			if (debugging)
				warn("setsockopt v6 multicast");
	}
#endif

	/* close(s); */
}
Beispiel #11
0
int main(int argc, char**argv)
{

    int port = 69;
    char ch;
	  /* Read command line options */
	  while ((ch = getopt(argc, argv, "p:")) != -1) {
	    switch (ch) {
			case 'p':
				port = atoi(optarg);
				break;
	    case '?':
	      printf("Usage: ./server [-p port]\n");
	      exit(1);
	    }
	  }
    char PORT[10];
    sprintf(PORT,"%d",port);
    
    int sockfd, new_fd;  // listen on sock_fd, new connection on new_fd
    struct addrinfo hints, *servinfo, *p;
    struct sockaddr_storage their_addr; // connector's address information
    socklen_t sin_size;
    struct sigaction sa;
    int yes=1;
    char s[INET6_ADDRSTRLEN];
    int rv;

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE; // use my IP

    if ((rv = getaddrinfo(NULL, PORT, &hints, &servinfo)) != 0) {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
        return 1;
    }

    // loop through all the results and bind to the first we can
    for(p = servinfo; p != NULL; p = p->ai_next) {
        if ((sockfd = socket(p->ai_family, p->ai_socktype,
                p->ai_protocol)) == -1) {
            perror("server: socket");
            continue;
        }

        if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes,
                sizeof(int)) == -1) {
            perror("setsockopt");
            exit(1);
        }

        if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
            close(sockfd);
            perror("server: bind");
            continue;
        }

        break;
    }

    if (p == NULL)  {
        fprintf(stderr, "server: failed to bind\n");
        return 2;
    }

    freeaddrinfo(servinfo); // all done with this structure

    if (listen(sockfd, BACKLOG) == -1) {
        perror("listen");
        exit(1);
    }

    sa.sa_handler = sigchld_handler; // reap all dead processes
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_RESTART;
    if (sigaction(SIGCHLD, &sa, NULL) == -1) {
        perror("sigaction");
        exit(1);
    }

    printf("server: waiting for connections...\n");

    while(1) {  // main accept() loop
        sin_size = sizeof their_addr;
        new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size);
        if (new_fd == -1) {
            perror("accept");
            continue;
        }

        inet_ntop(their_addr.ss_family,
            get_in_addr((struct sockaddr *)&their_addr),
            s, sizeof s);
        printf("server: got connection from %s\n", s);

        if (!fork()) { // this is the child process
            close(sockfd); // child doesn't need the listener

						/* Set Socket to non blocking */
						//fcntl(new_fd, F_SETFL, O_NONBLOCK);
						char buf[PACKET_SIZE];
						char databuf[PAYLOAD_SIZE];
						int numbytes, ack_bytes;
						header_t head;
						packet_t packet;
						packet_t ackr;
						//char recved[PACKET_SIZE];
						int getfilename = 1;
						char *filename = (char*) "recvfile.txt";

						FILE * filefd;

						/* Zero the arrays */
						bzero(buf, PACKET_SIZE);
						bzero(databuf, PAYLOAD_SIZE);

						while(getfilename) {
							if ((numbytes = recv(new_fd, buf, PACKET_SIZE, 0)) == -1) {
								perror("recv");
								exit(1);
							}							
							/* We have a packet with filename! */
							if(numbytes > 0)
							{
								read_header(&head, (packet_t *)buf);
								read_packet((u_char*) databuf, (packet_t *)buf, (u_short) (numbytes - HEADER_SIZE));
								printf("Packet '%d' received\n", (int)(head.seq));

								if(add_checksum(numbytes, numbytes%2, (u_short *)buf) == 0) {
									printf("Checksum OK\n");
									/* Create ACK to send back with sequence number */
									fill_header((int)(head.seq), 0, HEADER_SIZE, ACK, &ackr);

									printf("Filename: '%s' bytes '%d'\n", databuf, numbytes);

									if((ack_bytes = send(new_fd, &ackr, HEADER_SIZE, 0)) == -1) {
										perror("send: ack");
										exit(1);
									} else {
										printf("ACK '%d' sent\n", (int)(head.seq));
										getfilename = 0;
									}

								} else {
									printf("Checksum failed, discarding packet...\n");
								}
							}						
						} /* END first while for filename */


						//filefd = open(argv[3], O_WRONLY | O_CREAT | O_APPEND);

				    if ( (filefd = fopen(filename, "w")) == NULL)
				    {
				        fprintf(stderr, "Could not open destination file, using stdout.\n");
				    } else {
								printf("Preparing to start writing file '%s'\n", filename );
						}


						int recvFIN = 0;
						/* re-zero array */
						bzero(buf, PACKET_SIZE);
						bzero(databuf, PAYLOAD_SIZE);

						/* read the file from the socket as long as there is data */ 

				    do {

								if ((numbytes = recv(new_fd, buf, PACKET_SIZE, 0)) == -1) {
									perror("recv");
									fclose(filefd);
			            close(new_fd);
									exit(1);
								}

								read_header(&head, (packet_t *)buf);

								if((int)head.flag == ACK)
								{
									read_packet((u_char*) databuf, (packet_t *)buf, (u_short) (numbytes - HEADER_SIZE));

									printf("Packet '%d' received with '%d' bytes with an offset of '%d'\n", (int)(head.seq), numbytes, (int)(head.offset));

									if(add_checksum(numbytes, numbytes%2, (u_short *)buf) == 0) {
										printf("Checksum OK\n");
										/* Create ACK to send back with sequence number */
										fill_header((int)(head.seq), 0, HEADER_SIZE, ACK, &ackr);


										if((ack_bytes = send(new_fd, &ackr, HEADER_SIZE, 0)) == -1) {
											perror("send: ack");
											exit(1);
										} else {
											printf("ACK '%d' sent\n", (int)(head.seq));
											/* write to file */
											fwrite(databuf,1 , (int)(head.offset) ,filefd );
										}

									} else {
										printf("Checksum failed, discarding packet...\n");
									}
								}	else if ((int)head.flag == FIN) {
									printf("FIN received...\n");
									/* Create FIN to send back with sequence number */
									fill_header((int)(head.seq), 0, HEADER_SIZE, FIN, &ackr);
									if((ack_bytes = send(new_fd, &ackr, HEADER_SIZE, 0)) == -1) {
										perror("send: ack");
										exit(1);
									} else {
										printf("FIN '%d' sent\n", (int)(head.seq));
										recvFIN = 1;
									}
								}
								//else if ((int)head.flag == FIN) {
								/* re-zero */
								bzero(buf, PACKET_SIZE);
								bzero(databuf, PAYLOAD_SIZE);
							} while (!recvFIN );
						printf("Done...\n");

						fclose(filefd);
            close(new_fd);
            exit(0);
        }
        close(new_fd);  // parent doesn't need this
    }
    return 0;
}
Beispiel #12
0
int
ListenAtTcpPortAndAddress(int port, const char *address)
{
  int sock;
  int one = 1;
#ifndef LIBVNCSERVER_IPv6
  struct sockaddr_in addr;

  addr.sin_family = AF_INET;
  addr.sin_port = htons(port);
  if (address) {
    addr.sin_addr.s_addr = inet_addr(address);
  } else {
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
  }

  if (!initSockets())
    return -1;

  sock = socket(AF_INET, SOCK_STREAM, 0);
  if (sock < 0) {
    rfbClientErr("ListenAtTcpPort: socket\n");
    return -1;
  }

  if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
		 (const char *)&one, sizeof(one)) < 0) {
    rfbClientErr("ListenAtTcpPort: setsockopt\n");
    close(sock);
    return -1;
  }

  if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
    rfbClientErr("ListenAtTcpPort: bind\n");
    close(sock);
    return -1;
  }

#else
  int rv;
  struct addrinfo hints, *servinfo, *p;
  char port_str[8];

  snprintf(port_str, 8, "%d", port);

  memset(&hints, 0, sizeof(hints));
  hints.ai_family = AF_UNSPEC;
  hints.ai_socktype = SOCK_STREAM;
  hints.ai_flags = AI_PASSIVE; /* fill in wildcard address if address == NULL */

  if (!initSockets())
    return -1;

  if ((rv = getaddrinfo(address, port_str, &hints, &servinfo)) != 0) {
    rfbClientErr("ListenAtTcpPortAndAddress: error in getaddrinfo: %s\n", gai_strerror(rv));
    return -1;
  }

  /* loop through all the results and bind to the first we can */
  for(p = servinfo; p != NULL; p = p->ai_next) {
    if ((sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) < 0) {
      continue;
    }

#ifdef IPV6_V6ONLY
    /* we have seperate IPv4 and IPv6 sockets since some OS's do not support dual binding */
    if (p->ai_family == AF_INET6 && setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&one, sizeof(one)) < 0) {
      rfbClientErr("ListenAtTcpPortAndAddress: error in setsockopt IPV6_V6ONLY: %s\n", strerror(errno));
      close(sock);
      freeaddrinfo(servinfo);
      return -1;
    }
#endif

    if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)) < 0) {
      rfbClientErr("ListenAtTcpPortAndAddress: error in setsockopt SO_REUSEADDR: %s\n", strerror(errno));
      close(sock);
      freeaddrinfo(servinfo);
      return -1;
    }

    if (bind(sock, p->ai_addr, p->ai_addrlen) < 0) {
      close(sock);
      continue;
    }

    break;
  }

  if (p == NULL)  {
    rfbClientErr("ListenAtTcpPortAndAddress: error in bind: %s\n", strerror(errno));
    return -1;
  }

  /* all done with this structure now */
  freeaddrinfo(servinfo);
#endif

  if (listen(sock, 5) < 0) {
    rfbClientErr("ListenAtTcpPort: listen\n");
    close(sock);
    return -1;
  }

  return sock;
}
Beispiel #13
0
int
ConnectClientToTcpAddr6(const char *hostname, int port)
{
#ifdef LIBVNCSERVER_IPv6
  int sock;
  int n;
  struct addrinfo hints, *res, *ressave;
  char port_s[10];
  int one = 1;

  if (!initSockets())
	  return -1;

  snprintf(port_s, 10, "%d", port);
  memset(&hints, 0, sizeof(struct addrinfo));
  hints.ai_family = AF_UNSPEC;
  hints.ai_socktype = SOCK_STREAM;
  if ((n = getaddrinfo(hostname, port_s, &hints, &res)))
  {
    rfbClientErr("ConnectClientToTcpAddr6: getaddrinfo (%s)\n", gai_strerror(n));
    return -1;
  }

  ressave = res;
  sock = -1;
  while (res)
  {
    sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
    if (sock >= 0)
    {
      if (connect(sock, res->ai_addr, res->ai_addrlen) == 0)
        break;
      close(sock);
      sock = -1;
    }
    res = res->ai_next;
  }
  freeaddrinfo(ressave);

  if (sock == -1)
  {
    rfbClientErr("ConnectClientToTcpAddr6: connect\n");
    return -1;
  }

  if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
		 (char *)&one, sizeof(one)) < 0) {
    rfbClientErr("ConnectToTcpAddr: setsockopt\n");
    close(sock);
    return -1;
  }

  return sock;

#else

  rfbClientErr("ConnectClientToTcpAddr6: IPv6 disabled\n");
  return -1;

#endif
}
Beispiel #14
0
/* connecthostport()
 * return a socket connected (TCP) to the host and port
 * or -1 in case of error */
int connecthostport(const char * host, unsigned short port,
                    unsigned int scope_id)
{
	int s, n;
#ifdef USE_GETHOSTBYNAME
	struct sockaddr_in dest;
	struct hostent *hp;
#else /* #ifdef USE_GETHOSTBYNAME */
	char tmp_host[MAXHOSTNAMELEN+1];
	char port_str[8];
	struct addrinfo *ai, *p;
	struct addrinfo hints;
#endif /* #ifdef USE_GETHOSTBYNAME */
#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
	struct timeval timeout;
#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */

#ifdef USE_GETHOSTBYNAME
	hp = gethostbyname(host);
	if(hp == NULL)
	{
		herror(host);
		return -1;
	}
	memcpy(&dest.sin_addr, hp->h_addr, sizeof(dest.sin_addr));
	memset(dest.sin_zero, 0, sizeof(dest.sin_zero));
	s = socket(PF_INET, SOCK_STREAM, 0);
	if(s < 0)
	{
		PRINT_SOCKET_ERROR("socket");
		return -1;
	}
#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
	/* setting a 3 seconds timeout for the connect() call */
	timeout.tv_sec = 3;
	timeout.tv_usec = 0;
	if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0)
	{
		PRINT_SOCKET_ERROR("setsockopt");
	}
	timeout.tv_sec = 3;
	timeout.tv_usec = 0;
	if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0)
	{
		PRINT_SOCKET_ERROR("setsockopt");
	}
#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */
	dest.sin_family = AF_INET;
	dest.sin_port = htons(port);
	n = connect(s, (struct sockaddr *)&dest, sizeof(struct sockaddr_in));
#ifdef MINIUPNPC_IGNORE_EINTR
	/* EINTR The system call was interrupted by a signal that was caught
	 * EINPROGRESS The socket is nonblocking and the connection cannot
	 *             be completed immediately. */
	while(n < 0 && (errno == EINTR || errno == EINPROGRESS))
	{
		socklen_t len;
		fd_set wset;
		int err;
		FD_ZERO(&wset);
		FD_SET(s, &wset);
		if((n = select(s + 1, NULL, &wset, NULL, NULL)) == -1 && errno == EINTR)
			continue;
		/*len = 0;*/
		/*n = getpeername(s, NULL, &len);*/
		len = sizeof(err);
		if(getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &len) < 0) {
			PRINT_SOCKET_ERROR("getsockopt");
			closesocket(s);
			return -1;
		}
		if(err != 0) {
			errno = err;
			n = -1;
		}
	}
#endif /* #ifdef MINIUPNPC_IGNORE_EINTR */
	if(n<0)
	{
		PRINT_SOCKET_ERROR("connect");
		closesocket(s);
		return -1;
	}
#else /* #ifdef USE_GETHOSTBYNAME */
	/* use getaddrinfo() instead of gethostbyname() */
	memset(&hints, 0, sizeof(hints));
	/* hints.ai_flags = AI_ADDRCONFIG; */
#ifdef AI_NUMERICSERV
	hints.ai_flags = AI_NUMERICSERV;
#endif
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_family = AF_UNSPEC; /* AF_INET, AF_INET6 or AF_UNSPEC */
	/* hints.ai_protocol = IPPROTO_TCP; */
	snprintf(port_str, sizeof(port_str), "%hu", port);
	if(host[0] == '[')
	{
		/* literal ip v6 address */
		int i, j;
		for(i = 0, j = 1; host[j] && (host[j] != ']') && i < MAXHOSTNAMELEN; i++, j++)
		{
			tmp_host[i] = host[j];
			if(0 == memcmp(host+j, "%25", 3))	/* %25 is just url encoding for '%' */
				j+=2;							/* skip "25" */
		}
		tmp_host[i] = '\0';
	}
	else
	{
		strncpy(tmp_host, host, MAXHOSTNAMELEN);
	}
	tmp_host[MAXHOSTNAMELEN] = '\0';
	n = getaddrinfo(tmp_host, port_str, &hints, &ai);
	if(n != 0)
	{
#ifdef _WIN32
		fprintf(stderr, "getaddrinfo() error : %d\n", n);
#else
		fprintf(stderr, "getaddrinfo() error : %s\n", gai_strerror(n));
#endif
		return -1;
	}
	s = -1;
	for(p = ai; p; p = p->ai_next)
	{
		s = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
		if(s < 0)
			continue;
		if(p->ai_addr->sa_family == AF_INET6 && scope_id > 0) {
			struct sockaddr_in6 * addr6 = (struct sockaddr_in6 *)p->ai_addr;
			addr6->sin6_scope_id = scope_id;
		}
#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
		/* setting a 3 seconds timeout for the connect() call */
		timeout.tv_sec = 3;
		timeout.tv_usec = 0;
		if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0)
		{
			PRINT_SOCKET_ERROR("setsockopt");
		}
		timeout.tv_sec = 3;
		timeout.tv_usec = 0;
		if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0)
		{
			PRINT_SOCKET_ERROR("setsockopt");
		}
#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */
		n = connect(s, p->ai_addr, p->ai_addrlen);
#ifdef MINIUPNPC_IGNORE_EINTR
		/* EINTR The system call was interrupted by a signal that was caught
		 * EINPROGRESS The socket is nonblocking and the connection cannot
		 *             be completed immediately. */
		while(n < 0 && (errno == EINTR || errno == EINPROGRESS))
		{
			socklen_t len;
			fd_set wset;
			int err;
			FD_ZERO(&wset);
			FD_SET(s, &wset);
			if((n = select(s + 1, NULL, &wset, NULL, NULL)) == -1 && errno == EINTR)
				continue;
			/*len = 0;*/
			/*n = getpeername(s, NULL, &len);*/
			len = sizeof(err);
			if(getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &len) < 0) {
				PRINT_SOCKET_ERROR("getsockopt");
				closesocket(s);
				freeaddrinfo(ai);
				return -1;
			}
			if(err != 0) {
				errno = err;
				n = -1;
			}
		}
#endif /* #ifdef MINIUPNPC_IGNORE_EINTR */
		if(n < 0)
		{
			closesocket(s);
			continue;
		}
		else
		{
			break;
		}
	}
	freeaddrinfo(ai);
	if(s < 0)
	{
		PRINT_SOCKET_ERROR("socket");
		return -1;
	}
	if(n < 0)
	{
		PRINT_SOCKET_ERROR("connect");
		return -1;
	}
#endif /* #ifdef USE_GETHOSTBYNAME */
	return s;
}
Beispiel #15
0
static void
resolve_addr(const struct connection *conn, const char *address,
    struct addrinfo **ai, bool initiator_side)
{
	struct addrinfo hints;
	char *arg, *addr, *ch;
	const char *port;
	int error, colons = 0;

	arg = checked_strdup(address);

	if (arg[0] == '\0') {
		fail(conn, "empty address");
		log_errx(1, "empty address");
	}
	if (arg[0] == '[') {
		/*
		 * IPv6 address in square brackets, perhaps with port.
		 */
		arg++;
		addr = strsep(&arg, "]");
		if (arg == NULL) {
			fail(conn, "malformed address");
			log_errx(1, "malformed address %s", address);
		}
		if (arg[0] == '\0') {
			port = NULL;
		} else if (arg[0] == ':') {
			port = arg + 1;
		} else {
			fail(conn, "malformed address");
			log_errx(1, "malformed address %s", address);
		}
	} else {
		/*
		 * Either IPv6 address without brackets - and without
		 * a port - or IPv4 address.  Just count the colons.
		 */
		for (ch = arg; *ch != '\0'; ch++) {
			if (*ch == ':')
				colons++;
		}
		if (colons > 1) {
			addr = arg;
			port = NULL;
		} else {
			addr = strsep(&arg, ":");
			if (arg == NULL)
				port = NULL;
			else
				port = arg;
		}
	}

	if (port == NULL && !initiator_side)
		port = "3260";

	memset(&hints, 0, sizeof(hints));
	hints.ai_family = PF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV;
	if (initiator_side)
		hints.ai_flags |= AI_PASSIVE;

	error = getaddrinfo(addr, port, &hints, ai);
	if (error != 0) {
		fail(conn, gai_strerror(error));
		log_errx(1, "getaddrinfo for %s failed: %s",
		    address, gai_strerror(error));
	}
}
Beispiel #16
0
int simple (char *host, char *service)
{
  char buf[BUFSIZ];
  struct addrinfo hints;
  struct addrinfo *ai0, *ai;
  int res;

  dbgprintf ("Finding %s service %s...\n", host, service);

  /* This initializes "hints" but does not use it.  Is there a reason
     for this?  If so, please fix this comment.  */
  memset (&hints, 0, sizeof (hints));
  hints.ai_flags = AI_CANONNAME;
  hints.ai_family = AF_UNSPEC;
  hints.ai_socktype = SOCK_STREAM;

  res = getaddrinfo (host, service, 0, &ai0);

  dbgprintf ("res %d: %s\n", res, gai_strerror (res));

  if (res != 0)
    {
      /* IRIX reports EAI_NONAME for "https".  Don't fail the test
	 merely because of this.  */
      if (res == EAI_NONAME)
	return 0;
      /* Solaris reports EAI_SERVICE for "http" and "https".  Don't
         fail the test merely because of this.  */
      if (res == EAI_SERVICE)
	return 0;
      /* AIX reports EAI_NODATA for "https".  Don't fail the test
	 merely because of this.  */
      if (res == EAI_NODATA)
	return 0;

      return 1;
    }

  for (ai = ai0; ai; ai = ai->ai_next)
    {
      dbgprintf ("\tflags %x\n", ai->ai_flags);
      dbgprintf ("\tfamily %x\n", ai->ai_family);
      dbgprintf ("\tsocktype %x\n", ai->ai_socktype);
      dbgprintf ("\tprotocol %x\n", ai->ai_protocol);
      dbgprintf ("\taddrlen %ld: ", (unsigned long) ai->ai_addrlen);
      dbgprintf ("\tFound %s\n",
		 inet_ntop (ai->ai_family,
			    &((struct sockaddr_in *)
			      ai->ai_addr)->sin_addr,
			    buf, sizeof (buf) - 1));
      if (ai->ai_canonname)
	dbgprintf ("\tFound %s...\n", ai->ai_canonname);

      {
	char ipbuf[BUFSIZ];
	char portbuf[BUFSIZ];

	res = getnameinfo (ai->ai_addr, ai->ai_addrlen,
			   ipbuf, sizeof (ipbuf) - 1,
			   portbuf, sizeof (portbuf) - 1,
			   NI_NUMERICHOST|NI_NUMERICSERV);
	dbgprintf ("\t\tgetnameinfo %d: %s\n", res, gai_strerror (res));
	if (res == 0)
	  {
	    dbgprintf ("\t\tip %s\n", ipbuf);
	    dbgprintf ("\t\tport %s\n", portbuf);
	  }
      }

    }

  freeaddrinfo (ai0);

  return 0;
}
Beispiel #17
0
int
main(int argc, char *argv[])
{
	const char *cause = NULL;
	int ch, nsocks = 0, save_errno = 0;
	int inet4 = 0, inet6 = 0;
	char group[ICB_MAXGRPLEN], *grplist = NULL;
	char *ptr = NULL;

	/* init group lists before calling icb_addgroup */
	icb_init();

	while ((ch = getopt(argc, argv, "46CdG:M:nL:S:v")) != -1)
		switch (ch) {
		case '4':
			inet4++;
			break;
		case '6':
			inet6++;
			break;
		case 'C':
			creategroups++;
			break;
		case 'd':
			foreground++;
			break;
		case 'G':
			grplist = optarg;
			break;
		case 'L':
			strlcpy(logprefix, optarg, sizeof logprefix);
			dologging++;
			break;
		case 'M':
			strlcpy(modtabpath, optarg, sizeof modtabpath);
			break;
		case 'n':
			dodns = 0;
			break;
		case 'S':
			strlcpy(srvname, optarg, sizeof srvname);
			break;
		case 'v':
			verbose++;
			break;
		default:
			usage();
			/* NOTREACHED */
		}
	argc -= optind;
	argv += optind;

	/* add group "1" as it's a login group for most of the clients */
	if (icb_addgroup(NULL, "1") == NULL)
		err(EX_UNAVAILABLE, NULL);

	if (grplist) {
		while (icb_token(grplist, strlen(grplist), &ptr, group,
		    ICB_MAXGRPLEN, ',', 0) > 0)
			if (icb_addgroup(NULL, group) == NULL)
				err(EX_UNAVAILABLE, NULL);
	}

	if (argc == 0)
		argc++;

	if (inet4 && inet6)
		errx(EX_USAGE, "Can't specify both -4 and -6");

	tzset();
	(void)setlocale(LC_ALL, "C");

	if (foreground)
		openlog("icbd", LOG_PID | LOG_PERROR, LOG_DAEMON);
	else
		openlog("icbd", LOG_PID | LOG_NDELAY, LOG_DAEMON);

	if (!foreground && daemon(0, 0) < 0)
		err(EX_OSERR, NULL);

	(void)event_init();

	for (ch = 0; ch < argc; ch++) {
		struct addrinfo hints, *res, *res0;
		struct icbd_listener *l;
		char *addr, *port;
		int error, s, on = 1;

		addr = port = NULL;
		if (argv[ch] != NULL) {
			if (argv[ch][0] != ':')
				addr = argv[ch];
			if ((port = strrchr(argv[ch], ':')) != NULL)
				*port++ = '\0';
		}

		bzero(&hints, sizeof hints);
		if (inet4 || inet6)
			hints.ai_family = inet4 ? PF_INET : PF_INET6;
		else
			hints.ai_family = PF_UNSPEC;
		hints.ai_socktype = SOCK_STREAM;
		hints.ai_flags = AI_PASSIVE;
		if ((error = getaddrinfo(addr, port ? port : "icb", &hints,
		    &res0)) != 0) {
			syslog(LOG_ERR, "%s", gai_strerror(error));
			return (EX_UNAVAILABLE);
		}

		for (res = res0; res != NULL; res = res->ai_next) {
			if ((s = socket(res->ai_family, res->ai_socktype,
			    res->ai_protocol)) < 0) {
				cause = "socket";
				save_errno = errno;
				continue;
			}

			if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on,
			    sizeof on) < 0) {
				cause = "SO_REUSEADDR";
				save_errno = errno;
				(void)close(s);
				continue;
			}

			if (bind(s, res->ai_addr, res->ai_addrlen) < 0) {
				cause = "bind";
				save_errno = errno;
				(void)close(s);
				continue;
			}

			(void)listen(s, TCP_BACKLOG);

			if ((l = calloc(1, sizeof *l)) == NULL)
				err(EX_UNAVAILABLE, NULL);
			event_set(&l->ev, s, EV_READ | EV_PERSIST,
			    icbd_accept, l);
			if (event_add(&l->ev, NULL) < 0) {
				syslog(LOG_ERR, "event_add: %m");
				return (EX_UNAVAILABLE);
			}
			evtimer_set(&l->pause, icbd_paused, l);

			nsocks++;
		}

		freeaddrinfo(res0);
	}

	if (nsocks == 0) {
		errno = save_errno;
		syslog(LOG_ERR, "%s: %m", cause);
		return (EX_UNAVAILABLE);
	}

	/* start the logger service */
	logger_init();

	/* initialize resolver */
	res_init();

	icbd_restrict();

	icbd_modupdate();

	(void)signal(SIGPIPE, SIG_IGN);

	(void)event_dispatch();

	syslog(LOG_ERR, "event_dispatch: %m");

	return (EX_UNAVAILABLE);
}
Beispiel #18
0
/**
 * Get the list of addresses that a server for the given service
 * should bind to.
 *
 * @param service_name name of the service
 * @param cfg configuration (which specifies the addresses)
 * @param addrs set (call by reference) to an array of pointers to the
 *              addresses the server should bind to and listen on; the
 *              array will be NULL-terminated (on success)
 * @param addr_lens set (call by reference) to an array of the lengths
 *              of the respective `struct sockaddr` struct in the @a addrs
 *              array (on success)
 * @return number of addresses found on success,
 *              #GNUNET_SYSERR if the configuration
 *              did not specify reasonable finding information or
 *              if it specified a hostname that could not be resolved;
 *              #GNUNET_NO if the number of addresses configured is
 *              zero (in this case, `*addrs` and `*addr_lens` will be
 *              set to NULL).
 */
int
GNUNET_SERVICE_get_server_addresses (const char *service_name,
                                     const struct GNUNET_CONFIGURATION_Handle *cfg,
                                     struct sockaddr ***addrs,
                                     socklen_t ** addr_lens)
{
  int disablev6;
  struct GNUNET_NETWORK_Handle *desc;
  unsigned long long port;
  char *unixpath;
  struct addrinfo hints;
  struct addrinfo *res;
  struct addrinfo *pos;
  struct addrinfo *next;
  unsigned int i;
  int resi;
  int ret;
  int abstract;
  struct sockaddr **saddrs;
  socklen_t *saddrlens;
  char *hostname;

  *addrs = NULL;
  *addr_lens = NULL;
  desc = NULL;
  if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "DISABLEV6"))
  {
    if (GNUNET_SYSERR ==
        (disablev6 =
         GNUNET_CONFIGURATION_get_value_yesno (cfg, service_name, "DISABLEV6")))
      return GNUNET_SYSERR;
  }
  else
    disablev6 = GNUNET_NO;

  if (! disablev6)
  {
    /* probe IPv6 support */
    desc = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0);
    if (NULL == desc)
    {
      if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) ||
          (EACCES == errno))
      {
        LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket");
        return GNUNET_SYSERR;
      }
      LOG (GNUNET_ERROR_TYPE_INFO,
           _("Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n"),
           service_name, STRERROR (errno));
      disablev6 = GNUNET_YES;
    }
    else
    {
      GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc));
      desc = NULL;
    }
  }

  port = 0;
  if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "PORT"))
  {
    if (GNUNET_OK !=
	GNUNET_CONFIGURATION_get_value_number (cfg, service_name,
					       "PORT", &port))
    {
      LOG (GNUNET_ERROR_TYPE_ERROR,
           _("Require valid port number for service `%s' in configuration!\n"),
           service_name);
    }
    if (port > 65535)
    {
      LOG (GNUNET_ERROR_TYPE_ERROR,
           _("Require valid port number for service `%s' in configuration!\n"),
           service_name);
      return GNUNET_SYSERR;
    }
  }

  if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "BINDTO"))
  {
    GNUNET_break (GNUNET_OK ==
                  GNUNET_CONFIGURATION_get_value_string (cfg, service_name,
                                                         "BINDTO", &hostname));
  }
  else
    hostname = NULL;

  unixpath = NULL;
  abstract = GNUNET_NO;
#ifdef AF_UNIX
  if ((GNUNET_YES ==
       GNUNET_CONFIGURATION_have_value (cfg, service_name, "UNIXPATH")) &&
      (GNUNET_OK ==
       GNUNET_CONFIGURATION_get_value_filename (cfg, service_name, "UNIXPATH",
                                              &unixpath)) &&
      (0 < strlen (unixpath)))
  {
    /* probe UNIX support */
    struct sockaddr_un s_un;

    if (strlen (unixpath) >= sizeof (s_un.sun_path))
    {
      LOG (GNUNET_ERROR_TYPE_WARNING,
           _("UNIXPATH `%s' too long, maximum length is %llu\n"), unixpath,
           (unsigned long long) sizeof (s_un.sun_path));
      unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath);
      LOG (GNUNET_ERROR_TYPE_INFO,
	   _("Using `%s' instead\n"),
           unixpath);
    }
#ifdef LINUX
    abstract = GNUNET_CONFIGURATION_get_value_yesno (cfg,
                                                     "TESTING",
                                                     "USE_ABSTRACT_SOCKETS");
    if (GNUNET_SYSERR == abstract)
      abstract = GNUNET_NO;
#endif
    if ((GNUNET_YES != abstract)
        && (GNUNET_OK !=
            GNUNET_DISK_directory_create_for_file (unixpath)))
      GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
				"mkdir",
				unixpath);
  }
  if (NULL != unixpath)
  {
    desc = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0);
    if (NULL == desc)
    {
      if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) ||
          (EACCES == errno))
      {
        LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket");
        GNUNET_free_non_null (hostname);
        GNUNET_free (unixpath);
        return GNUNET_SYSERR;
      }
      LOG (GNUNET_ERROR_TYPE_INFO,
           _("Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"),
           service_name,
           STRERROR (errno));
      GNUNET_free (unixpath);
      unixpath = NULL;
    }
    else
    {
      GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc));
      desc = NULL;
    }
  }
#endif

  if ((0 == port) && (NULL == unixpath))
  {
    LOG (GNUNET_ERROR_TYPE_ERROR,
         _("Have neither PORT nor UNIXPATH for service `%s', but one is required\n"),
         service_name);
    GNUNET_free_non_null (hostname);
    return GNUNET_SYSERR;
  }
  if (0 == port)
  {
    saddrs = GNUNET_malloc (2 * sizeof (struct sockaddr *));
    saddrlens = GNUNET_malloc (2 * sizeof (socklen_t));
    add_unixpath (saddrs, saddrlens, unixpath, abstract);
    GNUNET_free_non_null (unixpath);
    GNUNET_free_non_null (hostname);
    *addrs = saddrs;
    *addr_lens = saddrlens;
    return 1;
  }

  if (NULL != hostname)
  {
    LOG (GNUNET_ERROR_TYPE_DEBUG,
         "Resolving `%s' since that is where `%s' will bind to.\n",
         hostname,
         service_name);
    memset (&hints, 0, sizeof (struct addrinfo));
    if (disablev6)
      hints.ai_family = AF_INET;
    hints.ai_protocol = IPPROTO_TCP;
    if ((0 != (ret = getaddrinfo (hostname, NULL, &hints, &res))) ||
        (NULL == res))
    {
      LOG (GNUNET_ERROR_TYPE_ERROR,
           _("Failed to resolve `%s': %s\n"),
           hostname,
           gai_strerror (ret));
      GNUNET_free (hostname);
      GNUNET_free_non_null (unixpath);
      return GNUNET_SYSERR;
    }
    next = res;
    i = 0;
    while (NULL != (pos = next))
    {
      next = pos->ai_next;
      if ((disablev6) && (pos->ai_family == AF_INET6))
        continue;
      i++;
    }
    if (0 == i)
    {
      LOG (GNUNET_ERROR_TYPE_ERROR,
           _("Failed to find %saddress for `%s'.\n"),
           disablev6 ? "IPv4 " : "",
           hostname);
      freeaddrinfo (res);
      GNUNET_free (hostname);
      GNUNET_free_non_null (unixpath);
      return GNUNET_SYSERR;
    }
    resi = i;
    if (NULL != unixpath)
      resi++;
    saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *));
    saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t));
    i = 0;
    if (NULL != unixpath)
    {
      add_unixpath (saddrs, saddrlens, unixpath, abstract);
      i++;
    }
    next = res;
    while (NULL != (pos = next))
    {
      next = pos->ai_next;
      if ((disablev6) && (AF_INET6 == pos->ai_family))
        continue;
      if ((IPPROTO_TCP != pos->ai_protocol) && (0 != pos->ai_protocol))
        continue;               /* not TCP */
      if ((SOCK_STREAM != pos->ai_socktype) && (0 != pos->ai_socktype))
        continue;               /* huh? */
      LOG (GNUNET_ERROR_TYPE_DEBUG, "Service `%s' will bind to `%s'\n",
           service_name, GNUNET_a2s (pos->ai_addr, pos->ai_addrlen));
      if (AF_INET == pos->ai_family)
      {
        GNUNET_assert (sizeof (struct sockaddr_in) == pos->ai_addrlen);
        saddrlens[i] = pos->ai_addrlen;
        saddrs[i] = GNUNET_malloc (saddrlens[i]);
        memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
        ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
      }
      else
      {
        GNUNET_assert (AF_INET6 == pos->ai_family);
        GNUNET_assert (sizeof (struct sockaddr_in6) == pos->ai_addrlen);
        saddrlens[i] = pos->ai_addrlen;
        saddrs[i] = GNUNET_malloc (saddrlens[i]);
        memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
        ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
      }
      i++;
    }
    GNUNET_free (hostname);
    freeaddrinfo (res);
    resi = i;
  }
  else
  {
    /* will bind against everything, just set port */
    if (disablev6)
    {
      /* V4-only */
      resi = 1;
      if (NULL != unixpath)
        resi++;
      i = 0;
      saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *));
      saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t));
      if (NULL != unixpath)
      {
        add_unixpath (saddrs, saddrlens, unixpath, abstract);
        i++;
      }
      saddrlens[i] = sizeof (struct sockaddr_in);
      saddrs[i] = GNUNET_malloc (saddrlens[i]);
#if HAVE_SOCKADDR_IN_SIN_LEN
      ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[i];
#endif
      ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
      ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
    }
    else
    {
      /* dual stack */
      resi = 2;
      if (NULL != unixpath)
        resi++;
      saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *));
      saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t));
      i = 0;
      if (NULL != unixpath)
      {
        add_unixpath (saddrs, saddrlens, unixpath, abstract);
        i++;
      }
      saddrlens[i] = sizeof (struct sockaddr_in6);
      saddrs[i] = GNUNET_malloc (saddrlens[i]);
#if HAVE_SOCKADDR_IN_SIN_LEN
      ((struct sockaddr_in6 *) saddrs[i])->sin6_len = saddrlens[0];
#endif
      ((struct sockaddr_in6 *) saddrs[i])->sin6_family = AF_INET6;
      ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
      i++;
      saddrlens[i] = sizeof (struct sockaddr_in);
      saddrs[i] = GNUNET_malloc (saddrlens[i]);
#if HAVE_SOCKADDR_IN_SIN_LEN
      ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[1];
#endif
      ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
      ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
    }
  }
  GNUNET_free_non_null (unixpath);
  *addrs = saddrs;
  *addr_lens = saddrlens;
  return resi;
}
int main(int argc, char *argv[])
{
	int sockfd, numbytes;  
	char buf[DATA];
	struct addrinfo hints, *servinfo, *p;
	int rv;
	char s[INET6_ADDRSTRLEN];
	char * host;

	if (argc != 2) {
	    fprintf(stderr,"usage: client hostname\r\n");
	    exit(1);
	}
	host = argv[1];
	char * array = host + 7;
	char * port;
	char * page;
	char * ip;
	char pointer;
	int z = 0;
	while(z < strlen(array))
	{
		pointer = array[z];
		if(pointer == ':')
		{
			ip = strtok(array, ":");
			
			port = strtok(NULL, "/");
			page = strtok(NULL, "\r\n");
		}
		else if(pointer == '/')
		{
			ip = strtok(array, "/");
			port = "80";
			page = strtok(NULL,"\r\n");
		}
		z++;
	}
	//GETQUERY
	char * get = getquery(array, page);
	fprintf(stderr, "Query: %s\n", get);

	memset(&hints, 0, sizeof hints);
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;

	if ((rv = getaddrinfo(ip, port, &hints, &servinfo)) != 0) {
		fprintf(stderr, "getaddrinfo: %s\r\n", gai_strerror(rv));
		return 1;
	}

	// loop through all the results and connect to the first we can
	for(p = servinfo; p != NULL; p = p->ai_next) {
		if ((sockfd = socket(p->ai_family, p->ai_socktype,
				p->ai_protocol)) == -1) {
			perror("client: socket");
			continue;
		}

		if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
			close(sockfd);
			perror("client: connect");
			continue;
		}

		break;
	}

	if (p == NULL) {
		fprintf(stderr, "client: failed to connect\r\n");
		return 2;
	}

	inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr),
			s, sizeof s);
	printf("client: connecting to %s\r\n", s);

	freeaddrinfo(servinfo); // all done with this structure


	//PRINT OUT MESSAGE
	memset(buf, '\0', sizeof(buf));
	sprintf(buf, "GET /%s HTTP/1.1\r\n", page);
	sprintf(buf + strlen(buf), "User-Agent: Wget/1.12 (linux-gnu)\r\n");
	sprintf(buf + strlen(buf), "Host: %s\r\n", ip);
	sprintf(buf + strlen(buf),"Connection: Keep-Alive\r\n\r\n");


	if((numbytes = send(sockfd, buf, strlen(buf), 0)) == -1)
	{
		perror("send");
		exit(1);
	}

	//RECEIVING STUFF
	FILE * output;
	output = fopen("temp", "wb");
	while(1)
	{
		if((numbytes = recv(sockfd, buf, DATA-1, 0)) == -1)
		{
			perror("recv");
			exit(1);
		}

		if(numbytes == 0)
		{
			break;
		}

		fwrite(buf, sizeof(char), numbytes, output);

	}

	close(sockfd);
	fclose(output);
	output = fopen("temp", "rb");
	FILE * foutput;
	foutput = fopen("output", "wb");

	int headerprocessed = 0;

	char * t;
	do
	{
		numbytes = fread(buf, sizeof(char), DATA, output);
		if(!headerprocessed)
		{
			t = strstr(buf, "\r\n\r\n") + 4;
			fwrite(t, sizeof(char), numbytes - (t - buf), foutput);
			headerprocessed = 1;
		}
		else
		{
			fwrite(buf, sizeof(char), numbytes, foutput);
		}
	}
	while(numbytes == DATA);
	fclose(foutput);
	fclose(output);
	remove("temp");

	return 0;
}
Beispiel #20
0
/**
 * Creates a socket and binds it.
 * @param listen_port - port to listen to
 * @param bind_to - IP address to bind to - if empty, will bind to :: (0.0.0.0) (all)
 * @param sock - socket to be update with the identifier of the opened one
 * @returns 1 on success, 0 on error
 */
int create_socket(int listen_port,str bind_to,unsigned int *sock)
{
	unsigned int server_sock=-1;
	struct addrinfo *ainfo=0,*res=0,hints;
	char buf[256],host[256],serv[256];
	int error=0;
	unsigned int option;

	memset (&hints, 0, sizeof(hints));
	//hints.ai_protocol = IPPROTO_SCTP;
	//hints.ai_protocol = IPPROTO_TCP;
	hints.ai_flags = AI_PASSIVE|AI_ADDRCONFIG;
	hints.ai_socktype = SOCK_STREAM;

	sprintf(buf,"%d",listen_port);

	if (bind_to.len){
		error = getaddrinfo(bind_to.s, buf, &hints, &res);
		if (error!=0){
			LM_WARN("create_socket(): Error opening %.*s port %d while doing gethostbyname >%s\n",
					bind_to.len,bind_to.s,listen_port,gai_strerror(error));
			goto error;
		}
	}else{
		error = getaddrinfo(NULL, buf, &hints, &res);
		if (error!=0){
			LM_WARN("create_socket(): Error opening ANY port %d while doing gethostbyname >%s\n",
					listen_port,gai_strerror(error));
			goto error;
		}
	}

	LM_DBG("create_sockets: create socket and bind for IPv4...\n");

	for(ainfo = res;ainfo;ainfo = ainfo->ai_next)
	{
		if (getnameinfo(ainfo->ai_addr,ainfo->ai_addrlen,
					host,256,serv,256,NI_NUMERICHOST|NI_NUMERICSERV)==0){
			LM_WARN("create_socket(): Trying to open/bind/listen on %s port %s\n",
					host,serv);
		}

		if ((server_sock = socket(ainfo->ai_family, ainfo->ai_socktype, ainfo->ai_protocol)) == -1) {
			LM_ERR("create_socket(): error creating server socket on %s port %s >"
					" %s\n",host,serv,strerror(errno));
			goto error;
		}
		option = 1;
		setsockopt(server_sock,SOL_SOCKET,SO_REUSEADDR,&option,sizeof(option));

		if (bind( 	server_sock,ainfo->ai_addr,ainfo->ai_addrlen)==-1 ) {
			LM_ERR("create_socket(): error binding on %s port %s >"
					" %s\n",host,serv,strerror(errno));
			goto error;
		}

		if (listen( server_sock, 5) == -1) {
			LM_ERR("create_socket(): error listening on %s port %s > %s\n",host,serv,strerror(errno) );
			goto error;
		}

		*sock = server_sock;

		LM_WARN("create_socket(): Successful socket open/bind/listen on %s port %s\n",
				host,serv);
	}
	if (res) freeaddrinfo(res);
	return 1;
error:
	if (res) freeaddrinfo(res);
	if (server_sock!=-1) close(server_sock);
	return 0;

}
Beispiel #21
0
void start_server(const char* port)
{
    int status;
    struct addrinfo  host_info;
    struct addrinfo* host_info_list;

    static server_t server(write_sock);
//    (
//          std::make_pair(name::page_400::name() , ecl::web::static_resource < resources::res_400_html_t    >())
//        , std::make_pair(name::page_404::name() , ecl::web::static_resource < resources::res_404_html_t    >())
//        , std::make_pair(name::page_500::name() , ecl::web::static_resource < resources::res_500_html_t    >())

//        , std::make_pair(name::index_1::name()  , ecl::web::static_resource < resources::res_index_html_t  >())
//        , std::make_pair(name::index_2::name()  , ecl::web::static_resource < resources::res_index_html_t  >())

//        , std::make_pair(name::icon::name()     , ecl::web::static_resource < resources::res_icon_png_t    >())
//        , std::make_pair(name::favicon::name()  , ecl::web::static_resource < resources::res_favicon_png_t >())
//        , std::make_pair(name::style::name()    , ecl::web::static_resource < resources::res_style_css_t   >())
//        , std::make_pair(name::jquery::name()   , ecl::web::static_resource < resources::res_jquery_js_t   >())
//    );

    bool resource_result = true;

    server_t::static_resource_t < resources::res_400_html_t    > res_400     ( ecl::web::content_type::TEXT_HTML       , ecl::web::status_code::BAD_REQUEST           );
    server_t::static_resource_t < resources::res_404_html_t    > res_404     ( ecl::web::content_type::TEXT_HTML       , ecl::web::status_code::NOT_FOUND             );
    server_t::static_resource_t < resources::res_500_html_t    > res_500     ( ecl::web::content_type::TEXT_HTML       , ecl::web::status_code::INTERNAL_SERVER_ERROR );

    server_t::static_resource_t < resources::res_index_html_t  > res_index_1 ( ecl::web::content_type::TEXT_HTML       );
    server_t::static_resource_t < resources::res_index_html_t  > res_index_2 ( ecl::web::content_type::TEXT_HTML       );

    server_t::static_resource_t < resources::res_icon_png_t    > res_icon    ( ecl::web::content_type::IMAGE_PNG       );
    server_t::static_resource_t < resources::res_favicon_png_t > res_favicon ( ecl::web::content_type::IMAGE_PNG       );
    server_t::static_resource_t < resources::res_style_css_t   > res_style   ( ecl::web::content_type::TEXT_CSS        );
    server_t::static_resource_t < resources::res_jquery_js_t   > res_jquery  ( ecl::web::content_type::TEXT_JAVASCRIPT );

    cgi_info c_info;

    resource_result &= server.attach_handler( res_400 );
    resource_result &= server.attach_handler( res_404 );
    resource_result &= server.attach_handler( res_500 );

    resource_result &= server.attach_resource( name::index_1::name()  , res_index_1 );
    resource_result &= server.attach_resource( name::index_2::name()  , res_index_2 );

    resource_result &= server.attach_resource( name::icon::name()     , res_icon    );
    resource_result &= server.attach_resource( name::favicon::name()  , res_favicon );
    resource_result &= server.attach_resource( name::style::name()    , res_style   );
    resource_result &= server.attach_resource( name::jquery::name()   , res_jquery  );

    resource_result &= server.attach_resource( name::info::name()     , c_info      );

    if(!resource_result)
    {
        std::cout << "Resource adding error!" << std::endl;
        exit(1);
    }

    memset(&host_info, 0, sizeof host_info);

    std::cout << "Setting up the structs..."  << std::endl;

    host_info.ai_family   = AF_UNSPEC;   // IP version not specified. Can be both.
    host_info.ai_socktype = SOCK_STREAM; // Use SOCK_STREAM for TCP or SOCK_DGRAM for UDP.
    host_info.ai_flags    = AI_PASSIVE;  // IP Wildcard

    // Now fill up the linked list of host_info structs with google's address information.
    status = getaddrinfo(NULL, port, &host_info, &host_info_list);
    // getaddrinfo returns 0 on succes, or some other value when an error occured.
    // (translated into human readable text by the gai_gai_strerror function).
    if (status != 0)
    {
        std::cout << "getaddrinfo error" << gai_strerror(status) << std::endl;
    }

    std::cout << "Creating a socket..."  << std::endl;
    int socketfd ; // The socket descripter
    socketfd = socket(host_info_list->ai_family, host_info_list->ai_socktype,
                      host_info_list->ai_protocol);
    if (socketfd == -1)
    {
        std::cout << "socket error ";
        exit(1);
    }

    std::cout << "Binding socket..."  << std::endl;
    // we use to make the setsockopt() function to make sure the port is not in use
    // by a previous execution of our code. (see man page for more information)
    int yes = 1;
    status = setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
    status = bind(socketfd, host_info_list->ai_addr, host_info_list->ai_addrlen);
    if (status == -1)
    {
        std::cout << "bind error" << std::endl;
        exit(1);
    }

    std::cout << "Listen()ing for connections at port " << port << "..." << std::endl;
    status =  listen(socketfd, 5);
    if (status == -1)
    {
        std::cout << "listen error" << std::endl;
        exit(1);
    }

    while(true)
    {
        memset(buffer, 0x00, sizeof(buffer));

        struct sockaddr their_addr;
        socklen_t addr_size = sizeof(their_addr);
        new_sd = accept(socketfd, &their_addr, &addr_size);
        if (new_sd == -1)
        {
            std::cout << "listen error" << std::endl ;
        }
        else
        {
            std::cout << "Connection accepted. Using new socketfd : "  <<  new_sd << std::endl;
        }

        std::cout << "Waiting to recieve data..."  << std::endl;
        ssize_t bytes_recieved;
        bytes_recieved = recv(new_sd, buffer, RECV_BUFFER_SIZE, 0);
        // If no data arrives, the program will just wait here until some data arrives.
        if (bytes_recieved == 0)
        {
            std::cout << "host shut down." << std::endl;
        }
        else if (bytes_recieved == -1)
        {
            std::cout << "recieve error!" << std::endl;
        }

        std::cout << bytes_recieved << " bytes recieved :" << std::endl;
        buffer[bytes_recieved] = 0;
        // for(ssize_t i = 0; i < bytes_recieved; ++i)
        // {
        //     if(std::isprint(buffer[i]))
        //     {
        //         std::cout << buffer[i];
        //     }
        //     else
        //     {
        //         std::cout << std::hex << std::setw(2) << std::setfill('0') << int(buffer[i]) << std::dec;
        //     }
        // }
        // std::cout << std::endl;
        std::cout << buffer << std::endl;

        server.process_request(buffer, static_cast<std::size_t>(bytes_recieved));

        close(new_sd);
    }
    // std::cout << "Stopping server..." << std::endl;
    // freeaddrinfo(host_info_list);
    // close(socketfd);
}
Beispiel #22
0
 virtual
 std::string
 message(int code) const {
     return gai_strerror(code);
 }
Beispiel #23
0
    socket::socket(const char* pHost, unsigned short pPort)
        : mHost(pHost)
        , mPort(pPort)
    {
        assert(pPort > 0);

        struct addrinfo hints, *ai;
        char ip[INET6_ADDRSTRLEN];

        std::fill(mInBuf, mInBuf+sizeof(mInBuf), 0);

        auto logentry = log::debug << LOC() << "Using host " << mHost << " with port " << mPort;
        logentry << " on " << (V4_ONLY ? "IPv4" : "IPv6") << log::done;
      
        memset(&hints, 0, sizeof hints);
        hints.ai_family = V4_ONLY ? AF_INET : AF_UNSPEC; // IPv4 or 6 (AF_INET or AF_INET6)
        hints.ai_socktype = SOCK_STREAM; // TCP
        hints.ai_flags = AI_PASSIVE; // Autodetect local host

        log::debug << LOC() << "Resolving host..." << log::done;
        if (int ret = getaddrinfo(mHost, std::to_string(mPort).c_str(), &hints, &mAddrInfoPtr))
        {
            auto logentry = log::error << LOC() << "Failed to resolve host: " << mHost;
            logentry << " (" << ret << ":" << gai_strerror(ret) << ")" << log::done;
            throw std::runtime_error(LOC() "Hostname not resolved");
        }
        log::debug << LOC() << "Done." << log::done;

        for ( ai = mAddrInfoPtr; ai != NULL; ai = ai->ai_next )
        {
            void *server; // sockaddr_in or sockaddr_in6
            if ( ai->ai_family == AF_INET )
            { // IPv4
                struct sockaddr_in *ipv4 = (struct sockaddr_in *)ai->ai_addr;
                server = &(ipv4->sin_addr);
            }
            else
            { // IPv6
                struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)ai->ai_addr;
                server = &(ipv6->sin6_addr);
            }
            inet_ntop(ai->ai_family, server, ip, sizeof ip);

            log::debug << LOC() << "Connecting to " << mHost << " (" << ip << ")... " << log::done;

            if ( (mSockfd = ::socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) < 0 )
            { 
                log::warn << LOC() << "Could not create socket" << log::done;
                continue;
            }

            if (int ret = connect(mSockfd, ai->ai_addr, ai->ai_addrlen))
            {
                log::warn << LOC() << "Connection to " << ip << " failed [" << ret << "]" << log::done;
            }
            else break;
        }
        if ( ai == NULL ) 
        {
            log::error << LOC() << "Could not connect to host: " << mHost << log::done;
            throw std::runtime_error(LOC() "Connection failed");
        }
        else
        {
            log::info << "Connected to IRC!" << log::done;
        }
    }
Beispiel #24
0
/* return non zero if error */
static int tcp_open(URLContext *h, const char *uri, int flags)
{
    struct addrinfo hints = { 0 }, *ai, *cur_ai;
    int port, fd = -1;
    TCPContext *s = h->priv_data;
    int listen_socket = 0;
    const char *p;
    char buf[256];
    int ret;
    socklen_t optlen;
    int timeout = 50;
    char hostname[1024],proto[1024],path[1024];
    char portstr[10];

    av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname),
        &port, path, sizeof(path), uri);
    if (strcmp(proto,"tcp") || port <= 0 || port >= 65536)
        return AVERROR(EINVAL);

    p = strchr(uri, '?');
    if (p) {
        if (av_find_info_tag(buf, sizeof(buf), "listen", p))
            listen_socket = 1;
        if (av_find_info_tag(buf, sizeof(buf), "timeout", p)) {
            timeout = strtol(buf, NULL, 10);
        }
    }
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    snprintf(portstr, sizeof(portstr), "%d", port);
    ret = getaddrinfo(hostname, portstr, &hints, &ai);
    if (ret) {
        av_log(h, AV_LOG_ERROR,
               "Failed to resolve hostname %s: %s\n",
               hostname, gai_strerror(ret));
        return AVERROR(EIO);
    }

    cur_ai = ai;

 restart:
    ret = AVERROR(EIO);
    fd = socket(cur_ai->ai_family, cur_ai->ai_socktype, cur_ai->ai_protocol);
    if (fd < 0)
        goto fail;

    if (listen_socket) {
        int fd1;
        ret = bind(fd, cur_ai->ai_addr, cur_ai->ai_addrlen);
        listen(fd, 1);
        fd1 = accept(fd, NULL, NULL);
        closesocket(fd);
        fd = fd1;
        ff_socket_nonblock(fd, 1);
    } else {
 redo:
        ff_socket_nonblock(fd, 1);
        ret = connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen);
    }

    if (ret < 0) {
        struct pollfd p = {fd, POLLOUT, 0};
        ret = ff_neterrno();
        if (ret == AVERROR(EINTR)) {
            if (ff_check_interrupt(&h->interrupt_callback)) {
                ret = AVERROR_EXIT;
                goto fail1;
            }
            goto redo;
        }
        if (ret != AVERROR(EINPROGRESS) &&
            ret != AVERROR(EAGAIN))
            goto fail;

        /* wait until we are connected or until abort */
        while(timeout--) {
            if (ff_check_interrupt(&h->interrupt_callback)) {
                ret = AVERROR_EXIT;
                goto fail1;
            }
            ret = poll(&p, 1, 100);
            if (ret > 0)
                break;
        }
        if (ret <= 0) {
            ret = AVERROR(ETIMEDOUT);
            goto fail;
        }
        /* test error */
        optlen = sizeof(ret);
        getsockopt (fd, SOL_SOCKET, SO_ERROR, &ret, &optlen);
        if (ret != 0) {
            av_log(h, AV_LOG_ERROR,
                   "TCP connection to %s:%d failed: %s\n",
                   hostname, port, strerror(ret));
            ret = AVERROR(ret);
            goto fail;
        }
    }
    h->is_streamed = 1;
    s->fd = fd;
    freeaddrinfo(ai);
    return 0;

 fail:
    if (cur_ai->ai_next) {
        /* Retry with the next sockaddr */
        cur_ai = cur_ai->ai_next;
        if (fd >= 0)
            closesocket(fd);
        goto restart;
    }
 fail1:
    if (fd >= 0)
        closesocket(fd);
    freeaddrinfo(ai);
    return ret;
}
Beispiel #25
0
/*
 * Main print server thread.  Accepts connect requests from
 * clients and spawns additional threads to service requests.
 *
 * LOCKING: none.
 */
int
main(int argc, char *argv[])
{
	pthread_t			tid;
	struct addrinfo		*ailist, *aip;
	int					sockfd, err, i, n, maxfd;
	char				*host;
	fd_set				rendezvous, rset;
	struct sigaction	sa;
	struct passwd		*pwdp;

	if (argc != 1)
		err_quit("usage: printd");
	daemonize("printd");

	sigemptyset(&sa.sa_mask);
	sa.sa_flags = 0;
	sa.sa_handler = SIG_IGN;
	if (sigaction(SIGPIPE, &sa, NULL) < 0)
		log_sys("sigaction failed");
	sigemptyset(&mask);
	sigaddset(&mask, SIGHUP);
	sigaddset(&mask, SIGTERM);
	if ((err = pthread_sigmask(SIG_BLOCK, &mask, NULL)) != 0)
		log_sys("pthread_sigmask failed");
	init_request();
	init_printer();

#ifdef _SC_HOST_NAME_MAX
	n = sysconf(_SC_HOST_NAME_MAX);
	if (n < 0)	/* best guess */
#endif
		n = HOST_NAME_MAX;

	if ((host = malloc(n)) == NULL)
		log_sys("malloc error");
	if (gethostname(host, n) < 0)
		log_sys("gethostname error");
	if ((err = getaddrlist(host, "print", &ailist)) != 0) {
		log_quit("getaddrinfo error: %s", gai_strerror(err));
		exit(1);
	}
	FD_ZERO(&rendezvous);
	maxfd = -1;
	for (aip = ailist; aip != NULL; aip = aip->ai_next) {
		if ((sockfd = initserver(SOCK_STREAM, aip->ai_addr,
		  aip->ai_addrlen, QLEN)) >= 0) {
			FD_SET(sockfd, &rendezvous);
			if (sockfd > maxfd)
				maxfd = sockfd;
		}
	}
	if (maxfd == -1)
		log_quit("service not enabled");

	pwdp = getpwnam("lp");
	if (pwdp == NULL)
		log_sys("can't find user lp");
	if (pwdp->pw_uid == 0)
		log_quit("user lp is privileged");
	if (setuid(pwdp->pw_uid) < 0)
		log_sys("can't change IDs to user lp");

	pthread_create(&tid, NULL, printer_thread, NULL);
	pthread_create(&tid, NULL, signal_thread, NULL);
	build_qonstart();

	log_msg("daemon initialized");

	for (;;) {
		rset = rendezvous;
		if (select(maxfd+1, &rset, NULL, NULL, NULL) < 0)
			log_sys("select failed");
		for (i = 0; i <= maxfd; i++) {
			if (FD_ISSET(i, &rset)) {

				/*
				 * Accept the connection and handle
				 * the request.
				 */
				sockfd = accept(i, NULL, NULL);
				if (sockfd < 0)
					log_ret("accept failed");
				pthread_create(&tid, NULL, client_thread,
				  (void *)sockfd);
			}
		}
	}
	exit(1);
}
Beispiel #26
0
void simplesocket::resolve (struct addrinfo * hint) {
  int err;
  int on = 1;
  
  char portStr[255];
  snprintf (portStr, sizeof(portStr), "%d", _port);
  
  if ((err = getaddrinfo (hostname(), portStr, hint, &_addresses)) != 0) {
    if (_debug) cerr << "Error in name resolution for " << name() << ", with error " << gai_strerror(err) << "\n";
    _nameResolved = false;
    return;
  }
  
  _nameResolved = true;
  _socketfd = socket (AF_INET, SOCK_STREAM, 0);
  if (_socketfd < 0) {
    if (_debug) cerr << "SOCKET CREATION FAILURE... aborting.\n";
    return;
  }
  
  setsockopt (_socketfd, 
	      SOL_SOCKET,
	      SO_REUSEADDR, 
	      (void *) &on,
	      sizeof (on));
}
/* Listen on address:port. Unless address is NULL, in which case listen on
 * everything. If called with address == "", we'll listen on localhost/loopback.
 * Returns the number of sockets bound on success, or -1 on failure. On
 * failure, if errstring wasn't NULL, it'll be a newly malloced error
 * string.*/
int dropbear_listen(const char* address, const char* port,
		int *socks, unsigned int sockcount, char **errstring, int *maxfd) {

	struct addrinfo hints, *res = NULL, *res0 = NULL;
	int err;
	unsigned int nsock;
	struct linger linger;
	int val;
	int sock;

	TRACE(("enter dropbear_listen"))
	
	memset(&hints, 0, sizeof(hints));
	hints.ai_family = AF_UNSPEC; /* TODO: let them flag v4 only etc */
	hints.ai_socktype = SOCK_STREAM;

	if (address && address[0] == '\0') {
		TRACE(("dropbear_listen: local loopback"))
		address = NULL;
	} else {
		TRACE(("dropbear_listen: not local loopback"))
		hints.ai_flags = AI_PASSIVE;
	}
	err = getaddrinfo(address, port, &hints, &res0);

	if (err) {
		if (errstring != NULL && *errstring == NULL) {
			int len;
			len = 20 + strlen(gai_strerror(err));
			*errstring = (char*)m_malloc(len);
			snprintf(*errstring, len, "Error resolving: %s", gai_strerror(err));
		}
		TRACE(("leave dropbear_listen: failed resolving"))
		return -1;
	}


	nsock = 0;
	for (res = res0; res != NULL && nsock < sockcount;
			res = res->ai_next) {
#if 1 //inetd
        if (nsock == 0)
        {
            socks[nsock] = CMS_DYNAMIC_LAUNCH_SERVER_FD;
    	    sock = socks[nsock]; /* For clarity */

		    /* Various useful socket options */
		    val = 1;

		    /* quick timeout */
		    linger.l_onoff = 1;
		    linger.l_linger = 5;
		    setsockopt(sock, SOL_SOCKET, SO_LINGER, (void*)&linger, sizeof(linger));

		    /* disable nagle */
		    setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void*)&val, sizeof(val));

        }
        else
        {
#endif
		/* Get a socket */
		socks[nsock] = socket(res->ai_family, res->ai_socktype,
				res->ai_protocol);

		sock = socks[nsock]; /* For clarity */

		if (sock < 0) {
			err = errno;
			TRACE(("socket() failed"))
			continue;
		}

		/* Various useful socket options */
		val = 1;
		/* set to reuse, quick timeout */
		setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*) &val, sizeof(val));
		linger.l_onoff = 1;
		linger.l_linger = 5;
		setsockopt(sock, SOL_SOCKET, SO_LINGER, (void*)&linger, sizeof(linger));

		/* disable nagle */
		setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void*)&val, sizeof(val));

		if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) {
			err = errno;
			close(sock);
			TRACE(("bind(%s) failed", port))
			continue;
		}

		if (listen(sock, 20) < 0) {
			err = errno;
			close(sock);
			TRACE(("listen() failed"))
			continue;
		    }
Beispiel #28
0
static int _redisContextConnectTcp(redisContext *c, const char *addr, int port,
                                   const struct timeval *timeout,
                                   const char *source_addr) {
    int s, rv, n;
    char _port[6];  /* strlen("65535"); */
    struct addrinfo hints, *servinfo, *bservinfo, *p, *b;
    int blocking = (c->flags & REDIS_BLOCK);
    int reuseaddr = (c->flags & REDIS_REUSEADDR);
    int reuses = 0;
    long timeout_msec = -1;

    servinfo = NULL;
    c->connection_type = REDIS_CONN_TCP;
    c->tcp.port = port;

    /* We need to take possession of the passed parameters
     * to make them reusable for a reconnect.
     * We also carefully check we don't free data we already own,
     * as in the case of the reconnect method.
     *
     * This is a bit ugly, but atleast it works and doesn't leak memory.
     **/
    if (c->tcp.host != addr) {
        if (c->tcp.host)
            free(c->tcp.host);

        c->tcp.host = strdup(addr);
    }

    if (timeout) {
        if (c->timeout != timeout) {
            if (c->timeout == NULL)
                c->timeout = malloc(sizeof(struct timeval));

            memcpy(c->timeout, timeout, sizeof(struct timeval));
        }
    } else {
        if (c->timeout)
            free(c->timeout);
        c->timeout = NULL;
    }

    if (redisContextTimeoutMsec(c, &timeout_msec) != REDIS_OK) {
        __redisSetError(c, REDIS_ERR_IO, "Invalid timeout specified");
        goto error;
    }

    if (source_addr == NULL) {
        free(c->tcp.source_addr);
        c->tcp.source_addr = NULL;
    } else if (c->tcp.source_addr != source_addr) {
        free(c->tcp.source_addr);
        c->tcp.source_addr = strdup(source_addr);
    }

    snprintf(_port, 6, "%d", port);
    memset(&hints,0,sizeof(hints));
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;

    /* Try with IPv6 if no IPv4 address was found. We do it in this order since
     * in a Redis client you can't afford to test if you have IPv6 connectivity
     * as this would add latency to every connect. Otherwise a more sensible
     * route could be: Use IPv6 if both addresses are available and there is IPv6
     * connectivity. */
    if ((rv = getaddrinfo(c->tcp.host,_port,&hints,&servinfo)) != 0) {
         hints.ai_family = AF_INET6;
         if ((rv = getaddrinfo(addr,_port,&hints,&servinfo)) != 0) {
            __redisSetError(c,REDIS_ERR_OTHER,gai_strerror(rv));
            return REDIS_ERR;
        }
    }
    for (p = servinfo; p != NULL; p = p->ai_next) {
addrretry:
        if ((s = socket(p->ai_family,p->ai_socktype,p->ai_protocol)) == -1)
            continue;

        c->fd = s;
        if (redisSetBlocking(c,0) != REDIS_OK)
            goto error;
        if (c->tcp.source_addr) {
            int bound = 0;
            /* Using getaddrinfo saves us from self-determining IPv4 vs IPv6 */
            if ((rv = getaddrinfo(c->tcp.source_addr, NULL, &hints, &bservinfo)) != 0) {
                char buf[128];
                snprintf(buf,sizeof(buf),"Can't get addr: %s",gai_strerror(rv));
                __redisSetError(c,REDIS_ERR_OTHER,buf);
                goto error;
            }

            if (reuseaddr) {
                n = 1;
                if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*) &n,
                               sizeof(n)) < 0) {
                    goto error;
                }
            }

            for (b = bservinfo; b != NULL; b = b->ai_next) {
                if (bind(s,b->ai_addr,b->ai_addrlen) != -1) {
                    bound = 1;
                    break;
                }
            }
            freeaddrinfo(bservinfo);
            if (!bound) {
                char buf[128];
                snprintf(buf,sizeof(buf),"Can't bind socket: %s",strerror(errno));
                __redisSetError(c,REDIS_ERR_OTHER,buf);
                goto error;
            }
        }
        if (connect(s,p->ai_addr,p->ai_addrlen) == -1) {
            if (errno == EHOSTUNREACH) {
                redisContextCloseFd(c);
                continue;
            } else if (errno == EINPROGRESS && !blocking) {
                /* This is ok. */
            } else if (errno == EADDRNOTAVAIL && reuseaddr) {
                if (++reuses >= REDIS_CONNECT_RETRIES) {
                    goto error;
                } else {
                    redisContextCloseFd(c);
                    goto addrretry;
                }
            } else {
                if (redisContextWaitReady(c,timeout_msec) != REDIS_OK)
                    goto error;
            }
        }
        if (blocking && redisSetBlocking(c,1) != REDIS_OK)
            goto error;
        if (redisSetTcpNoDelay(c) != REDIS_OK)
            goto error;

        c->flags |= REDIS_CONNECTED;
        rv = REDIS_OK;
        goto end;
    }
    if (p == NULL) {
        char buf[128];
        snprintf(buf,sizeof(buf),"Can't create socket: %s",strerror(errno));
        __redisSetError(c,REDIS_ERR_OTHER,buf);
        goto error;
    }

error:
    rv = REDIS_ERR;
end:
    freeaddrinfo(servinfo);
    return rv;  // Need to return REDIS_OK if alright
}
Beispiel #29
0
static int socksetup(char *listen_addr, int listen_port, int **socklist_p)
{
	int socknum = 0, *socklist = NULL;
	int maxfd = -1;
	char pbuf[NI_MAXSERV];
	struct addrinfo hints, *ai0, *ai;
	int gai;
	long flags;

	sprintf(pbuf, "%d", listen_port);
	memset(&hints, 0, sizeof(hints));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;
	hints.ai_flags = AI_PASSIVE;

	gai = getaddrinfo(listen_addr, pbuf, &hints, &ai0);
	if (gai)
		die("getaddrinfo() failed: %s\n", gai_strerror(gai));

	for (ai = ai0; ai; ai = ai->ai_next) {
		int sockfd;

		sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
		if (sockfd < 0)
			continue;
		if (sockfd >= FD_SETSIZE) {
			error("too large socket descriptor.");
			close(sockfd);
			continue;
		}

#ifdef IPV6_V6ONLY
		if (ai->ai_family == AF_INET6) {
			int on = 1;
			setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY,
				   &on, sizeof(on));
			/* Note: error is not fatal */
		}
#endif

		if (set_reuse_addr(sockfd)) {
			close(sockfd);
			continue;
		}

		if (bind(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) {
			close(sockfd);
			continue;	/* not fatal */
		}
		if (listen(sockfd, 5) < 0) {
			close(sockfd);
			continue;	/* not fatal */
		}

		flags = fcntl(sockfd, F_GETFD, 0);
		if (flags >= 0)
			fcntl(sockfd, F_SETFD, flags | FD_CLOEXEC);

		socklist = xrealloc(socklist, sizeof(int) * (socknum + 1));
		socklist[socknum++] = sockfd;

		if (maxfd < sockfd)
			maxfd = sockfd;
	}

	freeaddrinfo(ai0);

	*socklist_p = socklist;
	return socknum;
}
Beispiel #30
0
int resolve_host(const char *host, struct addrinfo **ai, char use_ipv6, int portnr)
{
	int rc = -1;
	char servname[10];
	struct addrinfo myaddr;

	memset(&myaddr, 0, sizeof myaddr);

	/* myaddr.ai_flags = AI_PASSIVE; */
	myaddr.ai_socktype = SOCK_STREAM;
	myaddr.ai_protocol = IPPROTO_TCP;
	myaddr.ai_family = use_ipv6 ? AF_INET6 : AF_INET;
	snprintf(servname, sizeof servname, "%d", portnr);

	rc = getaddrinfo(host, servname, &myaddr, ai);

	if (rc != 0)
		set_error(gettext("Resolving %s %sfailed: %s"), host, use_ipv6 ? gettext("(IPv6) ") : "", gai_strerror(rc));

	return rc;
}