jabberd2
2.2.16
|
00001 /* 00002 * jabberd - Jabber Open Source Server 00003 * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney, 00004 * Ryan Eatmon, Robert Norris 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA 00019 */ 00020 00021 #include "sm.h" 00022 00030 static mod_ret_t _deliver_in_sess(mod_instance_t mi, sess_t sess, pkt_t pkt) 00031 { 00032 /* ensure from is set correctly if not already by client */ 00033 if(pkt->from == NULL || jid_compare_user(pkt->from, sess->jid) != 0) { 00034 if(pkt->from != NULL) 00035 jid_free(pkt->from); 00036 00037 pkt->from = jid_dup(sess->jid); 00038 nad_set_attr(pkt->nad, 1, -1, "from", jid_full(pkt->from), 0); 00039 } 00040 00041 /* no to address means its to us */ 00042 if(pkt->to == NULL) { 00043 /* drop iq-result packets */ 00044 /* user client is confirming all iq-set, but we usually do not track these 00045 * confirmations and we need to drop it here, not loop back to client */ 00046 if(pkt->type == pkt_IQ_RESULT) { 00047 pkt_free(pkt); 00048 return mod_HANDLED; 00049 } 00050 00051 /* iq packets without to should have been already handled by modules */ 00052 if(pkt->type & pkt_IQ) { 00053 return -stanza_err_FEATURE_NOT_IMPLEMENTED; 00054 } 00055 00056 /* supplant user jid as 'to' */ 00057 pkt->to = jid_dup(sess->jid); 00058 nad_set_attr(pkt->nad, 1, -1, "to", jid_full(pkt->to), 0); 00059 } 00060 00061 /* let it go on the wire */ 00062 pkt_router(pkt); 00063 00064 return mod_HANDLED; 00065 } 00066 00067 static mod_ret_t _deliver_pkt_user(mod_instance_t mi, user_t user, pkt_t pkt) 00068 { 00069 sess_t sess; 00070 00071 /* if there's a resource, send it direct */ 00072 if(*pkt->to->resource != '\0') { 00073 /* find the session */ 00074 sess = sess_match(user, pkt->to->resource); 00075 00076 /* and send it straight there */ 00077 if(sess != NULL) { 00078 pkt_sess(pkt, sess); 00079 return mod_HANDLED; 00080 } 00081 00082 /* no session */ 00083 if(pkt->type & pkt_PRESENCE) { 00084 pkt_free(pkt); 00085 return mod_HANDLED; 00086 00087 } else if(pkt->type & pkt_IQ) 00088 return -stanza_err_SERVICE_UNAVAILABLE; 00089 00090 /* unmatched messages will fall through (XMPP-IM r20 s11 rule 2) */ 00091 } 00092 00093 return mod_PASS; 00094 } 00095 00096 DLLEXPORT int module_init(mod_instance_t mi, char *arg) { 00097 module_t mod = mi->mod; 00098 00099 if(mod->init) return 0; 00100 00101 mod->in_sess = _deliver_in_sess; 00102 mod->pkt_user = _deliver_pkt_user; 00103 00104 feature_register(mod->mm->sm, "message"); 00105 00106 return 0; 00107 }