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; }
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; }
/*----------------------------------------------------------------------* 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 }
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); }
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; }
/* {{{ 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; }
void Socket::GetSockName(sockaddr *psa, socklen_t *psaLen) { assert(m_s != INVALID_SOCKET); CheckAndHandleError_int("getsockname", getsockname(m_s, psa, psaLen)); }
/* * 功 能:处理客户端发来的数据 * 参 数: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; }
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; } } } }
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; }
/* 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; }
/* * 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; }
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 }
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; }
/* * 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; }
void CChannel::getSockAddr(sockaddr* addr) const { socklen_t namelen = (AF_INET == m_iIPversion) ? sizeof(sockaddr_in) : sizeof(sockaddr_in6); getsockname(m_iSocket, addr, &namelen); }
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; }
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; }
/* 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() */
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; } }
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; }
/*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; }
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; }
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; }
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; }
/* 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); } }
void Getsockname(int fd, struct sockaddr *sa, socklen_t *salenptr) { if (getsockname(fd, sa, salenptr) < 0) err_sys("getsockname error: %s", strerror(errno)); }
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; }