📄 sessions.c
字号:
} /* is history storage requested? */ /* only store messages */ if (store_history && p->type != JPACKET_MESSAGE) store_history = 0; /* don't store special messages, if not requested to do so */ if (store_history && !s->si->history_sent.special) { switch (jpacket_subtype(p)) { case JPACKET__HEADLINE: case JPACKET__GROUPCHAT: case JPACKET__ERROR: store_history = 0; } } /* don't store events */ if (store_history && xmlnode_get_tag(p->x, "?xmlns=" NS_EVENT) != NULL) if (xmlnode_get_tag(p->x, "body") == NULL) store_history = 0; if (store_history) { char *temp = xmlnode_get_attrib(p->x, "direction"); xmlnode_put_attrib(p->x, "direction", "sent"); xdb_act(s->si->xc, s->u->id, NS_JABBERD_HISTORY, "insert", NULL, p->x); if (temp == NULL) { xmlnode_hide_attrib(p->x, "direction"); } else { xmlnode_put_attrib(p->x, "direction", temp); } } /* let the modules have their heyday */ if(js_mapi_call(NULL, es_OUT, p, s->u, s)) return; /* no module handled it, so restore the to attrib to us */ if(p->to == NULL) { xmlnode_put_attrib(p->x,"to",jid_full(uid)); p->to = jid_new(p->p,jid_full(uid)); } /* pass these to the general delivery function */ js_deliver(s->si, p);}/** * child that handles packets to a specified resource (session) of a user * * It is checked if the session the packet is addressed to has the exit_flag set, * if so it is sent back (?) to js_deliver(). If the exit_flag is not set * it is first tried if one of the registered callbacks for es_IN handles the * packet. Iff not the exit_flag is checked again (and probably the packet sent * back to js_deliver()) and if it is still not set, the packet is passed to * js_session_route() which delivers it to the c2s for sending it to the * connection related to the session. * * @param arg the packet */void _js_session_to(void *arg){ jpacket p = (jpacket)arg; session s = (session)(p->aux1); int store_history = s->si->history_recv.general; /* if this session is dead... */ if(s->exit_flag) { /* ... and the packet is a message */ if(p->type == JPACKET_MESSAGE) js_deliver(s->si, p); else /* otherwise send it to oblivion */ xmlnode_free(p->x); return; } /* debug message */ log_debug2(ZONE, LOGT_DELIVER, "THREAD:SESSION:TO received data from %s!",jid_full(p->from)); /* increment packet in count */ s->c_in++; /* let the modules have their heyday */ if(js_mapi_call(NULL, es_IN, p, s->u, s)) return; /* we need to check again, s->exit_flag *could* have changed within the modules at some point */ if(s->exit_flag) { /* deliver that packet if it was a message, and sk'daddle */ if(p->type == JPACKET_MESSAGE) js_deliver(s->si, p); else xmlnode_free(p->x); return; } /* is history storage requested? */ /* only store messages */ if (store_history && p->type != JPACKET_MESSAGE) store_history = 0; /* don't store messages from offline storage, if not requested to do so */ if (store_history && p->flag == PACKET_FROM_OFFLINE_MAGIC && !s->si->history_recv.offline) store_history = 0; /* don't store special messages, if not requested to do so */ if (store_history && !s->si->history_recv.special) { switch (jpacket_subtype(p)) { case JPACKET__HEADLINE: case JPACKET__GROUPCHAT: case JPACKET__ERROR: store_history = 0; } } /* don't store events */ if (store_history && xmlnode_get_tag(p->x, "?xmlns=" NS_EVENT) != NULL) if (xmlnode_get_tag(p->x, "body") == NULL) store_history = 0; if (store_history) { char *temp = xmlnode_get_attrib(p->x, "direction"); xmlnode_put_attrib(p->x, "direction", "recv"); xdb_act(s->si->xc, s->u->id, NS_JABBERD_HISTORY, "insert", NULL, p->x); if (temp == NULL) { xmlnode_hide_attrib(p->x, "direction"); } else { xmlnode_put_attrib(p->x, "direction", temp); } } /* deliver to listeners on session */ js_session_route(s, p->x);}/** * child that cleans up a session * * Notify the responsible c2s instance about the closed session. * Call the modules that registered for the es_END event, to notify them about the closed session * * @param arg the session, that is closing */void _js_session_end(void *arg){ session s = (session)arg; /* debug message */ log_debug2(ZONE, LOGT_SESSION, "THREAD:SESSION exiting"); /* decrement the user's session count */ s->u->scount--; /* make sure the service knows the session is gone */ if(s->sid != NULL) js_session_route(s, NULL); /* let the modules have their heyday */ js_mapi_call(NULL, es_END, NULL, s->u, s); /* let the user struct go */ s->u->ref--; /* free the session's presence state */ xmlnode_free(s->presence); /* free the session's memory pool */ pool_free(s->p);}/** * find the session for a given resource * * Given a user and a resource, find the corresponding session * if the user is logged in. Otherweise return NULL. * * @param user the user's udata record * @param res the resource to search for * @return 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*/ for(cur = user->sessions; cur != NULL; cur = cur->next) if(j_strcmp(res, cur->res) == 0) 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) return cur; /* if we got this far, there is no session */ return NULL;}/** * find the primary session for the user * * Scan through the user's sessions to find the session with the * highest priority and return a pointer to it. * * @param user the user to find the highest session for * @return pointer to the primary session if the user is logged in with at least priority 0, NULL if there is no active session with a priority of at least 0 */session js_session_primary(udata user) { session cur, top; /* ignore illegal calls, or users with no sessions */ if(user == NULL || user->sessions == NULL) return NULL; /* find primary session */ 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 >= 0) return top; /* otherwise there's no active session */ return NULL;}/** * handle packets addresses to a specific resource (session) of a user * * pass them to _js_session_to() ... * * @param s the session the packet is addressed to * @param p the packet */void js_session_to(session s, jpacket p){ /* XXX: Florian had on his server the case where mod_offline.c called this function * with p==NULL, I don't know how this could happen yet. I have to check further if * this is a bug that is remotly expoitable ... if NULL is passed as p, p->p in this * function will cause a segmentation violation! */ if (s==NULL || p==NULL) { log_debug(ZONE, "logic error? js_session_to(%x, %x)", s, p); return; } /* queue the call to child, hide session in packet */ p->aux1 = (void *)s; mtq_send(s->q, p->p, _js_session_to, (void *)p);}/** * handle normal stanzas received inside a <route/> stanza from * jabberd. These are packets we get from the client connection manager, * that are from one of our users. * * Pass them to _js_session_from() ... * * @param s the session of the user * @param p the received packet */void js_session_from(session s, jpacket p){ /* check the provided parameters */ if (s==NULL || p==NULL) { log_debug(ZONE, "logic error? js_session_from(%x, %x)", s, p); return; } /* queue the call to child, hide session in packet */ p->aux1 = (void *)s; mtq_send(s->q, p->p, _js_session_from, (void *)p);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -