void cache_send_reply(struct cache_data *pcache,struct cs_cachepeer_data *peer) { uchar buf[64]; //Common Data buf[0] = TYPE_REPLY; buf[1] = pcache->tag; buf[2] = pcache->sid>>8; buf[3] = pcache->sid; buf[4] = pcache->onid>>8; buf[5] = pcache->onid&0xff; buf[6] = pcache->caid>>8; buf[7] = pcache->caid; buf[8] = pcache->hash>>24; buf[9] = pcache->hash>>16; buf[10] = pcache->hash>>8; buf[11] = pcache->hash; buf[12] = pcache->tag; // if (pcache->status==CACHE_STAT_WAIT) sendtopeer(peer, buf, 13); // Failed // else { if (pcache->status==CACHE_STAT_DCW) { //peer->sentrep++; // <1:type> <1:ecmtag> <2:sid> <2:onid> <2:caid> <4:hash> <1:ecmtag> <16dcw> <2:connector namelen> <n:connector name> memcpy( buf+13, pcache->cw, 16); // Connector name //buf[29] = 0; buf[30] = strlen(cs->name); memcpy(buf+31, cs->name, strlen(cs->name) ); sendtopeer(peer, buf, 29); } }
void cache_send_request(struct cache_data *pcache,struct cs_cachepeer_data *peer) { uchar buf[32]; //16 por defecto //01 80 00CD 0001 0500 8D1DB359 buf[0] = TYPE_REQUEST; buf[1] = pcache->tag; buf[2] = pcache->sid>>8; buf[3] = pcache->sid; buf[4] = pcache->onid>>8; buf[5] = pcache->onid&0xff; buf[6] = pcache->caid>>8; buf[7] = pcache->caid; buf[8] = pcache->hash>>24; buf[9] = pcache->hash>>16; buf[10] = pcache->hash>>8; buf[11] = pcache->hash; //peer->sentreq++; sendtopeer(peer, buf, 12); //*debugf(" [CACHE] >> Cache Request to (%s:%d) %04x:%04x:%08x\n", peer->host->name, peer->port, pcache->caid,pcache->sid,pcache->hash); }
void cache_send_ping(struct cs_cachepeer_data *peer) { // 03 00 00 01 2F EE B1 CB 54 00 00 D8 03 unsigned char buf[128]; //32 default struct timeval tv; gettimeofday( &tv, NULL ); buf[0] = TYPE_PINGREQ; // Self Program Use buf[1] = 0; buf[2] = 0; buf[3] = 0; // ping packet number buf[4] = peer->id>>8; buf[5] = peer->id&0xff; // Multics Identification buf[6] = 0; // unused must be zero (for next use) buf[7] = 'N'^buf[1]^buf[2]^buf[3]^buf[4]^buf[5]^buf[6]; // Multics Checksum buf[8] = 'N'; // Multics ID //Port buf[9] = 0; buf[10] = 0; buf[11] = cfg.cacheport>>8; buf[12] = cfg.cacheport&0xff; //Program buf[13] = 0x01; //ID buf[14] = 7; //LEN buf[15] = 'N'; buf[16] = 'e'; buf[17] = 'w'; buf[18] = 'B'; buf[19] = 'o'; buf[20] = 'x'; buf[21] = 0; //Version buf[22] = 0x02; //ID buf[23] = 3; //LEN buf[24] = 'v'; buf[25] = '0'+(REVISION/10); buf[26] = '0'+(REVISION%10); buf[27] = 0; buf[28] = 0; sendtopeer( peer, buf, 29); }
void cache_send_resendreq(struct cache_data *pcache,struct cs_cachepeer_data *peer) { // <1:TYPE_RESENDREQ> <2:port> <1:ecmtag> <2:sid> <2:onid> <2:caid> <4:hash> uchar buf[64]; buf[0] = TYPE_RESENDREQ; //Port buf[1] = 0; buf[2] = 0; buf[3] = cfg.cacheport>>8; buf[4] = cfg.cacheport&0xff; buf[5] = pcache->tag; buf[6] = pcache->sid>>8; buf[7] = pcache->sid; buf[8] = pcache->onid>>8; buf[9] = pcache->onid&0xff; buf[10] = pcache->caid>>8; buf[11] = pcache->caid; buf[12] = pcache->hash>>24; buf[13] = pcache->hash>>16; buf[14] = pcache->hash>>8; buf[15] = pcache->hash; sendtopeer(peer, buf, 16); }
//#include <termios.h> void *com_handler(void * peer){ struct peer* pinf = (struct peer*) peer; struct peer p; p.socket = pinf->socket; // creating a local copy of the peer object p.ip = pinf->ip; struct peer * pp = nw_get(p); printf("Peer connected (ip %lu socket %i).\n", pinf->ip, pinf->socket); struct msg newpeermsg = {.msgtype = OPCODE_NEWPEER,.from = p.ip,}; handle_msg(newpeermsg, 0); char recv_msg[MAXRECVSIZE]; int read_size; struct timeval ctime, ptime, ttime; gettimeofday(&ttime,0); /* Set non-blocking state */ int flags; if (-1 == (flags = fcntl(pinf->socket, F_GETFL, 0))){ flags = 0; } fcntl(p.socket, F_SETFL, flags | O_NONBLOCK); char * string = calloc(MAXRECVSIZE,1); char * cjsonstr = calloc(MAXRECVSIZE,1); /** Normal operating mode **/ while(1){ /** Maintain connection by passing and receiving I'm alive **/ gettimeofday(&ctime, 0); if((ctime.tv_usec - ptime.tv_usec) >= IMALIVE_UPPERIOD || (ctime.tv_usec<ptime.tv_usec)){ struct msg packet = { .msgtype = OPCODE_IMALIVE,}; char * cout = pack(packet); send(p.socket, cout, strlen(cout), 0); gettimeofday(&ptime, 0); } /** Receive data **/ read_size = recv(pinf->socket, recv_msg, MAXRECVSIZE, 0); if(read_size <= 0){ // ERROR/RECOVERY mode if(read_size == 0){ printf("Peer disconnected (ip %lu socket %i).\n", pinf->ip, pinf->socket); break; } else if((read_size==-1) ){ if( (errno != EAGAIN) && (errno != EWOULDBLOCK) ) { printf("Peer disconnected (ip %lu socket %i).\n", pinf->ip, pinf->socket); break; } } else{ 0;// Did not receive anything, but no error } } else { // Received something strcpy(string, recv_msg); string[read_size]='\0'; int start_i = 0; int end_i = cjsonendindex(string, start_i); /* Separate packets arriving together */ while(end_i<(strlen(string)-1)){ strncpy(cjsonstr, (string+start_i), (end_i-start_i+1)); cjsonstr[end_i-start_i+1] = '\0'; struct msg packetin = unpack(cjsonstr); packetin.from = p.ip; handle_msg(packetin, &ttime); start_i = end_i+1; end_i = cjsonendindex(string, start_i); } if(end_i!=-1){ strncpy(cjsonstr, (string+start_i), (end_i-start_i+1)); cjsonstr[end_i-start_i+1] = '\0'; struct msg packetin = unpack(cjsonstr); packetin.from = p.ip; handle_msg(packetin, &ttime); } } // tcflush(p.socket, TCIOFLUSH); /** Check for timeout **/ gettimeofday(&ctime, 0); if((ctime.tv_sec-ttime.tv_sec) > IMALIVE_TIMEOUT){ printf("Timeout on I'm alive, socket: %i\n", pinf->socket); break; } /** Send data **/ struct msg elem; while(!cbIsEmpty(&pp->bufout)){ // Send data from buffer cbRead(&pp->bufout, &elem); if (elem.msgtype!=OPCODE_CORRUPT){ char * cout = pack(elem); send(pinf->socket, cout, strlen(cout), 0); free(cout); } } } /** Recovery mode: **/ free(cjsonstr); free(string); nw_rm(p); nw_setevent(DISCONNECTION); struct msg recovermsg = { .from = p.ip, .to = highest_ip()}; if(recovermsg.to == root->p.ip){ // I have the highest ip on the network and should take over orders recovermsg.msgtype = OPCODE_PEERLOSTTAKEOVER; } else{ recovermsg.msgtype = OPCODE_PEERLOST; } handle_msg(recovermsg, 0); close(p.socket); pthread_exit(0); } int sendtoallpeer(struct msg package){ struct peer p = { .ip = TOALLIP }; return sendtopeer(package, p); } int sendtopeer(struct msg package, struct peer p){ struct nw_node * iter; iter = root; iter = iter->next; while(iter!=0){ if((iter->p.ip) == p.ip || p.ip == TOALLIP){ struct peer * pp = nw_get(iter->p); cbWrite(&pp->bufout, &package); } iter = iter->next; } return 1; } int connect_to_peer(in_addr_t peer_ip){ int peer_socket = socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in peer; peer.sin_family = AF_INET; peer.sin_addr.s_addr = peer_ip; peer.sin_port = htons(LISTEN_PORT); // Connect to listen port. if (connect(peer_socket, (struct sockaddr *)&peer , sizeof(peer)) < 0){ perror("err: connect. Connecting to peer failed\n"); return -1; } struct peer p = peer_object(peer_socket, peer_ip); nw_add(p); assign_com_thread(p); return 1; } void assign_com_thread(struct peer p){ // We have a connection! Now assign a communication handler thread. struct peer *pinf = malloc(sizeof(struct peer)); pinf->socket = p.socket; pinf->ip = p.ip; if( pthread_create( &pinf->com_thread , NULL , com_handler , pinf)<0){ perror("err: pthread_create\n"); exit(1); } } /* \!brief Listen for TCP connections and accept incoming. * */ void *listen_tcp(){ int opt = TRUE; struct sockaddr_in listen_addr; listen_addr.sin_family = AF_INET; listen_addr.sin_port = htons(LISTEN_PORT); listen_addr.sin_addr.s_addr = htons(INADDR_ANY); // Binding local IP-address listen_socket = socket(AF_INET, SOCK_STREAM, 0); if (setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, (char*)&opt, sizeof(opt)) == -1){ perror("err: setsockopt\n"); exit(1); } if ( bind(listen_socket, (struct sockaddr *)&listen_addr, sizeof listen_addr) == -1){ perror("err: bind\n"); exit(1); } struct sockaddr_in peer; int new_peer_socket, structsize; structsize = sizeof(struct sockaddr_in); while(1){ listen(listen_socket, LISTEN_BACKLOG); if ( (new_peer_socket = accept(listen_socket, (struct sockaddr *)&peer, (socklen_t*)&structsize)) == -1 ){ perror("err: accept\n"); exit(1); } struct peer newpeer = peer_object(new_peer_socket, peer.sin_addr.s_addr); if(!nw_find(newpeer)){ nw_add(newpeer); assign_com_thread(newpeer); nw_setevent(CONNECTION); } else{ // Already in connected list close(new_peer_socket); } } }