static void forward_test_case(int case_num) { if ((debug == 2) || (debug == 3)) { if (case_num == 0) { char *user_input_name = DEFAULT_USER_INPUT_NAME; char *user_output_name = DEFAULT_USER_OUTPUT_NAME; if (access(DEFAULT_USER_INPUT_NAME, F_OK) != 0) { create_user_file(user_input_name); } debug_printf("create default user file (%s)\n", DEFAULT_USER_INPUT_NAME); inputfd = open(user_input_name, O_RDONLY); if (!inputfd) { error_printf("can't open file: %s\n", user_input_name); exit (EXIT_FAILURE); } if (access(DEFAULT_USER_OUTPUT_NAME, F_OK) != 0) { create_user_file(user_output_name); } debug_printf("create default user file (%s)\n", DEFAULT_USER_OUTPUT_NAME); outputfd = open(user_output_name, O_WRONLY); if (!outputfd) { error_printf("can't open file: %s\n", user_output_name); exit (EXIT_FAILURE); } } else if ((case_num == 1) && (debug == 2)) { debug_printf("Test case 1 => begin \n"); debug_printf("from input file: %s to ttyfd: %s\n", DEFAULT_USER_INPUT_NAME, tty_name); forward_message(inputfd, ttyfd); debug_printf("from ttyfd: %s to output file: %s\n", tty_name, DEFAULT_USER_OUTPUT_NAME); forward_message(ttyfd, outputfd); if (0 != close(inputfd)) error_printf("Note: couldn't close file: %s correctly\n", DEFAULT_USER_INPUT_NAME); if (0 != close(outputfd)) error_printf("Note: couldn't close file: %s correctly\n", DEFAULT_USER_OUTPUT_NAME); debug_printf("Test case 1 => end \n"); exit (EXIT_SUCCESS); } else if ((case_num == 2) && (debug == 3)) { int err = 0; debug_printf("Test case 2 => begin \n"); do { debug_printf("from input file: %s to socketfd: %d\n", DEFAULT_USER_INPUT_NAME, clientfd); err = forward_message(inputfd, clientfd); debug_printf("from socketfd: %d to output file: %s\n", clientfd, DEFAULT_USER_OUTPUT_NAME); err = forward_message(clientfd, outputfd); } while (err == READ_WRITE_OK); close(serverfd); close(clientfd); if (0 != close(inputfd)) error_printf("Note: couldn't close file: %s correctly\n", DEFAULT_USER_INPUT_NAME); if (0 != close(outputfd)) error_printf("Note: couldn't close file: %s correctly\n", DEFAULT_USER_OUTPUT_NAME); debug_printf("Test case 2 => end \n"); exit(EXIT_SUCCESS); } } }
int server_socket_poll() { struct socket_server *ss = SOCKET_SERVER; assert(ss); struct socket_message result; int more = 1; int type = socket_server_poll(ss, &result, &more); switch (type) { case SOCKET_EXIT: return 0; case SOCKET_DATA: forward_message(SERVER_SOCKET_TYPE_DATA, false, &result); break; case SOCKET_CLOSE: forward_message(SERVER_SOCKET_TYPE_CLOSE, false, &result); break; case SOCKET_OPEN: forward_message(SERVER_SOCKET_TYPE_CONNECT, true, &result); break; case SOCKET_ERROR: forward_message(SERVER_SOCKET_TYPE_ERROR, false, &result); break; case SOCKET_ACCEPT: forward_message(SERVER_SOCKET_TYPE_ACCEPT, true, &result); break; default: server_error(NULL, "Unknown socket message type %d.",type); return -1; } if (more) { return -1; } return 1; }
// return type int socket_server_poll(struct socket_server *ss, struct socket_message * result, int * more) { for (;;) { if (ss->checkctrl) { if (has_cmd(ss)) { int type = ctrl_cmd(ss, result); if (type != -1) return type; else continue; } else { ss->checkctrl = 0; } } if (ss->event_index == ss->event_n) { ss->event_n = sp_wait(ss->event_fd, ss->ev, MAX_EVENT); ss->checkctrl = 1; if (more) { *more = 0; } ss->event_index = 0; if (ss->event_n <= 0) { ss->event_n = 0; return -1; } } struct event *e = &ss->ev[ss->event_index++]; struct socket *s = e->s; if (s == NULL) { // dispatch pipe message at beginning continue; } switch (s->type) { case SOCKET_TYPE_CONNECTING: return report_connect(ss, s, result); case SOCKET_TYPE_LISTEN: if (report_accept(ss, s, result)) { return SOCKET_ACCEPT; } break; case SOCKET_TYPE_INVALID: fprintf(stderr, "socket-server: invalid socket\n"); break; default: if (e->write) { int type = send_buffer(ss, s, result); if (type == -1) break; return type; } if (e->read) { int type = forward_message(ss, s, result); if (type == -1) break; return type; } break; } } }
static void *forward_thread(void *argument) { enum forward_type ret; thread_param_t thread_arg, *arg; thread_arg = *(thread_param_t *) argument; arg = &thread_arg; /* set thread name */ debug_printf("\nforward_thread: arg->name = %s\n", arg->name); prctl(PR_SET_NAME, (unsigned int) arg->name); while (1) { fd_set read_set; int numReady; FD_ZERO(&read_set); FD_SET(arg->from, &read_set); numReady = select(FD_SETSIZE, &read_set, 0, 0, 0); if (numReady) { if (FD_ISSET(arg->from, &read_set)) { ret = forward_message(arg->from, arg->to); if (0 != ret) break; } } } /* check if use STDIN_FILENO or not */ if (arg->from == STDIN_FILENO) (void) serial_restore(STDIN_FILENO); if (READ_FAILURE == ret) close(arg->from); else if (WRITE_FAILURE == ret) close(arg->to); pthread_exit((void *) arg->name); return NULL; }
LRESULT CALLBACK tab_group_subclass_proc(HWND window, UINT message, WPARAM wParam, LPARAM lParam, UINT_PTR ptr, DWORD_PTR /* ref */) { tab_group_t& tab_group(*reinterpret_cast<tab_group_t*>(ptr)); NMHDR* notice((NMHDR*) lParam); // // Here we report the selected tab changing to ui-core users. // if (message == WM_NOTIFY && notice && notice->hwndFrom == window) { if (notice->code == TCN_SELCHANGE) { long index(static_cast<long>(::SendMessage(tab_group.control_m, TCM_GETCURSEL, 0, 0))); if (!tab_group.value_proc_m.empty()) tab_group.value_proc_m(tab_group.items_m[index].value_m); } return 0; } else { LRESULT forward_result(0); if (forward_message(message, wParam, lParam, forward_result)) return forward_result; } return ::DefSubclassProc(window, message, wParam, lParam); }
/* 套接字模块的主函数, 不断处理各种套接字命令和套接字 I/O 事件, 将处理的结果发送给对应的服务. * 函数返回 0 表示需要退出套接字模块线程, 返回 -1 表示套接字模块处于忙碌状态, 返回 1 表示空闲的状态. * 检测是否忙碌是通过查看是否还有未执行完的套接字命令或者套接字 I/O 事件. * * 函数无参数 * 返回: 0 表示需要退出套接字模块线程; 1 表示空闲的状态; -1 表示套接字模块处于忙碌状态, 不应该打断; */ int skynet_socket_poll() { struct socket_server *ss = SOCKET_SERVER; assert(ss); struct socket_message result; int more = 1; int type = socket_server_poll(ss, &result, &more); switch (type) { case SOCKET_EXIT: return 0; case SOCKET_DATA: forward_message(SKYNET_SOCKET_TYPE_DATA, false, &result); break; /* SOCKET_CLOSE 的 result 中的 data 等于 NULL */ case SOCKET_CLOSE: forward_message(SKYNET_SOCKET_TYPE_CLOSE, false, &result); break; case SOCKET_OPEN: forward_message(SKYNET_SOCKET_TYPE_CONNECT, true, &result); break; case SOCKET_ERROR: forward_message(SKYNET_SOCKET_TYPE_ERROR, true, &result); break; /* SOCKET_ACCEPT 中得到的新的连接还没有 I/O 事件通知, 需要调用 skynet_socket_start 来开启 */ case SOCKET_ACCEPT: forward_message(SKYNET_SOCKET_TYPE_ACCEPT, true, &result); break; case SOCKET_UDP: forward_message(SKYNET_SOCKET_TYPE_UDP, false, &result); break; default: skynet_error(NULL, "Unknown socket message type %d.",type); return -1; } if (more) { return -1; } return 1; }
void event_based_actor::forward_to(const actor& whom, message_priority prio) { forward_message(whom, prio); }
int ChordNode::listen_incoming_connections(){ /* * This is the funtion each node-thread executes. Here is where all the magic happens. * Basically you setup a socket in the PORT_BASE + id port and wait. After receiving * a message go to the switch clause and do what you need to do (implement the routing protocol) */ char buffer[900]; char buffer_answer[300]; Command answer; /* Open a server socket to listen incoming connections */ int sd; if ((sd=socket(PF_INET, SOCK_STREAM,0)) < 0){ perror("socket"); return 1; } int yes=1; if (setsockopt(sd,SOL_SOCKET,SO_REUSEADDR, &yes, sizeof(int))==-1) perror("setsockopt"); #ifdef DEBUG printf("Node: %d listening to port: %d\n",id,PORT_BASE+id); #endif /* Try to bind into the port */ struct sockaddr_in sa; socklen_t len = sizeof(struct sockaddr_in); char addrstr[INET_ADDRSTRLEN]; while(true) { memset(&sa, 0, sizeof(sa)); sa.sin_family = AF_INET; sa.sin_port = htons(PORT_BASE+id); sa.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(sd, (struct sockaddr *)&sa, sizeof(sa)) < 0) { usleep(800000); perror("bind"); printf("port: %d\n",PORT_BASE+id); } else break; } if (listen(sd, TCP_BACKLOG) < 0){ perror("listen"); return 1; } /* Loop forever serving requests */ while(1){ int newsd; if ((newsd = accept(sd, (struct sockaddr *)&sa, &len)) < 0){ perror("accept"); return 1; } if (!inet_ntop(AF_INET, &sa.sin_addr, addrstr, sizeof(addrstr))) { perror("could not format client's IP address"); return 1; } int ret = read(newsd,buffer,sizeof(buffer)-1); if (ret <= 0) continue; if (buffer[ret-1] == '\n') buffer[ret-1]='\0'; else buffer[ret]= '\0'; #ifdef DEBUG printf("Node: %d Message: %s\n", id, buffer); #endif answer = parse_the_command(buffer); if (answer.type == INSERT_TYPE && (answer.key_and_value.first == "" || answer.key_and_value.second == -1)) { if (close(newsd) < 0) perror("close"); continue; } if (answer.type == QUERY_TYPE && answer.key_and_value.first == "") { if (close(newsd) < 0) perror("close"); continue; } if (answer.type == DELETE_TYPE && answer.key_and_value.first == ""){ if (close(newsd) < 0) perror("close"); continue; } if (answer.type == -1) continue; /* * Buffer holds the initial message */ switch (answer.type){ case INSERT_TYPE : { #ifdef DEBUG printf("Node: %d Type: %d Key: %s Value: %d Initial node: %d Initial node name:%s\n",id,answer->type,answer->key_and_value.first,answer->key_and_value.second,answer->initial_node,answer->initial_node_hostname); #endif if (insert(answer)){ if (answer.initial_node!=-1){ /* * Case: There is initial node and i did the insertion * Purpose: Answer to the initial node and he will answer to the client */ #ifdef DEBUG printf("Node: %d Case 1\n",id); #endif sprintf(buffer_answer, "INSERT DONE AT NODE %s PORT %d ID %d\n", my_hostname.c_str(), PORT_BASE+id, id); forward_message(buffer_answer,answer.initial_node_hostname, PORT_BASE + ring_size); }else{ /* * Case: There is no initial node and i did the insertion * Purpose: Answer directly to the client */ #ifdef DEBUG printf("Node: %d Case 2\n",id); #endif sprintf(buffer_answer, "INSERT DONE AT NODE %s PORT %d ID %d\n", my_hostname.c_str(), PORT_BASE+id, id); if (write(newsd,buffer_answer,strlen(buffer_answer)) != strlen(buffer_answer)) perror("write"); } }else{ if (answer.initial_node != -1){ /* * Case: There is initial node and i didn't do the insertion * Purpose: Just forward the message */ #ifdef DEBUG printf("Node: %d Case 3\n",id); printf("Forwarding to: %d\n",PORT_BASE+successor); #endif forward_message(buffer, successor_hostname, PORT_BASE+successor); }else { /* * Case: There is no initial node and i didn't do the insertion * Purpose: Forward the message to the successor adding the initial node (me) * and wait in port PORT_BASE + ring_size for the node that did the insertion */ #ifdef DEBUG printf("Node: %d Case 4\n",id); #endif std::string new_message = std::string(buffer) + "," + std::to_string(id) + "," + my_hostname; #ifdef DEBUG printf("Forwarding to: %d\n",PORT_BASE+successor); #endif forward_message(new_message, successor_hostname, PORT_BASE + successor); char * answer_buffer; answer_buffer = wait_response_initial_node(PORT_BASE+ ring_size); if (write(newsd,answer_buffer,strlen(answer_buffer)) != strlen(answer_buffer)) perror("write"); } } break; } case QUERY_TYPE : { #ifdef DEBUG printf("Node: %d Type: %d Key: %s Initial node: %d Initial node name:%s\n",id,answer->type,answer->key_and_value.first,answer->initial_node,answer->initial_node_hostname); #endif int value; if (value = query(answer)){ if (answer.initial_node != -1){ /* * Case: There is initial node and i found the key * Purpose: Answer to the initial node and he will answer to the client */ #ifdef DEBUG printf("Node: %d Case 1\n",id); #endif sprintf(buffer_answer,"KEY FOUND AT NODE %s PORT %d ID %d Value: %d\n", my_hostname.c_str(), PORT_BASE+id, id, value); forward_message(buffer_answer, answer.initial_node_hostname, PORT_BASE + ring_size); }else{ /* * Case: There is no initial node and i found the key * Purpose: Answer to the client */ #ifdef DEBUG printf("Node: %d Case 2\n",id); #endif sprintf(buffer_answer,"KEY FOUND AT NODE %s PORT %d ID %d Value: %d\n",my_hostname.c_str(), PORT_BASE+id, id, value); if (write(newsd,buffer_answer,strlen(buffer_answer)) != strlen(buffer_answer)) perror("write"); } }else{ if (answer.initial_node != -1){ /* * Case: There is initial node and i didn't find the key * Purpose: Check if the successor is the initial node. If he isn't just * forward the message. If he is send him failure to find message */ #ifdef DEBUG printf("Node: %d Case 3\n",id); #endif if (answer.initial_node == successor){ sprintf(buffer_answer,"KEY NOT FOUND :(\n"); forward_message(buffer_answer, answer.initial_node_hostname, PORT_BASE + ring_size); }else{ forward_message(buffer, successor_hostname, PORT_BASE+successor); } }else { /* * Case: There is no initial node and i didn't find the key * Purpose: Forward the message to the successor adding the initial node (me) * and wait in port PORT_BASE + ring_size for the node who found or not the element */ #ifdef DEBUG printf("Node: %d Case 4\n",id); #endif std::string new_message = std::string(buffer) + "," + std::to_string(id) + "," + my_hostname; forward_message(new_message,successor_hostname,PORT_BASE+successor); char * answer_buffer; answer_buffer = wait_response_initial_node(PORT_BASE+ ring_size); if (write(newsd,answer_buffer,strlen(answer_buffer)) != strlen(answer_buffer)) perror("write"); } } break; } case DELETE_TYPE : { #ifdef DEBUG printf("Node: %d Type: %d Key: %s Initial node: %d Initial node name:%s\n",id,answer->type,answer->key_and_value.first,answer->initial_node,answer->initial_node_hostname); #endif int value; if (value = delete_file(answer)){ if (answer.initial_node != -1){ /* * Case: There is initial node and i deleted the key * Purpose: Answer to the initial node and he will answer to the client */ #ifdef DEBUG printf("Node: %d Case 1\n",id); #endif std::string buffer_answer = "KEY DELETED AT NODE " + my_hostname + " PORT " + std::to_string(PORT_BASE+id) + " ID " + std::to_string(id); forward_message(buffer_answer, answer.initial_node_hostname, PORT_BASE + ring_size); }else{ /* * Case: There is no initial node and i deleted the key * Purpose: Answer to the client */ #ifdef DEBUG printf("Node: %d Case 2\n",id); #endif std::string buffer_answer = "KEY DELETED AT NODE " + my_hostname + " PORT " + std::to_string(PORT_BASE+id) + " ID " + std::to_string(id); if (write(newsd, buffer_answer.c_str(), buffer_answer.length()) != buffer_answer.length()) perror("write"); } }else{ if (answer.initial_node != -1){ /* * Case: There is initial node and i didn't delete the key * Purpose: Check if the successor is the initial node. If he isn't just * forward the message. If he is send him failure to delete message */ #ifdef DEBUG printf("Node: %d Case 3\n",id); #endif if (answer.initial_node == successor){ sprintf(buffer_answer, "KEY NOT FOUND :(\n"); forward_message(buffer_answer, answer.initial_node_hostname, PORT_BASE + ring_size); }else{ forward_message(buffer, successor_hostname, PORT_BASE+successor); } }else { /* * Case: There is no initial node and i didn't delete the key * Purpose: Forward the message to the successor adding the initial node (me) * and wait in port PORT_BASE + ring_size for the node who deleted or not the element */ #ifdef DEBUG printf("Node: %d Case 4\n",id); #endif std::string new_message = std::string(buffer) + "," + std::to_string(id) + "," + my_hostname; forward_message(new_message,successor_hostname,PORT_BASE+successor); char * answer_buffer; answer_buffer = wait_response_initial_node(PORT_BASE+ ring_size); if (write(newsd,answer_buffer,strlen(answer_buffer)) != strlen(answer_buffer)) perror("write"); } } break; } case QUERY_STAR : { #ifdef DEBUG printf("Node: %d Type: %d\n",id,answer->type); #endif /* * Just put all your files in a buffer and send it */ char temp_buffer[50]; sprintf(buffer,"Node %d files:\nFile Hash\tValue\n",id); for(int i=0; i< files.size(); i++){ sprintf(temp_buffer,"%d\t\t%d\n",files.at(i).first,files.at(i).second); if (i==files.size()-1) temp_buffer[strlen(temp_buffer)]='\0'; strcat(buffer,temp_buffer); } if (write(newsd,buffer,strlen(buffer)) != strlen(buffer)) perror("write"); break; } case JOIN_TRANSFER : { #ifdef DEBUG printf("Node: %d Type: %d New node: %d New node name: %s\n",id,answer->type,answer->initial_node,answer->initial_node_hostname); #endif std::vector<int> delete_vector; sprintf(buffer,"JOIN_RECEIVE,"); /* * Two cases: For a node that is smaller than me but has to also take the file at the end of the ring * and for the typical case */ if (answer.initial_node < id){ #ifdef DEBUG printf("1st case\n"); #endif char temp_buffer[50]; for (int i=0; i<files.size(); i++){ if (files.at(i).first < answer.initial_node || files.at(i).first > id) { sprintf(temp_buffer,"%d-%d-",files.at(i).first,files.at(i).second); strcat(buffer,temp_buffer); delete_vector.push_back(files.at(i).first); } } } else { #ifdef DEBUG printf("2nd case\n"); #endif char temp_buffer[50]; for (int i=0; i<files.size(); i++){ if ((files.at(i).first > id)&&(files.at(i).first < answer.initial_node)){ printf("%d ",files.at(i).first); sprintf(temp_buffer,"%d-%d-",files.at(i).first,files.at(i).second); strcat(buffer,temp_buffer); delete_vector.push_back(files.at(i).first); } } } for (int i=0; i < delete_vector.size(); i++) delete_file_from_hash(delete_vector.at(i)); forward_message(buffer, answer.initial_node_hostname, PORT_BASE + answer.initial_node); break; } case JOIN_RECEIVE : { #ifdef DEBUG printf("Node: %d Type: %d Receiving those files: %s\n",id,answer->type,answer->files); #endif /* * Inserts all the new files. This is the first thing that a joining node executes! */ int file, value; char * temp_string; if (answer.files == "") break; strcpy(buffer, answer.files.c_str()); temp_string = strtok(buffer,"-"); while(temp_string != NULL){ file= atoi(temp_string); temp_string = strtok(NULL,"-"); value = atoi(temp_string); temp_string = strtok(NULL,"-"); insert_file_from_hash(file,value); } break; } case DEPART_TRANSFER : { #ifdef DEBUG printf("Node: %d Type: %d Removing ths node.... :(\n",id,answer->type); #endif /* * No cases here. Just send everything away. */ char temp_buffer[50]; sprintf(buffer,"DEPART_RECEIVE,"); for (int i=0; i<files.size(); i++){ sprintf(temp_buffer,"%d-%d-",files.at(i).first,files.at(i).second); strcat(buffer,temp_buffer); } forward_message(buffer,successor_hostname,PORT_BASE+successor); if (close(sd) < 0) perror("close"); return 1; break; } case DEPART_RECEIVE : { #ifdef DEBUG printf("Node: %d Type: %d Receiving those files: %s\n",id,answer->type,answer->files); #endif /* * And here just insert everyting */ if (answer.files == "") break; int file, value; char * temp_string; strcpy(buffer,answer.files.c_str()); temp_string = strtok(buffer,"-"); while(temp_string != NULL){ file= atoi(temp_string); temp_string = strtok(NULL,"-"); value = atoi(temp_string); temp_string = strtok(NULL,"-"); insert_file_from_hash(file,value); } break; } } if (close(newsd) < 0) perror("close"); /* if (answer->key_and_value.first != NULL) free(answer->key_and_value.first); if (answer->initial_node_hostname != NULL) free(answer->initial_node_hostname); if (answer != NULL) free(answer); */ } };
static void init(SEL _sel, OBJ _1, OBJ _2, void *_arg, void *_ret) { cos_init(); forward_message(_1,_2); }
static olsr_bool process_tc(struct olsrv2 *olsr, struct tc_message *tc, union olsr_ip_addr *in_if ) { struct tc_mpr_addr *mpr_selector = NULL; OLSR_LIST *tmpList = NULL; OLSR_LIST_ENTRY *tmpEntry = NULL; OLSR_TOPOLOGY_TUPLE *tmpTuple = NULL; ATTACHED_NETWORK *attached_net_entry = NULL; char* paddr; if(DEBUG_OLSRV2) { olsr_printf("\tProcess TOPOLOGY MESSAGE\n"); } /* //codexxx' // before processing TC message add the queue length of the corresponding originator to the OLSR_LIST "queue_set" olsr_bool IPfound = OLSR_FALSE; struct queue_info *queueInf = NULL, *tempo= NULL ; OLSR_LIST_ENTRY *queueEntry = NULL; queueInf = (queue_info *)olsr_malloc(sizeof(queue_info), __FUNCTION__); queueInf->orig_IP = tc->originator; queueInf->Qlength = tc->queuelength; if(olsr->queue_set.numEntry == 0) { // insert to the list directly OLSR_InsertList(&olsr->queue_set,queueInf,sizeof(queue_info)); }else{ // liste deja contient des element ...donc trouver si deja existe queueEntry = olsr->queue_set.head ; while(queueEntry != NULL) ///// { tempo = (queue_info *)queueEntry->data ; if(!cmp_ip_addr(olsr,&tempo->orig_IP,&queueInf->orig_IP)) //// { // on a trouver cet originator IP ds la liste alors update le queue et sortir de la boucle tempo->Qlength = queueInf->Qlength; IPfound = OLSR_TRUE; break; } queueEntry = queueEntry->next ; } if(IPfound == OLSR_FALSE) { // cet IP n'existe pas deja dans la liste => l'introduire OLSR_InsertList(&olsr->queue_set,queueInf,sizeof(queue_info)); } } //end codexxx' */ //13.1.1 if (lookup_link_status(olsr, &tc->source_addr) != SYMMETRIC) { if(DEBUG_OLSRV2) { paddr = olsr_niigata_ip_to_string(olsr, &tc->source_addr); olsr_printf("\tsource addr:%s isn't sym neigh\n",paddr); free(paddr); } return OLSR_FALSE; } //13.1.2 //check previous :look tc_change_structure //13.1.3 if ((tmpList = lookup_topology_set(olsr, &tc->originator)) != NULL){ tmpEntry = (OLSR_LIST_ENTRY *)tmpList->head; while (tmpEntry) { tmpTuple = (OLSR_TOPOLOGY_TUPLE *)tmpEntry->data; if (tmpTuple->T_seq > tc->assn){ OLSR_DeleteList_Search(tmpList); if(DEBUG_OLSRV2) { olsr_printf("\t\tThis message is OLD.Skipped\n"); } return OLSR_FALSE; } tmpEntry = tmpEntry->next; } OLSR_DeleteList_Search(tmpList); } //13.1.4 mpr_selector = tc->mpr_selector_address; while (mpr_selector){ proc_topology_set(olsr, &mpr_selector->address, &tc->originator, tc->assn, OLSR_FALSE); mpr_selector = mpr_selector->next; } //updating the attached network set attached_net_entry = tc->attached_net_addr; while(attached_net_entry){ proc_attached_set(olsr, &attached_net_entry->network_addr, attached_net_entry->prefix_length, &tc->originator, tc->assn); attached_net_entry = attached_net_entry->next; } debug_code(print_attached_set(olsr)); if(proc_forward_set(olsr, &tc->originator, &tc->source_addr, tc->message_seq_number) == OLSR_TRUE){ forward_message(olsr); } return OLSR_TRUE; }
/** * This is the main message reading loop. Messages are read, validated, * decrypted if necessary, then passed to the appropriate routine for handling. */ void mainloop() { struct uftp_h *header; unsigned char *buf, *decrypted, *message; int packetlen, listidx, hostidx, i; unsigned int decryptlen, meslen; uint8_t *func; struct sockaddr_in src; struct in_addr srcaddr; struct timeval *tv; const int bsize = 9000; // Roughly size of ethernet jumbo frame log0(0, 0, "%s", VERSIONSTR); for (i = 0; i < key_count; i++) { log(0, 0, "Loaded key with fingerprint %s", print_key_fingerprint(privkey[i])); } buf = calloc(bsize, 1); decrypted = calloc(bsize, 1); if ((buf == NULL) || (decrypted == NULL)) { syserror(0, 0, "calloc failed!"); exit(1); } header = (struct uftp_h *)buf; while (1) { tv = getrecenttimeout(); if (read_packet(listener, &src, buf, &packetlen, bsize, tv) <= 0) { continue; } if ((header->uftp_id != UFTP_VER_NUM) && (header->uftp_id != UFTP_3_0_VER)) { log(0, 0, "Invalid message from %s: not uftp packet " "or invalid version", inet_ntoa(src.sin_addr)); continue; } if (packetlen != sizeof(struct uftp_h) + ntohs(header->blsize)) { log(0, 0, "Invalid packet size from %s: got %d, expected %d", inet_ntoa(src.sin_addr), packetlen, sizeof(struct uftp_h) + ntohs(header->blsize)); continue; } if ((src.sin_addr.s_addr == out_addr.s_addr) && (src.sin_port == htons(port))) { // Packet from self -- drop continue; } if (header->func == HB_REQ) { handle_hb_request(&src, buf); continue; } if (header->func == HB_RESP) { handle_hb_response(listener, &src, buf, hb_hosts, hbhost_count, noname, privkey[0]); continue; } if (header->func == KEY_REQ) { handle_key_req(&src, buf); continue; } if (header->func == PROXY_KEY) { // Only clients handle these, so drop continue; } if ((proxy_type == SERVER_PROXY) && (down_addr.sin_addr.s_addr == INADDR_ANY)) { log(0, 0, "Rejecting message from %s: downstream address " "not established", inet_ntoa(src.sin_addr)); continue; } listidx = find_group(ntohl(header->group_id)); if (header->func == ANNOUNCE) { handle_announce(listidx, &src, buf); } else { if (listidx == -1) { continue; } if (proxy_type == SERVER_PROXY) { // Server proxies don't do anything outside of an ANNOUNCE. // Just send it on through. forward_message(listidx, &src, buf); continue; } if (header->func == ABORT) { handle_abort(listidx, &src, buf); continue; } if (!memcmp(&src, &group_list[listidx].up_addr, sizeof(src))) { // Downstream message if (header->func == KEYINFO) { handle_keyinfo(listidx, buf); } else if ((header->func == REG_CONF) && (group_list[listidx].keytype != KEY_NONE)) { handle_regconf(listidx, buf); } else { // If we don't need to process the message, don't bother // decrypting anything. Just forward it on. forward_message(listidx, &src, buf); } } else { // Upstream message // Decrypt first if necessary hostidx = find_client(listidx, header->srcaddr); if ((hostidx != -1) && (header->func == ENCRYPTED) && (group_list[listidx].keytype != KEY_NONE)) { if (!validate_and_decrypt(buf, &decrypted, &decryptlen, group_list[listidx].mtu,group_list[listidx].keytype, group_list[listidx].groupkey, group_list[listidx].groupsalt, group_list[listidx].ivlen, group_list[listidx].hashtype, group_list[listidx].grouphmackey, group_list[listidx].hmaclen, group_list[listidx].sigtype, group_list[listidx].destinfo[hostidx].pubkey, group_list[listidx].destinfo[hostidx].pubkeylen)) { log(ntohl(header->group_id), 0, "Rejecting message " "from %s: decrypt/validate failed", inet_ntoa(src.sin_addr)); continue; } func = (uint8_t *)decrypted; message = decrypted; meslen = decryptlen; } else { if ((hostidx != -1) && (group_list[listidx].keytype != KEY_NONE) && ((header->func == INFO_ACK) || (header->func == STATUS) || (header->func == COMPLETE))) { log(ntohl(header->group_id), 0, "Rejecting %s message " "from %s: not encrypted", func_name(header->func), inet_ntoa(src.sin_addr)); continue; } func = (uint8_t *)&header->func; message = buf + sizeof(struct uftp_h); meslen = ntohs(header->blsize); } if ((hostidx == -1) && (header->srcaddr == 0)) { srcaddr = src.sin_addr; } else { srcaddr.s_addr = header->srcaddr; } switch (*func) { case REGISTER: handle_register(listidx, hostidx, message, meslen, srcaddr.s_addr); break; case CLIENT_KEY: handle_clientkey(listidx, hostidx, message, meslen, srcaddr.s_addr); break; case INFO_ACK: handle_info_ack(listidx, hostidx, message, meslen); break; case STATUS: handle_status(listidx, hostidx, message, meslen); break; case COMPLETE: handle_complete(listidx, hostidx, message, meslen); break; default: forward_message(listidx, &src, buf); break; } } } } }