jabberd2  2.6.1
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  if (getpeername(fd->fd, (struct sockaddr *) &sa, &namelen) < 0) {
115  return -1;
116  }
117  port = j_inet_getport(&sa);
118 
119  log_write(s2s->log, LOG_NOTICE, "[%d] [%s, port=%d] incoming connection", fd->fd, (char *) data, port);
120 
121  /* new conn */
122  in = (conn_t) calloc(1, sizeof(struct conn_st));
123 
124  in->s2s = s2s;
125 
126  strncpy(in->ip, (char *) data, INET6_ADDRSTRLEN);
127  in->port = port;
128 
129  in->states = xhash_new(101);
130  in->states_time = xhash_new(101);
131 
132  in->fd = fd;
133 
134  in->init_time = time(NULL);
135 
136  in->s = sx_new(s2s->sx_env, in->fd->fd, _in_sx_callback, (void *) in);
137  mio_app(m, in->fd, in_mio_callback, (void *) in);
138 
139  if(s2s->stanza_size_limit != 0)
140  in->s->rbytesmax = s2s->stanza_size_limit;
141 
142  /* add to incoming connections hash */
143  snprintf(ipport, INET6_ADDRSTRLEN + 16, "%s/%d", in->ip, in->port);
144  xhash_put(s2s->in_accept, pstrdup(xhash_pool(s2s->in_accept),ipport), (void *) in);
145 
146  flags = S2S_DB_HEADER;
147 #ifdef HAVE_SSL
148  if(s2s->sx_ssl != NULL)
149  flags |= SX_SSL_STARTTLS_OFFER;
150 #endif
151 #ifdef HAVE_LIBZ
152  if(s2s->compression)
153  flags |= SX_COMPRESS_OFFER;
154 #endif
155  sx_server_init(in->s, flags);
156  break;
157  }
158 
159  return 0;
160 }
161 
162 static int _in_sx_callback(sx_t s, sx_event_t e, void *data, void *arg) {
163  conn_t in = (conn_t) arg;
164  sx_buf_t buf = (sx_buf_t) data;
165  int len;
166  sx_error_t *sxe;
167  nad_t nad;
168  char ipport[INET6_ADDRSTRLEN + 17];
169  jid_t from;
170  int attr;
171 
172  switch(e) {
173  case event_WANT_READ:
174  log_debug(ZONE, "want read");
175  mio_read(in->s2s->mio, in->fd);
176  break;
177 
178  case event_WANT_WRITE:
179  log_debug(ZONE, "want write");
180  mio_write(in->s2s->mio, in->fd);
181  break;
182 
183  case event_READ:
184  log_debug(ZONE, "reading from %d", in->fd->fd);
185 
186  /* do the read */
187  len = recv(in->fd->fd, buf->data, buf->len, 0);
188 
189  if(len < 0) {
190  if(MIO_WOULDBLOCK) {
191  buf->len = 0;
192  return 0;
193  }
194 
195  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);
196 
197  sx_kill(s);
198 
199  return -1;
200  }
201 
202  else if(len == 0) {
203  /* they went away */
204  sx_kill(s);
205 
206  return -1;
207  }
208 
209  log_debug(ZONE, "read %d bytes", len);
210 
211  buf->len = len;
212 
213  return len;
214 
215  case event_WRITE:
216  log_debug(ZONE, "writing to %d", in->fd->fd);
217 
218  len = send(in->fd->fd, buf->data, buf->len, 0);
219  if(len >= 0) {
220  log_debug(ZONE, "%d bytes written", len);
221  return len;
222  }
223 
224  if(MIO_WOULDBLOCK)
225  return 0;
226 
227  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);
228 
229  sx_kill(s);
230 
231  return -1;
232 
233  case event_ERROR:
234  sxe = (sx_error_t *) data;
235  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);
236 
237  break;
238 
239  case event_STREAM:
240  case event_OPEN:
241 
242  log_debug(ZONE, "STREAM or OPEN event from %s port %d (id %s)", in->ip, in->port, s->id);
243 
244  /* first time, bring them online */
245  if ((!in->online)||(strcmp(in->key,s->id)!=0)) {
246  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);
247 
248  in->online = 1;
249 
250  /* record the id */
251  if (in->key != NULL) {
252  log_debug(ZONE,"adding new SSL stream id %s for stream id %s", s->id, in->key);
253 
254  /* remove the initial (non-SSL) stream id from the in connections hash */
255  xhash_zap(in->s2s->in, in->key);
256  free((void*)in->key);
257  }
258 
259  in->key = strdup(s->id);
260 
261  /* track it - add to open streams hash and remove from new connections hash */
262  xhash_put(in->s2s->in, in->key, (void *) in);
263 
264  snprintf(ipport, INET6_ADDRSTRLEN + 16, "%s/%d", in->ip, in->port);
265  xhash_zap(in->s2s->in_accept, ipport);
266  }
267 
268  break;
269 
270  case event_PACKET:
271  /* we're counting packets */
272  in->packet_count++;
273  in->s2s->packet_count++;
274 
275  nad = (nad_t) data;
276 
277  /* update last packet timestamp */
278  in->last_packet = time(NULL);
279 
280  /* dialback packets */
281  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 &&
282  (in->s2s->require_tls == 0 || s->ssf > 0)) {
283  /* only result and verify mean anything */
284  if(NAD_ENAME_L(nad, 0) == 6) {
285  if(strncmp("result", NAD_ENAME(nad, 0), 6) == 0) {
286  _in_result(in, nad);
287  return 0;
288  }
289 
290  if(strncmp("verify", NAD_ENAME(nad, 0), 6) == 0) {
291  _in_verify(in, nad);
292  return 0;
293  }
294  }
295 
296  log_debug(ZONE, "unknown dialback packet, dropping it");
297 
298  nad_free(nad);
299  return 0;
300  }
301 
302  /*
303  * not dialback, so it has to be a normal-ish jabber packet:
304  * - jabber:client or jabber:server
305  * - message, presence or iq
306  * - has to and from attributes
307  */
308 
309  if(!(
310  /* must be jabber:client or jabber:server */
311  NAD_ENS(nad, 0) >= 0 &&
312  ((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) ||
313  (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)) && (
314  /* can be message */
315  (NAD_ENAME_L(nad, 0) == 7 && strncmp("message", NAD_ENAME(nad, 0), 7) == 0) ||
316  /* or presence */
317  (NAD_ENAME_L(nad, 0) == 8 && strncmp("presence", NAD_ENAME(nad, 0), 8) == 0) ||
318  /* or iq */
319  (NAD_ENAME_L(nad, 0) == 2 && strncmp("iq", NAD_ENAME(nad, 0), 2) == 0)
320  ) &&
321  /* to and from required */
322  nad_find_attr(nad, 0, -1, "to", NULL) >= 0 && nad_find_attr(nad, 0, -1, "from", NULL) >= 0
323  )) {
324  log_debug(ZONE, "they sent us a non-jabber looking packet, dropping it");
325  nad_free(nad);
326  return 0;
327  }
328 
329  /* perform check against whitelist */
330  attr = nad_find_attr(nad, 0, -1, "from", NULL);
331  if(attr < 0 || (from = jid_new(NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr))) == NULL) {
332  log_debug(ZONE, "missing or invalid from on incoming packet, attr is %d", attr);
333  nad_free(nad);
334  return 0;
335  }
336 
337  if (in->s2s->enable_whitelist > 0 && (s2s_domain_in_whitelist(in->s2s, from->domain) == 0)) {
338  log_write(in->s2s->log, LOG_NOTICE, "received a packet not from a whitelisted domain %s, dropping it", from->domain);
339  jid_free(from);
340  nad_free(nad);
341  return 0;
342  }
343 
344  jid_free(from);
345 
346  _in_packet(in, nad);
347  return 0;
348 
349  case event_CLOSED:
350  if (in->fd != NULL) {
351  mio_close(in->s2s->mio, in->fd);
352  in->fd = NULL;
353  }
354  return -1;
355  }
356 
357  return 0;
358 }
359 
361 static void _in_result(conn_t in, nad_t nad) {
362  int attr, ns;
363  jid_t from, to;
364  char *rkey;
365  nad_t verify;
366  pkt_t pkt;
367  time_t now;
368 
369  attr = nad_find_attr(nad, 0, -1, "from", NULL);
370  if(attr < 0 || (from = jid_new(NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr))) == NULL) {
371  log_debug(ZONE, "missing or invalid from on db result packet");
372  nad_free(nad);
373  return;
374  }
375 
376  attr = nad_find_attr(nad, 0, -1, "to", NULL);
377  if(attr < 0 || (to = jid_new(NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr))) == NULL) {
378  log_debug(ZONE, "missing or invalid to on db result packet");
379  jid_free(from);
380  nad_free(nad);
381  return;
382  }
383 
384  rkey = s2s_route_key(NULL, to->domain, from->domain);
385 
386  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);
387 
388  /* get current state */
389  if((conn_state_t) xhash_get(in->states, rkey) == conn_VALID) {
390  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);
391 
392  /* its already valid, just reply right now */
393  stanza_tofrom(nad, 0);
394  nad_set_attr(nad, 0, -1, "type", "valid", 5);
395  nad->elems[0].icdata = nad->elems[0].itail = -1;
396  nad->elems[0].lcdata = nad->elems[0].ltail = 0;
397 
398  sx_nad_write(in->s, nad);
399 
400  free(rkey);
401 
402  jid_free(from);
403  jid_free(to);
404 
405  return;
406  }
407 
408  /* not valid, so we need to verify */
409 
410  /* need the key */
411  if(NAD_CDATA_L(nad, 0) <= 0) {
412  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);
413  free(rkey);
414  nad_free(nad);
415  jid_free(from);
416  jid_free(to);
417  return;
418  }
419 
420  log_debug(ZONE, "requesting verification for route %s", rkey);
421 
422  /* set the route status to INPROGRESS and set timestamp */
423  xhash_put(in->states, pstrdup(xhash_pool(in->states), rkey), (void *) conn_INPROGRESS);
424 
425  /* record the time that we set conn_INPROGRESS state */
426  now = time(NULL);
427  xhash_put(in->states_time, pstrdup(xhash_pool(in->states_time), rkey), (void *) now);
428 
429  free(rkey);
430 
431  /* new packet */
432  verify = nad_new();
433  ns = nad_add_namespace(verify, uri_DIALBACK, "db");
434 
435  nad_append_elem(verify, ns, "verify", 0);
436  nad_append_attr(verify, -1, "to", from->domain);
437  nad_append_attr(verify, -1, "from", to->domain);
438  nad_append_attr(verify, -1, "id", in->s->id);
439  nad_append_cdata(verify, NAD_CDATA(nad, 0), NAD_CDATA_L(nad, 0), 1);
440 
441  /* new packet */
442  pkt = (pkt_t) calloc(1, sizeof(struct pkt_st));
443 
444  pkt->nad = verify;
445 
446  pkt->to = from;
447  pkt->from = to;
448 
449  pkt->db = 1;
450 
451  /* its away */
452  out_packet(in->s2s, pkt);
453 
454  nad_free(nad);
455 }
456 
458 static void _in_verify(conn_t in, nad_t nad) {
459  int attr;
460  jid_t from, to;
461  char *id, *dbkey, *type;
462 
463  attr = nad_find_attr(nad, 0, -1, "from", NULL);
464  if(attr < 0 || (from = jid_new(NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr))) == NULL) {
465  log_debug(ZONE, "missing or invalid from on db verify packet");
466  nad_free(nad);
467  return;
468  }
469 
470  attr = nad_find_attr(nad, 0, -1, "to", NULL);
471  if(attr < 0 || (to = jid_new(NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr))) == NULL) {
472  log_debug(ZONE, "missing or invalid to on db verify packet");
473  jid_free(from);
474  nad_free(nad);
475  return;
476  }
477 
478  attr = nad_find_attr(nad, 0, -1, "id", NULL);
479  if(attr < 0) {
480  log_debug(ZONE, "missing id on db verify packet");
481  jid_free(from);
482  jid_free(to);
483  nad_free(nad);
484  return;
485  }
486 
487  if(NAD_CDATA_L(nad, 0) <= 0) {
488  log_debug(ZONE, "no cdata on db verify packet");
489  jid_free(from);
490  jid_free(to);
491  nad_free(nad);
492  return;
493  }
494 
495  /* extract the id */
496  id = (char *) malloc(sizeof(char) * (NAD_AVAL_L(nad, attr) + 1));
497  snprintf(id, NAD_AVAL_L(nad, attr) + 1, "%.*s", NAD_AVAL_L(nad, attr), NAD_AVAL(nad, attr));
498 
499  /* generate a dialback key */
500  dbkey = s2s_db_key(NULL, in->s2s->local_secret, from->domain, id);
501 
502  /* valid */
503  if(NAD_CDATA_L(nad, 0) == strlen(dbkey) && strncmp(dbkey, NAD_CDATA(nad, 0), NAD_CDATA_L(nad, 0)) == 0) {
504  log_debug(ZONE, "valid dialback key %s, verify succeeded", dbkey);
505  type = "valid";
506  } else {
507  log_debug(ZONE, "invalid dialback key %s, verify failed", dbkey);
508  type = "invalid";
509  }
510 
511  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);
512 
513  log_debug(ZONE, "letting them know");
514 
515  /* now munge the packet and send it back to them */
516  stanza_tofrom(nad, 0);
517  nad_set_attr(nad, 0, -1, "type", type, 0);
518  nad->elems[0].icdata = nad->elems[0].itail = -1;
519  nad->elems[0].lcdata = nad->elems[0].ltail = 0;
520 
521  sx_nad_write(in->s, nad);
522 
523  free(dbkey);
524  free(id);
525 
526  jid_free(from);
527  jid_free(to);
528 
529  return;
530 }
531 
533 static void _in_packet(conn_t in, nad_t nad) {
534  int elem, attr, ns, sns;
535  jid_t from, to;
536  char *rkey;
537 
538  attr = nad_find_attr(nad, 0, -1, "from", NULL);
539  if(attr < 0 || (from = jid_new(NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr))) == NULL) {
540  log_debug(ZONE, "missing or invalid from on incoming packet");
541  nad_free(nad);
542  return;
543  }
544 
545  attr = nad_find_attr(nad, 0, -1, "to", NULL);
546  if(attr < 0 || (to = jid_new(NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr))) == NULL) {
547  log_debug(ZONE, "missing or invalid to on incoming packet");
548  jid_free(from);
549  nad_free(nad);
550  return;
551  }
552 
553  rkey = s2s_route_key(NULL, to->domain, from->domain);
554 
555  log_debug(ZONE, "received packet from %s for %s", in->key, rkey);
556 
557  /* drop packets received on routes not valid on that connection as per XMPP 8.3.10 */
558  if((conn_state_t) xhash_get(in->states, rkey) != conn_VALID) {
559  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);
560  free(rkey);
561  nad_free(nad);
562  jid_free(from);
563  jid_free(to);
564  return;
565  }
566 
567  free(rkey);
568 
569  /* its good, off to the router with it */
570 
571  log_debug(ZONE, "incoming packet on valid route, preparing it for the router");
572 
573  /* rewrite server packets into client packets */
574  ns = nad_find_namespace(nad, 0, uri_SERVER, NULL);
575  if(ns >= 0) {
576  if(nad->elems[0].ns == ns)
577  nad->elems[0].ns = nad->nss[nad->elems[0].ns].next;
578  else {
579  for(sns = nad->elems[0].ns; sns >= 0 && nad->nss[sns].next != ns; sns = nad->nss[sns].next);
580  nad->nss[sns].next = nad->nss[nad->nss[sns].next].next;
581  }
582  }
583 
584  /*
585  * If stanza is not in any namespace (either because we removed the
586  * jabber:server namespace above or because it's in the default
587  * namespace for this stream) then this packet is intended to be
588  * handled by sm (and not just routed through the server), so set the
589  * jabber:client namespace.
590  */
591  if(ns >= 0 || nad->elems[0].ns < 0) {
592  ns = nad_add_namespace(nad, uri_CLIENT, NULL);
593  for(elem = 0; elem < nad->ecur; elem++)
594  if(nad->elems[elem].ns == ns)
595  nad->elems[elem].ns = nad->nss[nad->elems[elem].ns].next;
596  nad->nss[ns].next = nad->elems[0].ns;
597  nad->elems[0].ns = ns;
598  nad->scope = -1;
599  }
600 
601  nad->elems[0].my_ns = nad->elems[0].ns;
602 
603  /* wrap up the packet */
604  ns = nad_add_namespace(nad, uri_COMPONENT, NULL);
605 
606  nad_wrap_elem(nad, 0, ns, "route");
607 
608  nad_set_attr(nad, 0, -1, "to", to->domain, 0);
609  nad_set_attr(nad, 0, -1, "from", in->s2s->id, 0); /* route is from s2s, not packet source */
610 
611  log_debug(ZONE, "sending packet to %s", to->domain);
612 
613  /* go */
614  sx_nad_write(in->s2s->router, nad);
615 
616  jid_free(from);
617  jid_free(to);
618 }
#define INET6_ADDRSTRLEN
maximum length of the string representation of an IPv6 address
Definition: util_compat.h:46
void nad_wrap_elem(nad_t nad, unsigned int elem, int ns, const char *name)
wrap an element with another element
Definition: nad.c:507
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:745
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&#39;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
int nad_find_attr(nad_t nad, unsigned 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:237
void nad_set_attr(nad_t nad, unsigned 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:407
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:753
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
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:347
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:778
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:711
void nad_free(nad_t nad)
free that nad
Definition: nad.c:180
#define S2S_DB_HEADER
Definition: s2s.h:388
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
int nad_find_namespace(nad_t nad, unsigned int elem, const char *uri, const char *prefix)
get a matching ns on this elem, both uri and optional prefix
Definition: nad.c:264
#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:670
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:458
#define mio_app(m, fd, app, arg)
re-set the app handler
Definition: mio.h:152
int ssf
Definition: sx.h:343
static void _in_result(conn_t in, nad_t nad)
auth requests
Definition: in.c:361
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
static void _in_packet(conn_t in, nad_t nad)
they&#39;re trying to send us something
Definition: in.c:533
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:527
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:162
#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
#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:626
struct nad_st * nad_t
mio_fd_t fd
Definition: s2s.h:260
const char * id
Definition: sx.h:292
#define NAD_ENS(N, E)
Definition: nad.h:196
int my_ns
Definition: nad.h:76