static int32_t cc_cacheex_push_chk(struct s_client *cl, struct ecm_request_t *er) { struct cc_data *cc = cl->cc; if(chk_is_null_nodeid(cc->peer_node_id,8)) { cs_log_dbg(D_CACHEEX, "cacheex: NO peer_node_id got yet, skip!"); return 0; } if(ll_count(er->csp_lastnodes) >= cacheex_maxhop(cl)) //check max 10 nodes to push: { cs_log_dbg(D_CACHEEX, "cacheex: nodelist reached %d nodes, no push", cacheex_maxhop(cl)); return 0; } uint8_t *remote_node = cc->peer_node_id; //search existing peer nodes: LL_LOCKITER *li = ll_li_create(er->csp_lastnodes, 0); uint8_t *node; while((node = ll_li_next(li))) { cs_log_dbg(D_CACHEEX, "cacheex: check node %" PRIu64 "X == %" PRIu64 "X ?", cacheex_node_id(node), cacheex_node_id(remote_node)); if(memcmp(node, remote_node, 8) == 0) { break; } } ll_li_destroy(li); //node found, so we got it from there, do not push: if(node) { cs_log_dbg(D_CACHEEX, "cacheex: node %" PRIu64 "X found in list => skip push!", cacheex_node_id(node)); return 0; } if(!cl->cc) { if(cl->reader && !cl->reader->tcp_connected) { cc_cli_connect(cl); } } if(!cc || !cl->udp_fd) { cs_log_dbg(D_CACHEEX, "cacheex: not connected %s -> no push", username(cl)); return 0; } //check if cw is already pushed if(check_is_pushed(er->cw_cache, cl)) { return 0; } return 1; }
static int32_t camd35_cacheex_push_chk(struct s_client *cl, ECM_REQUEST *er) { if(ll_count(er->csp_lastnodes) >= cacheex_maxhop(cl)) //check max 10 nodes to push: { cs_log_dbg(D_CACHEEX, "cacheex: nodelist reached %d nodes, no push", cacheex_maxhop(cl)); return 0; } if(cl->reader) { if(!cl->reader->tcp_connected) { cs_log_dbg(D_CACHEEX, "cacheex: not connected %s -> no push", username(cl)); return 0; } } //if(chk_is_null_nodeid(remote_node,8)){ if(!cl->ncd_skey[8]) { cs_log_dbg(D_CACHEEX, "cacheex: NO peer_node_id got yet, skip!"); return 0; } uint8_t *remote_node = cl->ncd_skey; //it is sended by reader(mode 2) or client (mode 3) each 30s using keepalive msgs //search existing peer nodes: LL_LOCKITER *li = ll_li_create(er->csp_lastnodes, 0); uint8_t *node; while((node = ll_li_next(li))) { cs_log_dbg(D_CACHEEX, "cacheex: check node %" PRIu64 "X == %" PRIu64 "X ?", cacheex_node_id(node), cacheex_node_id(remote_node)); if(memcmp(node, remote_node, 8) == 0) { break; } } ll_li_destroy(li); //node found, so we got it from there, do not push: if(node) { cs_log_dbg(D_CACHEEX, "cacheex: node %" PRIu64 "X found in list => skip push!", cacheex_node_id(node)); return 0; } //check if cw is already pushed if(check_is_pushed(er->cw_cache, cl)) { return 0; } cs_log_dbg(D_CACHEEX, "cacheex: push ok %" PRIu64 "X to %" PRIu64 "X %s", cacheex_node_id(camd35_node_id), cacheex_node_id(remote_node), username(cl)); return 1; }
/** * send own id */ void camd35_cacheex_push_send_own_id(struct s_client *cl, uint8_t *mbuf) { uint8_t rbuf[32]; //minimal size if(!cl->crypted) { return; } cs_log_dbg(D_CACHEEX, "cacheex: received id request from node %" PRIu64 "X %s", cacheex_node_id(mbuf + 20), username(cl)); memset(rbuf, 0, sizeof(rbuf)); rbuf[0] = 0x3e; rbuf[1] = 12; rbuf[2] = 0; memcpy(rbuf + 20, camd35_node_id, 8); cs_log_dbg(D_CACHEEX, "cacheex: sending own id %" PRIu64 "X request %s", cacheex_node_id(camd35_node_id), username(cl)); camd35_send(cl, rbuf, 12); //send adds +20 }
void cc_cacheex_push_in(struct s_client *cl, uchar *buf) { struct cc_data *cc = cl->cc; ECM_REQUEST *er; if(!cc) { return; } if(cl->reader) { cl->reader->last_s = cl->reader->last_g = time((time_t *)0); } if(cl) { cl->last = time(NULL); } int8_t rc = buf[14]; if(rc != E_FOUND && rc != E_UNHANDLED) //Maybe later we could support other rcs { return; } uint16_t size = buf[12] | (buf[13] << 8); if(size != sizeof(er->ecmd5) + sizeof(er->csp_hash) + sizeof(er->cw)) { cs_log_dbg(D_CACHEEX, "cacheex: %s received old cash-push format! data ignored!", username(cl)); return; } if(!(er = get_ecmtask())) { return; } er->caid = b2i(2, buf + 0); er->prid = b2i(4, buf + 2); er->srvid = b2i(2, buf + 10); er->ecm[0] = buf[19]!=0x80 && buf[19]!=0x81 ? 0 : buf[19]; //odd/even byte, usefull to send it over CSP and to check cw for swapping er->rc = rc; er->ecmlen = 0; if(buf[18]) { if(buf[18] & (0x01 << 7)) { er->cwc_cycletime = (buf[18] & 0x7F); // remove bit 8 to get cycletime er->cwc_next_cw_cycle = 1; } else { er->cwc_cycletime = buf[18]; er->cwc_next_cw_cycle = 0; } } if (er->cwc_cycletime && er->cwc_next_cw_cycle < 2) { if(cl->typ == 'c' && cl->account && cl->account->cacheex.mode) { cl->account->cwc_info++; } else if((cl->typ == 'p' || cl->typ == 'r') && (cl->reader && cl->reader->cacheex.mode)) { cl->cwc_info++; } cs_log_dbg(D_CWC, "CWC (CE) received from %s cycletime: %isek - nextcwcycle: CW%i for %04X@%06X:%04X", username(cl), er->cwc_cycletime, er->cwc_next_cw_cycle, er->caid, er->prid, er->srvid); } uint8_t *ofs = buf + 20; //Read ecmd5 memcpy(er->ecmd5, ofs, sizeof(er->ecmd5)); //16 ofs += sizeof(er->ecmd5); if(!check_cacheex_filter(cl, er)) { return; } //Read csp_hash: er->csp_hash = ntohl(b2i(4, ofs)); ofs += 4; //Read cw: memcpy(er->cw, ofs, sizeof(er->cw)); //16 ofs += sizeof(er->cw); //Read lastnode count: uint8_t count = *ofs; ofs++; //check max nodes: if(count > cacheex_maxhop(cl)) { cs_log_dbg(D_CACHEEX, "cacheex: received %d nodes (max=%d), ignored! %s", (int32_t)count, cacheex_maxhop(cl), username(cl)); NULLFREE(er); return; } cs_log_dbg(D_CACHEEX, "cacheex: received %d nodes %s", (int32_t)count, username(cl)); //Read lastnodes: uint8_t *data; if (er){ er->csp_lastnodes = ll_create("csp_lastnodes"); } while(count) { if(!cs_malloc(&data, 8)) { break; } memcpy(data, ofs, 8); ofs += 8; ll_append(er->csp_lastnodes, data); count--; cs_log_dbg(D_CACHEEX, "cacheex: received node %" PRIu64 "X %s", cacheex_node_id(data), username(cl)); } //for compatibility: add peer node if no node received: if(!ll_count(er->csp_lastnodes)) { if(!cs_malloc(&data, 8)) { return; } memcpy(data, cc->peer_node_id, 8); ll_append(er->csp_lastnodes, data); cs_log_dbg(D_CACHEEX, "cacheex: added missing remote node id %" PRIu64 "X", cacheex_node_id(data)); } cacheex_add_to_cache(cl, er); }
static void log_cacheex_cw(ECM_REQUEST *er, char *reason) { uint8_t *data; uint8_t remotenodeid[8]; data = ll_last_element(er->csp_lastnodes); if(data) { memcpy(remotenodeid, data, 8); } else { memset(remotenodeid, 0 , 8); } char buf_ecm[109]; format_ecm(er, buf_ecm, 109); cs_log_dbg(D_CACHEEX,"got pushed ecm [%s]: %s - odd/even 0x%x - CSP cw: %s - pushed from %s, at hop %d, origin node-id %" PRIu64 "X", reason, buf_ecm, er->ecm[0], (checkECMD5(er)?"NO":"YES"), er->from_csp ? "csp" : username((er->cacheex_src?er->cacheex_src:er->client)), ll_count(er->csp_lastnodes), er->csp_lastnodes ? cacheex_node_id(remotenodeid): 0); }
/** * store received remote id */ static void camd35_cacheex_push_receive_remote_id(struct s_client *cl, uint8_t *buf) { memcpy(cl->ncd_skey, buf + 20, 8); cl->ncd_skey[8] = 1; cs_log_dbg(D_CACHEEX, "cacheex: received id answer from %s: %" PRIu64 "X", username(cl), cacheex_node_id(cl->ncd_skey)); }
static void camd35_cacheex_push_in(struct s_client *cl, uchar *buf) { int8_t rc = buf[3]; if(rc != E_FOUND && rc != E_UNHANDLED) //Maybe later we could support other rcs { return; } ECM_REQUEST *er; uint16_t size = buf[1] | (buf[2] << 8); if(size < sizeof(er->ecmd5) + sizeof(er->csp_hash) + sizeof(er->cw)) { cs_log_dbg(D_CACHEEX, "cacheex: %s received old cash-push format! data ignored!", username(cl)); return; } if(!(er = get_ecmtask())) { return; } er->srvid = b2i(2, buf + 8); er->caid = b2i(2, buf + 10); er->prid = b2i(4, buf + 12); er->pid = b2i(2, buf + 16); er->ecm[0] = buf[19]!=0x80 && buf[19]!=0x81 ? 0 : buf[19]; //odd/even byte, usefull to send it over CSP and to check cw for swapping er->rc = rc; er->ecmlen = 0; if(buf[18]) { if(buf[18] & (0x01 << 7)) { er->cwc_cycletime = (buf[18] & 0x7F); // remove bit 8 to get cycletime er->cwc_next_cw_cycle = 1; } else { er->cwc_cycletime = buf[18]; er->cwc_next_cw_cycle = 0; } } if (er->cwc_cycletime && er->cwc_next_cw_cycle < 2) { if(cl->typ == 'c' && cl->account && cl->account->cacheex.mode) { cl->account->cwc_info++; } else if((cl->typ == 'p' || cl->typ == 'r') && (cl->reader && cl->reader->cacheex.mode)) { cl->cwc_info++; } cs_log_dbg(D_CWC, "CWC (CE) received from %s cycletime: %isek - nextcwcycle: CW%i for %04X@%06X:%04X", username(cl), er->cwc_cycletime, er->cwc_next_cw_cycle, er->caid, er->prid, er->srvid); } uint8_t *ofs = buf + 20; //Read ecmd5 memcpy(er->ecmd5, ofs, sizeof(er->ecmd5)); //16 ofs += sizeof(er->ecmd5); if(!check_cacheex_filter(cl, er)) { return; } //Read csp_hash: er->csp_hash = ntohl(b2i(4, ofs)); ofs += 4; //Read cw: memcpy(er->cw, ofs, sizeof(er->cw)); //16 ofs += sizeof(er->cw); //Check auf neues Format: uint8_t *data; if(size > (sizeof(er->ecmd5) + sizeof(er->csp_hash) + sizeof(er->cw))) { //Read lastnodes: uint8_t count = *ofs; ofs++; //check max nodes: if(count > cacheex_maxhop(cl)) { cs_log_dbg(D_CACHEEX, "cacheex: received %d nodes (max=%d), ignored! %s", (int32_t)count, cacheex_maxhop(cl), username(cl)); NULLFREE(er); return; } cs_log_dbg(D_CACHEEX, "cacheex: received %d nodes %s", (int32_t)count, username(cl)); if (er){ er->csp_lastnodes = ll_create("csp_lastnodes"); } while(count) { if(!cs_malloc(&data, 8)) { break; } memcpy(data, ofs, 8); ofs += 8; ll_append(er->csp_lastnodes, data); count--; cs_log_dbg(D_CACHEEX, "cacheex: received node %" PRIu64 "X %s", cacheex_node_id(data), username(cl)); } } else { cs_log_dbg(D_CACHEEX, "cacheex: received old cachex from %s", username(cl)); er->csp_lastnodes = ll_create("csp_lastnodes"); } //store remote node id if we got one. The remote node is the first node in the node list data = ll_has_elements(er->csp_lastnodes); if(data && !cl->ncd_skey[8]) //Ok, this is tricky, we use newcamd key storage for saving the remote node { memcpy(cl->ncd_skey, data, 8); cl->ncd_skey[8] = 1; //Mark as valid node } cs_log_dbg(D_CACHEEX, "cacheex: received cacheex from remote node id %" PRIu64 "X", cacheex_node_id(cl->ncd_skey)); //for compatibility: add peer node if no node received (not working now, maybe later): if(!ll_count(er->csp_lastnodes) && cl->ncd_skey[8]) { if(!cs_malloc(&data, 8)) { return; } memcpy(data, cl->ncd_skey, 8); ll_append(er->csp_lastnodes, data); cs_log_dbg(D_CACHEEX, "cacheex: added missing remote node id %" PRIu64 "X", cacheex_node_id(data)); } cacheex_add_to_cache(cl, er); }