/* "tcp://host:port" "tcp://:port" "udp://host:port" "udp://:port" */ static int socket_open( UThread* ut, const UPortDevice* pdev, const UCell* from, int opt, UCell* res ) { NodeServ ns; SocketExt* ext; int socket; int nowait = opt & UR_PORT_NOWAIT; //int port = 0; //int hostPort = 0; //UCell* initAddr = 0; if( ! ur_is(from, UT_STRING) ) return ur_error( ut, UR_ERR_TYPE, "socket open expected string" ); ext = (SocketExt*) memAlloc( sizeof(SocketExt) ); ext->addrlen = 0; #ifdef _WIN32 ext->event = WSA_INVALID_EVENT; #endif //if( ur_is(from, UT_STRING) ) { stringToNodeServ( ut, from, &ns ); if( ! makeSockAddr( ut, ext, &ns ) ) goto fail; } #if 0 else if( ur_is(from, UT_BLOCK) )
int netAddrSend(PyrObject *netAddrObj, int msglen, char *bufptr, bool sendMsgLen) { int err, port, addr; SC_TcpClientPort* comPort = (SC_TcpClientPort*)(netAddrObj->slots + ivxNetAddr_Socket)->uptr; if (comPort) { // send TCP int tcpSocket = comPort->Socket(); if (sendMsgLen) { // send length of message in network byte-order int32 sizebuf = htonl(msglen); sendall(tcpSocket, &sizebuf, sizeof(int32)); } sendall(tcpSocket, bufptr, msglen); } else { if (gUDPport == 0) return errFailed; // send UDP err = slotIntVal(netAddrObj->slots + ivxNetAddr_Hostaddr, &addr); if (err) return err; if (addr == 0) { #ifdef NO_INTERNAL_SERVER // no internal server under SC_WIN32 yet #else if (gInternalSynthServer.mWorld) { World_SendPacket(gInternalSynthServer.mWorld, msglen, bufptr, &localServerReplyFunc); } #endif return errNone; } err = slotIntVal(netAddrObj->slots + ivxNetAddr_PortID, &port); if (err) return err; struct sockaddr_in toaddr; makeSockAddr(toaddr, addr, port); sendallto(gUDPport->Socket(), bufptr, msglen, (sockaddr*)&toaddr, sizeof(toaddr)); } return errNone; }
/* "tcps://host:port" "tcps://:port" "udps://host:port" "udps://:port" */ static int ssl_open( UThread* ut, const UPortDevice* pdev, const UCell* from, int opt, UCell* res ) { NodeServ ns; SSLExt* ext; int ok; //int nowait = opt & UR_PORT_NOWAIT; mbedtls_net_context* nc; mbedtls_ssl_context* sc; mbedtls_ssl_config* conf; const char* pers = "ssl_client1"; (void) opt; if( ! ur_is(from, UT_STRING) ) return ur_error( ut, UR_ERR_TYPE, "socket open expected string" ); ext = (SSLExt*) memAlloc( sizeof(SSLExt) ); ext->se.addrlen = 0; #ifdef _WIN32 ext->se.event = WSA_INVALID_EVENT; #endif //if( ur_is(from, UT_STRING) ) { stringToNodeServ( ut, from, &ns ); if( ! makeSockAddr( ut, &ext->se, &ns ) ) goto fail; } if( ! ns.service ) { ur_error( ut, UR_ERR_SCRIPT, "Socket port requires hostname and/or port" ); goto fail; } if( ! boron_requestAccess( ut, "Open socket %s", ns.service ) ) goto fail; ssl_init( ext ); nc = &ext->nc; sc = &ext->sc; conf = &ext->conf; ok = mbedtls_ctr_drbg_seed( &ext->ctr_drbg, mbedtls_entropy_func, &ext->entropy, (const unsigned char*) pers, strlen(pers) ); if( ok != 0 ) { ssl_error( ut, "mbedtls_ctr_drbg_seed", ok ); goto failSSL; } ok = mbedtls_net_connect( nc, ns.node, ns.service, (ns.socktype == SOCK_DGRAM) ? MBEDTLS_NET_PROTO_UDP : MBEDTLS_NET_PROTO_TCP ); if( ok != 0 ) { ssl_error( ut, "mbedtls_net_connect", ok ); goto failSSL; } ok = mbedtls_ssl_config_defaults( conf, MBEDTLS_SSL_IS_CLIENT, (ns.socktype == SOCK_DGRAM) ? MBEDTLS_SSL_TRANSPORT_DATAGRAM : MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT ); if( ok != 0 ) { ssl_error( ut, "mbedtls_ssl_config_defaults", ok ); goto failSSL; } mbedtls_ssl_conf_authmode( conf, MBEDTLS_SSL_VERIFY_NONE ); //mbedtls_ssl_conf_ca_chain( conf, cacert, NULL ); mbedtls_ssl_conf_rng( conf, mbedtls_ctr_drbg_random, &ext->ctr_drbg ); mbedtls_ssl_conf_dbg( conf, ssl_debug, stdout ); ok = mbedtls_ssl_setup( sc, conf ); if( ok != 0 ) { ssl_error( ut, "mbedtls_ssl_setup", ok ); goto failSSL; } ok = mbedtls_ssl_set_hostname( sc, "Boron TLS Server 1" ); if( ok != 0 ) { ssl_error( ut, "mbedtls_ssl_set_hostname", ok ); goto failSSL; } mbedtls_ssl_set_bio( sc, nc, mbedtls_net_send, mbedtls_net_recv, NULL ); while( (ok = mbedtls_ssl_handshake( sc )) != 0 ) { if( ok != MBEDTLS_ERR_SSL_WANT_READ && ok != MBEDTLS_ERR_SSL_WANT_WRITE ) { ssl_error( ut, "mbedtls_ssl_handshake", ok ); goto failSSL; } } { UBuffer* pbuf; pbuf = boron_makePort( ut, pdev, ext, res ); pbuf->TCP = (ns.socktype == SOCK_STREAM) ? 1 : 0; pbuf->FD = nc->fd; //printf( "KR socket_open %d %d\n", pbuf->FD, pbuf->TCP ); } return UR_OK; failSSL: ssl_free( ext ); fail: memFree( ext ); return UR_THROW; }
int prNetAddr_Connect(VMGlobals *g, int numArgsPushed) { PyrSlot* netAddrSlot = g->sp; PyrObject* netAddrObj = netAddrSlot->uo; int err, port, addr; err = slotIntVal(netAddrObj->slots + ivxNetAddr_PortID, &port); if (err) return err; err = slotIntVal(netAddrObj->slots + ivxNetAddr_Hostaddr, &addr); if (err) return err; struct sockaddr_in toaddr; makeSockAddr(toaddr, addr, port); int aSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (aSocket == -1) { //post("\nCould not create socket\n"); return errFailed; } const int on = 1; #ifdef SC_WIN32 if (setsockopt( aSocket, IPPROTO_TCP, TCP_NODELAY, (const char*)&on, sizeof(on)) != 0) { #else if (setsockopt( aSocket, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) != 0) { #endif //post("\nCould not setsockopt TCP_NODELAY\n"); #ifdef SC_WIN32 closesocket(aSocket); #else close(aSocket); #endif return errFailed; }; if(connect(aSocket,(struct sockaddr*)&toaddr,sizeof(toaddr)) != 0) { //post("\nCould not connect socket\n"); #ifdef SC_WIN32 closesocket(aSocket); #else close(aSocket); #endif return errFailed; } SC_TcpClientPort *comPort = new SC_TcpClientPort(aSocket, netAddrTcpClientNotifyFunc, netAddrObj); SetPtr(netAddrObj->slots + ivxNetAddr_Socket, comPort); return errNone; } int prNetAddr_Disconnect(VMGlobals *g, int numArgsPushed); int prNetAddr_Disconnect(VMGlobals *g, int numArgsPushed) { PyrSlot* netAddrSlot = g->sp; PyrObject* netAddrObj = netAddrSlot->uo; SC_TcpClientPort *comPort = (SC_TcpClientPort*)(netAddrObj->slots + ivxNetAddr_Socket)->uptr; if (comPort) comPort->Close(); return errNone; }
int main() { int sock = 0, /* Server socket descriptor */ cli = 0; /* Client's socket descriptor */ _sockaddr_in *server = NULL, /* Server to listen */ *client = NULL; /* Client to be written when connection accepted */ socklen_t len = 0; /* Length of sockaddr_in structure */ char mesg[] = "Hello to the world of socket programming!\n"; /* Mesg. to send */ int sent = 0; /* Bytes sent to client counter */ /* Take a TCP socket */ if((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { /* Error check */ perror("Socket: "); return 1; } /* Create server address structure */ if((server = makeSockAddr(10000, INADDR_ANY)) == NULL) return 2; len = sizeof(_sockaddr_in); /* Get size of structure */ /* Bind socket to port */ if(bind(sock, (_sockaddr *)server, len) == -1) { /* Error check */ /* Note that server is of sockaddr_in type, hence the casting; as sockaddr * is the superstructure containing it. */ perror("bind"); free(server); /* Release memory used for server */ return 3; } /* Wait for clients (listen) */ if(listen(sock, 5) == -1) { /* Error check (might not be needed */ /* 5 client back log queue requested */ perror("listen"); free(server); /* Release memory used for server */ return 4; } /* Once we start listening, we have to wait for the various clients to * connect. And once a client connects we start the processing. * In order to do that, lets use a perpetual loop. */ while(1) { /* This is not the best way to do it, because server won't be able to exit * upon signal, but let's keep it like this to make it simple. */ if((client = makeEmptySockAddr()) == NULL) { /* Client structure members are to be set by accept() */ free(server); /* Release memory used for server */ return 5; } if((cli = accept(sock, (_sockaddr *)client, &len)) == -1) { /* Error check */ /* Accept() receives the server socket, to create (write) the client's. * All info is to be written to the casted to sockaddr client structure, * hence the pointer. * Also we need to get (write) the client socket structure length in len. */ perror("accept"); free(client); /* Release memory used for client */ free(server); /* Release memory used for server */ return 6; } /* Now client socket has been returned and we can talk to it */ sent = send(cli, mesg, strlen(mesg), 0); /* Send message to client */ printf("Sent %d bytes to client: %s\n", sent, inet_ntoa(client->sin_addr)); /* Close connection */ close(cli); free(client); /* Release memory used for client */ printf("Client address memory released\n"); } free(server); return 0; }