Пример #1
0
//-----------------------------------------------
// to_s
//-----------------------------------------------
char* streamkey_to_s(char *dest, stream_key_t *key)
{
  uint16_t sport, dport;

  if (0) //pkt_is_v6(pkt))
  {
    sprintf(dest, "IPV6 STREAM HERE");
    //sprintf(dest, "%s_%s_%d_%s_%d", get_proto_name(pkt->ip6.ip_p),"?:?:?",sport, "?:?:?", dport);
    return dest;
  }
  else
  {
    char leftip[16], rightip[16];
    ip2string(leftip, GET_LEFT(key));
    ip2string(rightip, GET_RIGHT(key));

    sprintf(dest, "%s_%s_%d_%s_%d", get_proto_name(key->v4.ipproto), leftip, key->v4.lport, rightip, key->v4.rport);
    return dest;
  }

}
Пример #2
0
void frcc_sendcards_cli(struct cc_client_data *cli)
{
	int nbcard=0;
	struct cardserver_data *cs = cfg.cardserver;

	int i;
	if (cfg.freecccam.csport[0]) {
		for(i=0;i<MAX_CSPORTS;i++) {
			if(cfg.freecccam.csport[i]) {
				cs = getcsbyport(cfg.freecccam.csport[i]);
				if (cs)
					if (cc_sendcard_cli(cs, cli,0)) nbcard++;
			} else break;
		}
	}
	else {
		while (cs) {
			if (cc_sendcard_cli(cs, cli,0)) nbcard++;
			cs = cs->next;
		}
	}

	debugf(" FreeCCcam: %d cards --> client(%s)\n",  nbcard, ip2string(cli->ip) );
}
Пример #3
0
void *th_cs_connect_cli(struct cs_clicon *param)
{
    char passwdcrypt[120];
	unsigned char keymod[14];
	int i,index;
	unsigned char sessionkey[16];
	struct cs_custom_data clicd;
	unsigned char buf[CWS_NETMSGSIZE];

	struct cardserver_data *cs = param->cs;
	int sock = param->sock;
	uint32 ip = param->ip;
	free(param);
	// Create random deskey
	for (i=0; i<14; i++) keymod[i] = 0xff & rand();
	// Create NewBox ID
	keymod[3] = (keymod[0]^'N') + keymod[1] + keymod[2];
	keymod[7] = keymod[4] + (keymod[5]^'B') + keymod[6];
	keymod[11] = keymod[8] + keymod[9] + (keymod[10]^'x');

//STAT: SEND RND KEY
	// send random des key

	if (send_nonb(sock, keymod, 14, 500)<=0) {
		debugf(" ERR SEND\n");
		close(sock);
		pthread_exit(NULL);
	}

	uint32 ticks = GetTickCount();
	// Calc SessionKey
	//debugf(" DES Key: "); debughex(keymod,14);
	des_login_key_get(keymod, cs->key, 14, sessionkey);
	//debugf(" Login Key: "); debughex(sessionkey,16);

//md5_crypt("pass", "$1$abcdefgh$",passwdcrypt);
//debugf(" passwdcrypt = %s\n",passwdcrypt);

//STAT: LOGIN INFO
	// 3. login info
	i = cs_message_receive(sock, &clicd, buf, sessionkey,3000);
	if (i<=0) {
		if (i==-2) debugf(" %s: (%s) new connection closed, wrong des key\n", cs->name, ip2string(ip));
		else debugf(" %s: (%s) new connection closed, receive timeout\n", cs->name, ip2string(ip));
		close(sock);
		pthread_exit(NULL);
	}

	ticks = GetTickCount()-ticks;
	if (buf[0]!=MSG_CLIENT_2_SERVER_LOGIN) {
		close(sock);
		pthread_exit(NULL);
	}

	// Check username length
	if ( strlen( (char*)buf+3 )>63 ) {
		/*
		buf[0] = MSG_CLIENT_2_SERVER_LOGIN_NAK;
		buf[1] = 0;
		buf[2] = 0;
		cs_message_send(sock, NULL, buf, 3, sessionkey);
		*/
		debugf(" %s: (%s) new connection closed, wrong username length\n", cs->name, ip2string(ip));
		close(sock);
		pthread_exit(NULL);
	}

	pthread_mutex_lock(&prg.lockcli);
	index = 3;
	struct cs_client_data *usr = cs->client;
	int found = 0;
	while (usr) {
		if (!strcmp(usr->user,(char*)&buf[index])) {
			found=1;
			break;
		}
		usr = usr->next;
	}
	if (!found) {
		pthread_mutex_unlock(&prg.lockcli);
		buf[0] = MSG_CLIENT_2_SERVER_LOGIN_NAK;
		buf[1] = 0;
		buf[2] = 0;
		//cs_message_send(sock, NULL, buf, 3, sessionkey);
		debugf(" %s: (%s) new connection closed, unknown user '%s'\n", cs->name, ip2string(ip), &buf[3]);
		close(sock);
		pthread_exit(NULL);
	}

	// Check password
	index += strlen(usr->user) +1;
	__md5_crypt(usr->pass, "$1$abcdefgh$",passwdcrypt);
	if (!strcmp(passwdcrypt,(char*)&buf[index])) {
		//Check Reconnection
		if (usr->handle!=INVALID_SOCKET) {
			debugf(" %s: user already connected '%s' (%s)\n", cs->name, usr->user, ip2string(ip));
			cs_disconnect_cli(usr);
		}
		// Store program id
		usr->progid = clicd.sid;
		//
		buf[0] = MSG_CLIENT_2_SERVER_LOGIN_ACK;
		buf[1] = 0;
		buf[2] = 0;
		// Send NewBox Id&Version
		if (clicd.provid==0x0057484F) { // WHO 
			clicd.provid = 0x004E4278; // MBx
			clicd.sid = REVISION; // Revision
			cs_message_send(sock, &clicd, buf, 3, sessionkey);
		} else cs_message_send(sock, NULL, buf, 3, sessionkey);
		des_login_key_get( cs->key, (unsigned char*)passwdcrypt, strlen(passwdcrypt),sessionkey);
		memcpy( &usr->sessionkey, &sessionkey, 16);
		// Setup User data
		usr->handle = sock;
		usr->ip = ip;
		usr->ping = ticks;
		usr->lastecmtime = GetTickCount();
		usr->ecm.busy=0;
		usr->ecm.recvtime=0;
		usr->connected = GetTickCount();
		usr->chkrecvtime = 0;
		debugf(" %s: client '%s' connected (%s)\n", cs->name, usr->user, ip2string(ip));
		pipe_wakeup( srvsocks[1] );
	}
	else {
		// send NAK
		buf[0] = MSG_CLIENT_2_SERVER_LOGIN_NAK;
		buf[1] = 0;
		buf[2] = 0;
		//cs_message_send(sock, NULL, buf, 3, sessionkey);
		debugf(" newcamd: client '%s' wrong password (%s)\n", usr->user, ip2string(ip));
		close(sock);
	}
	pthread_mutex_unlock(&prg.lockcli);
	pthread_exit(NULL);
}
Пример #4
0
static string v2s(uint32_t version_no){
	return ip2string(version_no);
}
Пример #5
0
int main(int argc, char *argv[])
{
	int listenfd;
	struct sockaddr_in serv_addr;

	listenfd = socket(AF_INET, SOCK_STREAM, 0);
	if (listenfd < 0) {
		printf("Unable to open socket: %d (%s)\n", errno, strerror(errno));
		return 1;
	}

	serv_addr.sin_family = AF_INET;
	serv_addr.sin_addr.s_addr = INADDR_ANY;
	serv_addr.sin_port = htons(60002);

	if (bind(listenfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
		printf("Unable to bind address: %d (%s)\n", errno, strerror(errno));
		return 1;
	}

	listen(listenfd,5);

	if (fork())
		exit(0);
	setsid();
	if (fork())
		exit(0);

	std::vector<Client> clients;

	while (true) {
		fd_set rfds, wfds;
		FD_ZERO(&rfds);
		FD_ZERO(&wfds);
		int maxfd = 0;
		if (clients.size() < MAX_CLIENTS) {
			FD_SET(listenfd, &rfds);
			maxfd = listenfd;
		}
		for (auto it = clients.begin(), eit = clients.end(); it != eit; ++it) {
			if (it->write_ready()) {
				FD_SET(it->fd, &wfds);
				if (maxfd < it->fd)
					maxfd = it->fd;
			}
			if (it->read_ready()) {
				FD_SET(it->fd, &rfds);
				if (maxfd < it->fd)
					maxfd = it->fd;
			}
		}

		if (select(maxfd+1, &rfds, &wfds, NULL, NULL) < 0) {
			if (errno == EINTR)
				continue;

			syslog(LOG_ERR, "Error in select(): %m");
			break;
		}

		// Process any existing connections.
		for (auto it = clients.begin(), eit = clients.end(); it != eit; ++it) {
			if (FD_ISSET(it->fd, &rfds) || FD_ISSET(it->fd, &wfds))
				it->run_io();
		}

		// Accept New Connections
		if (FD_ISSET(listenfd, &rfds)) {
			struct sockaddr_in client_addr;
			socklen_t client_addr_len = sizeof(client_addr);
			int clientfd = accept(listenfd, reinterpret_cast<struct sockaddr*>(&client_addr), &client_addr_len);

#ifdef IP_ACL_FILE
			if (authorize_ip(ntohl(client_addr.sin_addr.s_addr))) {
#endif
				clients.emplace_back(clientfd);
#ifdef IP_ACL_FILE
			}
			else {
				close(clientfd);
				char ipaddr[16];
				ip2string(ntohl(client_addr.sin_addr.s_addr), ipaddr, 16);
				syslog(LOG_NOTICE, "Connection attempted from unauthorized IP: %s", ipaddr);
			}
#endif
		}
	}
	return 1;
}
Пример #6
0
void *freecc_connect_cli(struct struct_clicon *param)
{
	uint8 buf[CC_MAXMSGSIZE];
	uint8 data[16];
	int i;
	struct cc_crypt_block sendblock;	// crypto state block
	struct cc_crypt_block recvblock;	// crypto state block
	char usr[64];
	char pwd[255];

	int sock = param->sock;
	uint32 ip = param->ip;
	free(param);

	memset(usr, 0, sizeof(usr));
	memset(pwd, 0, sizeof(pwd));
	// create & send random seed
	for(i=0; i<12; i++ ) data[i]=fast_rnd();
	// Create Multics ID
	data[3] = (data[0]^'M') + data[1] + data[2];
	data[7] = data[4] + (data[5]^'C') + data[6];
	data[11] = data[8] + data[9] + (data[10]^'S');
	//Create checksum for "O" cccam:
	for (i = 0; i < 4; i++) {
		data[12 + i] = (data[i] + data[4 + i] + data[8 + i]) & 0xff;
	}
	send_nonb(sock, data, 16, 100);
	//XOR init bytes with 'CCcam'
	cc_crypt_xor(data);
	//SHA1
	SHA_CTX ctx;
	SHA1_Init(&ctx);
	SHA1_Update(&ctx, data, 16);
	SHA1_Final(buf, &ctx);
	//initialisate crypto states
	cc_crypt_init(&sendblock, buf, 20);
	cc_decrypt(&sendblock, data, 16);
	cc_crypt_init(&recvblock, data, 16);
	cc_decrypt(&recvblock, buf, 20);
	//debugdump(buf, 20, "SHA1 hash:");
	memcpy(usr,buf,20);
	if ((i=recv_nonb(sock, buf, 20,3000)) == 20) {
		cc_decrypt(&recvblock, buf, 20);
		//debugdump(buf, 20, "Recv SHA1 hash:");
		if ( memcmp(buf,usr,20)!=0 ) {
			//debugf(" cc_connect_cli(): wrong sha1 hash from client! (%s)\n",ip2string(ip));
			close(sock);
			return NULL;
		}
	} else {
		//debugf(" cc_connect_cli(): recv sha1 timeout\n");
		close(sock);
		return NULL;
	}

  // receive username
	if ((i=recv_nonb(sock, buf, 20,3000)) == 20) {
		cc_decrypt(&recvblock, buf, i);
		memcpy(usr,buf,20);
		//debugf(" cc_connect_cli(): username '%s'\n", usr);
	}
	else {
		//debugf(" cc_connect_cli(): recv user timeout\n");
		close(sock);
		return NULL;
	}


  // Check for username
	pthread_mutex_lock(&prg.lockfreecccli);
	int found = 0;
	struct cc_client_data *cli = cfg.freecccam.client;
	while (cli) {
		if (!strcmp(cfg.freecccam.user,usr)) {
			if (cli->handle<=0) {
				found = 1;
				break;
			}
			else {
				if (cli->ip == ip) { // dont connect
					cc_disconnect_cli(cli);
					found = 1;
					break;
				}
			}
		}
		cli = cli->next;
	}
	if (!found)
	while (cli) {
		if (!strcmp(cfg.freecccam.user,usr)) {
			if (cli->handle>0) {
				// Check if we can disconnect idle state clients
				if  (GetTickCount()-cli->lastecmtime > 100000) cc_disconnect_cli(cli);
			}
			if (cli->handle<=0) {
				found = 1;
				break;
			}
		}
		cli = cli->next;
	}
	pthread_mutex_unlock(&prg.lockfreecccli);

	if (!found) {
		debugf(" FreeCCcam: Failed to connect new client(%s)\n",ip2string(ip));
		close(sock);
		return NULL;
	}

  // receive passwd / 'CCcam'
	strcpy( pwd, cfg.freecccam.pass);
	cc_decrypt(&recvblock, (uint8*)pwd, strlen(pwd));
	if ((i=recv_nonb(sock, buf, 6,3000)) == 6) {
		cc_decrypt(&recvblock, buf, 6);
		if (memcmp( buf+1, "Ccam\0",5)) {
			debugf(" FreeCCcam: login failed from client(%s)\n",ip2string(ip));
			close(sock);
			return NULL;
		}
	} 
	else {
		close(sock);
		return NULL;
	}

  // send passwd ack
	memset(buf, 0, 20);
	memcpy(buf, "CCcam\0", 6);
	//debugf("Server: send ack '%s'\n",buf);
	cc_encrypt(&sendblock, buf, 20);
	send_nonb(sock, buf, 20, 100);

	sprintf(cli->user,"%s", ip2string(ip));
	//cli->ecmnb=0;
	//cli->ecmok=0;
	memcpy(&cli->sendblock,&sendblock,sizeof(sendblock));
	memcpy(&cli->recvblock,&recvblock,sizeof(recvblock));
	debugf(" FreeCCcam: client(%s) connected\n",ip2string(ip));

  // recv cli data
	memset(buf, 0, sizeof(buf));
	i = cc_msg_recv( sock, &cli->recvblock, buf, 3000);
	if (i!=97) {
		debug("error recv cli data\n");
		close(sock);
		return NULL;
	}

  // Setup Client Data
//	pthread_mutex_lock(&prg.lockfreecccli);
	memcpy( cli->nodeid, buf+24, 8);
	memcpy( cli->version, buf+33, 32);
	memcpy( cli->build, buf+65, 32 );
	debugf(" FreeCCcam: client(%s) running version %s build %s\n",ip2string(ip), cli->version, cli->build);  // cli->nodeid,8,
	cli->cardsent = 0;
	cli->connected = GetTickCount();
	cli->lastecmtime = GetTickCount();
	cli->handle = sock;
	cli->ip = ip;
	cli->chkrecvtime = 0;
//	pthread_mutex_unlock(&prg.lockfreecccli);

  // send cli data ack
	cc_msg_send( sock, &cli->sendblock, CC_MSG_CLI_INFO, 0, NULL);
	//cc_msg_send( sock, &cli->sendblock, CC_MSG_BAD_ECM, 0, NULL);
	int sendversion = ( (cli->version[28]=='W')&&(cli->version[29]='H')&&(cli->version[30]='O') );
	cc_sendinfo_cli(cli, sendversion);
	//cc_msg_send( sock, &cli->sendblock, CC_MSG_BAD_ECM, 0, NULL);
	cli->cardsent = 1;
	usleep(10000);
	frcc_sendcards_cli(cli);
	pipe_wakeup( srvsocks[1] );
	return cli;
}
Пример #7
0
void cache_recvmsg()
{
	unsigned int recv_ip;
	unsigned short recv_port;
	unsigned char buf[1024];
	struct sockaddr_in si_other;
	socklen_t slen=sizeof(si_other);
	uint ticks = GetTickCount();
	struct cs_cachepeer_data *peer;

	int received = recvfrom( cfg.cachesock, buf, sizeof(buf), 0, (struct sockaddr*)&si_other, &slen);
	memcpy( &recv_ip, &si_other.sin_addr, 4);
	recv_port = ntohs(si_other.sin_port);

	if (received>0) {
		if (flag_debugnet) {
			debugf(" cache: recv data (%d) from address (%s:%d)\n", received, ip2string(recv_ip), recv_port );
			debughex(buf,received);
		}
		// Store Data
		struct cache_data req;

		switch(buf[0]) {
				case TYPE_REQUEST:
					// Check Peer
					peer = getpeerbyaddr(recv_ip,recv_port);
					if (!peer) {
						peer = getpeerbyip(recv_ip);
						if (!peer) break;
					}
					peer->lastactivity = ticks;
					//peer->totreq++;
					// Check Multics diferent version
					if ( !strcmp("MultiCS",peer->program) && (!strcmp("r63",peer->version)||!strcmp("r64",peer->version)||!strcmp("r65",peer->version)||!strcmp("r66",peer->version)||!strcmp("r67",peer->version)||!strcmp("r68",peer->version)||!strcmp("r69",peer->version)||!strcmp("r70",peer->version)||!strcmp("r71",peer->version)||!strcmp("r72",peer->version)||!strcmp("r73",peer->version)||!strcmp("r74",peer->version)||!strcmp("r75",peer->version)||!strcmp("r76",peer->version)||!strcmp("r77",peer->version)||!strcmp("r78",peer->version)||!strcmp("r79",peer->version)||!strcmp("r80",peer->version)||!strcmp("r81",peer->version)||!strcmp("r82",peer->version)||!strcmp("r83",peer->version)||!strcmp("r84",peer->version)||!strcmp("r85",peer->version)) ) break;
					// Check CSP
					if (received==20) { // arbiter number
						strcpy(peer->program,"CSP");
						break;
					}
					// Check Status
					if (peer->disabled) break;
					// Get DATA
					req.tag = buf[1];
					req.sid = (buf[2]<<8) | buf[3];
					req.onid = (buf[4]<<8) | buf[5];
					req.caid = (buf[6]<<8) | buf[7];
					req.hash = (buf[8]<<24) | (buf[9]<<16) | (buf[10]<<8) |buf[11];
					// Check Cache Request
					if (!cache_check(&req)) break;
					//
					peer->reqnb++;
					// ADD CACHE
					struct cache_data *pcache = cache_fetch( &req );
					if (pcache==NULL) {
						//*debugf(" [CACHE] << Cache Request from %s %04x:%04x:%08x\n", peer->host->name, req.caid, req.sid, req.hash);
						pcache = cache_new( &req );
						if (cfg.cache.trackermode) {
							// Send REQUEST to all Peers
							struct cs_cachepeer_data *p = cfg.cachepeer;
							while (p) {
								if (!p->disabled)
								if (p->host->ip && p->port)
								if ( (p->lastactivity+75000)>ticks )
								if ( !p->fblock0onid || pcache->onid )
									cache_send_request(pcache,p);
								p = p->next;
							}
							pcache->sendcache = 1;
							cfg.cachereq++;
						}
					}
					else if (!cfg.cache.trackermode) {
						if ( (pcache->status==CACHE_STAT_DCW)&&(pcache->sendcache!=2) ) {
							//debugf(" [CACHE] << Request Reply >> to peer %s %04x:%04x:%08x\n", peer->host->name, req.caid, req.sid, req.hash);
							peer->ihitfwd++;
							peer->hitfwd++;
							cache_send_reply(pcache,peer);
						}
					}
					break;


				case TYPE_REPLY:
					// Check Peer
					peer = getpeerbyaddr(recv_ip,recv_port);
					if (!peer) {
						peer = getpeerbyip(recv_ip);
						if (!peer) break;
					}
					peer->lastactivity = ticks;

					//peer->totrep++;
					// Check Multics diferent version
					if ( !strcmp("MultiCS",peer->program) && (!strcmp("r63",peer->version)||!strcmp("r64",peer->version)||!strcmp("r65",peer->version)||!strcmp("r66",peer->version)||!strcmp("r67",peer->version)||!strcmp("r68",peer->version)||!strcmp("r69",peer->version)||!strcmp("r70",peer->version)||!strcmp("r71",peer->version)||!strcmp("r72",peer->version)||!strcmp("r73",peer->version)||!strcmp("r74",peer->version)||!strcmp("r75",peer->version)||!strcmp("r76",peer->version)||!strcmp("r77",peer->version)||!strcmp("r78",peer->version)||!strcmp("r79",peer->version)||!strcmp("r80",peer->version)||!strcmp("r81",peer->version)||!strcmp("r82",peer->version)||!strcmp("r83",peer->version)||!strcmp("r84",peer->version)||!strcmp("r85",peer->version)) ) break;

					// Check Status
					if (peer->disabled) break;

					// 02 80 00CD 0001 0500 8D1DB359 80  // failed
					// 02 80 00CD 0001 0500 8D1DB359 80 00CD 0000 0500  63339F359A663232B73158405A255DDC  // OLD
					// 02 80 001F 0001 0100 9A3BA1C1 80 BC02DB99DE3D526D5702D42D4C249505  0005 6361726431 // NEW
					if (buf[12]!=buf[1]) {
						//peer->rep_badheader++;
						break;
					}
					req.tag = buf[1];
					req.sid = (buf[2]<<8) | buf[3];
					req.onid = (buf[4]<<8) | buf[5];
					req.caid = (buf[6]<<8) | buf[7];
					req.hash = (buf[8]<<24) | (buf[9]<<16) | (buf[10]<<8) |buf[11];
					// Check Cache Request
					if (!cache_check(&req)) {
						//peer->rep_badfields++;
						break;
					}
					//
					if (received==13) { // FAILED
						//peer->rep_failed++;
						//*debugf(" [CACHE] <| Failed Cache Reply from %s (CAID:%04x SID:%04x ONID:%04x)\n", peer->host->name, req.caid, req.sid, req.onid);
						// NOTHING TO DO
						break;
					}
					else if (received>=29) {
						// 02 80 001F 0001 0100 9A3BA1C1  80  BC02DB99DE3D526D5702D42D4C249505  0005 6361726431 // NEW
						if ( !acceptDCW(buf+13) ) {
							//peer->rep_baddcw++;
							break;
						}
						//*debugf(" [CACHE] << Good Cache Reply from %s %04x:%04x:%08x (ONID:%04x)\n", peer->host->name, req.caid, req.sid, req.hash, req.onid);
						peer->repok++; // Request+Reply

						// Search for Cache data
						struct cache_data *pcache = cache_fetch( &req );
						if (pcache==NULL) pcache = cache_new( &req );

						if (pcache->status!=CACHE_STAT_DCW) {
							//*debugf(" [CACHE] Update Cache DCW %04x:%04x:%08x\n", pcache->caid, pcache->sid, pcache->hash);
							pcache->peerid = peer->id;
							memcpy(pcache->cw, buf+13, 16);
							pcache->status = CACHE_STAT_DCW;
							if (pcache->sendpipe) {
								uchar buf[128]; // 32 por defecto
								buf[0] = PIPE_CACHE_FIND_SUCCESS;
								buf[1] = 11+2+16; // Data length
								buf[2] = pcache->tag;
								buf[3] = pcache->sid>>8; buf[4] = pcache->sid&0xff;
								buf[5] = pcache->onid>>8; buf[6] = pcache->onid&0xff;
								buf[7] = pcache->caid>>8; buf[8] = pcache->caid&0xff;
								buf[9] = pcache->hash>>24; buf[10] = pcache->hash>>16; buf[11] = pcache->hash>>8; buf[12] = pcache->hash & 0xff;
								buf[13] = peer->id>>8; buf[14] = peer->id&0xff;
								memcpy( buf+15, pcache->cw, 16);
								//*debugf(" pipe Cache->Ecm: PIPE_CACHE_FIND_SUCCESS %04x:%04x:%08x\n",pcache->caid, pcache->sid, pcache->hash); // debughex(buf, 13+16);
								pipe_send( srvsocks[1], buf, 13+2+16);
								//pcache->sendpipe = 0;
							}

							if (cfg.cache.trackermode) {
								// Send REQUEST to all Peers
								struct cs_cachepeer_data *p = cfg.cachepeer;
								while (p) {
									if (!p->disabled)
									if (p->host->ip && p->port)
									if ( (p->lastactivity+75000)>ticks )
									if ( !p->fblock0onid || pcache->onid )
										cache_send_reply(pcache,p);
									p = p->next;
								}
								pcache->sendcache = 2;
								cfg.cacherep++;
							}

						}
						else if ( pcache->sendpipe && memcmp(pcache->cw, buf+13, 16) ) {
							// resend to server
							pcache->peerid = peer->id;
							memcpy(pcache->cw, buf+13, 16);
							pcache->status = CACHE_STAT_DCW;

							uchar buf[128]; // 32 por defecto
							buf[0] = PIPE_CACHE_FIND_SUCCESS;
							buf[1] = 11+2+16; // Data length
							buf[2] = pcache->tag;
							buf[3] = pcache->sid>>8; buf[4] = pcache->sid&0xff;
							buf[5] = pcache->onid>>8; buf[6] = pcache->onid&0xff;
							buf[7] = pcache->caid>>8; buf[8] = pcache->caid&0xff;
							buf[9] = pcache->hash>>24; buf[10] = pcache->hash>>16; buf[11] = pcache->hash>>8; buf[12] = pcache->hash & 0xff;
							buf[13] = peer->id>>8; buf[14] = peer->id&0xff;
							memcpy( buf+15, pcache->cw, 16);
							pipe_send( srvsocks[1], buf, 13+2+16);
						}