jabberd2  2.3.4
dispatch.c
Go to the documentation of this file.
1 /*
2  * jabberd - Jabber Open Source Server
3  * Copyright (c) 2002-2003 Jeremie Miller, Thomas Muldowney,
4  * Ryan Eatmon, Robert Norris
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA
19  */
20 
21 #include "sm.h"
22 
31 void dispatch(sm_t sm, pkt_t pkt) {
32  user_t user;
33  mod_ret_t ret;
34 
35  /* handle broadcasts */
36  if(pkt->rtype == route_BROADCAST) {
37  log_debug(ZONE, "can't handle broadcast routes (yet), dropping");
38  pkt_free(pkt);
39  return;
40  }
41 
42  /* routing errors, add a im error */
43  if(pkt->rtype & route_ERROR) {
44  int i, aerror, stanza_err;
45  aerror = nad_find_attr(pkt->nad, 0, -1, "error", NULL);
47  if(aerror >= 0) {
48  for(i=0; _stanza_errors[i].code != NULL; i++)
49  if(strncmp(_stanza_errors[i].code, NAD_AVAL(pkt->nad, aerror), NAD_AVAL_L(pkt->nad, aerror)) == 0) {
50  stanza_err = stanza_err_BAD_REQUEST + i;
51  break;
52  }
53  }
54  if(pkt_error(pkt, stanza_err) == NULL)
55  return;
56  }
57 
58  /*
59  * - if its from the router (non-route) it goes straight to pkt_router
60  * - hand it to in_router chain
61  * - if its for the sm itself (no user), hand it to the pkt_sm chain
62  * - find the user
63  * - hand to pkt_user
64  */
65 
66  /* non route packets are special-purpose things from the router */
67  if(!(pkt->rtype & route_UNICAST)) {
68  ret = mm_pkt_router(pkt->sm->mm, pkt);
69  switch(ret) {
70  case mod_HANDLED:
71  break;
72 
73  case mod_PASS:
74  default:
75  /* don't ever bounce these */
76  pkt_free(pkt);
77 
78  break;
79  }
80 
81  return;
82  }
83 
84  /* preprocessing */
85  if (pkt != NULL && pkt->sm != NULL) {
86  ret = mm_in_router(pkt->sm->mm, pkt);
87  switch(ret) {
88  case mod_HANDLED:
89  return;
90 
91  case mod_PASS:
92  break;
93 
94  default:
95  pkt_router(pkt_error(pkt, -ret));
96  return;
97  }
98  }
99 
100  /* has to come from someone and be directed to someone */
101  if(pkt->from == NULL || pkt->to == NULL) {
103  return;
104  }
105 
106  /* packet is for the sm itself */
107  if(*pkt->to->node == '\0') {
108  ret = mm_pkt_sm(pkt->sm->mm, pkt);
109  switch(ret) {
110  case mod_HANDLED:
111  break;
112 
113  case mod_PASS:
114  /* ignore IQ result packets that haven't been handled - XMPP 9.2.3.4 */
115  if(pkt->type == pkt_IQ_RESULT) {
116  pkt_free(pkt);
117  break;
118  } else
120 
121  default:
122  pkt_router(pkt_error(pkt, -ret));
123 
124  break;
125  }
126 
127  return;
128  }
129 
130  /* get the user */
131  user = user_load(sm, pkt->to);
132  if(user == NULL) {
133  if(pkt->type & pkt_PRESENCE && pkt->type != pkt_PRESENCE_PROBE) {
134  pkt_free(pkt);
135  return;
136  }
137 
138  if(pkt->type == pkt_PRESENCE_PROBE) {
139  pkt_router(pkt_create(pkt->sm, "presence", "unsubscribed", jid_full(pkt->from), jid_full(pkt->to)));
140  pkt_free(pkt);
141  return;
142  }
143 
145  return;
146  }
147 
148  if (pkt->sm != NULL) {
149  ret = mm_pkt_user(pkt->sm->mm, user, pkt);
150  switch(ret) {
151  case mod_HANDLED:
152  break;
153 
154  case mod_PASS:
155  /* ignore IQ result packets that haven't been handled - XMPP 9.2.3.4 */
156  if(pkt->type == pkt_IQ_RESULT) {
157  pkt_free(pkt);
158  break;
159  } else
161 
162  default:
163  pkt_router(pkt_error(pkt, -ret));
164 
165  break;
166  }
167  }
168 
169  /* if they have no sessions, they were only loaded to do delivery, so free them */
170  if(user->sessions == NULL)
171  user_free(user);
172 }
pkt_t pkt_error(pkt_t pkt, int err)
Definition: pkt.c:30
pkt_type_t type
packet type
Definition: sm.h:138
static sm_t sm
Definition: main.c:33
struct _stanza_error_st _stanza_errors[]
if you change these, reflect your changes in the defines in util.h
Definition: stanza.c:24
data structures and prototypes for the session manager
const char * jid_full(jid_t jid)
expand and return the full
Definition: jid.c:347
mm_t mm
module subsystem
Definition: sm.h:213
route error
Definition: sm.h:125
#define stanza_err_FEATURE_NOT_IMPLEMENTED
Definition: util.h:369
info/query (result)
Definition: sm.h:108
SM_API user_t user_load(sm_t sm, jid_t jid)
fetch user data
Definition: user.c:52
mod_ret_t mm_pkt_sm(mm_t mm, pkt_t pkt)
packets for sm
Definition: mm.c:567
const char * code
Definition: util.h:398
sm_t sm
sm context
Definition: sm.h:130
mod_ret_t mm_pkt_user(mm_t mm, user_t user, pkt_t pkt)
packets for user
Definition: mm.c:597
sess_t sessions
list of action sessions
Definition: sm.h:243
mod_ret_t mm_in_router(mm_t mm, pkt_t pkt)
packets from router
Definition: mm.c:473
jid_t from
packet addressing (not used for routing)
Definition: sm.h:140
packet summary data wrapper
Definition: sm.h:129
nad_t nad
nad of the entire packet
Definition: sm.h:146
mod_ret_t mm_pkt_router(mm_t mm, pkt_t pkt)
packets from the router
Definition: mm.c:628
session manager global context
Definition: sm.h:167
#define stanza_err_BAD_REQUEST
Definition: util.h:367
broadcast
Definition: sm.h:122
#define stanza_err_REMOTE_SERVER_NOT_FOUND
Definition: util.h:381
#define NAD_AVAL_L(N, A)
Definition: nad.h:190
void pkt_router(pkt_t pkt)
Definition: pkt.c:379
void pkt_free(pkt_t pkt)
Definition: pkt.c:315
#define log_debug(...)
Definition: log.h:65
#define NAD_AVAL(N, A)
Definition: nad.h:189
presence
Definition: sm.h:99
packet was unhandled, should be passed to the next module
Definition: sm.h:340
SM_API void user_free(user_t user)
Definition: user.c:80
packet was handled (and freed)
Definition: sm.h:339
jid_t to
Definition: sm.h:140
#define ZONE
Definition: mio_impl.h:76
int nad_find_attr(nad_t nad, int elem, int ns, const char *name, const char *val)
get a matching attr on this elem, both name and optional val
Definition: nad.c:235
unicast
Definition: sm.h:121
presence (probe)
Definition: sm.h:101
pkt_t pkt_create(sm_t sm, const char *elem, const char *type, const char *to, const char *from)
Definition: pkt.c:328
void dispatch(sm_t sm, pkt_t pkt)
main packet dispatcher
Definition: dispatch.c:31
mod_ret_t
module return values
Definition: sm.h:338
#define stanza_err_SERVICE_UNAVAILABLE
Definition: util.h:384
char * node
Definition: jid.h:44
data for a single user
Definition: sm.h:234
route_type_t rtype
type of enclosing route
Definition: sm.h:136