int modAOS_B_PDU_Add::svc() { svcStart_(); if ( ! _bpduLength) { if ( getMTU() > 0 ) { _bpduLength = getMTU(); _mtuIsManual = true; } else if (links_[PrimaryOutputLink] ) { MOD_INFO("B_PDU length is unset, asking output target %s for MRU.", links_[PrimaryOutputLink]->getTarget()->getName().c_str()); _bpduLength = links_[PrimaryOutputLink]->getTarget()->getMRU(); _mtuIsManual = false; } } if (_bpduLength > 0) { rebuildIdleUnitTemplate_(); while ( continueService() ) { std::pair<NetworkData*, int> queueTop = getData_(); // Check every 11th unit for a new MTU if ( ! _mtuIsManual && getReceivedUnitCount() % 11 == 0 && links_[PrimaryOutputLink] ) { _bpduLength = links_[PrimaryOutputLink]->getTarget()->getMRU(); } if ( msg_queue()->deactivated() ) break; if ( queueTop.second < 0 ) { MOD_ERROR("getData_() call failed."); continue; } else if ( ! queueTop.first ) { MOD_ERROR("getData_() returned with null data."); continue; } MOD_DEBUG("Received %d bytes to convert into AOS B_PDUs.", queueTop.first->getUnitLength()); AOS_Bitstream_PDU* bpdu_list = _process_data(queueTop.first); // Deletion of received data is performed in _process_data. if ( ! getSendImmediately() ) { while (bpdu_list) { AOS_Bitstream_PDU* cur = bpdu_list; _send(cur); bpdu_list = (AOS_Bitstream_PDU*) bpdu_list->getNextPart(); } } MOD_DEBUG("Finished processing incoming packets."); } } else { MOD_ERROR("No MTU obtainable, exiting service loop (pausing)."); } return svcEnd_(); }
/** * Read input from local keyboard. */ int8_t StandardIO::read_port() { char *input_text = (char*) alloca(getMTU()); // Buffer to hold user-input. int read_len = 0; if (connected()) { bzero(input_text, getMTU()); if (nullptr == fgets(input_text, getMTU()-1, stdin)) { return 0; } read_len = strlen(input_text); // NOTE: This should suffice to be binary-safe. //read_len = fread(input_text, 1, getMTU(), stdin); if (read_len > 0) { bytes_received += read_len; BufferPipe::fromCounterparty((uint8_t*) input_text, read_len, MEM_MGMT_RESPONSIBLE_BEARER); } } flushLocalLog(); return read_len; }
int main(int argc, char * argv[]){ //first, check the number of argument if (argc != 2){ printf("Usage: serveur.exe <port number>\n"); exit(1); } //trap SIGINT signal(SIGINT,SIGINT_handler); //variable definition int sock_Data, addr_len,pid, seq, cwnd,normal_wnd, advanced_wnd; int test =-1; int SEG_SIZE,size,inc,descriptorToCheck[2]; int reuse = 1; int ctrlBuff_SIZE = 12; int isSYN=0; int seq_advanced, seq_expected,checkBreak=0; char SYN_ACK[12]; char FIN[4]="FIN"; char ctrlBuffer[ctrlBuff_SIZE]; char * dataBuffer; FILE * file; DATA DATA = NULL; struct timeval ZERO = {0, 0}; // struct sockaddr_in SOCKADDR_IN * my_addr_UDP;//Adress for listening UDP SOCKADDR_IN * my_client_addr;//Adress client, for control SOCKADDR_IN * data_addr;//Adress client for Data int port_nb = atoi(argv[1]); int sock_Control= mySocket(AF_INET,SOCK_DGRAM,0); //socketUDP //display the descriptor value and pid of server printf("Id Socket: %i\n",sock_Control); printf("PID father: %i\n",getpid()); //allow to reuse immediately the socket setsockopt( sock_Control, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)); // structure sockaddr_in initialization my_addr_UDP = conf_sock_addr(AF_INET, port_nb, "0.0.0.0"); my_client_addr = init_sock_addr(); size = sizeof(*my_client_addr); //link the socket to the structure myBind(sock_Control,my_addr_UDP,sizeof(*my_addr_UDP)); descriptorToCheck[0] = sock_Control; //init fd set fd_set * my_read_set = init_fd_set(); //loop to be a daemon while (isSIGINT==0){ //set the fd_set set_fd_set(my_read_set,descriptorToCheck[0]); select(sock_Control+1,my_read_set,NULL,NULL,&ZERO); if ( FD_ISSET(sock_Control, my_read_set) ){ // message reception myReceiveFrom(sock_Control, ctrlBuffer, ctrlBuff_SIZE,my_client_addr,&size); printf("Reception UDP by %d: %s\n",getpid(),ctrlBuffer); // if message of type SYN if ( check_SYN(ctrlBuffer) == 1){ port_nb= (port_nb+1)%8975+1025 ; sprintf(SYN_ACK,"SYN-ACK%04d",port_nb); //new socket for receiving data sock_Data = mySocket(AF_INET,SOCK_DGRAM,0); data_addr = conf_sock_addr(AF_INET, port_nb, "0.0.0.0"); addr_len = sizeof(* data_addr); descriptorToCheck[1]=sock_Data; //binding sock on addr client myBind(sock_Data,data_addr,addr_len); printf("Connexion Asked by client, dialoguing on port %d \n", ntohs(data_addr->sin_port)); printf("Adresse client %s\n",inet_ntoa(my_client_addr->sin_addr)); data_addr = conf_sock_addr(AF_INET, port_nb, inet_ntoa(my_client_addr->sin_addr)); // variable for receiving SEG_SIZE= getMTU(data_addr)-28; // (MTU - header UDP + header IP) SEG_SIZE=(SEG_SIZE> 5000)?5000:SEG_SIZE; dataBuffer = (char *)malloc(SEG_SIZE*sizeof(char)); isSYN=1; mySendTo(sock_Control, SYN_ACK,12,my_client_addr); } if ( check_ACK(ctrlBuffer) == 1 && isSYN ==1){ printf("Connexion Accept\n"); isSYN = 0; //a little fork pid = fork(); //if error if (pid == -1){ perror("Fork Error\n"); exit(-1); } /*======================================================================================*/ /*===================================== child code =====================================*/ /*======================================================================================*/ else if (pid == 0){ myClose(sock_Control); // reception of file name myReceiveFrom(sock_Data,dataBuffer, SEG_SIZE,data_addr,&addr_len); printf("Client Asking for file %s\n",dataBuffer); //retrieve file name file=myOpen(dataBuffer,"r"); seq=1, seq_advanced=1, cwnd =400,normal_wnd=320, advanced_wnd=cwnd-normal_wnd; //while something to send, send and wait for ack do { checkBreak=0; seq_expected=(seq == seq_advanced)?seq+cwnd:seq_advanced+advanced_wnd; printf("seq :%d, seq_expected %d, seq_advanced %d\n",seq, seq_expected, seq_advanced); //construct DATA to send from file if (test == -1) test= readFileToBUFFER(file,&DATA,seq,(seq+cwnd==seq_expected)?cwnd:seq_advanced-seq+advanced_wnd,SEG_SIZE); else readFileToBUFFER(file,&DATA,seq,test-seq,SEG_SIZE); //send dataBuffer to client if(seq+normal_wnd==seq_expected || seq == 1) { sendData(sock_Data, cwnd, DATA, data_addr); }else{ printf("fast retransmit, resend sequence presumed lost\n"); sendData(sock_Data, normal_wnd, DATA, data_addr); printf("fast retransmit, send selected data\n"); sendSelectedData(sock_Data,seq_advanced,advanced_wnd,DATA,data_addr); } //while there is something to read set_fd_set(my_read_set, descriptorToCheck[1]); select(sock_Data + 1, my_read_set, NULL, NULL, &ZERO); while (FD_ISSET(sock_Data,my_read_set) ) { //reception myReceiveFrom(sock_Data, ctrlBuffer, ctrlBuff_SIZE, data_addr, &addr_len); //number of sequences acknowledged, (-1 si duplicate ACK) inc = check_ACK_Seq(seq,cwnd,ctrlBuffer); if (inc == -1) // if duplicate ACK { printf("ACK Duplicate "); sendSelectedData(sock_Data,seq,1,DATA,data_addr); if (checkBreak==0){ usleep(100000); checkBreak=1; } } else if (inc > 0){// if good ACK checkBreak=0; seq += inc; if (seq==seq_expected)break; } //set the descriptor to check set_fd_set(my_read_set, descriptorToCheck[1]); select(sock_Data + 1, my_read_set, NULL, NULL, &ZERO); } if ( test == -1) seq_advanced=(seq_advanced+advanced_wnd > seq+2000 || seq_advanced < seq+normal_wnd)?seq+normal_wnd:seq_advanced+advanced_wnd; else seq_advanced=(seq_advanced+advanced_wnd > seq + 2000 || seq_advanced+advanced_wnd> test+1)?seq+normal_wnd:seq_advanced+advanced_wnd; } while(seq != test+1 ); printf("client dialoguing on port %d\n",ntohs(data_addr->sin_port)); for(reuse=0;reuse<1000000;reuse++) mySendTo(sock_Data, FIN, 4, data_addr); //Send FIN to client //to do a clean exit myClose(sock_Data); free(my_addr_UDP); free(my_client_addr); free(dataBuffer); free_Data(DATA); fclose(file); printf("\e[1;3%dmEnd of connexion. Son with pid:%d is closing, communicate on %d\e[0m\n", sock_Data % 8, getpid(),port_nb); exit(1); } /*======================================================================================*/ /*==================================== end of child ====================================*/ /*======================================================================================*/ } }
devEthernet::devEthernet(const std::string& newName /* = "" */, const CE_DLL* newDLLPtr /* = 0 */): CE_Device(newName, newDLLPtr), _ifaceName(""), _ifaceNameSetting(CEcfg::instance()->getOrAddString(cfgKey("ifaceName"), _ifaceName)), _vendor(""), _model(""), _packetSocket(ACE_INVALID_HANDLE), _netlinkSocket(0), _snapLen(CEcfg::instance()->getOrAddInt(cfgKey("snapLen"), 0)), _activateOnLoad(CEcfg::instance()->getOrAddBool(cfgKey("activateOnLoad"), true)), _noArpSetting(CEcfg::instance()->getOrAddBool(cfgKey("flagNoARP"), false)), _promiscSetting(CEcfg::instance()->getOrAddBool(cfgKey("flagPromisc"), false)) { CEcfg::instance()->getOrAddString(cfgKey("devType")) = "Ethernet"; if ( strcmp(_ifaceNameSetting.c_str(), "") == 0) { MOD_INFO("Getting interface name from Device name (%s).", newName.c_str()); setIfaceName(newName); } else { MOD_INFO("Getting interface name from config file (%s).", _ifaceNameSetting.c_str()); _ifaceName = static_cast<const char*>(_ifaceNameSetting); } if ( ! _ifaceName.empty() ) { if ( isProtected() ) throw IsProtected("Device " + getIfaceName() + " is marked 'protected' and cannot be managed by the CE."); // IOCtlFailed is thrown if there's an error try { _ioctl(SIOCGIFFLAGS, _savedFlags, "Error getting flags for interface " + getIfaceName() + " via SIOCGIFFLAGS: "); } catch (...) { MOD_ERROR("Could not read flags to restore later."); } try { if (getActivateOnLoad()) activate(); } catch (...) { MOD_ERROR("Unable to activate at this time."); } if ( CEcfg::instance()->exists(cfgKey("MTU")) ) setMTU(static_cast<unsigned int>(CEcfg::instance()->get(cfgKey("MTU")))); } if ( getSnapLen() == 0 ) { MOD_DEBUG("Automatically setting snapLen."); setSnapLen(static_cast<int>(getMTU() + 30)); MOD_DEBUG("SnapLen set to %d.", getSnapLen()); } MOD_DEBUG("Connecting netlink socket."); _netlinkSocket = Linux::nl_socket_alloc(); if (Linux::nl_connect(_netlinkSocket, NETLINK_ROUTE) < 0) { ND_ERROR("[%s] Unable to connect netlink socket: %s\n", nl_geterror(errno)); Linux::nl_socket_free(_netlinkSocket); } MOD_DEBUG("Ethernet constructor complete."); }