Sock * Sock_connect(char *host, char *port, Sock *binded, sock_type socktype, sock_flags ssl_flag)
{
    Sock *s;
    char remote_host[128]; /*Unix Domain is largest*/
    char local_host[128]; /*Unix Domain is largest*/
    int sockfd = -1;
    struct sockaddr *sa_p = NULL;
    socklen_t sa_len = 0;
    int32_t local_port;
    int32_t remote_port;
#if HAVE_SSL
    SSL *ssl_con;
#endif

    if(binded) {
        sockfd = binded->fd;
    }

    if (sock_connect(host, port, &sockfd, socktype)) {
            net_log(NET_LOG_ERR, "Sock_connect() failure.\n");
            return NULL;
    }

#if HAVE_SSL
    if(ssl_flag & IS_SSL) {
        if (sock_SSL_connect(&ssl_con))
            net_log (NET_LOG_ERR, "Sock_connect() failure in SSL init.\n");
            sock_close(sockfd);
            return NULL;
    }
    else
#endif


    if (binded) {
        s = binded;
        free(s->local_host);
        s->local_host = NULL;
        free(s->remote_host);
        s->remote_host = NULL;
    } else if (!(s = calloc(1, sizeof(Sock)))) {
        net_log(NET_LOG_FATAL, "Unable to allocate a Sock struct in Sock_connect().\n");
#if HAVE_SSL
        if(ssl_flag & IS_SSL) 
            sock_SSL_close(ssl_con);
#endif
        sock_close (sockfd);
        return NULL;
    }

    s->fd = sockfd;
    s->socktype = socktype;
#if HAVE_SSL
    if(ssl_flag & IS_SSL) 
        s->ssl = ssl_con;
#endif
    s->flags = ssl_flag;

    sa_p = (struct sockaddr *) &(s->local_stg);
    sa_len = sizeof(struct sockaddr_storage);

    if(getsockname(s->fd, sa_p, &sa_len))
    {
        net_log(NET_LOG_ERR, "Unable to get remote port in Sock_connect().\n");
        Sock_close(s);
        return NULL;
    }

    if(!sock_ntop_host(sa_p, local_host, sizeof(local_host)))
        memset(local_host, 0, sizeof(local_host));

    if (!(s->local_host = strdup(local_host))) {
        net_log(NET_LOG_FATAL, "Unable to allocate local host in Sock_connect().\n");
        Sock_close(s);
        return NULL;
    }

    local_port = sock_get_port(sa_p);

    if(local_port < 0) {
        net_log(NET_LOG_ERR, "Unable to get local port in Sock_connect().\n");
        Sock_close(s);
        return NULL;
    } else
        s->local_port = ntohs(local_port);

    sa_p = (struct sockaddr *) &(s->remote_stg);
    sa_len = sizeof(struct sockaddr_storage);

    if(getpeername(s->fd, sa_p, &sa_len))
    {
        net_log(NET_LOG_ERR, "Unable to get remote address in Sock_connect().\n");
        Sock_close(s);
        return NULL;
    }

    if(!sock_ntop_host(sa_p, remote_host, sizeof(remote_host)))
        memset(remote_host, 0, sizeof(remote_host));
    
    if (!(s->remote_host = strdup(remote_host))) {
        net_log(NET_LOG_FATAL, "Unable to allocate remote host in Sock_connect().\n");
        Sock_close(s);
        return NULL;
    }

    remote_port = sock_get_port(sa_p);
    if(remote_port < 0) {
        net_log(NET_LOG_ERR, "Unable to get remote port in Sock_connect().\n");
        Sock_close(s);
        return NULL;
    } else
        s->remote_port = ntohs(remote_port);

    net_log(NET_LOG_DEBUG, "Socket connected between local=\"%s\":%u and "
        "remote=\"%s\":%u.\n", s->local_host, s->local_port, s->remote_host,
        s->remote_port);

    if(is_multicast_address(sa_p, s->remote_stg.ss_family)) {
        //fprintf(stderr,"IS MULTICAST\n");
        if(mcast_join(s->fd, sa_p, NULL, 0, &(s->addr))!=0) {
            Sock_close(s);
            return NULL;
        }
        s->flags |= IS_MULTICAST;
    }

    return s;
}
示例#2
0
int main(int argc, char *argv[])
{
	int s;
	int t;
	int addrl;
	struct sockaddr_in sa;
	struct sockaddr_in ca;
	FILE *f;

	// готовим сервер
	// заполняем поля локального адреса
	bzero(&sa, sizeof(struct sockaddr_in));
	sa.sin_family = AF_INET;
	sa.sin_addr.s_addr = INADDR_ANY;
	sa.sin_port = 0;

	// процедура создания и связывания
	s = socket(AF_INET, SOCK_STREAM, 0);
	bind(s, (struct sockaddr *) &sa, sizeof(struct sockaddr_in));
	printf("Ready to answer querys on %s\n", inet_ntoa(sa.sin_addr));

	socklen_t len = sizeof(sa);
	getsockname(s, (struct sockaddr_in *) &sa, &len);
	printf("Listen on port: %d\n", ntohs(sa.sin_port));

	// устанавливаем очередь размером 35767 запросов
	listen(s, 35767);

	// обработка сигнала SIGCHLD
	signal(SIGCHLD, zombiehunter);

	for (;;) {
		// ждем клиентские запросы
		bzero(&ca, sizeof(ca));
		addrl = sizeof(ca);

		// принимаем запрос и дублируем сокет s в t для
		// дальнейшей обработки
		t = accept(s, (struct sockaddr *) &ca, &addrl);
		printf("Got connection from %s\n", inet_ntoa(ca.sin_addr));

		switch(fork()) {
		case -1:
			perror("fork");
			close(s);
			close(t);
			exit(1);

		case 0:
			// внутри процесса-обработчика
			// в клиенте не нужен основной сокет
			close(s);
			int rb;
			char buffer[64];
			char fileName[512];
			strcpy(fileName, "/tmp/lab2_server.XXXXXX");
			mkstemp(fileName);

			f = fopen(fileName, "wb");

			while ((rb = recv(t, buffer, sizeof(buffer), 0)) != 0) {
				fwrite(buffer, rb, 1, f);
			}

			fcloseall();
			exit(0);

		default:
			// в родителе не нужнен сокет-дубликат
			close(t);
			continue;
		}
	}

	close(s);
	return 0;
}
int serveur_tcp (const char * nom_service)
{
	int err;
	int sock_serveur;
	int sock_connectee;
	struct addrinfo  hints;
	struct addrinfo *results;

	struct sockaddr_in * addr_in;
	socklen_t length = 0;
	char hostname [NI_MAXHOST];
	char servname [NI_MAXSERV];

	// Creer la socket serveur et lui attribuer un numero de service.
	if ((sock_serveur = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
		perror("socket");
		return -1;
	}

	memset(&hints, 0, sizeof(hints));
	hints.ai_family = AF_INET;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_flags = AI_PASSIVE;
	if ((err = getaddrinfo(NULL, nom_service,  &hints, &results)) != 0) {
		fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(err));
		close(sock_serveur);
		return -1;
	}

	err = bind(sock_serveur, results->ai_addr, results->ai_addrlen);
	freeaddrinfo(results);
	if (err < 0) {
		perror("bind");
		close(sock_serveur);
		return -1;
	}

	// Afficher notre adresse locale.
	fprintf(stdout, "Mon adresse >> ");
	length = sizeof(struct sockaddr_in);
	if (getsockname(sock_serveur, (struct sockaddr *) &addr_in, &length) < 0) {
		perror ("getsockname");
		return -1;
	}
	if (getnameinfo((struct sockaddr *) &addr_in, length,
	                hostname, NI_MAXHOST,
	                servname, NI_MAXSERV,
	                NI_NUMERICHOST | NI_NUMERICSERV) == 0) 
		fprintf (stdout, "IP = %s, Port = %s \n", hostname, servname);

	listen(sock_serveur, 5);

	while (! quitter_le_serveur()) {
		sock_connectee = accept(sock_serveur, NULL, NULL);
		if (sock_connectee < 0) {
			perror("accept");
			return -1;
		}
		switch (fork()) {
			case 0 : // fils
				close(sock_serveur);
				traite_connexion(sock_connectee);
				exit(EXIT_SUCCESS);
			case -1 :
				perror("fork");
				return -1;
			default : // pere
				close(sock_connectee);
		}
	}
	return 0;
}
示例#4
0
/*----------------------------------------------------------------------*
                         rtp_net_setmembership
 *----------------------------------------------------------------------*/
int rtp_net_setmembership (RTP_HANDLE sockHandle, unsigned char * ipAddr, int type, unsigned int onBool)
{
#ifdef LINUXTOBEIMPLEMENTED
    struct sockaddr_in localAddr;
    int result;
    int localLen;
    struct ip_mreq mcreq;
    unsigned long in_addr = 0;

    localLen = sizeof(localAddr);
    memset(&localAddr, 0, localLen);
    memset( ( void * )&mcreq, 0, sizeof( struct ip_mreq ) );

    if (ipAddr)
    {
        unsigned char *ptr = (unsigned char *) &in_addr;

        if (type == RTP_NET_TYPE_IPV4)
        {
            ptr[0] = ipAddr[0];
            ptr[1] = ipAddr[1];
            ptr[2] = ipAddr[2];
            ptr[3] = ipAddr[3];
        }
        else
        {
            /* ----------------------------------- */
            /* RTP_NET_TYPE_IPV6 not yet supported */
            /* ----------------------------------- */
            return (-1);
        }
    }
    else
    {
        in_addr = INADDR_ANY;
    }

#ifdef RTP_DEBUG
    /* ----------------------------------- */
    /*  Clear the error state by setting   */
    /*  to 0.                              */
    /* ----------------------------------- */
    WSASetLastError (0);
#endif

    if (getsockname ((SOCKET) sockHandle, (struct sockaddr *) &localAddr, (int *) &localLen) != 0)
    {
#ifdef RTP_DEBUG
        result = WSAGetLastError();
        RTP_DEBUG_OUTPUT_STR("rtp_net_setmembership: error returned ");
        RTP_DEBUG_OUTPUT_INT(result);
        RTP_DEBUG_OUTPUT_STR(".\n");
#endif
        return (-1);
    }

    memmove(&mcreq.imr_multiaddr.s_addr, &in_addr, 4);
    memmove(&mcreq.imr_interface.s_addr, &localAddr.sin_addr.s_addr, 4);

    if (onBool)
    {
        result = setsockopt((int) sockHandle, IPPROTO_IP,
                            IP_ADD_MEMBERSHIP, (const char *)&mcreq,
                            sizeof( struct ip_mreq ));
    }
    else
    {
        result = setsockopt((int) sockHandle, IPPROTO_IP,
                            IP_DROP_MEMBERSHIP, (const char *)&mcreq,
                            sizeof( struct ip_mreq ));
    }

    if (result != 0)
    {
#ifdef RTP_DEBUG
        result = WSAGetLastError();
        RTP_DEBUG_OUTPUT_STR("rtp_net_setmembership: error returned ");
        RTP_DEBUG_OUTPUT_INT(result);
        RTP_DEBUG_OUTPUT_STR(".\n");
#endif
        return (-1);
    }
    return (0);
#else
    return (0);
#endif
}
示例#5
0
int MAIN(int argc, char **argv)
	{
	int off=0;
	SSL *con=NULL,*con2=NULL;
	X509_STORE *store = NULL;
	int s,k,width,state=0;
	char *cbuf=NULL,*sbuf=NULL,*mbuf=NULL;
	int cbuf_len,cbuf_off;
	int sbuf_len,sbuf_off;
	fd_set readfds,writefds;
	short port=PORT;
	int full_log=1;
	char *host=SSL_HOST_NAME;
	char *cert_file=NULL,*key_file=NULL;
	int cert_format = FORMAT_PEM, key_format = FORMAT_PEM;
	char *passarg = NULL, *pass = NULL;
	X509 *cert = NULL;
	EVP_PKEY *key = NULL;
	char *CApath=NULL,*CAfile=NULL,*cipher=NULL;
	int reconnect=0,badop=0,verify=SSL_VERIFY_NONE,bugs=0;
	int crlf=0;
	int write_tty,read_tty,write_ssl,read_ssl,tty_on,ssl_pending;
	SSL_CTX *ctx=NULL;
	int ret=1,in_init=1,i,nbio_test=0;
	int starttls_proto = 0;
	int prexit = 0, vflags = 0;
	SSL_METHOD *meth=NULL;
#ifdef sock_type
#undef sock_type
#endif
	int sock_type=SOCK_STREAM;
	BIO *sbio;
	char *inrand=NULL;
#ifndef OPENSSL_NO_ENGINE
	char *engine_id=NULL;
	ENGINE *e=NULL;
#endif
#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE)
	struct timeval tv;
#endif

	struct sockaddr peer;
	int peerlen = sizeof(peer);
	int enable_timeouts = 0 ;
	long mtu = 0;

#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
	meth=SSLv23_client_method();
#elif !defined(OPENSSL_NO_SSL3)
	meth=SSLv3_client_method();
#elif !defined(OPENSSL_NO_SSL2)
	meth=SSLv2_client_method();
#endif

	apps_startup();
	c_Pause=0;
	c_quiet=0;
	c_ign_eof=0;
	c_debug=0;
	c_msg=0;
	c_showcerts=0;

	if (bio_err == NULL)
		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);

	if (!load_config(bio_err, NULL))
		goto end;

	if (	((cbuf=OPENSSL_malloc(BUFSIZZ)) == NULL) ||
		((sbuf=OPENSSL_malloc(BUFSIZZ)) == NULL) ||
		((mbuf=OPENSSL_malloc(BUFSIZZ)) == NULL))
		{
		BIO_printf(bio_err,"out of memory\n");
		goto end;
		}

	verify_depth=0;
	verify_error=X509_V_OK;
#ifdef FIONBIO
	c_nbio=0;
#endif

	argc--;
	argv++;
	while (argc >= 1)
		{
		if	(strcmp(*argv,"-host") == 0)
			{
			if (--argc < 1) goto bad;
			host= *(++argv);
			}
		else if	(strcmp(*argv,"-port") == 0)
			{
			if (--argc < 1) goto bad;
			port=atoi(*(++argv));
			if (port == 0) goto bad;
			}
		else if (strcmp(*argv,"-connect") == 0)
			{
			if (--argc < 1) goto bad;
			if (!extract_host_port(*(++argv),&host,NULL,&port))
				goto bad;
			}
		else if	(strcmp(*argv,"-verify") == 0)
			{
			verify=SSL_VERIFY_PEER;
			if (--argc < 1) goto bad;
			verify_depth=atoi(*(++argv));
			BIO_printf(bio_err,"verify depth is %d\n",verify_depth);
			}
		else if	(strcmp(*argv,"-cert") == 0)
			{
			if (--argc < 1) goto bad;
			cert_file= *(++argv);
			}
		else if	(strcmp(*argv,"-certform") == 0)
			{
			if (--argc < 1) goto bad;
			cert_format = str2fmt(*(++argv));
			}
		else if	(strcmp(*argv,"-crl_check") == 0)
			vflags |= X509_V_FLAG_CRL_CHECK;
		else if	(strcmp(*argv,"-crl_check_all") == 0)
			vflags |= X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL;
		else if	(strcmp(*argv,"-prexit") == 0)
			prexit=1;
		else if	(strcmp(*argv,"-crlf") == 0)
			crlf=1;
		else if	(strcmp(*argv,"-quiet") == 0)
			{
			c_quiet=1;
			c_ign_eof=1;
			}
		else if	(strcmp(*argv,"-ign_eof") == 0)
			c_ign_eof=1;
		else if	(strcmp(*argv,"-pause") == 0)
			c_Pause=1;
		else if	(strcmp(*argv,"-debug") == 0)
			c_debug=1;
#ifdef WATT32
		else if (strcmp(*argv,"-wdebug") == 0)
			dbug_init();
#endif
		else if	(strcmp(*argv,"-msg") == 0)
			c_msg=1;
		else if	(strcmp(*argv,"-showcerts") == 0)
			c_showcerts=1;
		else if	(strcmp(*argv,"-nbio_test") == 0)
			nbio_test=1;
		else if	(strcmp(*argv,"-state") == 0)
			state=1;
#ifndef OPENSSL_NO_SSL2
		else if	(strcmp(*argv,"-ssl2") == 0)
			meth=SSLv2_client_method();
#endif
#ifndef OPENSSL_NO_SSL3
		else if	(strcmp(*argv,"-ssl3") == 0)
			meth=SSLv3_client_method();
#endif
#ifndef OPENSSL_NO_TLS1
		else if	(strcmp(*argv,"-tls1") == 0)
			meth=TLSv1_client_method();
#endif
#ifndef OPENSSL_NO_DTLS1
		else if	(strcmp(*argv,"-dtls1") == 0)
			{
			meth=DTLSv1_client_method();
			sock_type=SOCK_DGRAM;
			}
		else if (strcmp(*argv,"-timeout") == 0)
			enable_timeouts=1;
		else if (strcmp(*argv,"-mtu") == 0)
			{
			if (--argc < 1) goto bad;
			mtu = atol(*(++argv));
			}
#endif
		else if (strcmp(*argv,"-bugs") == 0)
			bugs=1;
		else if	(strcmp(*argv,"-keyform") == 0)
			{
			if (--argc < 1) goto bad;
			key_format = str2fmt(*(++argv));
			}
		else if	(strcmp(*argv,"-pass") == 0)
			{
			if (--argc < 1) goto bad;
			passarg = *(++argv);
			}
		else if	(strcmp(*argv,"-key") == 0)
			{
			if (--argc < 1) goto bad;
			key_file= *(++argv);
			}
		else if	(strcmp(*argv,"-reconnect") == 0)
			{
			reconnect=5;
			}
		else if	(strcmp(*argv,"-CApath") == 0)
			{
			if (--argc < 1) goto bad;
			CApath= *(++argv);
			}
		else if	(strcmp(*argv,"-CAfile") == 0)
			{
			if (--argc < 1) goto bad;
			CAfile= *(++argv);
			}
		else if (strcmp(*argv,"-no_tls1") == 0)
			off|=SSL_OP_NO_TLSv1;
		else if (strcmp(*argv,"-no_ssl3") == 0)
			off|=SSL_OP_NO_SSLv3;
		else if (strcmp(*argv,"-no_ssl2") == 0)
			off|=SSL_OP_NO_SSLv2;
		else if (strcmp(*argv,"-serverpref") == 0)
			off|=SSL_OP_CIPHER_SERVER_PREFERENCE;
		else if	(strcmp(*argv,"-cipher") == 0)
			{
			if (--argc < 1) goto bad;
			cipher= *(++argv);
			}
#ifdef FIONBIO
		else if (strcmp(*argv,"-nbio") == 0)
			{ c_nbio=1; }
#endif
		else if	(strcmp(*argv,"-starttls") == 0)
			{
			if (--argc < 1) goto bad;
			++argv;
			if (strcmp(*argv,"smtp") == 0)
				starttls_proto = 1;
			else if (strcmp(*argv,"pop3") == 0)
				starttls_proto = 2;
			else
				goto bad;
			}
#ifndef OPENSSL_NO_ENGINE
		else if	(strcmp(*argv,"-engine") == 0)
			{
			if (--argc < 1) goto bad;
			engine_id = *(++argv);
			}
#endif
		else if (strcmp(*argv,"-rand") == 0)
			{
			if (--argc < 1) goto bad;
			inrand= *(++argv);
			}
		else
			{
			BIO_printf(bio_err,"unknown option %s\n",*argv);
			badop=1;
			break;
			}
		argc--;
		argv++;
		}
	if (badop)
		{
bad:
		sc_usage();
		goto end;
		}

	OpenSSL_add_ssl_algorithms();
	SSL_load_error_strings();

#ifndef OPENSSL_NO_ENGINE
        e = setup_engine(bio_err, engine_id, 1);
#endif
	if (!app_passwd(bio_err, passarg, NULL, &pass, NULL))
		{
		BIO_printf(bio_err, "Error getting password\n");
		goto end;
		}

	if (key_file == NULL)
		key_file = cert_file;


	if (key_file)

		{

		key = load_key(bio_err, key_file, key_format, 0, pass, e,
			       "client certificate private key file");
		if (!key)
			{
			ERR_print_errors(bio_err);
			goto end;
			}

		}

	if (cert_file)

		{
		cert = load_cert(bio_err,cert_file,cert_format,
				NULL, e, "client certificate file");

		if (!cert)
			{
			ERR_print_errors(bio_err);
			goto end;
			}
		}

	if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL
		&& !RAND_status())
		{
		BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n");
		}
	if (inrand != NULL)
		BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
			app_RAND_load_files(inrand));

	if (bio_c_out == NULL)
		{
		if (c_quiet && !c_debug && !c_msg)
			{
			bio_c_out=BIO_new(BIO_s_null());
			}
		else
			{
			if (bio_c_out == NULL)
				bio_c_out=BIO_new_fp(stdout,BIO_NOCLOSE);
				
			}
		}

	ctx=SSL_CTX_new(meth);
	if (ctx == NULL)
		{
		ERR_print_errors(bio_err);
		goto end;
		}

	if (bugs)
		SSL_CTX_set_options(ctx,SSL_OP_ALL|off);
	else
		SSL_CTX_set_options(ctx,off);
	/* DTLS: partial reads end up discarding unread UDP bytes :-( 
	 * Setting read ahead solves this problem.
	 */
	if (sock_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1);

	if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
	if (cipher != NULL)
		if(!SSL_CTX_set_cipher_list(ctx,cipher)) {
		BIO_printf(bio_err,"error setting cipher list\n");
		ERR_print_errors(bio_err);
		goto end;
	}
#if 0
	else
		SSL_CTX_set_cipher_list(ctx,getenv("SSL_CIPHER"));
#endif

	SSL_CTX_set_verify(ctx,verify,verify_callback);
	if (!set_cert_key_stuff(ctx,cert,key))
		goto end;

	if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) ||
		(!SSL_CTX_set_default_verify_paths(ctx)))
		{
		/* BIO_printf(bio_err,"error setting default verify locations\n"); */
		ERR_print_errors(bio_err);
		/* goto end; */
		}

	store = SSL_CTX_get_cert_store(ctx);
	X509_STORE_set_flags(store, vflags);

	con=SSL_new(ctx);
#ifndef OPENSSL_NO_KRB5
	if (con  &&  (con->kssl_ctx = kssl_ctx_new()) != NULL)
                {
                kssl_ctx_setstring(con->kssl_ctx, KSSL_SERVER, host);
		}
#endif	/* OPENSSL_NO_KRB5  */
/*	SSL_set_cipher_list(con,"RC4-MD5"); */

re_start:

	if (init_client(&s,host,port,sock_type) == 0)
		{
		BIO_printf(bio_err,"connect:errno=%d\n",get_last_socket_error());
		SHUTDOWN(s);
		goto end;
		}
	BIO_printf(bio_c_out,"CONNECTED(%08X)\n",s);

#ifdef FIONBIO
	if (c_nbio)
		{
		unsigned long l=1;
		BIO_printf(bio_c_out,"turning on non blocking io\n");
		if (BIO_socket_ioctl(s,FIONBIO,&l) < 0)
			{
			ERR_print_errors(bio_err);
			goto end;
			}
		}
#endif                                              
	if (c_Pause & 0x01) con->debug=1;

	if ( SSL_version(con) == DTLS1_VERSION)
		{
		struct timeval timeout;

		sbio=BIO_new_dgram(s,BIO_NOCLOSE);
		if (getsockname(s, &peer, (void *)&peerlen) < 0)
			{
			BIO_printf(bio_err, "getsockname:errno=%d\n",
				get_last_socket_error());
			SHUTDOWN(s);
			goto end;
			}

		BIO_ctrl_set_connected(sbio, 1, &peer);

		if ( enable_timeouts)
			{
			timeout.tv_sec = 0;
			timeout.tv_usec = DGRAM_RCV_TIMEOUT;
			BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
			
			timeout.tv_sec = 0;
			timeout.tv_usec = DGRAM_SND_TIMEOUT;
			BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
			}

		if ( mtu > 0)
			{
			SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
			SSL_set_mtu(con, mtu);
			}
		else
			/* want to do MTU discovery */
			BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);
		}
	else
		sbio=BIO_new_socket(s,BIO_NOCLOSE);



	if (nbio_test)
		{
		BIO *test;

		test=BIO_new(BIO_f_nbio_test());
		sbio=BIO_push(test,sbio);
		}

	if (c_debug)
		{
		con->debug=1;
		BIO_set_callback(sbio,bio_dump_callback);
		BIO_set_callback_arg(sbio,(char*)bio_c_out);
		}
	if (c_msg)
		{
		SSL_set_msg_callback(con, msg_cb);
		SSL_set_msg_callback_arg(con, bio_c_out);
		}

	SSL_set_bio(con,sbio,sbio);
	SSL_set_connect_state(con);

	/* ok, lets connect */
	width=SSL_get_fd(con)+1;

	read_tty=1;
	write_tty=0;
	tty_on=0;
	read_ssl=1;
	write_ssl=1;
	
	cbuf_len=0;
	cbuf_off=0;
	sbuf_len=0;
	sbuf_off=0;

	/* This is an ugly hack that does a lot of assumptions */
	if (starttls_proto == 1)
		{
		BIO_read(sbio,mbuf,BUFSIZZ);
		BIO_printf(sbio,"STARTTLS\r\n");
		BIO_read(sbio,sbuf,BUFSIZZ);
		}
	if (starttls_proto == 2)
		{
		BIO_read(sbio,mbuf,BUFSIZZ);
		BIO_printf(sbio,"STLS\r\n");
		BIO_read(sbio,sbuf,BUFSIZZ);
		}

	for (;;)
		{
		FD_ZERO(&readfds);
		FD_ZERO(&writefds);

		if (SSL_in_init(con) && !SSL_total_renegotiations(con))
			{
			in_init=1;
			tty_on=0;
			}
		else
			{
			tty_on=1;
			if (in_init)
				{
				in_init=0;
				print_stuff(bio_c_out,con,full_log);
				if (full_log > 0) full_log--;

				if (starttls_proto)
					{
					BIO_printf(bio_err,"%s",mbuf);
					/* We don't need to know any more */
					starttls_proto = 0;
					}

				if (reconnect)
					{
					reconnect--;
					BIO_printf(bio_c_out,"drop connection and then reconnect\n");
					SSL_shutdown(con);
					SSL_set_connect_state(con);
					SHUTDOWN(SSL_get_fd(con));
					goto re_start;
					}
				}
			}

		ssl_pending = read_ssl && SSL_pending(con);

		if (!ssl_pending)
			{
#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE)
			if (tty_on)
				{
				if (read_tty)  FD_SET(fileno(stdin),&readfds);
				if (write_tty) FD_SET(fileno(stdout),&writefds);
				
				}
			if (read_ssl)
				FD_SET(SSL_get_fd(con),&readfds);
			if (write_ssl)
				FD_SET(SSL_get_fd(con),&writefds);
#else
			if(!tty_on || !write_tty) {
				if (read_ssl)
					FD_SET(SSL_get_fd(con),&readfds);
				if (write_ssl)
					FD_SET(SSL_get_fd(con),&writefds);
			}
#endif
/*			printf("mode tty(%d %d%d) ssl(%d%d)\n",
				tty_on,read_tty,write_tty,read_ssl,write_ssl);*/

			/* Note: under VMS with SOCKETSHR the second parameter
			 * is currently of type (int *) whereas under other
			 * systems it is (void *) if you don't have a cast it
			 * will choke the compiler: if you do have a cast then
			 * you can either go for (int *) or (void *).
			 */
#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
                        /* Under Windows/DOS we make the assumption that we can
			 * always write to the tty: therefore if we need to
			 * write to the tty we just fall through. Otherwise
			 * we timeout the select every second and see if there
			 * are any keypresses. Note: this is a hack, in a proper
			 * Windows application we wouldn't do this.
			 */
			i=0;
			if(!write_tty) {
				if(read_tty) {
					tv.tv_sec = 1;
					tv.tv_usec = 0;
					i=select(width,(void *)&readfds,(void *)&writefds,
						 NULL,&tv);
#if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS)
					if(!i && (!_kbhit() || !read_tty) ) continue;
#else
					if(!i && (!((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0))) || !read_tty) ) continue;
#endif
				} else 	i=select(width,(void *)&readfds,(void *)&writefds,
					 NULL,NULL);
			}
#elif defined(OPENSSL_SYS_NETWARE)
			if(!write_tty) {
				if(read_tty) {
					tv.tv_sec = 1;
					tv.tv_usec = 0;
					i=select(width,(void *)&readfds,(void *)&writefds,
						NULL,&tv);
				} else 	i=select(width,(void *)&readfds,(void *)&writefds,
					NULL,NULL);
			}
#else
			i=select(width,(void *)&readfds,(void *)&writefds,
				 NULL,NULL);
#endif
			if ( i < 0)
				{
				BIO_printf(bio_err,"bad select %d\n",
				get_last_socket_error());
				goto shut;
				/* goto end; */
				}
			}

		if (!ssl_pending && FD_ISSET(SSL_get_fd(con),&writefds))
			{
			k=SSL_write(con,&(cbuf[cbuf_off]),
				(unsigned int)cbuf_len);
			switch (SSL_get_error(con,k))
				{
			case SSL_ERROR_NONE:
				cbuf_off+=k;
				cbuf_len-=k;
				if (k <= 0) goto end;
				/* we have done a  write(con,NULL,0); */
				if (cbuf_len <= 0)
					{
					read_tty=1;
					write_ssl=0;
					}
				else /* if (cbuf_len > 0) */
					{
					read_tty=0;
					write_ssl=1;
					}
				break;
			case SSL_ERROR_WANT_WRITE:
				BIO_printf(bio_c_out,"write W BLOCK\n");
				write_ssl=1;
				read_tty=0;
				break;
			case SSL_ERROR_WANT_READ:
				BIO_printf(bio_c_out,"write R BLOCK\n");
				write_tty=0;
				read_ssl=1;
				write_ssl=0;
				break;
			case SSL_ERROR_WANT_X509_LOOKUP:
				BIO_printf(bio_c_out,"write X BLOCK\n");
				break;
			case SSL_ERROR_ZERO_RETURN:
				if (cbuf_len != 0)
					{
					BIO_printf(bio_c_out,"shutdown\n");
					goto shut;
					}
				else
					{
					read_tty=1;
					write_ssl=0;
					break;
					}
				
			case SSL_ERROR_SYSCALL:
				if ((k != 0) || (cbuf_len != 0))
					{
					BIO_printf(bio_err,"write:errno=%d\n",
						get_last_socket_error());
					goto shut;
					}
				else
					{
					read_tty=1;
					write_ssl=0;
					}
				break;
			case SSL_ERROR_SSL:
				ERR_print_errors(bio_err);
				goto shut;
				}
			}
#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE)
		/* Assume Windows/DOS can always write */
		else if (!ssl_pending && write_tty)
#else

		else if (!ssl_pending && FD_ISSET(fileno(stdout),&writefds))

#endif
			{
#ifdef CHARSET_EBCDIC
			ascii2ebcdic(&(sbuf[sbuf_off]),&(sbuf[sbuf_off]),sbuf_len);
#endif

			i=write(fileno(stdout),&(sbuf[sbuf_off]),sbuf_len);

			if (i <= 0)
				{
				BIO_printf(bio_c_out,"DONE\n");
				goto shut;
				/* goto end; */
				}

			sbuf_len-=i;;
			sbuf_off+=i;
			if (sbuf_len <= 0)
				{
				read_ssl=1;
				write_tty=0;
				}
			}
		else if (ssl_pending || FD_ISSET(SSL_get_fd(con),&readfds))
			{
#ifdef RENEG
{ static int iiii; if (++iiii == 52) { SSL_renegotiate(con); iiii=0; } }
#endif
#if 1
			k=SSL_read(con,sbuf,1024 /* BUFSIZZ */ );
#else
/* Demo for pending and peek :-) */
			k=SSL_read(con,sbuf,16);
{ char zbuf[10240]; 
printf("read=%d pending=%d peek=%d\n",k,SSL_pending(con),SSL_peek(con,zbuf,10240));

}
#endif

			switch (SSL_get_error(con,k))
				{
			case SSL_ERROR_NONE:
				if (k <= 0)
					goto end;
				sbuf_off=0;
				sbuf_len=k;

				read_ssl=0;
				write_tty=1;
				break;
			case SSL_ERROR_WANT_WRITE:
				BIO_printf(bio_c_out,"read W BLOCK\n");
				write_ssl=1;
				read_tty=0;
				break;
			case SSL_ERROR_WANT_READ:
				BIO_printf(bio_c_out,"read R BLOCK\n");
				write_tty=0;
				read_ssl=1;
				if ((read_tty == 0) && (write_ssl == 0))
					write_ssl=1;
				break;
			case SSL_ERROR_WANT_X509_LOOKUP:
				BIO_printf(bio_c_out,"read X BLOCK\n");
				break;
			case SSL_ERROR_SYSCALL:
				BIO_printf(bio_err,"read:errno=%d\n",get_last_socket_error());
				goto shut;
			case SSL_ERROR_ZERO_RETURN:
				BIO_printf(bio_c_out,"closed\n");
				goto shut;
			case SSL_ERROR_SSL:
				ERR_print_errors(bio_err);
				goto shut;
				/* break; */
				}
			}

#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
#if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS)
		else if (_kbhit())
#else
		else if ((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0)))
#endif
#elif defined (OPENSSL_SYS_NETWARE)
        else if (_kbhit())
#else
		else if (FD_ISSET(fileno(stdin),&readfds))
		
#endif
			{
			if (crlf)
				{
				int j, lf_num;
				i=read(fileno(stdin),cbuf,BUFSIZZ/2);
				
				lf_num = 0;
				/* both loops are skipped when i <= 0 */
				for (j = 0; j < i; j++)
					if (cbuf[j] == '\n')
						lf_num++;
				for (j = i-1; j >= 0; j--)
					{
					cbuf[j+lf_num] = cbuf[j];
					if (cbuf[j] == '\n')
						{
						lf_num--;
						i++;
						cbuf[j+lf_num] = '\r';
						}
					}
				assert(lf_num == 0);
				}
			else
				i=read(fileno(stdin),cbuf,BUFSIZZ);

			if ((!c_ign_eof) && ((i <= 0) || (cbuf[0] == 'Q')))
				{
				BIO_printf(bio_err,"DONE\n");
				goto shut;
				}

			if ((!c_ign_eof) && (cbuf[0] == 'R'))
				{
				BIO_printf(bio_err,"RENEGOTIATING\n");
				SSL_renegotiate(con);
				cbuf_len=0;
				}
			else
				{
				cbuf_len=i;
				cbuf_off=0;
#ifdef CHARSET_EBCDIC
				ebcdic2ascii(cbuf, cbuf, i);
#endif
				}

			write_ssl=1;
			read_tty=0;
			}
		}
shut:
	SSL_shutdown(con);
	SHUTDOWN(SSL_get_fd(con));
	ret=0;
end:
	if(prexit) print_stuff(bio_c_out,con,1);
	if (con != NULL) SSL_free(con);
	if (con2 != NULL) SSL_free(con2);
	if (ctx != NULL) SSL_CTX_free(ctx);
	if (cert)
		X509_free(cert);
	if (key)
		EVP_PKEY_free(key);
	if (pass)
		OPENSSL_free(pass);
	if (cbuf != NULL) { OPENSSL_cleanse(cbuf,BUFSIZZ); OPENSSL_free(cbuf); }
	if (sbuf != NULL) { OPENSSL_cleanse(sbuf,BUFSIZZ); OPENSSL_free(sbuf); }
	if (mbuf != NULL) { OPENSSL_cleanse(mbuf,BUFSIZZ); OPENSSL_free(mbuf); }
	if (bio_c_out != NULL)
		{
		BIO_free(bio_c_out);
		bio_c_out=NULL;
		}
	apps_shutdown();
	OPENSSL_EXIT(ret);
	}
int
cliopen(char *host, char *port)
{
	int					fd, i, on;
	char				*protocol;
	unsigned long		inaddr;
	struct sockaddr_in	cli_addr, serv_addr;
	struct servent		*sp;
	struct hostent		*hp;

	protocol = udp ? "udp" : "tcp";

		/* initialize socket address structure */
	bzero((char *) &serv_addr, sizeof(serv_addr));
	serv_addr.sin_family = AF_INET;

		/* see if "port" is a service name or number */
	if ( (i = atoi(port)) == 0) {
		if ( (sp = getservbyname(port, protocol)) == NULL)
			err_quit("getservbyname() error for: %s/%s", port, protocol);

		serv_addr.sin_port = sp->s_port;
	} else
		serv_addr.sin_port = htons(i);

	/*
	 * First try to convert the host name as a dotted-decimal number.
	 * Only if that fails do we call gethostbyname().
	 */

	if ( (inaddr = inet_addr(host)) != INADDR_NONE) {
						/* it's dotted-decimal */
		bcopy((char *) &inaddr, (char *) &serv_addr.sin_addr, sizeof(inaddr));

	} else {
		if ( (hp = gethostbyname(host)) == NULL)
			err_quit("gethostbyname() error for: %s", host);

		bcopy(hp->h_addr, (char *) &serv_addr.sin_addr, hp->h_length);
	}

	if ( (fd = socket(AF_INET, udp ? SOCK_DGRAM : SOCK_STREAM, 0)) < 0)
		err_sys("socket() error");

	if (reuseaddr) {
		on = 1;
		if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
										(char *) &on, sizeof (on)) < 0)
			err_sys("setsockopt of SO_REUSEADDR error");
	}

	/*
	 * User can specify port number for client to bind.  Only real use
	 * is to see a TCP connection initiated by both ends at the same time.
	 * Also, if UDP is being used, we specifically call bind() to assign
	 * an ephemeral port to the socket.
	 */

	if (bindport != 0 || udp) {
		bzero((char *) &cli_addr, sizeof(cli_addr));
		cli_addr.sin_family      = AF_INET;
		cli_addr.sin_addr.s_addr = htonl(INADDR_ANY);	/* wildcard */
		cli_addr.sin_port        = htons(bindport);

		if (bind(fd, (struct sockaddr *) &cli_addr, sizeof(cli_addr)) < 0)
			err_sys("bind() error");
	}

	/* Need to allocate buffers before connect(), since they can affect
	 * TCP options (window scale, etc.).
	 */

	buffers(fd);
	sockopts(fd, 0);	/* may also want to set SO_DEBUG */

	/*
	 * Connect to the server.  Required for TCP, optional for UDP.
	 */

	if (connect(fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
		err_sys("connect() error");

	if (verbose) {
			/* Call getsockname() to find local address bound to socket:
			   TCP ephemeral port was assigned by connect() or bind();
			   UDP ephemeral port was assigned by bind(). */
		i = sizeof(cli_addr);
		if (getsockname(fd, (struct sockaddr *) &cli_addr, &i) < 0)
			err_sys("getsockname() error");

					/* Can't do one fprintf() since inet_ntoa() stores
					   the result in a static location. */
		fprintf(stderr, "connected on %s.%d ",
					INET_NTOA(cli_addr.sin_addr), ntohs(cli_addr.sin_port));
		fprintf(stderr, "to %s.%d\n",
					INET_NTOA(serv_addr.sin_addr), ntohs(serv_addr.sin_port));
	}

	sockopts(fd, 1);	/* some options get set after connect() */

	return(fd);
}
示例#7
0
static curl_socket_t sockdaemon(curl_socket_t sock,
                                unsigned short *listenport)
{
  /* passive daemon style */
  struct sockaddr_in me;
#ifdef ENABLE_IPV6
  struct sockaddr_in6 me6;
#endif /* ENABLE_IPV6 */
  int flag;
  int rc;
  int totdelay = 0;
  int maxretr = 10;
  int delay= 20;
  int attempt = 0;
  int error = 0;

  do {
    attempt++;
    flag = 1;
    rc = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
         (void *)&flag, sizeof(flag));
    if(rc) {
      error = SOCKERRNO;
      logmsg("setsockopt(SO_REUSEADDR) failed with error: (%d) %s",
             error, strerror(error));
      if(maxretr) {
        rc = wait_ms(delay);
        if(rc) {
          /* should not happen */
          error = SOCKERRNO;
          logmsg("wait_ms() failed with error: (%d) %s",
                 error, strerror(error));
          sclose(sock);
          return CURL_SOCKET_BAD;
        }
        if(got_exit_signal) {
          logmsg("signalled to die, exiting...");
          sclose(sock);
          return CURL_SOCKET_BAD;
        }
        totdelay += delay;
        delay *= 2; /* double the sleep for next attempt */
      }
    }
  } while(rc && maxretr--);

  if(rc) {
    logmsg("setsockopt(SO_REUSEADDR) failed %d times in %d ms. Error: (%d) %s",
           attempt, totdelay, error, strerror(error));
    logmsg("Continuing anyway...");
  }

  /* When the specified listener port is zero, it is actually a
     request to let the system choose a non-zero available port. */

#ifdef ENABLE_IPV6
  if(!use_ipv6) {
#endif
    memset(&me, 0, sizeof(me));
    me.sin_family = AF_INET;
    me.sin_addr.s_addr = INADDR_ANY;
    me.sin_port = htons(*listenport);
    rc = bind(sock, (struct sockaddr *) &me, sizeof(me));
#ifdef ENABLE_IPV6
  }
  else {
    memset(&me6, 0, sizeof(me6));
    me6.sin6_family = AF_INET6;
    me6.sin6_addr = in6addr_any;
    me6.sin6_port = htons(*listenport);
    rc = bind(sock, (struct sockaddr *) &me6, sizeof(me6));
  }
#endif /* ENABLE_IPV6 */
  if(rc) {
    error = SOCKERRNO;
    logmsg("Error binding socket: (%d) %s", error, strerror(error));
    sclose(sock);
    return CURL_SOCKET_BAD;
  }

  if(!*listenport) {
    /* The system was supposed to choose a port number, figure out which
       port we actually got and update the listener port value with it. */
    curl_socklen_t la_size;
    struct sockaddr *localaddr;
    struct sockaddr_in localaddr4;
#ifdef ENABLE_IPV6
    struct sockaddr_in6 localaddr6;
    if(!use_ipv6) {
#endif
      la_size = sizeof(localaddr4);
      localaddr = (struct sockaddr *)&localaddr4;
#ifdef ENABLE_IPV6
    }
    else {
      la_size = sizeof(localaddr6);
      localaddr = (struct sockaddr *)&localaddr6;
    }
#endif
    memset(localaddr, 0, (size_t)la_size);
    if(getsockname(sock, localaddr, &la_size) < 0) {
      error = SOCKERRNO;
      logmsg("getsockname() failed with error: (%d) %s",
             error, strerror(error));
      sclose(sock);
      return CURL_SOCKET_BAD;
    }
    switch (localaddr->sa_family) {
    case AF_INET:
      *listenport = ntohs(localaddr4.sin_port);
      break;
#ifdef ENABLE_IPV6
    case AF_INET6:
      *listenport = ntohs(localaddr6.sin6_port);
      break;
#endif
    default:
      break;
    }
    if(!*listenport) {
      /* Real failure, listener port shall not be zero beyond this point. */
      logmsg("Apparently getsockname() succeeded, with listener port zero.");
      logmsg("A valid reason for this failure is a binary built without");
      logmsg("proper network library linkage. This might not be the only");
      logmsg("reason, but double check it before anything else.");
      sclose(sock);
      return CURL_SOCKET_BAD;
    }
  }

  /* start accepting connections */
  rc = listen(sock, 5);
  if(0 != rc) {
    error = SOCKERRNO;
    logmsg("listen() failed with error: (%d) %s",
           error, strerror(error));
    sclose(sock);
    return CURL_SOCKET_BAD;
  }

  return sock;
}
示例#8
0
文件: ftp.c 项目: 20uf/php-src
/* {{{ ftp_getdata
 */
databuf_t*
ftp_getdata(ftpbuf_t *ftp)
{
	int			fd = -1;
	databuf_t		*data;
	php_sockaddr_storage addr;
	struct sockaddr *sa;
	socklen_t		size;
	union ipbox		ipbox;
	char			arg[sizeof("255, 255, 255, 255, 255, 255")];
	struct timeval	tv;


	/* ask for a passive connection if we need one */
	if (ftp->pasv && !ftp_pasv(ftp, 1)) {
		return NULL;
	}
	/* alloc the data structure */
	data = ecalloc(1, sizeof(*data));
	data->listener = -1;
	data->fd = -1;
	data->type = ftp->type;

	sa = (struct sockaddr *) &ftp->localaddr;
	/* bind/listen */
	if ((fd = socket(sa->sa_family, SOCK_STREAM, 0)) == SOCK_ERR) {
		php_error_docref(NULL, E_WARNING, "socket() failed: %s (%d)", strerror(errno), errno);
		goto bail;
	}

	/* passive connection handler */
	if (ftp->pasv) {
		/* clear the ready status */
		ftp->pasv = 1;

		/* connect */
		/* Win 95/98 seems not to like size > sizeof(sockaddr_in) */
		size = php_sockaddr_size(&ftp->pasvaddr);
		tv.tv_sec = ftp->timeout_sec;
		tv.tv_usec = 0;
		if (php_connect_nonb(fd, (struct sockaddr*) &ftp->pasvaddr, size, &tv) == -1) {
			php_error_docref(NULL, E_WARNING, "php_connect_nonb() failed: %s (%d)", strerror(errno), errno);
			goto bail;
		}

		data->fd = fd;

		ftp->data = data;
		return data;
	}


	/* active (normal) connection */

	/* bind to a local address */
	php_any_addr(sa->sa_family, &addr, 0);
	size = php_sockaddr_size(&addr);

	if (bind(fd, (struct sockaddr*) &addr, size) != 0) {
		php_error_docref(NULL, E_WARNING, "bind() failed: %s (%d)", strerror(errno), errno);
		goto bail;
	}

	if (getsockname(fd, (struct sockaddr*) &addr, &size) != 0) {
		php_error_docref(NULL, E_WARNING, "getsockname() failed: %s (%d)", strerror(errno), errno);
		goto bail;
	}

	if (listen(fd, 5) != 0) {
		php_error_docref(NULL, E_WARNING, "listen() failed: %s (%d)", strerror(errno), errno);
		goto bail;
	}

	data->listener = fd;

#if HAVE_IPV6 && HAVE_INET_NTOP
	if (sa->sa_family == AF_INET6) {
		/* need to use EPRT */
		char eprtarg[INET6_ADDRSTRLEN + sizeof("|x||xxxxx|")];
		char out[INET6_ADDRSTRLEN];
		inet_ntop(AF_INET6, &((struct sockaddr_in6*) sa)->sin6_addr, out, sizeof(out));
		snprintf(eprtarg, sizeof(eprtarg), "|2|%s|%hu|", out, ntohs(((struct sockaddr_in6 *) &addr)->sin6_port));

		if (!ftp_putcmd(ftp, "EPRT", eprtarg)) {
			goto bail;
		}

		if (!ftp_getresp(ftp) || ftp->resp != 200) {
			goto bail;
		}

		ftp->data = data;
		return data;
	}
#endif

	/* send the PORT */
	ipbox.ia[0] = ((struct sockaddr_in*) sa)->sin_addr;
	ipbox.s[2] = ((struct sockaddr_in*) &addr)->sin_port;
	snprintf(arg, sizeof(arg), "%u,%u,%u,%u,%u,%u", ipbox.c[0], ipbox.c[1], ipbox.c[2], ipbox.c[3], ipbox.c[4], ipbox.c[5]);

	if (!ftp_putcmd(ftp, "PORT", arg)) {
		goto bail;
	}
	if (!ftp_getresp(ftp) || ftp->resp != 200) {
		goto bail;
	}

	ftp->data = data;
	return data;

bail:
	if (fd != -1) {
		closesocket(fd);
	}
	efree(data);
	return NULL;
}
示例#9
0
void Socket::GetSockName(sockaddr *psa, socklen_t *psaLen)
{
	assert(m_s != INVALID_SOCKET);
	CheckAndHandleError_int("getsockname", getsockname(m_s, psa, psaLen));
}
示例#10
0
/*
 * 功  能:处理客户端发来的数据
 * 参  数:sock_fd, 客户端的套接字
 *         fout, 打开日志文件的句柄
 * 返回值:-1,连接断开
 *         -2,协议格式错误
 *         -3,数据内容错误
 *         -4,无线的参数
 */
int handle_recv(int sock_fd, FILE *fout)
{
    if (0 > sock_fd || NULL == fout) return -4;
    
    char recv_buff[SOCKET_RECV_MAXLEN];
    int recv_len, data_len, temp_len, recv_index, save_errno;

    recv_index = 1;
    recv_len = recv(sock_fd, recv_buff, 8, 0);
    HACK_DEBUG(0, "[%d] recv_buff is \"%s\"\n", recv_index, recv_buff);
    save_errno = errno;
    if (8 == recv_len && 0 == strcmp(recv_buff, "hack:"))
    {
        recv_index = 2;
        recv_len = recv(sock_fd, recv_buff, 10, 0);
        HACK_DEBUG(0, "[%d] recv_buff is \"%s\"\n", recv_index, recv_buff);
        save_errno = errno;
        if (10 == recv_len)
        {
            temp_len = 0;
            data_len = atoi(recv_buff);
            if (0 >= data_len)
            {
               HACK_DEBUG(9, "error, the datalen is %d\n", data_len);
               return -3;
            }

            while(temp_len < data_len)
            {
                int recv_max = (SOCKET_RECV_MAXLEN < (data_len - temp_len)) ? SOCKET_RECV_MAXLEN : data_len;
                recv_index += 1;
                recv_len = recv(sock_fd, recv_buff, recv_max, 0);
                save_errno = errno;
                if (0 > recv_len) break;
                HACK_DEBUG(0, "[%d] date_len=%d, temp_len=%d, recv_len=%d, recv_buff is \"%s\"\n", 
                    recv_index, data_len, temp_len, recv_len, recv_buff);
                if (0 == temp_len)
                {
                    /* get current time */
                    time_t curtime;
                    time(&curtime);
                    struct tm *timeinfo = localtime(&curtime);
                    char time_buff[64];
                    char *format = "[%Y-%m-%d %H:%M:%S] ";
                    strftime(time_buff, sizeof(time_buff), format, timeinfo);
                    /* get socket name */
                    struct sockaddr_in client_address;
                    int namelen = sizeof(client_address);
                    int ret = getsockname(sock_fd, (struct sockaddr *)&client_address, &namelen);
                    char name_buff[64];
                    if ( 0 == ret || namelen == sizeof(client_address))
                    {
                        snprintf(name_buff, 64, "[client_ip=%s, client_port=%d] ", 
                            inet_ntoa(client_address.sin_addr), ntohs(client_address.sin_port));
                    }else
                    {
                        snprintf(name_buff, 64, "[client_ip=0.0.0.0, client_port=0] ");
                    }
                    /* write to file */
                    fwrite(time_buff, strlen(time_buff), 1, fout);
                    fwrite(name_buff, strlen(name_buff), 1, fout);
                    fwrite(recv_buff, recv_len, 1, fout);
                    fwrite("\n", 1, 1, fout);
                    fflush(fout);
                }
                temp_len += recv_len;
            }
            if (temp_len >= data_len) return 0;
        }
    }
    HACK_DEBUG(9, "recv failed (recv_index=%d and recv_len=%d), %s\n", recv_index, recv_len, strerror(errno));
    return 0 == recv_len ? -1 : -2;
}
示例#11
0
static void server_recv_cb(EV_P_ ev_io *w, int revents)
{
    struct server_ctx *server_recv_ctx = (struct server_ctx *)w;
    struct server *server = server_recv_ctx->server;
    struct remote *remote = server->remote;
    char *buf;

    if (remote == NULL) {
        buf = server->buf;
    } else {
        buf = remote->buf;
    }

    ssize_t r;

    r = recv(server->fd, buf, BUF_SIZE, 0);

    if (r == 0) {
        // connection closed
        close_and_free_remote(EV_A_ remote);
        close_and_free_server(EV_A_ server);
        return;
    } else if (r < 0) {
        if (errno == EAGAIN || errno == EWOULDBLOCK) {
            // no data
            // continue to wait for recv
            return;
        } else {
            ERROR("server_recv_cb_recv");
            close_and_free_remote(EV_A_ remote);
            close_and_free_server(EV_A_ server);
            return;
        }
    }

    while (1) {
        // local socks5 server
        if (server->stage == 5) {
            if (remote == NULL) {
                LOGE("invalid remote");
                close_and_free_server(EV_A_ server);
                return;
            }

            if (!remote->direct && remote->send_ctx->connected && auth) {
                remote->buf = ss_gen_hash(remote->buf, &r, remote->hash_buf, &remote->hash_idx, BUF_SIZE);
            }

            // insert shadowsocks header
            if (!remote->direct) {
                remote->buf = ss_encrypt(BUF_SIZE, remote->buf, &r,
                                         server->e_ctx);

                if (remote->buf == NULL) {
                    LOGE("invalid password or cipher");
                    close_and_free_remote(EV_A_ remote);
                    close_and_free_server(EV_A_ server);
                    return;
                }
            }

            if (!remote->send_ctx->connected) {

#ifdef ANDROID
                if (vpn) {
                    if (protect_socket(remote->fd) == -1) {
                        ERROR("protect_socket");
                        close_and_free_remote(EV_A_ remote);
                        close_and_free_server(EV_A_ server);
                        return;
                    }
                }
#endif

                remote->buf_idx = 0;
                remote->buf_len = r;

                if (!fast_open || remote->direct) {
                    // connecting, wait until connected
                    connect(remote->fd, (struct sockaddr *)&(remote->addr), remote->addr_len);

                    // wait on remote connected event
                    ev_io_stop(EV_A_ & server_recv_ctx->io);
                    ev_io_start(EV_A_ & remote->send_ctx->io);
                    ev_timer_start(EV_A_ & remote->send_ctx->watcher);
                } else {
#ifdef TCP_FASTOPEN
                    int s = sendto(remote->fd, remote->buf, r, MSG_FASTOPEN,
                                   (struct sockaddr *)&(remote->addr), remote->addr_len);
                    if (s == -1) {
                        if (errno == EINPROGRESS) {
                            // in progress, wait until connected
                            remote->buf_idx = 0;
                            remote->buf_len = r;
                            ev_io_stop(EV_A_ & server_recv_ctx->io);
                            ev_io_start(EV_A_ & remote->send_ctx->io);
                            return;
                        } else {
                            ERROR("sendto");
                            if (errno == ENOTCONN) {
                                LOGE(
                                    "fast open is not supported on this platform");
                                // just turn it off
                                fast_open = 0;
                            }
                            close_and_free_remote(EV_A_ remote);
                            close_and_free_server(EV_A_ server);
                            return;
                        }
                    } else if (s < r) {
                        remote->buf_len = r - s;
                        remote->buf_idx = s;
                    }

                    // Just connected
                    remote->send_ctx->connected = 1;
                    ev_timer_stop(EV_A_ & remote->send_ctx->watcher);
                    ev_io_start(EV_A_ & remote->recv_ctx->io);
#else
                    // if TCP_FASTOPEN is not defined, fast_open will always be 0
                    LOGE("can't come here");
                    exit(1);
#endif
                }
            } else {
                int s = send(remote->fd, remote->buf, r, 0);
                if (s == -1) {
                    if (errno == EAGAIN || errno == EWOULDBLOCK) {
                        // no data, wait for send
                        remote->buf_idx = 0;
                        remote->buf_len = r;
                        ev_io_stop(EV_A_ & server_recv_ctx->io);
                        ev_io_start(EV_A_ & remote->send_ctx->io);
                        return;
                    } else {
                        ERROR("server_recv_cb_send");
                        close_and_free_remote(EV_A_ remote);
                        close_and_free_server(EV_A_ server);
                        return;
                    }
                } else if (s < r) {
                    remote->buf_len = r - s;
                    remote->buf_idx = s;
                    ev_io_stop(EV_A_ & server_recv_ctx->io);
                    ev_io_start(EV_A_ & remote->send_ctx->io);
                    return;
                }
            }

            // all processed
            return;
        } else if (server->stage == 0) {
            struct method_select_response response;
            response.ver = SVERSION;
            response.method = 0;
            char *send_buf = (char *)&response;
            send(server->fd, send_buf, sizeof(response), 0);
            server->stage = 1;
            return;
        } else if (server->stage == 1) {
            struct socks5_request *request = (struct socks5_request *)buf;

            struct sockaddr_in sock_addr;
            memset(&sock_addr, 0, sizeof(sock_addr));

            int udp_assc = 0;

            if (mode != TCP_ONLY && request->cmd == 3) {
                udp_assc = 1;
                socklen_t addr_len = sizeof(sock_addr);
                getsockname(server->fd, (struct sockaddr *)&sock_addr,
                            &addr_len);
                if (verbose) {
                    LOGI("udp assc request accepted");
                }
            } else if (request->cmd != 1) {
                LOGE("unsupported cmd: %d", request->cmd);
                struct socks5_response response;
                response.ver = SVERSION;
                response.rep = CMD_NOT_SUPPORTED;
                response.rsv = 0;
                response.atyp = 1;
                char *send_buf = (char *)&response;
                send(server->fd, send_buf, 4, 0);
                close_and_free_remote(EV_A_ remote);
                close_and_free_server(EV_A_ server);
                return;
            } else {
                char host[256], port[16];
                char ss_addr_to_send[320];

                ssize_t addr_len = 0;
                ss_addr_to_send[addr_len++] = request->atyp;

                // get remote addr and port
                if (request->atyp == 1) {
                    // IP V4
                    size_t in_addr_len = sizeof(struct in_addr);
                    memcpy(ss_addr_to_send + addr_len, buf + 4, in_addr_len +
                           2);
                    addr_len += in_addr_len + 2;

                    if (acl || verbose) {
                        uint16_t p =
                            ntohs(*(uint16_t *)(buf + 4 + in_addr_len));
                        dns_ntop(AF_INET, (const void *)(buf + 4),
                                 host, INET_ADDRSTRLEN);
                        sprintf(port, "%d", p);
                    }
                } else if (request->atyp == 3) {
                    // Domain name
                    uint8_t name_len = *(uint8_t *)(buf + 4);
                    ss_addr_to_send[addr_len++] = name_len;
                    memcpy(ss_addr_to_send + addr_len, buf + 4 + 1, name_len +
                           2);
                    addr_len += name_len + 2;

                    if (acl || verbose) {
                        uint16_t p =
                            ntohs(*(uint16_t *)(buf + 4 + 1 + name_len));
                        memcpy(host, buf + 4 + 1, name_len);
                        host[name_len] = '\0';
                        sprintf(port, "%d", p);
                    }
                } else if (request->atyp == 4) {
                    // IP V6
                    size_t in6_addr_len = sizeof(struct in6_addr);
                    memcpy(ss_addr_to_send + addr_len, buf + 4, in6_addr_len +
                           2);
                    addr_len += in6_addr_len + 2;

                    if (acl || verbose) {
                        uint16_t p =
                            ntohs(*(uint16_t *)(buf + 4 + in6_addr_len));
                        dns_ntop(AF_INET6, (const void *)(buf + 4),
                                 host, INET6_ADDRSTRLEN);
                        sprintf(port, "%d", p);
                    }
                } else {
                    LOGE("unsupported addrtype: %d", request->atyp);
                    close_and_free_remote(EV_A_ remote);
                    close_and_free_server(EV_A_ server);
                    return;
                }

                server->stage = 5;

                r -= (3 + addr_len);
                buf += (3 + addr_len);

                if (verbose) {
                    LOGI("connect to %s:%s", host, port);
                }

                if ((acl && (request->atyp == 1 || request->atyp == 4) && acl_contains_ip(host))) {
                    if (verbose) {
                        LOGI("bypass %s:%s", host, port);
                    }
                    struct sockaddr_storage storage;
                    memset(&storage, 0, sizeof(struct sockaddr_storage));
                    if (get_sockaddr(host, port, &storage, 0) != -1) {
                        remote = create_remote(server->listener, (struct sockaddr *)&storage);
                        remote->direct = 1;
                    }
                } else {
                    remote = create_remote(server->listener, NULL);
                }

                if (remote == NULL) {
                    LOGE("invalid remote addr");
                    close_and_free_server(EV_A_ server);
                    return;
                }

                if (!remote->direct) {
                    if (auth) {
                        ss_addr_to_send[0] |= ONETIMEAUTH_FLAG;
                        ss_onetimeauth(ss_addr_to_send + addr_len, ss_addr_to_send, addr_len, server->e_ctx);
                        addr_len += ONETIMEAUTH_BYTES;
                    }

                    memcpy(remote->buf, ss_addr_to_send, addr_len);

                    if (auth) {
                        buf = ss_gen_hash(buf, &r, remote->hash_buf, &remote->hash_idx, BUF_SIZE);
                    }

                    if (r > 0) {
                        memcpy(remote->buf + addr_len, buf, r);
                    }
                    r += addr_len;
                } else {
                    if (r > 0) {
                        memcpy(remote->buf, buf, r);
                    }
                }

                server->remote = remote;
                remote->server = server;
            }

            // Fake reply
            struct socks5_response response;
            response.ver = SVERSION;
            response.rep = 0;
            response.rsv = 0;
            response.atyp = 1;

            memcpy(server->buf, &response, sizeof(struct socks5_response));
            memcpy(server->buf + sizeof(struct socks5_response),
                   &sock_addr.sin_addr, sizeof(sock_addr.sin_addr));
            memcpy(server->buf + sizeof(struct socks5_response) +
                   sizeof(sock_addr.sin_addr),
                   &sock_addr.sin_port, sizeof(sock_addr.sin_port));

            int reply_size = sizeof(struct socks5_response) +
                             sizeof(sock_addr.sin_addr) +
                             sizeof(sock_addr.sin_port);
            int s = send(server->fd, server->buf, reply_size, 0);
            if (s < reply_size) {
                LOGE("failed to send fake reply");
                close_and_free_remote(EV_A_ remote);
                close_and_free_server(EV_A_ server);
                return;
            }

            if (udp_assc) {
                close_and_free_remote(EV_A_ remote);
                close_and_free_server(EV_A_ server);
                return;
            }
        }
    }
}
示例#12
0
int main(int argc, char *argv[]) {

	printf(
			"EACCES=%d EACCES=%d EPERM=%d EADDRINUSE=%d EAFNOSUPPORT=%d EAGAIN=%d EALREADY=%d EBADF=%d ECONNREFUSED=%d EFAULT=%d EINPROGRESS=%d EINTR=%d EISCONN=%d ENETUNREACH=%d ENOTSOCK=%d ETIMEDOUT=%d\n",
			EACCES, EACCES, EPERM, EADDRINUSE, EAFNOSUPPORT, EAGAIN, EALREADY, EBADF, ECONNREFUSED, EFAULT, EINPROGRESS, EINTR, EISCONN, ENETUNREACH, ENOTSOCK,
			ETIMEDOUT);

	uint16_t port;

	(void) signal(SIGINT, termination_handler);

	int sock;
	socklen_t addr_len = sizeof(struct sockaddr);
	int bytes_read;
	char recv_data[500000];
	int ret;
	pid_t pID = 0;

	struct sockaddr_in server_addr;
	struct sockaddr_in *client_addr;

#ifdef BUILD_FOR_ANDROID
	port = 45454;
#else
	if (argc > 1) {
		port = atoi(argv[1]);
	} else {
		//port = 45454;
		port = 53; //dnsmasq
	}
#endif

	client_addr = (struct sockaddr_in *) malloc(sizeof(struct sockaddr_in));
	//if ((sock = socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK, 0)) == -1) {
	if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
		//if ((sock = socket(39, SOCK_DGRAM, 0)) == -1) {
		perror("Socket");
		exit(1);
	}

	printf("Provided with sock=%d\n", sock);

	struct timeval tv_1;
	socklen_t size_1 = sizeof(struct timeval);
	getsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv_1, &size_1);

	struct timeval tv_2;
	socklen_t size_2 = sizeof(struct timeval);
	getsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &tv_2, &size_2);

	printf("size_1=%d, size_2=%d, SO_RCVTIMEO=%u,%u, SO_SNDTIMEO=%u,%u\n", size_1, size_2, (uint32_t) tv_1.tv_sec, (uint32_t) tv_1.tv_usec,
			(uint32_t) tv_2.tv_sec, (uint32_t) tv_2.tv_usec);

	//tv.tv_sec = 30; /* 30 Secs Timeout */

	//int FSO_RCVTIMEO = 0;
	//getsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &FSO_RCVTIMEO, sizeof(FSO_RCVTIMEO));
	//int FSO_SNDTIMEO = 0;
	//setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &FSO_SNDTIMEO, sizeof(FSO_SNDTIMEO));

	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(port);

	//server_addr.sin_addr.s_addr = xxx(127,0,0,1);
	//server_addr.sin_addr.s_addr = xxx(114,53,31,172);
	//server_addr.sin_addr.s_addr = xxx(172,31,54,87);
	//server_addr.sin_addr.s_addr = xxx(192,168,1,13);
	server_addr.sin_addr.s_addr = INADDR_ANY;
	//server_addr.sin_addr.s_addr = INADDR_LOOPBACK;
	server_addr.sin_addr.s_addr = htonl(server_addr.sin_addr.s_addr);
	bzero(&(server_addr.sin_zero), 8);

	printf("Binding to server: pID=%d addr=%s:%d, netw=%u\n", pID, inet_ntoa(server_addr.sin_addr), ntohs(server_addr.sin_port), server_addr.sin_addr.s_addr);
	fflush(stdout);
	if (bind(sock, (struct sockaddr *) &server_addr, sizeof(struct sockaddr_in)) == -1) {
		perror("Bind");
		printf("Failure");
		exit(1);
	}

	struct sockaddr_in client_addr2;
	uint32_t socklen = sizeof(struct sockaddr_in);
	int ret_val = getsockname(sock, (struct sockaddr *) &client_addr2, &socklen);
	if (ret_val < 0) {
		perror("getsockname");
		printf("Failure");
		exit(1);
	} else {
		printf("\n UDPServer bound at family=%u, client_addr=%s/%d, netw=%u\n", client_addr2.sin_family, inet_ntoa(client_addr2.sin_addr),
				ntohs(client_addr2.sin_port), client_addr2.sin_addr.s_addr);
		fflush(stdout);
	}
	addr_len = sizeof(struct sockaddr);

	printf("\n UDPServer Waiting for client at server_addr=%s/%d, netw=%u", inet_ntoa(server_addr.sin_addr), ntohs(server_addr.sin_port),
			server_addr.sin_addr.s_addr);
	fflush(stdout);

	i = 0;

	int nfds = 2;
	struct pollfd fds[nfds];
	fds[0].fd = -1;
	fds[0].events = POLLIN | POLLPRI | POLLRDNORM;
	fds[1].fd = sock;
	fds[1].events = POLLIN | POLLPRI | POLLRDNORM;
	//fds[1].events = POLLIN | POLLPRI | POLLOUT | POLLERR | POLLHUP | POLLNVAL | POLLRDNORM | POLLRDBAND | POLLWRNORM | POLLWRBAND;
	printf("\n fd: sock=%d, events=%x", sock, fds[1].events);
	int timeout = 10000;

	printf("\n POLLIN=%x POLLPRI=%x POLLOUT=%x POLLERR=%x POLLHUP=%x POLLNVAL=%x POLLRDNORM=%x POLLRDBAND=%x POLLWRNORM=%x POLLWRBAND=%x", POLLIN, POLLPRI,
			POLLOUT, POLLERR, POLLHUP, POLLNVAL, POLLRDNORM, POLLRDBAND, POLLWRNORM, POLLWRBAND);
	fflush(stdout);

	int temp = fds[1].events;
	printf("\n POLLIN=%x POLLPRI=%x POLLOUT=%x POLLERR=%x POLLHUP=%x POLLNVAL=%x POLLRDNORM=%x POLLRDBAND=%x POLLWRNORM=%x POLLWRBAND=%x val=%d (%x)",
			(temp & POLLIN) > 0, (temp & POLLPRI) > 0, (temp & POLLOUT) > 0, (temp & POLLERR) > 0, (temp & POLLHUP) > 0, (temp & POLLNVAL) > 0,
			(temp & POLLRDNORM) > 0, (temp & POLLRDBAND) > 0, (temp & POLLWRNORM) > 0, (temp & POLLWRBAND) > 0, temp, temp);

	struct timeval tv;

	tv.tv_sec = 0; /* 30 Secs Timeout */
	tv.tv_usec = 0; // Not init'ing this can cause strange errors

	//ret = getsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *) &tv, sizeof(struct timeval));
	//printf("\n ret=%d tv.tv_sec=%d tv.tv_usec=%d", ret, tv.tv_sec, tv.tv_usec);
	fflush(stdout);

	int j = 0;
	while (++j <= 3) {
		//pID = fork();
		if (pID == 0) { // child -- Capture process
			continue;
		} else if (pID < 0) { // failed to fork
			printf("Failed to Fork \n");
			fflush(stdout);
			exit(1);
		} else { // parent
			//port += j - 1;
			break;
		}
	}

	if (pID == 0) {
		//while (1);
	}

	if (1) {
		j = 0;
		int k = 0;
		while (1) {
			printf("\n pID=%d poll before", pID);
			fflush(stdout);
			ret = poll(fds, nfds, timeout);
			//printf("\n poll: pID=%d, ret=%d, revents=%x", pID, ret, fds[ret].revents);
			//fflush(stdout);
			if (ret || 0) {
				if (1) {
					printf("\n poll: ret=%d, revents=%x", ret, fds[ret].revents);
					printf("\n POLLIN=%d POLLPRI=%d POLLOUT=%d POLLERR=%d POLLHUP=%d POLLNVAL=%d POLLRDNORM=%d POLLRDBAND=%d POLLWRNORM=%d POLLWRBAND=%d ",
							(fds[ret].revents & POLLIN) > 0, (fds[ret].revents & POLLPRI) > 0, (fds[ret].revents & POLLOUT) > 0,
							(fds[ret].revents & POLLERR) > 0, (fds[ret].revents & POLLHUP) > 0, (fds[ret].revents & POLLNVAL) > 0,
							(fds[ret].revents & POLLRDNORM) > 0, (fds[ret].revents & POLLRDBAND) > 0, (fds[ret].revents & POLLWRNORM) > 0,
							(fds[ret].revents & POLLWRBAND) > 0);
					fflush(stdout);
				}

				if ((fds[ret].revents & (POLLIN | POLLRDNORM)) || 0) {
					//bytes_read = recvfrom(sock, recv_data, 200000, MSG_DONTWAIT, (struct sockaddr *) client_addr, &addr_len);
					bytes_read = recvfrom(sock, recv_data, 200000, 0, (struct sockaddr *) client_addr, &addr_len);
					//bytes_read = recvfrom(sock,recv_data,1024,0,NULL, NULL);
					//bytes_read = recv(sock,recv_data,1024,0);
					if (bytes_read > 0) {
						if (1) {
							print_hex(3 * 4, (uint8_t *) recv_data);
						}
						recv_data[bytes_read] = '\0';
						printf("\n frame=%d, pID=%d, client=%s:%u: said='%s'\n", ++k, pID, inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port),
								recv_data);
						fflush(stdout);

						//bytes_read = sendto(sock, recv_data, 1, 0, (struct sockaddr *) client_addr, sizeof(struct sockaddr_in));

						if ((strcmp(recv_data, "q") == 0) || strcmp(recv_data, "Q") == 0) {
							break;
						}
					} else /*if (errno != EWOULDBLOCK && errno != EAGAIN)*/{
						printf("\n Error recv at the Server: ret=%d errno='%s' (%d)\n", bytes_read, strerror(errno), errno);
						perror("Error:");
						fflush(stdout);
						sleep(2);
					}
				}
			}
			j++;
			sleep(2);
			//break;
		}
	}
	if (0) {
		i = 0;
		while (1) {
			//printf("\n pID=%d recvfrom before", pID);
			//fflush(stdout);
			bytes_read = recvfrom(sock, recv_data, 2000, 0, (struct sockaddr *) client_addr, &addr_len);
			//printf("\n pID=%d recvfrom after", pID);
			//fflush(stdout);
			//bytes_read = recvfrom(sock,recv_data,1024,0,NULL, NULL);
			//bytes_read = recv(sock,recv_data,1024,0);
			if (bytes_read > 0) {
				recv_data[bytes_read] = '\0';
				printf("\n frame=%d, pID=%d, client=%s:%u: said='%s'\n", ++i, pID, inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port), recv_data);
				fflush(stdout);

				if (0) {

				}

				//bytes_read = sendto(sock, recv_data, 1, 0, (struct sockaddr *) client_addr, sizeof(struct sockaddr_in));

				if ((strcmp(recv_data, "q") == 0) || strcmp(recv_data, "Q") == 0) {
					break;
				}
			} else if (errno != EWOULDBLOCK && errno != EAGAIN) {
				printf("\n Error recv at the Server: ret=%d errno='%s' (%d)\n", bytes_read, strerror(errno), errno);
				perror("Error:");
				fflush(stdout);
				break;
			}
		}
	}

	if (0) {
		struct timeval start, end;
		int its = 10000;
		//len = 1000;

		int data_len = 1000;
		while (data_len < 4000) {
			//data_len += 100;
			//data_len = 1000;

			int total_bytes = 0;
			double total_time = 0;
			int total_success = 0;
			double diff;

			int i = 0;
			while (i < its) {
				i++;

				gettimeofday(&start, 0);
				//numbytes = sendto(sock, send_data, data_len, 0, (struct sockaddr *) &server_addr, sizeof(struct sockaddr));
				bytes_read = recvfrom(sock, recv_data, 2000, 0, (struct sockaddr *) client_addr, &addr_len);
				gettimeofday(&end, 0);
				diff = time_diff(&start, &end);

				if (bytes_read > 0) {
					total_success++;
					total_bytes += bytes_read;
					total_time += diff;
				} else {
					perror("error");
				}
			}

			//printf("\n diff=%f, len=%d, avg=%f ms, calls=%f, bits=%f", diff, data_len, diff / its, 1000 / (diff / its), 1000 / (diff / its) * data_len);
			printf("\n len=%d, time=%f, suc=%d, bytes=%d, avg=%f ms, eff=%f, thr=%f, calls=%f, act=%f", data_len, total_time, total_success, total_bytes,
					total_time / total_success, total_success / (double) its, total_bytes / (double) its / data_len, 1000 / (total_time / total_success),
					1000 / (total_time / total_success) * data_len * 8);
			fflush(stdout);

			sleep(5);
		}
	}

	printf("\n Closing server socket");
	fflush(stdout);
	close(sock);

	printf("\n FIN");
	fflush(stdout);

	while (1)
		;

	return 0;
}
示例#13
0
文件: util.c 项目: TonyChiang/amanda
/* return >0: this is the connected socket */
int
connect_port(
    sockaddr_union *addrp,
    in_port_t  		port,
    char *		proto,
    sockaddr_union *svaddr,
    int			nonblock)
{
    int			save_errno;
    struct servent *	servPort;
    socklen_t_equiv	len;
    socklen_t_equiv	socklen;
    int			s;

    servPort = getservbyport((int)htons(port), proto);
    if (servPort != NULL && !strstr(servPort->s_name, "amanda")) {
	dbprintf(_("connect_port: Skip port %d: owned by %s.\n"),
		  port, servPort->s_name);
	errno = EBUSY;
	return -1;
    }

    if ((s = make_socket(SU_GET_FAMILY(addrp))) == -1) return -2;

    SU_SET_PORT(addrp, port);
    socklen = SS_LEN(addrp);
    if (bind(s, (struct sockaddr *)addrp, socklen) != 0) {
	save_errno = errno;
	aclose(s);
	if(servPort == NULL) {
	    dbprintf(_("connect_port: Try  port %d: available - %s\n"),
		     port, strerror(errno));
	} else {
	    dbprintf(_("connect_port: Try  port %d: owned by %s - %s\n"),
		     port, servPort->s_name, strerror(errno));
	}
	if (save_errno != EADDRINUSE) {
	    errno = save_errno;
	    return -2;
	}

	errno = save_errno;
	return -1;
    }
    if(servPort == NULL) {
	dbprintf(_("connect_port: Try  port %d: available - Success\n"), port);
    } else {
	dbprintf(_("connect_port: Try  port %d: owned by %s - Success\n"),
		  port, servPort->s_name);
    }

    /* find out what port was actually used */

    len = sizeof(*addrp);
    if (getsockname(s, (struct sockaddr *)addrp, &len) == -1) {
	save_errno = errno;
	dbprintf(_("connect_port: getsockname() failed: %s\n"),
		  strerror(save_errno));
	aclose(s);
	errno = save_errno;
	return -1;
    }

    if (nonblock)
	fcntl(s, F_SETFL, fcntl(s, F_GETFL, 0)|O_NONBLOCK);
    if (connect(s, (struct sockaddr *)svaddr, SS_LEN(svaddr)) == -1 && !nonblock) {
	save_errno = errno;
	dbprintf(_("connect_portrange: Connect from %s failed: %s\n"),
		  str_sockaddr(addrp),
		  strerror(save_errno));
	dbprintf(_("connect_portrange: connect to %s failed: %s\n"),
		  str_sockaddr(svaddr),
		  strerror(save_errno));
	aclose(s);
	errno = save_errno;
	if (save_errno == ECONNREFUSED ||
	    save_errno == EHOSTUNREACH ||
	    save_errno == ENETUNREACH ||
	    save_errno == ETIMEDOUT)  {
	    return -2	;
	}
	return -1;
    }

    dbprintf(_("connected to %s\n"),
              str_sockaddr(svaddr));
    dbprintf(_("our side is %s\n"),
              str_sockaddr(addrp));
    return s;
}
示例#14
0
/*
 * Initialize SASL and set necessary options
 */
int init_sasl(isieve_t *obj,
              int ssf,
              sasl_callback_t *callbacks)
{
  static int sasl_started = 0;
  int saslresult = SASL_OK;
  sasl_security_properties_t *secprops=NULL;
  socklen_t addrsize=sizeof(struct sockaddr_storage);
  struct sockaddr_storage saddr_l, saddr_r;
  char localip[60], remoteip[60];

  /* attempt to start sasl */
  if(!sasl_started) {
      saslresult=sasl_client_init(NULL);
      obj->conn = NULL;
      sasl_started = 1;
  }

  /* Save the callbacks array */
  obj->callbacks = callbacks;

  if (saslresult!=SASL_OK) return -1;

  addrsize=sizeof(struct sockaddr_storage);
  if (getpeername(obj->sock,(struct sockaddr *)&saddr_r,&addrsize)!=0)
      return -1;

  addrsize=sizeof(struct sockaddr_storage);
  if (getsockname(obj->sock,(struct sockaddr *)&saddr_l,&addrsize)!=0)
      return -1;
#if 0
  /* XXX  The following line causes problems with KERBEROS_V4 decoding.
   * We're not sure why its an issue, but this code isn't used in any of
   * our other client code (imtest.c, backend.c), so we're removing it.
   */
  /* set the port manually since getsockname is stupid and doesn't */
  ((struct sockaddr_in *)&saddr_l)->sin_port = htons(obj->port);
#endif
  if (iptostring((struct sockaddr *)&saddr_r, addrsize, remoteip, 60))
      return -1;

  if (iptostring((struct sockaddr *)&saddr_l, addrsize, localip, 60))
      return -1;

  if(obj->conn) sasl_dispose(&obj->conn);

  /* client new connection */
  saslresult=sasl_client_new(SIEVE_SERVICE_NAME,
                             obj->serverFQDN,
                             localip, remoteip,
                             callbacks,
                             SASL_SUCCESS_DATA,
                             &obj->conn);

  if (saslresult!=SASL_OK) return -1;

  /* create a security structure and give it to sasl */
  secprops = make_secprops(0, ssf);
  if (secprops != NULL)
  {
    sasl_setprop(obj->conn, SASL_SEC_PROPS, secprops);
    free(secprops);
  }

  return 0;
}
示例#15
0
int is_notified(notifier_t n, struct timeval *timeout)
{
    fd_set fds;

    FD_ZERO(&fds);
    FD_SET(n, &fds);

#if defined(_WIN32) || defined(__CYGWIN__)
    char buf[64];
    if (select(100000, &fds, NULL, NULL, timeout) > 0) {
        recv(n, buf, sizeof(buf), 0);
#else
    unsigned char buf[64];
    if (select(n + 1, &fds, NULL, NULL, timeout) > 0) {
        int rc = read(n, buf, sizeof(buf));
        if (rc < 0) {
            fprintf(stderr, "Warning, notifier socket error\n");
            perror("read()");
        } else if (rc == 0) {
            fprintf(stderr, "Warning, notifier socket EOF\n");
        }
#endif
        return 1;
    } else {
        return 0;
    }
}

/*
 * Based on evutil_socketpair() from libevent.
 */
int create_notifier(notifier_t not[2])
{
#if defined(_WIN32) || defined(__CYGWIN__)
    SOCKET listener = -1, connector = -1, acceptor = -1;
    struct sockaddr_in listen_addr, connect_addr;
    int size;

    listener = socket(AF_INET, SOCK_STREAM, 0);
    if (listener < 0)
        return -1;
    memset(&listen_addr, 0, sizeof(listen_addr));
    listen_addr.sin_family = AF_INET;
    listen_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
    listen_addr.sin_port = 0;	/* kernel chooses port.	 */
    if (bind(listener, (struct sockaddr *) &listen_addr, sizeof (listen_addr))
        == -1)
        goto out;
    if (listen(listener, 1) == -1)
        goto out;

    connector = socket(AF_INET, SOCK_STREAM, 0);
    if (connector < 0)
        goto out;

    /* We want to find out the port number to connect to.  */
    size = sizeof(connect_addr);
    if (getsockname(listener, (struct sockaddr *) &connect_addr, &size) == -1)
        goto out;
    if (size != sizeof(connect_addr))
        goto out;
    if (connect(connector, (struct sockaddr *) &connect_addr,
                sizeof(connect_addr)) == -1)
        goto out;

    size = sizeof(listen_addr);
    acceptor = accept(listener, (struct sockaddr *) &listen_addr, &size);
    if (acceptor < 0)
        goto out;
    if (size != sizeof(listen_addr))
        goto out;
    /* Now check we are talking to ourself by matching port and host on the
       two sockets.	 */
    if (getsockname(connector, (struct sockaddr *) &connect_addr, &size) == -1)
        goto out;
    if (size != sizeof(connect_addr)
        || listen_addr.sin_family != connect_addr.sin_family
        || listen_addr.sin_addr.s_addr != connect_addr.sin_addr.s_addr
        || listen_addr.sin_port != connect_addr.sin_port)
        goto out;
    closesocket(listener);
    not[0] = (int)connector;
    not[1] = (int)acceptor;

    return 0;

out:
    if (listener != -1)
        closesocket(listener);
    if (connector != -1)
        closesocket(connector);
    if (acceptor != -1)
        closesocket(acceptor);
    return -1;
#else
    return pipe(not);
#endif
}
示例#16
0
文件: chat.c 项目: rahpaere/tcpr
static void setup_connection(void)
{
    char *host;
    char *port;
    int err;
    int s;
    int yes = 1;
    socklen_t addrlen;
    struct addrinfo *ai;
    struct addrinfo hints;

    if (!buffer_size)
        buffer_size = 16384;

    send_buffer = malloc(buffer_size);
    if (!send_buffer) {
        perror("malloc");
        exit(EXIT_FAILURE);
    }

    receive_buffer = malloc(buffer_size);
    if (!receive_buffer) {
        perror("malloc");
        exit(EXIT_FAILURE);
    }

    s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (s < 0) {
        perror("Creating socket");
        exit(EXIT_FAILURE);
    }
    if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
        perror("Setting SO_REUSEADDR");
        exit(EXIT_FAILURE);
    }

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    if (bind_address) {
        port = strchr(bind_address, ':');
        if (port) {
            host = bind_address;
            *port++ = '\0';
        } else {
            port = bind_address;
            host = NULL;
        }

        if (!connect_address)
            hints.ai_flags |= AI_PASSIVE;
        err = getaddrinfo(host, port, &hints, &ai);
        if (err) {
            fprintf(stderr, "Resolving \"%s\": %s\n", bind_address, gai_strerror(err));
            exit(EXIT_FAILURE);
        }
        if (bind(s, ai->ai_addr, ai->ai_addrlen) < 0) {
            perror("Binding");
            exit(EXIT_FAILURE);
        }
        freeaddrinfo(ai);

        if (!connect_address) {
            if (listen(s, 16) < 0) {
                perror("Listening");
                exit(EXIT_FAILURE);
            }

            if (tcpr_sock != -1) {
                addrlen = sizeof(sockname);
                getsockname(s, (struct sockaddr *)&sockname, &addrlen);
                state.address = sockname.sin_addr.s_addr;
                state.peer_address = 0;
                state.tcpr.port = sockname.sin_port;
                state.tcpr.hard.port = sockname.sin_port;
                state.tcpr.hard.peer.port = 0;
                send(tcpr_sock, &state, sizeof(state), 0);
            }

            listen_sock = s;
            addrlen = sizeof(peername);
            s = accept(listen_sock, (struct sockaddr *)&peername, &addrlen);
            if (s < 0) {
                perror("Accepting");
                exit(EXIT_FAILURE);
            }

            addrlen = sizeof(sockname);
            getsockname(s, (struct sockaddr *)&sockname, &addrlen);

            if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &buffer_size, sizeof(buffer_size)) < 0)
                perror("Setting SO_RCVBUF");
            if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &buffer_size, sizeof(buffer_size)) < 0)
                perror("Setting SO_SNDBUF");

            sock = s;
            return;
        }
    }

    port = strchr(connect_address, ':');
    if (port) {
        host = connect_address;
        *port++ = '\0';
    } else {
        port = connect_address;
        host = NULL;
    }

    err = getaddrinfo(host, port, &hints, &ai);
    if (err) {
        fprintf(stderr, "Resolving \"%s\": %s\n", connect_address, gai_strerror(err));
        exit(EXIT_FAILURE);
    }
    while (connect(s, ai->ai_addr, ai->ai_addrlen) < 0) {
        perror("Connecting");
        if (errno != ECONNREFUSED)
            exit(EXIT_FAILURE);
        sleep(2);
    }
    freeaddrinfo(ai);

    addrlen = sizeof(peername);
    getpeername(s, (struct sockaddr *)&peername, &addrlen);

    addrlen = sizeof(sockname);
    getsockname(s, (struct sockaddr *)&sockname, &addrlen);

    if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &buffer_size, sizeof(buffer_size)) < 0)
        perror("Setting SO_RCVBUF");
    if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &buffer_size, sizeof(buffer_size)) < 0)
        perror("Setting SO_SNDBUF");

    sock = s;
}
示例#17
0
/*
 * css_open_server_connection_socket() - open the socket used by the server
 *                                       for incoming client connection
 *                                       requests
 *   return: port id
 */
int
css_open_server_connection_socket (void)
{
  struct sockaddr_in tcp_srv_addr;	/* server's internet socket addr */
  SOCKET fd;
  int get_length;
  int bool_value;

#if !defined(SERVER_MODE)
  if (css_windows_startup () < 0)
    {
      return -1;
    }
#endif /* not SERVER_MODE */

  /* Create the socket */
  fd = socket (AF_INET, SOCK_STREAM, 0);
  if (IS_INVALID_SOCKET (fd))
    {
      er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ERR_CSS_WINTCP_CANNOT_CREATE_STREAM, 1, WSAGetLastError ());
      return -1;
    }

  bool_value = 1;
  setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, (const char *) &bool_value, sizeof (int));

  if (prm_get_bool_value (PRM_ID_TCP_KEEPALIVE))
    {
      setsockopt (fd, SOL_SOCKET, SO_KEEPALIVE, (const char *) &bool_value, sizeof (int));
    }

  /* 
   * Set up an address asking for "any" (the local ?) IP addres
   * and set the port to zero to it will be automatically assigned.
   */
  memset ((void *) &tcp_srv_addr, 0, sizeof (tcp_srv_addr));
  tcp_srv_addr.sin_family = AF_INET;
  tcp_srv_addr.sin_addr.s_addr = htonl (INADDR_ANY);
  tcp_srv_addr.sin_port = 0;


  /* Bind the socket */
  if (bind (fd, (struct sockaddr *) &tcp_srv_addr, sizeof (tcp_srv_addr)) == SOCKET_ERROR)
    {
      goto error;
    }

  /* Determine which port_id the system has assigned. */
  get_length = sizeof (tcp_srv_addr);
  if (getsockname (fd, (struct sockaddr *) &tcp_srv_addr, &get_length) == SOCKET_ERROR)
    {
      goto error;
    }

  /* 
   * Set it up to listen for incoming connections.  Note that under Winsock
   * (NetManage version at least), the backlog parameter is silently limited
   * to 5, regardless of what is requested.
   */
  if (listen (fd, css_Maximum_server_count) == SOCKET_ERROR)
    {
      goto error;
    }

  css_Server_connection_socket = fd;

  return (int) ntohs (tcp_srv_addr.sin_port);

error:
  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ERR_CSS_WINTCP_BIND_ABORT, 1, WSAGetLastError ());
  css_shutdown_socket (fd);
  return -1;
}
示例#18
0
void CChannel::getSockAddr(sockaddr* addr) const
{
   socklen_t namelen = (AF_INET == m_iIPversion) ? sizeof(sockaddr_in) : sizeof(sockaddr_in6);

   getsockname(m_iSocket, addr, &namelen);
}
示例#19
0
int main(int argc, char *argv[])
{
    struct sockaddr_in my_addr, cli_addr,sin,serv_addr,gen_addr;
    int sockfd, i, n, length, p1, p2, optval;
    socklen_t slen=sizeof(cli_addr),slen1;
    char buf[BUFLEN], line[BUFLEN], buf2[BUFLEN],line2[BUFLEN],b[30],b2[30],c1[100],c2[100];
    struct hostent *hp, *h;
    char host[50],file[30]="passGn.txt";
    char *unit1,*unit2,*temp,*val1,*val2;
    char u1[20],v1[2],u2[20],v2[2];
    bzero(u1, 20);
    bzero(v1, 2);
    bzero(u2, 20);
    bzero(v2, 2);


    sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (sockfd==-1)
        err("socket");
    else
        // printf("Server : Socket() successful\n");
        length = sizeof(my_addr);
    bzero(&my_addr, sizeof(my_addr));
    my_addr.sin_family = AF_INET;
    my_addr.sin_port = htons(atoi(GENPORT));
    my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    //my_addr.sin_port=htons(atoi(argv[1]));

    if (bind(sockfd, (struct sockaddr* ) &my_addr, sizeof(my_addr))<0)
        err("bind");
    else
        // printf("Server : bind() successful\n");
        bzero(buf, BUFLEN);
    bzero(buf2, BUFLEN);

    gethostname(host,50);
    hp=gethostbyname(host);

    if(hp==0)
        err("Unknown host");

    bcopy((char *)hp->h_addr, (char *)&my_addr.sin_addr,hp->h_length);
    printf("General has UDP Port: %s and IP Address: %s for Phase 2\n",GENPORT, inet_ntoa(my_addr.sin_addr));
// getsockname(sockfd, (struct sockaddr *)&sin, &slen1);


    {   //FROM MAJOR
        n=recvfrom(sockfd, buf, BUFLEN, 0, (struct sockaddr*)&cli_addr, &slen);
        strcpy(line,buf);

        if (n<0)
            err("Could not receive from Major");

        n=recvfrom(sockfd, buf2, BUFLEN, 0, (struct sockaddr*)&cli_addr, &slen);
        if (n<0)
            err("Could not receive from Captain 1");

        //SUCCESS RATES
        n=recvfrom(sockfd, v1, 2, 0, (struct sockaddr*)&cli_addr, &slen);
        strcpy(line,buf);
        if (n<0)
            err("Could not receive port from Major");

        n=recvfrom(sockfd, v2, 2, 0, (struct sockaddr*)&cli_addr, &slen);
        if (n<0)
            err("Could not receive password from Major");
        p1=v1[0];
        p2=v2[0];
        printf("Received the Password from Major\n");
        //	printf("Port number sent by Major: %s\n",buf);
        //	printf("Password sent by Major is: %s\n",buf2);
    }
    FILE *fptr;
    fptr=fopen(file,"rt");
    if(fptr==NULL)
    {
        printf("Could not open file\n");
    }
    else
    {
        fscanf(fptr,"%s",&b);
        fscanf(fptr,"%s",&b2);
        while((strcmp(buf,b)!=0)||(strcmp(buf2,b2)!=0))
        {
            fclose(fptr);
            bzero(buf, BUFLEN);
            bzero(buf2, BUFLEN);
            printf("Wrong Password from Major, try again\n");
            n=recvfrom(sockfd, buf, BUFLEN, 0, (struct sockaddr*)&cli_addr, &slen);
            strcpy(line,buf);
            if (n<0)
                err("Could not receive port from Major");

            n=recvfrom(sockfd, buf2, BUFLEN, 0, (struct sockaddr*)&cli_addr, &slen);
            if (n<0)
                err("Could not receive password from Major");
            //SUCCESS RATE
            n=recvfrom(sockfd, v1, 2, 0, (struct sockaddr*)&cli_addr, &slen);
            strcpy(line,buf);
            if (n<0)
                err("Could not receive port from Major");

            n=recvfrom(sockfd, v2, 2, 0, (struct sockaddr*)&cli_addr, &slen);
            if (n<0)
                err("Could not receive password from Major");

            p1=v1[0];
            p2=v2[0];
            FILE *fptr;
            fptr=fopen(file,"rt");
            if(fptr==NULL)
            {
                printf("Could not open file\n");
            }
            else
            {
                fscanf(fptr,"%s",&b);
                fscanf(fptr,"%s",&b2);
                //printf("Compare %s: %s\n",buf,b);
                //printf("Compare %s: %s\n",buf2,b2);
            }
        }
        printf("Correct Password from Major\n");
        printf("Success Rate of Captain 1 = %d\n",p1);
        printf("Success Rate of Captain 2 = %d\n",p2);
        printf("End of Phase 2 for the General\n");
    }
    printf("----------------------------------------------------------\n");
    close(sockfd);


    /* --------------------------------------PHASE 3 FOR GENERAL STARTING--------------------------------------------*/
    bzero(c1, 100);
    bzero(c2, 100);

    /* length = sizeof(gen_addr);
    bzero(&gen_addr, sizeof(gen_addr));
    gen_addr.sin_family = AF_INET;
    gen_addr.sin_port = htons(atoi(GENTCP));
    //  gen_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    gethostname(host,50);
    h=gethostbyname(host);
    if(h==0)
    	printf("Unknown host");
    bcopy((char *)h->h_addr, (char *)&gen_addr.sin_addr,h->h_length);
    if (bind(sockfd, (struct sockaddr* ) &my_addr, sizeof(my_addr))<0)
      err("bind");*/
    if(p1>p2)
    {
        strcpy(c1,"start");
        strcpy(c2,"backup");
    }
    else
    {
        strcpy(c1,"backup");
        strcpy(c2,"start");
    }
    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        printf("\n Error : Could not create socket \n");
        return 1;
    }

    length = sizeof(gen_addr);
    bzero(&gen_addr, sizeof(gen_addr));
    gen_addr.sin_family = AF_INET;
    gen_addr.sin_port = htons(atoi(GENTCP));
    //  gen_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    gethostname(host,50);
    h=gethostbyname(host);
    if(h==0)
        printf("Unknown host");
    bcopy((char *)h->h_addr, (char *)&gen_addr.sin_addr,h->h_length);

    // set SO_REUSEADDR on a socket to true (1):
    optval = 1;
    setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval);

    if (bind(sockfd, (struct sockaddr* ) &my_addr, sizeof(my_addr))<0)
        err("bind");


    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(CAPT1PORT);
    gethostname(host,50);
    h=gethostbyname(host);
    if(h==0)
        printf("Unknown host");
    bcopy((char *)h->h_addr, (char *)&serv_addr.sin_addr,h->h_length);

    if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
    {
        printf("\n Error : Connect Failed \n");
        return 1;
    }
    n=send(sockfd,c1,strlen(c1),0);
    //  sleep(2);

    if(n < 0)
        printf("\n Send error \n");
    close(sockfd);
    //	sleep(1);

    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        printf("\n Error : Could not create socket \n");
        return 1;
    }
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(CAPT2PORT);
    gethostname(host,50);
    h=gethostbyname(host);
    if(h==0)
        printf("Unknown host");
    bcopy((char *)h->h_addr, (char *)&serv_addr.sin_addr,h->h_length);

    if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
    {
        printf("\n Error : Connect Failed \n");
        return 1;
    }
    n=send(sockfd,c2,strlen(c2),0);
//	 sleep(2);
    if(n < 0)
        printf("\n Send error \n");

    getsockname(sockfd, (struct sockaddr *)&cli_addr, &slen1);
    printf("General has TCP Port: %d and IP Address: %s\n", ntohs(gen_addr.sin_port),inet_ntoa(gen_addr.sin_addr));
    if(p1>p2)
    {
        printf("Captain 1 has the highest probability of success\n");
        printf("Command to start the mission sent to Captain 1\n");
        printf("Command to be the backup for the mission sent to Captain 2\n");
    }
    else
    {
        printf("Captain 2 has the highest probability of success\n");
        printf("Command to start the mission sent to Captain 2\n");
        printf("Command to be the backup for the mission sent to Captain 1\n");
    }
    printf("End of phase 3 for the General\n");
    printf("----------------------------------------------------------\n");
    close(sockfd);
    return 0;
}
示例#20
0
static int
netsnmp_ssh_recv(netsnmp_transport *t, void *buf, int size,
		 void **opaque, int *olength)
{
    int rc = -1;
    netsnmp_tmStateReference *tmStateRef = NULL;
    netsnmp_ssh_addr_pair *addr_pair = NULL;
    int iamclient = 0;

    DEBUGMSGTL(("ssh", "at the top of ssh_recv\n"));
    DEBUGMSGTL(("ssh", "t=%p\n", t));
    if (t != NULL && t->data != NULL) {
	addr_pair = (netsnmp_ssh_addr_pair *) t->data;
    }

    DEBUGMSGTL(("ssh", "addr_pair=%p\n", addr_pair));
    if (t != NULL && addr_pair && addr_pair->channel) {
        DEBUGMSGTL(("ssh", "t=%p, addr_pair=%p, channel=%p\n",
                    t, addr_pair, addr_pair->channel));
        iamclient = 1;
	while (rc < 0) {
	    rc = libssh2_channel_read(addr_pair->channel, buf, size);
	    if (rc < 0) {  /* XXX: from tcp; ssh equiv?:  && errno != EINTR */
		DEBUGMSGTL(("ssh", "recv fd %d err %d (\"%s\")\n",
			    t->sock, errno, strerror(errno)));
		break;
	    }
	    DEBUGMSGTL(("ssh", "recv fd %d got %d bytes\n",
			t->sock, rc));
	}
    } else if (t != NULL) {

#ifdef SNMPSSHDOMAIN_USE_EXTERNAL_PIPE

        socklen_t       tolen = sizeof(struct sockaddr_un);

        if (t != NULL && t->sock >= 0) {
            struct sockaddr *to;
            to = (struct sockaddr *) SNMP_MALLOC_STRUCT(sockaddr_un);
            if (NULL == to) {
                *opaque = NULL;
                *olength = 0;
                return -1;
            }

            if(getsockname(t->sock, to, &tolen) != 0){
                free(to);
                *opaque = NULL;
                *olength = 0;
                return -1;
            };

            if (addr_pair->username[0] == '\0') {
                /* we don't have a username yet, so this is the first message */
                struct ucred *remoteuser;
                struct msghdr msg;
                struct iovec iov[1];
                char cmsg[CMSG_SPACE(sizeof(remoteuser))+4096];
                struct cmsghdr *cmsgptr;
                u_char *charbuf  = buf;

                iov[0].iov_base = buf;
                iov[0].iov_len = size;

                memset(&msg, 0, sizeof msg);
                msg.msg_iov = iov;
                msg.msg_iovlen = 1;
                msg.msg_control = &cmsg;
                msg.msg_controllen = sizeof(cmsg);
                
                rc = recvmsg(t->sock, &msg, MSG_DONTWAIT); /* use DONTWAIT? */
                if (rc <= 0) {
                    return rc;
                }

                /* we haven't received the starting info */
                if ((u_char) charbuf[0] > NETSNMP_SSHTOSNMP_VERSION1) {
                    /* unsupported connection version */
                    snmp_log(LOG_ERR, "received unsupported sshtosnmp version: %d\n", charbuf[0]);
                    return -1;
                }

                DEBUGMSGTL(("ssh", "received first msg over SSH; internal SSH protocol version %d\n", charbuf[0]));

                for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) {
                    if (cmsgptr->cmsg_level == SOL_SOCKET && cmsgptr->cmsg_type == SCM_CREDENTIALS) {
                        /* received credential info */
                        struct passwd *user_pw;

                        remoteuser = (struct ucred *) CMSG_DATA(cmsgptr);

                        if ((user_pw = getpwuid(remoteuser->uid)) == NULL) {
                            snmp_log(LOG_ERR, "No user found for uid %d\n",
                                remoteuser->uid);
                            return -1;
                        }
                        if (strlen(user_pw->pw_name) >
                            sizeof(addr_pair->username)-1) {
                            snmp_log(LOG_ERR,
                                     "User name '%s' too long for snmp\n",
                                     user_pw->pw_name);
                            return -1;
                        }
                        strlcpy(addr_pair->username, user_pw->pw_name,
                                sizeof(addr_pair->username));
                    }
                    DEBUGMSGTL(("ssh", "Setting user name to %s\n",
                                addr_pair->username));
                }

                if (addr_pair->username[0] == '\0') {
                    snmp_log(LOG_ERR,
                             "failed to extract username from sshd connected unix socket\n");
                    return -1;
                }

                if (rc == 1) {
                    /* the only packet we received was the starting one */
                    t->flags |= NETSNMP_TRANSPORT_FLAG_EMPTY_PKT;
                    return 0;
                }

                rc -= 1;
                memmove(charbuf, &charbuf[1], rc);
            } else {
                while (rc < 0) {
                    rc = recvfrom(t->sock, buf, size, 0, NULL, NULL);
                    if (rc < 0 && errno != EINTR) {
                        DEBUGMSGTL(("ssh", "recv fd %d err %d (\"%s\")\n",
                                    t->sock, errno, strerror(errno)));
                        return rc;
                    }
                    *opaque = (void*)to;
                    *olength = sizeof(struct sockaddr_un);
                }
            }
            DEBUGMSGTL(("ssh", "recv fd %d got %d bytes\n",
                        t->sock, rc));
        }
        
#else /* we're called directly by sshd and use stdin/out */

        struct passwd *user_pw;

        iamclient = 0;
        /* we're on the server side and should read from stdin */
        while (rc < 0) {
            rc = read(STDIN_FILENO, buf, size);
            if (rc < 0 && errno != EINTR) {
                DEBUGMSGTL(("ssh",
                            " read on stdin failed: %d (\"%s\")\n",
                            errno, strerror(errno)));
                break;
            }
            if (rc == 0) {
                /* 0 input is probably bad since we selected on it */
                DEBUGMSGTL(("ssh", "got a 0 read on stdin\n"));
                return -1;
            }
            DEBUGMSGTL(("ssh", "read on stdin got %d bytes\n", rc));
        }

/* XXX: need to check the username, but addr_pair doesn't exist! */
        /*
        DEBUGMSGTL(("ssh", "current username=%s\n", c));
        if (addr_pair->username[0] == '\0') {
            if ((user_pw = getpwuid(getuid())) == NULL) {
                snmp_log(LOG_ERR, "No user found for uid %d\n", getuid());
                return -1;
            }
            if (strlen(user_pw->pw_name) > sizeof(addr_pair->username)-1) {
                snmp_log(LOG_ERR, "User name '%s' too long for snmp\n",
                         user_pw->pw_name);
                return -1;
            }
            strlcpy(addr_pair->username, user_pw->pw_name,
                    sizeof(addr_pair->username));
        }
        */

#endif /* ! SNMPSSHDOMAIN_USE_EXTERNAL_PIPE */
    }

    /* create a tmStateRef cache */
    tmStateRef = SNMP_MALLOC_TYPEDEF(netsnmp_tmStateReference);

    /* secshell document says were always authpriv, even if NULL algorithms */
    /* ugh! */
    /* XXX: disallow NULL in our implementations */
    tmStateRef->transportSecurityLevel = SNMP_SEC_LEVEL_AUTHPRIV;

    /* XXX: figure out how to get the specified local secname from the session */
    if (iamclient && 0) {
        /* XXX: we're on the client; we should have named the
           connection ourselves...  pull this from session somehow? */
        strlcpy(tmStateRef->securityName, addr_pair->username,
                sizeof(tmStateRef->securityName));
    } else {
#ifdef SNMPSSHDOMAIN_USE_EXTERNAL_PIPE
        strlcpy(tmStateRef->securityName, addr_pair->username,
                sizeof(tmStateRef->securityName));
#else /* we're called directly by sshd and use stdin/out */
        /* we're on the server... */
        /* XXX: this doesn't copy properly and can get pointer
           reference issues */
        if (strlen(getenv("USER")) > 127) {
            /* ruh roh */
            /* XXX: clean up */
            return -1;
            exit;
        }

        /* XXX: detect and throw out overflow secname sizes rather
           than truncating. */
        strlcpy(tmStateRef->securityName, getenv("USER"),
                sizeof(tmStateRef->securityName));
#endif /* ! SNMPSSHDOMAIN_USE_EXTERNAL_PIPE */
    }
    tmStateRef->securityName[sizeof(tmStateRef->securityName)-1] = '\0';
    tmStateRef->securityNameLen = strlen(tmStateRef->securityName);
    *opaque = tmStateRef;
    *olength = sizeof(netsnmp_tmStateReference);

    return rc;
}
示例#21
0
文件: erl_start.c 项目: HansN/otp
/* Start an Erlang node. return value 0 indicates that node was
 * started successfully, negative values indicate error. 
 * 
 * node -  the name of the remote node to start (alivename@hostname).
 * flags - turn on or off certain options. See erl_start.h for a list.
 * erl -  is the name of the erl script to call. If NULL, the default
 * name "erl" will be used.
 * args - a NULL-terminated list of strings containing
 * additional arguments to be sent to the remote Erlang node. These
 * strings are simply appended to the end of the command line, so any
 * quoting of special characters, etc must be done by the caller.
 * There may be some conflicts between some of these arguments and the
 * default arguments hard-coded into this function, so be careful. 
 */
int erl_start_sys(ei_cnode *ec, char *alive, Erl_IpAddr adr, int flags,
		  char *erl, char *args[])
{
  struct timeval timeout;
  struct sockaddr_in addr;
  SocklenType namelen;
  int port;
  int sockd = 0;
  int one = 1;
#if defined(VXWORKS) || defined(__WIN32__)
  unsigned long pid = 0;
#else
  int pid = 0;
#endif
  int r = 0;

  if (((sockd = socket(AF_INET, SOCK_STREAM, 0)) < 0) ||
      (setsockopt(sockd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)) < 0)) {
    r = ERL_SYS_ERROR;
    goto done;
  }

  memset(&addr,0,sizeof(addr));
  addr.sin_family = AF_INET;
  addr.sin_addr.s_addr = htonl(INADDR_ANY);
  addr.sin_port = 0;

  if (bind(sockd,(struct sockaddr *)&addr,sizeof(addr))<0) {
      return ERL_SYS_ERROR;
  }
  namelen = sizeof(addr);
  if (getsockname(sockd,(struct sockaddr *)&addr,&namelen)<0) {
      return ERL_SYS_ERROR;
  }
  port = ntohs(addr.sin_port);

  listen(sockd,5);

#if defined(VXWORKS) || defined(__WIN32__)
  if((pid = spawn_erlang_epmd(ec,alive,adr,flags,erl,args,port,1))
      == 0)
     return ERL_SYS_ERROR;
  timeout.tv_usec = 0;
  timeout.tv_sec = 10; /* ignoring ERL_START_TIME */
  if((r = wait_for_erlang(sockd,unique_id(),&timeout))
     == ERL_TIMEOUT) {
#if defined(VXWORKS)
      taskDelete((int) pid);
      if(taskIdVerify((int) pid) != ERROR)
	  taskDeleteForce((int) pid);
#else /* Windows */
      /* Well, this is not a nice way to do it, and it does not 
	 always kill the emulator, but the alternatives are few.*/
      TerminateProcess((HANDLE) pid,1);
#endif /* defined(VXWORKS) */
  }
#else /* Unix */
  switch ((pid = fork())) {
  case -1:
    r = ERL_SYS_ERROR;
    break;

  case 0:
    /* child - start the erlang node */
    exec_erlang(ec, alive, adr, flags, erl, args, port);

    /* error if reached - parent reports back to caller after timeout
       so we just exit here */
    exit(1);
    break;

  default:

    /* parent - waits for response from Erlang node */
    /* child pid used here as magic number */
    timeout.tv_usec = 0;
    timeout.tv_sec = 10; /* ignoring ERL_START_TIME */
    if ((r = wait_for_erlang(sockd,pid,&timeout)) == ERL_TIMEOUT) {
      /* kill child if no response */
      kill(pid,SIGINT);
      sleep(1);
      if (waitpid(pid,NULL,WNOHANG) != pid) {
	/* no luck - try harder */
	kill(pid,SIGKILL);
	sleep(1);
	waitpid(pid,NULL,WNOHANG);
      }
    }

  }
#endif /* defined(VXWORKS) || defined(__WIN32__) */

done:
#if defined(__WIN32__)
  if (sockd) closesocket(sockd);
#else
  if (sockd) close(sockd);
#endif
  return r;
} /* erl_start_sys() */
示例#22
0
文件: ftp_data.c 项目: xsmart/3535
int ftp_open_data(struct ftpconnection *connection) {
    struct sockaddr_in servaddr;
    struct in_addr sin;
    char *line;
    int h1, h2, h3, h4, p1, p2, port;
    int response;
    SOCKLEN len;
    if ((connection->dataconfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        perror("socket");
        return -1;
    }
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = 0;
    if (bind(connection->dataconfd, (SOCKADDR *)&servaddr, sizeof(servaddr)) < 0) {
        perror("bind");
        return -1;
    }
    if (listen(connection->dataconfd, 1) < 0) {
        perror("listen");
        return -1;
    }
    len = 128;
    if (getsockname(connection->dataconfd, (SOCKADDR *)&servaddr, &len) < 0) {
        perror("getsockname");
        return -1;
    }
    line = (char *)malloc(MAX_LINE_SIZE);
    if(NULL == line)
    {
        return -1;
    }
    port = servaddr.sin_port;
    sin.s_addr = connection->localip;
    sprintf(line, "%s.%d\r\n", inet_ntoa(sin), port);
    sscanf(line, "%d.%d.%d.%d.%d", &h1, &h2, &h3, &h4, &port);
    p1 = (port / 256);
    p2 = port - (256 * p1);
    sprintf(line, "PORT %d,%d,%d,%d,%d,%d\r\n", h1, h2, h3, h4, p2, p1);
    connection->status = STATUS_WAITING;
    ftp_sendline(connection, line);
    FREE(line);
    response = ftp_getrc(connection, NULL, 0, 0);
    switch (response) {
    case 200 :
        return 0;
    case 421 :
        printf("Service unavailable\n");
        ftp_disconnect(connection);
        return response;
        break;
    case 500 :
        printf("Server doesn't understand PORT\n");
        return response;
        break;
    case 501 :
        printf("Server doesn't understand PORT parameters\n");
        return response;
        break;
    case 502 :
        printf("Server doesn't understand PORT\n");
        return response;
        break;
    case 530 :
        printf("Not logged in\n");
        return response;
        break;
    default  :
        printf("Unknown response to PORT: %d\n", response);
        return response;
        break;
    }
}
示例#23
0
ftpbuf_t*
ftp_open(const char *host, short port)
{
	int			fd = -1;
	ftpbuf_t		*ftp;
	struct sockaddr_in	addr;
	struct hostent		*he;
	int			size;


	/* set up the address */
	if ((he = gethostbyname(host)) == NULL) {
#if 0
		herror("gethostbyname");
#endif
		return NULL;
	}

	memset(&addr, 0, sizeof(addr));
	memcpy(&addr.sin_addr, he->h_addr, he->h_length);
	addr.sin_family = AF_INET;
	addr.sin_port = port ? port : htons(21);


	/* alloc the ftp structure */
	ftp = calloc(1, sizeof(*ftp));
	if (ftp == NULL) {
		perror("calloc");
		return NULL;
	}

	/* connect */
	if ((fd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
		perror("socket");
		goto bail;
	}

	if (my_connect(fd, (struct sockaddr*) &addr, sizeof(addr)) == -1) {
		perror("connect");
		goto bail;
	}

	size = sizeof(addr);
	if (getsockname(fd, (struct sockaddr*) &addr, &size) == -1) {
		perror("getsockname");
		goto bail;
	}

	ftp->localaddr = addr.sin_addr;
	ftp->fd = fd;

	if (!ftp_getresp(ftp) || ftp->resp != 220) {
		goto bail;
	}

	return ftp;

bail:
	if (fd != -1)
		closesocket(fd);
	free(ftp);
	return NULL;
}
示例#24
0
/*FUNCTION*/
int httpd(int argc,
          char *argv[],
          int (*AppInit)(int argc,char *argv[],pHttpdThread pHT,void **AppData),
          int (*AppStart)(void **AppData),
          void (*HttpProc)(pHttpdThread pHT,pThreadData ThisThread),
          int (*FtpProc)(pHttpdThread pHT,pThreadData ThisThread, char *pszCommand)
){
/*noverbatim
CUT*/
  int addr_size;
  int i,j,so;
  int length;
  struct _fun Functions;
  struct sockaddr_in server;
  pThreadData ThisThread;
  HttpdThread HT;
  int iState;
  int cThread;
  unsigned long iL;
#ifdef WIN32
  WORD wVersionRequested;
  WSADATA wsaData;
  int err;
#else
  int cpid;
#endif
  char *optarg,opt;
  int OptionIndex;
  fd_set acceptfds;
  struct timeval timeout;


#ifdef WIN32
  wVersionRequested = MAKEWORD( 2, 2 );
  err = WSAStartup( wVersionRequested, &wsaData );
  if( err != 0 ){
    fprintf(stderr,"Error initializing the Windows Socket subsystem\n");
    exit(1);
    }
#endif
  HT.server[0].port      = HTTPD_PORT;
  HT.server[0].ip        = HTTPD_IP;
  HT.c_servers           = 1;
  HT.threadmax           = CONCURRENT_HITS;
  HT.listenmax           = LISTEN_BACKLOG;
  HT.server[0].cAllowed  = 0;
  HT.server[0].cDenied   = 0;

  /* init the signal handlerts to SIG_IGN so that a brokern pipe does not kill us */
  InitSignalHandlers();

  /* This is just a pointer that we guarantee not to be altered. */
  HT.AppData = NULL;
  /* AppInit should return zero on success. */
  if( i=AppInit(argc,argv,&HT,&(HT.AppData)) ){
    fprintf(stderr,"AppInit returned %d\n",i);
    exit(i);
    }

  OptionIndex = 0;
  while( (opt = getoptt(argc, argv, "p:h:",&optarg,&OptionIndex)) != ':'){
    switch( opt ){
      case 'p' : /* you can specify a port number on the command line to bind on */
                 /* this overrides the configuration port */
         HT.server[0].port  = atoi(optarg);
         HT.c_servers = 1;
         break;
      case 'h' : /* you can specify a single host IP to bind on */
                 /* this overrides the configuration ip */
         HT.server[0].ip     = inet_addr(optarg);
         HT.c_servers  = 1;
         break;
      }
    }

  for( i=0 ; i < HT.c_servers ; i++ ){
    HT.server[i].sock = socket(AF_INET, SOCK_STREAM, 0);
    so=1;
    setsockopt(HT.server[i].sock, SOL_SOCKET, SO_REUSEADDR, (char *)(&so),sizeof(i));
    if( HT.server[i].sock < 0 ){
      fprintf(stderr, "Error at socket");
      exit(1);
      }
    server.sin_family = AF_INET;   
    server.sin_addr.s_addr = HT.server[i].ip;
    server.sin_port = htons(HT.server[i].port);

    for( j=0 ; j<MAXBINDTRIAL ; j++ ){
      if( ! bind(HT.server[i].sock, (struct sockaddr *)&server, sizeof(server)) )break;
      if( j == MAXBINDTRIAL-1 ){
        fprintf(stderr, "\nError at bind.");
        exit(1);
        }
      if( j== 0 )fprintf(stderr,"Bind failed on %s:%d, retrying at most %d times\n.",
                            inet_ntoa(server.sin_addr), ntohs(server.sin_port),MAXBINDTRIAL);
      else fprintf(stderr,".");
      if( j%40 == 39 )fprintf(stderr,"\n");
      Sleep(BINDSLEEP);
      }
    if( j )fprintf(stderr,"\nBind finally successful after %d trials\n",j);
    
    length = sizeof(server);
    if( getsockname(HT.server[i].sock, (struct sockaddr *)&server, &length) ){ 
      fprintf(stderr, "Error at getsockname.");
      exit(1);
      }

    listen(HT.server[i].sock, HT.listenmax);
    }
  HT.iState = STATE_NORMAL;

  if( j=AppStart(&(HT.AppData)) ){
    fprintf(stderr,"Appstart returned %d\n",j);
    exit(j);
    }

  HT.threads = (pThreadData)malloc(HT.threadmax*sizeof(ThreadData));
  if( HT.threads == NULL ){
    fprintf(stderr,"Not enough memory\n");
    exit(1);
    }

  /* Initialize the list of thread data
  */
  for( i=0 ; i < HT.threadmax ; i++ ){
    HT.threads[i].ThreadIndex = i;
    HT.threads[i].pFunctions = &Functions;
    HT.threads[i].NextFree   = i+1;
    HT.threads[i].pHT        = &HT;
    }
  HT.cThread = 0;
  /* make it dead end */
  HT.threads[HT.threadmax-1].NextFree = -1;
  HT.FirstFreeThread = 0;
  thread_InitMutex(&(HT.mxFirstFreeThread));
  Functions.pGetServerVariable = _GetServerVariable;
  Functions.pWriteClient       = _WriteClient;
  Functions.pWriteClientText   = _WriteClientText;
  Functions.pReadClient        = _ReadClient;
  Functions.pState             = _State;
  Functions.pContentType       = _ContentType;
  Functions.pHeader            = _Header;
  Functions.pStartBody         = _StartBody;
  Functions.pGetParam          = _GetParam;
  Functions.pPostParam         = _PostParam;
  Functions.pCloseClient       = _CloseClient;
  Functions.pScriptName        = _ScriptName;
  Functions.HttpProc           = HttpProc;
  Functions.FtpProc            = FtpProc;
  while(1){
    ThisThread = GetFreeThread(&HT);

    FD_ZERO(&acceptfds);
    for( i=0 ; i < HT.c_servers ; i++ )
      FD_SET(HT.server[i].sock,&acceptfds);
    timeout.tv_sec=60;
    timeout.tv_usec=0;
    i = select(FD_SETSIZE,&acceptfds,NULL,NULL,&timeout);
    for( i=0 ; i < HT.c_servers ; i++ ){
      if( FD_ISSET(HT.server[i].sock,&acceptfds) ){
        do{
          addr_size=sizeof(struct sockaddr);
          ThisThread->msgsock = accept(HT.server[i].sock,
                                      (struct sockaddr *)&(ThisThread->addr),
                                      &addr_size);
          }while(
    #ifdef WIN32
                  ThisThread->msgsock == INVALID_SOCKET
    #else
                  ThisThread->msgsock <= 0
    #endif
                  );
        thread_LockMutex(&(HT.mxState));
        iState = HT.iState;
        thread_UnlockMutex(&(HT.mxState));
        if( iState == STATE_SHUT ){/* we have to stop */
          /* wait for all threads to stop */
          for( iL = 0 ; iL < HT.lWaitCount ; iL++ ){
            thread_LockMutex(&(HT.mxFirstFreeThread));
            cThread = HT.cThread;
            thread_UnlockMutex(&(HT.mxFirstFreeThread));
            if( cThread == 1 )break;
            Sleep(HT.lWaitSec*SLEEPER);
            }
          return 0;
          }
        ThisThread->SocketOpened = 1;
        ThisThread->server_index = i;
        thread_CreateThread(&(ThisThread->T),HitHandler,ThisThread);
        }
      }
    }
  /* we never get here */
  return 0;
  }
示例#25
0
int pipe(int filedes[2]) {
    int listener;
    struct sockaddr_in addr, peer;
    socklen_t len;

    listener = -1;
    filedes[0] = -1;
    filedes[1] = -1;

    listener = socket(PF_INET, SOCK_STREAM, 0);
    if (listener < 0)
        goto error;

    filedes[0] = socket(PF_INET, SOCK_STREAM, 0);
    if (filedes[0] < 0)
        goto error;

    filedes[1] = socket(PF_INET, SOCK_STREAM, 0);
    if (filedes[1] < 0)
        goto error;

    /* Make non-blocking so that connect() won't block */
    if (set_block(filedes[0], 0) < 0)
        goto error;

    addr.sin_family = AF_INET;
    addr.sin_port = 0;
    addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

    if (bind(listener, (struct sockaddr*)&addr, sizeof(addr)) < 0)
        goto error;

    if (listen(listener, 1) < 0)
        goto error;

    len = sizeof(addr);
    if (getsockname(listener, (struct sockaddr*)&addr, &len) < 0)
        goto error;

    if (connect(filedes[0], (struct sockaddr*)&addr, sizeof(addr)) < 0) {
#ifdef OS_IS_WIN32
        if (WSAGetLastError() != EWOULDBLOCK)
#else
        if (errno != EINPROGRESS)
#endif
            goto error;
    }

    len = sizeof(peer);
    filedes[1] = accept(listener, (struct sockaddr*)&peer, &len);
    if (filedes[1] < 0)
        goto error;

    /* Restore blocking */
    if (set_block(filedes[0], 1) < 0)
        goto error;

    len = sizeof(addr);
    if (getsockname(filedes[0], (struct sockaddr*)&addr, &len) < 0)
        goto error;

    /* Check that someone else didn't steal the connection */
    if ((addr.sin_port != peer.sin_port) || (addr.sin_addr.s_addr != peer.sin_addr.s_addr))
        goto error;

    pa_close(listener);

    return 0;

error:
        if (listener >= 0)
                pa_close(listener);
        if (filedes[0] >= 0)
                pa_close(filedes[0]);
        if (filedes[1] >= 0)
                pa_close(filedes[1]);

        return -1;
}
示例#26
0
NiceSocket *
nice_udp_bsd_socket_new (NiceAddress *addr)
{
  int sockfd = -1;
  struct sockaddr_storage name;
  socklen_t name_len = sizeof (name);
  NiceSocket *sock = g_slice_new0 (NiceSocket);

  if (addr != NULL) {
    nice_address_copy_to_sockaddr(addr, (struct sockaddr *)&name);
  } else {
    memset (&name, 0, sizeof (name));
    name.ss_family = AF_UNSPEC;
  }

  if (name.ss_family == AF_UNSPEC || name.ss_family == AF_INET) {
    sockfd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP);
    name.ss_family = AF_INET;
#ifdef HAVE_SA_LEN
    name.ss_len = sizeof (struct sockaddr_in);
#endif
  } else if (name.ss_family == AF_INET6) {
    sockfd = socket (PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
    name.ss_family = AF_INET6;
#ifdef HAVE_SA_LEN
    name.ss_len = sizeof (struct sockaddr_in6);
#endif
  }

  if (sockfd == -1) {
    g_slice_free (NiceSocket, sock);
    return NULL;
  }

#ifdef FD_CLOEXEC
  fcntl (sockfd, F_SETFD, fcntl (sockfd, F_GETFD) | FD_CLOEXEC);
#endif
#ifdef O_NONBLOCK
  fcntl (sockfd, F_SETFL, fcntl (sockfd, F_GETFL) | O_NONBLOCK);
#endif

  if(bind (sockfd, (struct sockaddr *) &name,
          name.ss_family == AF_INET? sizeof (struct sockaddr_in) :
          sizeof(struct sockaddr_in6)) < 0) {
    g_slice_free (NiceSocket, sock);
#ifdef G_OS_WIN32
    closesocket(sockfd);
#else
    close (sockfd);
#endif
    return NULL;
  }

  name_len = name.ss_family == AF_INET? sizeof (struct sockaddr_in) :
      sizeof(struct sockaddr_in6);
  if (getsockname (sockfd, (struct sockaddr *) &name, &name_len) < 0) {
    g_slice_free (NiceSocket, sock);
#ifdef G_OS_WIN32
    closesocket(sockfd);
#else
    close (sockfd);
#endif
    return NULL;
  }

  nice_address_set_from_sockaddr (&sock->addr, (struct sockaddr *)&name);
  sock->fileno = sockfd;

  sock->send = socket_send;
  sock->recv = socket_recv;
  sock->is_reliable = socket_is_reliable;
  sock->close = socket_close;

  return sock;
}
示例#27
0
bool open_ipc (ipc_t* ipc_desc)
{
	bool ret_val = false;
	int port_no, sock_type;	
        char ip_addr [INET6_ADDRSTRLEN];
	struct sockaddr_in sock_addr;
        struct addrinfo addr_info, *result_addr_info, *it_addr;
	
	if (server_sock_fd == -1) // Can do that coz union has only int (so any one should do)
	{
		ZERO (&addr_info, sizeof (addr_info));
		ZERO (ip_addr, INET6_ADDRSTRLEN);
		ZERO (&sock_addr, sizeof (struct sockaddr_in));
		
		sock_addr.sin_family            = AF_INET;
		sock_addr.sin_port              = htons(0); /*Assign a new port to me*/
		
		sock_type = ipc_mode == ipc_mode_tcp_sock ? SOCK_STREAM : SOCK_DGRAM;
		
		server_sock_fd = socket (AF_INET, sock_type, 0);
		if (-1 == server_sock_fd)
		{
			printf (IPC_OPEN_ERR, strerror(errno));
			return ret_val;
		}

		addr_length = sizeof (sock_addr);
		if (-1 == bind(server_sock_fd, (struct sockaddr*) &sock_addr, addr_length))
		{
			printf (IPC_OPEN_ERR, strerror(errno));
			return ret_val;
		}

		if (-1 == getsockname (server_sock_fd, (struct sockaddr*) &sock_addr,  &addr_length)) //Who am I???
		{
			printf (IPC_OPEN_ERR, strerror(errno));
			return ret_val;
		}

		port_no = ntohs (sock_addr.sin_port);
		inet_ntop (AF_INET, &sock_addr, ip_addr, INET_ADDRSTRLEN);
		char primary_ip[INET_ADDRSTRLEN];
		
		primary_ip_addr (primary_ip);
		CONNECTION_DETAILS(primary_ip, port_no);
	}

        switch (ipc_mode)
        {
                case ipc_mode_tcp_sock:
                {
			if (listen (server_sock_fd, BACKLOG) == -1)
				printf (IPC_OPEN_ERR, strerror(errno));

			ipc_desc->tcp_fd = accept (server_sock_fd, (struct sockaddr*) &sock_addr, &addr_length);
			if (ipc_desc->tcp_fd == -1)
			{
				printf (IPC_OPEN_ERR, strerror(errno));
				break;
			}
			else
				printf ("\nConnection Accepted!\nAccepting request from this client now...\n");
			
			ret_val = true;
		}

                break;
                case ipc_mode_udp_sock:
                {
			ipc_desc->udp_fd = server_sock_fd;
			ret_val = true;
		}
                break;
        }
        
        return ret_val;
}
示例#28
0
/* Just seperated into another func for tidiness really.. */
void ListenSocket::AcceptInternal()
{
	irc::sockets::sockaddrs client;
	irc::sockets::sockaddrs server;

	socklen_t length = sizeof(client);
	int incomingSockfd = ServerInstance->SE->Accept(this, &client.sa, &length);

	ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "HandleEvent for Listensocket %s nfd=%d", bind_desc.c_str(), incomingSockfd);
	if (incomingSockfd < 0)
	{
		ServerInstance->stats->statsRefused++;
		return;
	}

	socklen_t sz = sizeof(server);
	if (getsockname(incomingSockfd, &server.sa, &sz))
	{
		ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "Can't get peername: %s", strerror(errno));
		irc::sockets::aptosa(bind_addr, bind_port, server);
	}

	/*
	 * XXX -
	 * this is done as a safety check to keep the file descriptors within range of fd_ref_table.
	 * its a pretty big but for the moment valid assumption:
	 * file descriptors are handed out starting at 0, and are recycled as theyre freed.
	 * therefore if there is ever an fd over 65535, 65536 clients must be connected to the
	 * irc server at once (or the irc server otherwise initiating this many connections, files etc)
	 * which for the time being is a physical impossibility (even the largest networks dont have more
	 * than about 10,000 users on ONE server!)
	 */
	if (incomingSockfd >= ServerInstance->SE->GetMaxFds())
	{
		ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "Server is full");
		ServerInstance->SE->Shutdown(incomingSockfd, 2);
		ServerInstance->SE->Close(incomingSockfd);
		ServerInstance->stats->statsRefused++;
		return;
	}

	if (client.sa.sa_family == AF_INET6)
	{
		/*
		 * This case is the be all and end all patch to catch and nuke 4in6
		 * instead of special-casing shit all over the place and wreaking merry
		 * havoc with crap, instead, we just recreate sockaddr and strip ::ffff: prefix
		 * if it's a 4in6 IP.
		 *
		 * This is, of course, much improved over the older way of handling this
		 * (pretend it doesn't exist + hack around it -- yes, both were done!)
		 *
		 * Big, big thanks to danieldg for his work on this.
		 * -- w00t
		 */
		static const unsigned char prefix4in6[12] = { 0,0,0,0, 0,0,0,0, 0,0,0xFF,0xFF };
		if (!memcmp(prefix4in6, &client.in6.sin6_addr, 12))
		{
			// recreate as a sockaddr_in using the IPv4 IP
			uint16_t sport = client.in6.sin6_port;
			client.in4.sin_family = AF_INET;
			client.in4.sin_port = sport;
			memcpy(&client.in4.sin_addr.s_addr, client.in6.sin6_addr.s6_addr + 12, sizeof(uint32_t));

			sport = server.in6.sin6_port;
			server.in4.sin_family = AF_INET;
			server.in4.sin_port = sport;
			memcpy(&server.in4.sin_addr.s_addr, server.in6.sin6_addr.s6_addr + 12, sizeof(uint32_t));
		}
	}

	ServerInstance->SE->NonBlocking(incomingSockfd);

	ModResult res;
	FIRST_MOD_RESULT(OnAcceptConnection, res, (incomingSockfd, this, &client, &server));
	if (res == MOD_RES_PASSTHRU)
	{
		std::string type = bind_tag->getString("type", "clients");
		if (type == "clients")
		{
			ServerInstance->Users->AddUser(incomingSockfd, this, &client, &server);
			res = MOD_RES_ALLOW;
		}
	}
	if (res == MOD_RES_ALLOW)
	{
		ServerInstance->stats->statsAccept++;
	}
	else
	{
		ServerInstance->stats->statsRefused++;
		ServerInstance->Logs->Log("SOCKET", LOG_DEFAULT, "Refusing connection on %s - %s",
			bind_desc.c_str(), res == MOD_RES_DENY ? "Connection refused by module" : "Module for this port not found");
		ServerInstance->SE->Close(incomingSockfd);
	}
}
示例#29
0
void
Getsockname(int fd, struct sockaddr *sa, socklen_t *salenptr)
{
	if (getsockname(fd, sa, salenptr) < 0)
		err_sys("getsockname error: %s", strerror(errno));
}
示例#30
0
static int
TcpGetOptionProc(
    ClientData instanceData,	/* Socket state. */
    Tcl_Interp *interp,		/* For error reporting - can be NULL. */
    const char *optionName,	/* Name of the option to retrieve the value
				 * for, or NULL to get all options and their
				 * values. */
    Tcl_DString *dsPtr)		/* Where to store the computed value;
				 * initialized by caller. */
{
    TcpState *statePtr = instanceData;
    size_t len = 0;

    if (optionName != NULL) {
	len = strlen(optionName);
    }

    if ((len > 1) && (optionName[1] == 'e') &&
	    (strncmp(optionName, "-error", len) == 0)) {
	socklen_t optlen = sizeof(int);
	int err, ret;

        if (statePtr->status == 0) {
            ret = getsockopt(statePtr->fds.fd, SOL_SOCKET, SO_ERROR,
                    (char *) &err, &optlen);
            if (ret < 0) {
                err = errno;
            }
        } else {
            err = statePtr->status;
            statePtr->status = 0;
        }
	if (err != 0) {
	    Tcl_DStringAppend(dsPtr, Tcl_ErrnoMsg(err), -1);
	}
	return TCL_OK;
    }

    if ((len == 0) || ((len > 1) && (optionName[1] == 'p') &&
	    (strncmp(optionName, "-peername", len) == 0))) {
        address peername;
        socklen_t size = sizeof(peername);

	if (getpeername(statePtr->fds.fd, &peername.sa, &size) >= 0) {
	    if (len == 0) {
		Tcl_DStringAppendElement(dsPtr, "-peername");
		Tcl_DStringStartSublist(dsPtr);
	    }
            TcpHostPortList(interp, dsPtr, peername, size);
	    if (len) {
                return TCL_OK;
            }
            Tcl_DStringEndSublist(dsPtr);
	} else {
	    /*
	     * getpeername failed - but if we were asked for all the options
	     * (len==0), don't flag an error at that point because it could be
	     * an fconfigure request on a server socket (which have no peer).
	     * Same must be done on win&mac.
	     */

	    if (len) {
		if (interp) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
                            "can't get peername: %s",
			    Tcl_PosixError(interp)));
		}
		return TCL_ERROR;
	    }
	}
    }

    if ((len == 0) || ((len > 1) && (optionName[1] == 's') &&
	    (strncmp(optionName, "-sockname", len) == 0))) {
	TcpFdList *fds;
        address sockname;
        socklen_t size;
	int found = 0;

	if (len == 0) {
	    Tcl_DStringAppendElement(dsPtr, "-sockname");
	    Tcl_DStringStartSublist(dsPtr);
	}
	for (fds = &statePtr->fds; fds != NULL; fds = fds->next) {
	    size = sizeof(sockname);
	    if (getsockname(fds->fd, &(sockname.sa), &size) >= 0) {
		found = 1;
                TcpHostPortList(interp, dsPtr, sockname, size);
	    }
	}
        if (found) {
            if (len) {
                return TCL_OK;
            }
            Tcl_DStringEndSublist(dsPtr);
        } else {
            if (interp) {
                Tcl_SetObjResult(interp, Tcl_ObjPrintf(
                        "can't get sockname: %s", Tcl_PosixError(interp)));
            }
	    return TCL_ERROR;
	}
    }

    if (len > 0) {
	return Tcl_BadChannelOption(interp, optionName, "peername sockname");
    }

    return TCL_OK;
}