void icmp_get_FF(struct finsFrame *ff) { do { sem_wait (&Switch_to_ICMP_Qsem); ff = read_queue(Switch_to_ICMP_Queue); sem_post (&Switch_to_ICMP_Qsem); } while (ff == NULL); if(ff->dataOrCtrl == CONTROL){ // send to something to deal with FCF PRINT_DEBUG("send to CONTROL HANDLER !"); } if( (ff->dataOrCtrl == DATA) && ( (ff->dataFrame).directionFlag == UP) ) { icmp_in(ff); } if( (ff->dataOrCtrl == DATA) && ( (ff->dataFrame).directionFlag == DOWN)) { icmp_out(ff); } }
int main(int argc, char const *argv[]) { printf("----- Server running.. -----\n"); unlink_queue("/mta"); unlink_queue("/mailbox1"); unlink_queue("/mailbox2"); //We create a queue for MTA input mqd_t input = init_queue("/mta", O_CREAT | O_RDONLY); //and two more for writing to clients mqd_t client1 = init_queue("/mailbox1", O_CREAT | O_WRONLY); mqd_t client2 = init_queue("/mailbox2", O_CREAT | O_WRONLY); //loop msg message; while(1) { printf("Waiting for messages..\n"); message = read_queue(input); printf("Transmitting message \"%s\" from: %i to: %i\n", message.data, message.from, message.to); if(message.to == 1) { printf("Sending message to client1\n"); write_queue(client1, message); } if(message.to == 2){ printf("Sending message to client2\n"); write_queue(client2, message); } } return 0; }
// }}} // {{{ int main(int argc, char **argv) int main(int argc, char **argv) { ffqueued_init(); while(1) { read_queue(); update_progress(); check_exits(); sleep(10); } }
void rtm_get_ff(struct fins_module *module) { struct rtm_data *md = (struct rtm_data *) module->data; struct finsFrame *ff; do { secure_sem_wait(module->event_sem); secure_sem_wait(module->input_sem); ff = read_queue(module->input_queue); sem_post(module->input_sem); } while (module->state == FMS_RUNNING && ff == NULL && !md->interrupt_flag); //TODO change logic here, combine with switch_to_rtm? if (module->state != FMS_RUNNING) { if (ff != NULL) { freeFinsFrame(ff); } return; } if (ff != NULL) { if (ff->metaData == NULL) { PRINT_ERROR("Error fcf.metadata==NULL"); exit(-1); } if (ff->dataOrCtrl == FF_CONTROL) { rtm_fcf(module, ff); PRINT_DEBUG(""); } else if (ff->dataOrCtrl == FF_DATA) { if (ff->dataFrame.directionFlag == DIR_UP) { //rtm_in_fdf(module, ff); PRINT_WARN("todo error"); freeFinsFrame(ff); } else if (ff->dataFrame.directionFlag == DIR_DOWN) { //rtm_out_fdf(module, ff); PRINT_WARN("todo error"); freeFinsFrame(ff); } else { PRINT_ERROR("todo error"); exit(-1); } } else { PRINT_ERROR("todo error"); exit(-1); } } else if (md->interrupt_flag) { md->interrupt_flag = 0; rtm_interrupt(module); //TODO unused, implement or remove } else { PRINT_ERROR("todo error: dataOrCtrl=%u", ff->dataOrCtrl); exit(-1); } }
/**@brief from the (any) module to switch queue a fins frame is read into the * switch. Note that the function init_switch() is needed to initialize the switch, the queues and the semaphores which * control access to these queues. This function reads from the queue as pointed to by the input parameter and sends * a fins frame in response via the fins_switch_out. * @param module_to_switch_bff is the pointer to the queue from (any) module into the switch */ void fins_switch_in(struct queue *module_to_switch_bff){ struct finsFrame fins_in, fins_out; struct destinationList *dstPtr; struct tableRecord *searched_table_ptr; sem_wait(&(module_to_switch_bff->locked));/**lock the queue being read from*/ read_queue(&fins_in, module_to_switch_bff); sem_post(&(module_to_switch_bff->locked));/**lock the queue being read from*/ if (fins_in.dataOrCtrl == CONTROL) //control type fins Frame { if (fins_in.ctrlFrame.opcode == QUERYREQUEST) //if this is a query request generate a query reply { searched_table_ptr = switch_search_query(&(fins_in)); //carries the request fins frame gen_query_reply(&fins_out, &fins_in, searched_table_ptr); print_records(searched_table_ptr); //pointer to linked list of found elements from the table } //for all other opcodes simply copy the frame and send out else if ((fins_in.ctrlFrame.opcode == READREQUEST) &&(fins_in.ctrlFrame.opcode == READREPLY) && (fins_in.ctrlFrame.opcode == WRITEREQUEST) && (fins_in.ctrlFrame.opcode == WRITECONF)) memcpy(&fins_out, &fins_in, sizeof(struct finsFrame)); fins_switch_out(&fins_out); } else if (fins_in.dataOrCtrl == DATA) //data type fins Frame { /**@check the destination ID and send the frame to the module with this ID*/ dstPtr = &(fins_in.destinationID); /**@ The received FINS frame is duplicated and send to each of the modules (i.e. dest list). * However the destination list is pruned for the correct member for this purpose. * For example, if the list has three members each of the three modules will receive exactly * the same frame but without the original destination list (i.e. the destination ID will contain only the module's ID). * */ memcpy(&fins_out, &fins_in, sizeof(struct finsFrame)); while (dstPtr!=NULL){ fins_out.destinationID.id = dstPtr->id; fins_out.destinationID.next = NULL; dstPtr = dstPtr->next; fins_switch_out(&fins_out); //send to the queue for the given module as stored in dstPtr } } }
static void create_q_threads(gpointer key, gpointer value, gpointer user_data) { #ifdef USE_ST if (st_thread_create(read_queue, value, 0, 0) == NULL) { LOG(LOG_WARNING, "couldn't create queue thread for %s", (char *)key); } else { if (debug > 3) { LOG(LOG_DEBUG, "created new thread"); } thread_count++; } #else read_queue(value); #endif }
void internal_server::handle_process() { send_function send_fn; variant request; int session_id; if(read_queue(&send_fn, &request, &session_id)) { server_ptr->handle_message( send_fn, boost::bind(&internal_server::finish_socket, this, send_fn, _1), boost::bind(&internal_server::get_socket_info, server_ptr.get(), send_fn), session_id, request); } io_service_.poll(); io_service_.reset(); }
//Code to receive a finsFrame from the Switch void rtm_get_ff(void) { int numBytes = 0; struct finsFrame *ff; do { secure_sem_wait(&Switch_to_RTM_Qsem); ff = read_queue(Switch_to_RTM_Queue); sem_post(&Switch_to_RTM_Qsem); } while (ff == NULL); if (ff->dataOrCtrl == CONTROL) { //CONTROL FF // send to something to deal with FCF //format: || Data/Control | Destination_IDs_List | SenderID | Write_parameter_Confirmation_Code | Serial_Number || PRINT_DEBUG("send to CONTROL HANDLER !"); PRINT_DEBUG("dataOrCtrl parameter has been set to %d", (int)(ff->dataOrCtrl)); PRINT_DEBUG("destinationID parameter has been set to %d", (int)(ff->destinationID.id)); PRINT_DEBUG("opcode parameter has been set to %d", ff->ctrlFrame.opcode); PRINT_DEBUG("senderID parameter has been set to %d", (int)(ff->ctrlFrame.senderID)); //PRINT_DEBUG("serial_num parameter has been set to %d",ff->ctrlFrame.serial_num); //Currently it serializes and sends any Control Frame it receives over the rtm_out pipe rtm_out_fd = open(RTM_PIPE_OUT, O_RDWR); //should not be O_RDWR, should be WRITE ONLY //FOWARD CONFIRMATION FRAME TO CLICOMM //|| Data/Control | Destination_IDs_List | SenderID | Write_parameter_Confirmation_Code | Serial_Number || // reimplement with the new serialize function numBytes = 0; numBytes += write(rtm_out_fd, &ff->dataOrCtrl, sizeof(unsigned char)); numBytes += write(rtm_out_fd, &ff->destinationID.id, sizeof(unsigned char)); numBytes += write(rtm_out_fd, &ff->ctrlFrame.senderID, sizeof(unsigned char)); numBytes += write(rtm_out_fd, &ff->ctrlFrame.opcode, sizeof(unsigned short int)); numBytes += write(rtm_out_fd, &ff->ctrlFrame.serial_num, sizeof(unsigned int)); PRINT_DEBUG ("serial_num %d", ff->ctrlFrame.serial_num); } else //DATA FF { PRINT_DEBUG("Find out what to do with data frames"); } }
void ipv4_get_ff(struct fins_module *module) { struct finsFrame *ff; do { secure_sem_wait(module->event_sem); secure_sem_wait(module->input_sem); ff = read_queue(module->input_queue); sem_post(module->input_sem); } while (module->state == FMS_RUNNING && ff == NULL); //TODO change logic here, combine with switch_to_ipv4? if (module->state != FMS_RUNNING) { if (ff != NULL) { freeFinsFrame(ff); } return; } if (ff->metaData == NULL) { PRINT_ERROR("Error fcf.metadata==NULL"); exit(-1); } if (ff->dataOrCtrl == FF_CONTROL) { ipv4_fcf(module, ff); PRINT_DEBUG(""); } else if (ff->dataOrCtrl == FF_DATA) { if (ff->dataFrame.directionFlag == DIR_UP) { ipv4_in_fdf(module, ff); PRINT_DEBUG(""); } else if (ff->dataFrame.directionFlag == DIR_DOWN) { ipv4_out_fdf(module, ff); PRINT_DEBUG(""); } else { PRINT_ERROR("Error: Wrong value of fdf.directionFlag"); exit(-1); } } else { PRINT_ERROR("Error: Wrong ff->dataOrCtrl value"); exit(-1); } }
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 IP4_receive_fdf(void) { struct finsFrame* pff = NULL; uint32_t protocol; do { sem_wait(&Switch_to_IPv4_Qsem); pff = read_queue(Switch_to_IPv4_Queue); sem_post(&Switch_to_IPv4_Qsem); } while (ipv4_running && pff == NULL); if (!ipv4_running) { return; } if (pff->dataOrCtrl == CONTROL) { PRINT_DEBUG("Received frame: D/C: %d, DestID=%d, ff=%p, meta=%p", pff->dataOrCtrl, pff->destinationID.id, pff, pff->metaData); ipv4_fcf(pff); } else if (pff->dataOrCtrl == DATA) { PRINT_DEBUG("Received frame: D/C: %d, DestID=%d, ff=%p, meta=%p", pff->dataOrCtrl, pff->destinationID.id, pff, pff->metaData); PRINT_DEBUG("PDU Length: %d", pff->dataFrame.pduLength); PRINT_DEBUG("Data direction: %d", pff->dataFrame.directionFlag); PRINT_DEBUG("pdu=%p", pff->dataFrame.pdu); if (pff->dataFrame.directionFlag == UP) { PRINT_DEBUG("IP4_in"); IP4_in(pff, (struct ip4_packet*) pff->dataFrame.pdu, pff->dataFrame.pduLength); } else if (pff->dataFrame.directionFlag == DOWN) { PRINT_DEBUG("IP4_out"); metadata *params = pff->metaData; if (params == NULL) { PRINT_ERROR("todo error"); freeFinsFrame(pff); return; } int ret = 0; ret += metadata_readFromElement(params, "send_protocol", &protocol) == META_FALSE; if (ret) { PRINT_ERROR("metadata read error: ret=%d", ret); } PRINT_DEBUG("%lu", my_ip_addr); PRINT_DEBUG("Transport protocol going out passed to IPv4: protocol=%u", protocol); switch (protocol) { case IP4_PT_ICMP: IP4_out(pff, pff->dataFrame.pduLength, my_ip_addr, IP4_PT_ICMP); break; case IP4_PT_TCP: IP4_out(pff, pff->dataFrame.pduLength, my_ip_addr, IP4_PT_TCP); break; case IP4_PT_UDP: IP4_out(pff, pff->dataFrame.pduLength, my_ip_addr, IP4_PT_UDP); break; default: PRINT_ERROR("invalid protocol: protocol=%u", protocol); /** * TODO investigate why the freeFinsFrame below create segmentation fault */ freeFinsFrame(pff); break; } } else { PRINT_ERROR("Error: Wrong value of fdf.directionFlag"); freeFinsFrame(pff); } } else { PRINT_ERROR("Error: Wrong pff->dataOrCtrl value"); freeFinsFrame(pff); } }
int main(int argc, char **argv) { mqd_t actor4 = init_queue("/actor4", O_CREAT | O_RDONLY); message msgreceived; //printf("Waiting to receive something\n"); msgreceived = read_queue(actor4); //printf("I got something\n"); char order[34]; int me = 0; char content[256]; //int next; char nextq[7]; strcpy(order, msgreceived.order); strcpy(content, msgreceived.content); int i; for(i = 0; i<33; i++){ // printf("%c order\n", order[i]); if (order[i]=='4'){ if (i <=7){ //I am the first actor me = 1; //next = atoi(order[i+9]); strncpy(nextq, &order[i]+4, 7); nextq[6] = '\0'; }else if(i<=17){ //I am the second actor me = 2; strncpy(nextq, &order[i]+4, 7); nextq[6] = '\0'; }else if(i <= 26){ //I am the third actor me = 3; strncpy(nextq, &order[i]+4, 7); nextq[6] = '\0'; }else if (i <=34){ //I am the fourth actor me = 4; } } } //write message message msg; char text[256]; strcpy(text, msgreceived.content); printf("%s text\n", text); //text = strcat("TEXT " + var); strcpy(msg.order, order); if (me != 4){ if (me==1){ strcpy (msg.content, "[EscribiendoActor4-"); }else{ strcat(text,"EscribiendoActor4-"); strcpy(msg.content, text); } }else{ strcat(text, "EscribiendoActor4]"); strcpy(msg.content, text); } //We know the name of the following queue we have to send to char nextqueue[7]; sprintf(nextqueue, "/%s", nextq); mqd_t next; if (me!=4){ next = init_queue(nextqueue, O_WRONLY); }else{ printf("I'm opening to director\n"); next = init_queue("/director", O_WRONLY); } write_queue(next, msg); printf("I sent\n"); return 0; }
void *switch_loop(void *local) { struct fins_module *module = (struct fins_module *) local; PRINT_DEBUG("Entered: module=%p, index=%u, id=%u, name='%s'", module, module->index, module->id, module->name); struct switch_data *md = (struct switch_data *) module->data; uint32_t i; int ret; //int32_t val; struct finsFrame *ff; //uint8_t index; int counter = 0; while (module->state == FMS_RUNNING) { secure_sem_wait(module->event_sem); //TODO uncomment, for testing //secure_sem_wait(module->input_sem); secure_sem_wait(&md->overall->sem); for (i = 0; i < MAX_MODULES; i++) { if (md->overall->modules[i] != NULL) { //helgrind says is race condition, though there will always be FF when post to event_sem if (!IsEmpty(md->overall->modules[i]->output_queue)) { //added as optimization /* //can possibly cause switch to be "behind" ret = sem_getvalue(md->overall->modules[i]->output_sem, &val); if (ret) { PRINT_ERROR("sem get value prob: src module_index=%u, ret=%d", i, ret); exit(-1); } //*/ //if (val != 0) { while ((ret = sem_wait(md->overall->modules[i]->output_sem)) && errno == EINTR) ; if (ret != 0) { PRINT_ERROR("sem wait prob: src module_index=%u, ret=%d", i, ret); exit(-1); } ff = read_queue(md->overall->modules[i]->output_queue); sem_post(md->overall->modules[i]->output_sem); //if (ff != NULL) { //shouldn't occur counter++; //index = ff->destinationID; if (ff->destinationID < 0 || ff->destinationID > MAX_MODULES) { PRINT_ERROR("dropping ff: illegal destination: src module_index=%u, dst module_index=%u, ff=%p, meta=%p", i, ff->destinationID, ff, ff->metaData); //TODO if FCF set ret_val=0 & return? or free or just exit(-1)? freeFinsFrame(ff); } else { //if (i != id) //TODO add this? if (md->overall->modules[ff->destinationID] != NULL) { PRINT_DEBUG("Counter=%d, from='%s', to='%s', ff=%p, meta=%p", counter, md->overall->modules[i]->name, md->overall->modules[ff->destinationID]->name, ff, ff->metaData); //TODO decide if should drop all traffic to switch input queues, or use that as linking table requests if (ff->destinationID == module->index) { switch_process_ff(module, ff); } else { while ((ret = sem_wait(md->overall->modules[ff->destinationID]->input_sem)) && errno == EINTR) ; if (ret != 0) { PRINT_ERROR("sem wait prob: dst index=%u, ff=%p, meta=%p, ret=%d", ff->destinationID, ff, ff->metaData, ret); exit(-1); } if (write_queue(ff, md->overall->modules[ff->destinationID]->input_queue)) { sem_post(md->overall->modules[ff->destinationID]->event_sem); sem_post(md->overall->modules[ff->destinationID]->input_sem); } else { sem_post(md->overall->modules[ff->destinationID]->input_sem); PRINT_ERROR("Write queue error: dst index=%u, ff=%p, meta=%p", ff->destinationID, ff, ff->metaData); freeFinsFrame(ff); } } } else { PRINT_ERROR("dropping ff: destination not registered: src index=%u, dst index=%u, ff=%p, meta=%p", i, ff->destinationID, ff, ff->metaData); print_finsFrame(ff); //TODO if FCF set ret_val=0 & return? or free or just exit(-1)? freeFinsFrame(ff); } //} //} } } } } //sem_post(module->input_sem); sem_post(&md->overall->sem); } PRINT_DEBUG("Exited: module=%p, index=%u, id=%u, name='%s'", module, module->index, module->id, module->name); return NULL; }
void *switch_loop(void *local) { PRINT_DEBUG("Entered"); int i; struct finsFrame *ff; int counter = 0; while (switch_running) { /** the receiving Queues are only the even numbers * 0,2,4,6,8,10,12,14. This is why we increase the counter by 2 */ for (i = 0; i < MAX_modules; i = i + 2) { sem_wait(IO_queues_sem[i]); ff = read_queue(modules_IO_queues[i]); sem_post(IO_queues_sem[i]); if (ff != NULL) { counter++; //PRINT_DEBUG("Counter %d", counter); switch (ff->destinationID.id) { case ARP_ID: PRINT_DEBUG("Counter=%d, from='%s' to ARP Queue +1, ff=%p, meta=%p", counter, modules_IO_queues[i]->name, ff, ff->metaData); sem_wait(&Switch_to_ARP_Qsem); write_queue(ff, Switch_to_ARP_Queue); sem_post(&Switch_to_ARP_Qsem); break; case RTM_ID: PRINT_DEBUG("Counter=%d, from='%s' to RTM Queue +1, ff=%p, meta=%p", counter, modules_IO_queues[i]->name, ff, ff->metaData); sem_wait(&Switch_to_RTM_Qsem); write_queue(ff, Switch_to_RTM_Queue); sem_post(&Switch_to_RTM_Qsem); break; case DAEMON_ID: PRINT_DEBUG("Counter=%d, from='%s' to Daemon Queue +1, ff=%p, meta=%p", counter, modules_IO_queues[i]->name, ff, ff->metaData); sem_wait(&Switch_to_Daemon_Qsem); write_queue(ff, Switch_to_Daemon_Queue); sem_post(&Switch_to_Daemon_Qsem); break; case UDP_ID: PRINT_DEBUG("Counter=%d, from='%s' to UDP Queue +1, ff=%p, meta=%p", counter, modules_IO_queues[i]->name, ff, ff->metaData); sem_wait(&Switch_to_UDP_Qsem); write_queue(ff, Switch_to_UDP_Queue); sem_post(&Switch_to_UDP_Qsem); break; case TCP_ID: PRINT_DEBUG("Counter=%d, from='%s' to TCP Queue +1, ff=%p, meta=%p", counter, modules_IO_queues[i]->name, ff, ff->metaData); sem_wait(&Switch_to_TCP_Qsem); write_queue(ff, Switch_to_TCP_Queue); sem_post(&Switch_to_TCP_Qsem); break; case IPV4_ID: PRINT_DEBUG("Counter=%d, from='%s' to IPv4 Queue +1, ff=%p, meta=%p", counter, modules_IO_queues[i]->name, ff, ff->metaData); sem_wait(&Switch_to_IPv4_Qsem); write_queue(ff, Switch_to_IPv4_Queue); sem_post(&Switch_to_IPv4_Qsem); break; case INTERFACE_ID: PRINT_DEBUG("Counter=%d, from='%s' to Interface Queue +1, ff=%p, meta=%p", counter, modules_IO_queues[i]->name, ff, ff->metaData); sem_wait(&Switch_to_Interface_Qsem); write_queue(ff, Switch_to_Interface_Queue); sem_post(&Switch_to_Interface_Qsem); break; case ICMP_ID: PRINT_DEBUG("Counter=%d, from='%s' to ICMP Queue +1, ff=%p, meta=%p", counter, modules_IO_queues[i]->name, ff, ff->metaData); sem_wait(&Switch_to_ICMP_Qsem); write_queue(ff, Switch_to_ICMP_Queue); sem_post(&Switch_to_ICMP_Qsem); break; default: PRINT_DEBUG("Counter=%d, from='%s' to Unknown Dest, ff=%p, meta=%p", counter, modules_IO_queues[i]->name, ff, ff->metaData); freeFinsFrame(ff); break; } // end of Switch statement } // end of if (ff != NULL ) else { //PRINT_DEBUG("No frame read from Queue # %d", i); } } //end of for For loop (Round Robin reading from Modules) } // end of while loop PRINT_DEBUG("Exited"); pthread_exit(NULL); } // end of switch_init Function
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 init_switch() { PRINT_DEBUG("SWITCH Module started"); int i; struct finsFrame *ff = NULL; int protocol; int index; int status; uint16_t dstport, hostport; uint32_t dstip, hostip; int counter = 0; while (1) { /** the receiving Queues are only the even numbers * 0,2,4,6,8,10,12,14. This is why we increase the counter by 2 */ for (i = 0; i < MAX_modules; i = i + 2) { sem_wait(IO_queues_sem[i]); ff = read_queue(modules_IO_queues[i]); sem_post(IO_queues_sem[i]); if (ff != NULL) { counter++; PRINT_DEBUG("Counter %d", counter); switch (ff->destinationID.id) { case ARPID: { PRINT_DEBUG("ARP Queue +1"); sem_wait(&Switch_to_ARP_Qsem); write_queue(ff, Switch_to_ARP_Queue); sem_post(&Switch_to_ARP_Qsem); break; } case RTMID: { PRINT_DEBUG("RTM Queue +1"); sem_wait(&Switch_to_RTM_Qsem); write_queue(ff, Switch_to_RTM_Queue); sem_post(&Switch_to_RTM_Qsem); break; } case JINNIID: { PRINT_DEBUG("Jinni Queue +1"); sem_wait(&Switch_to_Jinni_Qsem); write_queue(ff, Switch_to_Jinni_Queue); sem_post(&Switch_to_Jinni_Qsem); break; } case UDPID: { PRINT_DEBUG("UDP Queue +1"); sem_wait(&Switch_to_UDP_Qsem); write_queue(ff, Switch_to_UDP_Queue); sem_post(&Switch_to_UDP_Qsem); break; } case TCPID: { PRINT_DEBUG("TCP Queue +1"); sem_wait(&Switch_to_TCP_Qsem); write_queue(ff, Switch_to_TCP_Queue); sem_post(&Switch_to_TCP_Qsem); break; } case IPV4ID: { PRINT_DEBUG("IP Queue +1"); sem_wait(&Switch_to_IPv4_Qsem); write_queue(ff, Switch_to_IPv4_Queue); sem_post(&Switch_to_IPv4_Qsem); break; } case ETHERSTUBID: { PRINT_DEBUG("EtherStub Queue +1"); sem_wait(&Switch_to_EtherStub_Qsem); write_queue(ff, Switch_to_EtherStub_Queue); sem_post(&Switch_to_EtherStub_Qsem); break; } case ICMPID: { PRINT_DEBUG("ICMP Queue +1"); sem_wait(&Switch_to_ICMP_Qsem); write_queue(ff, Switch_to_ICMP_Queue); sem_post(&Switch_to_ICMP_Qsem); break; } default: { PRINT_DEBUG("Unknown Destination"); // free(ff); break; } } // end of Switch statement } // end of if (ff != NULL ) else { //PRINT_DEBUG("No frame read from Queue # %d", i); } } //end of for For loop (Round Robin reading from Modules) } // end of while loop } // end of switch_init Function