示例#1
0
/*
 *  js_session_get -- find the session for a resource
 *
 *  Given a user and a resource, find the corresponding session
 *  if the user is logged in. Otherwise return NULL.
 *
 *  parameters
 *	user -- the user's udata record
 *	res -- the resource to search for
 *
 *  returns
 *	a pointer to the session if the user is logged in
 *	NULL if the user isn't logged in on this resource
 */
session js_session_get(udata user, char *res)
{
	session cur;		/* session pointer */

	/* screen out illeagal calls */
	if (user == NULL || res == NULL)
		return NULL;

	/* find the session and return it */
	SEM_LOCK(user->sem);
	for (cur = user->sessions; cur != NULL; cur = cur->next)
		if ((j_strcmp(res, cur->res) == 0) && (!cur->exit_flag)) {
			SEM_UNLOCK(user->sem);
			return cur;
		}

	/* find any matching resource that is a subset and return it */
	for (cur = user->sessions; cur != NULL; cur = cur->next)
		if ((j_strncmp(res, cur->res, j_strlen(cur->res)) == 0)
		    && (!cur->exit_flag)) {
			SEM_UNLOCK(user->sem);
			return cur;
		}

	SEM_UNLOCK(user->sem);

	/* if we got this far, there is no session */
	return NULL;

}
示例#2
0
/* do not free sem at the end if session was found */
session js_session_primary_all_sem(udata user)
{
	session cur, top;

	/* ignore illeagal calls, or users with no sessions */
	if (user == NULL || user->sessions == NULL)
		return NULL;

	/* find primary session */
	SEM_LOCK(user->sem);

	if (user->sessions == NULL) {
		SEM_UNLOCK(user->sem);
		return NULL;
	}

	top = user->sessions;
	for (cur = top; cur != NULL; cur = cur->next)
		if (cur->priority > top->priority)
			top = cur;

	/* return it if it's active */
	if (top->priority > -128)
		return top;

	else {			/* otherwise there's no active session */
		SEM_UNLOCK(user->sem);
		return NULL;
	}

}
示例#3
0
mreturn mod_browse_reply(mapi m, void *arg)
{
	xmlnode browse, ns, cur;
	session s;

	if (m->packet->type != JPACKET_IQ)
		return M_IGNORE;
	if (!NSCHECK(m->packet->iq, NS_BROWSE))
		return M_PASS;

	/* first, is this a valid request? */
	switch (jpacket_subtype(m->packet)) {
	case JPACKET__RESULT:
	case JPACKET__ERROR:
		return M_PASS;
	case JPACKET__SET:
		js_bounce(m->si, m->packet->x, TERROR_NOTALLOWED);
		return M_HANDLED;
	}

	log_debug("handling query for user %s", m->user->user);

	/* get this dudes browse info */
	browse = mod_browse_get(m, m->packet->to);

	/* insert the namespaces */
	ns = xdb_get(m->si->xc, m->packet->to, NS_XDBNSLIST);
	for (cur = xmlnode_get_firstchild(ns); cur != NULL;
	     cur = xmlnode_get_nextsibling(cur))
		if (xmlnode_get_attrib(cur, "type") == NULL)
			xmlnode_insert_tag_node(browse, cur);	/* only include the generic <ns>foo</ns> */
	xmlnode_free(ns);

	/* include any connected resources if there's a s10n from them */
	if (js_trust(m->user, m->packet->from)) {
		SEM_LOCK(m->user->sem);
		for (s = m->user->sessions; s != NULL; s = s->next) {
			/* if(s->priority < 0) continue; *** include all resources I guess */
			if (xmlnode_get_tag
			    (browse,
			     spools(m->packet->p, "?jid=", jid_full(s->id),
				    m->packet->p)) != NULL)
				continue;	/* already in the browse result */
			cur = xmlnode_insert_tag(browse, "user");
			xmlnode_put_attrib(cur, "type", "client");
			xmlnode_put_attrib(cur, "jid", jid_full(s->id));
		}
		SEM_UNLOCK(m->user->sem);
	}

	/* XXX include iq:filter forwards */

	jutil_iqresult(m->packet->x);
	jpacket_reset(m->packet);
	xmlnode_insert_tag_node(m->packet->x, browse);
	js_deliver(m->si, m->packet);

	xmlnode_free(browse);
	return M_HANDLED;
}
示例#4
0
void fast_mtq_send(fast_mtq f_mtq, void *arg)
{
	fast_mtq_elem e = (fast_mtq_elem) arg;

	if (f_mtq->shutdown)
		return;

	e->mtq_next = NULL;

	SEM_LOCK(f_mtq->sem);

	if (f_mtq->first) {
		f_mtq->last->mtq_next = e;
	} else {
		f_mtq->first = e;
	}
	f_mtq->last = e;

	f_mtq->queue++;
	f_mtq->queue2++;

	COND_SIGNAL(f_mtq->cond);

	SEM_UNLOCK(f_mtq->sem);
}
示例#5
0
/* thread safe with sem */
mreturn mod_presence_deliver(mapi m, void *arg)
{
	session cur;

	if (m->packet->type != JPACKET_PRESENCE)
		return M_IGNORE;

	log_debug("deliver phase");

	/* only if we HAVE a user, and it was sent to ONLY the user@server, and there is at least one session available */
	if (m->user != NULL && m->packet->to->resource == NULL && js_session_primary_all_sem(m->user) != NULL) {
		log_debug("broadcasting to %s", m->user->user);

		/* broadcast */
		for (cur = m->user->sessions; cur != NULL; cur = cur->next) {
			if (cur->priority < -128)
				continue;
			js_session_to(cur, jpacket_new(xmlnode_dup(m->packet->x)));
		}
		SEM_UNLOCK(m->user->sem);

		if (jpacket_subtype(m->packet) != JPACKET__PROBE) {
			/* probes get handled by the offline thread as well? */
			xmlnode_free(m->packet->x);
			return M_HANDLED;
		}
	}

	return M_PASS;
}
示例#6
0
文件: deliver.c 项目: smokku/wpjabber
/* always deliver threads */
static void js_outgoing_packet(jsmi si, jpacket jp, dpacket p)
{
	session s = NULL;
	udata u;

	/* attempt to locate the session by matching the special resource */
	u = js_user(si, p->id, 0);
	if (u == NULL) {
		log_notice(p->host,
			   "Bouncing packet intended for nonexistant user: %s",
			   xmlnode2str(p->x));
		deliver_fail(dpacket_new(p->x), "Invalid User");
		return;
	}

	SEM_LOCK(u->sem);
	for (s = u->sessions; s != NULL; s = s->next)
		if (j_strcmp(p->id->resource, s->route->resource) == 0)
			break;
	SEM_UNLOCK(u->sem);

	THREAD_DEC(u->ref);

	if (s != NULL) {	/* just pass to the session normally */
		js_session_from(s, jp);
		return;
	}

	log_notice(p->host, "Bouncing %s packet intended for session %s",
		   xmlnode_get_name(jp->x), jid_full(p->id));
	deliver_fail(dpacket_new(p->x), "Invalid Session");
}
示例#7
0
文件: xdb.c 项目: smokku/wpjabber
result xdb_results(instance id, dpacket p, void *arg)
{
	xdbcache xc = (xdbcache) arg;
	xdbrequest_p cur, last;
	unsigned int idnum;
	char *idstr;

	if (p->type != p_NORM || *(xmlnode_get_name(p->x)) != 'x')
		return r_PASS;	/* yes, we are matching ANY <x*> element */

	log_debug("xdb_results checking xdb packet %s", xmlnode2str(p->x));

	if ((idstr = xmlnode_get_attrib(p->x, "id")) == NULL)
		return r_ERR;

	idnum = atoi(idstr);

	SEM_LOCK(xc->sem);

	for (last = NULL, cur = xc->first;
	     (cur) && (cur->id != idnum); last = cur, cur = cur->next);

	if (!cur) {
		pool_free(p->p);
		SEM_UNLOCK(xc->sem);
		return r_DONE;
	}

	/* associte only a non-error packet w/ waiting cache */
	if (j_strcmp(xmlnode_get_attrib(p->x, "type"), "error") == 0) {
		cur->data = NULL;
		pool_free(p->p);
	} else
		cur->data = p->x;

	if (!last)
		xc->first = cur->next;
	else
		last->next = cur->next;

	cur->external = 0;
	SEM_UNLOCK(xc->sem);

	cur->preblock = 1;
	return r_DONE;
}
示例#8
0
文件: xdb.c 项目: smokku/wpjabber
/* match will find a child in the parent, and either replace (if it's an insert) or remove (if data is NULL) */
int xdb_act(xdbcache xc, jid owner, char *ns, char *act, char *match,
	    xmlnode data)
{
	xdbrequest_p cur;
	struct timeval tv;

	if (xc->shutdown)
		return 1;

	if (xc == NULL || owner == NULL || ns == NULL) {
		log_alert("xdb_set",
			  "Programming Error: xdb_set() called with NULL\n");
		return 1;
	}

	log_debug("XDB SET");


	cur = malloc(sizeof(xdbrequest_t));
	memset(cur, 0, sizeof(xdbrequest_t));

	cur->set = 1;
	cur->data = data;
	cur->ns = ns;
	cur->owner = owner;
	cur->act = act;
	cur->match = match;
	gettimeofday(&tv, NULL);
	cur->sent = tv.tv_sec;

	SEM_LOCK(xc->sem);
	cur->id = xc->id++;

	cur->next = xc->first;
	xc->first = cur;

	SEM_UNLOCK(xc->sem);

	/* send it on it's way */
	xdb_deliver(xc->i, cur, 0);
	cur->external = 1;

	/* if it hasn't already returned, we should block here until it returns */
	while (cur->preblock != 1)
		usleep(10);

	/* if it didn't actually get set, flag that */
	if (cur->data == NULL) {
		free(cur);
		return 1;
	}

	xmlnode_free(cur->data);

	free(cur);
	return 0;
}
示例#9
0
/*
 *  js_session_end -- shut down the session
 *
 *  This function gets called when the user disconnects or when the server shuts
 *  down. It changes the user's presence to offline, cleans up the session data
 *  and sends an end spacket
 *
 *  parameters
 *	s -- the session to end
 *	reason -- the reason the session is shutting down (for logging)
 *
 */
void js_session_end(session s, char *reason)
{
	session cur;		/* used to iterate over the user's session list
				   when removing the session from the list */

	/* ignore illegal calls */
	if (s == NULL || s->exit_flag == 1 || reason == NULL)
		return;

	/* so it doesn't get freed */
	THREAD_INC(s->u->ref);

	/* log the reason the session ended */
	log_debug("end %d '%s'", s, reason);

	/* flag the session to exit ASAP */
	s->exit_flag = 1;

	/* make sure we're not the primary session */
	s->priority = -129;

	/* presence will be updated in _js_session_end to be shore that
	   only session thread is changing this value  */

	/*
	 * remove this session from the user's session list --
	 * first check if this session is at the head of the list
	 */
	SEM_LOCK(s->u->sem);
	if (s == s->u->sessions) {
		/* yup, just bump up the next session */
		s->u->sessions = s->next;

	} else {

		/* no, we have to traverse the list to find it */
		for (cur = s->u->sessions; cur->next != s;
		     cur = cur->next);
		cur->next = s->next;

	}

	s->u->scount--;
	SEM_UNLOCK(s->u->sem);

	/* end */
	{
		packet_thread_p pt;
		pt = pmalloco(s->p, sizeof(packet_thread_t));
		pt->s = s;
		pt->type = 1;
		fast_mtq_send(s->q->mtq, pt);
	}
}
示例#10
0
void *fast_mtq_thread(void *arg)
{
	fast_mtq f_mtq = (fast_mtq) arg;
	register fast_mtq_elem e;
	void *cb_arg;

	cb_arg = f_mtq->arg;

	if (f_mtq->start_cb) {
		cb_arg = (f_mtq->start_cb) (cb_arg);
	}

	log_debug("fast mtq thread start");

	while (1) {

		/* check if something to resolv */
		SEM_LOCK(f_mtq->sem);

		e = NULL;

		if (f_mtq->shutdown != 2) {
			if ((!(f_mtq->first)) && (!(f_mtq->shutdown))) {
				COND_WAIT(f_mtq->cond, f_mtq->sem);
			}

			/* get element */
			e = f_mtq->first;
			if (e) {
				f_mtq->first = e->mtq_next;
				f_mtq->queue--;
				f_mtq->queue2--;
			}
		}

		SEM_UNLOCK(f_mtq->sem);

		if (e) {
			(f_mtq->cb) (cb_arg, (void *) e);
		} else {
			if (f_mtq->shutdown)
				break;
		}
	}

	log_alert("mtq", "fast mtq thread stop %d [%d][%d]",
		  f_mtq->shutdown, f_mtq->queue, f_mtq->queue2);

	if (f_mtq->stop_cb) {
		(f_mtq->stop_cb) (cb_arg);
	}

	return NULL;
}
示例#11
0
文件: mtq.c 项目: Doap/transports
/* main slave thread */
void *mtq_main(void *arg)
{
    mth t = (mth)arg;
    mtqqueue mq; /* temp call structure */
    _mtqqueue mqcall; /* temp call structure */
    log_debug("mtq","%X starting mq=%d",t->thread,t->mtq);

    while(1) {

	  /* check if something to resolv */
	  SEM_LOCK(t->mtq->sem);
	  if (t->mtq->last == NULL) {
		COND_WAIT(t->mtq->cond,t->mtq->sem);
	  }

	  /* get element */
	  mq = t->mtq->last;
	  if (mq != NULL) {
		mqcall.f = mq->f;
		mqcall.arg = mq->arg;
		
		/* remove call from list */		    
		t->mtq->last = t->mtq->last->prev;		    
		t->mtq->dl--;
		
		/* add mq to list */
		mq->prev = NULL;
		
		if (t->mtq->free_last == NULL)
		  t->mtq->free_last = mq;
		else
		  t->mtq->free_first->prev = mq;
		
		t->mtq->free_first = mq;		
	  }

	  SEM_UNLOCK(t->mtq->sem);

	  if (mq != NULL) {
		(*(mqcall.f))(mqcall.arg);
	  }
	  else {	  
		/* mq is NULL here, so no more packets in queue */
		if (mtq__shutdown == 1)
		  break;		
	  }
	} /* loop end */
    
    log_debug("mtq","%X ending mq=%d",t->thread,t->mtq);
    return NULL;
}
示例#12
0
文件: xdb.c 项目: smokku/wpjabber
void xdb_shutdown(void *arg)
{
	xdbcache xc = (xdbcache) arg;
	xdbrequest_p cur;

	log_debug("XDB SHUTDOWN");

	xc->shutdown = 1;

	SEM_LOCK(xc->sem);
	while (xc->first) {
		cur = xc->first;
		xc->first = cur->next;

		cur->data = NULL;
		cur->preblock = 1;
	}
	SEM_UNLOCK(xc->sem);
}
示例#13
0
文件: xdb.c 项目: smokku/wpjabber
/** resend packets. heartbeat thread */
result xdb_thump(void *arg)
{
	xdbcache xc = (xdbcache) arg;
	xdbrequest_p cur, next, last;
	struct timeval tv;
	time_t now;

	if (xc->shutdown)
		return r_UNREG;

	gettimeofday(&tv, NULL);
	now = tv.tv_sec;

	SEM_LOCK(xc->sem);
	/* spin through the cache looking for stale requests */

	for (last = NULL, cur = xc->first; cur;) {
		next = cur->next;
		if ((cur->external) && ((now - cur->sent) > 30)) {

			if (!last)
				xc->first = next;
			else
				last->next = next;

			cur->data = NULL;
			cur->preblock = 1;
		} else {
			last = cur;

			if ((cur->external) && ((now - cur->sent) > 10)) {
				log_alert("xdb", "Resend xdb packet");
				xdb_deliver(xc->i, cur, 1);
			}
		}

		cur = next;
	}
	SEM_UNLOCK(xc->sem);

	return r_DONE;
}
示例#14
0
/** Shut down transport, kill all sessions */
void it_shutdown(void *arg)
{
    iti ti = (iti) arg;

    log_alert(ZONE,"JIT Transport, shutting down");

    ti->shutdown = 1;

    /* wait */
    usleep(1000);

    if (ti->sessions_count) { 
	  SEM_LOCK(ti->sessions_sem);
      wpxhash_walk(ti->sessions,it_sessions_end,NULL);      
	  SEM_UNLOCK(ti->sessions_sem);
    }

    while (ti->sessions_count > 0)
      usleep(100);
    
    wpxhash_free(ti->sessions);
    ti->sessions = NULL;
}
示例#15
0
/*
 *  js_session_new -- creates a new session, registers the resource for it
 *
 *  Sets up all the data associated with the new session, then send it a
 *  start spacket, which basically notifies all modules about the new session
 *
 *  returns
 *	a pointer to the new session
 */
session js_session_new(jsmi si, dpacket dp)
{
	pool p;
	session s, cur;
	udata u;
	int i;
	char routeres[10];

	/* screen out illegal calls */
	if (dp == NULL || dp->id->user == NULL || dp->id->resource == NULL
	    || xmlnode_get_attrib(dp->x, "from") == NULL)
		return NULL;

	if ((u = js_user(si, dp->id, 0)) == NULL)
		return NULL;

	if (u->scount >= MAX_USER_SESSIONS) {
		THREAD_DEC(u->ref);
		return NULL;
	}


	log_debug("session_create %s", jid_full(dp->id));

	/* create session */
	p = pool_heap(1024);
	s = pmalloco(p, sizeof(struct session_struct));
	s->p = p;
	s->si = si;

	/* save authorative remote session id */
	s->sid = jid_new(p, xmlnode_get_attrib(dp->x, "from"));

	/* session identity */
	s->id = jid_new(p, jid_full(dp->id));
	/* id bez resource */
	s->uid = jid_user(s->id);
	s->route = jid_new(p, jid_full(dp->id));
	snprintf(routeres, 9, "%X", s);
	jid_set(s->route, routeres, JID_RESOURCE);
	s->res = pstrdup(p, dp->id->resource);
	s->u = u;

	jid_full(s->sid);
	jid_full(s->uid);
	jid_full(s->id);
	jid_full(s->route);

	{
		register char *text;
		text = xmlnode_get_attrib(dp->x, "ip");
		if (text) {
			s->ip =
			    pstrdup(s->p, xmlnode_get_attrib(dp->x, "ip"));
			xmlnode_hide_attrib(dp->x, "ip");
		} else
			s->ip = "none";
	}

	/* default settings */
	s->exit_flag = 0;
	s->roster = 0;
	s->priority = -129;
	s->presence = jutil_presnew(JPACKET__UNAVAILABLE, NULL, NULL);
	xmlnode_put_attrib(s->presence, "from", jid_full(s->id));
	s->c_in = s->c_out = 0;

	for (i = 0; i < es_LAST; i++)
		s->events[i] = NULL;

	SEM_LOCK(u->sem);

	if (u->sessions != NULL) {
		s->q = get_mtq_queue(si, u->sessions->q);

		for (cur = u->sessions; cur != NULL; cur = cur->next)
			if (j_strcmp(dp->id->resource, cur->res) == 0)
				js_session_end_nosem(cur,
						     "Replaced by new connection");
	} else {
		s->q = get_mtq_queue(si, NULL);
	}

	/* make sure we're linked with the user */
	s->next = s->u->sessions;
	s->u->sessions = s;
	s->u->scount++;

	SEM_UNLOCK(u->sem);

	/* session start */
	{
		packet_thread_p pt;
		pt = malloc(sizeof(packet_thread_t));
		pt->s = s;
		pt->type = 0;
		fast_mtq_send(s->q->mtq, pt);
	}

	THREAD_DEC(u->ref);
	return s;
}
示例#16
0
文件: mtq.c 项目: Doap/transports
void mtq_send(mtq q, pool p, mtq_callback f, void *arg)
{
    mtqqueue mq;  /* one element */ 
	mtq mtq;


    /* initialization stuff */
    if(mtq__master == NULL)
    {
	  mtq_init();
    }

    if(q != NULL)  {
      mtq = q;
    }
    else {
      /* take next thread */
	  mtq__master->random++;
	  if (mtq__master->random >= MTQ_THREADS)
		mtq__master->random = 0;
	  
	  mtq = mtq__master->all[mtq__master->random]->mtq;      
    }
	
    /* build queue */
    log_debug(ZONE,"mtq_send insert into mtq=%p",mtq);

    /* lock operation on queue */
    SEM_LOCK(mtq->sem);

    /* find free memory */
    mq = mtq->free_last;
            
    if (mq == NULL)
    {  
	  while ((mq = malloc(sizeof(_mtqqueue)))==NULL) Sleep(1000);
	  /* it means new malloc 
		 maybe we should free this mq later ? */
	  log_alert(ZONE,"MTQ new queue malloc");
	  mq->memory = 1;
	  mtq->length++;
    }
    else   {
	  /* take it out from queue */
	  mtq->free_last = mtq->free_last->prev;
    }
    
    mq->f = f;
    mq->arg = arg;
    mq->prev = NULL;
    
    mtq->dl++;
    
    /* if queue is empty */
    if (mtq->last == NULL)
      mtq->last = mq;
    else
      mtq->first->prev = mq;

    mtq->first = mq;

	COND_SIGNAL(mtq->cond);

    SEM_UNLOCK(mtq->sem);
}
示例#17
0
/** Callback processing incoming Jabber packets. */
result it_receive(instance i, dpacket d, void *arg) {
    iti ti = (iti) arg;
    jpacket jp;
    session s;
    session_ref alt_s;
    unsigned char *user;
    
    log_debug(ti->i->id,"Packet received: %s\n",xmlnode2str(d->x)); 

    switch(d->type) {
    case p_ROUTE: {
      /* ignore */
      return r_PASS;
    }
            
    case p_NONE:
    case p_NORM:
      jp = jpacket_new(d->x);
      break;

    default:
      return r_ERR;
    }

    if (!jp->from ||/* !jp->from->user ||*/ jp->type == JPACKET_UNKNOWN /* || jpacket_subtype(jp) == JPACKET__ERROR */)
    { /* ignore invalid packets */
        xmlnode_free(jp->x);
        return r_DONE;
    }

    /* JID user part should be case insensitive */
    /* convert user part of from JID to lower case */
    if(jp->from->user != NULL) 
	  for(user = jp->from->user; *user != '\0'; user++)
		if(*user < 128)
		  *user = tolower(*user);
	/* Mangle "from" JID, save original attribute for XDB conversion */
	xmlnode_put_attrib(jp->x, "origfrom", xmlnode_get_attrib(jp->x, "from"));
	xmlnode_put_attrib(jp->x, "from", jid_full(jp->from));

    SEM_LOCK(ti->sessions_sem);
    s = (session) wpxhash_get(ti->sessions,jid_full(jid_user(jp->from)));
    alt_s = (session_ref) wpxhash_get(ti->sessions_alt,jp->to->user);
    if (s != NULL) {
      if (s->exit_flag) {
    SEM_UNLOCK(ti->sessions_sem);
    log_alert("exit flag","message to exiting session");
    if (jp->type != JPACKET_PRESENCE){
      jutil_error(jp->x,TERROR_NOTFOUND);
      it_deliver(ti,jp->x);
    }
    else
      xmlnode_free(jp->x);
      } else if ((alt_s != NULL) && (
               (jp->type == JPACKET_MESSAGE)            // all messages
            || ((jp->type == JPACKET_IQ) && (j_strcmp(xmlnode_get_attrib(jp->iq,"xmlns"),NS_VCARD) == -1)) // all IQs except of vCard
            || (jp->type == JPACKET_PRESENCE) )) {      // all presences _targeted_to_specific_user_
        // rewriting "to" and "from" and putting packet back on the wire
        xmlnode_put_attrib(jp->x, "from", jid_full(it_uin2jid(jp->p,s->uin,jp->to->server)));
        xmlnode_put_attrib(jp->x, "to", jid_full(alt_s->s->orgid));
        SEM_UNLOCK(ti->sessions_sem);
        it_deliver(ti,jp->x);
      } else {
        jp->aux1 = (void *) s;
        mtq_send(s->q,jp->p,it_session_jpacket,(void *) jp);
        SEM_UNLOCK(ti->sessions_sem);
      }
    }
    else {
	  SEM_UNLOCK(ti->sessions_sem);

      if(jpacket_subtype(jp)!=JPACKET__ERROR)
    it_unknown(ti,jp);
      else
    xmlnode_free(jp->x);
    }
    return r_DONE;
}
示例#18
0
/*
 *  Buffer 2 Node DMA transfer
 */
void ipc_dma_memcpy_buf2node(struct USB_IPC_API_PARAMS *ipc_ch)
{
	int size, len, index, frame_index, num;
	IPC_DATA_HEADER *header;
	HW_CTRL_IPC_WRITE_STATUS_T ipc_status;

	DEBUG("%s\n", __func__);

	if (ipc_memcpy_buf2node.dma_ch == -1) {	/* error: using memcpy */
		header = (IPC_DATA_HEADER *) (ipc_ch->read_ptr.temp_buff);
		size = header->frames[0].length;
		len = sizeof(IPC_DATA_HEADER_INDEX) +
			(sizeof(IPC_FRAME_DESCRIPTOR) * (header->nb_frame));
		/* copy data from temporary buffer to scatter buffers */
		for (index = 0, frame_index = 0;
		     index < ipc_ch->read_ptr.node_num; index++) {
			num = (size > (ipc_ch->read_ptr.node_ptr)[index].
				length) ?
				(ipc_ch->read_ptr.node_ptr)[index].length :
				size;
			memcpy((ipc_ch->read_ptr.node_ptr)[index].data_ptr,
				(void *)&((ipc_ch->read_ptr.temp_buff)[len]),
				num);
			ipc_ch->read_ptr.total_num += num;
			/* set flag to indicate received data is filled ... */
			(ipc_ch->read_ptr.node_ptr)[index].comand |=
				NODE_DESCRIPTOR_DONE_BIT;
			size -= num;
			len += num;
			if (size == 0) {
				(ipc_ch->read_ptr.node_ptr)[index].length =
					num;
				(ipc_ch->read_ptr.node_ptr)[index].
					comand |= NODE_DESCRIPTOR_LAST_BIT;
				frame_index++;
				if ((frame_index >= header->nb_frame) ||
					(frame_index >= MAX_FRAME_NUM))
					break;

				size = header->frames[frame_index].length;
			}
		}
		if (index < ipc_ch->read_ptr.node_num) {
			ipc_ch->read_ptr.node_ptr[index].comand |=
			    NODE_DESCRIPTOR_END_BIT;
		} else {
			ipc_ch->read_ptr.node_ptr[index - 1].comand |=
			    NODE_DESCRIPTOR_END_BIT;
		}

		/* clear flag to indicate API read function call is done */
		ipc_ch->read_flag = 0;
		if (ipc_ch->cfg.read_callback != NULL) {
			LOG_IPC_ACTIVITY(aIpcR, iIpcR, 0x1F);
			ipc_status.nb_bytes = ipc_ch->read_ptr.total_num;
			ipc_status.channel = &ipc_ch->ch;
			ipc_ch->cfg.read_callback(&ipc_status);
		} else {
			SEM_UNLOCK(&ipc_ch->read_ptr.read_mutex);
		}
		return;
	}

	header = (IPC_DATA_HEADER *) (ipc_ch->read_ptr.temp_buff);
	DEBUG("header->version=%x header->nb_frame=%d"
		"read_ptr.temp_buff_phy_addr=%x\n",
		header->version, header->nb_frame,
		ipc_ch->read_ptr.temp_buff_phy_addr);

	ipc_memcpy_buf2node.node_index = 0;
	ipc_memcpy_buf2node.frame_index = 0;
	ipc_memcpy_buf2node.total_size = 0;
	ipc_memcpy_buf2node.ipc_ch = ipc_ch;
	ipc_memcpy_buf2node.header =
		(IPC_DATA_HEADER *)(ipc_ch->read_ptr.temp_buff);
	ipc_memcpy_buf2node.buf_phy = ipc_ch->read_ptr.temp_buff_phy_addr +
		(sizeof(IPC_DATA_HEADER_INDEX) +
			(sizeof(IPC_FRAME_DESCRIPTOR) *
				(ipc_memcpy_buf2node.header->nb_frame)));

	/* set DMA parameters, then start DMA transfer */
	size = ipc_memcpy_buf2node.header->frames
		[ipc_memcpy_buf2node.frame_index].length;
	if (size > ipc_ch->read_ptr.node_ptr[0].length)
		size = ipc_ch->read_ptr.node_ptr[0].length;

	ipc_ch->read_ptr.node_ptr[0].length = size;

	DEBUG("Start DMA:buf_phy=%lx total_size=%d"
	      "node_index=%d frame_index=%d\n",
	      ipc_memcpy_buf2node.buf_phy, ipc_memcpy_buf2node.total_size,
	      ipc_memcpy_buf2node.node_index,
	      ipc_memcpy_buf2node.frame_index);

	LOG_IPC_ACTIVITY(aIpcR, iIpcR, 0x14);
	/* set DMA parameters, then start DMA transfer */
	OMAP_DMA_MEM2MEM_START(ipc_memcpy_buf2node.dma_ch,
			ipc_memcpy_buf2node.buf_phy,
			NODE_BUF_PHYS_ADDR(ipc_ch->read_ptr.node_ptr
				[ipc_memcpy_buf2node.node_index].data_ptr),
			size);
}
示例#19
0
/*
 *  Buffer 2 Node DMA callback
 */
void ipc_dma_buf2node_callback(int lch, u16 ch_status, void *data)
{
	int size;
	HW_CTRL_IPC_WRITE_STATUS_T ipc_status;
	struct USB_IPC_API_PARAMS *ipc_ch;

	DEBUG("%s\n", __func__);

	ipc_ch = ipc_memcpy_buf2node.ipc_ch;
	/* Set DONE bit. If all node buffer are copied to URB buffer,
	 * finished
	 */
	ipc_ch->read_ptr.node_ptr[ipc_memcpy_buf2node.node_index].comand |=
		NODE_DESCRIPTOR_DONE_BIT;
	ipc_memcpy_buf2node.buf_phy +=
		ipc_ch->read_ptr.node_ptr[ipc_memcpy_buf2node.node_index].
			length;
	ipc_memcpy_buf2node.header->frames[ipc_memcpy_buf2node.
					   frame_index].length -=
		ipc_ch->read_ptr.node_ptr[ipc_memcpy_buf2node.node_index].
			length;
	if (ipc_memcpy_buf2node.header->
	    frames[ipc_memcpy_buf2node.frame_index].length == 0) {
		ipc_ch->read_ptr.node_ptr[ipc_memcpy_buf2node.node_index].
			comand |= NODE_DESCRIPTOR_LAST_BIT;
		ipc_memcpy_buf2node.frame_index++;
	}

	dma_cache_maint(ipc_ch->read_ptr.
			node_ptr[ipc_memcpy_buf2node.node_index].data_ptr,
		ipc_ch->read_ptr.node_ptr
			[ipc_memcpy_buf2node.node_index].length,
		DMA_FROM_DEVICE);

	ipc_memcpy_buf2node.total_size +=
		ipc_ch->read_ptr.node_ptr[ipc_memcpy_buf2node.node_index].
			length;

	ipc_memcpy_buf2node.node_index++;
	if ((ipc_memcpy_buf2node.node_index >=
	     ipc_memcpy_buf2node.ipc_ch->read_ptr.node_num) ||
	    (ipc_memcpy_buf2node.frame_index >=
	     ipc_memcpy_buf2node.header->nb_frame)) {
		omap_stop_dma(ipc_memcpy_buf2node.dma_ch);

		ipc_ch->read_ptr.node_ptr
			[ipc_memcpy_buf2node.node_index-1].comand |=
		    NODE_DESCRIPTOR_END_BIT;

		DEBUG("DMA copy ok:header->version=%x header->nb_frame=%d\n",
			ipc_memcpy_buf2node.header->version,
			ipc_memcpy_buf2node.header->nb_frame);
		DEBUG("buf_phy=%lx total_size=%d node_index=%d "
		      "frame_index=%d\n",
			ipc_memcpy_buf2node.buf_phy,
			ipc_memcpy_buf2node.total_size,
			ipc_memcpy_buf2node.node_index,
			ipc_memcpy_buf2node.frame_index);

		/* clear flag to indicate API read function call is done */
		ipc_memcpy_buf2node.ipc_ch->read_flag = 0;

		/* read callback, ... */
		if (ipc_memcpy_buf2node.ipc_ch->cfg.read_callback != NULL) {
			ipc_status.nb_bytes = ipc_memcpy_buf2node.total_size;
			ipc_status.channel = &ipc_memcpy_buf2node.ipc_ch->ch;
			LOG_IPC_ACTIVITY(aIpcR, iIpcR, 0x16);
			ipc_memcpy_buf2node.ipc_ch->cfg.
				read_callback(&ipc_status);
		} else {
			LOG_IPC_ACTIVITY(aIpcR, iIpcR, 0x1E);
			SEM_UNLOCK(&ipc_memcpy_buf2node.ipc_ch->read_ptr.
				read_mutex);
		}
		return;
	}

	/* set DMA parameters, then start DMA transfer */
	size = ipc_memcpy_buf2node.header->frames
			[ipc_memcpy_buf2node.frame_index].length;
	if (size >
	    ipc_ch->read_ptr.node_ptr[ipc_memcpy_buf2node.node_index].
	    length) {
		size = ipc_ch->read_ptr.node_ptr[ipc_memcpy_buf2node.
				node_index].length;
	}
	ipc_ch->read_ptr.node_ptr[ipc_memcpy_buf2node.node_index].length =
	    size;

	DEBUG("Continue DMA:buf_phy=%lx total_size=%d"
	      "node_index=%d frame_index=%d\n",
		ipc_memcpy_buf2node.buf_phy, ipc_memcpy_buf2node.total_size,
		ipc_memcpy_buf2node.node_index,
		ipc_memcpy_buf2node.frame_index);
	LOG_IPC_ACTIVITY(aIpcR, iIpcR, 0x15);
	/* set DMA parameters, then start DMA transfer */
	OMAP_DMA_MEM2MEM_START(ipc_memcpy_buf2node.dma_ch,
		ipc_memcpy_buf2node.buf_phy,
		NODE_BUF_PHYS_ADDR(ipc_ch->read_ptr.
			node_ptr[ipc_memcpy_buf2node.node_index].data_ptr),
		size);
}
示例#20
0
文件: deliver.c 项目: smokku/wpjabber
/* any thread */
result js_packet(instance i, dpacket p, void *arg)
{
	jsmi si = (jsmi) arg;
	jpacket jp = NULL;
	session s = NULL;
	packet_thread_p pt;
	udata u;

	char *type, *authto;

	log_debug("incoming packet %s", xmlnode2str(p->x));

	/* if this is a routed packet */
	if (p->type == p_ROUTE) {
		type = xmlnode_get_attrib(p->x, "type");

		/* new session requests */
		if (j_strcmp(type, "session") == 0) {
			js_session_new_mtq(si, p);
			return r_DONE;
		}

		/* get the internal jpacket */
		if (xmlnode_get_firstchild(p->x) != NULL)	/* XXX old libjabber jpacket_new() wasn't null safe, this is just safety */
			jp = jpacket_new(xmlnode_get_firstchild(p->x));


		/* auth/reg requests */
		if (jp != NULL && j_strcmp(type, "auth") == 0) {
			/* check and see if we're configured to forward auth packets for processing elsewhere */
			if ((authto =
			     xmlnode_get_data(js_config(si, "auth"))) !=
			    NULL) {
				xmlnode_put_attrib(p->x, "oto", xmlnode_get_attrib(p->x, "to"));	/* preserve original to */
				xmlnode_put_attrib(p->x, "to", authto);
				deliver(dpacket_new(p->x), i);
				return r_DONE;
			}

			/* internally, hide the route to/from addresses on the authreg request */
			xmlnode_put_attrib(jp->x, "to",
					   xmlnode_get_attrib(p->x, "to"));
			xmlnode_put_attrib(jp->x, "from",
					   xmlnode_get_attrib(p->x,
							      "from"));
			xmlnode_put_attrib(jp->x, "route",
					   xmlnode_get_attrib(p->x,
							      "type"));
			jpacket_reset(jp);
			jp->aux1 = (void *) si;

			pt = pmalloco(jp->p, sizeof(packet_thread_t));
			pt->jp = jp;
			fast_mtq_send(si->mtq_authreg, pt);
			return r_DONE;
		}

		/* if it's an error */
		if (j_strcmp(type, "error") == 0) {

			/* look for users online */
			u = js_user(si, p->id, 1);
			if (u == NULL) {
				/* if this was a message,
				   it should have been delievered to that session, store offline */
				if (jp != NULL
				    && jp->type == JPACKET_MESSAGE) {
					pt = pmalloco(jp->p,
						      sizeof
						      (packet_thread_t));
					pt->jp = jp;
					fast_mtq_send(si->mtq_deliver, pt);
					return r_DONE;
				}

				xmlnode_free(p->x);
				return r_DONE;
				/*
				   log_notice(p->host,
				   "Bouncing packet intended for nonexistant user: %s",
				   xmlnode2str(p->x));
				   deliver_fail(dpacket_new(p->x), "Invalid User");
				   return r_DONE;
				 */
			}

			if (p->id->resource != NULL) {
				SEM_LOCK(u->sem);
				for (s = u->sessions; s != NULL;
				     s = s->next)
					if (j_strcmp
					    (p->id->resource,
					     s->route->resource) == 0)
						break;
				SEM_UNLOCK(u->sem);

				if (s != NULL) {
					s->sid = NULL;	/* they generated the error,
							   no use in sending there anymore! */
					js_session_end(s, "Disconnected");
				}
			} else {
				session temp;
				/* a way to boot an entire user off */
				SEM_LOCK(u->sem);
				for (s = u->sessions; s != NULL;) {
					temp = s;
					s = s->next;
					js_session_end_nosem(temp,
							     "Removed");
				}
				u->pass = NULL;	/* so they can't log back in */

				SEM_UNLOCK(u->sem);

				xmlnode_free(p->x);
				THREAD_DEC(u->ref);
				return r_DONE;
			}

			THREAD_DEC(u->ref);

			/* if this was a message,
			   it should have been delievered to that session, store offline */
			if (jp != NULL && jp->type == JPACKET_MESSAGE) {
				pt = pmalloco(jp->p,
					      sizeof(packet_thread_t));
				pt->jp = jp;
				fast_mtq_send(si->mtq_deliver, pt);
				return r_DONE;
			}

			/* drop and return */
			if (xmlnode_get_firstchild(p->x) != NULL)
				log_notice(p->host,
					   "Dropping a bounced session packet to %s",
					   jid_full(p->id));

			xmlnode_free(p->x);
			return r_DONE;
		}

		/* uhh, empty packet, *shrug* */
		if (jp == NULL) {
			log_notice(p->host,
				   "Dropping an invalid or empty route packet: %s",
				   xmlnode2str(p->x), jid_full(p->id));
			xmlnode_free(p->x);
			return r_DONE;
		}

		/* ============================================================== */


		/* attempt to locate the session by matching the special resource */
		u = js_user(si, p->id, 1);
		if (u == NULL) {
			/* only when route packet to users not online */
			pt = pmalloco(p->p, sizeof(packet_thread_t));
			pt->p = p;
			pt->jp = jp;
			fast_mtq_send(si->mtq_deliver, pt);
			return r_DONE;
		}

		/* user is online :) */
		SEM_LOCK(u->sem);
		for (s = u->sessions; s != NULL; s = s->next)
			if (j_strcmp(p->id->resource, s->route->resource)
			    == 0)
				break;
		SEM_UNLOCK(u->sem);

		THREAD_DEC(u->ref);

		if (s != NULL) {	/* just pass to the session normally */
			js_session_from(s, jp);
			return r_DONE;
		}

		log_notice(p->host,
			   "Bouncing %s packet intended for session %s",
			   xmlnode_get_name(jp->x), jid_full(p->id));
		deliver_fail(dpacket_new(p->x), "Invalid Session");
		return r_DONE;
	}

	/* normal server-server packet, should we make sure it's not spoofing us?  if so, if ghash_get(p->to->server) then bounce w/ security error */

	jp = jpacket_new(p->x);
	if (jp == NULL) {
		log_warn(p->host, "Dropping invalid incoming packet: %s",
			 xmlnode2str(p->x));
		xmlnode_free(p->x);
		return r_DONE;
	}

	pt = pmalloco(jp->p, sizeof(packet_thread_t));
	pt->jp = jp;
	fast_mtq_send(si->mtq_deliver, pt);
	return r_DONE;
}
示例#21
0
文件: xdb.c 项目: smokku/wpjabber
/* blocks until namespace is retrieved, host must map back to this service! */
xmlnode xdb_get(xdbcache xc, jid owner, char *ns)
{
	xdbrequest_p cur;
	xmlnode x;
	struct timeval tv;

	if (xc->shutdown)
		return NULL;

	if (xc == NULL || owner == NULL || ns == NULL) {
		if (ns) {
			log_alert("xdb_get",
				  "Programming Error: xdb_get() called with NULL ns: %s\n",
				  ns);
		} else {
			log_alert("xdb_get",
				  "Programming Error: xdb_get() called with NULL ns: NULL\n");
		}

		if (owner) {
			log_alert("owner", "%s", jid_full(owner));
		}
		return NULL;
	}

	log_debug("XDB GET");

	/* init this newx */
	cur = malloc(sizeof(xdbrequest_t));
	memset(cur, 0, sizeof(xdbrequest_t));
	// cur->set = 0;
	// cur->data = NULL;
	cur->ns = ns;
	cur->owner = owner;
	gettimeofday(&tv, NULL);
	cur->sent = tv.tv_sec;

	SEM_LOCK(xc->sem);
	cur->id = xc->id++;

	cur->next = xc->first;
	xc->first = cur;

	SEM_UNLOCK(xc->sem);

	/* send it on it's way */
	xdb_deliver(xc->i, cur, 0);
	cur->external = 1;

	/* if it hasn't already returned, we should block here until it returns */
	while (cur->preblock != 1)
		usleep(10);

	/* newx.data is now the returned xml packet */

	/* return the xmlnode inside <xdb>...</xdb> */
	for (x = xmlnode_get_firstchild(cur->data);
	     x != NULL && xmlnode_get_type(x) != NTYPE_TAG;
	     x = xmlnode_get_nextsibling(x));

	/* there were no children (results) to the xdb request, free the packet */
	if (x == NULL)
		xmlnode_free(cur->data);

	free(cur);
	return x;
}