jabberd2  2.3.2
pkt.c
Go to the documentation of this file.
1 /*
2  * jabberd - Jabber Open Source Server
3  * Copyright (c) 2002 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 
30 pkt_t pkt_error(pkt_t pkt, int err) {
31  if(pkt == NULL) return NULL;
32 
33  /* if it's an error already, log, free, return */
34  if(pkt->type & pkt_ERROR) {
35  log_debug(ZONE, "dropping error pkt");
36  pkt_free(pkt);
37  return NULL;
38  }
39 
40  stanza_error(pkt->nad, 1, err);
41 
42  /* update vars and attrs */
43  pkt_tofrom(pkt);
44  pkt->type |= pkt_ERROR;
45 
46  /* supplant route destination in case there was none in original packet */
47  if(pkt->to == NULL && pkt->rto != NULL)
48  pkt->to = jid_dup(pkt->rto);
49 
50  /* all done, error'd and addressed */
51  log_debug(ZONE, "processed %d error pkt", err);
52 
53  return pkt;
54 }
55 
58  jid_t tmp;
59 
60  if(pkt == NULL) return NULL;
61 
62  /* swap vars */
63  tmp = pkt->from;
64  pkt->from = pkt->to;
65  pkt->to = tmp;
66  tmp = pkt->rfrom;
67  pkt->rfrom = pkt->rto;
68  pkt->rto = tmp;
69 
70  /* update attrs */
71  if(pkt->to != NULL)
72  nad_set_attr(pkt->nad, 1, -1, "to", jid_full(pkt->to), 0);
73  if(pkt->from != NULL)
74  nad_set_attr(pkt->nad, 1, -1, "from", jid_full(pkt->from), 0);
75  if(pkt->rto != NULL)
76  nad_set_attr(pkt->nad, 0, -1, "to", jid_full(pkt->rto), 0);
77  if(pkt->rfrom != NULL)
78  nad_set_attr(pkt->nad, 0, -1, "from", jid_full(pkt->rfrom), 0);
79 
80  return pkt;
81 }
82 
84 pkt_t pkt_dup(pkt_t pkt, const char *to, const char *from) {
85  pkt_t pnew;
86 
87  if(pkt == NULL) return NULL;
88 
89  pnew = (pkt_t) calloc(1, sizeof(struct pkt_st));
90 
91  pnew->sm = pkt->sm;
92  pnew->type = pkt->type;
93  pnew->nad = nad_copy(pkt->nad);
94 
95  /* set replacement attrs */
96  if(to != NULL) {
97  pnew->to = jid_new(to, -1);
98  nad_set_attr(pnew->nad, 1, -1, "to", jid_full(pnew->to), 0);
99  } else if(pkt->to != NULL)
100  pnew->to = jid_dup(pkt->to);
101 
102  if(from != NULL) {
103  pnew->from = jid_new(from, -1);
104  nad_set_attr(pnew->nad, 1, -1, "from", jid_full(pnew->from), 0);
105  } else if(pkt->from != NULL)
106  pnew->from = jid_dup(pkt->from);
107 
108  log_debug(ZONE, "duplicated packet");
109 
110  return pnew;
111 }
112 
114  pkt_t pkt;
115  int ns, attr, elem;
116  char pri[20];
117 
118  log_debug(ZONE, "creating new packet");
119 
120  /* find the route */
121  ns = nad_find_namespace(nad, 0, uri_COMPONENT, NULL);
122  if(ns < 0) {
123  log_debug(ZONE, "packet not in component namespace");
124  nad_free(nad);
125  return NULL;
126  }
127 
128  /* create the pkt holder */
129  pkt = (pkt_t) calloc(1, sizeof(struct pkt_st));
130 
131  pkt->sm = sm;
132  pkt->nad = nad;
133 
134  /* routes */
135  if(NAD_ENAME_L(nad, 0) == 5 && strncmp("route", NAD_ENAME(nad, 0), 5) == 0) {
136  /* route element */
137  if((attr = nad_find_attr(nad, 0, -1, "to", NULL)) >= 0)
138  pkt->rto = jid_new(NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr));
139  if((attr = nad_find_attr(nad, 0, -1, "from", NULL)) >= 0)
140  pkt->rfrom = jid_new(NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr));
141 
142  /* route type */
143  attr = nad_find_attr(nad, 0, -1, "type", NULL);
144  if(attr < 0)
145  pkt->rtype = route_UNICAST;
146  else if(NAD_AVAL_L(nad, attr) == 9 && strncmp("broadcast", NAD_AVAL(nad, attr), 9) == 0)
147  pkt->rtype = route_BROADCAST;
148 
149  /* route errors */
150  if(nad_find_attr(nad, 0, -1, "error", NULL) >= 0)
151  pkt->rtype |= route_ERROR;
152 
153  /* client packets */
154  ns = nad_find_namespace(nad, 1, uri_CLIENT, NULL);
155  if(ns >= 0) {
156 
157  /* get initial addresses */
158  if((attr = nad_find_attr(pkt->nad, 1, -1, "to", NULL)) >= 0 && NAD_AVAL_L(pkt->nad, attr) > 0)
159  pkt->to = jid_new(NAD_AVAL(pkt->nad, attr), NAD_AVAL_L(pkt->nad, attr));
160  if((attr = nad_find_attr(pkt->nad, 1, -1, "from", NULL)) >= 0 && NAD_AVAL_L(pkt->nad, attr) > 0)
161  pkt->from = jid_new(NAD_AVAL(pkt->nad, attr), NAD_AVAL_L(pkt->nad, attr));
162 
163  /* find type, if any */
164  attr = nad_find_attr(pkt->nad, 1, -1, "type", NULL);
165 
166  /* messages are simple, only subtypes */
167  if(NAD_ENAME_L(pkt->nad, 1) == 7 && strncmp("message", NAD_ENAME(pkt->nad, 1), 7) == 0) {
168  pkt->type = pkt_MESSAGE;
169  if(attr >= 0) {
170  if(NAD_AVAL_L(pkt->nad, attr) == 4 && strncmp("chat", NAD_AVAL(pkt->nad, attr), 4) == 0)
171  pkt->type = pkt_MESSAGE_CHAT;
172  else if(NAD_AVAL_L(pkt->nad, attr) == 8 && strncmp("headline", NAD_AVAL(pkt->nad, attr), 8) == 0)
173  pkt->type = pkt_MESSAGE_HEADLINE;
174  else if(NAD_AVAL_L(pkt->nad, attr) == 9 && strncmp("groupchat", NAD_AVAL(pkt->nad, attr), 9) == 0)
176  else if(NAD_AVAL_L(pkt->nad, attr) == 5 && strncmp("error", NAD_AVAL(pkt->nad, attr), 5) == 0)
177  pkt->type = pkt_MESSAGE | pkt_ERROR;
178  }
179 
180  return pkt;
181  }
182 
183  /* presence is a mixed bag, s10ns in here too */
184  if(NAD_ENAME_L(pkt->nad, 1) == 8 && strncmp("presence", NAD_ENAME(pkt->nad, 1), 8) == 0) {
185  pkt->type = pkt_PRESENCE;
186  if(attr >= 0) {
187  if(NAD_AVAL_L(pkt->nad, attr) == 11 && strncmp("unavailable", NAD_AVAL(pkt->nad, attr), 11) == 0)
188  pkt->type = pkt_PRESENCE_UN;
189  else if(NAD_AVAL_L(pkt->nad, attr) == 5 && strncmp("probe", NAD_AVAL(pkt->nad, attr), 5) == 0)
190  pkt->type = pkt_PRESENCE_PROBE;
191  else if(NAD_AVAL_L(pkt->nad, attr) == 9 && strncmp("subscribe", NAD_AVAL(pkt->nad, attr), 9) == 0)
192  pkt->type = pkt_S10N;
193  else if(NAD_AVAL_L(pkt->nad, attr) == 10 && strncmp("subscribed", NAD_AVAL(pkt->nad, attr), 10) == 0)
194  pkt->type = pkt_S10N_ED;
195  else if(NAD_AVAL_L(pkt->nad, attr) == 11 && strncmp("unsubscribe", NAD_AVAL(pkt->nad, attr), 11) == 0)
196  pkt->type = pkt_S10N_UN;
197  else if(NAD_AVAL_L(pkt->nad, attr) == 12 && strncmp("unsubscribed", NAD_AVAL(pkt->nad, attr), 12) == 0)
198  pkt->type = pkt_S10N_UNED;
199  else if(NAD_AVAL_L(pkt->nad, attr) == 5 && strncmp("error", NAD_AVAL(pkt->nad, attr), 5) == 0)
200  pkt->type = pkt_PRESENCE | pkt_ERROR;
201  }
202 
203  /* priority */
204  if((elem = nad_find_elem(pkt->nad, 1, NAD_ENS(pkt->nad, 1), "priority", 1)) < 0)
205  return pkt;
206 
207  if(NAD_CDATA_L(pkt->nad, elem) <= 0 || NAD_CDATA_L(pkt->nad, elem) > 19)
208  return pkt;
209 
210  memcpy(pri, NAD_CDATA(pkt->nad, elem), NAD_CDATA_L(pkt->nad, elem));
211  pri[NAD_CDATA_L(pkt->nad, elem)] = '\0';
212  pkt->pri = atoi(pri);
213 
214  if(pkt->pri > 127) pkt->pri = 127;
215  if(pkt->pri < -128) pkt->pri = -128;
216 
217  return pkt;
218  }
219 
220  /* iq's are pretty easy, but also set xmlns */
221  if(NAD_ENAME_L(pkt->nad, 1) == 2 && strncmp("iq", NAD_ENAME(pkt->nad, 1), 2) == 0) {
222  pkt->type = pkt_IQ;
223  if (attr < 0) {
224  log_write(sm->log, LOG_ERR, "dropping iq without type");
225  log_debug(ZONE, "dropping iq without type");
226  pkt_free(pkt);
227  return NULL;
228  }
229  if (NAD_AVAL_L(pkt->nad, attr) == 6 && strncmp("result", NAD_AVAL(pkt->nad, attr), 6) == 0) pkt->type = pkt_IQ_RESULT;
230  else if (NAD_AVAL_L(pkt->nad, attr) == 5 && strncmp("error", NAD_AVAL(pkt->nad, attr), 5) == 0) pkt->type = pkt_IQ | pkt_ERROR;
231  else if (NAD_AVAL_L(pkt->nad, attr) == 3 && strncmp("set", NAD_AVAL(pkt->nad, attr), 3) == 0) pkt->type = pkt_IQ_SET;
232  else if (NAD_AVAL_L(pkt->nad, attr) != 3 || strncmp("get", NAD_AVAL(pkt->nad, attr), 3)) {
233  log_write(sm->log, LOG_ERR, "dropping iq with bad type \"%.*s\"", NAD_AVAL_L(pkt->nad, attr), NAD_AVAL(pkt->nad, attr));
234  log_debug(ZONE, "dropping iq with bad type \"%.*s\"", NAD_AVAL_L(pkt->nad, attr), NAD_AVAL(pkt->nad, attr));
235  pkt_free(pkt);
236  return NULL;
237  }
238 
239  if(pkt->nad->ecur > 2 && (ns = NAD_ENS(pkt->nad, 2)) >= 0)
240  pkt->ns = (int) (long) xhash_getx(pkt->sm->xmlns, NAD_NURI(pkt->nad, ns), NAD_NURI_L(pkt->nad, ns));
241 
242  return pkt;
243  }
244 
245  log_debug(ZONE, "unknown client namespace packet");
246 
247  return pkt;
248  }
249 
250  /* sessions packets */
251  ns = nad_find_namespace(nad, 1, uri_SESSION, NULL);
252  if(ns >= 0) {
253 
254  /* sessions */
255  if(NAD_ENAME_L(pkt->nad, 1) == 7 && strncmp("session", NAD_ENAME(pkt->nad, 1), 7) == 0) {
256 
257  /* find action */
258  attr = nad_find_attr(pkt->nad, 1, -1, "action", NULL);
259 
260  if(attr >= 0) {
261  if(NAD_AVAL_L(pkt->nad, attr) == 5 && strncmp("start", NAD_AVAL(pkt->nad, attr), 5) >= 0)
262  pkt->type = pkt_SESS;
263  else if(NAD_AVAL_L(pkt->nad, attr) == 3 && strncmp("end", NAD_AVAL(pkt->nad, attr), 3) >= 0)
264  pkt->type = pkt_SESS_END;
265  else if(NAD_AVAL_L(pkt->nad, attr) == 6 && strncmp("create", NAD_AVAL(pkt->nad, attr), 6) >= 0)
266  pkt->type = pkt_SESS_CREATE;
267  else if(NAD_AVAL_L(pkt->nad, attr) == 6 && strncmp("delete", NAD_AVAL(pkt->nad, attr), 6) >= 0)
268  pkt->type = pkt_SESS_DELETE;
269  else if(NAD_AVAL_L(pkt->nad, attr) == 7 && strncmp("started", NAD_AVAL(pkt->nad, attr), 7) >= 0)
270  pkt->type = pkt_SESS | pkt_SESS_FAILED;
271  else if(NAD_AVAL_L(pkt->nad, attr) == 5 && strncmp("ended", NAD_AVAL(pkt->nad, attr), 5) >= 0)
273  else if(NAD_AVAL_L(pkt->nad, attr) == 7 && strncmp("created", NAD_AVAL(pkt->nad, attr), 7) >= 0)
275  else if(NAD_AVAL_L(pkt->nad, attr) == 7 && strncmp("deleted", NAD_AVAL(pkt->nad, attr), 7) >= 0)
277 
278  return pkt;
279  } else {
280  log_debug(ZONE, "missing action on session packet");
281  return pkt;
282  }
283  }
284 
285  log_debug(ZONE, "unknown session namespace packet");
286 
287  return pkt;
288  }
289 
290  log_debug(ZONE, "unknown packet");
291 
292  return pkt;
293  }
294 
295  /* advertisements */
296  if(NAD_ENAME_L(nad, 0) == 8 && strncmp("presence", NAD_ENAME(nad, 0), 8) == 0) {
297  if(nad_find_attr(nad, 0, -1, "type", "unavailable") >= 0)
298  pkt->rtype = route_ADV_UN;
299  else
300  pkt->rtype = route_ADV;
301 
302  attr = nad_find_attr(nad, 0, -1, "from", NULL);
303  if(attr >= 0)
304  pkt->from = jid_new(NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr));
305 
306  return pkt;
307  }
308 
309  log_debug(ZONE, "invalid component packet");
310 
311  pkt_free(pkt);
312  return NULL;
313 }
314 
315 void pkt_free(pkt_t pkt) {
316  log_debug(ZONE, "freeing pkt");
317 
318  if (pkt != NULL) {
319  if(pkt->rto != NULL) jid_free(pkt->rto);
320  if(pkt->rfrom != NULL) jid_free(pkt->rfrom);
321  if(pkt->to != NULL) jid_free(pkt->to);
322  if(pkt->from != NULL) jid_free(pkt->from);
323  if(pkt->nad != NULL) nad_free(pkt->nad);
324  free(pkt);
325  }
326 }
327 
328 pkt_t pkt_create(sm_t sm, const char *elem, const char *type, const char *to, const char *from) {
329  nad_t nad;
330  int ns;
331 
332  nad = nad_new();
333 
334  ns = nad_add_namespace(nad, uri_COMPONENT, NULL);
335  nad_append_elem(nad, ns, "route", 0);
336 
337  nad_add_namespace(nad, uri_SESSION, "sm");
338 
339  ns = nad_add_namespace(nad, uri_CLIENT, NULL);
340  nad_append_elem(nad, ns, elem, 1);
341 
342  if(type != NULL)
343  nad_append_attr(nad, -1, "type", type);
344  if(to != NULL)
345  nad_append_attr(nad, -1, "to", to);
346  if(from != NULL)
347  nad_append_attr(nad, -1, "from", from);
348 
349  return pkt_new(sm, nad);
350 }
351 
353 void pkt_id(pkt_t src, pkt_t dest) {
354  int attr;
355 
356  attr = nad_find_attr(src->nad, 1, -1, "id", NULL);
357  if(attr >= 0)
358  nad_set_attr(dest->nad, 1, -1, "id", NAD_AVAL(src->nad, attr), NAD_AVAL_L(src->nad, attr));
359  else
360  nad_set_attr(dest->nad, 1, -1, "id", NULL, 0);
361 }
362 
364 void pkt_id_new(pkt_t pkt) {
365  char id[40];
366  int i, r;
367 
368  /* as we are not using ids for tracking purposes, these can be generated randomly */
369  for(i = 0; i < 40; i++) {
370  r = (int) (36.0 * rand() / RAND_MAX);
371  id[i] = (r >= 0 && r <= 9) ? (r + 48) : (r + 87);
372  }
373 
374  nad_set_attr(pkt->nad, 1, -1, "id", id, 40);
375 
376  return;
377 }
378 
379 void pkt_router(pkt_t pkt) {
380  mod_ret_t ret;
381  int ns, scan;
382 
383  if(pkt == NULL) return;
384 
385  log_debug(ZONE, "delivering pkt to router");
386 
387  if(pkt->to == NULL) {
388  log_debug(ZONE, "no to address on packet, unable to route");
389  pkt_free(pkt);
390  return;
391  }
392 
393  if(pkt->rto != NULL)
394  jid_free(pkt->rto);
395  pkt->rto = jid_new(pkt->to->domain, -1);
396 
397  if(pkt->rto == NULL) {
398  log_debug(ZONE, "invalid to address on packet, unable to route");
399  pkt_free(pkt);
400  return;
401  }
402 
403  nad_set_attr(pkt->nad, 0, -1, "to", pkt->rto->domain, 0);
404 
405  if(pkt->rfrom != NULL)
406  jid_free(pkt->rfrom);
407  pkt->rfrom = jid_new(pkt->sm->id, -1);
408 
409  if(pkt->rfrom == NULL) {
410  log_debug(ZONE, "invalid from address on packet, unable to route");
411  pkt_free(pkt);
412  return;
413  }
414 
415  nad_set_attr(pkt->nad, 0, -1, "from", pkt->rfrom->domain, 0);
416 
417  ret = mm_out_router(pkt->sm->mm, pkt);
418  switch(ret) {
419  case mod_HANDLED:
420  return;
421 
422  case mod_PASS:
423 
424  /* remove sm specifics */
425  ns = nad_find_namespace(pkt->nad, 1, uri_SESSION, NULL);
426  /* remove them if there is no session elements in packet */
427  if(ns >= 0 && nad_find_elem(pkt->nad, 0, ns, NULL, 1) < 0) {
428  nad_set_attr(pkt->nad, 1, ns, "c2s", NULL, 0);
429  nad_set_attr(pkt->nad, 1, ns, "sm", NULL, 0);
430 
431  /* forget about the internal namespace too */
432  if(pkt->nad->elems[1].ns == ns)
433  pkt->nad->elems[1].ns = pkt->nad->nss[ns].next;
434 
435  else {
436  for(scan = pkt->nad->elems[1].ns; pkt->nad->nss[scan].next != -1 && pkt->nad->nss[scan].next != ns; scan = pkt->nad->nss[scan].next);
437 
438  /* got it */
439  if(pkt->nad->nss[scan].next != -1)
440  pkt->nad->nss[scan].next = pkt->nad->nss[ns].next;
441  }
442  }
443 
444  sx_nad_write(pkt->sm->router, pkt->nad);
445 
446  /* nad already free'd, free the rest */
447  pkt->nad = NULL;
448  pkt_free(pkt);
449 
450  break;
451 
452  default:
453  pkt_router(pkt_error(pkt, -ret));
454 
455  break;
456  }
457 }
458 
459 void pkt_sess(pkt_t pkt, sess_t sess) {
460  mod_ret_t ret;
461 
462  if(pkt == NULL) return;
463 
464  log_debug(ZONE, "delivering pkt to session %s", jid_full(sess->jid));
465 
466  if(pkt->rto != NULL)
467  jid_free(pkt->rto);
468  pkt->rto = jid_new(sess->c2s, -1);
469 
470  if(pkt->rto == NULL) {
471  log_debug(ZONE, "invalid to address on packet, unable to route");
472  pkt_free(pkt);
473  return;
474  }
475 
476  nad_set_attr(pkt->nad, 0, -1, "to", pkt->rto->domain, 0);
477 
478  if(pkt->rfrom != NULL)
479  jid_free(pkt->rfrom);
480  pkt->rfrom = jid_new(pkt->sm->id, -1);
481 
482  if(pkt->rfrom == NULL) {
483  log_debug(ZONE, "invalid from address on packet, unable to route");
484  pkt_free(pkt);
485  return;
486  }
487 
488  nad_set_attr(pkt->nad, 0, -1, "from", pkt->rfrom->domain, 0);
489 
490  ret = mm_out_sess(pkt->sm->mm, sess, pkt);
491  switch(ret) {
492  case mod_HANDLED:
493  return;
494 
495  case mod_PASS:
496  sess_route(sess, pkt);
497 
498  break;
499 
500  default:
501  pkt_router(pkt_error(pkt, -ret));
502 
503  break;
504  }
505 }
506 
508 void pkt_delay(pkt_t pkt, time_t t, const char *from) {
509  char timestamp[21];
510  int ns, elem;
511 
512 #ifdef ENABLE_SUPERSEDED
513  datetime_out(t, dt_LEGACY, timestamp, 18);
514  ns = nad_add_namespace(pkt->nad, uri_DELAY, NULL);
515  elem = nad_insert_elem(pkt->nad, 1, ns, "x", NULL);
516  nad_set_attr(pkt->nad, elem, -1, "stamp", timestamp, 0);
517  if(from != NULL)
518  nad_set_attr(pkt->nad, elem, -1, "from", from, 0);
519  log_debug(ZONE, "added pkt XEP-0091 delay stamp %s", timestamp);
520 #endif
521  datetime_out(t, dt_DATETIME, timestamp, 21);
522  ns = nad_add_namespace(pkt->nad, uri_URN_DELAY, NULL);
523  elem = nad_insert_elem(pkt->nad, 1, ns, "delay", NULL);
524  nad_set_attr(pkt->nad, elem, -1, "stamp", timestamp, 0);
525  if(from != NULL)
526  nad_set_attr(pkt->nad, elem, -1, "from", from, 0);
527  log_debug(ZONE, "added pkt XEP-0203 delay stamp %s", timestamp);
528 }
pkt_t pkt_error(pkt_t pkt, int err)
Definition: pkt.c:30
pkt_type_t type
packet type
Definition: sm.h:138
jid_t jid
session jid (user@host/res)
Definition: sm.h:257
struct nad_elem_st * elems
Definition: nad.h:95
static sm_t sm
Definition: main.c:33
Definition: nad.h:93
nad_t nad_new(void)
create a new nad
Definition: nad.c:125
int nad_append_attr(nad_t nad, int ns, const char *name, const char *val)
attach new attr to the last elem
Definition: nad.c:701
data structures and prototypes for the session manager
session end request
Definition: sm.h:110
int nad_insert_elem(nad_t nad, int parent, int ns, const char *name, const char *cdata)
shove in a new child elem after the given one
Definition: nad.c:405
subscribe request
Definition: sm.h:102
packet error
Definition: sm.h:115
#define NAD_CDATA_L(N, E)
Definition: nad.h:186
const char * id
component id
Definition: sm.h:168
#define sx_nad_write(s, nad)
Definition: sx.h:166
session start request
Definition: sm.h:109
int pri
presence priority
Definition: sm.h:144
const char * jid_full(jid_t jid)
expand and return the full
Definition: jid.c:347
jid_t rfrom
addressing of enclosing route
Definition: sm.h:134
jid_t jid_new(const char *id, int len)
make a new jid
Definition: jid.c:81
pkt_t pkt_tofrom(pkt_t pkt)
swap a packet's to and from attributes
Definition: pkt.c:57
log_t log
log context
Definition: sm.h:199
int nad_find_elem(nad_t nad, int elem, int ns, const char *name, int depth)
locate the next elem at a given depth with an optional matching name
Definition: nad.c:204
void * xhash_getx(xht h, const char *key, int len)
Definition: xhash.c:170
void log_write(log_t log, int level, const char *msgfmt,...)
Definition: log.c:104
message (groupchat)
Definition: sm.h:98
mm_t mm
module subsystem
Definition: sm.h:212
mod_ret_t mm_out_sess(mm_t mm, sess_t sess, pkt_t pkt)
packets to active session
Definition: mm.c:505
route error
Definition: sm.h:125
info/query (set)
Definition: sm.h:107
jid_t rto
Definition: sm.h:134
int nad_add_namespace(nad_t nad, const char *uri, const char *prefix)
bring a new namespace into scope
Definition: nad.c:734
pkt_t pkt_dup(pkt_t pkt, const char *to, const char *from)
duplicate pkt, replacing addresses
Definition: pkt.c:84
info/query (result)
Definition: sm.h:108
#define NAD_ENAME(N, E)
Definition: nad.h:183
sm_t sm
sm context
Definition: sm.h:130
void pkt_id_new(pkt_t pkt)
create an id value for new iq packets
Definition: pkt.c:364
int nad_append_elem(nad_t nad, int ns, const char *name, int depth)
create a new elem on the list
Definition: nad.c:667
void nad_free(nad_t nad)
free that nad
Definition: nad.c:178
nad_t nad_copy(nad_t nad)
copy a nad
Definition: nad.c:145
void nad_set_attr(nad_t nad, int elem, int ns, const char *name, const char *val, int vallen)
create, update, or zap any matching attr on this elem
Definition: nad.c:375
presence (unavailable)
Definition: sm.h:100
pkt_t pkt_new(sm_t sm, nad_t nad)
Definition: pkt.c:113
jid_t from
packet addressing (not used for routing)
Definition: sm.h:140
sx_t router
SX of router connection.
Definition: sm.h:185
packet summary data wrapper
Definition: sm.h:129
struct nad_ns_st * nss
Definition: nad.h:97
#define NAD_ENAME_L(N, E)
Definition: nad.h:184
#define NAD_NURI_L(N, NS)
Definition: nad.h:192
nad_t nad
nad of the entire packet
Definition: sm.h:146
session manager global context
Definition: sm.h:167
void jid_free(jid_t jid)
free a jid
Definition: jid.c:286
advertisement (available)
Definition: sm.h:123
void datetime_out(time_t t, datetime_t type, char *date, int datelen)
Definition: datetime.c:114
message (chat)
Definition: sm.h:96
session delete request
Definition: sm.h:112
char * domain
Definition: jid.h:45
Definition: jid.h:42
broadcast
Definition: sm.h:122
int ecur
Definition: nad.h:105
struct pkt_st * pkt_t
packet summary data wrapper
mod_ret_t mm_out_router(mm_t mm, pkt_t pkt)
packets to router
Definition: mm.c:536
#define NAD_AVAL_L(N, A)
Definition: nad.h:190
void pkt_id(pkt_t src, pkt_t dest)
convenience - copy the packet id from src to dest
Definition: pkt.c:353
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
info/query (get)
Definition: sm.h:106
nad_t stanza_error(nad_t nad, int elem, int err)
error the packet
Definition: stanza.c:52
#define uri_CLIENT
Definition: uri.h:35
#define NAD_AVAL(N, A)
Definition: nad.h:189
int ns
Definition: nad.h:75
presence
Definition: sm.h:99
packet was unhandled, should be passed to the next module
Definition: sm.h:339
int ns
iq sub-namespace
Definition: sm.h:142
packet was handled (and freed)
Definition: sm.h:338
There is one instance of this struct per user who is logged in to this c2s instance.
Definition: c2s.h:74
unsubscribe request
Definition: sm.h:104
subscribed response
Definition: sm.h:103
#define uri_DELAY
Definition: uri.h:64
message
Definition: sm.h:95
jid_t to
Definition: sm.h:140
int nad_find_namespace(nad_t nad, int elem, const char *uri, const char *prefix)
get a matching ns on this elem, both uri and optional prefix
Definition: nad.c:262
void pkt_delay(pkt_t pkt, time_t t, const char *from)
add an x:delay stamp
Definition: pkt.c:508
#define NAD_CDATA(N, E)
Definition: nad.h:185
jid_t jid_dup(jid_t jid)
duplicate a jid
Definition: jid.c:373
#define uri_COMPONENT
Definition: uri.h:51
#define ZONE
Definition: mio_impl.h:76
advertisement (unavailable)
Definition: sm.h:124
message (headline)
Definition: sm.h:97
#define NAD_NURI(N, NS)
Definition: nad.h:191
xht xmlns
index of namespaces (for iq sub-namespace in pkt_t)
Definition: sm.h:192
int next
Definition: nad.h:90
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
c2s_t c2s
Definition: c2s.h:75
presence (probe)
Definition: sm.h:101
session create request
Definition: sm.h:111
#define uri_SESSION
Definition: uri.h:52
pkt_t pkt_create(sm_t sm, const char *elem, const char *type, const char *to, const char *from)
Definition: pkt.c:328
void sess_route(sess_t sess, pkt_t pkt)
send a packet to the client for this session
Definition: sess.c:31
mod_ret_t
module return values
Definition: sm.h:337
void pkt_sess(pkt_t pkt, sess_t sess)
Definition: pkt.c:459
#define uri_URN_DELAY
Definition: uri.h:65
#define NAD_ENS(N, E)
Definition: nad.h:196
unsubscribed response
Definition: sm.h:105
session request failed (mask)
Definition: sm.h:113
route_type_t rtype
type of enclosing route
Definition: sm.h:136