示例#1
0
static S_COOL_CHANHANDLE *find_chanhandle(int32_t demux_index, int32_t pid)
{
	// Find matching channel, if it exists.
	if(ll_count(ll_cool_chanhandle) > 0)
	{
		LL_ITER itr = ll_iter_create(ll_cool_chanhandle);
		S_COOL_CHANHANDLE *handle_item;

		while((handle_item = ll_iter_next(&itr)))
		{
			if(handle_item->demux_index == demux_index && handle_item->pid == pid)
			{
				return handle_item;
			}
		}
	}

	return NULL;
}
示例#2
0
static S_COOL_FILTER  *find_filter_by_chanhandle(S_COOL_CHANHANDLE *chanhandle, int32_t filter_num)
{
	// Find matching channel, if it exists.
	if(ll_count(ll_cool_filter) > 0)
	{
		LL_ITER itr = ll_iter_create(ll_cool_filter);
		S_COOL_FILTER *filter_item;

		while((filter_item = ll_iter_next(&itr)))
		{
			if(filter_item->chanhandle == chanhandle && filter_item->filter_num == filter_num)
			{
				return filter_item;
			}
		}
	}

	return NULL;
}
示例#3
0
static int32_t remove_filter(S_COOL_FILTER *filter_handle)
{
	if(ll_count(ll_cool_filter) > 0)
	{
		LL_ITER itr = ll_iter_create(ll_cool_filter);
		S_COOL_FILTER *filter_item;

		while((filter_item = ll_iter_next(&itr)))
		{
			if(filter_item == filter_handle)
			{
				ll_iter_remove_data(&itr);
				return 0;
			}
		}
	}

	return -1;
}
示例#4
0
/*
 * Creates a string ready to write as a token into config or WebIf for au readers. You must free the returned value through free_mk_t().
 */
char *mk_t_aureader(struct s_auth *account)
{
	int32_t pos = 0;
	char *dot = "";

	char *value;
	if(ll_count(account->aureader_list) == 0 || !cs_malloc(&value, 256)) { return ""; }
	value[0] = '\0';

	struct s_reader *rdr;
	LL_ITER itr = ll_iter_create(account->aureader_list);
	while((rdr = ll_iter_next(&itr)))
	{
		pos += snprintf(value + pos, 256 - pos, "%s%s", dot, rdr->label);
		dot = ",";
	}

	return value;
}
示例#5
0
static void log_list_add(struct s_log *log)
{
	if(logStarted == 0)
		{ return; }
	
	int32_t count = ll_count(log_list);
	log_list_queued++;
	if(count < MAX_LOG_LIST_BACKLOG)
	{
		ll_append(log_list, log);
	}
	else     // We have too much backlog
	{
		NULLFREE(log->txt);
		NULLFREE(log);
		cs_write_log("-------------> Too much data in log_list, dropping log message.\n", 1, 0, 0);
	}
	SAFE_COND_SIGNAL_NOLOG(&log_thread_sleep_cond);
}
示例#6
0
static int32_t remove_chanhandle(S_COOL_CHANHANDLE *handle)
{
	// Find matching channel, if it exists.
	if(ll_count(ll_cool_chanhandle) > 0)
	{
		LL_ITER itr = ll_iter_create(ll_cool_chanhandle);
		S_COOL_CHANHANDLE *handle_item;

		while((handle_item = ll_iter_next(&itr)))
		{
			if(handle_item == handle)
			{
				ll_iter_remove_data(&itr);
				return 0;
			}
		}
	}

	return -1;
}
示例#7
0
void gbox_remove_cards_without_goodsids(LLIST *card_list)
{
	if(card_list)
	{
		LL_ITER it = ll_iter_create(card_list);
		struct gbox_card *card;
		while((card = ll_iter_next(&it)))
		{
			if(ll_count(card->goodsids) == 0)
			{
				ll_iter_remove(&it);
				gbox_free_card(card);
			}
			else
			{
				ll_destroy_data_NULL(card->badsids);
			}
		}
	}
	return;
}
示例#8
0
void log_list_thread()
{
	char buf[LOG_BUF_SIZE];

	while (1) {
		LL_ITER it = ll_iter_create(log_list);
		struct s_log *log;
		while ((log=ll_iter_next_remove(&it))) {
			int8_t do_flush = ll_count(log_list) == 0; //flush on writing last element

			cs_strncpy(buf, log->txt, LOG_BUF_SIZE);
			if (log->direct_log)
				cs_write_log(buf, do_flush);
			else
				write_to_log(buf, log, do_flush);
			free(log->txt);
			free(log);
		}
		cs_sleepms(50);
	}
}
示例#9
0
void cs_disable_log(int8_t disabled)
{
	if (cfg.disablelog != disabled) {
		if(disabled && logStarted) {
			cs_log("Stopping log...");
			int32_t i = 0;
			while(ll_count(log_list) > 0 && i < 200){
				cs_sleepms(5);
				++i;
			}
		}
		cfg.disablelog = disabled;
		if (disabled){
			if(logStarted) {
				cs_sleepms(20);
				cs_close_log();
			}
		} else {
			cs_open_logfiles();
		}
	}
}
示例#10
0
文件: rqd.c 项目: hyper/rqd
// create and init the 'server' structure.
static void init_servers(system_data_t *sysdata)
{
	char *str;
	
	assert(sysdata);
	assert(sysdata->servers == NULL);
	sysdata->servers = ll_init(NULL);
	assert(sysdata->servers);

	assert(sysdata->settings->port > 0);
	assert(sysdata->settings->interfaces);
	if (ll_count(sysdata->settings->interfaces) == 0) {
		// no interfaces were specified, so we need to bind to all of them.
		server_listen(sysdata, sysdata->settings->port, NULL);
	}
	else {

		// we have some specific interfaces, so we will bind to each of them only.
		while ((str = ll_pop_tail(sysdata->settings->interfaces))) {
			server_listen(sysdata, sysdata->settings->port, str);
			free(str);
		}
	}
}
示例#11
0
/**
 * adds a job to the job queue
 * if ptr should be free() after use, set len to the size
 * else set size to 0
**/
int32_t add_job(struct s_client *cl, enum actions action, void *ptr, int32_t len)
{
	if(!cl || cl->kill)
	{
		if(!cl)
			{ cs_log("WARNING: add_job failed. Client killed!"); } // Ignore jobs for killed clients
		if(len && ptr)
			{ NULLFREE(ptr); }
		return 0;
	}


#ifdef CS_CACHEEX
	// Avoid full running queues:
	if(action == ACTION_CACHE_PUSH_OUT && ll_count(cl->joblist) > 2000)
	{
		cs_debug_mask(D_TRACE, "WARNING: job queue %s %s has more than 2000 jobs! count=%d, dropped!",
					  cl->typ == 'c' ? "client" : "reader",
					  username(cl), ll_count(cl->joblist));
		if(len && ptr)
			{ NULLFREE(ptr); }
		// Thread down???
		pthread_mutex_lock(&cl->thread_lock);
		if(cl && !cl->kill && cl->thread && cl->thread_active)
		{
			// Just test for invalid thread id:
			if(pthread_detach(cl->thread) == ESRCH)
			{
				cl->thread_active = 0;
				cs_debug_mask(D_TRACE, "WARNING: %s %s thread died!",
							  cl->typ == 'c' ? "client" : "reader", username(cl));
			}
		}
		pthread_mutex_unlock(&cl->thread_lock);
		return 0;
	}
#endif


	struct job_data *data;
	if(!cs_malloc(&data, sizeof(struct job_data)))
	{
		if(len && ptr)
			{ NULLFREE(ptr); }
		return 0;
	}

	data->action = action;
	data->ptr    = ptr;
	data->cl     = cl;
	data->len    = len;
	cs_ftime(&data->time);

	pthread_mutex_lock(&cl->thread_lock);
	if(cl && !cl->kill && cl->thread_active)
	{
		if(!cl->joblist)
			{ cl->joblist = ll_create("joblist"); }
		ll_append(cl->joblist, data);
		if(cl->thread_active == 2)
			{ pthread_kill(cl->thread, OSCAM_SIGNAL_WAKEUP); }
		pthread_mutex_unlock(&cl->thread_lock);
		cs_debug_mask(D_TRACE, "add %s job action %d queue length %d %s",
					  action > ACTION_CLIENT_FIRST ? "client" : "reader", action,
					  ll_count(cl->joblist), username(cl));
		return 1;
	}

	pthread_attr_t attr;
	pthread_attr_init(&attr);
	/* pcsc doesn't like this either; segfaults on x86, x86_64 */
	struct s_reader *rdr = cl->reader;
	if(cl->typ != 'r' || !rdr || rdr->typ != R_PCSC)
		{ pthread_attr_setstacksize(&attr, PTHREAD_STACK_SIZE); }

	if(action != ACTION_READER_CHECK_HEALTH)
	{
		cs_debug_mask(D_TRACE, "start %s thread action %d",
					  action > ACTION_CLIENT_FIRST ? "client" : "reader", action);
	}

	int32_t ret = pthread_create(&cl->thread, &attr, work_thread, (void *)data);
	if(ret)
	{
		cs_log("ERROR: can't create thread for %s (errno=%d %s)",
			   action > ACTION_CLIENT_FIRST ? "client" : "reader", ret, strerror(ret));
		free_job_data(data);
	}
	else
	{
		pthread_detach(cl->thread);
	}
	pthread_attr_destroy(&attr);

	cl->thread_active = 1;
	pthread_mutex_unlock(&cl->thread_lock);
	return 1;
}
示例#12
0
int32_t cs_auth_client(struct s_client * client, struct s_auth *account, const char *e_txt)
{
    int32_t rc = 0;
    unsigned char md5tmp[MD5_DIGEST_LENGTH];
    char buf[32];
    char *t_crypt = "encrypted";
    char *t_plain = "plain";
    char *t_grant = " granted";
    char *t_reject = " rejected";
    char *t_msg[] = { buf, "invalid access", "invalid ip", "unknown reason", "protocol not allowed" };
    struct s_module *module = get_module(client);

    memset(&client->grp, 0xff, sizeof(uint64_t));
    //client->grp=0xffffffffffffff;
    if ((intptr_t)account != 0 && (intptr_t)account != -1 && account->disabled) {
        cs_add_violation(client, account->usr);
        cs_log("%s %s-client %s%s (%s%sdisabled account)",
               client->crypted ? t_crypt : t_plain,
               module->desc,
               IP_ISSET(client->ip) ? cs_inet_ntoa(client->ip) : "",
               IP_ISSET(client->ip) ? t_reject : t_reject+1,
               e_txt ? e_txt : "",
               e_txt ? " " : "");
        return 1;
    }

    // check whether client comes in over allowed protocol
    if ((intptr_t)account != 0 && (intptr_t)account != -1 && (intptr_t)account->allowedprotocols &&
            (((intptr_t)account->allowedprotocols & module->listenertype) != module->listenertype))
    {
        cs_add_violation(client, account->usr);
        cs_log("%s %s-client %s%s (%s%sprotocol not allowed)",
               client->crypted ? t_crypt : t_plain,
               module->desc,
               IP_ISSET(client->ip) ? cs_inet_ntoa(client->ip) : "",
               IP_ISSET(client->ip) ? t_reject : t_reject+1,
               e_txt ? e_txt : "",
               e_txt ? " " : "");
        return 1;
    }

    client->account = first_client->account;
    switch((intptr_t)account) {

    case 0: { // reject access
        rc = 1;
        cs_add_violation(client, NULL);
        cs_log("%s %s-client %s%s (%s)",
               client->crypted ? t_crypt : t_plain,
               module->desc,
               IP_ISSET(client->ip) ? cs_inet_ntoa(client->ip) : "",
               IP_ISSET(client->ip) ? t_reject : t_reject+1,
               e_txt ? e_txt : t_msg[rc]);
        break;
    }

    default: { // grant/check access
        if (IP_ISSET(client->ip) && account->dyndns) {
            if (!IP_EQUAL(client->ip, account->dynip))
                cs_user_resolve(account);
            if (!IP_EQUAL(client->ip, account->dynip)) {
                cs_add_violation(client, account->usr);
                rc=2;
            }
        }
        client->monlvl = account->monlvl;
        client->account = account;
        if (!rc)
        {
            client->dup=0;
            if (client->typ=='c' || client->typ=='m')
                client->pcrc = crc32(0L, MD5((uchar *)(ESTR(account->pwd)), strlen(ESTR(account->pwd)), md5tmp), MD5_DIGEST_LENGTH);
            if (client->typ=='c')
            {
                client->last_caid = NO_CAID_VALUE;
                client->last_srvid = NO_SRVID_VALUE;
                client->expirationdate = account->expirationdate;
                client->disabled = account->disabled;
                client->allowedtimeframe[0] = account->allowedtimeframe[0];
                client->allowedtimeframe[1] = account->allowedtimeframe[1];
                if (account->firstlogin == 0) account->firstlogin = time((time_t*)0);
                client->failban = account->failban;
                client->c35_suppresscmd08 = account->c35_suppresscmd08;
                client->ncd_keepalive = account->ncd_keepalive;
                client->grp = account->grp;
                client->aureader_list = account->aureader_list;
                client->autoau = account->autoau;
                client->tosleep = (60*account->tosleep);
                client->c35_sleepsend = account->c35_sleepsend;
                memcpy(&client->ctab, &account->ctab, sizeof(client->ctab));
                if (account->uniq)
                    cs_fake_client(client, account->usr, account->uniq, client->ip);
                client->ftab  = account->ftab;   // IDENT filter
                client->cltab = account->cltab;  // CLASS filter
                client->fchid = account->fchid;  // CHID filter
                client->sidtabs.ok= account->sidtabs.ok;   // services
                client->sidtabs.no= account->sidtabs.no;   // services
                memcpy(&client->ttab, &account->ttab, sizeof(client->ttab));
                ac_init_client(client, account);
            }
        }
    }

    case -1: { // anonymous grant access
        if (rc) {
            t_grant = t_reject;
        } else {
            if (client->typ == 'm') {
                snprintf(t_msg[0], sizeof(buf), "lvl=%d", client->monlvl);
            } else {
                int32_t rcount = ll_count(client->aureader_list);
                snprintf(buf, sizeof(buf), "au=");
                if (!rcount)
                    snprintf(buf+3, sizeof(buf)-3, "off");
                else {
                    if (client->autoau)
                        snprintf(buf+3, sizeof(buf)-3, "auto (%d reader)", rcount);
                    else
                        snprintf(buf+3, sizeof(buf)-3, "on (%d reader)", rcount);
                }
            }
        }
        cs_log("%s %s-client %s%s (%s, %s)",
               client->crypted ? t_crypt : t_plain,
               e_txt ? e_txt : module->desc,
               IP_ISSET(client->ip) ? cs_inet_ntoa(client->ip) : "",
               IP_ISSET(client->ip) ? t_grant : t_grant + 1,
               username(client), t_msg[rc]);
        break;
    }
    }
    return rc;
}
示例#13
0
static char *monitor_client_info(char id, struct s_client *cl, char *sbuf){
	char channame[32];
	sbuf[0] = '\0';

	if (cl){
		char ldate[16], ltime[16], *usr;
		int32_t lsec, isec, con, cau, lrt =- 1;
		time_t now;
		struct tm lt;
		now=time((time_t*)0);

		if	((cfg.hideclient_to <= 0) ||
				(now-cl->lastecm < cfg.hideclient_to) ||
				(now-cl->lastemm < cfg.hideclient_to) ||
				(cl->typ != 'c'))
		{
			lsec = now - cl->login;
			isec = now - cl->last;
			usr = username(cl);
			if (cl->dup)
				con = 2;
			else
				if ((cl->tosleep) && (now-cl->lastswitch>cl->tosleep))
					con = 1;
				else
					con = 0;

			// no AU reader == 0 / AU ok == 1 / Last EMM > aulow == -1
			if(cl->typ == 'c' || cl->typ == 'p' || cl->typ == 'r') {

				if ((cl->typ == 'c' && ll_count(cl->aureader_list) == 0) ||
						((cl->typ == 'p' || cl->typ == 'r') && cl->reader->audisabled))
					cau = 0;

				else if ((now-cl->lastemm) / 60 > cfg.aulow)
					cau = (-1);

				else
					cau = 1;

			} else {
				cau = 0;
			}

			if( cl->typ == 'r')
			{
				int32_t i;
				struct s_reader *rdr;
				for (i=0,rdr=first_active_reader; rdr ; rdr=rdr->next, i++)
					if (cl->reader == rdr)
						lrt=i;

				if( lrt >= 0 )
					lrt = 10 + cl->reader->card_status;
			}
			else
                lrt = cl->cwlastresptime;
			localtime_r(&cl->login, &lt);
			snprintf(ldate, sizeof(ldate), "%02d.%02d.%02d", lt.tm_mday, lt.tm_mon+1, lt.tm_year % 100);
			int32_t cnr=get_threadnum(cl);
			snprintf(ltime, sizeof(ldate), "%02d:%02d:%02d", lt.tm_hour, lt.tm_min, lt.tm_sec);
			snprintf(sbuf, 256, "[%c--CCC]%8X|%c|%d|%s|%d|%d|%s|%d|%s|%s|%s|%d|%04X:%04X|%s|%d|%d|%d|%d|%d|%d|%d|%d|%d|%d\n",
					id, cl->tid, cl->typ, cnr, usr, cau, cl->crypted,
					cs_inet_ntoa(cl->ip), cl->port, client_get_proto(cl),
					ldate, ltime, lsec, cl->last_caid, cl->last_srvid,
					get_servicename(cl, cl->last_srvid, cl->last_caid, channame), isec, con,
                                        cl->cwfound, cl->cwnot, cl->cwcache, cl->cwignored,
                                        cl->cwtout, cl->emmok, cl->emmnok, lrt);
		}
	}
	return sbuf;
}
示例#14
0
文件: commands.c 项目: hyper/rqd
//-----------------------------------------------------------------------------
// A request has been received for a queue.  We need take it and pass it to a
// node that can handle the request.
static void cmdRequest(void *base)
{
	node_t *node = (node_t *) base;
	message_t *msg;
	queue_t *q;
	stats_t *stats;

 	assert(node);
 	assert(node->handle >= 0);
	assert(node->sysdata);
	logger(node->sysdata->logging, 3,
		"node:%d REQUEST (flags:%x, mask:%x)", node->handle, node->data.flags, node->data.mask);

	assert(node->sysdata->queues);
	assert(node->sysdata->bufpool);

	// make sure we have the required data. At least payload, and a queueid or queue.
	if (BIT_TEST(node->data.mask, DATA_MASK_PAYLOAD) && (BIT_TEST(node->data.mask, DATA_MASK_QUEUE) || BIT_TEST(node->data.mask, DATA_MASK_QUEUEID))) {

		// create the message object to hold the data.
		assert(node->sysdata->msg_list);
		msg = next_message(node);
		assert(msg);

		// The node should have received a payload command.  It would have been
		// assigned to an appropriate buffer.  We need to move that buffer to the
		// message, where it will be handled from there.
		assert(node->data.payload);
		assert(msg->data == NULL);
		msg->data = node->data.payload;
		node->data.payload = NULL;
		
		// if message is NOREPLY, then we dont need some bits.  However, we will need to send a DELIVERED.
		if (BIT_TEST(node->data.flags, DATA_FLAG_NOREPLY)) {
			BIT_SET(msg->flags, FLAG_MSG_NOREPLY);
			assert(msg->source_id == 0);

			// the source_node would have been set when the message object was
			// obtained.  But since we dont want it in this mode, we set it to
			// NULL.
			assert(msg->source_node != NULL);
			msg->source_node = NULL;

			assert(BIT_TEST(node->data.mask, DATA_MASK_ID));
			sendDelivered(node, node->data.id);
		}
		else {
			assert(BIT_TEST(msg->flags, FLAG_MSG_NOREPLY) == 0);
		
			// make a note in the msg object, the source node. If a reply is
			// expected, a messageid should also have been supplied, use that for
			// the node_side.
			assert(msg->source_node == node);
			assert(BIT_TEST(node->data.mask, DATA_MASK_ID));
			message_set_origid(msg, node->data.id);
		}
		
		if (BIT_TEST(node->data.mask, DATA_MASK_TIMEOUT)) {
			// set the timeout... 
			message_set_timeout(msg, node->data.timeout);
		}
		
		// find the q object for this queue.
		if (BIT_TEST(node->data.mask, DATA_MASK_QUEUE)) {
			q = queue_get_name(node->sysdata->queues, expbuf_string(&node->data.queue));
		}
		else if (BIT_TEST(node->data.mask, DATA_MASK_QUEUEID)) {
			q = queue_get_id(node->sysdata->queues, node->data.qid);
		}
		else {
			assert(0);
		}
	
		if (q == NULL) {
			// we dont have a queue, so we will need to create one.
			q = queue_create(node->sysdata, expbuf_string(&node->data.queue));
		}
		assert(q);
		assert(ll_count(node->sysdata->queues) > 0);
		
		// add the message to the queue.

		logger(node->sysdata->logging, 2, "processRequest: node:%d, msg_id:%d, q:%d", node->handle, msg->id, q->qid);
		assert(q->sysdata);
		queue_addmsg(q, msg);

		stats = node->sysdata->stats;
		assert(stats);
		stats->requests ++;
	}
	else {
		// required data was not found.
		// need to return some sort of error
		assert(0);
	}
}
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);
}
示例#16
0
文件: stats.c 项目: hyper/rqd
static void stats_handler(int fd, short int flags, void *arg)
{
	stats_t *stats;
	system_data_t *sysdata;
	int clients;
	int queues;
	int msg_pending, msg_proc;
	queue_t *q;

	assert(fd < 0);
	assert((flags & EV_TIMEOUT) == EV_TIMEOUT);
	assert(arg);

	stats = arg;

	// clear the stats event.
	assert(stats->stats_event);
	event_free(stats->stats_event);
	stats->stats_event = NULL;
	
	assert(stats->sysdata);
	sysdata = stats->sysdata;
	
// 	assert(stats->sysdata->server != NULL);
// 	server = stats->sysdata->server;

	assert(sysdata->nodelist);
	clients = ll_count(sysdata->nodelist);

	queues = 0;
	msg_pending = 0;
	msg_proc = 0;
	ll_start(sysdata->queues);
	while ((q = ll_next(sysdata->queues))) {
		queues ++;
		msg_pending += ll_count(&q->msg_pending);
		msg_proc += ll_count(&q->msg_proc);
	}
	ll_finish(sysdata->queues);

	assert(stats != NULL);
	if (stats->in_bytes || stats->out_bytes || stats->requests || stats->replies || stats->broadcasts || stats->re || stats->we) {

		logger(sysdata->logging, 1, "Bytes[%u/%u], Clients[%u], Requests[%u], Replies[%u], Broadcasts[%u], Queues[%u], Msgs[%d/%d], MsgPool[%u/%u], Events[%u/%u/%u]",
			stats->in_bytes,
			stats->out_bytes,
			clients,
			stats->requests,
			stats->replies,
			stats->broadcasts,
			queues,
			msg_pending, msg_proc,
			sysdata->msg_used, sysdata->msg_max,
			stats->re, stats->we, stats->te);
		
		stats->in_bytes = 0;
		stats->out_bytes = 0;
		stats->requests = 0;
		stats->replies = 0;
		stats->broadcasts = 0;
		stats->re = 0;
		stats->we = 0;
		stats->te = 0;
	}

	// if we are not shutting down, then schedule the stats event again.
	if (stats->shutdown == 0) {
		stats_start(stats);
	}
}
示例#17
0
int mst_kruksal(struct vertex *arr1[],struct vertex *arr2[],int arg_weight,int nodes)
{
    int i,j,k=0,l=0,flag=0,first_flag1=1,count1=0,random_weight,vertex1,vertex2;
    struct vertex *temp1;
    int F[MAX-1][3];                 /* set of edges in min. span. tree */
    int num_edges = 0,edges=0;             /* num of edges in min. span. tree */
    int next_edge = 0;             /* next edge not yet considered */
    int weight = 0;                /* minimal spanning tree weight */
    int a,b,c;          /* counter/placeholder variables */

    for(i=0; i<nodes; i++)
    {
        temp1 = arr1[i];
        vertex1 = arr1[i]->vertex_id;
        count1 = ll_count(arr1[i]);
        first_flag1 = 1;
        for(j=0; j<count1; j++)
        {
            if(first_flag1 == 1)
            {
                first_flag1 = 0;
            }
            else
            {
                vertex2 = arr1[i]->vertex_id;
                mst_edge_matrix[k][0] = vertex1;          /* first vertex of edge */
                mst_edge_matrix[k][1] = vertex2;          /* second vertex of edge */
                random_weight = (1 + rand() % arg_weight);
                if(random_weight == 0)
                {
                    random_weight = arg_weight;
                }
                //printf("\nv1 %d",vertex1);
                //printf("\nv2 %d",vertex2);
                //printf("\nw1 %d",random_weight);
                for(l=0; l<k; l++)
                {
                    if((mst_edge_matrix[l][0] == vertex2) && (mst_edge_matrix[l][1] == vertex1))
                    {
                        //printf("\nmatch");
                        mst_edge_matrix[k][2] = mst_edge_matrix[l][2];    /* weight of edge */
                        flag = 1;
                        break;
                    }
                }
                if(flag != 1)
                {
                    mst_edge_matrix[k][2] = random_weight;
                }
                k++;
                flag = 0;

            }
            if(arr1[i]->next !=NULL)
            {
                arr1[i] = arr1[i]->next;
            }
        }
        arr1[i] = temp1;
    }
    edges = k;
    /* Display edges */
    printf("\n\n");
    printf("Edges with Weights:\n");
    printf("Edge\tEdge\tWeight\n");
    for (i = 0; i < edges; i++)
    {
        for (j = 0; j < 3; j++)
        {
            printf("%d\t", mst_edge_matrix[i][j]);
        }
        printf("\n");
    }

    for (i = edges - 1; i > 0; i--)
    {
        for (j = 0; j < i; j++)
        {
            if (mst_edge_matrix[j][2] > mst_edge_matrix[j+1][2])
            {
                a = mst_edge_matrix[j][0];
                b = mst_edge_matrix[j][1];
                c = mst_edge_matrix[j][2];
                mst_edge_matrix[j][0] = mst_edge_matrix[j+1][0];
                mst_edge_matrix[j][1] = mst_edge_matrix[j+1][1];
                mst_edge_matrix[j][2] = mst_edge_matrix[j+1][2];
                mst_edge_matrix[j+1][0] = a;
                mst_edge_matrix[j+1][1] = b;
                mst_edge_matrix[j+1][2] = c;
            }
        }
    }

    /* Display edges */
    /*printf("\n");
    for (i = 0; i < edges; i++)
    {
    	for (j = 0; j < 3; j++)
    	{
    		printf(" %3d", mst_edge_matrix[i][j]);
    	}
    	printf("\n");
    }*/
    /* create n disjoint subsets */
    mst_initial (nodes);

    /* initialize set of edges in min. span. tree to empty */
    for (i = 0; i < nodes - 1; i++)
    {
        for (j = 0; j < 3; j++)
        {
            F[i][j] = -1;            /* '-1' denotes 'empty' */
        }
    }
    //mst_test_univ(nodes);

    /* find minimal spanning tree */
    while (num_edges < nodes - 1)
    {
        a = mst_edge_matrix[next_edge][0];
        b = mst_edge_matrix[next_edge][1];

        i = mst_find(a);
        j = mst_find(b);

        if (!mst_equal(i, j))
        {
            mst_merge (i, j);
            F[num_edges][0] = mst_edge_matrix[next_edge][0];
            F[num_edges][1] = mst_edge_matrix[next_edge][1];
            F[num_edges][2] = mst_edge_matrix[next_edge][2];
            num_edges++;

            //mst_test_univ(nodes);
        }

        next_edge++;
    }

    /* display edges comprising minimal spanning tree */
    printf("\n");
    printf("\nMinimal Spanning Tree Edges:\n");
    printf("F = (");
    for (i = 0; i < nodes - 1; i++)
    {
        printf("(V%d,V%d)", F[i][0], F[i][1]);
        if (i < nodes - 2)
        {
            printf(", ");
        }
        printf("W:%d  ",F[i][2]);
        weight = weight + F[i][2];
    }
    printf(")\n");

    return weight;
}
示例#18
0
static int32_t ghttp_recv_chk(struct s_client *client, uchar *dcw, int32_t *rc, uchar *buf, int32_t n)
{
	char *data;
	char *hdrstr;
	uchar *content;
	int rcode, len, clen = 0;
	s_ghttp *context = (s_ghttp *)client->ghttp;
	ECM_REQUEST *er = NULL;

	if(n < 5) { return -1; }

	data = strstr((char *)buf, "HTTP/1.1 ");
	if(!data || ll_count(context->ecm_q) > 6)
	{
		cs_debug_mask(D_CLIENT, "%s: non http or otherwise corrupt response: %s", client->reader->label, buf);
		cs_ddump_mask(D_CLIENT, buf, n, "%s: ", client->reader->label);
		network_tcp_connection_close(client->reader, "receive error");
		NULLFREE(context->session_id);
		ll_clear(context->ecm_q);
		return -1;
	}

	LL_ITER itr = ll_iter_create(context->ecm_q);
	er = (ECM_REQUEST *)ll_iter_next(&itr);

	rcode = _get_int_header(buf, "HTTP/1.1 ");
	clen = _get_int_header(buf, "Content-Length: ");

	content = (uchar *)(strstr(data, "\r\n\r\n") + 4);

	hdrstr = _get_header_substr(buf, "ETag: \"", "\"\r\n");
	if(hdrstr)
	{
		NULLFREE(context->host_id);
		context->host_id = (uchar *)hdrstr;
		cs_debug_mask(D_CLIENT, "%s: new name: %s", client->reader->label, context->host_id);
		len = b64decode(context->host_id);
		if(len == 0 || len >= 64)
		{
			NULLFREE(context->host_id);
		}
		else
		{
			cs_debug_mask(D_CLIENT, "%s: redirected...", client->reader->label);
			NULLFREE(context->session_id);
			ll_clear_data(ghttp_ignored_contexts);
			ll_clear(context->ecm_q);
			return -1;
		}
	}

	hdrstr = _get_header_substr(buf, "ETag: W/\"", "\"\r\n");
	if(hdrstr)
	{
		NULLFREE(context->fallback_id);
		context->fallback_id = (uchar *)hdrstr;
		cs_debug_mask(D_CLIENT, "%s: new fallback name: %s", client->reader->label, context->fallback_id);
		len = b64decode(context->fallback_id);
		if(len == 0 || len >= 64)
		{
			NULLFREE(context->fallback_id);
		}
	}

	hdrstr = _get_header(buf, "Set-Cookie: GSSID=");
	if(hdrstr)
	{
		NULLFREE(context->session_id);
		context->session_id = (uchar *)hdrstr;
		cs_debug_mask(D_CLIENT, "%s: set session_id to: %s", client->reader->label, context->session_id);
	}

	// buf[n] = '\0';
	// cs_ddump_mask(D_TRACE, content, clen, "%s: reply\n%s", client->reader->label, buf);

	if(rcode < 200 || rcode > 204)
	{
		cs_debug_mask(D_CLIENT, "%s: http error code %d", client->reader->label, rcode);
		data = strstr((char *)buf, "Content-Type: application/octet-stream"); // if not octet-stream, google error. need reconnect?
		if(data)    // we have error info string in the post content
		{
			if(clen > 0)
			{
				content[clen] = '\0';
				cs_debug_mask(D_CLIENT, "%s: http error message: %s", client->reader->label, content);
			}
		}
		if(rcode == 503)
		{
			if(er && _is_post_context(context->post_contexts, er, false))
			{
				if(_swap_hosts(context))
				{
					cs_debug_mask(D_CLIENT, "%s: switching to fallback", client->reader->label);
				}
				else
				{
					cs_debug_mask(D_CLIENT, "%s: recv_chk got 503 despite post, trying reconnect", client->reader->label);
					network_tcp_connection_close(client->reader, "reconnect");
					ll_clear(context->ecm_q);
				}
			}
			else
			{
				// on 503 cache timeout, retry with POST immediately (and switch to POST for subsequent)
				if(er)
				{
					_set_pid_status(context->post_contexts, er->onid, er->tsid, er->srvid, 0);
					cs_debug_mask(D_CLIENT, "%s: recv_chk got 503, trying direct post", client->reader->label);
					_ghttp_post_ecmdata(client, er);
				}
			}
		}
		else if(rcode == 401)
		{
			NULLFREE(context->session_id);
			if(er)
			{
				cs_debug_mask(D_CLIENT, "%s: session expired, trying direct post", client->reader->label);
				_ghttp_post_ecmdata(client, er);
			}
		}
		else if(rcode == 403)
		{
			client->reader->enable = 0;
			network_tcp_connection_close(client->reader, "login failure");
			ll_clear(context->ecm_q);
			cs_log("%s: invalid username/password, disabling reader.", client->reader->label);
		}

		// not sure if this is needed on failure, copied from newcamd
		*rc = 0;
		memset(dcw, 0, 16);

		return -1;
	}

	// successful http reply (200 ok or 204 no content)

	hdrstr = _get_header(buf,  "Pragma: context-ignore=");
	if(hdrstr)
	{
		if(clen > 1)
		{
			cs_ddump_mask(D_CLIENT, content, clen, "%s: pmt ignore reply - %s (%d pids)", client->reader->label, hdrstr, clen / 2);
			uint32_t onid = 0, tsid = 0, sid = 0;
			if(sscanf(hdrstr, "%4x-%4x-%4x", &onid, &tsid, &sid) == 3)
				{ _set_pids_status(ghttp_ignored_contexts, onid, tsid, sid, content, clen); }
			NULLFREE(hdrstr);
			return -1;
		}
		NULLFREE(hdrstr);
	}

	data = strstr((char *)buf, "Pragma: context-ignore-clear");
	if(data)
	{
		cs_debug_mask(D_CLIENT, "%s: clearing local ignore list (size %d)", client->reader->label, ll_count(ghttp_ignored_contexts));
		ll_clear_data(ghttp_ignored_contexts);
	}

	// switch back to cache get after rapid ecm response (arbitrary atm), only effect is a slight bw save for client
	if(!er || _is_post_context(context->post_contexts, er, false))
	{
		data = strstr((char *)buf, "Pragma: cached");
		if(data || (client->cwlastresptime > 0 && client->cwlastresptime < 640))
		{
			cs_debug_mask(D_CLIENT, "%s: probably cached cw (%d ms), switching back to cache get for next req", client->reader->label, client->cwlastresptime);
			if(er) { _is_post_context(context->post_contexts, er, true); }
		}
	}

	if(clen == 16)    // cw in content
	{
		memcpy(dcw, content, 16);
		*rc = 1;
		er = ll_remove_first(context->ecm_q);
		if(!er) { return -1; }
		cs_ddump_mask(D_TRACE, dcw, 16, "%s: cw recv chk for idx %d", client->reader->label, er->idx);
		return er->idx;
	}
	else
	{
		if(clen != 0) { cs_ddump_mask(D_CLIENT, content, clen, "%s: recv_chk fail, clen = %d", client->reader->label, clen); }
	}
	return -1;
}
示例#19
0
文件: oscam-emm.c 项目: westaus/oscam
void do_emm(struct s_client * client, EMM_PACKET *ep)
{
	char *typtext[]={"unknown", "unique", "shared", "global"};
	char tmp[17];
	int32_t emmnok=0;

	struct s_reader *aureader = NULL;
	cs_ddump_mask(D_EMM, ep->emm, ep->emmlen, "emm:");

	int8_t cl_dvbapi = 0, assemble = 0;
#ifdef HAVE_DVBAPI
	cl_dvbapi = streq(cfg.dvbapi_usr, client->account->usr);
#endif
	if (client->account->emm_reassembly > 1 || (client->account->emm_reassembly && cl_dvbapi))
		assemble = 1;

	LL_ITER itr = ll_iter_create(client->aureader_list);
	while ((aureader = ll_iter_next(&itr))) {
		if (!aureader->enable)
			continue;

		uint16_t caid = b2i(2, ep->caid);
		uint32_t provid = b2i(4, ep->provid);

		if (aureader->audisabled) {
			rdr_debug_mask(aureader, D_EMM, "AU is disabled");
			/* we have to write the log for blocked EMM here because
			 this EMM never reach the reader module where the rest
			 of EMM log is done. */
			if (aureader->logemm & 0x10)  {
				rdr_log(aureader, "%s emmtype=%s, len=%d, idx=0, cnt=1: audisabled (0 ms)",
						client->account->usr,
						typtext[ep->type],
						ep->emm[2]);
			}
			continue;
		}

		if (!(aureader->grp & client->grp)) {
			rdr_debug_mask(aureader, D_EMM, "skip emm, group mismatch");
			continue;
		}

		//TODO: provider possibly not set yet, this is done in get_emm_type()
		if (!emm_reader_match(aureader, caid, provid))
			continue;

		struct s_cardsystem *cs = NULL;

		if (is_cascading_reader(aureader)) { // network reader (R_CAMD35 R_NEWCAMD R_CS378X R_CCCAM)
			if (!aureader->ph.c_send_emm) // no emm support
				continue;

			cs = get_cardsystem_by_caid(caid);
			if (!cs) {
				rdr_debug_mask(aureader, D_EMM, "unable to find cardsystem for caid %04X", caid);
				continue;
			}
		} else { // local reader
			if (aureader->csystem.active)
				cs=&aureader->csystem;
		}

		if (cs && cs->get_emm_type) {
			if (!cs->get_emm_type(ep, aureader)) {
				rdr_debug_mask(aureader, D_EMM, "emm skipped, get_emm_type() returns error");
				emmnok++;
				continue;
			}
		}

		if (cs && cs->get_emm_filter) {
			if (!do_simple_emm_filter(aureader, cs, ep)) {
				rdr_debug_mask(aureader, D_EMM, "emm skipped, emm_filter() returns invalid");
				emmnok++;
				continue;
			}
		}

		if (cs && cs->do_emm_reassembly) {
			if (assemble) {
				if (!cs->do_emm_reassembly(client, ep))
					return;
			} else {
				rdr_debug_mask(aureader, D_EMM, "processing raw emm");
			}
		}

		rdr_debug_mask_sensitive(aureader, D_EMM, "emmtype %s. Reader serial {%s}.", typtext[ep->type],
			cs_hexdump(0, aureader->hexserial, 8, tmp, sizeof(tmp)));
		rdr_debug_mask_sensitive(aureader, D_EMM, "emm UA/SA: {%s}.",
			cs_hexdump(0, ep->hexserial, 8, tmp, sizeof(tmp)));

		client->last = time(NULL);
		saveemm(aureader, ep);

		int32_t is_blocked = 0;
		switch (ep->type) {
			case UNKNOWN: is_blocked = (aureader->blockemm & EMM_UNKNOWN) == EMM_UNKNOWN; break;
			case UNIQUE : is_blocked = (aureader->blockemm & EMM_UNIQUE ) == EMM_UNIQUE;  break;
			case SHARED : is_blocked = (aureader->blockemm & EMM_SHARED ) == EMM_SHARED;  break;
			case GLOBAL : is_blocked = (aureader->blockemm & EMM_GLOBAL ) == EMM_GLOBAL;  break;
		}

		// if not already blocked we check for block by len
		if (!is_blocked) is_blocked = cs_emmlen_is_blocked( aureader, ep->emm[2] ) ;

		if (is_blocked != 0) {
#ifdef WEBIF
			aureader->emmblocked[ep->type]++;
			is_blocked = aureader->emmblocked[ep->type];
#endif
			/* we have to write the log for blocked EMM here because
			 this EMM never reach the reader module where the rest
			 of EMM log is done. */
			if (aureader->logemm & 0x08)  {
				rdr_log(aureader, "%s emmtype=%s, len=%d, idx=0, cnt=%d: blocked (0 ms)",
						client->account->usr,
						typtext[ep->type],
						ep->emm[2],
						is_blocked);
			}
			continue;
		}

		client->lastemm = time((time_t*)0);

		client->emmok++;
		if (client->account)
			client->account->emmok++;
		first_client->emmok++;

		//Check emmcache early:
		int32_t i;
		unsigned char md5tmp[CS_EMMSTORESIZE];
		struct s_client *au_cl = aureader->client;

		MD5(ep->emm, ep->emm[2], md5tmp);
		ep->client = client;

		for (i=0; i<CS_EMMCACHESIZE; i++) {
			if (!memcmp(au_cl->emmcache[i].emmd5, md5tmp, CS_EMMSTORESIZE)) {
				rdr_debug_mask(aureader, D_EMM, "emm found in cache: count %d rewrite %d",
					au_cl->emmcache[i].count, aureader->rewritemm);
				if (aureader->cachemm && (au_cl->emmcache[i].count > aureader->rewritemm)) {
					reader_log_emm(aureader, ep, i, 2, NULL);
					return;
				}
				break;
			}
		}

		EMM_PACKET *emm_pack;
		if (cs_malloc(&emm_pack, sizeof(EMM_PACKET))) {
			rdr_debug_mask(aureader, D_EMM, "emm is being sent to reader");
			memcpy(emm_pack, ep, sizeof(EMM_PACKET));
			add_job(aureader->client, ACTION_READER_EMM, emm_pack, sizeof(EMM_PACKET));
		}
	}
	if (emmnok > 0 && emmnok == ll_count(client->aureader_list)) {
		client->emmnok++;
		if (client->account)
			client->account->emmnok++;
		first_client->emmnok++;
	}
}
示例#20
0
文件: commands.c 项目: hyper/rqd
static void cmdDelivered(void *base)
{
	node_t *node = (node_t *) base;
	msg_id_t msgid;
	message_t *msg;
	queue_t *q;
 	
 	assert(node);
	assert(node->sysdata);
	logger(node->sysdata->logging, 3, 
		"node:%d DELIVERED (flags:%x, mask:%x)",
		node->handle, node->data.flags, node->data.mask);

	// get the messageID
	assert(BIT_TEST(node->data.mask, DATA_MASK_ID));
	msgid = node->data.id;
	assert(msgid >= 0);

	logger(node->sysdata->logging, 2, "processDelivered.  Node:%d, msg_id:%d", node->handle, msgid);

	// find message in node->out_msg
	msg = node_findoutmsg(node, msgid);
	if (msg == NULL) {
		// didn't find the message that is being marked as delivered.
		assert(0);
	}
	else {

		if (BIT_TEST(msg->flags, FLAG_MSG_NOREPLY)) {
			// message is NOREPLY,

			logger(node->sysdata->logging, 2, "delivery(%d): Noreply.", msgid);
		
			// assert that message doesnt have source-node.
			assert(msg->source_node == NULL);
			
			// tell the queue that the node has finished processing a message.  This
			// will find the node, and remove it from the node_busy list.
			assert(msg->queue);
			assert(msg->target_node);
			queue_msg_done(msg->queue, msg->target_node);
						
			// then remove from the queue->msg_proc list
			assert(msg->queue);
			q = msg->queue;
			ll_remove(&q->msg_proc, msg);
			msg->queue = NULL;
			
			// set action to remove the message.
			assert(BIT_TEST(msg->flags, FLAG_MSG_ACTIVE));
			message_clear(msg);
			assert(node->sysdata->msg_used > 0);
			node->sysdata->msg_used --;
			assert(node->sysdata->msg_used >= 0);
			node->sysdata->msg_next = msg->id;

			// if there are more messages in the queue, then we need to deliver them.
			if (ll_count(&q->msg_pending) > 0) {
				logger(node->sysdata->logging, 2, "delivery(%d): setting delivery action.", msgid);
				queue_deliver(q);
			}
			else {
				logger(node->sysdata->logging, 2, "delivery(%d): no items to deliver.", msgid);
			}
		}
		else {
			// message is expecting a reply, so we need to tell the source that it was delivered.
			
			// mark the message as delivered.
			assert(BIT_TEST(msg->flags, FLAG_MSG_DELIVERED) == 0);
			BIT_SET(msg->flags, FLAG_MSG_DELIVERED);

			// send delivery message back to source.
			assert(msg->source_node);
			assert(msg->source_id >= 0);
			sendDelivered(msg->source_node, msg->source_id);

			// but we dont need to original payload anymore, so we can release that back into the bufpool.
			assert(msg->data);
			assert(node->sysdata);
			assert(node->sysdata->bufpool);
			expbuf_clear(msg->data);
			expbuf_pool_return(node->sysdata->bufpool, msg->data);
			msg->data = NULL;
		}
	}
}
示例#21
0
文件: commands.c 项目: hyper/rqd
//-----------------------------------------------------------------------------
// When a node indicates that it wants to consume a queue,the node needs to be
// added to the queue list.  If this is the first time this queue is being
// consumed, then we need to create an action so that it can be consumed on
// other servers.
static void cmdConsume(void *base)
{
	node_t *node = (node_t *) base;
 	queue_t *q=NULL;
 	int max;
 	int priority;
 	unsigned int qflags;
 	
 	assert(node);
	assert(node->sysdata);
	logger(node->sysdata->logging, 3,
		"node:%d CONSUME (flags:%x, mask:%x)",
		node->handle, node->data.flags, node->data.mask);

	// make sure that we have the minimum information that we need.
	if (BIT_TEST(node->data.mask, DATA_MASK_QUEUE)) {

		logger(node->sysdata->logging, 2, 
			"Processing QUEUE request from node:%d", node->handle);

		assert(BIT_TEST(node->data.mask, DATA_MASK_QUEUE));
		assert(BUF_LENGTH(&node->data.queue) > 0);
	
		// check to see if we already have a queue with this name, in our list.		
		assert(q == NULL);
		if (node->sysdata->queues)
			q = queue_get_name(node->sysdata->queues, expbuf_string(&node->data.queue));
		
		if (q == NULL) {
			// we didn't find the queue...
			logger(node->sysdata->logging, 2, 
				"Didn't find queue '%s', creating new entry.", expbuf_string(&node->data.queue));
			q = queue_create(node->sysdata, expbuf_string(&node->data.queue));
		}
	
	
		// at this point we have a queue object.  We dont yet know if this
		// consumption request can continue, because we haven't looked at the
		// queue options.
		assert(q != NULL);

		max = 0;
		priority = 0;
		qflags = 0;

		if (BIT_TEST(node->data.mask, DATA_MASK_MAX))
			max = node->data.max;
			
		if (BIT_TEST(node->data.mask, DATA_MASK_PRIORITY))
			priority = node->data.priority;
			
		if (BIT_TEST(node->data.flags, DATA_FLAG_EXCLUSIVE))
			BIT_SET(qflags, QUEUE_FLAG_EXCLUSIVE);
		
		if (queue_add_node(q, node, max, priority, qflags) > 0) {
			// send reply back to the node.
			sendConsumeReply(node, q->name, q->qid);
		}

		// need to check the queue to see if there are messages pending.  If there
		// are, then send some to this node.
		if (ll_count(&q->msg_pending) > 0) {
			queue_deliver(q);
		}
	}
}
示例#22
0
文件: commands.c 项目: hyper/rqd
static void cmdReply(void *base)
{
	node_t *node = (node_t *) base;
	msg_id_t id;
	message_t *msg;
	stats_t *stats;
	queue_t *q;

 	assert(node);
	assert(node->handle >= 0);
	assert(node->sysdata);
	logger(node->sysdata->logging, 3, 
		"node:%d REPLY (flags:%x, mask:%x)", node->handle, node->data.flags, node->data.mask);

	// make sure that we have the minimum information that we need.
	if (BIT_TEST(node->data.mask, DATA_MASK_ID) && BIT_TEST(node->data.mask, DATA_MASK_PAYLOAD)) {

		id = node->data.id;
		assert(id >= 0);

		// find the message that the reply belongs to.
		assert(node->sysdata);
		assert(node->sysdata->msg_list);
		assert(id < node->sysdata->msg_max);
		msg = node->sysdata->msg_list[id];
		assert(msg);
		assert(msg->id == id);
		assert(BIT_TEST(msg->flags, FLAG_MSG_ACTIVE));
		assert(msg->target_node == node);

		// apply the payload which is part of the reply, replacing the payload which was the request.
		assert(node->sysdata);
		assert(node->sysdata->bufpool);
		assert(node->data.payload);
		assert(msg->data == NULL);
		msg->data = node->data.payload;
		node->data.payload = NULL;
		
		// send the payload to the source node of the message.
		assert(msg->source_node);
		sendReply(msg->source_node, msg);

		// tell the queue that the node has finished processing a message.  This
		// will find the node, and remove it from the node_busy list.
		assert(msg->queue);
		assert(msg->target_node);
		queue_msg_done(msg->queue, msg->target_node);

		// then remove from the queue->msg_proc list
		assert(msg->queue);
		q = msg->queue;
		ll_remove(&q->msg_proc, msg);
		msg->queue = NULL;

		assert(msg->data);
		assert(node->sysdata);
		assert(node->sysdata->bufpool);
		expbuf_clear(msg->data);
		expbuf_pool_return(node->sysdata->bufpool, msg->data);
		msg->data = NULL;


		// set action to remove the message.
		msg->source_node = NULL;
		msg->target_node = NULL;
		assert(BIT_TEST(msg->flags, FLAG_MSG_ACTIVE));
		message_clear(msg);
		assert(node->sysdata->msg_used > 0);
		node->sysdata->msg_used --;
		assert(node->sysdata->msg_used >= 0);
		node->sysdata->msg_next = msg->id;

		// if there are more messages in the queue, then we need to deliver them.
		if (ll_count(&q->msg_pending) > 0) {
			logger(node->sysdata->logging, 2, "delivery: setting delivery action.");
			queue_deliver(q);
		}
		else {
			logger(node->sysdata->logging, 2, "delivery: no items to deliver.");
		}


		stats = node->sysdata->stats;
		assert(stats);
		stats->replies ++;
	}
	else {
		// we should handle failure a bit better, and log the information.
		assert(0);
	}
	
}
示例#23
0
void *work_thread(void *ptr)
{
	struct job_data *data = (struct job_data *)ptr;
	struct s_client *cl = data->cl;
	struct s_reader *reader = cl->reader;
	struct timeb start, end;  // start time poll, end time poll

	struct job_data tmp_data;
	struct pollfd pfd[1];

	pthread_setspecific(getclient, cl);
	cl->thread = pthread_self();
	cl->thread_active = 1;

	set_work_thread_name(data);

	struct s_module *module = get_module(cl);
	uint16_t bufsize = module->bufsize; //CCCam needs more than 1024bytes!
	if(!bufsize)
		{ bufsize = 1024; }

	uint8_t *mbuf;
	if(!cs_malloc(&mbuf, bufsize))
		{ return NULL; }
	cl->work_mbuf = mbuf; // Track locally allocated data, because some callback may call cs_exit/cs_disconect_client/pthread_exit and then mbuf would be leaked
	int32_t n = 0, rc = 0, i, idx, s;
	uint8_t dcw[16];
	int8_t restart_reader = 0;
	while(cl->thread_active)
	{
		cs_ftime(&start); // register start time
		while(cl->thread_active)
		{
			if(!cl || cl->kill || !is_valid_client(cl))
			{
				pthread_mutex_lock(&cl->thread_lock);
				cl->thread_active = 0;
				pthread_mutex_unlock(&cl->thread_lock);
				cs_debug_mask(D_TRACE, "ending thread (kill)");
				__free_job_data(cl, data);
				cl->work_mbuf = NULL; // Prevent free_client from freeing mbuf (->work_mbuf)
				free_client(cl);
				if(restart_reader)
					{ restart_cardreader(reader, 0); }
				NULLFREE(mbuf);
				pthread_exit(NULL);
				return NULL;
			}

			if(data && data->action != ACTION_READER_CHECK_HEALTH)
				{ cs_debug_mask(D_TRACE, "data from add_job action=%d client %c %s", data->action, cl->typ, username(cl)); }

			if(!data)
			{
				if(!cl->kill && cl->typ != 'r')
					{ client_check_status(cl); } // do not call for physical readers as this might cause an endless job loop
				pthread_mutex_lock(&cl->thread_lock);
				if(cl->joblist && ll_count(cl->joblist) > 0)
				{
					LL_ITER itr = ll_iter_create(cl->joblist);
					data = ll_iter_next_remove(&itr);
					if(data)
						{ set_work_thread_name(data); }
					//cs_debug_mask(D_TRACE, "start next job from list action=%d", data->action);
				}
				pthread_mutex_unlock(&cl->thread_lock);
			}

			if(!data)
			{
				/* for serial client cl->pfd is file descriptor for serial port not socket
				   for example: pfd=open("/dev/ttyUSB0"); */
				if(!cl->pfd || module->listenertype == LIS_SERIAL)
					{ break; }
				pfd[0].fd = cl->pfd;
				pfd[0].events = POLLIN | POLLPRI;

				pthread_mutex_lock(&cl->thread_lock);
				cl->thread_active = 2;
				pthread_mutex_unlock(&cl->thread_lock);
				rc = poll(pfd, 1, 3000);
				pthread_mutex_lock(&cl->thread_lock);
				cl->thread_active = 1;
				pthread_mutex_unlock(&cl->thread_lock);
				if(rc > 0)
				{
					cs_ftime(&end); // register end time
					cs_debug_mask(D_TRACE, "[OSCAM-WORK] new event %d occurred on fd %d after %"PRId64" ms inactivity", pfd[0].revents,
								  pfd[0].fd, comp_timeb(&end, &start));
					data = &tmp_data;
					data->ptr = NULL;
					cs_ftime(&start); // register start time for new poll next run

					if(reader)
						{ data->action = ACTION_READER_REMOTE; }
					else
					{
						if(cl->is_udp)
						{
							data->action = ACTION_CLIENT_UDP;
							data->ptr = mbuf;
							data->len = bufsize;
						}
						else
							{ data->action = ACTION_CLIENT_TCP; }
						if(pfd[0].revents & (POLLHUP | POLLNVAL | POLLERR))
							{ cl->kill = 1; }
					}
				}
			}

			if(!data)
				{ continue; }

			if(!reader && data->action < ACTION_CLIENT_FIRST)
			{
				__free_job_data(cl, data);
				break;
			}

			if(!data->action)
				{ break; }

			struct timeb actualtime;
			cs_ftime(&actualtime);
			int32_t gone = comp_timeb(&actualtime, &data->time);
			if(data != &tmp_data && gone > (int) cfg.ctimeout+1000)
			{
				cs_debug_mask(D_TRACE, "dropping client data for %s time %dms", username(cl), gone);
				__free_job_data(cl, data);
				continue;
			}

			if(data != &tmp_data)
				{ cl->work_job_data = data; } // Track the current job_data
			switch(data->action)
			{
			case ACTION_READER_IDLE:
				reader_do_idle(reader);
				break;
			case ACTION_READER_REMOTE:
				s = check_fd_for_data(cl->pfd);
				if(s == 0)  // no data, another thread already read from fd?
					{ break; }
				if(s < 0)
				{
					if(reader->ph.type == MOD_CONN_TCP)
						{ network_tcp_connection_close(reader, "disconnect"); }
					break;
				}
				rc = reader->ph.recv(cl, mbuf, bufsize);
				if(rc < 0)
				{
					if(reader->ph.type == MOD_CONN_TCP)
						{ network_tcp_connection_close(reader, "disconnect on receive"); }
					break;
				}
				cl->last = time(NULL); // *********************************** TO BE REPLACE BY CS_FTIME() LATER ****************
				idx = reader->ph.c_recv_chk(cl, dcw, &rc, mbuf, rc);
				if(idx < 0) { break; }  // no dcw received
				if(!idx) { idx = cl->last_idx; }
				reader->last_g = time(NULL); // *********************************** TO BE REPLACE BY CS_FTIME() LATER **************** // for reconnect timeout
				for(i = 0, n = 0; i < cfg.max_pending && n == 0; i++)
				{
					if(cl->ecmtask[i].idx == idx)
					{
						cl->pending--;
						casc_check_dcw(reader, i, rc, dcw);
						n++;
					}
				}
				break;
			case ACTION_READER_RESET:
				cardreader_do_reset(reader);
				break;
			case ACTION_READER_ECM_REQUEST:
				reader_get_ecm(reader, data->ptr);
				break;
			case ACTION_READER_EMM:
				reader_do_emm(reader, data->ptr);
				break;
			case ACTION_READER_CARDINFO:
				reader_do_card_info(reader);
				break;
			case ACTION_READER_INIT:
				if(!cl->init_done)
					{ reader_init(reader); }
				break;
			case ACTION_READER_RESTART:
				cl->kill = 1;
				restart_reader = 1;
				break;
			case ACTION_READER_RESET_FAST:
				reader->card_status = CARD_NEED_INIT;
				cardreader_do_reset(reader);
				break;
			case ACTION_READER_CHECK_HEALTH:
				cardreader_do_checkhealth(reader);
				break;
			case ACTION_READER_CAPMT_NOTIFY:
				if(reader->ph.c_capmt) { reader->ph.c_capmt(cl, data->ptr); }
				break;
			case ACTION_CLIENT_UDP:
				n = module->recv(cl, data->ptr, data->len);
				if(n < 0) { break; }
				module->s_handler(cl, data->ptr, n);
				break;
			case ACTION_CLIENT_TCP:
				s = check_fd_for_data(cl->pfd);
				if(s == 0)  // no data, another thread already read from fd?
					{ break; }
				if(s < 0)    // system error or fd wants to be closed
				{
					cl->kill = 1; // kill client on next run
					continue;
				}
				n = module->recv(cl, mbuf, bufsize);
				if(n < 0)
				{
					cl->kill = 1; // kill client on next run
					continue;
				}
				module->s_handler(cl, mbuf, n);
				break;
			case ACTION_CACHEEX_TIMEOUT:
#ifdef CS_CACHEEX
				cacheex_timeout(data->ptr);
#endif
				break;
			case ACTION_FALLBACK_TIMEOUT:
				fallback_timeout(data->ptr);
				break;
			case ACTION_CLIENT_TIMEOUT:
				ecm_timeout(data->ptr);
				break;
			case ACTION_ECM_ANSWER_READER:
				chk_dcw(data->ptr);
				break;
			case ACTION_ECM_ANSWER_CACHE:
				write_ecm_answer_fromcache(data->ptr);
				break;
			case ACTION_CLIENT_INIT:
				if(module->s_init)
					{ module->s_init(cl); }
				cl->is_udp = module->type == MOD_CONN_UDP;
				cl->init_done = 1;
				break;
			case ACTION_CLIENT_IDLE:
				if(module->s_idle)
					{ module->s_idle(cl); }
				else
				{
					cs_log("user %s reached %d sec idle limit.", username(cl), cfg.cmaxidle);
					cl->kill = 1;
				}
				break;
			case ACTION_CACHE_PUSH_OUT:
			{
#ifdef CS_CACHEEX
				ECM_REQUEST *er = data->ptr;
				int32_t res = 0, stats = -1;
				// cc-nodeid-list-check
				if(reader)
				{
					if(reader->ph.c_cache_push_chk && !reader->ph.c_cache_push_chk(cl, er))
						{ break; }
					res = reader->ph.c_cache_push(cl, er);
					stats = cacheex_add_stats(cl, er->caid, er->srvid, er->prid, 0);
				}
				else
				{
					if(module->c_cache_push_chk && !module->c_cache_push_chk(cl, er))
						{ break; }
					res = module->c_cache_push(cl, er);
				}
				debug_ecm(D_CACHEEX, "pushed ECM %s to %s res %d stats %d", buf, username(cl), res, stats);
				cl->cwcacheexpush++;
				if(cl->account)
					{ cl->account->cwcacheexpush++; }
				first_client->cwcacheexpush++;
#endif
				break;
			}
			case ACTION_CLIENT_KILL:
				cl->kill = 1;
				break;
			case ACTION_CLIENT_SEND_MSG:
			{
#ifdef MODULE_CCCAM
				struct s_clientmsg *clientmsg = (struct s_clientmsg *)data->ptr;
				cc_cmd_send(cl, clientmsg->msg, clientmsg->len, clientmsg->cmd);
#endif
				break;
			}
			} // switch

			__free_job_data(cl, data);
		}

		if(thread_pipe[1] && (mbuf[0] != 0x00))
		{
			cs_ddump_mask(D_TRACE, mbuf, 1, "[OSCAM-WORK] Write to pipe:");
			if(write(thread_pipe[1], mbuf, 1) == -1)    // wakeup client check
			{
				cs_debug_mask(D_TRACE, "[OSCAM-WORK] Writing to pipe failed (errno=%d %s)", errno, strerror(errno));
			}
		}

		// Check for some race condition where while we ended, another thread added a job
		pthread_mutex_lock(&cl->thread_lock);
		if(cl->joblist && ll_count(cl->joblist) > 0)
		{
			pthread_mutex_unlock(&cl->thread_lock);
			continue;
		}
		else
		{
			cl->thread_active = 0;
			pthread_mutex_unlock(&cl->thread_lock);
			break;
		}
	}
	cl->thread_active = 0;
	cl->work_mbuf = NULL; // Prevent free_client from freeing mbuf (->work_mbuf)
	NULLFREE(mbuf);
	pthread_exit(NULL);
	return NULL;
}
示例#24
0
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);
}
static int32_t cc_cacheex_push_out(struct s_client *cl, struct ecm_request_t *er)
{
	int8_t rc = (er->rc < E_NOTFOUND) ? E_FOUND : er->rc;
	if(rc != E_FOUND && rc != E_UNHANDLED) { return -1; }  //Maybe later we could support other rcs

	if(cl->reader)
	{
		if(!cl->reader->tcp_connected)
			{ cc_cli_connect(cl); }
	}

	struct cc_data *cc = cl->cc;
	if(!cc || !cl->udp_fd)
	{
		cs_log_dbg(D_CACHEEX, "cacheex: not connected %s -> no push", username(cl));
		return (-1);
	}

	uint32_t size = sizeof(er->ecmd5) + sizeof(er->csp_hash) + sizeof(er->cw) + sizeof(uint8_t) +
					(ll_count(er->csp_lastnodes) + 1) * 8;

	unsigned char *buf;
	if(!cs_malloc(&buf, size + 20))  //camd35_send() adds +20
		{ return -1; }

	// build ecm message
	//buf[0] = er->caid >> 8;
	//buf[1] = er->caid & 0xff;
	//buf[2] = er->prid >> 24;
	//buf[3] = er->prid >> 16;
	//buf[4] = er->prid >> 8;
	//buf[5] = er->prid & 0xff;
	//buf[10] = er->srvid >> 8;
	//buf[11] = er->srvid & 0xff;
	buf[12] = (sizeof(er->ecmd5) + sizeof(er->csp_hash) + sizeof(er->cw)) & 0xff;
	buf[13] = (sizeof(er->ecmd5) + sizeof(er->csp_hash) + sizeof(er->cw)) >> 8;
	//buf[12] = 0;
	//buf[13] = 0;
	buf[14] = rc;

	i2b_buf(2, er->caid, buf + 0);
	i2b_buf(4, er->prid, buf + 2);
	i2b_buf(2, er->srvid, buf + 10);

	if(er->cwc_cycletime && er->cwc_next_cw_cycle < 2)
	{
		buf[18] = er->cwc_cycletime; // contains cwc stage3 cycletime
		if(er->cwc_next_cw_cycle == 1)
		{ buf[18] = (buf[18] | 0x80); } // set bit 8 to high

		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) push to %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);
	}

	buf[19] = er->ecm[0] != 0x80 && er->ecm[0] != 0x81 ? 0 : er->ecm[0];

	uint8_t *ofs = buf + 20;

	//write oscam ecmd5:
	memcpy(ofs, er->ecmd5, sizeof(er->ecmd5)); //16
	ofs += sizeof(er->ecmd5);

	//write csp hashcode:
	i2b_buf(4, htonl(er->csp_hash), ofs);
	ofs += 4;

	//write cw:
	memcpy(ofs, er->cw, sizeof(er->cw)); //16
	ofs += sizeof(er->cw);

	//write node count:
	*ofs = ll_count(er->csp_lastnodes) + 1;
	ofs++;

	//write own node:
	memcpy(ofs, cc->node_id, 8);
	ofs += 8;

	//write other nodes:
	LL_LOCKITER *li = ll_li_create(er->csp_lastnodes, 0);
	uint8_t *node;
	while((node = ll_li_next(li)))
	{
		memcpy(ofs, node, 8);
		ofs += 8;
	}
	ll_li_destroy(li);

	int32_t res = cc_cmd_send(cl, buf, size + 20, MSG_CACHE_PUSH);
	if(res > 0)   // cache-ex is pushing out, so no receive but last_g should be updated otherwise disconnect!
	{
		if(cl->reader)
			{ cl->reader->last_s = cl->reader->last_g = time((time_t *)0); } // correct
		if(cl) { cl->last = time(NULL); }
	}
	NULLFREE(buf);
	return res;
}
示例#26
0
void printZlibInfo(const std::vector<unsigned char>& in, const Options& options)
{
  if(!options.zlib_info && !options.zlib_blocks) return;

  std::vector<lodepng::ZlibBlockInfo> zlibinfo;
  lodepng::extractZlibInfo(zlibinfo, in);

  if(options.zlib_info)
  {
    //std::cout << "Zlib info: " << std::endl;
    size_t compressed = 0;
    size_t uncompressed = 0;
    std::vector<size_t> boundaries_compressed;
    std::vector<size_t> boundaries_uncompressed;
    for(size_t i = 0; i < zlibinfo.size(); i++)
    {
      compressed += zlibinfo[i].compressedbits / 8;
      uncompressed += zlibinfo[i].uncompressedbytes;
      boundaries_compressed.push_back(compressed);
      boundaries_uncompressed.push_back(uncompressed);
    }

    std::cout << "Compressed size: " << compressed << std::endl;
    std::cout << "Uncompressed size: " << uncompressed << std::endl;
    std::cout << "Amount of zlib blocks: " << zlibinfo.size() << std::endl;
    if(zlibinfo.size() > 1)
    {
      std::cout << "Block sizes (uncompressed): ";
      for(size_t i = 0; i < zlibinfo.size(); i++)
          std::cout << zlibinfo[i].uncompressedbytes << " ";
      std::cout << std::endl;
      std::cout << "Block sizes (compressed): ";
      for(size_t i = 0; i < zlibinfo.size(); i++)
          std::cout << (zlibinfo[i].compressedbits / 8) << " ";
      std::cout << std::endl;
      std::cout << "Block boundaries (uncompressed): ";
      for(size_t i = 0; i + 1 < boundaries_uncompressed.size(); i++)
          std::cout << boundaries_uncompressed[i] << " ";
      std::cout << std::endl;
      std::cout << "Block boundaries (compressed): ";
      for(size_t i = 0; i + 1 < boundaries_compressed.size(); i++)
          std::cout << boundaries_compressed[i] << " ";
      std::cout << std::endl;
    }
  }

  if(options.zlib_blocks)
  {
    for(size_t i = 0; i < zlibinfo.size(); i++)
    {
      const lodepng::ZlibBlockInfo& info = zlibinfo[i];

      std::cout << "Zlib block " << i << ":" << std::endl;
      std::cout << " block type: " << info.btype << std::endl;

      size_t compressedsize = info.compressedbits / 8;
      size_t uncompressedsize = info.uncompressedbytes;
      std::cout << " block compressed: " << compressedsize << " (" << compressedsize / 1024 << "K) (" << info.compressedbits << " bits)" << std::endl;
      std::cout << " block uncompressed: " << uncompressedsize << " (" << uncompressedsize / 1024 << "K)" << std::endl;

      if(info.btype > 2)
      {
        std::cout << "Error: Invalid Block Type" << std::endl;
        return;
      }

      if(info.btype == 2)
      {
        std::cout << " encoded trees size: " << info.treebits / 8 << " (" << info.treebits << " bits)" << std::endl;
        std::cout << " HLIT: " << info.hlit << std::endl;
        std::cout << " HDIST: " << info.hdist << std::endl;
        std::cout << " HCLEN: " << info.hclen << std::endl;
        std::cout << std::hex;
        std::cout << " code length code lengths: "; for(size_t j = 0; j < 19; j++) std::cout << info.clcl[j]; std::cout << std::endl;
        if(!options.use_hex) std::cout << std::dec;
        if(options.zlib_full)
        {
          for(size_t j = 0; j < info.treecodes.size(); j++)
          {
            int code = info.treecodes[j];
            if(code < 17)
            {
               std::cout << " tree: " << code << std::endl;
            }
            else
            {
              j++;
              std::cout << " tree: " << code << " rep: " << info.treecodes[j] << std::endl;
            }
            
          }
        }

        std::cout << std::hex;
        std::cout << " lit code lengths 0-127  : "; for(size_t j = 0; j < 128; j++) std::cout << info.litlenlengths[j]; std::cout << std::endl;
        std::cout << " lit code lengths 128-255: "; for(size_t j = 128; j < 256; j++) std::cout << info.litlenlengths[j]; std::cout << std::endl;
        std::cout << " end code length         : "; std::cout << info.litlenlengths[256]; std::cout << std::endl;
        std::cout << " len code lengths        : "; for(size_t j = 257; j < 288; j++) std::cout << info.litlenlengths[j]; std::cout << std::endl;
        std::cout << " dist code lengths       : "; for(size_t j = 0; j < 32; j++) std::cout << info.distlengths[j]; std::cout << std::endl;
        if(!options.use_hex) std::cout << std::dec;
      }
      

      if(info.btype != 0)
      {
        std::cout << " code counts: lit: " << info.numlit << ", len/dist: " << info.numlen << ", total: " << (info.numlit + info.numlen + 1) << ", with dists: " << (info.numlit + 2 * info.numlen + 1) << std::endl;

        if(options.zlib_full)
        {
          for(size_t j = 0; j < info.lz77_lcode.size(); j++)
          {
            int symbol = info.lz77_lcode[j];
            if(symbol == 256)
            {
              std::cout << " end" << std::endl;
            }
            else if(symbol < 256)
            {
              std::cout << " lit: " << symbol << std::endl;
            }
            else
            {
              std::cout << " len: " << info.lz77_lvalue[j] << ", dist: " << info.lz77_dvalue[j] << std::endl;
            }
          }
        }

        if(options.zlib_counts)
        {
          std::vector<size_t> ll_count(288, 0);
          std::vector<size_t> d_count(32, 0);
          for(size_t j = 0; j < info.lz77_lcode.size(); j++)
          {
            int symbol = info.lz77_lcode[j];
            if(symbol <= 256)
            {
              ll_count[symbol]++;
            }
            else
            {
              ll_count[symbol]++;
              d_count[info.lz77_dcode[j]]++;
            }
          }
          std::cout << " lit code 0-63 counts   : "; for(size_t j = 0; j < 64; j++) std::cout << ll_count[j] << " "; std::cout << std::endl;
          std::cout << " lit code 64-127 counts : "; for(size_t j = 64; j < 128; j++) std::cout << ll_count[j] << " "; std::cout << std::endl;
          std::cout << " lit code 128-191 counts: "; for(size_t j = 128; j < 192; j++) std::cout << ll_count[j] << " "; std::cout << std::endl;
          std::cout << " lit code 192-255 counts: "; for(size_t j = 192; j < 256; j++) std::cout << ll_count[j] << " "; std::cout << std::endl;
          std::cout << " end code count         : "; std::cout << ll_count[256] << " "; std::cout << std::endl;
          std::cout << " len code counts        : "; for(size_t j = 257; j < 288; j++) std::cout << ll_count[j] << " "; std::cout << std::endl;
          std::cout << " dist code counts       : "; for(size_t j = 0; j < 32; j++) std::cout << d_count[j] << " "; std::cout << std::endl;
        }
      }
    }
  }
}
示例#27
0
static void refresh_lcd_file(void) {
	char targetfile[256];
	char tmpfile[256];
	char channame[32];

	if(cfg.lcd_output_path == NULL){
		snprintf(targetfile, sizeof(targetfile),"%s%s", get_tmp_dir(), "/oscam.lcd");
		snprintf(tmpfile, sizeof(tmpfile), "%s%s.tmp", get_tmp_dir(), "/oscam.lcd");
	} else {
		snprintf(targetfile, sizeof(targetfile),"%s%s", cfg.lcd_output_path, "/oscam.lcd");
		snprintf(tmpfile, sizeof(tmpfile), "%s%s.tmp", cfg.lcd_output_path, "/oscam.lcd");
	}

	int8_t iscccam = 0;
	int32_t seconds = 0, secs = 0, fullmins = 0, mins = 0, fullhours = 0, hours = 0,	days = 0;
	time_t now = time((time_t*)0);


	while(running) {
		now = time((time_t*)0);
		int16_t cnt = 0, idx = 0, count_r = 0, count_p = 0, count_u = 0;
		FILE *fpsave;

		if((fpsave = fopen(tmpfile, "w"))){

			idx = 0;
			int16_t i;
			char *type;
			char *label;
			char *status;

			// Statuslines start
			secs = 0; fullmins = 0; mins = 0; fullhours = 0; hours = 0; days = 0;

			seconds = now - first_client->login;
			secs = seconds % 60;
			if (seconds > 60) {
				fullmins = seconds / 60;
				mins = fullmins % 60;
				if(fullmins > 60) {
					fullhours = fullmins / 60;
					hours = fullhours % 24;
					days = fullhours / 24;
				}
			}

			fprintf(fpsave,"Version: %s\n", CS_VERSION);
			fprintf(fpsave,"Revision: %s\n", CS_SVN_VERSION);
			if(days == 0)
				fprintf(fpsave, "up: %02d:%02d:%02d\n", hours, mins, secs);
			else
				fprintf(fpsave, "up: %02dd %02d:%02d:%02d\n", days, hours, mins, secs);
			fprintf(fpsave,"totals: %d/%d/%d/%d/%d/%d\n", first_client->cwfound, first_client->cwnot, first_client->cwignored, first_client->cwtout, first_client->cwcache, first_client->cwtun);
			fprintf(fpsave,"uptime: %d\n", seconds);
			// Statuslines end

			// Readertable head
			fprintf(fpsave,"Typ| Label      | Idle         | w | s | b | e | St\n");
			fprintf(fpsave,"---+------------+--------------+---+---+---+---+----\n");

			struct s_client *cl;

			// Reader/Proxy table start
			for ( i=0, cl=first_client; cl ; cl=cl->next, i++) {

				if ((cl->typ=='r' || cl->typ=='p') && ((now - cl->last) < 20 || !cfg.lcd_hide_idle)){
					type = "";
					label = "";
					status = "OFF";
					secs = 0; fullmins = 0; mins = 0; fullhours = 0; hours = 0; days = 0;

					seconds = now - cl->last;

					if (cl->typ == 'r'){
						type = "R";
						idx = count_r;
						label = cl->reader->label;
						if (cl->reader->card_status == CARD_INSERTED)
							status = "OK";
						count_r++;
					}

					else if (cl->typ == 'p'){
						type = "P";
						iscccam = 0;
						idx = count_p;
						label = cl->reader->label;
						if ((strncmp(monitor_get_proto(cl), "cccam", 5) == 0))
							iscccam = 1;

						if (cl->reader->card_status == CARD_INSERTED)
							status = "CON";

						count_p++;
					}


					secs = seconds % 60;
					if (seconds > 60) {
						fullmins = seconds / 60;
						mins = fullmins % 60;
						if(fullmins > 60) {
							fullhours = fullmins / 60;
							hours = fullhours % 24;
							days = fullhours / 24;
						}
					}

					int16_t written = 0, skipped = 0, blocked = 0, error = 0;

					char *emmtext;
					if(cs_malloc(&emmtext, 16 * sizeof(char), -1)){
						if(cl->typ == 'r' || !iscccam ){
							for (i=0; i<4; i++) {
								error += cl->reader->emmerror[i];
								blocked += cl->reader->emmblocked[i];
								skipped += cl->reader->emmskipped[i];
								written += cl->reader->emmwritten[i];
							}
							snprintf(emmtext, 16, "%3d|%3d|%3d|%3d",
									written > 999? 999 : written,
									skipped > 999? 999 : skipped,
									blocked > 999? 999 : blocked,
									error > 999? 999 : error);

						}
#ifdef MODULE_CCCAM
						else if(cl->typ == 'p' && iscccam ){
							struct cc_data *rcc = cl->cc;
							if(rcc){
								LLIST *cards = rcc->cards;
								if (cards) {
									int32_t cnt = ll_count(cards);
									int32_t locals = rcc->num_hop1;
									snprintf(emmtext, 16, " %3d/%3d card%s", locals, cnt, (cnt > 1)? "s ": "  ");
								}
							} else {
								snprintf(emmtext, 16, "   No cards    ");
							}
						}
#endif
						else {
							snprintf(emmtext, 16, "               ");
						}

					}

					if(days == 0) {
						fprintf(fpsave,"%s%d | %-10.10s |     %02d:%02d:%02d |%s| %s\n",
								type, idx, label, hours, mins,
								secs, emmtext, status);
					} else {
						fprintf(fpsave,"%s%d | %-10.10s |% 3dd %02d:%02d:%02d |%s| %s\n",
								type, idx, label, days, hours, mins,
								secs, emmtext, status);
					}
					free(emmtext);
				}
			}

			fprintf(fpsave,"---+------------+--------------+---+---+---+--++----\n");
			// Reader/Proxy table end


			// Usertable start
			fprintf(fpsave,"Typ| Label      | Channel                     | Time\n");
			fprintf(fpsave,"---+------------+-----------------------------+-----\n");

			/*
			//Testclient
			fprintf(fpsave,"%s%d | %-10.10s | %-10.10s:%-17.17s| % 4d\n",
					"U",
					1,
					"test",
					"Sky De",
					"Discovery Channel",
					568);

			*/

			for ( i=0, cl=first_client; cl ; cl=cl->next, i++) {

				seconds = now - cl->lastecm;

				if (cl->typ == 'c' && seconds < 15){
					type = "U";
					idx = count_u;
					label = cl->account->usr;
					count_u++;

					get_servicename(cl, cl->last_srvid, cl->last_caid, channame);
					fprintf(fpsave,"%s%d | %-10.10s | %-10.10s:%-17.17s| % 4d\n",
							type,
							idx,
							label,
							cl->last_srvidptr && cl->last_srvidptr->prov ? cl->last_srvidptr->prov : "",
									cl->last_srvidptr && cl->last_srvidptr->name ? cl->last_srvidptr->name : "",
											cl->cwlastresptime);

				}
			}
			fprintf(fpsave,"---+------------+-----------------------------+-----\n");
			// Usertable end
			fclose(fpsave);
		}

		idx = 0;
		cs_sleepms(cfg.lcd_write_intervall * 1000);
		cnt++;

		if(rename(tmpfile, targetfile) < 0)
			cs_log("An error occured while writing oscam.lcd file %s.", targetfile);

	}

}
示例#28
0
文件: oscam-work.c 项目: FFTEAM/oscam
/**
 * adds a job to the job queue
 * if ptr should be free() after use, set len to the size
 * else set size to 0
**/
int32_t add_job(struct s_client *cl, enum actions action, void *ptr, int32_t len)
{
	if(!cl || cl->kill)
	{
		if(!cl)
			{ cs_log("WARNING: add_job failed. Client killed!"); } // Ignore jobs for killed clients
		if(len && ptr)
			{ NULLFREE(ptr); }
		return 0;
	}

	if(action == ACTION_CACHE_PUSH_OUT && cacheex_check_queue_length(cl))
	{
		if(len && ptr)
			{ NULLFREE(ptr); }
		return 0;
	}

	struct job_data *data;
	if(!cs_malloc(&data, sizeof(struct job_data)))
	{
		if(len && ptr)
			{ NULLFREE(ptr); }
		return 0;
	}

	data->action = action;
	data->ptr    = ptr;
	data->cl     = cl;
	data->len    = len;
	cs_ftime(&data->time);

	SAFE_MUTEX_LOCK(&cl->thread_lock);
	if(cl && !cl->kill && cl->thread_active)
	{
		if(!cl->joblist)
			{ cl->joblist = ll_create("joblist"); }
		ll_append(cl->joblist, data);
		if(cl->thread_active == 2)
			{ pthread_kill(cl->thread, OSCAM_SIGNAL_WAKEUP); }
		SAFE_MUTEX_UNLOCK(&cl->thread_lock);
		cs_log_dbg(D_TRACE, "add %s job action %d queue length %d %s",
					  action > ACTION_CLIENT_FIRST ? "client" : "reader", action,
					  ll_count(cl->joblist), username(cl));
		return 1;
	}
	
	/* pcsc doesn't like this; segfaults on x86, x86_64 */
	int8_t modify_stacksize = 0;
	struct s_reader *rdr = cl->reader;
	if(cl->typ != 'r' || !rdr || rdr->typ != R_PCSC)
		{ modify_stacksize = 1; }

	if(action != ACTION_READER_CHECK_HEALTH)
	{
		cs_log_dbg(D_TRACE, "start %s thread action %d",
					  action > ACTION_CLIENT_FIRST ? "client" : "reader", action);
	}

	int32_t ret = start_thread("client work", work_thread, (void *)data, &cl->thread, 1, modify_stacksize);
	if(ret)
	{
		cs_log("ERROR: can't create thread for %s (errno=%d %s)",
			   action > ACTION_CLIENT_FIRST ? "client" : "reader", ret, strerror(ret));
		free_job_data(data);
	}

	cl->thread_active = 1;
	SAFE_MUTEX_UNLOCK(&cl->thread_lock);
	return 1;
}
示例#29
0
int32_t coolapi_set_filter (int32_t fd, int32_t num, int32_t pid, uchar * flt, uchar * mask, int32_t type)
{
	dmx_t * dmx =  find_demux(fd, 0);
	if(!dmx) {
		cs_debug_mask(D_DVBAPI, "dmx is NULL!");
		return -1;
	}

	int32_t result, channel_found=0;

	void * channel = NULL;

	if (ll_count(ll_cool_chanhandle) > 0) {
		LL_ITER itr = ll_iter_create(ll_cool_chanhandle);
		S_COOL_CHANHANDLE *handle_item;
		while ((handle_item=ll_iter_next(&itr))) {
			if (handle_item->demux_index == dmx->demux_index && handle_item->pid == pid) {
				channel = handle_item->channel;
				channel_found=1;
				break;
			}
		}
	}

	if (!channel) {
		buffer_open_arg_t bufarg;
		int32_t uBufferSize = 8256;
		memset(&bufarg, 0, sizeof(bufarg));

		bufarg.type = 3;
		bufarg.size = uBufferSize;
		bufarg.unknown3 = (uBufferSize * 7) / 8;

		result = cnxt_cbuf_open(&dmx->buffer1, &bufarg, NULL, NULL);
		coolapi_check_error("cnxt_cbuf_open", result);

		bufarg.type = 0;

		result = cnxt_cbuf_open(&dmx->buffer2, &bufarg, NULL, NULL);
		coolapi_check_error("cnxt_cbuf_open", result);

		channel_open_arg_t chanarg;
		memset(&chanarg, 0, sizeof(channel_open_arg_t));
		chanarg.type = 4;

		result = cnxt_dmx_channel_open(dmx->device, &dmx->channel, &chanarg, dmx_callback, dmx);
		coolapi_check_error("cnxt_dmx_channel_open", result);

		result = cnxt_dmx_set_channel_buffer(dmx->channel, 0, dmx->buffer1);
		coolapi_check_error("cnxt_dmx_set_channel_buffer", result);

		result = cnxt_dmx_channel_attach(dmx->channel, 0xB, 0, dmx->buffer2);
		coolapi_check_error("cnxt_dmx_channel_attach", result);

		result = cnxt_cbuf_attach(dmx->buffer2, 2, dmx->channel);
		coolapi_check_error("cnxt_cbuf_attach", result);

		result = cnxt_dmx_set_channel_pid(dmx->channel, pid);
		coolapi_check_error("cnxt_dmx_set_channel_pid", result);

		result = cnxt_cbuf_flush (dmx->buffer1, 0);
		coolapi_check_error("cnxt_cbuf_flush", result);
		result = cnxt_cbuf_flush (dmx->buffer2, 0);
		coolapi_check_error("cnxt_cbuf_flush", result);

		S_COOL_CHANHANDLE *handle_item;
		if (cs_malloc(&handle_item,sizeof(S_COOL_CHANHANDLE))) {
			handle_item->pid 			= pid;
			handle_item->channel 		= dmx->channel;
			handle_item->buffer1 		= dmx->buffer1;
			handle_item->buffer2		= dmx->buffer2;
			handle_item->demux_index 	= dmx->demux_index;
			ll_append(ll_cool_chanhandle, handle_item);
		}
		cs_debug_mask(D_DVBAPI, "opened new channel %x", (int32_t) dmx->channel);
   } else {
		channel_found=1;
		dmx->channel = channel;
		dmx->buffer1 = NULL;
		dmx->buffer2 = NULL;
	}

	cs_debug_mask(D_DVBAPI, "setting new filter fd=%08x demux=%d channel=%x num=%d pid=%04x flt=%x mask=%x", fd, dmx->demux_index, (int32_t) dmx->channel, num, pid, flt[0], mask[0]);

	pthread_mutex_lock(&dmx->mutex);

	filter_set_t filter;
	dmx->filter_num = num;
	dmx->pid = pid;
	dmx->type = type;

	memset(&filter, 0, sizeof(filter));
	filter.length = 12;
	memcpy(filter.filter, flt, 16);
	memcpy(filter.mask, mask, 16);

	result = cnxt_dmx_open_filter(dmx->device, &dmx->filter);
	coolapi_check_error("cnxt_dmx_open_filter", result);

	result = cnxt_dmx_set_filter(dmx->filter, &filter, NULL);
	coolapi_check_error("cnxt_dmx_set_filter", result);

	result = cnxt_dmx_channel_attach_filter(dmx->channel, dmx->filter);
	coolapi_check_error("cnxt_dmx_channel_attach_filter", result);

	if (channel_found) {
		result = cnxt_dmx_channel_ctrl(dmx->channel, 0, 0);
		coolapi_check_error("cnxt_dmx_channel_ctrl", result);
	}

	result = cnxt_dmx_channel_ctrl(dmx->channel, 2, 0);
	coolapi_check_error("cnxt_dmx_channel_ctrl", result);

	pthread_mutex_unlock(&dmx->mutex);

	S_COOL_FILTER *filter_item;
	if (cs_malloc(&filter_item,sizeof(S_COOL_FILTER))) {
		// fill filter item
		filter_item->fd = fd;
		filter_item->pid = pid;
		filter_item->channel = (int32_t) dmx->channel;
		memcpy(filter_item->filter16, flt, 16);
		memcpy(filter_item->mask16, mask, 16);

		//add filter item
		ll_append(ll_cool_filter, filter_item);
	}
	return 0;
}
示例#30
0
文件: controllers.c 项目: hyper/rqd
//-----------------------------------------------------------------------------
// callback function that will fire when the connection to the controller is reached.
static void controller_connect_handler(int fd, short int flags, void *arg)
{
	controller_t *ct = (controller_t *) arg;
	node_t *node;
	system_data_t *sysdata;
	queue_t *q;
	int error;
	socklen_t foo;
	struct timeval t = {.tv_sec = 1, .tv_usec = 0};
	short int exclusive;

	assert(fd >= 0);
	assert(flags != 0);
	assert(ct);
	assert(ct->node == NULL);
	assert(ct->target);
	assert(ct->sysdata);
	sysdata = ct->sysdata;
	
	// we only need to detect EV_WRITE for a connect event.
	assert(flags == EV_WRITE);

	// remove the connect event
	assert(ct->connect_event);
	event_free(ct->connect_event);
	ct->connect_event = NULL;

	// we are no longer connected.  We are either connected, or not.
	assert(BIT_TEST(ct->flags, FLAG_CONTROLLER_CONNECTING));
	BIT_CLEAR(ct->flags, FLAG_CONTROLLER_CONNECTING);

	// check to see if we really are connected.
	foo = sizeof(error);
	getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &foo);
	if (error == ECONNREFUSED) {
		// we were connecting, but couldn't.
		BIT_SET(ct->flags, FLAG_CONTROLLER_CLOSED);

		// close the socket that didn't connect.
		close(fd);

		//set the action so that we can attempt to reconnect.
		assert(ct->connect_event == NULL);
		assert(sysdata->evbase);
		ct->connect_event = evtimer_new(sysdata->evbase, controller_wait_handler, (void *) ct);
		evtimer_add(ct->connect_event, &t);
	}
	else {
		logger(((system_data_t *)ct->sysdata)->logging, 2,
			"connected to remote controller: %s", ct->target);
	
		// create the node object.
		node = node_create(sysdata, fd);
	
		// add node to the main nodes list.
		ct->node = node;
		assert(node->controller == NULL);
		node->controller = ct;
		BIT_SET(node->flags, FLAG_NODE_CONTROLLER);
	
		// we need to check to see if we have any queues with active consumers,
		// and if we do, then we need to send consume requests to this node for
		// each one.
		assert(sysdata->queues);
		ll_start(sysdata->queues);
		while ((q = ll_next(sysdata->queues))) {
			assert(q->qid > 0);
			assert(q->name);
	
			if (ll_count(&q->nodes_busy) > 0 || ll_count(&q->nodes_ready) > 0) {
				logger(((system_data_t *)ct->sysdata)->logging, 2, 
					"Sending queue consume ('%s') to alternate controller at %s",
					q->name, ct->target );

				exclusive = 0;
				if (BIT_TEST(q->flags, QUEUE_FLAG_EXCLUSIVE))
					exclusive = 1;
				
				sendConsume(node, q->name, 1, RQ_PRIORITY_LOW, exclusive);
				ll_push_head(&q->nodes_consuming, node);
			}
		}
		ll_finish(sysdata->queues);
	}
}





void controller_connect(controller_t *ct)
{
	evutil_socket_t sock;
	int result;
	int len;

	assert(ct);
	assert(ct->target);
	assert(ct->node == NULL);
	assert(BIT_TEST(ct->flags, FLAG_CONTROLLER_CONNECTED) == 0);
	assert(BIT_TEST(ct->flags, FLAG_CONTROLLER_FAILED) == 0);
	assert(BIT_TEST(ct->flags, FLAG_CONTROLLER_CONNECTING) == 0);

	// if not already resolved.... resolve the target.
	if (BIT_TEST(ct->flags, FLAG_CONTROLLER_RESOLVED) == 0) {
		assert(ct->flags == 0);
		
		logger(((system_data_t *)ct->sysdata)->logging, 3, "resolving controller %s.", ct->target);

		len = sizeof(ct->saddr);
		if (evutil_parse_sockaddr_port(ct->target, &ct->saddr, &len) == 0) {
			BIT_SET(ct->flags, FLAG_CONTROLLER_RESOLVED);
		}
		else {
			BIT_SET(ct->flags, FLAG_CONTROLLER_FAILED);
		}
	}
	

	if (BIT_TEST(ct->flags, FLAG_CONTROLLER_FAILED) == 0) {
		assert(BIT_TEST(ct->flags, FLAG_CONTROLLER_RESOLVED));

		BIT_SET(ct->flags, FLAG_CONTROLLER_CONNECTING);

		sock = socket(AF_INET,SOCK_STREAM,0);
		assert(sock >= 0);
						
		// Before we attempt to connect, set the socket to non-blocking mode.
		evutil_make_socket_nonblocking(sock);

		logger(((system_data_t *)ct->sysdata)->logging, 3, "Attempting Remote connect to %s.", ct->target);

		result = connect(sock, &ct->saddr, sizeof(struct sockaddr));
		assert(result < 0);
		assert(errno == EINPROGRESS);

		// connect process has been started.  Now we need to create an event so that we know when the connect has completed.
		assert(ct->connect_event == NULL);
		assert(ct->sysdata);
		assert(((system_data_t *)ct->sysdata)->evbase);
		ct->connect_event = event_new(((system_data_t *)ct->sysdata)->evbase, sock, EV_WRITE, controller_connect_handler, ct);
		event_add(ct->connect_event, NULL);
	}
	else {
		assert(ct->target);
		logger(((system_data_t *)ct->sysdata)->logging, 2, "Remote connect to %s has failed.", ct->target);
	}
}