void close_call_handler(unsigned long long uniqueSockID, int threads, unsigned char *buf, ssize_t len) { int index; PRINT_DEBUG("socket call handler1"); PRINT_DEBUG("%llu", uniqueSockID); index = findjinniSocket(uniqueSockID); if (index == -1) { PRINT_DEBUG("CRASH !!socket descriptor not found into jinni sockets"); nack_send(uniqueSockID, close_call); return; } /** * TODO Fix the problem with terminate queue which goes into infinite loop * when close is called */ if (removejinniSocket(uniqueSockID)) { ack_send(uniqueSockID, close_call); } else { nack_send(uniqueSockID, close_call); } }
//TODO: dummy function, need to implement this void ioctl_call_handler(unsigned long long uniqueSockID, int threads, unsigned char *buf, ssize_t len) { int index; u_int cmd; u_long arg; u_char *pt; PRINT_DEBUG(""); pt = buf; cmd = *(u_int *) pt; pt += sizeof(u_int); arg = *(u_long *) pt; pt += sizeof(u_long); if (pt - buf != len) { PRINT_DEBUG("READING ERROR! CRASH, diff=%d len=%d", pt - buf, len); nack_send(uniqueSockID, ioctl_call); return; } PRINT_DEBUG(""); index = findjinniSocket(uniqueSockID); PRINT_DEBUG(""); if (index == -1) { PRINT_DEBUG( "CRASH !!! socket descriptor not found into jinni sockets SO pipe descriptor to reply is not found too "); nack_send(uniqueSockID, ioctl_call); return; } PRINT_DEBUG("uniqueSockID=%llu, index=%d, cmd=%d, arg=%lu", uniqueSockID, index, cmd, arg); /*if (jinniSockets[index].type == SOCK_DGRAM) ioctl_udp(uniqueSockID, cmd, arg); else if (jinniSockets[index].type == SOCK_STREAM) ioctl_tcp(uniqueSockID, cmd, arg); else if (jinniSockets[index].type == SOCK_RAW) { ioctl_icmp(uniqueSockID, cmd, arg); } else { PRINT_DEBUG("unknown socket type has been read !!!"); nack_send(uniqueSockID, setsockopt_call); }*/ ack_send(uniqueSockID, ioctl_call); }
void listen_udp(unsigned long long uniqueSockID, int backlog) { int index; index = findjinniSocket(uniqueSockID); if (index == -1) { PRINT_DEBUG("socket descriptor not found into jinni sockets"); return; } PRINT_DEBUG("index = %d", index); ack_send(uniqueSockID, listen_call); }
//TODO: dummy function, need to implement this void release_call_handler(unsigned long long uniqueSockID, int threads, unsigned char *buf, ssize_t len) { u_char *pt; pt = buf; if (pt - buf != len) { PRINT_DEBUG("READING ERROR! CRASH, diff=%d len=%d", pt - buf, len); nack_send(uniqueSockID, release_call); return; } if (removejinniSocket(uniqueSockID)) { ack_send(uniqueSockID, release_call); } else { nack_send(uniqueSockID, release_call); } }
void shutdown_udp(unsigned long long uniqueSockID, int how) { /** * * TODO Implement the checking of the shut_RD, shut_RW flags before making any operations * applied on a TCP socket */ int index; index = findjinniSocket(uniqueSockID); /** TODO unlock access to the jinnisockets */ if (index == -1) { PRINT_DEBUG("socket descriptor not found into jinni sockets"); return; } PRINT_DEBUG("index = %d", index); ack_send(uniqueSockID, shutdown_call); }
/** * End of interfacing socketjinni with FINS core * */ void socket_udp(int domain, int type, int protocol, unsigned long long uniqueSockID) { PRINT_DEBUG("socket_UDP CALL"); char clientName[200]; int index; int pipe_desc; int tester; /** TODO lock the pipe semaphore then open the pipe*/ insertjinniSocket(uniqueSockID, type, protocol); PRINT_DEBUG(); index = findjinniSocket(uniqueSockID); if (index < 0) { PRINT_DEBUG("incorrect index !! Crash"); return; } ack_send(uniqueSockID, socket_call); }
static EVENT_HANDLER(ready_physical) { if(nodetype != RECEIVER) { ACK_FRAME f; int link; size_t length; length = sizeof(ACK_FRAME); CHECK(CNET_read_physical(&link, (char*) &f, &length)); uint16_t check = f.check; f.check = 0; if(CNET_ccitt((unsigned char*) &f, sizeof(ACK_FRAME)) != check) return; if(f.sequence <= 0) { // SREJ FRAME printf("\t\t\t\tSREJ received, sequence=%d\n", -f.sequence); f.sequence = -f.sequence; CNET_stop_timer(timer); trans_frame_state[f.sequence] = ACK_WAIT; frame_send(&(t_window[f.sequence].message), t_window[f.sequence].length, f.sequence); } else { // RECVREADY FRAME printf("\t\t\t\tACK received, sequence=%d\n", f.sequence); int i; for(i = (last_ack_recv + 1)%(MAXSEQ + 1); i != f.sequence - 1; i = (i + 1) % (MAXSEQ + 1)) trans_frame_state[i] = ACK_RECEIVED; last_ack_recv = f.sequence - 1; trans_frame_state[f.sequence-1] = ACK_RECEIVED; CNET_stop_timer(timer_wait); if(packets_sent >= 10000) { if(time_end == 0) time_end = nodeinfo.time_of_day.sec; } else { packets_sent++; CNET_enable_application(ALLNODES); } } } else { FRAME_DATA f; size_t length; int link; int checksum; length = sizeof(FRAME_DATA); CHECK(CNET_read_physical(&link, (char*) &f, &length)); checksum = f.checksum; f.checksum = 0; if(CNET_ccitt((unsigned char*) &f, CHECK_BYTES) != checksum) { // bad checksum, ignore frame printf("\t\t\t\tBAD checksum - frame ignored\n"); ack_send(last_ack_sent + 1, SREJ); printf("Requesting to send frame %d\n",last_ack_sent+1); return; } recv_frame_status[f.sequence] = RECEIVED; printf("\t\t\t\tDATA received, sequence=%d\n", f.sequence); int i; for(i = (last_ack_sent + 1) % (MAXSEQ + 1); i != f.sequence; i = (i + 1) % (MAXSEQ + 1)) { if(recv_frame_status[i] != RECEIVED) break; } if(i == f.sequence) ack_send(f.sequence + 1, RECVREADY); } }
void sendto_udp(unsigned long long uniqueSockID, int socketCallType, int datalen, u_char *data, int flags, struct sockaddr_in *addr, socklen_t addrlen) { uint16_t hostport; uint16_t dstport; uint32_t host_IP; uint32_t dst_IP; int len = datalen; int index; int i; struct in_addr *temp; PRINT_DEBUG(); /** TODO handle flags cases */ switch (flags) { case MSG_CONFIRM: case MSG_DONTROUTE: case MSG_DONTWAIT: case MSG_EOR: case MSG_MORE: case MSG_NOSIGNAL: case MSG_OOB: /** case of recieving a (write call)*/ default: break; } PRINT_DEBUG(""); index = findjinniSocket(uniqueSockID); if (index == -1) { PRINT_DEBUG("CRASH !! socket descriptor not found into jinni sockets"); return; } if (addr->sin_family != AF_INET) { PRINT_DEBUG("Wrong address family"); nack_send(uniqueSockID, socketCallType); return; } /** copying the data passed to be able to free the old memory location * the new created location is the one to be included into the newly created finsFrame*/ PRINT_DEBUG(""); dst_IP = ntohl(addr->sin_addr.s_addr);/** it is in network format since application used htonl */ /** addresses are in host format given that there are by default already filled * host IP and host port. Otherwise, a port and IP has to be assigned explicitly below */ /** Keep all ports and addresses in host order until later action taken */ dstport = ntohs(addr->sin_port); /** reverse it since it is in network order after application used htons */ /** * the current value of host_IP is zero but to be filled later with * the current IP using the IPv4 modules unless a binding has occured earlier */ host_IP = jinniSockets[index].host_IP; /** * Default current host port to be assigned is 58088 * It is supposed to be randomly selected from the range found in * /proc/sys/net/ipv4/ip_local_port_range * default range in Ubuntu is 32768 - 61000 * The value has been chosen randomly when the socket firstly inserted into the jinnisockets * check insertjinniSocket(processid, sockfd, fakeID, type, protocol); */ hostport = jinniSockets[index].hostport; if (hostport == (uint16_t)(-1)) { while (1) { hostport = randoming(MIN_port, MAX_port); if (checkjinniports(hostport, host_IP)) { break; } } jinniSockets[index].hostport = hostport; } PRINT_DEBUG(""); PRINT_DEBUG("index=%d, dst=%d/%d, host=%d/%d", index, dst_IP, dstport, host_IP, hostport); temp = (struct in_addr *) malloc(sizeof(struct in_addr)); temp->s_addr = host_IP; PRINT_DEBUG("index=%d, dst=%s/%d, host=%s/%d", index, inet_ntoa( addr->sin_addr), dstport, inet_ntoa(*temp), hostport); //free(data); //free(addr); PRINT_DEBUG(""); /** the meta-data parameters are all passes by copy starting from this point * */ if (jinni_UDP_to_fins(data, len, dstport, dst_IP, hostport, host_IP) == 1) { /** TODO prevent the socket interceptor from holding this semaphore before we reach this point */ PRINT_DEBUG(""); ack_send(uniqueSockID, socketCallType); PRINT_DEBUG(""); } else { PRINT_DEBUG("socketjinni failed to accomplish sendto"); nack_send(uniqueSockID, socketCallType); } return; } //end of sendto_udp
void send_udp(unsigned long long uniqueSockID, int socketCallType, int datalen, u_char *data, int flags) { uint16_t hostport; uint16_t dstport; uint32_t host_IP; uint32_t dst_IP; int len = datalen; int index; if (flags == -1000) { return (write_udp(uniqueSockID, socketCallType, datalen, data)); } /** TODO handle flags cases */ switch (flags) { case MSG_CONFIRM: case MSG_DONTROUTE: case MSG_DONTWAIT: case MSG_EOR: case MSG_MORE: case MSG_NOSIGNAL: case MSG_OOB: /** case of recieving a (write call)*/ default: break; } // end of the switch clause PRINT_DEBUG(""); index = findjinniSocket(uniqueSockID); if (index == -1) { PRINT_DEBUG("CRASH !! socket descriptor not found into jinni sockets"); return; } /** copying the data passed to be able to free the old memory location * the new created location is the one to be included into the newly created finsFrame*/ PRINT_DEBUG(""); /** check if this socket already connected to a destined address or not */ if (jinniSockets[index].connection_status == 0) { /** socket is not connected to an address. Send call will fail */ PRINT_DEBUG("socketjinni failed to accomplish send"); nack_send(uniqueSockID, socketCallType); return; } /** Keep all ports and addresses in host order until later action taken */ dstport = jinniSockets[index].dstport; dst_IP = jinniSockets[index].dst_IP; //hostport = jinniSockets[index].hostport; //hostport = 3000; /** addresses are in host format given that there are by default already filled * host IP and host port. Otherwise, a port and IP has to be assigned explicitly below */ /** * the current value of host_IP is zero but to be filled later with * the current IP using the IPv4 modules unless a binding has occured earlier */ host_IP = jinniSockets[index].host_IP; /** * Default current host port to be assigned is 58088 * It is supposed to be randomly selected from the range found in * /proc/sys/net/ipv4/ip_local_port_range * default range in Ubuntu is 32768 - 61000 * The value has been chosen randomly when the socket firstly inserted into the jinnisockets * check insertjinniSocket(processid, sockfd, fakeID, type, protocol); */ hostport = jinniSockets[index].hostport; if (hostport == (uint16_t)(-1)) { while (1) { hostport = randoming(MIN_port, MAX_port); if (checkjinniports(hostport, host_IP)) { break; } } jinniSockets[index].hostport = hostport; } PRINT_DEBUG(""); PRINT_DEBUG("addr %d,%d,%d,%d", dst_IP, dstport, host_IP, hostport); //free(data); //free(addr); PRINT_DEBUG(""); /** the meta-data paraters are all passes by copy starting from this point * */ if (jinni_UDP_to_fins(data, len, dstport, dst_IP, hostport, host_IP) == 1) { PRINT_DEBUG(""); /** TODO prevent the socket interceptor from holding this semaphore before we reach this point */ PRINT_DEBUG(""); ack_send(uniqueSockID, socketCallType); PRINT_DEBUG(""); } else { PRINT_DEBUG("socketjinni failed to accomplish send"); nack_send(uniqueSockID, socketCallType); } }// end of send_udp
void connect_udp(unsigned long long uniqueSockID, struct sockaddr_in *addr) { uint16_t dstport; uint32_t dst_IP; int index; index = findjinniSocket(uniqueSockID); if (index == -1) { PRINT_DEBUG("socket descriptor not found into jinni sockets"); return; } if (addr->sin_family != AF_INET) { PRINT_DEBUG("Wrong address family"); nack_send(uniqueSockID, connect_call); return; } /** TODO fix host port below, it is not initialized with any variable !!! */ /** the check below is to make sure that the port is not previously allocated */ dstport = ntohs(addr->sin_port); dst_IP = ntohl((addr->sin_addr).s_addr); /** check if the same port and address have been both used earlier or not * it returns (-1) in case they already exist, so that we should not reuse them * according to the RFC document and man pages: Application can call connect more than * once over the same UDP socket changing the address from one to another. SO the assigning * will take place even if the check functions returns (-1) !!! * */ /** TODO connect for UDP means that this address will be the default address to send * to. BUT IT WILL BE ALSO THE ONLY ADDRESS TO RECEIVER FROM * NOTICE THAT the relation * */ /** * NOTICE THAT the relation between the host and the destined address is many to one. * more than one local socket maybe connected to the same destined address */ if (jinniSockets[index].connection_status > 0) { PRINT_DEBUG("old destined address %d, %d", jinniSockets[index].dst_IP, jinniSockets[index].dstport); PRINT_DEBUG("new destined address %d, %d", dst_IP, dstport); } /**TODO check if the port is free for binding or previously allocated * Current code assume that the port is authorized to be accessed * and also available * */ /** Reverse again because it was reversed by the application itself */ //hostport = ntohs(addr->sin_port); /** TODO lock and unlock the protecting semaphores before making * any modifications to the contents of the jinniSockets database */ PRINT_DEBUG("%d,%d,%d", (addr->sin_addr).s_addr, ntohs(addr->sin_port), addr->sin_family); sem_wait(&jinniSockets_sem); jinniSockets[index].dstport = ntohs(addr->sin_port); jinniSockets[index].dst_IP = ntohl((addr->sin_addr).s_addr); jinniSockets[index].connection_status++; sem_post(&jinniSockets_sem); /** Reverse again because it was reversed by the application itself * In our example it is not reversed */ //jinniSockets[index].host_IP.s_addr = ntohl(jinniSockets[index].host_IP.s_addr); /** TODO convert back to the network endian form before * sending to the fins core */ ack_send(uniqueSockID, connect_call); free(addr); return; }
void bind_udp(unsigned long long uniqueSockID, struct sockaddr_in *addr) { uint16_t hostport; uint16_t dstport; uint32_t host_IP_netformat; uint32_t dst_IP_netformat; int index; index = findjinniSocket(uniqueSockID); if (index == -1) { PRINT_DEBUG("socket descriptor not found into jinni sockets"); return; } if (addr->sin_family != AF_INET) { PRINT_DEBUG("Wrong address family"); nack_send(uniqueSockID, bind_call); return; } /** TODO fix host port below, it is not initialized with any variable !!! */ /** the check below is to make sure that the port is not previously allocated */ hostport = ntohs(addr->sin_port); host_IP_netformat = (addr->sin_addr).s_addr; /** check if the same port and address have been both used earlier or not * it returns (-1) in case they already exist, so that we should not reuse them * */ if (!checkjinniports(hostport, host_IP_netformat) && !jinniSockets[index].sockopts.FSO_REUSEADDR) { PRINT_DEBUG("this port is not free"); nack_send(uniqueSockID, bind_call); free(addr); return; } /**TODO check if the port is free for binding or previously allocated * Current code assume that the port is authorized to be accessed * and also available * */ /** Reverse again because it was reversed by the application itself */ //hostport = ntohs(addr->sin_port); /** TODO lock and unlock the protecting semaphores before making * any modifications to the contents of the jinniSockets database */ PRINT_DEBUG("bind address: %d,%d,%d", (addr->sin_addr).s_addr, ntohs( addr->sin_port), addr->sin_family); PRINT_DEBUG("bind address: %d, %s/%d", addr->sin_family, inet_ntoa( addr->sin_addr), ntohs(addr->sin_port)); /** * Binding */ sem_wait(&jinniSockets_sem); jinniSockets[index].hostport = ntohs(addr->sin_port); jinniSockets[index].host_IP = (addr->sin_addr).s_addr; sem_post(&jinniSockets_sem); /** Reverse again because it was reversed by the application itself * In our example it is not reversed */ //jinniSockets[index].host_IP.s_addr = ntohl(jinniSockets[index].host_IP.s_addr); /** TODO convert back to the network endian form before * sending to the fins core */ PRINT_DEBUG("bind: index:%d, host:%d/%d, dst:%d/%d", index, jinniSockets[index].host_IP, jinniSockets[index].hostport, jinniSockets[index].dst_IP, jinniSockets[index].dstport); ack_send(uniqueSockID, bind_call); free(addr); return; } // end of bind_udp
void setsockopt_udp(unsigned long long uniqueSockID, int level, int optname, int optlen, u_char *optval) { int index; index = findjinniSocket(uniqueSockID); if (index == -1) { PRINT_DEBUG("socket descriptor not found into jinni sockets"); return; } PRINT_DEBUG("index = %d", index); PRINT_DEBUG("level=%d, optname=%d, optlen=%d", level, optname, optlen); /* * 7 levels+: * IPPPROTO_IP * IPPPROTO_IPv6 * IPPPROTO_ICMP * IPPPROTO_RAW * IPPPROTO_TCP * IPPPROTO_UDP * SOL_SOCKET */ switch (optname) { case SO_DEBUG: jinniSockets[index].sockopts.FSO_DEBUG = *(int *) optval; PRINT_DEBUG("FSO_DEBUG=%d", jinniSockets[index].sockopts.FSO_DEBUG); break; case SO_REUSEADDR: jinniSockets[index].sockopts.FSO_REUSEADDR = *(int *) optval; PRINT_DEBUG("FSO_REUSEADDR=%d", jinniSockets[index].sockopts.FSO_REUSEADDR); break; case SO_TYPE: case SO_PROTOCOL: case SO_DOMAIN: case SO_ERROR: case SO_DONTROUTE: case SO_BROADCAST: case SO_SNDBUF: case SO_SNDBUFFORCE: case SO_RCVBUF: case SO_RCVBUFFORCE: case SO_KEEPALIVE: case SO_OOBINLINE: case SO_NO_CHECK: case SO_PRIORITY: case SO_LINGER: case SO_BSDCOMPAT: case SO_TIMESTAMP: case SO_TIMESTAMPNS: case SO_TIMESTAMPING: case SO_RCVTIMEO: case SO_SNDTIMEO: case SO_RCVLOWAT: case SO_SNDLOWAT: case SO_PASSCRED: case SO_PEERCRED: case SO_PEERNAME: case SO_ACCEPTCONN: case SO_PASSSEC: case SO_PEERSEC: case SO_MARK: case SO_RXQ_OVFL: case SO_ATTACH_FILTER: case SO_DETACH_FILTER: default: PRINT_DEBUG("default=%d", optname); break; } ack_send(uniqueSockID, setsockopt_call); /* metadata *udpout_meta = (metadata *) malloc(sizeof(metadata)); metadata_create(udpout_meta); metadata_writeToElement(udpout_meta, "dstport", &dstprt, META_TYPE_INT); */ /** check the opt_name to find which bit to access in the options variable then use * the following code to handle the bits individually * setting a bit number |= 1 << x; That will set bit x. * Clearing a bit number &= ~(1 << x); That will clear bit x. * The XOR operator (^) can be used to toggle a bit. number ^= 1 << x; That will toggle bit x. * Checking a bit value = number & (1 << x); */ //uint32_t socketoptions; }