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); }
void cc_srv_recvmsg(struct cs_server_data *srv) { unsigned char buf[CC_MAXMSGSIZE]; struct cs_card_data *card; struct cardserver_data *cs; int i, len; ECM_DATA *ecm; if ( (srv->type==TYPE_CCCAM)&&(srv->handle>0) ) { len = cc_msg_chkrecv(srv->handle,&srv->recvblock); if (len==0) { debugf(" CCcam: server (%s:%d) read failed %d\n", srv->host->name, srv->port, len); cc_disconnect_srv(srv); } else if (len==-1) { if (!srv->chkrecvtime) srv->chkrecvtime = GetTickCount(); else if ( (srv->chkrecvtime+500)<GetTickCount() ) { debugf(" CCcam: server (%s:%d) read failed %d\n", srv->host->name, srv->port, len); cc_disconnect_srv(srv); } } else if (len>0) { srv->chkrecvtime = 0; len = cc_msg_recv(srv->handle, &srv->recvblock, buf, 3); if (len==0) { debugf(" CCcam: server (%s:%d) read failed %d\n", srv->host->name, srv->port, len); cc_disconnect_srv(srv); } else if (len<0) { debugf(" CCcam: server (%s:%d) read failed %d(%d)\n", srv->host->name, srv->port, len, errno); cc_disconnect_srv(srv); } else if (len>0) { switch (buf[1]) { case CC_MSG_CLI_INFO: debugf(" CCcam: Client data ACK from Server (%s:%d)\n", srv->host->name,srv->port); break; case CC_MSG_ECM_REQUEST: // Get CW if (!srv->busy) { debugf(" [!] dcw error from server (%s:%d), unknown ecm request\n",srv->host->name,srv->port); break; } uint8 dcw[16]; cc_crypt_cw( cfg.cccam.nodeid, srv->busycardid, &buf[4]); memcpy(dcw, &buf[4], 16); cc_decrypt(&srv->recvblock, buf+4, len-4); // additional crypto step srv->busy = 0; srv->lastdcwtime = GetTickCount(); pthread_mutex_lock(&prg.lockecm); //### ecm = getecmbyid(srv->busyecmid); if (!ecm) { debugf(" [!] error cw from server (%s:%d), ecm not found!!!\n",srv->host->name,srv->port); pthread_mutex_unlock(&prg.lockecm); //### srv->busy = 0; break; } // check for ECM??? if (ecm->hash!=srv->busyecmhash) { debugf(" [!] error cw from server (%s:%d), ecm deleted!!!\n",srv->host->name,srv->port); pthread_mutex_unlock(&prg.lockecm); //### srv->busy = 0; break; } cs = getcsbyid(ecm->csid); int cardcheck = istherecard( srv, srv->busycard ); // Check for DCW if (!acceptDCW(dcw)) { srv->ecmerrdcw ++; if (cs&&cardcheck) { cardsids_update( srv->busycard, ecm->provid, ecm->sid, -1); srv_cstatadd( srv, cs->id, 0 , 0); } ecm_setsrvflag(srv->busyecmid, srv->id, ECM_SRV_REPLY_FAIL); pthread_mutex_unlock(&prg.lockecm); //### break; } // else { srv->lastecmoktime = GetTickCount()-srv->lastecmtime; srv->ecmoktime += srv->lastecmoktime; srv->ecmok++; ecm_setsrvflagdcw(srv->busyecmid, srv->id, ECM_SRV_REPLY_GOOD,dcw); if (cs&&cardcheck) { cardsids_update( srv->busycard, ecm->provid, ecm->sid, 1); /// + Card nodeID srv_cstatadd( srv, cs->id, 1 , srv->lastecmoktime); } if (cardcheck) { srv->busycard->ecmoktime += GetTickCount()-srv->lastecmtime; srv->busycard->ecmok++; } if (ecm->dcwstatus!=STAT_DCW_SUCCESS) { static char msg[] = "Good dcw from CCcam server"; ecm->statusmsg = msg; ecm_setdcw( cs, ecm, dcw, DCW_SOURCE_SERVER, srv->id ); debugf(" <= cw from CCcam server (%s:%d) ch %04x:%06x:%04x (%dms)\n", srv->host->name,srv->port, ecm->caid,ecm->provid,ecm->sid, GetTickCount()-srv->lastecmtime); } pthread_mutex_unlock(&prg.lockecm); //### break; case CC_MSG_ECM_NOK1: // EAGAIN, Retry /* if (!srv->busy) break; ecm = srv->busyecm; debugf(" <| decode1 failed from CCcam server (%s:%d) ch %04x:%06x:%04x (%dms)\n", srv->host->name,srv->port, ecm->caid,ecm->provid,ecm->sid, GetTickCount()-srv->lastecmtime); if ( (GetTickCount()-srv->lastecmtime)<CC_ECMRETRY_TIMEOUT ) { if (srv->retry<CC_ECMRETRY_MAX) { srv->busy = 0; if (cc_sendecm_srv(srv, ecm)) { srv->lastecmtime = GetTickCount(); srv->busy = 1; srv->retry++; break; } } } if (srv->retry>=CC_ECMRETRY_MAX) { ecm_setsrvflag(ecm, srv->id, ECM_SRV_EXCLUDE); } srv->busy = 0; break; */ case CC_MSG_ECM_NOK2: // ecm decode failed if (!srv->busy) { debugf(" [!] dcw error from server (%s:%d), unknown ecm request\n",srv->host->name,srv->port); break; } pthread_mutex_lock(&prg.lockecm); //### ecm = getecmbyid(srv->busyecmid); if (!ecm) { debugf(" [!] dcw error from server (%s:%d), ecm not found!!!\n",srv->host->name,srv->port); pthread_mutex_unlock(&prg.lockecm); //### srv->busy = 0; break; } // check for ECM??? if (ecm->hash!=srv->busyecmhash) { debugf(" [!] dcw error from server (%s:%d), ecm deleted!!!\n",srv->host->name,srv->port); pthread_mutex_unlock(&prg.lockecm); //### srv->busy = 0; break; } debugf(" <| decode failed from CCcam server (%s:%d) ch %04x:%06x:%04x (%dms)\n", srv->host->name,srv->port, ecm->caid,ecm->provid,ecm->sid, GetTickCount()-srv->lastecmtime); cs = getcsbyid(ecm->csid); if (ecm->dcwstatus!=STAT_DCW_SUCCESS) { if ( cs && (GetTickCount()-ecm->recvtime)<cs->cstimeout ) { if (srv->retry<cs->ccretry) { srv->busy = 0; if (cc_sendecm_srv(srv, ecm)) { srv->lastecmtime = GetTickCount(); srv->busy = 1; srv->retry++; debugf(" (RE%d) -> ecm to CCcam server (%s:%d) ch %04x:%06x:%04x\n",srv->retry,srv->host->name,srv->port,ecm->caid,ecm->provid,ecm->sid); pthread_mutex_unlock(&prg.lockecm); //### break; } } } } if (cs) { if ( istherecard( srv, srv->busycard ) ) cardsids_update( srv->busycard, ecm->provid, ecm->sid, -1); srv_cstatadd( srv, cs->id, 0 , 0); } ecm_setsrvflag(srv->busyecmid, srv->id, ECM_SRV_REPLY_FAIL); srv->busy = 0; pthread_mutex_unlock(&prg.lockecm); //### break; case CC_MSG_BAD_ECM: // Add Card cc_msg_send( srv->handle, &srv->sendblock, CC_MSG_BAD_ECM, 0, NULL); //debugf(" CCcam: cmd 0x05 from Server (%s:%d)\n",srv->host->name,srv->port); //currentecm.state = ECM_STATUS_FAILED; break; case CC_MSG_KEEPALIVE: srv->keepalivesent = 0; //debugf(" CCcam: Keepalive ACK from Server (%s:%d)\n",srv->host->name,srv->port); break; case CC_MSG_CARD_DEL: // Delete Card card = srv->card; uint32 k = buf[4]<<24 | buf[5]<<16 | buf[6]<<8 | buf[7]; struct cs_card_data *prevcard = NULL; while (card) { if (card->shareid==k) { debugf(" CCcam: server (%s:%d), remove share-id %d\n",srv->host->name,srv->port,k); if (prevcard) prevcard->next = card->next; else srv->card = card->next; //Free SIDs while (card->sids) { struct sid_data *sid = card->sids; card->sids = card->sids->next; free(sid); } free(card); // check for current ecm if (srv->busy && (srv->busycardid==k) ) ecm_setsrvflag(srv->busyecmid, srv->id, ECM_SRV_EXCLUDE); break; } prevcard = card; card = card->next; } break; case CC_MSG_CARD_ADD: // remove own cards -> same nodeid "cfg.cccam.nodeid" if ( (buf[14]<srv->uphops) && (buf[24]<=16) && memcmp(buf+26+buf[24]*7,cfg.cccam.nodeid,8) ) { // check Only the first 4 bytes // nodeid index = 26 + 7 * buf[24] struct cs_card_data *card = malloc( sizeof(struct cs_card_data) ); memset(card, 0, sizeof(struct cs_card_data) ); card->shareid = buf[4]<<24 | buf[5]<<16 | buf[6]<<8 | buf[7]; card->uphops = buf[14]+1; memcpy( card->nodeid, buf+26+buf[24]*7, 8); card->caid = (buf[12]<<8)+(buf[13]); card->nbprov = buf[24]; card->sids = NULL; i = 26+buf[24]*7; debugf(" CCcam: new card (%s:%d) %02x%02x%02x%02x%02x%02x%02x%02x_%x uphops %d caid %04x providers %d\n",srv->host->name,srv->port, buf[i],buf[i+1],buf[i+2],buf[i+3],buf[i+4],buf[i+5],buf[i+6],buf[i+7],card->shareid ,card->uphops, card->caid, card->nbprov); if (card->nbprov>CARD_MAXPROV) card->nbprov = CARD_MAXPROV; for (i=0;i<card->nbprov; i++) { card->prov[i] = (buf[25+i*7]<<16) | (buf[26+i*7]<<8) | (buf[27+i*7]); //debugf(" Provider %d = %06x\n",i, card->prov[i]); } card->next = srv->card; srv->card = card; } break; case CC_MSG_SRV_INFO: memcpy(srv->nodeid, buf+4, 8); memcpy(srv->version, buf+12, 31); for (i=12; i<53; i++) { if (!buf[i]) break; if ( (buf[i]<32)||(buf[i]>'z') ) { memset(srv->version, 0, 31); break; } } memcpy(srv->build, buf+44, 31); debugf(" CCcam: server (%s:%d), info: version %s build %s\n",srv->host->name,srv->port,buf+12, buf+44); break; //default: debugdump(buf,len," CCcam: unknown packet from server (%s:%d): ",srv->host->name,srv->port); } // switch } srv->keepalivetime = GetTickCount(); } } }
void rdgd_srv_recvmsg(struct cs_server_data *srv) { int len; ECM_DATA *ecm; unsigned char buf[CWS_NETMSGSIZE]; if (srv->handle>0) if (srv->type==TYPE_RADEGAST) { len = rdgd_check_message(srv->handle); if (len==0) { debugf(" radegast: server (%s:%d) read failed %d\n", srv->host->name, srv->port, len); rdgd_disconnect_srv(srv); } else if (len==-1) { if (!srv->chkrecvtime) srv->chkrecvtime = GetTickCount(); else if ( (srv->chkrecvtime+300)<GetTickCount() ) { debugf(" radegast: server (%s:%d) read failed %d\n", srv->host->name, srv->port, len); rdgd_disconnect_srv(srv); } } else if (len>0) { srv->chkrecvtime = 0; len = rdgd_message_receive(srv->handle, buf, 3); if (len==0) { debugf(" radegast: server (%s:%d) read failed %d\n", srv->host->name, srv->port, len); rdgd_disconnect_srv(srv); } else if (len<0) { debugf(" radegast: server (%s:%d) read failed %d(%d)\n", srv->host->name, srv->port, len, errno); rdgd_disconnect_srv(srv); } else if (len>0) { switch ( buf[0] ) { case 0x02: // DCW srv->lastdcwtime = GetTickCount(); if (!srv->busy) { debugf(" [!] dcw error from server (%s:%d), unknown ecm request\n",srv->host->name,srv->port); break; } srv->busy = 0; pthread_mutex_lock(&prg.lockecm); //### ecm = getecmbyid(srv->busyecmid); if (!ecm) { debugf(" [!] dcw error from server (%s:%d), ecm not found!!!\n",srv->host->name,srv->port); pthread_mutex_unlock(&prg.lockecm); //### break; } // check for ECM??? if (ecm->hash!=srv->busyecmhash) { debugf(" [!] dcw error from server (%s:%d), ecm deleted!!!\n",srv->host->name,srv->port); pthread_mutex_unlock(&prg.lockecm); //### break; } if ( (buf[1]==0x12)&&(buf[2]==0x05)&&(buf[3]==0x10) ) { // Check for DCW if (!acceptDCW(&buf[4])) { srv->ecmerrdcw ++; pthread_mutex_unlock(&prg.lockecm); //### break; } srv->ecmok++; srv->ecmoktime += GetTickCount()-srv->lastecmtime; srv->lastecmoktime = GetTickCount()-srv->lastecmtime; ecm_setsrvflagdcw(srv->busyecmid, srv->id, ECM_SRV_REPLY_GOOD, &buf[4]); debugf(" <= cw from server (%s:%d) ch %04x:%06x:%04x (%dms)\n", srv->host->name,srv->port, ecm->caid,ecm->provid,ecm->sid, GetTickCount()-srv->lastecmtime); if (ecm->dcwstatus!=STAT_DCW_SUCCESS) { static char msg[] = "Good dcw from Radegast server"; ecm->statusmsg = msg; // Store ECM Answer ecm_setdcw( getcsbyid(ecm->csid), ecm, &buf[4], DCW_SOURCE_SERVER, srv->id ); } else { //TODO: check same dcw between cards srv->ecmerrdcw ++; if ( memcmp(&ecm->cw, &buf[3],16) ) debugf(" !!! different dcw from server (%s:%d)\n",srv->host->name,srv->port); } // ADD IN SID LIST struct cardserver_data *cs=getcsbyid(ecm->csid); if (cs) { cardsids_update( srv->busycard, ecm->provid, ecm->sid, 1); srv_cstatadd( srv, cs->id, 1 , srv->lastecmoktime); } } else { struct cardserver_data *cs=getcsbyid(ecm->csid); if ( cs && (ecm->dcwstatus!=STAT_DCW_SUCCESS) && (srv->retry<cs->rdgdretry) ) { if ( (GetTickCount()-ecm->recvtime)<cs->cstimeout ) if (rdgd_sendecm_srv(srv, ecm)>0) { srv->retry++; ecm->lastsendtime = GetTickCount(); debugf(" (RE) -> ecm to server (%s:%d) ch %04x:%06x:%04x\n",srv->host->name,srv->port,ecm->caid,ecm->provid,ecm->sid); srv->lastecmtime = GetTickCount(); srv->ecmnb++; srv->busy=1; //srv->busyecm = ecm; pthread_mutex_unlock(&prg.lockecm); //### break; } } ecm_setsrvflag(srv->busyecmid, srv->id, ECM_SRV_REPLY_FAIL); debugf(" <| decode failed from server (%s:%d) ch %04x:%06x:%04x (%dms)\n", srv->host->name,srv->port, ecm->caid,ecm->provid,ecm->sid, GetTickCount()-srv->lastecmtime); // ADD IN SID LIST if (cs) { cardsids_update( srv->busycard, ecm->provid, ecm->sid, -1); srv_cstatadd( srv, cs->id, 0 , 0); } ecm_check_time = 0; } pthread_mutex_unlock(&prg.lockecm); //### break; default: buf[0] = 0x81; buf[1] = 0; rdgd_message_send(srv->handle,buf,2); } } } } }