📄 pkt.c
字号:
/* * jabberd - Jabber Open Source Server * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney, * Ryan Eatmon, Robert Norris * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA */#include "sm.h"/** @file sm/pkt.c * @brief packet abstraction * @author Robert Norris * $Date: 2004/10/05 04:34:10 $ * $Revision: 1.25.2.4 $ */pkt_t pkt_error(pkt_t pkt, int err) { if(pkt == NULL) return NULL; /* if it's an error already, log, free, return */ if(pkt->type & pkt_ERROR) { log_debug(ZONE, "dropping error pkt"); pkt_free(pkt); return NULL; } stanza_error(pkt->nad, 1, err); /* update vars and attrs */ pkt_tofrom(pkt); pkt->type |= pkt_ERROR; /* all done, error'd and addressed */ log_debug(ZONE, "processed %d error pkt", err); return pkt;}/** swap a packet's to and from attributes */pkt_t pkt_tofrom(pkt_t pkt) { jid_t tmp; if(pkt == NULL) return NULL; /* swap vars */ tmp = pkt->from; pkt->from = pkt->to; pkt->to = tmp; /* update attrs */ if(pkt->to != NULL) nad_set_attr(pkt->nad, 1, -1, "to", jid_full(pkt->to), 0); if(pkt->from != NULL) nad_set_attr(pkt->nad, 1, -1, "from", jid_full(pkt->from), 0); return pkt;}/** duplicate pkt, replacing addresses */pkt_t pkt_dup(pkt_t pkt, const char *to, const char *from) { pkt_t pnew; if(pkt == NULL) return NULL; pnew = (pkt_t) malloc(sizeof(struct pkt_st)); memset(pnew, 0, sizeof(struct pkt_st)); pnew->sm = pkt->sm; pnew->type = pkt->type; pnew->nad = nad_copy(pkt->nad); /* set replacement attrs */ if(to != NULL) { pnew->to = jid_new(pkt->sm->pc, to, 0); nad_set_attr(pnew->nad, 1, -1, "to", jid_full(pnew->to), 0); } else if(pkt->to != NULL) pnew->to = jid_dup(pkt->to); if(from != NULL) { pnew->from = jid_new(pkt->sm->pc, from, 0); nad_set_attr(pnew->nad, 1, -1, "from", jid_full(pnew->from), 0); } else if(pkt->from != NULL) pnew->from = jid_dup(pkt->from); log_debug(ZONE, "duplicated packet"); return pnew;}pkt_t pkt_new(sm_t sm, nad_t nad) { pkt_t pkt; int ns, attr, elem; char pri[20]; log_debug(ZONE, "creating new packet"); /* find the route */ ns = nad_find_namespace(nad, 0, uri_COMPONENT, NULL); if(ns < 0) { log_debug(ZONE, "packet not in component namespace"); return NULL; } /* create the pkt holder */ pkt = (pkt_t) malloc(sizeof(struct pkt_st)); memset(pkt, 0, sizeof(struct pkt_st)); pkt->sm = sm; pkt->nad = nad; /* routes */ if(NAD_ENAME_L(nad, 0) == 5 && strncmp("route", NAD_ENAME(nad, 0), 5) == 0) { /* route element */ if((attr = nad_find_attr(nad, 0, -1, "to", NULL)) >= 0) pkt->rto = jid_new(sm->pc, NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr)); if((attr = nad_find_attr(nad, 0, -1, "from", NULL)) >= 0) pkt->rfrom = jid_new(sm->pc, NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr)); /* route type */ attr = nad_find_attr(nad, 0, -1, "type", NULL); if(attr < 0) pkt->rtype = route_UNICAST; else if(NAD_AVAL_L(nad, attr) == 9 && strncmp("broadcast", NAD_AVAL(nad, attr), 9) == 0) pkt->rtype = route_BROADCAST; /* route errors */ if(nad_find_attr(nad, 0, -1, "error", NULL) >= 0) pkt->rtype |= route_ERROR; /* client packets */ ns = nad_find_namespace(nad, 1, uri_CLIENT, NULL); if(ns >= 0) { /* get initial addresses */ if((attr = nad_find_attr(pkt->nad, 1, -1, "to", NULL)) >= 0 && NAD_AVAL_L(pkt->nad, attr) > 0) pkt->to = jid_new(sm->pc, NAD_AVAL(pkt->nad, attr), NAD_AVAL_L(pkt->nad, attr)); if((attr = nad_find_attr(pkt->nad, 1, -1, "from", NULL)) >= 0 && NAD_AVAL_L(pkt->nad, attr) > 0) pkt->from = jid_new(sm->pc, NAD_AVAL(pkt->nad, attr), NAD_AVAL_L(pkt->nad, attr)); /* find type, if any */ attr = nad_find_attr(pkt->nad, 1, -1, "type", NULL); /* messages are simple */ if(NAD_ENAME_L(pkt->nad, 1) == 7 && strncmp("message", NAD_ENAME(pkt->nad, 1), 7) == 0) { pkt->type = pkt_MESSAGE; if(attr >= 0 && NAD_AVAL_L(pkt->nad, attr) == 5 && strncmp("error", NAD_AVAL(pkt->nad, attr), 5) == 0) pkt->type |= pkt_ERROR; return pkt; } /* presence is a mixed bag, s10ns in here too */ if(NAD_ENAME_L(pkt->nad, 1) == 8 && strncmp("presence", NAD_ENAME(pkt->nad, 1), 8) == 0) { pkt->type = pkt_PRESENCE; if(attr >= 0) { if(NAD_AVAL_L(pkt->nad, attr) == 11 && strncmp("unavailable", NAD_AVAL(pkt->nad, attr), 11) == 0) pkt->type = pkt_PRESENCE_UN; else if(NAD_AVAL_L(pkt->nad, attr) == 5 && strncmp("probe", NAD_AVAL(pkt->nad, attr), 5) == 0) pkt->type = pkt_PRESENCE_PROBE; else if(NAD_AVAL_L(pkt->nad, attr) == 9 && strncmp("invisible", NAD_AVAL(pkt->nad, attr), 9) == 0) pkt->type = pkt_PRESENCE_INVIS; else if(NAD_AVAL_L(pkt->nad, attr) == 9 && strncmp("subscribe", NAD_AVAL(pkt->nad, attr), 9) == 0) pkt->type = pkt_S10N; else if(NAD_AVAL_L(pkt->nad, attr) == 10 && strncmp("subscribed", NAD_AVAL(pkt->nad, attr), 10) == 0) pkt->type = pkt_S10N_ED; else if(NAD_AVAL_L(pkt->nad, attr) == 11 && strncmp("unsubscribe", NAD_AVAL(pkt->nad, attr), 11) == 0) pkt->type = pkt_S10N_UN; else if(NAD_AVAL_L(pkt->nad, attr) == 12 && strncmp("unsubscribed", NAD_AVAL(pkt->nad, attr), 12) == 0) pkt->type = pkt_S10N_UNED; else if(NAD_AVAL_L(pkt->nad, attr) == 5 && strncmp("error", NAD_AVAL(pkt->nad, attr), 5) == 0) pkt->type = pkt_PRESENCE | pkt_ERROR; } /* priority */ if((elem = nad_find_elem(pkt->nad, 1, NAD_ENS(pkt->nad, 1), "priority", 1)) < 0) return pkt; if(NAD_CDATA_L(pkt->nad, elem) <= 0 || NAD_CDATA_L(pkt->nad, elem) > 19) return pkt; memcpy(pri, NAD_CDATA(pkt->nad, elem), NAD_CDATA_L(pkt->nad, elem)); pri[NAD_CDATA_L(pkt->nad, elem)] = '\0'; pkt->pri = atoi(pri); if(pkt->pri > 127) pkt->pri = 127; if(pkt->pri < -128) pkt->pri = -128; return pkt; } /* iq's are pretty easy, but also set xmlns */ if(NAD_ENAME_L(pkt->nad, 1) == 2 && strncmp("iq", NAD_ENAME(pkt->nad, 1), 2) == 0) { pkt->type = pkt_IQ; if(attr >= 0) { if(NAD_AVAL_L(pkt->nad, attr) == 3 && strncmp("set", NAD_AVAL(pkt->nad, attr), 3) == 0) pkt->type = pkt_IQ_SET; else if(NAD_AVAL_L(pkt->nad, attr) == 6 && strncmp("result", NAD_AVAL(pkt->nad, attr), 6) == 0) pkt->type = pkt_IQ_RESULT; else if(NAD_AVAL_L(pkt->nad, attr) == 5 && strncmp("error", NAD_AVAL(pkt->nad, attr), 5) == 0) pkt->type = pkt_IQ | pkt_ERROR; } if(pkt->nad->ecur > 2 && (ns = NAD_ENS(pkt->nad, 2)) >= 0) pkt->ns = (int) xhash_getx(pkt->sm->xmlns, NAD_NURI(pkt->nad, ns), NAD_NURI_L(pkt->nad, ns)); return pkt; } log_debug(ZONE, "unknown client namespace packet"); return pkt; } /* sessions packets */ ns = nad_find_namespace(nad, 1, uri_SESSION, NULL); if(ns >= 0) { /* sessions */ if(NAD_ENAME_L(pkt->nad, 1) == 7 && strncmp("session", NAD_ENAME(pkt->nad, 1), 7) == 0) { /* find action */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -