./ MultiCS.r82 / cacheex.c
/////////////////////////////////////////////////////////////////////////////// // TOOL /////////////////////////////////////////////////////////////////////////////// int acceptshare( struct sharelimit_data sharelimits[100], uint16_t caid, uint32_t provid) { int i; if (sharelimits[0].caid==0xffff) return 1; for (i=0; i<100; i++) { if (sharelimits[i].caid==0xffff) break; if (sharelimits[i].caid==caid) { if (sharelimits[i].provid==provid) return 1; else if (sharelimits[i].provid==0xFFFFFF) return 1; } } return 0; } /////////////////////////////////////////////////////////////////////////////// // TOOL /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // pipe --> cacheex /////////////////////////////////////////////////////////////////////////////// int pipe_send_cacheex_push_out(ECM_DATA *ecm) { uint8_t buf[128]; buf[0] = PIPE_CACHEEX_PUSH_LOCAL; buf[1] = (ecm->caid)>>8; buf[2] = (ecm->caid)&0xff; buf[3] = ecm->ecm[0]; buf[4] = ecm->provid>>16; buf[5] = ecm->provid>>8; buf[6] = ecm->provid & 0xff; buf[7] = (ecm->sid)>>8; buf[8] = (ecm->sid)&0xff; buf[9] = ecm->hash>>24; buf[10] = ecm->hash>>16; buf[11] = ecm->hash>>8; buf[12] = ecm->hash & 0xff; memcpy(buf+13, ecm->ecmd5, 16); memcpy(buf+29, ecm->cw, 16); pipe_send( prg.pipe.cacheex[1], buf, 45); return 1; } int pipe_send_cacheex_push_cache(struct cache_data *pcache, uint8_t *cw, uint8_t *nodeid) { uint8_t buf[128]; buf[0] = PIPE_CACHEEX_PUSH_REMOTE; buf[1] = (pcache->caid)>>8; buf[2] = (pcache->caid)&0xff; buf[3] = pcache->tag; buf[4] = pcache->provid>>16; buf[5] = pcache->provid>>8; buf[6] = pcache->provid & 0xff; buf[7] = (pcache->sid)>>8; buf[8] = (pcache->sid)&0xff; buf[9] = pcache->hash>>24; buf[10] = pcache->hash>>16; buf[11] = pcache->hash>>8; buf[12] = pcache->hash & 0xff; memcpy(buf+13, pcache->ecmd5, 16); memcpy(buf+29, cw, 16); memcpy( buf+29+16, nodeid, 8); pipe_send( prg.pipe.cacheex[1], buf, 29+16+8); return 1; } int pipe_send_cacheex_push_in(struct cache_data *pcache, uint8_t cw[16], int clid, int hop) { uint8_t buf[128]; buf[0] = PIPE_CACHEEX_PUSH_IN; buf[1] = (pcache->caid)>>8; buf[2] = (pcache->caid)&0xff; buf[3] = pcache->tag; buf[4] = pcache->provid>>16; buf[5] = pcache->provid>>8; buf[6] = pcache->provid & 0xff; buf[7] = (pcache->sid)>>8; buf[8] = (pcache->sid)&0xff; buf[9] = pcache->hash>>24; buf[10] = pcache->hash>>16; buf[11] = pcache->hash>>8; buf[12] = pcache->hash & 0xff; memcpy(buf+13, pcache->ecmd5, 16); memcpy(buf+29, cw, 16); buf[45] = clid>>8; buf[46] = clid; buf[47] = hop; pipe_send( prg.pipe.cacheex[1], buf, 48); return 1; } /////////////////////////////////////////////////////////////////////////////// // PUSH OUT /////////////////////////////////////////////////////////////////////////////// int get_cccam_cacheex_push(struct cache_data *pcache, uint8_t cw[16], uint8_t *buf, uint8_t *nodeid ) { memset(buf, 0, 57+8 ); buf[0] = pcache->caid>>8; buf[1] = pcache->caid; buf[2] = pcache->provid>>24; buf[3] = pcache->provid>>16; buf[4] = pcache->provid>>8; buf[5] = pcache->provid; buf[10] = pcache->sid>>8; buf[11] = pcache->sid; buf[12] = 0x24; // ( 16 + 4 + 16 ) buf[13] = 0; buf[14] = 0; buf[19] = pcache->tag; memcpy(buf+20, pcache->ecmd5, 16); buf[36] = pcache->hash; buf[37] = pcache->hash >> 8; buf[38] = pcache->hash >> 16; buf[39] = pcache->hash >> 24; memcpy(buf+40, cw, 16); if (nodeid) { buf[56] = 2; memcpy(buf+57, cccam_nodeid, 8 ); memcpy(buf+57+8, nodeid, 8 ); return 57+8+8; } buf[56] = 1; // Uphops = 1 (local) memcpy(buf+57, cccam_nodeid, 8 ); return 57+8; } int get_camd35_cacheex_push(struct cache_data *pcache, uint8_t cw[16], uint8_t *buf, uint8_t *nodeid ) { memset(buf, 0, 57+8 ); buf[0] = 0x3F; buf[1] = 57+8-20; buf[8] = pcache->sid>>8; buf[9] = pcache->sid; buf[10] = pcache->caid>>8; buf[11] = pcache->caid; buf[12] = pcache->provid>>24; buf[13] = pcache->provid>>16; buf[14] = pcache->provid>>8; buf[15] = pcache->provid; buf[19] = pcache->tag; memcpy(buf+20, pcache->ecmd5, 16); buf[36] = pcache->hash; buf[37] = pcache->hash >> 8; buf[38] = pcache->hash >> 16; buf[39] = pcache->hash >> 24; memcpy(buf+40, cw, 16); if (nodeid) { buf[1] += 8; buf[56] = 2; memcpy(buf+57, cccam_nodeid, 8 ); memcpy(buf+57+8, nodeid, 8 ); return 57+8+8; } buf[56] = 1; // Uphops = 1 (local) memcpy(buf+57, cccam_nodeid, 8 ); return 57+8; } void cacheex_push(struct cache_data *pcache, uint8_t cw[16], uint8_t *nodeid ) { uint8_t camd35buf[128]; int camd35len = get_camd35_cacheex_push( pcache, cw, camd35buf, nodeid ); uint8_t cccambuf[128]; int cccamlen = get_cccam_cacheex_push( pcache, cw, cccambuf, nodeid ); // PUSH TO SERVERS cacheex=3 struct server_data *srv = cfg.cacheexserver; while (srv) { //debugf( getdbgflag(DBG_CACHEEX, 0, 0)," CACHEEX PUSH to server (%s:%d) %04x:%06x:%04x:%08x\n",srv->host->name, srv->port,pcache->caid,pcache->provid,pcache->sid,pcache->hash); debughex(cw,16); if ( (srv->cacheex_mode==3) && (srv->connection.status>0) ) if ( acceptshare(srv->sharelimits, pcache->caid, pcache->provid) ) { if (srv->type==TYPE_CCCAM) { if ( !cc_msg_send( srv->handle, &srv->sendblock, CC_MSG_CACHE_PUSH, cccamlen, cccambuf) ) disconnect_srv(srv); } #ifdef CAMD35_CLI else if (srv->type==TYPE_CAMD35) camd35_sendto( srv->handle, srv->host->ip, srv->port, &srv->encryptkey, srv->ucrc, camd35buf, camd35len); #endif #ifdef CS378X_CLI else if (srv->type==TYPE_CS378X) { if ( !cs378x_send( srv->handle, &srv->encryptkey, srv->ucrc, camd35buf, camd35len) ) disconnect_srv(srv); } #endif srv->cacheex.push[0]++; if (nodeid) srv->cacheex.push[2]++; else srv->cacheex.push[1]++; } srv = srv->next; } #ifdef CCCAM_SRV // PUSH TO CCCAM CLIENTS cacheex=2 struct cccam_server_data *cccam = cfg.cccam.server; while (cccam) { struct cc_client_data *cli = cccam->cacheexclient; while (cli) { if ( (cli->cacheex_mode==2) && (cli->connection.status>0) ) if ( acceptshare(cli->sharelimits, pcache->caid, pcache->provid) ) { if ( !cc_msg_send( cli->handle, &cli->sendblock, CC_MSG_CACHE_PUSH, cccamlen, cccambuf) ) cc_disconnect_cli(cli); cli->cacheex.push[0]++; if (nodeid) cli->cacheex.push[2]++; else cli->cacheex.push[1]++; //debugf( getdbgflag(DBG_CACHEEX, 0, 0)," CACHEEX PUSH to client %04x:%06x:%04x:%08x\n",pcache->caid,pcache->provid,pcache->sid,pcache->hash);// debughex(req.cw,16); } cli = cli->next; } cccam = cccam->next; } #endif #ifdef CAMD35_SRV // PUSH TO CAMD35 CLIENTS cacheex=2 struct camd35_server_data *camd35 = cfg.camd35.server; while (camd35) { struct camd35_client_data *cli = camd35->cacheexclient; while (cli) { if ( (cli->cacheex_mode==2) && (cli->connection.status>0) ) if ( !nodeid || memcmp(nodeid, cli->nodeid, 8) ) if ( acceptshare(cli->sharelimits, pcache->caid, pcache->provid) ) { camd35_sendto( camd35->handle, cli->ip, cli->port, &cli->encryptkey, cli->ucrc, camd35buf, camd35len); cli->cacheex.push[0]++; if (nodeid) cli->cacheex.push[2]++; else cli->cacheex.push[1]++; //debugf( getdbgflag(DBG_CACHEEX, 0, 0)," CACHEEX PUSH to client %04x:%06x:%04x:%08x\n",pcache->caid,pcache->provid,pcache->sid,pcache->hash);// debughex(req.cw,16); } cli = cli->next; } camd35 = camd35->next; } #endif #ifdef CS378X_SRV // PUSH TO CS378X CLIENTS cacheex=2 struct camd35_server_data *cs378x = cfg.cs378x.server; while (cs378x) { struct camd35_client_data *cli = cs378x->cacheexclient; while (cli) { if ( (cli->cacheex_mode==2) && (cli->connection.status>0) ) if ( !nodeid || memcmp(nodeid, cli->nodeid, 8) ) if ( acceptshare(cli->sharelimits, pcache->caid, pcache->provid) ) { if ( !cs378x_send( cli->handle, &cli->encryptkey, cli->ucrc, camd35buf, camd35len) ) cs378x_disconnect_cli(cli); cli->cacheex.push[0]++; if (nodeid) cli->cacheex.push[2]++; else cli->cacheex.push[1]++; //debugf( getdbgflag(DBG_CACHEEX, 0, 0)," CACHEEX PUSH to client %04x:%06x:%04x:%08x\n",pcache->caid,pcache->provid,pcache->sid,pcache->hash);// debughex(req.cw,16); } cli = cli->next; } cs378x = cs378x->next; } #endif } void cacheex_pipe_recvmsg() { uint8_t buf[512]; uint8_t cw[16]; struct cache_data req; struct pollfd pfd; do { int len = pipe_recv( prg.pipe.cacheex[0], buf ); if (len>0) { //debugf( getdbgflag(DBG_CACHEEX, 0, 0)," Recv from CacheEX Pipe\n"); debughex(buf,len); switch(buf[0]) { case PIPE_WAKEUP: // ADD NEW CLIENT break; case PIPE_CACHEEX_PUSH_LOCAL: // from local // Setup Cache Request req.caid = (buf[1]<<8) | buf[2]; req.tag = buf[3]; req.provid = (buf[4]<<16) | (buf[5]<<8) | (buf[6]); req.sid = (buf[7]<<8) | buf[8]; req.hash = (buf[9]<<24) | (buf[10]<<16) | (buf[11]<<8) | (buf[12]); memcpy( req.ecmd5, buf+13, 16); memcpy( cw, buf+29, 16); //debugf( getdbgflag(DBG_CACHEEX, 0, 0)," PIPE_CACHEEX_PUSH_OUT %04x:%06x:%04x:%08x\n", req.caid,req.provid,req.sid,req.hash); // Send Reply cfg.cacheex.rep++; cacheex_push( &req, cw, NULL ); break; case PIPE_CACHEEX_PUSH_REMOTE: // from cacheex peers // Setup Cache Request req.caid = (buf[1]<<8) | buf[2]; req.tag = buf[3]; req.provid = (buf[4]<<16) | (buf[5]<<8) | (buf[6]); req.sid = (buf[7]<<8) | buf[8]; req.hash = (buf[9]<<24) | (buf[10]<<16) | (buf[11]<<8) | (buf[12]); memcpy( req.ecmd5, buf+13, 16); memcpy( cw, buf+29, 16); //debugf( getdbgflag(DBG_CACHEEX, 0, 0)," PIPE_CACHEEX_PUSH_REMOTE %04x:%06x:%04x:%08x\n", req.caid,req.provid,req.sid,req.hash); // Send Reply cfg.cacheex.rep++; cacheex_push( &req, cw, buf+29+16 ); break; }//switch }//if pfd.fd = prg.pipe.cacheex[0]; pfd.events = POLLIN | POLLPRI; } while ( poll(&pfd, 1, 1)>0 ); } /* 1 for server>clients 1 for client>servers */ /////////////////////////////////////////////////////////////////////////////// int cacheex_check( struct cache_data *req ) { if ( !req->caid || !req->hash || !req->sid ) return 0; if (cfg.cache.caids[0]) { int i; for(i=0; i<32; i++) { if (!cfg.cache.caids[i]) break; if (cfg.cache.caids[i]==req->caid) return 1; } return 0; } return 1; } /////////////////////////////////////////////////////////////////////////////// void *cacheex_recvmsg_thread(void *param) { prg.pid_ccex_msg = syscall(SYS_gettid); struct pollfd pfd[CACHEEX_MAX_PFD]; int pfdcount = 0; while(1) { pfdcount = 0; // Clients mode 2 struct cccam_server_data *cccam = cfg.cccam.server; while (cccam) { if ( !IS_DISABLED(cccam->flags)&&(cccam->handle>0) ) { struct cc_client_data *cccli = cccam->cacheexclient; while (cccli) { if (cccli->cacheex_mode==2) { if ( !IS_DISABLED(cccli->flags)&&(cccli->handle>0) ) { cccli->ipoll = pfdcount; pfd[pfdcount].fd = cccli->handle; pfd[pfdcount++].events = POLLIN | POLLPRI; } else cccli->ipoll = -1; } cccli = cccli->next; } } cccam = cccam->next; } // Servers mode 3 struct server_data *srv = cfg.cacheexserver; while (srv) { if ( (srv->cacheex_mode==3) && !IS_DISABLED(srv->flags) && (srv->handle>0) ) { srv->ipoll = pfdcount; pfd[pfdcount].fd = srv->handle; pfd[pfdcount++].events = POLLIN | POLLPRI; } else srv->ipoll = -1; srv = srv->next; } int retval = poll(pfd, pfdcount, 3005); // for 3seconds if ( retval>0 ) { if (cfg.delay.thread) usleep(cfg.delay.thread); // CCcam Clients - cacheex_mode = 3 struct cccam_server_data *cccam = cfg.cccam.server; while (cccam) { if ( !IS_DISABLED(cccam->flags)&&(cccam->handle>0) ) { //pthread_mutex_lock(&prg.lockcccli); struct cc_client_data *cccli = cccam->cacheexclient; while (cccli) { if (cccli->cacheex_mode==2) { if ( !IS_DISABLED(cccli->flags)&&(cccli->handle>0)&&(cccli->ipoll>=0)&&(cccli->handle==pfd[cccli->ipoll].fd) ) { if ( pfd[cccli->ipoll].revents & (POLLHUP|POLLNVAL) ) cc_disconnect_cli(cccli); else if ( pfd[cccli->ipoll].revents & (POLLIN|POLLPRI) ) cc_cli_recvmsg(cccli); } } cccli = cccli->next; } //pthread_mutex_unlock(&prg.lockcccli); } cccam = cccam->next; } //Servers struct server_data *srv = cfg.cacheexserver; while (srv) { if ( (srv->cacheex_mode==3) && !IS_DISABLED(srv->flags) && (srv->handle>0) ) if ( (srv->ipoll>=0)&&(srv->handle==pfd[srv->ipoll].fd) ) { if ( pfd[srv->ipoll].revents & (POLLIN|POLLPRI) ) { if (srv->type==TYPE_CCCAM) cc_srv_recvmsg(srv); #ifdef CAMD35_CLI else if (srv->type==TYPE_CAMD35) camd35_srv_recvmsg(srv); #endif #ifdef CS378X_CLI else if (srv->type==TYPE_CS378X) cs378x_srv_recvmsg(srv); #endif } } srv = srv->next; } } else if ( retval<0 ) { debugf(0, " thread receive messages: poll error %d(errno=%d)\n", retval, errno); } } return NULL; } void *cacheex_pipe_thread(void *param) { struct pollfd pfd; while(1) { pfd.fd = prg.pipe.cacheex[0]; pfd.events = POLLIN | POLLPRI; int retval = poll(&pfd, 1, 3015); // for 3seconds if ( retval>0 ) { cacheex_pipe_recvmsg(); } else if ( retval<0 ) { debugf(0, " thread receive messages: poll error %d(errno=%d)\n", retval, errno); } } return NULL; } int start_thread_cacheex() { //memset( icacheextab, 0, sizeof(icacheextab)); //create_thread(&prg.tid_cacheex, (threadfn)cacheex_send_thread,NULL); create_thread(&prg.tid_cacheex, cacheex_recvmsg_thread,NULL); create_thread(&prg.tid_cacheex, cacheex_pipe_thread,NULL); return 0; }