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); } }
void getsockopt_call_handler(unsigned long long uniqueSockID, int threads, unsigned char *buf, ssize_t len) { int index; int level; int optname; int optlen; u_char *optval; u_char *pt; PRINT_DEBUG(""); pt = buf; level = *(int *) pt; pt += sizeof(int); optname = *(int *) pt; pt += sizeof(int); optlen = *(int *) pt; pt += sizeof(int); if (optlen > 0) { optval = (u_char *) malloc(optlen); memcpy(optval, pt, optlen); pt += optlen; } if (pt - buf != len) { PRINT_DEBUG("READING ERROR! CRASH, diff=%d len=%d", pt - buf, len); nack_send(uniqueSockID, getsockopt_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, getsockopt_call); return; } PRINT_DEBUG(""); if (jinniSockets[index].type == SOCK_DGRAM) getsockopt_udp(uniqueSockID, level, optname, optlen, optval); else if (jinniSockets[index].type == SOCK_STREAM) getsockopt_tcp(uniqueSockID, level, optname, optlen, optval); else if (jinniSockets[index].type == SOCK_RAW) { getsockopt_icmp(uniqueSockID, level, optname, optlen, optval); } else { PRINT_DEBUG("unknown socket type has been read !!!"); nack_send(uniqueSockID, getsockopt_call); } }
void connect_call_handler(unsigned long long uniqueSockID, int threads, unsigned char *buf, ssize_t len) { int index; socklen_t addrlen; struct sockaddr_in *addr; u_char *pt; pt = buf; addrlen = *(int *) pt; pt += sizeof(int); if (addrlen <= 0) { PRINT_DEBUG("READING ERROR! CRASH, addrlen=%d", addrlen); nack_send(uniqueSockID, connect_call); return; } addr = (struct sockaddr_in *) malloc(addrlen); memcpy(addr, pt, addrlen); pt += addrlen; if (pt - buf != len) { PRINT_DEBUG("READING ERROR! CRASH, diff=%d len=%d", pt - buf, len); nack_send(uniqueSockID, connect_call); return; } PRINT_DEBUG("%d,%d,%d", (addr->sin_addr).s_addr, ntohs(addr->sin_port), addr->sin_family); index = findjinniSocket(uniqueSockID); /** if that requested socket does not exist !! * this means we can not even talk to the requester FINS crash as a response!! */ if (index == -1) { PRINT_DEBUG( " CRASH !socket descriptor not found into jinni sockets! Bind failed on Jinni Side "); nack_send(uniqueSockID, connect_call); return; } if (jinniSockets[index].type == SOCK_DGRAM) { connect_udp(uniqueSockID, addr); } else if (jinniSockets[index].type == SOCK_STREAM) { connect_tcp(uniqueSockID, addr); } else { PRINT_DEBUG("This socket is of unknown type"); nack_send(uniqueSockID, connect_call); } return; }
void getpeername_udp(unsigned long long uniqueSockID, int addrlen) { void *msg; u_char *pt; int msg_len; int ret_val; int index; struct sockaddr_in address; int address_length = sizeof(struct sockaddr_in); index = findjinniSocket(uniqueSockID); address.sin_family = AF_INET; address.sin_addr.s_addr = jinniSockets[index].dst_IP; address.sin_port = jinniSockets[index].dstport; memset(address.sin_zero, 0, 8); PRINT_DEBUG("*****%d*********%d , %d*************",address_length,address.sin_addr.s_addr,address.sin_port ) msg_len = sizeof(u_int) + sizeof(unsigned long long) + 2*sizeof(int) + address_length; msg = malloc(msg_len); pt = msg; *(u_int *) pt = getpeername_call; pt += sizeof(u_int); *(unsigned long long *) pt = uniqueSockID; pt += sizeof(unsigned long long); *(int *) pt = ACK; pt += sizeof(int); *(int *) pt = address_length; pt += sizeof(int); memcpy(pt, &address, address_length); pt += address_length; if (pt - (u_char *) msg != msg_len) { PRINT_DEBUG("write error: diff=%d len=%d\n", pt - (u_char *) msg, msg_len); free(msg); nack_send(uniqueSockID, getpeername_call); return; } PRINT_DEBUG("msg_len=%d msg=%s", msg_len, (char *) msg); ret_val = send_wedge(nl_sockfd, msg, msg_len, 0); free(msg); if (ret_val) { nack_send(uniqueSockID, getpeername_call); } }
void recv_call_handler(unsigned long long uniqueSockID, int threads, unsigned char *buf, ssize_t len) { int index; int datalen; int flags; u_char *pt; PRINT_DEBUG(); pt = buf; datalen = *(size_t *) pt; pt += sizeof(size_t); flags = *(int *) pt; pt += sizeof(int); if (pt - buf != len) { PRINT_DEBUG("READING ERROR! CRASH, diff=%d len=%d", pt - buf, len); nack_send(uniqueSockID, recv_call); return; } /** Notice that send is only used with tcp connections since * the receiver is already known */ index = findjinniSocket(uniqueSockID); if (index == -1) { PRINT_DEBUG("CRASH !!socket descriptor not found into jinni sockets"); nack_send(uniqueSockID, recv_call); return; } if (jinniSockets[index].type == SOCK_DGRAM) { /** Whenever we need to implement non_blocking mode using * threads. We will call the function below using thread_create */ recv_udp(uniqueSockID, datalen, flags); } else if (jinniSockets[index].type == SOCK_STREAM) { recv_tcp(uniqueSockID, datalen, flags); } else { PRINT_DEBUG("This socket is of unknown type"); nack_send(uniqueSockID, recv_call); } } // end of recv_call_handler()
//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); }
/** * End of interfacing socketjinni with FINS core * */ void socket_udp(int domain, int type,int protocol,int sockfd,int fakeID,pid_t processid) { 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(processid, sockfd,fakeID,type,protocol); PRINT_DEBUG(); sprintf(clientName,CLIENT_CHANNEL_RX,processid,fakeID); mkfifo(clientName,0777); pipe_desc = open(clientName,O_WRONLY); index = findjinniSocket(processid,sockfd); if (index < 0) { PRINT_DEBUG("incorrect index !! Crash"); exit(1); } PRINT_DEBUG("0000"); jinniSockets[index].jinniside_pipe_ds = pipe_desc; /** Now the client can proceed to next step after openning the pipe */ PRINT_DEBUG("0002"); sem_getvalue(jinniSockets[index].s, &tester); PRINT_DEBUG("tester = %d", tester); PRINT_DEBUG("0001"); sem_wait(jinniSockets[index].s); ack_write(pipe_desc,processid,sockfd); sem_post(jinniSockets[index].as); /** TODO unlock the semaphore */ sem_post(jinniSockets[index].s); PRINT_DEBUG("0003"); return; }
void listen_call_handler(unsigned long long uniqueSockID, int threads, unsigned char *buf, ssize_t len) { int index; int backlog; u_char *pt; PRINT_DEBUG(""); pt = buf; backlog = *(int *) pt; pt += sizeof(int); if (pt - buf != len) { PRINT_DEBUG("READING ERROR! CRASH, diff=%d len=%d", pt - buf, len); nack_send(uniqueSockID, listen_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, listen_call); return; } PRINT_DEBUG(""); if (jinniSockets[index].type == SOCK_DGRAM) listen_udp(uniqueSockID, backlog); else if (jinniSockets[index].type == SOCK_STREAM) listen_tcp(uniqueSockID, backlog); else if (jinniSockets[index].type == SOCK_RAW) { listen_icmp(uniqueSockID, backlog); } else { PRINT_DEBUG("unknown socket type has been read !!!"); nack_send(uniqueSockID, listen_call); } }
void shutdown_call_handler(unsigned long long uniqueSockID, int threads, unsigned char *buf, ssize_t len) { int index; int how; u_char *pt; PRINT_DEBUG(); pt = buf; how = *(int *) pt; pt += sizeof(int); if (pt - buf != len) { PRINT_DEBUG("READING ERROR! CRASH, diff=%d len=%d", pt - buf, len); nack_send(uniqueSockID, shutdown_call); return; } index = findjinniSocket(uniqueSockID); if (index == -1) { PRINT_DEBUG("CRASH !!socket descriptor not found into jinni sockets"); nack_send(uniqueSockID, shutdown_call); return; } if (jinniSockets[index].type == SOCK_DGRAM) { /** Whenever we need to implement non_blocking mode using * threads. We will call the function below using thread_create */ shutdown_udp(uniqueSockID, how); } else if (jinniSockets[index].type == SOCK_STREAM) { shutdown_tcp(uniqueSockID, how); } else { PRINT_DEBUG("This socket is of unknown type"); nack_send(uniqueSockID, shutdown_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); }
void recvfrom_call_handler(unsigned long long uniqueSockID, int threads, unsigned char *buf, ssize_t len) { int index; int datalen; int flags; int symbol; u_char *data; socklen_t addrlen; struct sockaddr *addr; u_char *pt; struct recvfrom_data *thread_data; pthread_t *recvmsg_thread; int rc; PRINT_DEBUG(); pt = buf; datalen = *(size_t *) pt; pt += sizeof(size_t); flags = *(int *) pt; pt += sizeof(int); symbol = *(int *) pt; pt += sizeof(int); if (pt - buf != len) { PRINT_DEBUG("READING ERROR! CRASH, diff=%d len=%d", pt - buf, len); nack_send(uniqueSockID, recvfrom_call); return; } /** Notice that send is only used with tcp connections since * the receiver is already known */ index = findjinniSocket(uniqueSockID); if (index == -1) { PRINT_DEBUG("CRASH !!socket descriptor not found into jinni sockets"); nack_send(uniqueSockID, recvfrom_call); return; } if (recv_thread_count < MAX_recv_threads) { PRINT_DEBUG("recv_thread_count=%d", recv_thread_count); recvmsg_thread = (pthread_t *) malloc(sizeof(pthread_t)); thread_data = (struct recvfrom_data *) malloc( sizeof(struct recvfrom_data)); thread_data->id = recv_thread_index++; thread_data->uniqueSockID = uniqueSockID; thread_data->socketCallType = recvfrom_call; thread_data->datalen = datalen; thread_data->flags = flags; thread_data->symbol = symbol; if (jinniSockets[index].type == SOCK_DGRAM) { /** Whenever we need to implement non_blocking mode using * threads. We will call the function below using thread_create */ rc = pthread_create(recvmsg_thread, NULL, (void * (*)(void *)) recvfrom_udp, (void *) thread_data); //recvfrom_udp(uniqueSockID, recvfrom_call, datalen, flags, symbol); } else if (jinniSockets[index].type == SOCK_STREAM) { rc = pthread_create(recvmsg_thread, NULL, (void * (*)(void *)) recvfrom_tcp, (void *) thread_data); //recvfrom_tcp(uniqueSockID, recvfrom_call, datalen, flags, symbol); } else if ((jinniSockets[index].type == SOCK_RAW) && (jinniSockets[index].protocol == IPPROTO_ICMP)) { rc = pthread_create(recvmsg_thread, NULL, (void * (*)(void *)) recvfrom_icmp, (void *) thread_data); //recvfrom_icmp(uniqueSockID, recvfrom_call, datalen, flags, symbol); } else { PRINT_DEBUG("This socket is of unknown type"); nack_send(uniqueSockID, recvfrom_call); rc = 1; } if (rc) { PRINT_DEBUG("Problem starting recvmsg thread: %d, ret=%d", thread_data->id, rc); } else { sem_wait(&recv_thread_sem); recv_thread_count++; sem_post(&recv_thread_sem); } free(recvmsg_thread); } else { PRINT_DEBUG("Hit max allowed recv thread, count=%d", recv_thread_count); nack_send(uniqueSockID, recvfrom_call); } } // end of recvfrom_call_handler()
void getsockopt_udp(unsigned long long uniqueSockID, int level, int optname, int optlen, u_char *optval) { int index; int len; char *val; void *msg; u_char *pt; int msg_len; int ret_val; 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); /* metadata *udpout_meta = (metadata *) malloc(sizeof(metadata)); metadata_create(udpout_meta); metadata_writeToElement(udpout_meta, "dstport", &dstprt, META_TYPE_INT); */ switch (optname) { case SO_DEBUG: //jinniSockets[index].sockopts.FSO_DEBUG = *(int *)optval; break; case SO_REUSEADDR: len = sizeof(int); val = (char *) &(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: //nack? break; } msg_len = sizeof(u_int) + sizeof(unsigned long long) + 2 * sizeof(int) + len; msg = malloc(msg_len); pt = msg; *(u_int *) pt = getsockopt_call; pt += sizeof(u_int); *(unsigned long long *) pt = uniqueSockID; pt += sizeof(unsigned long long); *(int *) pt = ACK; pt += sizeof(int); *(int *) pt = len; pt += sizeof(int); memcpy(pt, val, len); pt += len; if (pt - (u_char *) msg != msg_len) { PRINT_DEBUG("write error: diff=%d len=%d\n", pt - (u_char *) msg, msg_len); free(msg); nack_send(uniqueSockID, getsockopt_call); return; } PRINT_DEBUG("msg_len=%d msg=%s", msg_len, (char *) msg); ret_val = send_wedge(nl_sockfd, msg, msg_len, 0); free(msg); if (ret_val) { nack_send(uniqueSockID, getsockopt_call); } }
void sendto_call_handler(unsigned long long uniqueSockID, int threads, unsigned char *buf, ssize_t len) { int index; int datalen; int flags; u_char *data; socklen_t addrlen; struct sockaddr_in *addr; u_char *pt; PRINT_DEBUG(""); pt = buf; datalen = *(int *) pt; pt += sizeof(int); PRINT_DEBUG("passed data len = %d", datalen); if (datalen <= 0) { PRINT_DEBUG("DATA Field is empty!!"); nack_send(uniqueSockID, sendto_call); return; } data = (u_char *) malloc(datalen); PRINT_DEBUG(""); memcpy(data, pt, datalen); pt += datalen; PRINT_DEBUG(""); flags = *(int *) pt; pt += sizeof(int); PRINT_DEBUG(""); addrlen = *(socklen_t *) pt; pt += sizeof(socklen_t); PRINT_DEBUG(""); addr = (struct sockaddr_in *) malloc(addrlen); memcpy(addr, pt, addrlen); pt += addrlen; PRINT_DEBUG(""); if (pt - buf != len) { PRINT_DEBUG("READING ERROR! CRASH, diff=%d len=%d", pt - buf, len); nack_send(uniqueSockID, sendto_call); return; } index = findjinniSocket(uniqueSockID); if (index == -1) { PRINT_DEBUG( "CRASH !!! socket descriptor not found into jinni sockets SO pipe descriptor to reply is notfound too "); nack_send(uniqueSockID, sendto_call); return; } PRINT_DEBUG(""); /** * * In case a connected socket has been called by mistake using sendto * (IGNORE THE ADDRESSES AND USET THE ADDRESS THE SOCKET IS CONNECTED TO IT) */ if (jinniSockets[index].connection_status > 0) { if (jinniSockets[index].type == SOCK_DGRAM) send_udp(uniqueSockID, sendto_call, datalen, data, flags); else if (jinniSockets[index].type == SOCK_STREAM) send_tcp(uniqueSockID, sendto_call, datalen, data, flags); else if (jinniSockets[index].type == SOCK_RAW) { } else { PRINT_DEBUG("unknown socket type has been read !!!"); nack_send(uniqueSockID, sendto_call); } } else { /** * The default case , the socket is not connected socket */ if (jinniSockets[index].type == SOCK_DGRAM) sendto_udp(uniqueSockID, sendto_call, datalen, data, flags, addr, addrlen); else if (jinniSockets[index].type == SOCK_STREAM) sendto_tcp(uniqueSockID, sendto_call, datalen, data, flags, addr, addrlen); else if (jinniSockets[index].type == SOCK_RAW) { } else { PRINT_DEBUG("unknown socket type has been read !!!"); nack_send(uniqueSockID, sendto_call); } } PRINT_DEBUG(); return; } //end of sendto_call_handler()
void send_call_handler(unsigned long long uniqueSockID, int threads, unsigned char *buf, ssize_t len) { int index; int datalen; int flags; u_char *data; socklen_t addrlen; struct sockaddr *addr; u_char *pt; PRINT_DEBUG(""); pt = buf; datalen = *(ssize_t *) pt; pt += sizeof(ssize_t); PRINT_DEBUG("passed data len = %d", datalen); if (datalen <= 0) { PRINT_DEBUG("DATA Field is empty!!"); nack_send(uniqueSockID, send_call); return; } data = (u_char *) malloc(datalen); PRINT_DEBUG(""); memcpy(data, pt, datalen); pt += datalen; PRINT_DEBUG(""); flags = *(int *) pt; pt += sizeof(int); if (pt - buf != len) { PRINT_DEBUG("READING ERROR! CRASH, diff=%d len=%d", pt - buf, len); nack_send(uniqueSockID, send_call); return; } PRINT_DEBUG(""); index = findjinniSocket(uniqueSockID); if (index == -1) { PRINT_DEBUG( "CRASH !!! socket descriptor not found into jinni sockets SO pipe descriptor to reply is notfound too "); nack_send(uniqueSockID, send_call); return; } PRINT_DEBUG(""); if (jinniSockets[index].connection_status <= 0) { PRINT_DEBUG("Socket is not connected to any destination !!!"); nack_send(uniqueSockID, send_call); } if (jinniSockets[index].type == SOCK_DGRAM) send_udp(uniqueSockID, send_call, datalen, data, flags); else if (jinniSockets[index].type == SOCK_STREAM) send_tcp(uniqueSockID, send_call, datalen, data, flags); else { PRINT_DEBUG("unknown socket type has been read !!!"); nack_send(uniqueSockID, send_call); } PRINT_DEBUG(); return; } //end of send_call_handler()
void bind_call_handler(unsigned long long uniqueSockID, int threads, unsigned char *buf, ssize_t len) { int index; socklen_t addrlen; struct sockaddr_in *addr; u_char *pt; int reuseaddr; pt = buf; addrlen = *(int *) pt; pt += sizeof(int); if (addrlen <= 0) { PRINT_DEBUG("READING ERROR! CRASH, addrlen=%d", addrlen); nack_send(uniqueSockID, bind_call); return; } else { PRINT_DEBUG("addrlen=%d", addrlen); } addr = (struct sockaddr_in *) malloc(addrlen); memcpy(addr, pt, addrlen); pt += addrlen; reuseaddr = *(int *) pt; pt += sizeof(int); if (pt - buf != len) { PRINT_DEBUG("READING ERROR! CRASH, diff=%d len=%d", pt - buf, len); nack_send(uniqueSockID, bind_call); return; } PRINT_DEBUG("%d,%d,%d", (addr->sin_addr).s_addr, ntohs(addr->sin_port), addr->sin_family); index = findjinniSocket(uniqueSockID); /** if that requested socket does not exist !! * this means we can not even talk to the requester FINS crash as a response!! */ if (index == -1) { PRINT_DEBUG( " CRASH !socket descriptor not found into jinni sockets! Bind failed on Jinni Side "); nack_send(uniqueSockID, bind_call); return; } jinniSockets[index].sockopts.FSO_REUSEADDR |= reuseaddr; //TODO: when sockopts fully impelmented just set to '=' if (jinniSockets[index].type == SOCK_DGRAM) bind_udp(uniqueSockID, addr); else if (jinniSockets[index].type == SOCK_STREAM) bind_tcp(uniqueSockID, addr); else PRINT_DEBUG("unknown socket type has been read !!!"); return; } //end of bind_call_handler()
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 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 bind_udp(int sender,int sockfd,struct sockaddr *addr) { uint16_t hostport; uint16_t dstport; uint32_t host_IP_netformat; uint32_t dst_IP_netformat; int index; struct sockaddr_in *address; address = (struct sockaddr_in *) addr; /** TODO lock access to the jinnisockets */ index = findjinniSocket(sender,sockfd); /** TODO unlock access to the jinnisockets */ if (index == -1) { PRINT_DEBUG("socket descriptor not found into jinni sockets"); exit(1); } if (address->sin_family != AF_INET ) { PRINT_DEBUG("Wrong address family"); sem_wait(jinniSockets[index].s); nack_write(jinniSockets[index].jinniside_pipe_ds,sender,sockfd); sem_post(jinniSockets[index].as); sem_post(jinniSockets[index].s); } /**TODO lock the jinni sockets */ if (index == -1) { PRINT_DEBUG("socket descriptor not found into jinni sockets"); exit(1); } /** 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(address->sin_port); host_IP_netformat = (address->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) == -1) { PRINT_DEBUG("this port is not free"); sem_wait(jinniSockets[index].s); nack_write(jinniSockets[index].jinniside_pipe_ds,sender,sockfd); sem_post(jinniSockets[index].as); sem_post(jinniSockets[index].s); 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(address->sin_port); /** TODO lock and unlock the protecting semaphores before making * any modiciations to the contents of the jinniSockets database */ PRINT_DEBUG("%d,%d,%d",(address->sin_addr).s_addr, ntohs(address->sin_port), address->sin_family); jinniSockets[index].hostport = ntohs(address->sin_port); jinniSockets[index].host_IP = (address->sin_addr).s_addr; /** 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 */ sem_wait(jinniSockets[index].s); ack_write(jinniSockets[index].jinniside_pipe_ds,sender,sockfd); sem_post(jinniSockets[index].as); sem_post(jinniSockets[index].s); 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 recv_udp(unsigned long long uniqueSockID, int datalen, int flags) { //u_char *buf= NULL; u_char buf[MAX_DATA_PER_UDP]; int buflen = 0; int index; int i; void *msg; u_char *pt; int msg_len; int ret_val; int blocking_flag; int multi_flag; blocking_flag = 1; multi_flag = 0; //for udp, if SOL_SOCKET/SO_REUSEADDR /** TODO handle flags cases */ switch (flags) { default: break; } index = findjinniSocket(uniqueSockID); if (index == -1) { PRINT_DEBUG("socket descriptor not found into jinni sockets"); return; } PRINT_DEBUG("index = %d", index); PRINT_DEBUG(); /** the meta-data parameters are all passed by copy starting from this point * */ /** passing 0 as value for symbol, and NULL as an address * this the difference between the call from here, and the call in case of * the function recvfrom_udp * */ if (UDPreadFrom_fins(uniqueSockID, buf, &buflen, 0, NULL, blocking_flag, multi_flag) == 1) { buf[buflen] = '\0'; //may be specific to symbol==0 PRINT_DEBUG("%d", buflen); PRINT_DEBUG("%s", buf); msg_len = sizeof(u_int) + sizeof(unsigned long long) + sizeof(int) + buflen; msg = malloc(msg_len); pt = msg; *(u_int *) pt = recv_call; pt += sizeof(u_int); *(unsigned long long *) pt = uniqueSockID; pt += sizeof(unsigned long long); *(int *) pt = ACK; pt += sizeof(int); *(int *) pt = buflen; pt += sizeof(int); memcpy(pt, buf, buflen); pt += buflen; if (pt - (u_char *) msg != msg_len) { PRINT_DEBUG("write error: diff=%d len=%d\n", pt - (u_char *) msg, msg_len); free(msg); nack_send(uniqueSockID, recv_call); return; } PRINT_DEBUG("msg_len=%d msg=%s", msg_len, (char *) msg); ret_val = send_wedge(nl_sockfd, msg, msg_len, 0); free(msg); if (ret_val) { nack_send(uniqueSockID, recv_call); } PRINT_DEBUG(); // free(buf); PRINT_DEBUG(); } else { PRINT_DEBUG("socketjinni failed to accomplish recv_udp"); nack_send(uniqueSockID, recv_call); } PRINT_DEBUG(); /** TODO find a way to release these buffers later * using free here causing a segmentation fault */ //free(address); //free(buf); } // end of recv_udp
/** * @function recvfrom_udp * @param symbol tells if an address has been passed from the application to get the sender address or not * Note this method is coded to be thread safe since UDPreadFrom_fins mimics blocking and needs to be threaded. * */ void recvfrom_udp(void *threadData) { /** symbol parameter is the one to tell if an address has been passed from the * application to get the sender address or not */ u_char *buf = NULL; //u_char buf[MAX_DATA_PER_UDP]; u_char *bufptr; struct sockaddr_in *addr; int buflen = 0; int index; int i; int blocking_flag; int multi_flag; void *msg; u_char *pt; int msg_len; int ret_val; struct recvfrom_data *thread_data; thread_data = (struct recvfrom_data *) threadData; unsigned long long uniqueSockID = thread_data->uniqueSockID; int socketCallType = thread_data->socketCallType; int datalen = thread_data->datalen; int flags = thread_data->flags; int symbol = thread_data->symbol; PRINT_DEBUG("Entered recv thread=%d", thread_data->id); sem_wait(&jinniSockets_sem); index = findjinniSocket(uniqueSockID); if (index == -1) { PRINT_DEBUG("socket descriptor not found into jinni sockets"); sem_post(&jinniSockets_sem); recvthread_exit(thread_data); } PRINT_DEBUG("index = %d", index); blocking_flag = jinniSockets[index].blockingFlag; multi_flag = 0; //for udp, if SOL_SOCKET/SO_REUSEADDR sem_post(&jinniSockets_sem); if (symbol == 1) addr = (struct sockaddr_in *) malloc(sizeof(struct sockaddr_in)); else addr = NULL; /** TODO handle flags cases */ switch (flags) { default: break; } /** the meta-data parameters are all passed by copy starting from this point * */ buf = (u_char *) malloc(MAX_DATA_PER_UDP + 1); bufptr = buf; if (UDPreadFrom_fins(uniqueSockID, bufptr, &buflen, symbol, addr, blocking_flag, multi_flag) == 1) { PRINT_DEBUG("after UDPreadFrom_fins uniqID=%llu ind=%d", uniqueSockID, index); buf[buflen] = '\0'; //may be specific to symbol==0 PRINT_DEBUG("buflen=%d", buflen); for (i = 0; i < buflen; i++) { PRINT_DEBUG("%d", buf[i]); } PRINT_DEBUG("buf=%s", buf); msg_len = 4 * sizeof(int) + sizeof(unsigned long long) + buflen + (symbol ? sizeof(struct sockaddr_in) : 0); msg = malloc(msg_len); pt = msg; *(int *) pt = socketCallType; pt += sizeof(int); *(unsigned long long *) pt = uniqueSockID; pt += sizeof(unsigned long long); *(int *) pt = ACK; pt += sizeof(int); if (symbol) { *(int *) pt = sizeof(struct sockaddr_in); pt += sizeof(int); memcpy(pt, addr, sizeof(struct sockaddr_in)); pt += sizeof(struct sockaddr_in); //####### PRINT_DEBUG("address: %d/%d", (addr->sin_addr).s_addr, ntohs( addr->sin_port)); //####### } *(int *) pt = buflen; pt += sizeof(int); memcpy(pt, buf, buflen); pt += buflen; if (pt - (u_char *) msg != msg_len) { PRINT_DEBUG("write error: diff=%d len=%d\n", pt - (u_char *) msg, msg_len); free(msg); free(buf); if (addr) free(addr); nack_send(uniqueSockID, socketCallType); recvthread_exit(thread_data); } PRINT_DEBUG("msg_len=%d msg=%s", msg_len, (char *) msg); ret_val = send_wedge(nl_sockfd, msg, msg_len, 0); free(msg); if (ret_val) { nack_send(uniqueSockID, socketCallType); } PRINT_DEBUG(); } else { PRINT_DEBUG("socketjinni failed to accomplish recvfrom"); nack_send(uniqueSockID, socketCallType); } PRINT_DEBUG(); if (addr) free(addr); free(buf); recvthread_exit(thread_data); }
void sendmsg_call_handler(unsigned long long uniqueSockID, int threads, unsigned char *buf, ssize_t len) { int index; int datalen; int flags; int msg_flags; int symbol; int controlFlag = 0; u_char *data; socklen_t addrlen; void *msg_control; int msg_controlLength; struct sockaddr_in *addr; u_char *pt; PRINT_DEBUG(""); pt = buf; flags = *(int *) pt; pt += sizeof(int); symbol = *(int *) pt; pt += sizeof(int); if (symbol) { addrlen = *(u_int *) pt; pt += sizeof(u_int); addr = (struct sockaddr_in *) malloc(addrlen); memcpy(addr, pt, addrlen); pt += addrlen; PRINT_DEBUG("addr=%s/%d", inet_ntoa(addr->sin_addr), addr->sin_port); } msg_flags = *(int *) pt; pt += sizeof(int); controlFlag = *(int *) pt; pt += sizeof(int); if (controlFlag) { msg_controlLength = *(u_int *) pt; pt += sizeof(u_int); msg_control = malloc(msg_controlLength); memcpy(msg_control, pt, msg_controlLength); pt += msg_controlLength; } datalen = *(u_int *) pt; pt += sizeof(u_int); if (datalen <= 0) { PRINT_DEBUG("DATA Field is empty!!"); nack_send(uniqueSockID, sendmsg_call); return; } data = (u_char *) malloc(datalen); PRINT_DEBUG(""); memcpy(data, pt, datalen); pt += datalen; if (pt - buf != len) { PRINT_DEBUG("READING ERROR! CRASH, diff=%d len=%d", pt - buf, len); nack_send(uniqueSockID, sendmsg_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 notfound too "); nack_send(uniqueSockID, sendmsg_call); return; } PRINT_DEBUG(""); /** * In case of connected sockets */ if (jinniSockets[index].connection_status > 0) { if (jinniSockets[index].type == SOCK_DGRAM) send_udp(uniqueSockID, sendmsg_call, datalen, data, flags); else if (jinniSockets[index].type == SOCK_STREAM) send_tcp(uniqueSockID, sendmsg_call, datalen, data, flags); else if ((jinniSockets[index].type == SOCK_RAW) && (jinniSockets[index].protocol == IPPROTO_ICMP)) { } else { PRINT_DEBUG("unknown socket type has been read !!!"); nack_send(uniqueSockID, sendmsg_call); } } else { /** * In case of NON-connected sockets, WE USE THE ADDRESS GIVEN BY the APPlication * Process. Check if an address has been passed or not is required */ if (symbol) { // check that the passed address is not NULL if (jinniSockets[index].type == SOCK_DGRAM) sendto_udp(uniqueSockID, sendmsg_call, datalen, data, flags, addr, addrlen); else if (jinniSockets[index].type == SOCK_STREAM) sendto_tcp(uniqueSockID, sendmsg_call, datalen, data, flags, addr, addrlen); else if ((jinniSockets[index].type == SOCK_RAW) && (jinniSockets[index].protocol == IPPROTO_ICMP)) { sendto_icmp(uniqueSockID, sendmsg_call, datalen, data, flags, addr, addrlen); } else { PRINT_DEBUG("unknown target address !!!"); nack_send(uniqueSockID, sendmsg_call); } } else { PRINT_DEBUG("unknown target address !!!"); nack_send(uniqueSockID, sendmsg_call); } } PRINT_DEBUG(); return; }
void recvfrom_udp(int senderid,int sockfd,int datalen,int flags, int symbol ) { //u_char *buf= NULL; u_char buf[MAX_DATA_PER_UDP]; int buflen=0; int index; int i; struct sockaddr_in *address = (struct sockaddr_in *)malloc (sizeof(struct sockaddr_in)); int blocking_flag; blocking_flag = 1; /** TODO handle flags cases */ switch (flags) { default: break; } /** TODO lock access to the jinnisockets */ index = findjinniSocket(senderid,sockfd); /** TODO unlock access to the jinnisockets */ if (index == -1) { PRINT_DEBUG("socket descriptor not found into jinni sockets"); exit(1); } PRINT_DEBUG("index = %d",index); PRINT_DEBUG(); /** the meta-data parameters are all passed by copy starting from this point * */ if ( readFrom_fins(senderid,sockfd,&buf,&buflen,symbol,address,blocking_flag)== 1) { if (symbol == 0) { sem_wait(jinniSockets[index].s); ack_write(jinniSockets[index].jinniside_pipe_ds,senderid,sockfd); buf[buflen] = '\0'; PRINT_DEBUG("%d",buflen ); PRINT_DEBUG("%s",buf); write(jinniSockets[index].jinniside_pipe_ds,&buflen,sizeof(int)); write(jinniSockets[index].jinniside_pipe_ds,buf,buflen); sem_post(jinniSockets[index].as); sem_post(jinniSockets[index].s); PRINT_DEBUG(); // free(buf); PRINT_DEBUG(); } else if (symbol == 1 ) { sem_wait(jinniSockets[index].s); ack_write(jinniSockets[index].jinniside_pipe_ds,senderid,sockfd); PRINT_DEBUG(); write(jinniSockets[index].jinniside_pipe_ds,address,sizeof(struct sockaddr_in)); write(jinniSockets[index].jinniside_pipe_ds,&buflen,sizeof(int)); write(jinniSockets[index].jinniside_pipe_ds,buf,buflen); sem_post(jinniSockets[index].as); sem_post(jinniSockets[index].s); } else { } } else { PRINT_DEBUG("socketjinni failed to accomplish recvfrom"); sem_wait(jinniSockets[index].s); nack_write(jinniSockets[index].jinniside_pipe_ds,senderid,sockfd); sem_post(jinniSockets[index].as); sem_post(jinniSockets[index].s); } PRINT_DEBUG(); /** TODO find a way to release these buffers later * using free here causing a segmentation fault */ //free(address); //free(buf); return; }
int UDPreadFrom_fins(unsigned long long uniqueSockID, u_char *buf, int *buflen, int symbol, struct sockaddr_in *address, int block_flag, int multi_flag) { /**TODO MUST BE FIXED LATER * force symbol to become zero */ //symbol = 0; struct finsFrame *ff = NULL; struct finsFrame *ff_copy = NULL; int index; uint16_t srcport; uint32_t srcip; struct sockaddr_in * addr_in = (struct sockaddr_in *) address; int i; sem_wait(&jinniSockets_sem); index = findjinniSocket(uniqueSockID); sem_post(&jinniSockets_sem); PRINT_DEBUG("index = %d", index); /** * It keeps looping as a bad method to implement the blocking feature * of recvfrom. In case it is not blocking then the while loop should * be replaced with only a single trial ! * TODO Replace the dataqueue with a pipeline (file) this will make it easier * to emulate the file characteristics of the socket such as blocking and non-blocking * */ PRINT_DEBUG(); if (block_flag == 1) { PRINT_DEBUG(); int value; sem_getvalue(&(jinniSockets[index].Qs), &value); PRINT_DEBUG("uniqID=%llu sem: ind=%d, val=%d", uniqueSockID, index, value); PRINT_DEBUG("block=%d, multi=%d, threads=%d", block_flag, multi_flag, jinniSockets[index].threads); do { sem_wait(&jinniSockets_sem); if (jinniSockets[index].uniqueSockID != uniqueSockID) { PRINT_DEBUG("Socket closed, canceling read block."); sem_post(&jinniSockets_sem); return (0); } sem_wait(&(jinniSockets[index].Qs)); // PRINT_DEBUG(); ff = read_queue(jinniSockets[index].dataQueue); // ff = get_fake_frame(); // PRINT_DEBUG(); if (ff && multi_flag) { PRINT_DEBUG("index=%d threads=%d replies=%d", index, jinniSockets[index].threads, jinniSockets[index].replies); if (jinniSockets[index].replies) { jinniSockets[index].replies--; } else { jinniSockets[index].replies = jinniSockets[index].threads - 1; for (i = 0; i < jinniSockets[index].replies; i++) { PRINT_DEBUG("adding frame copy, threads=%d", jinniSockets[index].threads); ff_copy = (struct finsFrame *) malloc( sizeof(struct finsFrame)); cpy_fins_to_fins(ff_copy, ff); //copies pointers, freeFinsFrame doesn't free pointers if (!write_queue_front(ff_copy, jinniSockets[index].dataQueue)) { ; //error } } } } sem_post(&(jinniSockets[index].Qs)); sem_post(&jinniSockets_sem); } while (ff == NULL); PRINT_DEBUG(); } else { PRINT_DEBUG(); sem_wait(&jinniSockets_sem); if (jinniSockets[index].uniqueSockID != uniqueSockID) { PRINT_DEBUG("Socket closed, canceling read block."); sem_post(&jinniSockets_sem); return (0); } sem_wait(&(jinniSockets[index].Qs)); //ff= read_queue(jinniSockets[index].dataQueue); /** ff = get_fake_frame(); print_finsFrame(ff); */ ff = read_queue(jinniSockets[index].dataQueue); if (ff && multi_flag) { PRINT_DEBUG("index=%d threads=%d replies=%d", index, jinniSockets[index].threads, jinniSockets[index].replies); if (jinniSockets[index].replies) { jinniSockets[index].replies--; } else { jinniSockets[index].replies = jinniSockets[index].threads - 1; for (i = 0; i < jinniSockets[index].replies; i++) { PRINT_DEBUG("adding frame copy, threads=%d", jinniSockets[index].threads); ff_copy = (struct finsFrame *) malloc( sizeof(struct finsFrame)); cpy_fins_to_fins(ff_copy, ff); //copies pointers, freeFinsFrame doesn't free pointers if (!write_queue_front(ff_copy, jinniSockets[index].dataQueue)) { ; //error } } } } sem_post(&(jinniSockets[index].Qs)); sem_post(&jinniSockets_sem); } if (ff == NULL) { //free(ff); return (0); } PRINT_DEBUG("recv'd uniqID=%llu ind=%d", uniqueSockID, index); PRINT_DEBUG("PDU length %d", ff->dataFrame.pduLength); if (metadata_readFromElement(ff->dataFrame.metaData, "portsrc", (uint16_t *) &srcport) == 0) { addr_in->sin_port = 0; } if (metadata_readFromElement(ff->dataFrame.metaData, "ipsrc", (uint32_t *) &srcip) == 0) { addr_in->sin_addr.s_addr = 0; } /** * making sure that the datagram coming from the destination we are connected to it * in case of connection previously done */ sem_wait(&jinniSockets_sem); if (jinniSockets[index].uniqueSockID != uniqueSockID) { PRINT_DEBUG("Socket closed, canceling read block."); sem_post(&jinniSockets_sem); return (0); } PRINT_DEBUG("Rest of read for index=%d.", index); if (jinniSockets[index].connection_status > 0) { if ((srcport != jinniSockets[index].dstport) || (srcip != jinniSockets[index].dst_IP)) { PRINT_DEBUG( "Wrong address, the socket is already connected to another destination"); sem_post(&jinniSockets_sem); return (0); } } sem_post(&jinniSockets_sem); //*buf = (u_char *)malloc(sizeof(ff->dataFrame.pduLength)); //memcpy(*buf,ff->dataFrame.pdu,ff->dataFrame.pduLength); memcpy(buf, ff->dataFrame.pdu, ff->dataFrame.pduLength); *buflen = ff->dataFrame.pduLength; PRINT_DEBUG(); if (symbol == 0) { // address = NULL; PRINT_DEBUG(); // freeFinsFrame(ff); return (1); } PRINT_DEBUG(); addr_in->sin_port = srcport; addr_in->sin_addr.s_addr = srcip; /**TODO Free the finsFrame * This is the final consumer * call finsFrame_free(Struct finsFrame** ff) */ PRINT_DEBUG(); //freeFinsFrame(ff); /** Finally succeeded * */ return (1); } //end of readFrom_fins
void sendto_udp(int senderid,int sockfd,int datalen,u_char *data,int flags, struct sockaddr *addr,socklen_t addrlen) { uint16_t hostport; uint16_t dstport; uint32_t host_IP; uint32_t dst_IP; int len=datalen; int index; /** check if the original call is either (sendto) or (send) or (write)*/ if ( (addr == NULL) && (addrlen == 0) && (flags != -1000) ) { /** In case of (send) */ PRINT_DEBUG(); return ( send_udp(senderid,sockfd,datalen,data,flags) ) ; } if ( (addr == NULL) && (addrlen == 0) && (flags == -1000)) { PRINT_DEBUG(); /** In case of (write) */ return ( write_udp (senderid,sockfd,datalen,data) ) ; } 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(""); struct sockaddr_in *address; address = (struct sockaddr_in *) addr; /** TODO lock access to the jinnisockets */ index = findjinniSocket(senderid,sockfd); PRINT_DEBUG(""); /** TODO unlock access to the jinnisockets */ if (index == -1) { PRINT_DEBUG("CRASH !! socket descriptor not found into jinni sockets"); exit(1); } if (address->sin_family != AF_INET ) { PRINT_DEBUG("Wrong address family"); PRINT_DEBUG(""); sem_wait(jinniSockets[index].s); PRINT_DEBUG(""); nack_write(jinniSockets[index].jinniside_pipe_ds,senderid,sockfd); sem_post(jinniSockets[index].as); sem_post(jinniSockets[index].s); PRINT_DEBUG(""); } /** 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(""); /** Keep all ports and addresses in host order until later action taken */ dstport =ntohs( address->sin_port); /** reverse it since it is in network order after application used htons */ if (dst_IP != INADDR_LOOPBACK) dst_IP = ntohl(address-> sin_addr.s_addr);/** it is in network format since application used htonl */ else dst_IP = ntohl(address-> sin_addr.s_addr); //hostport = jinniSockets[index].hostport; hostport = 3000; host_IP = jinniSockets[index].host_IP; PRINT_DEBUG(""); PRINT_DEBUG("%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 */ sem_wait(jinniSockets[index].s); PRINT_DEBUG(""); ack_write(jinniSockets[index].jinniside_pipe_ds,senderid,sockfd); sem_post(jinniSockets[index].as); sem_post(jinniSockets[index].s); PRINT_DEBUG(""); } else { PRINT_DEBUG("socketjinni failed to accomplish sendto"); sem_wait(jinniSockets[index].s); nack_write(jinniSockets[index].jinniside_pipe_ds,senderid,sockfd); sem_post(jinniSockets[index].as); sem_post(jinniSockets[index].s); } return; } //end of sendto_udp
void getpeername_call_handler(unsigned long long uniqueSockID, int threads, unsigned char *buf, ssize_t len) { int index; socklen_t addrlen; struct sockaddr_in *addr; void *msg; u_char *pt; int msg_len; int ret_val; addrlen = sizeof(struct sockaddr_in); addr = (struct sockaddr_in *) malloc(addrlen); index = findjinniSocket(uniqueSockID); /** if that requested socket does not exist !! * this means we can not even talk to the requester FINS crash as a response!! */ if (index == -1) { PRINT_DEBUG( " CRASH !socket descriptor not found into jinni sockets! Bind failed on Jinni Side "); nack_send(uniqueSockID, getpeername_call); return; } PRINT_DEBUG("getpeername_handler called"); //memset( addr, 0,addrlen); addr->sin_family = AF_INET; addr->sin_addr.s_addr = ntohl(jinniSockets[index].dst_IP); addr->sin_port = jinniSockets[index].dstport; PRINT_DEBUG("%d , %d", jinniSockets[index].dst_IP, jinniSockets[index].dstport); msg_len = sizeof(u_int) + sizeof(unsigned long long) + sizeof(int) + addrlen; msg = malloc(msg_len); pt = msg; *(u_int *) pt = getpeername_call; pt += sizeof(u_int); *(unsigned long long *) pt = uniqueSockID; pt += sizeof(unsigned long long); *(int *) pt = ACK; pt += sizeof(int); *(int *) pt = addrlen; pt += sizeof(int); memcpy(pt, addr, addrlen); pt += addrlen; if (pt - (u_char *) msg != msg_len) { PRINT_DEBUG("write error: diff=%d len=%d\n", pt - (u_char *) msg, msg_len); free(msg); nack_send(uniqueSockID, getpeername_call); return; } PRINT_DEBUG("msg_len=%d msg=%s", msg_len, (char *) msg); ret_val = send_wedge(nl_sockfd, msg, msg_len, 0); free(msg); PRINT_DEBUG("getpeername DONE"); return; }
int readFrom_fins(int senderid,int sockfd,u_char **buf,int *buflen,int symbol,struct sockaddr_in *address, int block_flag) { /**TODO MUST BE FIXED LATER * force symbol to become zero */ symbol = 0; struct finsFrame *ff=NULL; int index; uint16_t srcport; uint32_t srcip; struct sockaddr_in * addr_in= (struct sockaddr_in * )address; index = findjinniSocket(senderid,sockfd); PRINT_DEBUG("index = %d",index); /** * It keeps looping as a bad method to implement the blocking feature * of recvfrom. In case it is not blocking then the while loop should * be replaced with only a single trial ! * */ PRINT_DEBUG(); if (block_flag == 1) { PRINT_DEBUG(); do { sem_wait(&(jinniSockets[index].Qs)); // PRINT_DEBUG(); ff= read_queue(jinniSockets[index].dataQueue); // ff = get_fake_frame(); // PRINT_DEBUG(); sem_post(&(jinniSockets[index].Qs)); } while(ff == NULL); PRINT_DEBUG(); } else { PRINT_DEBUG(); sem_wait(&(jinniSockets[index].Qs)); //ff= read_queue(jinniSockets[index].dataQueue); /** ff = get_fake_frame(); print_finsFrame(ff); */ ff= read_queue(jinniSockets[index].dataQueue); sem_post(&(jinniSockets[index].Qs)); } if (ff == NULL) { //free(ff); return(0); } PRINT_DEBUG("PDU lenght %d",ff->dataFrame.pduLength); //*buf = (u_char *)malloc(sizeof(ff->dataFrame.pduLength)); //memcpy(*buf,ff->dataFrame.pdu,ff->dataFrame.pduLength); memcpy(buf,ff->dataFrame.pdu,ff->dataFrame.pduLength); *buflen = ff->dataFrame.pduLength; PRINT_DEBUG(); if (symbol == 0) { // address = NULL; PRINT_DEBUG(); // freeFinsFrame(ff); return (1); } PRINT_DEBUG(); if (metadata_readFromElement(ff->dataFrame.metaData,"hostport",&srcport) == 0 ) { address->sin_port = 0; return (1); } if (metadata_readFromElement(ff->dataFrame.metaData,"hostip",&srcip) == 0 ) { address->sin_addr.s_addr =0; return (1); } addr_in->sin_port = srcport; addr_in->sin_addr.s_addr = srcip; /**TODO Free the finsFrame * This is the final consumer * call finsFrame_free(Struct finsFrame** ff) */ PRINT_DEBUG(); //freeFinsFrame(ff); /** Finally succeeded * */ return(1); } //end of readFrom_fins
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; }