コード例 #1
0
ファイル: httpd.c プロジェクト: DrMcCoy/contiki-inga
/*---------------------------------------------------------------------------*/
void
httpd_appcall(void *state)
{
#if DEBUGLOGIC
  struct httpd_state *s; //Enter here for debugging with output directed to TCPBUF
  s = sg = (struct httpd_state *) memb_alloc(&conns);
  if (1) {
#else
  struct httpd_state *s = (struct httpd_state *) state;
  if (uip_closed() || uip_aborted() || uip_timedout()) {
    if (s != NULL) {
      if (s->fd >= 0) {
        httpd_fs_close(s->fd);
        s->fd = -1;
      }
      memb_free(&conns, s);
    }
  } else if (uip_connected()) {
    s = (struct httpd_state *) memb_alloc(&conns);
    if (s == NULL) {
      uip_abort();
      return;
    }
#endif
    tcp_markconn(uip_conn, s);
    PSOCK_INIT(&s->sin, (uint8_t *) s->inputbuf, sizeof (s->inputbuf) - 1);
    PSOCK_INIT(&s->sout, (uint8_t *) s->inputbuf, sizeof (s->inputbuf) - 1);
    PT_INIT(&s->outputpt);
    s->state = STATE_WAITING;
    s->timer = 0;
#if WEBSERVER_CONF_AJAX
    s->ajax_timeout = WEBSERVER_CONF_TIMEOUT;
#endif
    handle_connection(s);
  } else if (s != NULL) {
    if (uip_poll()) {
      ++s->timer;
#if WEBSERVER_CONF_AJAX
      if (s->timer >= s->ajax_timeout) {
#else
      if (s->timer >= WEBSERVER_CONF_TIMEOUT) {
#endif
        uip_abort();
        if (s->fd >= 0) {
          httpd_fs_close(s->fd);
          s->fd = -1;
        }
        memb_free(&conns, s);
      }
    } else {
      s->timer = 0;
    }
    handle_connection(s);
  } else {
    uip_abort();
  }
}
/*---------------------------------------------------------------------------*/
void
httpd_init(void)
{
  tcp_listen(UIP_HTONS(80));
  memb_init(&conns);
  PRINTD(" sizof(struct httpd_state) = %d\n",sizeof(struct httpd_state));
  PRINTA(" %d bytes used for httpd state storage\n", conns.size * conns.num);

}
コード例 #2
0
ファイル: recv.c プロジェクト: object8421/tanlz
int main(int argc, char *argv[])
{
    int ret, n, max, lsnid, sckid = -1;
    fd_set rdset;
    struct timeval timeout;
    socklen_t len;
    struct sockaddr_in cliaddr;
    char buff[1500];


    lsnid = tcp_listen(atoi(argv[1]));
    if (lsnid < 0) {
        return -1;
    }

    while(1) {
        FD_ZERO(&rdset);
        FD_SET(lsnid, &rdset);

        if (sckid > 0) {
            FD_SET(sckid, &rdset);
        }

        max = lsnid > sckid? lsnid : sckid;

        timeout.tv_sec = 30;
        timeout.tv_usec = 0;

        ret = select(max+1, &rdset, NULL, NULL, &timeout);
        if (ret < 0) {
            if (EINTR == errno) { continue; }
            return -1;
        }
        else if (0 == ret) {
            continue;
        }
        

        if (FD_ISSET(lsnid, &rdset)) {
            len = sizeof(cliaddr);

            sckid = accept(lsnid, (struct sockaddr *)&cliaddr, &len);
            if (sckid < 0) {
                frpintf(stderr, "errmsg:[%d] %s\n", errno, strerror(errno));
                return -1;
            }
        }

        if (sckid > 0 && FD_ISSET(sckid, &rdset)) {
            while (1) {
                n = read(sckid, buff, sizeof(buff));
                if (n < 0) {
                    break;
                }
            }
        }
    }

    close(lsnid);
    close(sckid);
    return 0;
}
コード例 #3
0
ファイル: server.c プロジェクト: tdautc19841202/wolfssl
THREAD_RETURN CYASSL_THREAD server_test(void* args)
{
    SOCKET_T sockfd   = WOLFSSL_SOCKET_INVALID;
    SOCKET_T clientfd = WOLFSSL_SOCKET_INVALID;

    SSL_METHOD* method = 0;
    SSL_CTX*    ctx    = 0;
    SSL*        ssl    = 0;

    const char msg[] = "I hear you fa shizzle!";
    char   input[80];
    int    ch;
    int    version = SERVER_DEFAULT_VERSION;
    int    doCliCertCheck = 1;
    int    useAnyAddr = 0;
    word16 port = wolfSSLPort;
    int    usePsk = 0;
    int    useAnon = 0;
    int    doDTLS = 0;
    int    needDH = 0;
    int    useNtruKey   = 0;
    int    nonBlocking  = 0;
    int    trackMemory  = 0;
    int    fewerPackets = 0;
    int    pkCallbacks  = 0;
    int    serverReadyFile = 0;
    int    wc_shutdown     = 0;
    int    resume = 0;
    int    resumeCount = 0;
    int    loopIndefinitely = 0;
    int    echoData = 0;
    int    throughput = 0;
    int    minDhKeyBits = DEFAULT_MIN_DHKEY_BITS;
    int    doListen = 1;
    int    ret;
    char*  alpnList = NULL;
    unsigned char alpn_opt = 0;
    char*  cipherList = NULL;
    const char* verifyCert = cliCert;
    const char* ourCert    = svrCert;
    const char* ourKey     = svrKey;
    const char* ourDhParam = dhParam;
    int    argc = ((func_args*)args)->argc;
    char** argv = ((func_args*)args)->argv;

#ifndef NO_PSK
    int sendPskIdentityHint = 1;
#endif

#ifdef HAVE_SNI
    char*  sniHostName = NULL;
#endif

#ifdef HAVE_OCSP
    int    useOcsp  = 0;
    char*  ocspUrl  = NULL;
#endif

    ((func_args*)args)->return_code = -1; /* error state */

#ifdef NO_RSA
    verifyCert = (char*)cliEccCert;
    ourCert    = (char*)eccCert;
    ourKey     = (char*)eccKey;
#endif
    (void)trackMemory;
    (void)pkCallbacks;
    (void)needDH;
    (void)ourKey;
    (void)ourCert;
    (void)ourDhParam;
    (void)verifyCert;
    (void)useNtruKey;
    (void)doCliCertCheck;
    (void)minDhKeyBits;
    (void)alpnList;
    (void)alpn_opt;

#ifdef CYASSL_TIRTOS
    fdOpenSession(Task_self());
#endif

#ifdef WOLFSSL_VXWORKS
    useAnyAddr = 1;
#else
    while ((ch = mygetopt(argc, argv, "?dbstnNufrRawPIp:v:l:A:c:k:Z:S:oO:D:L:ieB:"))
                         != -1) {
        switch (ch) {
            case '?' :
                Usage();
                exit(EXIT_SUCCESS);

            case 'd' :
                doCliCertCheck = 0;
                break;

            case 'b' :
                useAnyAddr = 1;
                break;

            case 's' :
                usePsk = 1;
                break;

            case 't' :
            #ifdef USE_WOLFSSL_MEMORY
                trackMemory = 1;
            #endif
                break;

            case 'n' :
                useNtruKey = 1;
                break;

            case 'u' :
                doDTLS  = 1;
                break;

            case 'f' :
                fewerPackets = 1;
                break;

            case 'R' :
                serverReadyFile = 1;
                break;

            case 'r' :
                #ifndef NO_SESSION_CACHE
                    resume = 1;
                #endif
                break;

            case 'P' :
            #ifdef HAVE_PK_CALLBACKS
                pkCallbacks = 1;
            #endif
                break;

            case 'p' :
                port = (word16)atoi(myoptarg);
                #if !defined(NO_MAIN_DRIVER) || defined(USE_WINDOWS_API)
                    if (port == 0)
                        err_sys("port number cannot be 0");
                #endif
                break;

            case 'w' :
                wc_shutdown = 1;
                break;

            case 'v' :
                version = atoi(myoptarg);
                if (version < 0 || version > 3) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                break;

            case 'l' :
                cipherList = myoptarg;
                break;

            case 'A' :
                verifyCert = myoptarg;
                break;

            case 'c' :
                ourCert = myoptarg;
                break;

            case 'k' :
                ourKey = myoptarg;
                break;

            case 'D' :
                #ifndef NO_DH
                    ourDhParam = myoptarg;
                #endif
                break;

            case 'Z' :
                #ifndef NO_DH
                    minDhKeyBits = atoi(myoptarg);
                    if (minDhKeyBits <= 0 || minDhKeyBits > 16000) {
                        Usage();
                        exit(MY_EX_USAGE);
                    }
                #endif
                break;

            case 'N':
                nonBlocking = 1;
                break;

            case 'S' :
                #ifdef HAVE_SNI
                    sniHostName = myoptarg;
                #endif
                break;

            case 'o' :
                #ifdef HAVE_OCSP
                    useOcsp = 1;
                #endif
                break;

            case 'O' :
                #ifdef HAVE_OCSP
                    useOcsp = 1;
                    ocspUrl = myoptarg;
                #endif
                break;

            case 'a' :
                #ifdef HAVE_ANON
                    useAnon = 1;
                #endif
                break;
            case 'I':
                #ifndef NO_PSK
                    sendPskIdentityHint = 0;
                #endif
                break;

            case 'L' :
                #ifdef HAVE_ALPN
                    alpnList = myoptarg;

                    if (alpnList[0] == 'C' && alpnList[1] == ':')
                        alpn_opt = WOLFSSL_ALPN_CONTINUE_ON_MISMATCH;
                    else if (alpnList[0] == 'F' && alpnList[1] == ':')
                        alpn_opt = WOLFSSL_ALPN_FAILED_ON_MISMATCH;
                    else {
                        Usage();
                        exit(MY_EX_USAGE);
                    }

                    alpnList += 2;

                #endif
                break;

            case 'i' :
                loopIndefinitely = 1;
                break;

            case 'e' :
                echoData = 1;
                break;

            case 'B':
                throughput = atoi(myoptarg);
                if (throughput <= 0) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                break;

            default:
                Usage();
                exit(MY_EX_USAGE);
        }
    }

    myoptind = 0;      /* reset for test cases */
#endif /* !WOLFSSL_VXWORKS */

    /* sort out DTLS versus TLS versions */
    if (version == CLIENT_INVALID_VERSION) {
        if (doDTLS)
            version = CLIENT_DTLS_DEFAULT_VERSION;
        else
            version = CLIENT_DEFAULT_VERSION;
    }
    else {
        if (doDTLS) {
            if (version == 3)
                version = -2;
            else
                version = -1;
        }
    }

#ifdef USE_CYASSL_MEMORY
    if (trackMemory)
        InitMemoryTracker();
#endif

    switch (version) {
#ifndef NO_OLD_TLS
    #ifdef WOLFSSL_ALLOW_SSLV3
        case 0:
            method = SSLv3_server_method();
            break;
    #endif

    #ifndef NO_TLS
        case 1:
            method = TLSv1_server_method();
            break;


        case 2:
            method = TLSv1_1_server_method();
            break;

        #endif
#endif

#ifndef NO_TLS
        case 3:
            method = TLSv1_2_server_method();
            break;
#endif

#ifdef CYASSL_DTLS
    #ifndef NO_OLD_TLS
        case -1:
            method = DTLSv1_server_method();
            break;
    #endif

        case -2:
            method = DTLSv1_2_server_method();
            break;
#endif

        default:
            err_sys("Bad SSL version");
    }

    if (method == NULL)
        err_sys("unable to get method");

    ctx = SSL_CTX_new(method);
    if (ctx == NULL)
        err_sys("unable to get ctx");

#if defined(HAVE_SESSION_TICKET) && defined(HAVE_CHACHA) && \
                                    defined(HAVE_POLY1305)
    if (TicketInit() != 0)
        err_sys("unable to setup Session Ticket Key context");
    wolfSSL_CTX_set_TicketEncCb(ctx, myTicketEncCb);
#endif

    if (cipherList)
        if (SSL_CTX_set_cipher_list(ctx, cipherList) != SSL_SUCCESS)
            err_sys("server can't set cipher list 1");

#ifdef CYASSL_LEANPSK
    usePsk = 1;
#endif

#if defined(NO_RSA) && !defined(HAVE_ECC)
    usePsk = 1;
#endif

    if (fewerPackets)
        CyaSSL_CTX_set_group_messages(ctx);

#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
    SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif

#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    if (!usePsk && !useAnon) {
        if (SSL_CTX_use_certificate_file(ctx, ourCert, SSL_FILETYPE_PEM)
                                         != SSL_SUCCESS)
            err_sys("can't load server cert file, check file and run from"
                    " wolfSSL home dir");
    }
#endif

#ifndef NO_DH
    wolfSSL_CTX_SetMinDhKey_Sz(ctx, (word16)minDhKeyBits);
#endif

#ifdef HAVE_NTRU
    if (useNtruKey) {
        if (CyaSSL_CTX_use_NTRUPrivateKey_file(ctx, ourKey)
                                != SSL_SUCCESS)
            err_sys("can't load ntru key file, "
                    "Please run from wolfSSL home dir");
    }
#endif
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    if (!useNtruKey && !usePsk && !useAnon) {
        if (SSL_CTX_use_PrivateKey_file(ctx, ourKey, SSL_FILETYPE_PEM)
                                         != SSL_SUCCESS)
            err_sys("can't load server private key file, check file and run "
                "from wolfSSL home dir");
    }
#endif

    if (usePsk) {
#ifndef NO_PSK
        SSL_CTX_set_psk_server_callback(ctx, my_psk_server_cb);

        if (sendPskIdentityHint == 1)
            SSL_CTX_use_psk_identity_hint(ctx, "cyassl server");

        if (cipherList == NULL) {
            const char *defaultCipherList;
            #if defined(HAVE_AESGCM) && !defined(NO_DH)
                defaultCipherList = "DHE-PSK-AES128-GCM-SHA256";
                needDH = 1;
            #elif defined(HAVE_NULL_CIPHER)
                defaultCipherList = "PSK-NULL-SHA256";
            #else
                defaultCipherList = "PSK-AES128-CBC-SHA256";
            #endif
            if (SSL_CTX_set_cipher_list(ctx, defaultCipherList) != SSL_SUCCESS)
                err_sys("server can't set cipher list 2");
        }
#endif
    }

    if (useAnon) {
#ifdef HAVE_ANON
        CyaSSL_CTX_allow_anon_cipher(ctx);
        if (cipherList == NULL) {
            if (SSL_CTX_set_cipher_list(ctx, "ADH-AES128-SHA") != SSL_SUCCESS)
                err_sys("server can't set cipher list 4");
        }
#endif
    }

#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    /* if not using PSK, verify peer with certs */
    if (doCliCertCheck && usePsk == 0 && useAnon == 0) {
        SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER |
                                SSL_VERIFY_FAIL_IF_NO_PEER_CERT,0);
        if (SSL_CTX_load_verify_locations(ctx, verifyCert, 0) != SSL_SUCCESS)
            err_sys("can't load ca file, Please run from wolfSSL home dir");
    }
#endif

#if defined(CYASSL_SNIFFER)
    /* don't use EDH, can't sniff tmp keys */
    if (cipherList == NULL) {
        if (SSL_CTX_set_cipher_list(ctx, "AES256-SHA256") != SSL_SUCCESS)
            err_sys("server can't set cipher list 3");
    }
#endif

#ifdef HAVE_SNI
    if (sniHostName)
        if (CyaSSL_CTX_UseSNI(ctx, CYASSL_SNI_HOST_NAME, sniHostName,
                                           XSTRLEN(sniHostName)) != SSL_SUCCESS)
            err_sys("UseSNI failed");
#endif

    while (1) {
        /* allow resume option */
        if(resumeCount > 1) {
            if (doDTLS == 0) {
                SOCKADDR_IN_T client;
                socklen_t client_len = sizeof(client);
                clientfd = accept(sockfd, (struct sockaddr*)&client,
                                 (ACCEPT_THIRD_T)&client_len);
            } else {
                tcp_listen(&sockfd, &port, useAnyAddr, doDTLS);
                clientfd = sockfd;
            }
            if(WOLFSSL_SOCKET_IS_INVALID(clientfd)) {
                err_sys("tcp accept failed");
            }
        }

        ssl = SSL_new(ctx);
        if (ssl == NULL)
            err_sys("unable to get SSL");

#ifndef NO_HANDSHAKE_DONE_CB
        wolfSSL_SetHsDoneCb(ssl, myHsDoneCb, NULL);
#endif
#ifdef HAVE_CRL
        CyaSSL_EnableCRL(ssl, 0);
        CyaSSL_LoadCRL(ssl, crlPemDir, SSL_FILETYPE_PEM, CYASSL_CRL_MONITOR |
                                                         CYASSL_CRL_START_MON);
        CyaSSL_SetCRL_Cb(ssl, CRL_CallBack);
#endif
#ifdef HAVE_OCSP
        if (useOcsp) {
            if (ocspUrl != NULL) {
                CyaSSL_CTX_SetOCSP_OverrideURL(ctx, ocspUrl);
                CyaSSL_CTX_EnableOCSP(ctx, CYASSL_OCSP_NO_NONCE
                                                        | CYASSL_OCSP_URL_OVERRIDE);
            }
            else
                CyaSSL_CTX_EnableOCSP(ctx, CYASSL_OCSP_NO_NONCE);
        }
#endif
#ifdef HAVE_PK_CALLBACKS
        if (pkCallbacks)
            SetupPkCallbacks(ctx, ssl);
#endif

        /* do accept */
        tcp_accept(&sockfd, &clientfd, (func_args*)args, port, useAnyAddr,
                       doDTLS, serverReadyFile, doListen);
        doListen = 0; /* Don't listen next time */

        SSL_set_fd(ssl, clientfd);

#ifdef HAVE_ALPN
        if (alpnList != NULL) {
            printf("ALPN accepted protocols list : %s\n", alpnList);
            wolfSSL_UseALPN(ssl, alpnList, (word32)XSTRLEN(alpnList), alpn_opt);
        }
#endif

#ifdef WOLFSSL_DTLS
        if (doDTLS) {
            SOCKADDR_IN_T cliaddr;
            byte          b[1500];
            int           n;
            socklen_t     len = sizeof(cliaddr);

            /* For DTLS, peek at the next datagram so we can get the client's
             * address and set it into the ssl object later to generate the
             * cookie. */
            n = (int)recvfrom(sockfd, (char*)b, sizeof(b), MSG_PEEK,
                              (struct sockaddr*)&cliaddr, &len);
            if (n <= 0)
                err_sys("recvfrom failed");

            wolfSSL_dtls_set_peer(ssl, &cliaddr, len);
        }
#endif
        if (usePsk == 0 || useAnon == 1 || cipherList != NULL || needDH == 1) {
            #if !defined(NO_FILESYSTEM) && !defined(NO_DH) && !defined(NO_ASN)
                CyaSSL_SetTmpDH_file(ssl, ourDhParam, SSL_FILETYPE_PEM);
            #elif !defined(NO_DH)
                SetDH(ssl);  /* repick suites with DHE, higher priority than PSK */
            #endif
        }

#ifndef CYASSL_CALLBACKS
        if (nonBlocking) {
            CyaSSL_set_using_nonblock(ssl, 1);
            tcp_set_nonblocking(&clientfd);
            NonBlockingSSL_Accept(ssl);
        } else if (SSL_accept(ssl) != SSL_SUCCESS) {
            int err = SSL_get_error(ssl, 0);
            char buffer[CYASSL_MAX_ERROR_SZ];
            printf("error = %d, %s\n", err, ERR_error_string(err, buffer));
            err_sys("SSL_accept failed");
        }
#else
        NonBlockingSSL_Accept(ssl);
#endif
        showPeer(ssl);

#ifdef HAVE_ALPN
        if (alpnList != NULL) {
            int err;
            char *protocol_name = NULL, *list = NULL;
            word16 protocol_nameSz = 0, listSz = 0;

            err = wolfSSL_ALPN_GetProtocol(ssl, &protocol_name, &protocol_nameSz);
            if (err == SSL_SUCCESS)
                printf("Sent ALPN protocol : %s (%d)\n",
                       protocol_name, protocol_nameSz);
            else if (err == SSL_ALPN_NOT_FOUND)
                printf("No ALPN response sent (no match)\n");
            else
                printf("Getting ALPN protocol name failed\n");

            err = wolfSSL_ALPN_GetPeerProtocol(ssl, &list, &listSz);
            if (err == SSL_SUCCESS)
                printf("List of protocol names sent by Client: %s (%d)\n",
                       list, listSz);
            else
                printf("Get list of client's protocol name failed\n");

            free(list);
        }
#endif
        if(echoData == 0 && throughput == 0) {
            ret = SSL_read(ssl, input, sizeof(input)-1);
            if (ret > 0) {
                input[ret] = 0;
                printf("Client message: %s\n", input);

            }
            else if (ret < 0) {
                int readErr = SSL_get_error(ssl, 0);
                if (readErr != SSL_ERROR_WANT_READ)
                    err_sys("SSL_read failed");
            }

            if (SSL_write(ssl, msg, sizeof(msg)) != sizeof(msg))
                err_sys("SSL_write failed");
        }
        else {
            ServerEchoData(ssl, clientfd, echoData, throughput);
        }

#if defined(WOLFSSL_MDK_SHELL) && defined(HAVE_MDK_RTX)
        os_dly_wait(500) ;
#elif defined (CYASSL_TIRTOS)
        Task_yield();
#endif

        if (doDTLS == 0) {
            ret = SSL_shutdown(ssl);
            if (wc_shutdown && ret == SSL_SHUTDOWN_NOT_DONE)
                SSL_shutdown(ssl);    /* bidirectional shutdown */
        }
        SSL_free(ssl);

        CloseSocket(clientfd);

        if (resume == 1 && resumeCount == 0) {
            resumeCount++;           /* only do one resume for testing */
            continue;
        }
        resumeCount = 0;

        if(!loopIndefinitely) {
            break;  /* out of while loop, done with normal and resume option */
        }
    } /* while(1) */

    CloseSocket(sockfd);
    SSL_CTX_free(ctx);

    ((func_args*)args)->return_code = 0;


#if defined(NO_MAIN_DRIVER) && defined(HAVE_ECC) && defined(FP_ECC) \
                            && defined(HAVE_THREAD_LS)
    ecc_fp_free();  /* free per thread cache */
#endif

#ifdef USE_WOLFSSL_MEMORY
    if (trackMemory)
        ShowMemoryTracker();
#endif

#ifdef CYASSL_TIRTOS
    fdCloseSession(Task_self());
#endif

#if defined(HAVE_SESSION_TICKET) && defined(HAVE_CHACHA) && \
                                    defined(HAVE_POLY1305)
    TicketCleanup();
#endif

#ifndef CYASSL_TIRTOS
    return 0;
#endif
}
コード例 #4
0
ファイル: serialexa.c プロジェクト: jgambox/DCRabbit_9
void vs_handler(VsState* state)
{
	auto tcp_Socket* socket;
	auto int ch, bytes_written;
	auto int bytes_to_write;

	if(vs_info.mode==VS_MODEOFF)
		return;

	socket=&state->socket;

	/*
	 *		was the connection reset?
	 */
	if(state->state!=VS_INIT && tcp_tick(socket)==0) {
#ifdef VERBOSE
		printf("Connection closed\n");
#endif
		state->state=VS_INIT;
		state->open_timeout=vs_info.open_timeout;
	}

	switch(state->state)
	{
		case VS_INIT:
			/*
			 *		passive open on the socket port
			 */

			if(state->open_timeout && vs_info.mode == VS_MODEACTIVE) {
				costate {
					waitfor(DelayMs(state->open_timeout));
					state->open_timeout=0;
				}

				if(state->open_timeout)
					break;
			}

			serXopen(vs_info.baud);

			if(vs_info.mode == VS_MODEPASSIVE) {
				if (tcp_listen(socket,vs_info.port,0,0,NULL,0) != 0) {
					state->state=VS_LISTEN;
#ifdef VERBOSE
					printf("\nListening on socket\n");
#endif
				}
				else {
					printf("\nError listening on socket!\n");
				}
			} else if(vs_info.mode == VS_MODEACTIVE) {
				if (tcp_open(socket,0,vs_info.dest_ip,vs_info.dest_port,NULL) != 0) {
					state->state=VS_OPENING;
#ifdef VERBOSE
					printf("\nOpening socket\n");
#endif
				}
				else {
					printf("\nError opening socket!\n");
				}
			}
			break;

		case VS_LISTEN:
		case VS_OPENING:
			/*
			 *		wait for a connection
			 */

			if(sock_established(socket) || sock_bytesready(socket) >= 0) {
				state->state=VS_OPEN;
				sock_mode(socket,vs_info.binary);

#ifdef VERBOSE
				printf("New Connection\n");
#endif
			}
			break;

		case VS_OPEN:
			if(vs_info.timeout!=0 &&
				state->offset &&
				(state->last_character+vs_info.timeout)<MS_TIMER) {
				bytes_written=sock_fastwrite(socket,state->buffer,state->offset);
				if (bytes_written < 0) {
					state->state = VS_WAITCLOSE;
					sock_close(socket);
#ifdef VERBOSE
					printf("Connection closed\n");
#endif
					break;
				}

				/*
				 *		Hmmm... We weren't able to write all the bytes out.
				 *		Since we don't want to loose any characters, we will
				 *		shift everything over and hopefully write it soon.
				 *
				 */

				if(bytes_written!=state->offset) {
					memcpy(state->buffer,state->buffer+bytes_written,state->offset-bytes_written);
					state->offset = bytes_written;
					break;
				} else
					state->offset = 0;
			}

			/*
			 *		process any characters.
			 */

			bytes_to_write=sock_bytesready(socket);
			if(bytes_to_write>serXwrFree())
				bytes_to_write=serXwrFree();

			if(bytes_to_write>(int)sizeof(state->buffer))
				bytes_to_write=sizeof(state->buffer);

			if(bytes_to_write>0) {
				sock_read(socket,state->buffer,bytes_to_write);
				serXwrite(state->buffer,bytes_to_write);
			}

			/*
			 *		If we aren't worried about interpacket delay
			 *		just send the characters if there is room in
			 *		the buffer.
			 *
			 */

			if(vs_info.timeout==0) {
				bytes_to_write=serXrdUsed();

				if(bytes_to_write>sock_tbleft(socket))
					bytes_to_write=sock_tbleft(socket);

				if(bytes_to_write>(int)sizeof(state->buffer))
					bytes_to_write=sizeof(state->buffer);

				if(bytes_to_write>0) {
					serXread(state->buffer,bytes_to_write,0);
					sock_write(socket,state->buffer,bytes_to_write);
				}
			} else {
				while(state->offset<VS_MAXOFFSET && (ch=serXgetc())!=-1) {
#ifdef USE_STDIO
					printf("%c",ch);
#endif
					state->buffer[state->offset++]=ch;
					state->last_character=MS_TIMER;
				}
			}

			/*
			 *		We should immediately flush characters if the buffer
			 *		is full.
			 *
			 */

			if(state->offset==VS_MAXOFFSET) {
				bytes_written=sock_fastwrite(socket,state->buffer,state->offset);
				if (bytes_written < 0) {
					state->state = VS_WAITCLOSE;
					sock_close(socket);
#ifdef VERBOSE
					printf("Connection closed\n");
#endif
					break;
				}

				/*
				 *		Hmmm... We weren't able to write all the bytes out.
				 *		Since we don't want to loose any characters, we will
				 *		shift everything over and hopefully write it soon.
				 *
				 */

				if(bytes_written!=state->offset) {
					memcpy(state->buffer,state->buffer+bytes_written,state->offset-bytes_written);
					state->offset = bytes_written;
				} else
					state->offset = 0;
			}

			break;

		case VS_WAITCLOSE:
			break;

		default:
			/*
			 *		how did we get here?  programming error?
			 */

			state->state=VS_INIT;
			break;
	}