int main(int argc, char** argv) { int socket; int rc; uint16_t msg_size = MAX_MSGSIZE; char buffer[MAX_MSGSIZE + 1]; char msg[MAX_MSGSIZE + 1]; #ifdef _WIN32 WSADATA wsaData; rc = WSAStartup(MAKEWORD(2,2), &wsaData); if (rc != 0) { printf("WSAStartup failed with error: %d\n", rc); goto err; } #endif ProcessArgs(argc, argv); memset(buffer, 0, MAX_MSGSIZE + 1); memset(msg, 0, MAX_MSGSIZE + 1); strcpy(msg, "Hello, this is the client!"); if (bIsServer) { socket = announce(OPTRC_FILE); if (socket == INVALID_SOCKET) { rc = -1; goto err; } rc = recvdata(socket, buffer, &msg_size); if (rc == SOCKET_ERROR) { goto err; } printf("%s\n", buffer); } else { socket = locate(OPTRC_FILE); if (socket == INVALID_SOCKET) { rc = -1; goto err; } rc = senddata(socket, msg, strlen(msg)); if (rc == SOCKET_ERROR) { goto err; } } err: #ifdef _WIN32 closesocket(socket); WSACleanup(); #else close(socket); #endif return rc; }
int main(int argc, char *argv[]) { // default to localhost char *server_name= "localhost"; unsigned short port = DEFAULT_PORT; int i, loopcount, maxloop=-1; int retval; unsigned int addr; int socket_type = DEFAULT_PROTO; struct sockaddr_in server; if (argc < 3) { Usage(); } if ((retval = WSAStartup(0x202, &wsaData)) != 0) { fprintf(stderr,"WSAStartup() failed with error %d\n", retval); WSACleanup(); return -1; } // Get portnum port = atoi(argv[2]); memset(&server, 0, sizeof(server)); server.sin_addr.s_addr = inet_addr(argv[1]); server.sin_family = AF_INET; server.sin_port = htons(port); conn_socket = socket(AF_INET, socket_type, 0); /* Open a socket */ if (conn_socket <0 ) { fprintf(stderr,"Client: Error Opening socket: Error %d\n", WSAGetLastError()); WSACleanup(); return -1; } if (connect(conn_socket, (struct sockaddr*)&server, sizeof(server)) == SOCKET_ERROR) { fprintf(stderr,"Client: connect() failed: %d\n", WSAGetLastError()); WSACleanup(); return -1; } // Send the data senddata(); // recieve a msg recvdata(); closesocket(conn_socket); WSACleanup(); return 0; }
//~~~~~~~~~~~~~~~~~~~~~用户登陆~~~~~~~~~~~~~~~~~~~~~~~~~~~ //传送格式username*userpasswd# int login(char username[20],char userpasswd[10]) { top: printf("ID: "); scanf("%s",username); strcpy(tempuname,username); printf("PASSWD: "); scanf("%s",userpasswd); strcat(username,"*"); strcat(username,userpasswd); strcat(username,"#"); // printf("%s\n",username); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ struct FilePackage data; data=pack('L', username, " ", 0, 9,strlen(username),tempuname); // printf("%s\n",username); if(senddata(data)==0) exit(0); // printf("%s\n",username); if(recvdata(&data)==0) exit(0); // printf("%s\n",username); // printf("%s\n",data.buf); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if(data.cmd == 'L' && data.ack == 0) { printf("\n\033[33mUsername or Password error!\033[0m\n\n"); goto top; } if(data.cmd == 'L' && data.ack == 1) { printf("Login Success\n"); printf("%s\n",data.buf); // SSL_shutdown(ssl); // SSL_free(ssl); // close(sockclient); // SSL_CTX_free(ctx); return 1; } if(data.cmd == 'L' && data.ack == 2) { printf("\n\033[32mMaxnum connection!\033[0m\n\n"); exit(0); } return 0; }
void mesgWnd(int sockfd) { WINDOW *wnd, *pad; int max_y, max_x, pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol; initscr(); noecho(); nocbreak(); start_color(); use_default_colors(); init_pair(1, COLOR_WHITE, COLOR_BLUE); init_pair(2, COLOR_BLACK, COLOR_WHITE); getmaxyx(stdscr, max_y, max_x); wnd = newwin(0, 0, max_y, max_x - WNDWIDTH); pad = newpad(max_y, WNDWIDTH); wbkgd(wnd, COLOR_PAIR(1)); wbkgd(pad, COLOR_PAIR(2)); pminrow = pmincol = 0; sminrow = 0; smincol = max_x; smaxrow = max_y; smaxcol = max_x + WNDWIDTH; wprintw(wnd, "mainwindow> "); wrefresh(wnd); prefresh(pad, pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol); for(;;) { char buf[BUFSIZ], *p; recvdata(sockfd, buf, BUFSIZ); if(strcmp(buf, "exit") == 0) break; wprintw(pad, "%s\n", buf); wrefresh(wnd); prefresh(pad, pminrow, pmincol, sminrow, smincol - WNDWIDTH - 1, smaxrow, smaxcol - WNDWIDTH - 1); sleep(3); prefresh(pad, pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol); } endwin(); delwin(wnd); delwin(pad); }
/* Fetch data, check if it's data for us and whether it's useable or not. If not, return * a failure code so we can delete this server from our list and continue with another one. */ int recvpkt ( SOCKET rsock, struct pkt *rpkt, /* received packet (response) */ unsigned int rsize, /* size of rpkt buffer */ struct pkt *spkt /* sent packet (request) */ ) { int rdy_socks; int pkt_len; sockaddr_u sender; struct timeval timeout_tv; fd_set recv_fd; FD_ZERO(&recv_fd); FD_SET(rsock, &recv_fd); if (ENABLED_OPT(TIMEOUT)) timeout_tv.tv_sec = (int) atol(OPT_ARG(TIMEOUT)); else timeout_tv.tv_sec = 68; /* ntpd broadcasts every 64s */ timeout_tv.tv_usec = 0; rdy_socks = select(rsock + 1, &recv_fd, 0, 0, &timeout_tv); switch (rdy_socks) { case -1: if (ENABLED_OPT(NORMALVERBOSE)) perror("sntp recvpkt: select()"); return PACKET_UNUSEABLE; break; case 0: if (ENABLED_OPT(NORMALVERBOSE)) printf("sntp recvpkt: select() reached timeout (%u sec), aborting.\n", (unsigned)timeout_tv.tv_sec); return PACKET_UNUSEABLE; break; default: break; } pkt_len = recvdata(rsock, &sender, (char *)rpkt, rsize); if (pkt_len > 0) pkt_len = process_pkt(rpkt, &sender, pkt_len, MODE_SERVER, spkt, "recvpkt"); return pkt_len; }
//~~~~~~~~~~~~~~~~~~~~~~~显示客户端目录~~~~~~~~~~~~~~~~~~~ void Show(char temp[100]) { char command [2]; if((strncpy(command,temp,1),*command)=='1'||(strncpy(command,temp,1),*command)=='2'||(strncpy(command,temp,1),*command)=='3') return; if(strncmp(temp,"cd",2)==0) { char dir[40]={'\0'}; temp[strlen(temp)-1]='\0'; strncpy(dir,(&(*temp)+3),strlen(&(*temp)+3)); /* printf("%d%s",strlen((&(*temp)+3)),(&(*temp)+3)); printf("%d%s",strlen(dir),dir); if(dir[strlen(dir)]=='\0') printf("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n"); */ chdir(dir); strcpy(temp,"ls"); } system("clear"); printf("\n\033[34m----------------------------- \033[31mClient Files List \033[34m----------------------------\033[0m\n"); system(temp); // printf("\033[34m*******************************************************************************\033[0m\n"); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~显示服务器目录~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ senddata(pack('S', " ", " ", 0, 9,1,tempuname)); struct FilePackage data; if(recvdata(&data)==0) exit(0); if(data.cmd=='S') { printf("\033[34m----------------------------- \033[31mServer Files List \033[34m----------------------------\033[0m\n"); printf("%s\n",data.buf); printf("\033[34m--------------------------------------------------------------------------------\033[0m\n"); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ }
/*************************************TcpClient::clientInit*********************************************/ void TcpClient::clientInit(sockaddr_in addr, int pipereadId) { pthread_mutex_init(&(this->mutex), NULL); //初始化互斥锁 this->setstatus(false); //初始后状态字 this->pipewrite = pipereadId; //设置写管道ID debug("Child:pipewriteID:%d child's process pid:%d\n" ,this->pipewrite,getpid()); this->clientsock = socket(AF_INET, SOCK_STREAM, 0); if (this->clientsock == -1) { cout << "create client error" << endl; } if (0 == clientConnect(addr, sizeof(sockaddr_in), CONNECTTIMEOUT)) { //正常连接,则创建发送线程 pthread_create(&(this->tid), NULL, PerTransFun, (void *) this); //创建周期性发数据的线程 } else { //处理硬错误,错误代码111,此时connect不会阻塞到SIGALRM信号的发生 cout << "Client(" << getpid() << "):connect timeout within given time"; perror(""); exit(-1); } //创建select来接收到来的包,并调用函数进行分析 fd_set rset; FD_ZERO(&rset); struct timeval tt; tt.tv_sec = 1; tt.tv_usec = 0; while (1) { FD_SET(this->clientsock, &rset); select((this->clientsock) + 1, &rset, NULL, NULL, &tt); if (this->getstatus() && FD_ISSET(this->clientsock,&rset)) { this->coordinate.push_back(recvdata()); } else if (!this->getstatus()) { break; } } pthread_join(this->tid, NULL); debug("Child:init end child's process pid:%d\n" , getpid()); }
// // Function: ClientThread // // Description: // This is a client thread that is spawned with each client // connection. The thread simply reads data and writes it // back to the client until the socket is closed. // DWORD WINAPI ClientThread(LPVOID lpParam) { SOCKET s = (SOCKET)lpParam; int ret, len; char szRecvBuff[MAX_BUFFER]; while (1) { // Read data from client // len = MAX_BUFFER; if ((ret = recvdata(s, szRecvBuff, &len)) != 0) { printf("recv() failed: %d\n", ret); break; } if (len == 0) // Graceful close break; szRecvBuff[len] = 0; printf("Read: %d bytes\n", len); // // Write data back until socket closure, len will // equal 0 when the socket has been gracefully closed // if ((ret = senddata(s, szRecvBuff, &len)) != 0) { printf("send() failed: %d\n", ret); break; } if (len == 0) // Graceful close break; printf("Wrote: %d bytes\n", len); } closesocket(s); return 0; }
/* ** Socket readable/timeout Callback: ** Read in the packet ** Unicast: ** - close socket ** - decrement n_pending_ntp ** - If packet is good, set the time and "exit" ** Broadcast: ** - If packet is good, set the time and "exit" */ void sock_cb( evutil_socket_t fd, short what, void *ptr ) { sockaddr_u sender; sockaddr_u * psau; sent_pkt ** p_pktlist; sent_pkt * spkt; int rpktl; int rc; INSIST(sock4 == fd || sock6 == fd); TRACE(3, ("sock_cb: event on sock%s:%s%s%s%s\n", (fd == sock6) ? "6" : "4", (what & EV_TIMEOUT) ? " timeout" : "", (what & EV_READ) ? " read" : "", (what & EV_WRITE) ? " write" : "", (what & EV_SIGNAL) ? " signal" : "")); if (!(EV_READ & what)) { if (EV_TIMEOUT & what) timeout_queries(); return; } /* Read in the packet */ rpktl = recvdata(fd, &sender, &rbuf, sizeof(rbuf)); if (rpktl < 0) { msyslog(LOG_DEBUG, "recvfrom error %m"); return; } if (sock6 == fd) p_pktlist = &v6_pkts_list; else p_pktlist = &v4_pkts_list; for (spkt = *p_pktlist; spkt != NULL; spkt = spkt->link) { psau = &spkt->addr; if (SOCK_EQ(&sender, psau)) break; } if (NULL == spkt) { msyslog(LOG_WARNING, "Packet from unexpected source %s dropped", sptoa(&sender)); return; } TRACE(1, ("sock_cb: %s %s\n", spkt->dctx->name, sptoa(&sender))); rpktl = process_pkt(&r_pkt, &sender, rpktl, MODE_SERVER, &spkt->x_pkt, "sock_cb"); TRACE(2, ("sock_cb: process_pkt returned %d\n", rpktl)); /* If this is a Unicast packet, one down ... */ if (!spkt->done && (CTX_UCST & spkt->dctx->flags)) { dec_pending_ntp(spkt->dctx->name, &spkt->addr); spkt->done = TRUE; } /* If the packet is good, set the time and we're all done */ rc = handle_pkt(rpktl, &r_pkt, &spkt->addr, spkt->dctx->name); if (0 != rc) TRACE(1, ("sock_cb: handle_pkt() returned %d\n", rc)); check_exit_conditions(); }
void *dataio (void *arg) { struct msg_queue wpenq; /* Pendientes de escritura */ struct msg_queue rpenq; /* Pendientes de lectura */ struct msg_queue to_krn; struct msg_queue tmp; struct mb_queue no_sent; struct itc_event_info ieinfo; struct msg *mptr; ssize_t io_ret; int max, ret; fd_set wset, rset; char *where; arg = NULL; itc_block_signal(); init_msg_queue(&wpenq); init_msg_queue(&rpenq); while (1) { FD_ZERO(&wset); FD_ZERO(&rset); /* * Add itc file descriptor */ FD_SET(itc_event, &rset); max = itc_event; /* * Add all sockets scaning read events */ ret = fill_fdset(&rpenq, &rset); max = ( max > ret ) ? max : ret; /* * Add all sockets scaning write envents */ ret = fill_fdset(&wpenq, &wset); max = ( max > ret ) ? max : ret; ret = select_nosignal(max+1, &rset, &wset, NULL, NULL); if (ret == -1) { where = "select_nosignal()"; goto panic; } init_msg_queue(&tmp); init_msg_queue(&to_krn); while ((mptr = msg_dequeue(&wpenq)) != NULL) { if (FD_ISSET(mptr->type.io.io_socket, &wset)) { io_ret = senddata(mptr->type.io.io_socket, &mptr->mb.mbq, &no_sent, DISCARD_TRUE); if (io_ret > 0 && no_sent.size == 0) { mptr->type.io.io_opt = IO_OPT_WRITE; mptr->type.io.io_ret = IO_RET_SUCCESS; mptr->type.io.io_errno = 0; mptr->type.io.io_rep_len += io_ret; mptr->msg_type = MSG_IO_REPLY; msg_enqueue(&to_krn, mptr); } else if ( io_ret == -1 ) { mptr->type.io.io_opt = IO_OPT_WRITE; mptr->type.io.io_ret = IO_RET_FAILURE; mptr->type.io.io_errno = errno; mptr->msg_type = MSG_IO_REPLY; mbuffmove(&(mptr->mb.mbq), &no_sent); msg_enqueue(&to_krn, mptr); } else { mptr->type.io.io_rep_len += io_ret; mbuffmove(&(mptr->mb.mbq), &no_sent); msg_enqueue(&tmp, mptr); } } else msg_enqueue(&tmp, mptr); } msgmove(&wpenq, &tmp); init_msg_queue(&tmp); while ((mptr = msg_dequeue(&rpenq)) != NULL) { if (FD_ISSET(mptr->type.io.io_socket, &rset)) { io_ret = recvdata(mptr->type.io.io_socket, &(mptr->mb.mbq), mptr->type.io.io_req_len, mptr->type.io.io_chunk_size); if (io_ret > 0) { mptr->type.io.io_opt = IO_OPT_READ; mptr->type.io.io_ret = IO_RET_SUCCESS; mptr->type.io.io_errno = 0; mptr->type.io.io_rep_len = io_ret; mptr->msg_type = MSG_IO_REPLY; msg_enqueue(&to_krn, mptr); } else if ( io_ret == -1 ) { mptr->type.io.io_opt = IO_OPT_READ; mptr->type.io.io_ret = IO_RET_FAILURE; mptr->type.io.io_errno = errno; mptr->msg_type = MSG_IO_REPLY; msg_enqueue(&to_krn, mptr); } else { msg_enqueue(&tmp, mptr); } } else msg_enqueue(&tmp, mptr); } msgmove(&rpenq, &tmp); init_msg_queue(&tmp); /* * Look for new request */ if (FD_ISSET(itc_event, &rset)) { ret = itc_read_event(itc_event, &ieinfo); if (ret == -1) { where = "itc_read_event()"; goto panic; } if (ieinfo.src != KERNEL_LAYER_THREAD) { where = "[itc wrong src]"; goto panic; } itc_readfrom(KERNEL_LAYER_THREAD, &tmp, 0); while( (mptr = msg_dequeue(&tmp)) != NULL) { if (mptr->msg_type != MSG_IO_REQUEST) /* Drop silently */ continue; mptr->type.io.io_ret = 0; mptr->type.io.io_errno = 0; mptr->type.io.io_rep_len = 0; if (mptr->type.io.io_opt == IO_OPT_READ) msg_enqueue(&rpenq, mptr); if (mptr->type.io.io_opt == IO_OPT_WRITE) msg_enqueue(&wpenq, mptr); } } /* * Send the reply to the kernel */ if (to_krn.size != 0) itc_writeto(KERNEL_LAYER_THREAD, &to_krn, 0); } panic: PANIC(errno,"DATAIO_LAYER_THREAD",where); return NULL; }
int main(int argc, char *argv[]) { if (argc < 3) { // Checking for correct arquments printf("Useage: dhtnode own_hostname own_port\n"); exit(0); } char* my_url = argv[1]; char* my_port = argv[2]; sha1_t my_hash; // Create hash for own address hash_url(my_url, my_port, my_hash); fd_set master; fd_set rfds; int retval; int running = 1; int listensock = create_listen_socket(my_port); con_t server; memset(&server,0,sizeof server); con_t left; memset(&left,0,sizeof left); con_t right; memset(&right,0,sizeof right); FD_SET(STDIN_FILENO, &master); FD_SET(listensock, &master); int fdmax = listensock; struct timeval looptime; while (running) { looptime.tv_sec = 1; looptime.tv_usec = 0; rfds = master; retval = select(fdmax + 1, &rfds, NULL, NULL, &looptime); if (retval == -1) die("select failed"); else if (retval) { if (FD_ISSET(STDIN_FILENO, &rfds)) { int argcount; char** arguments = NULL; int cmd = getcommand(STDIN_FILENO, &argcount, &arguments); printf("got command\n"); if (cmd < 0) { //TODO handle different errors differently printf("error: %d\n", cmd); exit(-1); } switch (cmd) { case USER_EXIT: if(server.state != ST_EMPTY && (argcount == 0 || strcmp(arguments[0],"force"))){//remember strcmp returns 0 on match printf("trying to exit\n"); send_dht_pckt(server.socket,DHT_DEREGISTER_BEGIN,my_hash,my_hash,0,NULL); } else{ printf("exiting\n"); running = 0; } freeargs(argcount, arguments); break; case USER_CONNECT: if(argcount != 2){ printf("usage: connect url port\n"); freeargs(argcount,arguments); break; } if(server.state != ST_EMPTY){ printf("Already connected to the server. Use exit to disconnect.\n"); freeargs(argcount,arguments); break; } printf("connecting to %s:%s\n", arguments[0], arguments[1]); int sock = create_connection(arguments[0], arguments[1]); printf("connection made\n"); FD_SET(sock, &master); if(sock > fdmax) fdmax = sock; server.socket = sock; server.state = ST_WF_SER_SHAKE; freeargs(argcount, arguments); break; case USER_PRINT: printf("printing...\n"); for(int i = 0; i < argcount; i++){ printf("%s:\n",arguments[i]); if(!strcmp(arguments[i],"sockets")){ printf("server, %d %s\n",server.socket,(server.socket != 0 && FD_ISSET(server.socket,&master))? "is set":"not set"); printf("right, %d %s\n",right.socket,(right.socket != 0 && FD_ISSET(right.socket,&master))? "is set":"not set"); printf("left, %d %s\n",left.socket,(left.socket != 0 && FD_ISSET(left.socket,&master))? "is set":"not set"); } else if(!strcmp(arguments[i],"states")){ printf("server, %d\n",server.state); printf("right, %d\n",right.state); printf("left, %d\n",left.state); } } freeargs(argcount,arguments); break; case USER_UNKNW_CMD: printf("unknown command, line was:"); for (int i = 0; i < argcount; i++) { printf(" %s", arguments[i]); } printf("\n"); freeargs(argcount, arguments); break; } } //check for new connections if (FD_ISSET(listensock, &rfds)) { printf("someone is connecting\n"); if(right.state == ST_EMPTY){ right.socket = accept_connection(listensock); if(right.socket < 0){ die(strerror(errno)); } FD_SET(right.socket, &master); if(right.socket > fdmax) fdmax = right.socket; right.state = ST_WF_CLI_SHAKE; } else if (left.state == ST_EMPTY) { left.socket = accept_connection(listensock); if(left.socket < 0){ die(strerror(errno)); } FD_SET(left.socket, &master); if(left.socket > fdmax) fdmax = left.socket; left.state = ST_WF_CLI_SHAKE; } } //check for msg from server if(server.state != ST_EMPTY && FD_ISSET(server.socket, &rfds)){ int status; if(server.state == ST_WF_SER_SHAKE){ printf("getting shake\n"); status = recvdata(server.socket, NULL); if(status == NTW_SERVER_SHAKE){ printf("shaking back\n"); send_shake(server.socket, NTW_CLIENT_SHAKE); unsigned char formated_url[strlen(my_url)+3]; format_url(my_url, my_port, formated_url); printf("sending DHT_REGISTER_BEGIN\n"); send_dht_pckt(server.socket,DHT_REGISTER_BEGIN,my_hash,my_hash,strlen(my_url)+3,formated_url); server.state = ST_ONLINE; } //TODO error handling /*On correct shake shake back and send DHT_REGISTER_BEGIN with our sha1 as sender and target and our port+url as payload switch state to ST_ONLINE*/ } else{ DHT_t packet; memset(&packet, 0, sizeof packet); status = recvdata(server.socket, &packet); if(status != NTW_PACKET_OK){ switch(status){ case NTW_ERR_SERIOUS: die(strerror(errno)); break; case NTW_DISCONNECT: die("server disconnected"); break; default: printf("getting packet failed somehow\n"); memset(&packet, 0, sizeof packet); break; } } printf("received from server:\n"); print_dht_packet(&packet); //TODO error handling uint16_t reqt = ntohs(packet.req_type); if(server.state == ST_ONLINE && reqt == DHT_REGISTER_FAKE_ACK){ printf("fake ack received\n"); /*send DHT_REGISTER_DONE to server target and sender are both our hash state to ST_IDLING*/ int a = send_dht_pckt(server.socket, DHT_REGISTER_DONE, my_hash, my_hash, 0, NULL); if(a == 0) server.state = ST_IDLING; else exit(1); // or error handling } else if(server.state == ST_IDLING && reqt == DHT_REGISTER_BEGIN){ printf("dht_register_begin received\n"); /*open connection to the new node which port+url is in packet and send data + DHT_REGISTER_ACK our hash sender and target state to ST_WF_REG_DONE*/ char his_url[packet.pl_length-2]; strcpy(his_url,(char*)packet.payload+2); uint16_t* port = (uint16_t*)packet.payload; *port = ntohs(*port); char his_port[10]; sprintf(his_port,"%u",*port); int sock = create_connection(his_url,his_port); FD_SET(sock, &master); if(sock > fdmax) fdmax = sock; con_t* pal; pal = (right.state == ST_EMPTY) ? &right : &left; memcpy(pal->hash,packet.sender,20); pal->socket = sock; pal->state = ST_WF_SER_SHAKE; //server.state = ST_WF_REG_DONE; } else if(server.state == ST_IDLING && reqt == DHT_REGISTER_DONE){ printf("received reg done\n"); //server.state = ST_IDLING; /*dump old data and return to ST_IDLING*/ } else if(server.state == ST_IDLING && reqt == DHT_DEREGISTER_ACK){ printf("dereg ack received\n"); /*open connection to neighbours their urls are as payload of the package and send data and DHT_DEREGISTER_BEGIN (our hash as sender and target) change to ST_WF_DEREG_DONE*/ uint16_t port_buf = ((uint16_t*)packet.payload)[0]; port_buf = ntohs(port_buf); char port1[10]; sprintf(port1,"%u",port_buf); char url1[30]; strcpy(url1,(char*)(packet.payload+2)); port_buf = ((uint16_t*)(packet.payload+3+strlen(url1)))[0]; port_buf = ntohs(port_buf); char port2[10]; sprintf(port2,"%u",port_buf); char url2[30]; strcpy(url2,(char*)(packet.payload+5+strlen(url1))); printf("parsing got:\nurl1 = %s:%s\nurl2 = %s:%s\n", url1, port1, url2, port2); //connect to right neighbour right.socket = create_connection(url1,port1); FD_SET(right.socket, &master); if(right.socket > fdmax) fdmax = right.socket; hash_url(url1,port1,right.hash); right.state = ST_WF_SER_SHAKE; //connect to left neighbour left.socket = create_connection(url2,port2); FD_SET(left.socket, &master); if(left.socket > fdmax) fdmax = left.socket; hash_url(url2,port2,left.hash); left.state = ST_WF_SER_SHAKE; server.state = ST_WF_DEREG_DONE; } else if(server.state == ST_IDLING && reqt == DHT_DEREGISTER_DENY){ printf("dereg deny received\n"); /*tell user that leaving is impossible return to ST_IDLING*/ printf("Unable to exit. You are the last node. To over-ride this use exit force command.\n"); server.state = ST_IDLING; } else if(server.state == ST_WF_DEREG_DONE && reqt == DHT_DEREGISTER_DONE){ if(right.state == ST_DEREG_DATA_SENT && !memcmp(right.hash, packet.sender, 20)){ FD_CLR(right.socket, &master); close(right.socket); memset(&right,0,sizeof right); } else if(left.state == ST_DEREG_DATA_SENT && !memcmp(left.hash, packet.sender, 20)){ FD_CLR(left.socket, &master); close(left.socket); memset(&left,0,sizeof left); } if(left.state == ST_EMPTY && right.state == ST_EMPTY){ printf("leaving the network\n"); close(server.socket); FD_CLR(server.socket, &master); memset(&server,0,sizeof server); printf("left the network\n"); } /*close the connection to server state to ST_EMPTY*/ } } } } for(int i = 0; i<2;i++){ con_t* neighbour = (i == 0) ? &right : &left; //check for msg from right and left neighbour if(neighbour->state != ST_EMPTY && FD_ISSET(neighbour->socket, &rfds)){ int status; if(neighbour->state == ST_WF_CLI_SHAKE){ /* prepare to receive data switch state to ST_RCV_DATA_REG or ST_RCV_DATA_DEREG depending on server state*/ status = recvdata(neighbour->socket, NULL); if(status == NTW_CLIENT_SHAKE){ if(server.state == ST_ONLINE){ neighbour->state = ST_RCV_DATA_REG; } if(server.state == ST_IDLING){ neighbour->state = ST_RCV_DATA_DEREG; } } else { switch(status){ case NTW_ERR_SERIOUS: die(strerror(errno)); break; case NTW_DISCONNECT: printf("%s disconnected\n",(i)?"left":"right"); FD_CLR(neighbour->socket,&master); memset(neighbour,0,sizeof *neighbour); break; default: printf("getting shake failed somehow\n"); break; } } } else if (neighbour->state == ST_WF_SER_SHAKE){ /* answer with client shake and pump your data to the neighbour after that send DHT_REGISTER_ACK or DHT_DEREG_BEGIN either way after this the connection to neighbour can be disconnected*/ status = recvdata(neighbour->socket, NULL); if(status == NTW_SERVER_SHAKE){ printf("shaking back\n"); send_shake(neighbour->socket, NTW_CLIENT_SHAKE); if(server.state == ST_IDLING){ //we should end with DHT_REGISTER_ACK send_dht_pckt(neighbour->socket,DHT_REGISTER_ACK,my_hash,my_hash,0,NULL); FD_CLR(neighbour->socket, &master); close(neighbour->socket); memset(neighbour,0,sizeof *neighbour); } if(server.state == ST_WF_DEREG_DONE){ //we should end with DHT_DEREGISTER_BEGIN send_dht_pckt(neighbour->socket,DHT_DEREGISTER_BEGIN,my_hash,my_hash,0,NULL); FD_CLR(neighbour->socket, &master); close(neighbour->socket); neighbour->state = ST_DEREG_DATA_SENT; } } else { switch(status){ case NTW_ERR_SERIOUS: die(strerror(errno)); break; case NTW_DISCONNECT: die("neighbour disconnected"); break; default: printf("getting shake failed somehow\n"); break; } } } else{ DHT_t packet; memset(&packet, 0, sizeof packet); status = recvdata(neighbour->socket, &packet); printf("received package from %s:\n",(i)?"left":"right"); print_dht_packet(&packet); if(status != NTW_PACKET_OK){ switch(status){ case NTW_ERR_SERIOUS: die(strerror(errno)); break; case NTW_DISCONNECT: printf("%s neighbour disconnected.\n",(i)?"left":"right"); FD_CLR(neighbour->socket,&master); close(neighbour->socket); memset(neighbour,0,sizeof * neighbour); break; case NTW_ERR_TIMEOUT: printf("package from %s timed out!\n",(i)?"left":"right"); memset(&packet,0,sizeof packet); break; } } uint16_t reqt = ntohs(packet.req_type); if(neighbour->state == ST_RCV_DATA_REG && reqt == DHT_REGISTER_ACK){ /*all data is now received */ FD_CLR(neighbour->socket, &master); close(neighbour->socket); memset(neighbour,0,sizeof *neighbour); neighbour->state = ST_REG_DATA_RCVD; if(right.state == ST_REG_DATA_RCVD && left.state == ST_REG_DATA_RCVD){ send_dht_pckt(server.socket, DHT_REGISTER_DONE, my_hash, my_hash, 0, NULL); right.state = ST_EMPTY; left.state = ST_EMPTY; server.state = ST_IDLING; } } else if(neighbour->state == ST_RCV_DATA_DEREG && reqt == DHT_DEREGISTER_BEGIN){ send_dht_pckt(server.socket, DHT_DEREGISTER_DONE, packet.sender, my_hash, 0, NULL); FD_CLR(neighbour->socket, &master); close(neighbour->socket); memset(neighbour,0,sizeof *neighbour); } } } } } close(listensock); return 0; }
/* Fetch data, check if it's data for us and whether it's useable or not. If not, return * a failure code so we can delete this server from our list and continue with another one. */ int recvpkt ( SOCKET rsock, struct pkt *rpkt, struct pkt *spkt ) { sockaddr_u sender; char *rdata /* , done */; register int a; int has_mac, is_authentic, pkt_len, orig_pkt_len; /* Much space, just to be sure */ rdata = emalloc(sizeof(char) * 256); pkt_len = recvdata(rsock, &sender, rdata, 256); #if 0 /* done uninitialized */ if (!done) { /* Do something about it, first check for a maximum length of ntp packets, * probably that's something we can avoid */ } #endif if (pkt_len < 0) { if (ENABLED_OPT(NORMALVERBOSE)) { printf("sntp recvpkt failed: %d.\n", pkt_len); } free(rdata); return pkt_len; } /* Some checks to see if that packet is intended for us */ /* No MAC, no authentication */ if (LEN_PKT_NOMAC == pkt_len) has_mac = 0; /* If there's more than just the NTP packet it should be a MAC */ else if (pkt_len > LEN_PKT_NOMAC) has_mac = pkt_len - LEN_PKT_NOMAC; else { if (ENABLED_OPT(NORMALVERBOSE)) printf("sntp recvpkt: Funny packet length: %i. Discarding package.\n", pkt_len); free(rdata); return PACKET_UNUSEABLE; } /* Packet too big */ if (pkt_len > LEN_PKT_MAC) { if (ENABLED_OPT(NORMALVERBOSE)) printf("sntp recvpkt: Received packet is too big (%i bytes), trying again to get a useable packet\n", pkt_len); free(rdata); return PACKET_UNUSEABLE; } orig_pkt_len = pkt_len; pkt_len = min(pkt_len, sizeof(struct pkt)); for (a = 0; a < pkt_len; a++) /* FIXME! */ if (a < orig_pkt_len) ((char *) rpkt)[a] = rdata[a]; else ((char *) rpkt)[a] = 0; free(rdata); rdata = NULL; /* MAC could be useable for us */ if (has_mac) { /* Two more things that the MAC must conform to */ if(has_mac > MAX_MAC_LEN || has_mac % 4 != 0) { is_authentic = 0; /* Or should we discard this packet? */ } else { if (MAX_MAC_LEN == has_mac) { struct key *pkt_key = NULL; /* * Look for the key used by the server in the specified keyfile * and if existent, fetch it or else leave the pointer untouched */ get_key(rpkt->mac[0], &pkt_key); /* Seems like we've got a key with matching keyid */ if (pkt_key != NULL) { /* * Generate a md5sum of the packet with the key from our keyfile * and compare those md5sums */ if (!auth_md5((char *) rpkt, has_mac, pkt_key)) { if (ENABLED_OPT(AUTHENTICATION)) { /* We want a authenticated packet */ if (ENABLED_OPT(NORMALVERBOSE)) { char *hostname = ss_to_str(&sender); printf("sntp recvpkt: Broadcast packet received from %s is not authentic. Will discard this packet.\n", hostname); free(hostname); } return SERVER_AUTH_FAIL; } else { /* * We don't know if the user wanted authentication so let's * use it anyways */ if (ENABLED_OPT(NORMALVERBOSE)) { char *hostname = ss_to_str(&sender); printf("sntp recvpkt: Broadcast packet received from %s is not authentic. Authentication not enforced.\n", hostname); free(hostname); } is_authentic = 0; } } else { /* Yay! Things worked out! */ if (ENABLED_OPT(NORMALVERBOSE)) { char *hostname = ss_to_str(&sender); printf("sntp recvpkt: Broadcast packet received from %s successfully authenticated using key id %i.\n", hostname, rpkt->mac[0]); free(hostname); } is_authentic = 1; } } } } } /* Check for server's ntp version */ if (PKT_VERSION(rpkt->li_vn_mode) < NTP_OLDVERSION || PKT_VERSION(rpkt->li_vn_mode) > NTP_VERSION) { if (ENABLED_OPT(NORMALVERBOSE)) printf("sntp recvpkt: Packet got wrong version (%i)\n", PKT_VERSION(rpkt->li_vn_mode)); return SERVER_UNUSEABLE; } /* We want a server to sync with */ if (PKT_MODE(rpkt->li_vn_mode) != MODE_SERVER && PKT_MODE(rpkt->li_vn_mode) != MODE_PASSIVE) { if (ENABLED_OPT(NORMALVERBOSE)) printf("sntp recvpkt: mode %d stratum %i\n", PKT_MODE(rpkt->li_vn_mode), rpkt->stratum); return SERVER_UNUSEABLE; } /* Stratum is unspecified (0) check what's going on */ if (STRATUM_PKT_UNSPEC == rpkt->stratum) { char *ref_char; if (ENABLED_OPT(NORMALVERBOSE)) printf("sntp recvpkt: Stratum unspecified, going to check for KOD (stratum: %i)\n", rpkt->stratum); ref_char = (char *) &rpkt->refid; if (ENABLED_OPT(NORMALVERBOSE)) printf("sntp recvpkt: Packet refid: %c%c%c%c\n", ref_char[0], ref_char[1], ref_char[2], ref_char[3]); /* If it's a KOD packet we'll just use the KOD information */ if (ref_char[0] != 'X') { if (!strncmp(ref_char, "DENY", 4)) return KOD_DEMOBILIZE; if (!strncmp(ref_char, "RSTR", 4)) return KOD_DEMOBILIZE; if (!strncmp(ref_char, "RATE", 4)) return KOD_RATE; /* There are other interesting kiss codes which might be interesting for authentication */ } } /* If the server is not synced it's not really useable for us */ if (LEAP_NOTINSYNC == PKT_LEAP(rpkt->li_vn_mode)) { if (ENABLED_OPT(NORMALVERBOSE)) printf("sntp recvpkt: Server not in sync, skipping this server\n"); return SERVER_UNUSEABLE; } /* * Decode the org timestamp and make sure we're getting a response * to our last request. */ #ifdef DEBUG printf("rpkt->org:\n"); l_fp_output(&rpkt->org, stdout); printf("spkt->xmt:\n"); l_fp_output(&spkt->xmt, stdout); #endif if (!L_ISEQU(&rpkt->org, &spkt->xmt)) { if (ENABLED_OPT(NORMALVERBOSE)) printf("sntp recvpkt: pkt.org and peer.xmt differ\n"); return PACKET_UNUSEABLE; } return pkt_len; }
int networkthink() { char netrecbuffer[NETBUFFER_SIZE]; int msgsize = 0; unsigned short port = 0; char charip[25] = { 0 }; char*worked = net.Receive(&msgsize, &port, charip, netrecbuffer, NETBUFFER_SIZE); if (!msgsize) return 0; if (!strstr(serverip, charip)) { printf("ip mismatch??\n"); return 0; } bf_read recvdata(netrecbuffer, msgsize); int header = recvdata.ReadLong(); int connection_less = 0; if (header == NET_HEADER_FLAG_QUERY) connection_less = 1; if (header == NET_HEADER_FLAG_SPLITPACKET) { printf("SPLIT\n"); if (!netchan->HandleSplitPacket(netrecbuffer, msgsize, recvdata)) return 0; header = recvdata.ReadLong(); } if (header == NET_HEADER_FLAG_COMPRESSEDPACKET) { unsigned int uncompressedSize = msgsize * 16; char*tmpbuffer = new char[uncompressedSize]; memmove(netrecbuffer, netrecbuffer + 4, msgsize + 4); NET_BufferToBufferDecompress(tmpbuffer, uncompressedSize, netrecbuffer, msgsize); memcpy(netrecbuffer, tmpbuffer, uncompressedSize); recvdata.StartReading(netrecbuffer, uncompressedSize, 0); printf("."); delete[] tmpbuffer; tmpbuffer = 0; } recvdata.Reset(); if (connection_less) { return HandleConnectionLessPacket(charip, port, connection_less, recvdata); } int flags = netchan->ProcessPacketHeader(msgsize, recvdata); if (flags == -1) { printf("Malformed package!\n"); return 0; } last_packet_received = clock(); if (flags & PACKET_FLAG_RELIABLE) { int i = 0; int bit = recvdata.ReadUBitLong(3); bit = 1 << bit; for (i = 0; i<MAX_STREAMS; i++) { if (recvdata.ReadOneBit() != 0) { if (!netchan->ReadSubChannelData(recvdata, i)) { return 0; } } } FLIPBIT(netchan->m_nInReliableState, bit); for (i = 0; i<MAX_STREAMS; i++) { if (!netchan->CheckReceivingList(i)) { return 0; } } } if (recvdata.GetNumBitsLeft() > 0) { int proc = ProcessMessages(recvdata); } static bool neededfragments = false; if (netchan->NeedsFragments() || flags&PACKET_FLAG_TABLES) { neededfragments = true; NET_RequestFragments(); } return 0; }