jabberd2  2.3.6
in.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 "s2s.h"
22 
23 /*
24  * we handle incoming connections, and the packets that arrive on them.
25  *
26  * action points:
27  *
28  * event_STREAM - new incoming connection
29  * - create new dbconn (key stream id)
30  * - DONE
31  *
32  * event_PACKET: <result from='them' to='us'>key</result> - auth request
33  * - get dbconn for this sx
34  * - if dbconn state is valid
35  * - send result: <result to='them' from='us' type='valid'/>
36  * - DONE
37  * - out_packet(s2s, <verify to='them' from='us' id='stream id'>key</verify>)
38  * - DONE
39  *
40  * event_PACKET: <verify from='them' to='us' id='123'>key</verify> - validate their key
41  * - generate dbkey: sha1(secret+remote+id)
42  * - if their key matches dbkey
43  * - send them: <verify to='them' from='us' id='123' type='valid'/>
44  * - else
45  * - send them: <verify to='them' from='us' id='123' type='invalid'/>
46  * - DONE
47  *
48  * event_PACKET - they're trying to send us something
49  * - get dbconn for this sx
50  * - if dbconn state is invalid
51  * - drop packet
52  * - DONE
53  * - write packet to router
54  * - DONE
55  */
56 
57 /* forward decls */
58 static int _in_sx_callback(sx_t s, sx_event_t e, void *data, void *arg);
59 static void _in_result(conn_t in, nad_t nad);
60 static void _in_verify(conn_t in, nad_t nad);
61 static void _in_packet(conn_t in, nad_t nad);
62 
63 int in_mio_callback(mio_t m, mio_action_t a, mio_fd_t fd, void *data, void *arg) {
64  conn_t in = (conn_t) arg;
65  s2s_t s2s = (s2s_t) arg;
66  struct sockaddr_storage sa;
67  socklen_t namelen = sizeof(sa);
68  int port, nbytes, flags = 0;
69  char ipport[INET6_ADDRSTRLEN + 17];
70 
71  switch(a) {
72  case action_READ:
73  log_debug(ZONE, "read action on fd %d", fd->fd);
74 
75  ioctl(fd->fd, FIONREAD, &nbytes);
76  if(nbytes == 0) {
77  sx_kill(in->s);
78  return 0;
79  }
80 
81  return sx_can_read(in->s);
82 
83  case action_WRITE:
84  log_debug(ZONE, "write action on fd %d", fd->fd);
85  return sx_can_write(in->s);
86 
87  case action_CLOSE:
88  log_debug(ZONE, "close action on fd %d", fd->fd);
89 
90  if (fd == s2s->server_fd) break;
91 
92  /* !!! logging */
93  log_write(in->s2s->log, LOG_NOTICE, "[%d] [%s, port=%d] disconnect, packets: %i", fd->fd, in->ip, in->port, in->packet_count);
94 
95  jqueue_push(in->s2s->dead, (void *) in->s, 0);
96 
97  /* remove from open streams hash if online, or open connections if not */
98  if (in->online)
99  xhash_zap(in->s2s->in, in->key);
100  else {
101  snprintf(ipport, INET6_ADDRSTRLEN + 16, "%s/%d", in->ip, in->port);
102  xhash_zap(in->s2s->in_accept, ipport);
103  }
104 
105  jqueue_push(in->s2s->dead_conn, (void *) in, 0);
106 
107  break;
108 
109  case action_ACCEPT:
110  s2s = (s2s_t) arg;
111 
112  log_debug(ZONE, "accept action on fd %d", fd->fd);
113 
114  getpeername(fd->fd, (struct sockaddr *) &sa, &namelen);
115  port = j_inet_getport(&sa);
116 
117  log_write(s2s->log, LOG_NOTICE, "[%d] [%s, port=%d] incoming connection", fd->fd, (char *) data, port);
118 
119  /* new conn */
120  in = (conn_t) calloc(1, sizeof(struct conn_st));
121 
122  in->s2s = s2s;
123 
124  strncpy(in->ip, (char *) data, INET6_ADDRSTRLEN);
125  in->port = port;
126 
127  in->states = xhash_new(101);
128  in->states_time = xhash_new(101);
129 
130  in->fd = fd;
131 
132  in->init_time = time(NULL);
133 
134  in->s = sx_new(s2s->sx_env, in->fd->fd, _in_sx_callback, (void *) in);
135  mio_app(m, in->fd, in_mio_callback, (void *) in);
136 
137  if(s2s->stanza_size_limit != 0)
138  in->s->rbytesmax = s2s->stanza_size_limit;
139 
140  /* add to incoming connections hash */
141  snprintf(ipport, INET6_ADDRSTRLEN + 16, "%s/%d", in->ip, in->port);
142  xhash_put(s2s->in_accept, pstrdup(xhash_pool(s2s->in_accept),ipport), (void *) in);
143 
144  flags = S2S_DB_HEADER;
145 #ifdef HAVE_SSL
146  if(s2s->sx_ssl != NULL)
147  flags |= SX_SSL_STARTTLS_OFFER;
148 #endif
149 #ifdef HAVE_LIBZ
150  if(s2s->compression)
151  flags |= SX_COMPRESS_OFFER;
152 #endif
153  sx_server_init(in->s, flags);
154  break;
155  }
156 
157  return 0;
158 }
159 
160 static int _in_sx_callback(sx_t s, sx_event_t e, void *data, void *arg) {
161  conn_t in = (conn_t) arg;
162  sx_buf_t buf = (sx_buf_t) data;
163  int len;
164  sx_error_t *sxe;
165  nad_t nad;
166  char ipport[INET6_ADDRSTRLEN + 17];
167  jid_t from;
168  int attr;
169 
170  switch(e) {
171  case event_WANT_READ:
172  log_debug(ZONE, "want read");
173  mio_read(in->s2s->mio, in->fd);
174  break;
175 
176  case event_WANT_WRITE:
177  log_debug(ZONE, "want write");
178  mio_write(in->s2s->mio, in->fd);
179  break;
180 
181  case event_READ:
182  log_debug(ZONE, "reading from %d", in->fd->fd);
183 
184  /* do the read */
185  len = recv(in->fd->fd, buf->data, buf->len, 0);
186 
187  if(len < 0) {
188  if(MIO_WOULDBLOCK) {
189  buf->len = 0;
190  return 0;
191  }
192 
193  log_write(in->s2s->log, LOG_NOTICE, "[%d] [%s, port=%d] read error: %s (%d)", in->fd->fd, in->ip, in->port, MIO_STRERROR(MIO_ERROR), MIO_ERROR);
194 
195  sx_kill(s);
196 
197  return -1;
198  }
199 
200  else if(len == 0) {
201  /* they went away */
202  sx_kill(s);
203 
204  return -1;
205  }
206 
207  log_debug(ZONE, "read %d bytes", len);
208 
209  buf->len = len;
210 
211  return len;
212 
213  case event_WRITE:
214  log_debug(ZONE, "writing to %d", in->fd->fd);
215 
216  len = send(in->fd->fd, buf->data, buf->len, 0);
217  if(len >= 0) {
218  log_debug(ZONE, "%d bytes written", len);
219  return len;
220  }
221 
222  if(MIO_WOULDBLOCK)
223  return 0;
224 
225  log_write(in->s2s->log, LOG_NOTICE, "[%d] [%s, port=%d] write error: %s (%d)", in->fd->fd, in->ip, in->port, MIO_STRERROR(MIO_ERROR), MIO_ERROR);
226 
227  sx_kill(s);
228 
229  return -1;
230 
231  case event_ERROR:
232  sxe = (sx_error_t *) data;
233  log_write(in->s2s->log, LOG_NOTICE, "[%d] [%s, port=%d] error: %s (%s)", in->fd->fd, in->ip, in->port, sxe->generic, sxe->specific);
234 
235  break;
236 
237  case event_STREAM:
238  case event_OPEN:
239 
240  log_debug(ZONE, "STREAM or OPEN event from %s port %d (id %s)", in->ip, in->port, s->id);
241 
242  /* first time, bring them online */
243  if ((!in->online)||(strcmp(in->key,s->id)!=0)) {
244  log_write(in->s2s->log, LOG_NOTICE, "[%d] [%s, port=%d] incoming stream online (id %s)", in->fd->fd, in->ip, in->port, s->id);
245 
246  in->online = 1;
247 
248  /* record the id */
249  if (in->key != NULL) {
250  log_debug(ZONE,"adding new SSL stream id %s for stream id %s", s->id, in->key);
251 
252  /* remove the initial (non-SSL) stream id from the in connections hash */
253  xhash_zap(in->s2s->in, in->key);
254  free((void*)in->key);
255  }
256 
257  in->key = strdup(s->id);
258 
259  /* track it - add to open streams hash and remove from new connections hash */
260  xhash_put(in->s2s->in, in->key, (void *) in);
261 
262  snprintf(ipport, INET6_ADDRSTRLEN + 16, "%s/%d", in->ip, in->port);
263  xhash_zap(in->s2s->in_accept, ipport);
264  }
265 
266  break;
267 
268  case event_PACKET:
269  /* we're counting packets */
270  in->packet_count++;
271  in->s2s->packet_count++;
272 
273  nad = (nad_t) data;
274 
275  /* update last packet timestamp */
276  in->last_packet = time(NULL);
277 
278  /* dialback packets */
279  if(NAD_NURI_L(nad, NAD_ENS(nad, 0)) == strlen(uri_DIALBACK) && strncmp(uri_DIALBACK, NAD_NURI(nad, NAD_ENS(nad, 0)), strlen(uri_DIALBACK)) == 0 &&
280  (in->s2s->require_tls == 0 || s->ssf > 0)) {
281  /* only result and verify mean anything */
282  if(NAD_ENAME_L(nad, 0) == 6) {
283  if(strncmp("result", NAD_ENAME(nad, 0), 6) == 0) {
284  _in_result(in, nad);
285  return 0;
286  }
287 
288  if(strncmp("verify", NAD_ENAME(nad, 0), 6) == 0) {
289  _in_verify(in, nad);
290  return 0;
291  }
292  }
293 
294  log_debug(ZONE, "unknown dialback packet, dropping it");
295 
296  nad_free(nad);
297  return 0;
298  }
299 
300  /*
301  * not dialback, so it has to be a normal-ish jabber packet:
302  * - jabber:client or jabber:server
303  * - message, presence or iq
304  * - has to and from attributes
305  */
306 
307  if(!(
308  /* must be jabber:client or jabber:server */
309  NAD_ENS(nad, 0) >= 0 &&
310  ((NAD_NURI_L(nad, NAD_ENS(nad, 0)) == strlen(uri_CLIENT) && strncmp(uri_CLIENT, NAD_NURI(nad, NAD_ENS(nad, 0)), strlen(uri_CLIENT)) == 0) ||
311  (NAD_NURI_L(nad, NAD_ENS(nad, 0)) == strlen(uri_SERVER) && strncmp(uri_SERVER, NAD_NURI(nad, NAD_ENS(nad, 0)), strlen(uri_SERVER)) == 0)) && (
312  /* can be message */
313  (NAD_ENAME_L(nad, 0) == 7 && strncmp("message", NAD_ENAME(nad, 0), 7) == 0) ||
314  /* or presence */
315  (NAD_ENAME_L(nad, 0) == 8 && strncmp("presence", NAD_ENAME(nad, 0), 8) == 0) ||
316  /* or iq */
317  (NAD_ENAME_L(nad, 0) == 2 && strncmp("iq", NAD_ENAME(nad, 0), 2) == 0)
318  ) &&
319  /* to and from required */
320  nad_find_attr(nad, 0, -1, "to", NULL) >= 0 && nad_find_attr(nad, 0, -1, "from", NULL) >= 0
321  )) {
322  log_debug(ZONE, "they sent us a non-jabber looking packet, dropping it");
323  nad_free(nad);
324  return 0;
325  }
326 
327  /* perform check against whitelist */
328  attr = nad_find_attr(nad, 0, -1, "from", NULL);
329  if(attr < 0 || (from = jid_new(NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr))) == NULL) {
330  log_debug(ZONE, "missing or invalid from on incoming packet, attr is %d", attr);
331  nad_free(nad);
332  return 0;
333  }
334 
335  if (in->s2s->enable_whitelist > 0 && (s2s_domain_in_whitelist(in->s2s, from->domain) == 0)) {
336  log_write(in->s2s->log, LOG_NOTICE, "received a packet not from a whitelisted domain %s, dropping it", from->domain);
337  jid_free(from);
338  nad_free(nad);
339  return 0;
340  }
341 
342  jid_free(from);
343 
344  _in_packet(in, nad);
345  return 0;
346 
347  case event_CLOSED:
348  if (in->fd != NULL) {
349  mio_close(in->s2s->mio, in->fd);
350  in->fd = NULL;
351  }
352  return -1;
353  }
354 
355  return 0;
356 }
357 
359 static void _in_result(conn_t in, nad_t nad) {
360  int attr, ns;
361  jid_t from, to;
362  char *rkey;
363  nad_t verify;
364  pkt_t pkt;
365  time_t now;
366 
367  attr = nad_find_attr(nad, 0, -1, "from", NULL);
368  if(attr < 0 || (from = jid_new(NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr))) == NULL) {
369  log_debug(ZONE, "missing or invalid from on db result packet");
370  nad_free(nad);
371  return;
372  }
373 
374  attr = nad_find_attr(nad, 0, -1, "to", NULL);
375  if(attr < 0 || (to = jid_new(NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr))) == NULL) {
376  log_debug(ZONE, "missing or invalid to on db result packet");
377  jid_free(from);
378  nad_free(nad);
379  return;
380  }
381 
382  rkey = s2s_route_key(NULL, to->domain, from->domain);
383 
384  log_write(in->s2s->log, LOG_NOTICE, "[%d] [%s, port=%d] received dialback auth request for route '%s'", in->fd->fd, in->ip, in->port, rkey);
385 
386  /* get current state */
387  if((conn_state_t) xhash_get(in->states, rkey) == conn_VALID) {
388  log_write(in->s2s->log, LOG_NOTICE, "[%d] [%s, port=%d] route '%s' is already valid: sending valid", in->fd->fd, in->ip, in->port, rkey);
389 
390  /* its already valid, just reply right now */
391  stanza_tofrom(nad, 0);
392  nad_set_attr(nad, 0, -1, "type", "valid", 5);
393  nad->elems[0].icdata = nad->elems[0].itail = -1;
394  nad->elems[0].lcdata = nad->elems[0].ltail = 0;
395 
396  sx_nad_write(in->s, nad);
397 
398  free(rkey);
399 
400  jid_free(from);
401  jid_free(to);
402 
403  return;
404  }
405 
406  /* not valid, so we need to verify */
407 
408  /* need the key */
409  if(NAD_CDATA_L(nad, 0) <= 0) {
410  log_write(in->s2s->log, LOG_NOTICE, "[%d] [%s, port=%d] no dialback key given with db result packet", in->fd->fd, in->ip, in->port, rkey);
411  free(rkey);
412  nad_free(nad);
413  jid_free(from);
414  jid_free(to);
415  return;
416  }
417 
418  log_debug(ZONE, "requesting verification for route %s", rkey);
419 
420  /* set the route status to INPROGRESS and set timestamp */
421  xhash_put(in->states, pstrdup(xhash_pool(in->states), rkey), (void *) conn_INPROGRESS);
422 
423  /* record the time that we set conn_INPROGRESS state */
424  now = time(NULL);
425  xhash_put(in->states_time, pstrdup(xhash_pool(in->states_time), rkey), (void *) now);
426 
427  free(rkey);
428 
429  /* new packet */
430  verify = nad_new();
431  ns = nad_add_namespace(verify, uri_DIALBACK, "db");
432 
433  nad_append_elem(verify, ns, "verify", 0);
434  nad_append_attr(verify, -1, "to", from->domain);
435  nad_append_attr(verify, -1, "from", to->domain);
436  nad_append_attr(verify, -1, "id", in->s->id);
437  nad_append_cdata(verify, NAD_CDATA(nad, 0), NAD_CDATA_L(nad, 0), 1);
438 
439  /* new packet */
440  pkt = (pkt_t) calloc(1, sizeof(struct pkt_st));
441 
442  pkt->nad = verify;
443 
444  pkt->to = from;
445  pkt->from = to;
446 
447  pkt->db = 1;
448 
449  /* its away */
450  out_packet(in->s2s, pkt);
451 
452  nad_free(nad);
453 }
454 
456 static void _in_verify(conn_t in, nad_t nad) {
457  int attr;
458  jid_t from, to;
459  char *id, *dbkey, *type;
460 
461  attr = nad_find_attr(nad, 0, -1, "from", NULL);
462  if(attr < 0 || (from = jid_new(NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr))) == NULL) {
463  log_debug(ZONE, "missing or invalid from on db verify packet");
464  nad_free(nad);
465  return;
466  }
467 
468  attr = nad_find_attr(nad, 0, -1, "to", NULL);
469  if(attr < 0 || (to = jid_new(NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr))) == NULL) {
470  log_debug(ZONE, "missing or invalid to on db verify packet");
471  jid_free(from);
472  nad_free(nad);
473  return;
474  }
475 
476  attr = nad_find_attr(nad, 0, -1, "id", NULL);
477  if(attr < 0) {
478  log_debug(ZONE, "missing id on db verify packet");
479  jid_free(from);
480  jid_free(to);
481  nad_free(nad);
482  return;
483  }
484 
485  if(NAD_CDATA_L(nad, 0) <= 0) {
486  log_debug(ZONE, "no cdata on db verify packet");
487  jid_free(from);
488  jid_free(to);
489  nad_free(nad);
490  return;
491  }
492 
493  /* extract the id */
494  id = (char *) malloc(sizeof(char) * (NAD_AVAL_L(nad, attr) + 1));
495  snprintf(id, NAD_AVAL_L(nad, attr) + 1, "%.*s", NAD_AVAL_L(nad, attr), NAD_AVAL(nad, attr));
496 
497  /* generate a dialback key */
498  dbkey = s2s_db_key(NULL, in->s2s->local_secret, from->domain, id);
499 
500  /* valid */
501  if(NAD_CDATA_L(nad, 0) == strlen(dbkey) && strncmp(dbkey, NAD_CDATA(nad, 0), NAD_CDATA_L(nad, 0)) == 0) {
502  log_debug(ZONE, "valid dialback key %s, verify succeeded", dbkey);
503  type = "valid";
504  } else {
505  log_debug(ZONE, "invalid dialback key %s, verify failed", dbkey);
506  type = "invalid";
507  }
508 
509  log_write(in->s2s->log, LOG_NOTICE, "[%d] [%s, port=%d] checking dialback verification from %s: sending %s", in->fd->fd, in->ip, in->port, from->domain, type);
510 
511  log_debug(ZONE, "letting them know");
512 
513  /* now munge the packet and send it back to them */
514  stanza_tofrom(nad, 0);
515  nad_set_attr(nad, 0, -1, "type", type, 0);
516  nad->elems[0].icdata = nad->elems[0].itail = -1;
517  nad->elems[0].lcdata = nad->elems[0].ltail = 0;
518 
519  sx_nad_write(in->s, nad);
520 
521  free(dbkey);
522  free(id);
523 
524  jid_free(from);
525  jid_free(to);
526 
527  return;
528 }
529 
531 static void _in_packet(conn_t in, nad_t nad) {
532  int elem, attr, ns, sns;
533  jid_t from, to;
534  char *rkey;
535 
536  attr = nad_find_attr(nad, 0, -1, "from", NULL);
537  if(attr < 0 || (from = jid_new(NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr))) == NULL) {
538  log_debug(ZONE, "missing or invalid from on incoming packet");
539  nad_free(nad);
540  return;
541  }
542 
543  attr = nad_find_attr(nad, 0, -1, "to", NULL);
544  if(attr < 0 || (to = jid_new(NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr))) == NULL) {
545  log_debug(ZONE, "missing or invalid to on incoming packet");
546  jid_free(from);
547  nad_free(nad);
548  return;
549  }
550 
551  rkey = s2s_route_key(NULL, to->domain, from->domain);
552 
553  log_debug(ZONE, "received packet from %s for %s", in->key, rkey);
554 
555  /* drop packets received on routes not valid on that connection as per XMPP 8.3.10 */
556  if((conn_state_t) xhash_get(in->states, rkey) != conn_VALID) {
557  log_write(in->s2s->log, LOG_NOTICE, "[%d] [%s, port=%d] dropping packet on unvalidated route: '%s'", in->fd->fd, in->ip, in->port, rkey);
558  free(rkey);
559  nad_free(nad);
560  jid_free(from);
561  jid_free(to);
562  return;
563  }
564 
565  free(rkey);
566 
567  /* its good, off to the router with it */
568 
569  log_debug(ZONE, "incoming packet on valid route, preparing it for the router");
570 
571  /* rewrite server packets into client packets */
572  ns = nad_find_namespace(nad, 0, uri_SERVER, NULL);
573  if(ns >= 0) {
574  if(nad->elems[0].ns == ns)
575  nad->elems[0].ns = nad->nss[nad->elems[0].ns].next;
576  else {
577  for(sns = nad->elems[0].ns; sns >= 0 && nad->nss[sns].next != ns; sns = nad->nss[sns].next);
578  nad->nss[sns].next = nad->nss[nad->nss[sns].next].next;
579  }
580  }
581 
582  /*
583  * If stanza is not in any namespace (either because we removed the
584  * jabber:server namespace above or because it's in the default
585  * namespace for this stream) then this packet is intended to be
586  * handled by sm (and not just routed through the server), so set the
587  * jabber:client namespace.
588  */
589  if(ns >= 0 || nad->elems[0].ns < 0) {
590  ns = nad_add_namespace(nad, uri_CLIENT, NULL);
591  for(elem = 0; elem < nad->ecur; elem++)
592  if(nad->elems[elem].ns == ns)
593  nad->elems[elem].ns = nad->nss[nad->elems[elem].ns].next;
594  nad->nss[ns].next = nad->elems[0].ns;
595  nad->elems[0].ns = ns;
596  nad->scope = -1;
597  }
598 
599  nad->elems[0].my_ns = nad->elems[0].ns;
600 
601  /* wrap up the packet */
602  ns = nad_add_namespace(nad, uri_COMPONENT, NULL);
603 
604  nad_wrap_elem(nad, 0, ns, "route");
605 
606  nad_set_attr(nad, 0, -1, "to", to->domain, 0);
607  nad_set_attr(nad, 0, -1, "from", in->s2s->id, 0); /* route is from s2s, not packet source */
608 
609  log_debug(ZONE, "sending packet to %s", to->domain);
610 
611  /* go */
612  sx_nad_write(in->s2s->router, nad);
613 
614  jid_free(from);
615  jid_free(to);
616 }
#define INET6_ADDRSTRLEN
maximum length of the string representation of an IPv6 address
Definition: util_compat.h:46
struct nad_elem_st * elems
Definition: nad.h:95
Definition: nad.h:93
nad_t nad_new(void)
create a new nad
Definition: nad.c:125
Definition: sx.h:113
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:729
Definition: s2s.h:66
unsigned int packet_count
Definition: s2s.h:286
char ip[INET6_ADDRSTRLEN+1]
Definition: s2s.h:262
int enable_whitelist
Definition: s2s.h:187
sx_t router
router's conn
Definition: s2s.h:91
#define NAD_CDATA_L(N, E)
Definition: nad.h:186
#define sx_nad_write(s, nad)
Definition: sx.h:167
int db
Definition: s2s.h:240
Definition: sx.h:59
int ltail
Definition: nad.h:73
log_t log
logging
Definition: s2s.h:101
jid_t jid_new(const char *id, int len)
make a new jid
Definition: jid.c:81
Definition: sx.h:65
jqueue_t dead
list of sx_t on the way out
Definition: s2s.h:192
void nad_append_cdata(nad_t nad, const char *cdata, int len, int depth)
append new cdata to the last elem
Definition: nad.c:737
void log_write(log_t log, int level, const char *msgfmt,...)
Definition: log.c:104
int port
Definition: s2s.h:263
error info for event_ERROR
Definition: sx.h:99
xht in_accept
incoming conns prior to stream initiation (key is ip/port)
Definition: s2s.h:219
int rbytesmax
Definition: sx.h:313
sx_t sx_new(sx_env_t env, int tag, sx_callback_t cb, void *arg)
if you change these, reflect your changes in the table in error.c
Definition: sx.c:23
#define MIO_STRERROR(e)
Definition: mio.h:170
int sx_can_write(sx_t s)
Definition: io.c:333
int icdata
Definition: nad.h:72
int nad_add_namespace(nad_t nad, const char *uri, const char *prefix)
bring a new namespace into scope
Definition: nad.c:762
void sx_server_init(sx_t s, unsigned int flags)
Definition: server.c:248
xht states
states of outgoing dialbacks (key is local/remote)
Definition: s2s.h:266
#define NAD_ENAME(N, E)
Definition: nad.h:183
struct conn_st * conn_t
Definition: s2s.h:41
mio_action_t
these are the actions and a handler type assigned by the applicaiton using mio
Definition: mio.h:106
Definition: mio.h:109
int nad_append_elem(nad_t nad, int ns, const char *name, int depth)
create a new elem on the list
Definition: nad.c:695
void nad_free(nad_t nad)
free that nad
Definition: nad.c:178
#define S2S_DB_HEADER
Definition: s2s.h:388
void nad_wrap_elem(nad_t nad, int elem, int ns, const char *name)
wrap an element with another element
Definition: nad.c:503
long long int packet_count
packet counter
Definition: s2s.h:109
#define SX_COMPRESS_OFFER
Definition: plugins.h:32
Definition: sx.h:60
s2s_t s2s
Definition: s2s.h:254
#define mio_read(m, fd)
process read events for this fd
Definition: mio.h:161
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:403
#define MIO_ERROR
all MIO related routines should use those for error reporting
Definition: mio.h:168
char * s2s_route_key(pool_t p, const char *local, const char *remote)
generate a local/remote route key
Definition: util.c:27
sx_env_t sx_env
sx environment
Definition: s2s.h:85
#define MIO_WOULDBLOCK
Definition: mio.h:171
int sx_can_read(sx_t s)
we can read
Definition: io.c:196
int compression
enable Stream Compression
Definition: s2s.h:154
int online
Definition: s2s.h:276
int stanza_size_limit
maximum stanza size
Definition: s2s.h:151
holds the state for a single stream
Definition: sx.h:253
char * data
Definition: sx.h:114
jid_t from
packet addressing (not used for routing)
Definition: sm.h:140
conn_state_t
Definition: s2s.h:246
int j_inet_getport(struct sockaddr_storage *sa)
get the port number out of a struct sockaddr_storage
Definition: inaddr.c:148
char * s2s_db_key(pool_t p, const char *secret, const char *remote, const char *id)
generate a dialback key
Definition: util.c:61
packet summary data wrapper
Definition: sm.h:129
struct nad_ns_st * nss
Definition: nad.h:97
const char * key
Definition: s2s.h:256
#define NAD_ENAME_L(N, E)
Definition: nad.h:184
void jqueue_push(jqueue_t q, void *data, int priority)
Definition: jqueue.c:44
#define NAD_NURI_L(N, NS)
Definition: nad.h:192
nad_t nad
nad of the entire packet
Definition: sm.h:146
void jid_free(jid_t jid)
free a jid
Definition: jid.c:286
int s2s_domain_in_whitelist(s2s_t s2s, const char *in_domain)
Definition: main.c:680
sx_plugin_t sx_ssl
Definition: s2s.h:86
jqueue_t dead_conn
list of conn_t on the way out
Definition: s2s.h:195
sx_t s
Definition: s2s.h:259
void xhash_put(xht h, const char *key, void *val)
Definition: xhash.c:163
#define SX_SSL_STARTTLS_OFFER
Definition: plugins.h:26
xht states_time
time of the last state change (key is local/remote)
Definition: s2s.h:269
char * domain
Definition: jid.h:45
const char * generic
Definition: sx.h:101
nad_t stanza_tofrom(nad_t nad, int elem)
flip the to and from attributes on this elem
Definition: stanza.c:78
Definition: jid.h:42
int ecur
Definition: nad.h:105
int in_mio_callback(mio_t m, mio_action_t a, mio_fd_t fd, void *data, void *arg)
Definition: in.c:63
struct pkt_st * pkt_t
packet summary data wrapper
const char * local_secret
dialback secret
Definition: s2s.h:127
#define NAD_AVAL_L(N, A)
Definition: nad.h:190
void xhash_zap(xht h, const char *key)
Definition: xhash.c:235
#define log_debug(...)
Definition: log.h:65
#define uri_CLIENT
Definition: uri.h:35
#define NAD_AVAL(N, A)
Definition: nad.h:189
struct _sx_buf_st * sx_buf_t
utility: buffer
Definition: sx.h:112
mio_fd_t server_fd
listening sockets
Definition: s2s.h:95
int ns
Definition: nad.h:75
time_t last_packet
Definition: s2s.h:284
int scope
Definition: nad.h:107
static void _in_verify(conn_t in, nad_t nad)
validate their key
Definition: in.c:456
#define mio_app(m, fd, app, arg)
re-set the app handler
Definition: mio.h:152
int ssf
Definition: sx.h:340
static void _in_result(conn_t in, nad_t nad)
auth requests
Definition: in.c:359
const char * specific
Definition: sx.h:102
int fd
Definition: mio.h:102
unsigned int len
Definition: sx.h:115
struct s2s_st * s2s_t
Definition: s2s.h:39
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
static void _in_packet(conn_t in, nad_t nad)
they're trying to send us something
Definition: in.c:531
pool_t xhash_pool(xht h)
get our pool
Definition: xhash.c:305
const char * id
our id (hostname) with the router
Definition: s2s.h:68
mio_t mio
mio context
Definition: s2s.h:82
char * pstrdup(pool_t p, const char *src)
XXX efficient: move this to const char * and then loop throug the existing heaps to see if src is wit...
Definition: pool.c:191
Definition: mio.h:100
#define NAD_CDATA(N, E)
Definition: nad.h:185
void sx_kill(sx_t s)
Definition: io.c:513
xht in
incoming conns (key is stream id)
Definition: s2s.h:216
void * xhash_get(xht h, const char *key)
Definition: xhash.c:184
#define uri_COMPONENT
Definition: uri.h:52
#define mio_close(m, fd)
request that mio close this fd
Definition: mio.h:155
#define mio_write(m, fd)
mio should try the write action on this fd now
Definition: mio.h:158
int require_tls
Apple security options.
Definition: s2s.h:186
#define ZONE
Definition: mio_impl.h:76
Definition: s2s.h:253
static int _in_sx_callback(sx_t s, sx_event_t e, void *data, void *arg)
Definition: in.c:160
#define NAD_NURI(N, NS)
Definition: nad.h:191
sx_event_t
things that can happen
Definition: sx.h:56
#define uri_SERVER
Definition: uri.h:36
xht xhash_new(int prime)
Definition: xhash.c:96
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
#define uri_DIALBACK
Definition: uri.h:37
int itail
Definition: nad.h:73
int lcdata
Definition: nad.h:72
Definition: sx.h:62
int out_packet(s2s_t s2s, pkt_t pkt)
send a packet out
Definition: out.c:610
struct nad_st * nad_t
mio_fd_t fd
Definition: s2s.h:260
const char * id
Definition: sx.h:292
time_t init_time
Definition: s2s.h:274
#define NAD_ENS(N, E)
Definition: nad.h:196
int my_ns
Definition: nad.h:76