void peisk_acceptTCPConnections() { int sin_size=sizeof(struct sockaddr_in); int sock; struct sockaddr_in peerAddr; PeisConnection *connection; PeisConnectMessage message; if(!peiskernel.tcp_isListening) return; sock=accept(peiskernel.tcp_serverSocket,(struct sockaddr *)&peerAddr,(socklen_t*) &sin_size); if(sock <= 0) return; if(peisk_printLevel & PEISK_PRINT_CONNECTIONS) printf("peisk: incomming TCP connection ...\n"); if(fcntl(sock,F_SETFL,O_NONBLOCK) == -1) { fprintf(stderr,"peisk: error setting socket nonblocking, closing connection\n"); close(sock); return; } /* Create connection structure to use */ connection = peisk_newConnection(); if(!connection) return; /* Wait up to 200ms for data - otherwise drop connection */ if(!peisk_recvBlocking(sock,&message,sizeof(message),0,0.2) && (peisk_printLevel & PEISK_PRINT_CONNECTIONS)) { printf("Timeout on incomming connection (1)\n"); peisk_freeConnection(connection); close(sock); return; } /* Check that it's ok to accept this connection */ if(peisk_verifyConnectMessage(connection,&message) != 0) { peisk_freeConnection(connection); close(sock); return; } /* Store TCP information in connection */ connection->type = eTCPConnection; connection->connection.tcp.socket=sock; /* Let P2P layer handle this connection */ peisk_incommingConnectFinished(connection,&message); if(peisk_printLevel & PEISK_PRINT_CONNECTIONS) printf("peisk: accepted new connection to %d with index: %d, flags=%d\n", message.id,connection->id,message.flags); }
void peisk_bluetoothAcceptConnections() { int i,len; PeisBluetoothAdaptor *adaptor; socklen_t opt = sizeof(struct sockaddr_l2); char str[256]; PeisConnectMessage message; PeisConnection *connection; for(i=0;i<peisk_nBluetoothAdaptors;i++) { adaptor = &peisk_bluetoothAdaptors[i]; if(adaptor->incomming.mode == 0) { adaptor->incomming.socket = accept(adaptor->listenSocket,(struct sockaddr*) &adaptor->incomming.remoteAddr, &opt); if(adaptor->incomming.socket == -1) continue; printf("Setting MTU of incomming socket\n"); peisk_bluetooth_setMTU(adaptor->incomming.socket); #ifdef OLD struct l2cap_options opts; struct l2cap_conninfo conn; socklen_t optlen; printf("Setting MTU of incomming socket\n"); memset(&opts, 0, sizeof(opts)); optlen = sizeof(opts); if (getsockopt(adaptor->incomming.socket, SOL_L2CAP, L2CAP_OPTIONS, &opts, &optlen) < 0) { perror("Can't get default L2CAP options"); } /* Set new options */ printf("Old L2CAP MTU: %d %d\n",opts.omtu,opts.imtu); opts.omtu = PEISK_MAX_PACKAGE_SIZE; opts.imtu = PEISK_MAX_PACKAGE_SIZE; /* if (rfcmode > 0) opts.mode = rfcmode;*/ #endif ba2str(&adaptor->incomming.remoteAddr.l2_bdaddr,str); printf("Incomming connection from: %s\n",str); if(fcntl(adaptor->incomming.socket,F_SETFL,O_NONBLOCK) != 0) { perror("Failed to set incomming socket nonblocking\n"); } adaptor->incomming.timeout = peisk_timeNow + 5.0; adaptor->incomming.mode = 1; } if(adaptor->incomming.mode == 1) { len = read(adaptor->incomming.socket,(void*)&message,sizeof(message)); if(len == sizeof(message)) { /* Create connection structure to use */ printf("Received connection message:\n"); peisk_hexDump(&message,len); printf("\n"); connection = peisk_newConnection(); if(!connection) { fprintf(stderr,"peisk::error - failed to create connection structure\n"); return; } if(peisk_verifyConnectMessage(connection,&message) != 0) { printf("do not accept him\n"); peisk_abortConnect(connection); close(adaptor->incomming.socket); adaptor->incomming.mode = 0; continue; } connection->type = eBluetoothConnection; connection->connection.bluetooth.socket = adaptor->incomming.socket; connection->connection.bluetooth.adaptor = adaptor; printf("connection %x accepted\n",(int)connection); /* Let P2P layer handle this connection */ peisk_incommingConnectFinished(connection,&message); if(1 || peisk_printLevel & PEISK_PRINT_CONNECTIONS) printf("peisk: accepted new incomming BLUETOOTH connection to %d with index: %d, flags=%d\n", message.id,connection->id,message.flags); adaptor->incomming.mode = 0; } else if(len > 0) { fprintf(stderr,"Warning, received incorrect length on incomming bluetooth connection\n"); close(adaptor->incomming.socket); adaptor->incomming.mode = 0; continue; } } if(adaptor->incomming.mode == 1 && adaptor->incomming.timeout < peisk_timeNow) { /* peisk_abortConnect(adaptor->outgoing.connection); ?? */ peisk_freeConnection(connection); close(adaptor->incomming.socket); adaptor->incomming.mode = 0; } } }
PeisConnection *peisk_tcpConnect(char *name,int port,int flags) { struct hostent *hostent; struct sockaddr_in peerAddr; int sock; int retval; socklen_t retlen; fd_set writeSet, readSet, exepSet; struct timeval timeout; PeisConnection *connection; /** \todo peisk_tcpConnect - refuse to connect to hosts we already are connected to. */ /* Refuse connections to ourselves */ if(port == peiskernel.tcp_serverPort && (strcmp(name,"localhost") == 0 || strcmp(name,"127.0.0.1") == 0 || strcmp(name,peiskernel.hostInfo.hostname) == 0)) return NULL; /* Lookup hostname */ h_errno=0; hostent=gethostbyname(name); if(!hostent) { fprintf(stdout, "peisk: gethostbyname(%s) failed. h_errno=%d hostent=%x\n", name,h_errno,(unsigned int)(unsigned long) hostent); return NULL; } /* Create connection structure to use. This will allocate and place the connection in PENDING mode. */ connection = peisk_newConnection(); /* Prepare OS socket */ sock=socket(AF_INET,SOCK_STREAM,0); if(sock == -1) { perror("Failed to create a new socket\n"); return NULL; } peerAddr.sin_family = AF_INET; peerAddr.sin_port = htons(port); peerAddr.sin_addr.s_addr = INADDR_ANY; bzero(&(peerAddr.sin_zero),8); bcopy((char *)hostent->h_addr,(char *)&peerAddr.sin_addr,hostent->h_length); /* Set socket non blocking before connecting */ if(fcntl(sock,F_SETFL,O_NONBLOCK) == -1) { fprintf(stderr,"peisk: error setting socket nonblocking, not connecting\n"); close(sock); return NULL; } /* Start connecting */ connect(sock,(struct sockaddr*)&peerAddr,sizeof(struct sockaddr)); /** For now, wait and see if connection has succeeded within 100ms and continue afterwards. \todo Handle queued connection attempts better, eg. by placing them on a queue of pending connections */ timeout.tv_sec=0; timeout.tv_usec=100000; /* Use a timeout of 100ms */ FD_ZERO(&readSet); FD_ZERO(&writeSet); FD_ZERO(&exepSet); FD_SET(sock,&writeSet); retval=select(sock+1, &readSet, &writeSet, &exepSet, &timeout); if(retval <= 0) { if(peisk_printLevel & PEISK_PRINT_CONNECTIONS) fprintf(stdout,"peisk: failed to connect to %s:%d.\n Select returned: %d\n",name,port,retval); return NULL; } retlen=sizeof(int); if(getsockopt(sock,SOL_SOCKET,SO_ERROR,&retval,&retlen) == -1) { if(peisk_printLevel & PEISK_PRINT_CONNECTIONS) fprintf(stdout,"peisk: failed to connect to %s:%d.\n Getsockopt failed, errno: %d\n",name,port,errno); return NULL; } if(retval) { if(peisk_printLevel & PEISK_PRINT_CONNECTIONS) fprintf(stdout, "peisk: failed to connect to %s:%d.\n SO_ERROR is %d\n", name,port,retval); return NULL; } connection->type=eTCPConnection; connection->connection.tcp.socket=sock; PeisConnectMessage message; peisk_initConnectMessage(&message,flags); send(sock,&message,sizeof(message),MSG_NOSIGNAL); peisk_outgoingConnectFinished(connection,flags); if(peisk_printLevel & PEISK_PRINT_CONNECTIONS) fprintf(stdout,"peisk: new outbound tcp/ip connection #%d to %s:%d established, flags=%d\n", connection->id,name,port,flags); return connection; }
PeisConnection *peisk_bluetoothConnect(unsigned char btAddr[6],int port,int flags) { int i,j,bestStrength; PeisBtDevice *device; PeisBluetoothAdaptor *adaptor; printf("Attempting to connect to "); peisk_printBluetoothAddress(btAddr); printf(";%d\n",port); /* Find the device corresponding to this address */ for(i=0;i<peisk_nBluetoothDevices;i++) { device = &peisk_bluetoothDevices[i]; for(j=0;j<6;j++) if(device->btAddr[j] != btAddr[j]) break; if(j == 6) break; } if(i == peisk_nBluetoothDevices) { printf("No such device found\n"); return NULL; } /*printf("Adaptor modes: %d\n",peisk_bluetoothAdaptors[0].outgoing.mode); printf("Last seen: %f\n",device->lastSeen[0]-peisk_timeNow); printf("Strength: %d\n",device->rawStrength[0]); */ /* Find the best interface for this address */ for(i=0,bestStrength=0,adaptor=NULL;i<peisk_nBluetoothAdaptors;i++) { if(peisk_bluetoothAdaptors[i].outgoing.mode == 0 && device->lastSeen[i] > peisk_timeNow - PEISK_BLUETOOTH_KEEPALIVE && device->rawStrength[i] > PEISK_BLUETOOTH_MIN_CONNECTABLE_STRENGTH && device->rawStrength[i] > bestStrength) { adaptor = &peisk_bluetoothAdaptors[i]; bestStrength = device->rawStrength[i]; } } if(!adaptor) { printf("No suitable adaptor found\n"); return NULL; } /*printf("Using adaptor: %s\n",adaptor->name);*/ /* Allocate connection structure to use. This will allocate and place the connection in PENDING mode. */ adaptor->outgoing.connection = peisk_newConnection(); adaptor->outgoing.connection->type = eBluetoothConnection; adaptor->outgoing.connection->connection.bluetooth.adaptor = adaptor; printf("Preparing connection: %x id: %d\n",(unsigned int) adaptor->outgoing.connection,adaptor->outgoing.connection->id); /* Prepare connection request structure and connection */ adaptor->outgoing.flags = flags; adaptor->outgoing.mode = 1; adaptor->outgoing.timeout = peisk_timeNow + PEISK_CONNECT_TIMEOUT; /* Finally, initiate connection attempt. Will be finalized by bluetoothConnectOutgoing periodic function */ struct sockaddr_l2 addr = { 0 }; adaptor->outgoing.socket = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); addr.l2_family = AF_BLUETOOTH; addr.l2_psm = htobs(-1); /* should be -1 or 0 ?? */ addr.l2_bdaddr = adaptor->addr; bind(adaptor->outgoing.socket, (struct sockaddr *)&addr, sizeof(addr)); printf("Setting MTU of outgoing socket\n"); peisk_bluetooth_setMTU(adaptor->outgoing.socket); addr.l2_family = AF_BLUETOOTH; addr.l2_psm = htobs(port); for(j=0;j<6;j++) addr.l2_bdaddr.b[j] = btAddr[5-j]; if(fcntl(adaptor->outgoing.socket,F_SETFL,O_NONBLOCK) != 0) { perror("Failed to set bluetooth socket nonblocking\n"); } connect(adaptor->outgoing.socket, (struct sockaddr *)&addr, sizeof(addr)); return adaptor->outgoing.connection; }