jabberd2  2.3.3
main.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 "c2s.h"
22 
23 #include <stringprep.h>
24 
25 static sig_atomic_t c2s_shutdown = 0;
26 sig_atomic_t c2s_lost_router = 0;
27 static sig_atomic_t c2s_logrotate = 0;
28 static sig_atomic_t c2s_sighup = 0;
29 
30 static void _c2s_signal(int signum)
31 {
32  c2s_shutdown = 1;
33  c2s_lost_router = 0;
34 }
35 
36 static void _c2s_signal_hup(int signum)
37 {
38  c2s_logrotate = 1;
39  c2s_sighup = 1;
40 }
41 
42 static void _c2s_signal_usr1(int signum)
43 {
44  set_debug_flag(0);
45 }
46 
47 static void _c2s_signal_usr2(int signum)
48 {
49  set_debug_flag(1);
50 }
51 
53 static void _c2s_pidfile(c2s_t c2s) {
54  const char *pidfile;
55  FILE *f;
56  pid_t pid;
57 
58  pidfile = config_get_one(c2s->config, "pidfile", 0);
59  if(pidfile == NULL)
60  return;
61 
62  pid = getpid();
63 
64  if((f = fopen(pidfile, "w+")) == NULL) {
65  log_write(c2s->log, LOG_ERR, "couldn't open %s for writing: %s", pidfile, strerror(errno));
66  return;
67  }
68 
69  if(fprintf(f, "%d", pid) < 0) {
70  log_write(c2s->log, LOG_ERR, "couldn't write to %s: %s", pidfile, strerror(errno));
71  fclose(f);
72  return;
73  }
74 
75  fclose(f);
76 
77  log_write(c2s->log, LOG_INFO, "process id is %d, written to %s", pid, pidfile);
78 }
80 static void _c2s_config_expand(c2s_t c2s)
81 {
82  const char *str, *ip, *mask;
83  char *req_domain, *to_address, *to_port;
84  config_elem_t elem;
85  int i;
87 
89 
90  c2s->id = config_get_one(c2s->config, "id", 0);
91  if(c2s->id == NULL)
92  c2s->id = "c2s";
93 
94  c2s->router_ip = config_get_one(c2s->config, "router.ip", 0);
95  if(c2s->router_ip == NULL)
96  c2s->router_ip = "127.0.0.1";
97 
98  c2s->router_port = j_atoi(config_get_one(c2s->config, "router.port", 0), 5347);
99 
100  c2s->router_user = config_get_one(c2s->config, "router.user", 0);
101  if(c2s->router_user == NULL)
102  c2s->router_user = "jabberd";
103  c2s->router_pass = config_get_one(c2s->config, "router.pass", 0);
104  if(c2s->router_pass == NULL)
105  c2s->router_pass = "secret";
106 
107  c2s->router_pemfile = config_get_one(c2s->config, "router.pemfile", 0);
108 
109  c2s->router_cachain = config_get_one(c2s->config, "router.cachain", 0);
110 
111  c2s->router_private_key_password = config_get_one(c2s->config, "router.private_key_password", 0);
112 
113  c2s->retry_init = j_atoi(config_get_one(c2s->config, "router.retry.init", 0), 3);
114  c2s->retry_lost = j_atoi(config_get_one(c2s->config, "router.retry.lost", 0), 3);
115  if((c2s->retry_sleep = j_atoi(config_get_one(c2s->config, "router.retry.sleep", 0), 2)) < 1)
116  c2s->retry_sleep = 1;
117 
118  c2s->log_type = log_STDOUT;
119  if(config_get(c2s->config, "log") != NULL) {
120  if((str = config_get_attr(c2s->config, "log", 0, "type")) != NULL) {
121  if(strcmp(str, "file") == 0)
122  c2s->log_type = log_FILE;
123  else if(strcmp(str, "syslog") == 0)
124  c2s->log_type = log_SYSLOG;
125  }
126  }
127 
128  if(c2s->log_type == log_SYSLOG) {
129  c2s->log_facility = config_get_one(c2s->config, "log.facility", 0);
130  c2s->log_ident = config_get_one(c2s->config, "log.ident", 0);
131  if(c2s->log_ident == NULL)
132  c2s->log_ident = "jabberd/c2s";
133  } else if(c2s->log_type == log_FILE)
134  c2s->log_ident = config_get_one(c2s->config, "log.file", 0);
135 
136  c2s->packet_stats = config_get_one(c2s->config, "stats.packet", 0);
137 
138  c2s->local_ip = config_get_one(c2s->config, "local.ip", 0);
139  if(c2s->local_ip == NULL)
140  c2s->local_ip = "0.0.0.0";
141 
142  c2s->local_port = j_atoi(config_get_one(c2s->config, "local.port", 0), 0);
143 
144  c2s->local_pemfile = config_get_one(c2s->config, "local.pemfile", 0);
145 
146  c2s->local_cachain = config_get_one(c2s->config, "local.cachain", 0);
147 
148  c2s->local_private_key_password = config_get_one(c2s->config, "local.private_key_password", 0);
149 
150  c2s->local_verify_mode = j_atoi(config_get_one(c2s->config, "local.verify-mode", 0), 0);
151 
152  c2s->local_ssl_port = j_atoi(config_get_one(c2s->config, "local.ssl-port", 0), 0);
153 
154  c2s->http_forward = config_get_one(c2s->config, "local.httpforward", 0);
155 
156  c2s->io_max_fds = j_atoi(config_get_one(c2s->config, "io.max_fds", 0), 1024);
157 
158  c2s->compression = (config_get(c2s->config, "io.compression") != NULL);
159 
160  c2s->io_check_interval = j_atoi(config_get_one(c2s->config, "io.check.interval", 0), 0);
161  c2s->io_check_idle = j_atoi(config_get_one(c2s->config, "io.check.idle", 0), 0);
162  c2s->io_check_keepalive = j_atoi(config_get_one(c2s->config, "io.check.keepalive", 0), 0);
163 
164  c2s->pbx_pipe = config_get_one(c2s->config, "pbx.pipe", 0);
165 
166  elem = config_get(c2s->config, "stream_redirect.redirect");
167  if(elem != NULL)
168  {
169  for(i = 0; i < elem->nvalues; i++)
170  {
172  if(!sr) {
173  log_write(c2s->log, LOG_ERR, "cannot allocate memory for new stream redirection record, aborting");
174  exit(1);
175  }
176  req_domain = j_attr((const char **) elem->attrs[i], "requested_domain");
177  to_address = j_attr((const char **) elem->attrs[i], "to_address");
178  to_port = j_attr((const char **) elem->attrs[i], "to_port");
179 
180  if(req_domain == NULL || to_address == NULL || to_port == NULL) {
181  log_write(c2s->log, LOG_ERR, "Error reading a stream_redirect.redirect element from file, skipping");
182  continue;
183  }
184 
185  // Note that to_address should be RFC 3986 compliant
186  sr->to_address = to_address;
187  sr->to_port = to_port;
188 
189  xhash_put(c2s->stream_redirects, pstrdup(xhash_pool(c2s->stream_redirects), req_domain), sr);
190  }
191  }
192 
193  c2s->ar_module_name = config_get_one(c2s->config, "authreg.module", 0);
194 
195  if(config_get(c2s->config, "authreg.mechanisms.traditional.plain") != NULL) c2s->ar_mechanisms |= AR_MECH_TRAD_PLAIN;
196  if(config_get(c2s->config, "authreg.mechanisms.traditional.digest") != NULL) c2s->ar_mechanisms |= AR_MECH_TRAD_DIGEST;
197  if(config_get(c2s->config, "authreg.mechanisms.traditional.cram-md5") != NULL) c2s->ar_mechanisms |= AR_MECH_TRAD_CRAMMD5;
198 
199  if(config_get(c2s->config, "authreg.ssl-mechanisms.traditional.plain") != NULL) c2s->ar_ssl_mechanisms |= AR_MECH_TRAD_PLAIN;
200  if(config_get(c2s->config, "authreg.ssl-mechanisms.traditional.digest") != NULL) c2s->ar_ssl_mechanisms |= AR_MECH_TRAD_DIGEST;
201  if(config_get(c2s->config, "authreg.ssl-mechanisms.traditional.cram-md5") != NULL) c2s->ar_ssl_mechanisms |= AR_MECH_TRAD_CRAMMD5;
202 
203  elem = config_get(c2s->config, "io.limits.bytes");
204  if(elem != NULL)
205  {
206  c2s->byte_rate_total = j_atoi(elem->values[0], 0);
207  if(c2s->byte_rate_total != 0)
208  {
209  c2s->byte_rate_seconds = j_atoi(j_attr((const char **) elem->attrs[0], "seconds"), 1);
210  c2s->byte_rate_wait = j_atoi(j_attr((const char **) elem->attrs[0], "throttle"), 5);
211  }
212  }
213 
214  elem = config_get(c2s->config, "io.limits.stanzas");
215  if(elem != NULL)
216  {
217  c2s->stanza_rate_total = j_atoi(elem->values[0], 0);
218  if(c2s->stanza_rate_total != 0)
219  {
220  c2s->stanza_rate_seconds = j_atoi(j_attr((const char **) elem->attrs[0], "seconds"), 1);
221  c2s->stanza_rate_wait = j_atoi(j_attr((const char **) elem->attrs[0], "throttle"), 5);
222  }
223  }
224 
225  elem = config_get(c2s->config, "io.limits.connects");
226  if(elem != NULL)
227  {
228  c2s->conn_rate_total = j_atoi(elem->values[0], 0);
229  if(c2s->conn_rate_total != 0)
230  {
231  c2s->conn_rate_seconds = j_atoi(j_attr((const char **) elem->attrs[0], "seconds"), 5);
232  c2s->conn_rate_wait = j_atoi(j_attr((const char **) elem->attrs[0], "throttle"), 5);
233  }
234  }
235 
236  c2s->stanza_size_limit = j_atoi(config_get_one(c2s->config, "io.limits.stanzasize", 0), 0);
237 
238  /* tweak timed checks with rate times */
239  if(c2s->io_check_interval == 0) {
240  if(c2s->byte_rate_total != 0)
241  c2s->io_check_interval = c2s->byte_rate_wait;
242 
243  if(c2s->stanza_rate_total != 0 && c2s->io_check_interval > c2s->stanza_rate_wait)
245  }
246 
247  str = config_get_one(c2s->config, "io.access.order", 0);
248  if(str == NULL || strcmp(str, "deny,allow") != 0)
249  c2s->access = access_new(0);
250  else
251  c2s->access = access_new(1);
252 
253  elem = config_get(c2s->config, "io.access.allow");
254  if(elem != NULL)
255  {
256  for(i = 0; i < elem->nvalues; i++)
257  {
258  ip = j_attr((const char **) elem->attrs[i], "ip");
259  mask = j_attr((const char **) elem->attrs[i], "mask");
260 
261  if(ip == NULL)
262  continue;
263 
264  if(mask == NULL)
265  mask = "255.255.255.255";
266 
267  access_allow(c2s->access, ip, mask);
268  }
269  }
270 
271  elem = config_get(c2s->config, "io.access.deny");
272  if(elem != NULL)
273  {
274  for(i = 0; i < elem->nvalues; i++)
275  {
276  ip = j_attr((const char **) elem->attrs[i], "ip");
277  mask = j_attr((const char **) elem->attrs[i], "mask");
278 
279  if(ip == NULL)
280  continue;
281 
282  if(mask == NULL)
283  mask = "255.255.255.255";
284 
285  access_deny(c2s->access, ip, mask);
286  }
287  }
288 }
289 
290 static void _c2s_hosts_expand(c2s_t c2s)
291 {
292  char *realm;
293  config_elem_t elem;
294  char id[1024];
295  int i;
296 
297  elem = config_get(c2s->config, "local.id");
298  if(!elem) {
299  log_write(c2s->log, LOG_NOTICE, "no local.id configured - skipping local domains configuration");
300  return;
301  }
302  for(i = 0; i < elem->nvalues; i++) {
303  host_t host = (host_t) pmalloco(xhash_pool(c2s->hosts), sizeof(struct host_st));
304  if(!host) {
305  log_write(c2s->log, LOG_ERR, "cannot allocate memory for new host, aborting");
306  exit(1);
307  }
308 
309  realm = j_attr((const char **) elem->attrs[i], "realm");
310 
311  /* stringprep ids (domain names) so that they are in canonical form */
312  strncpy(id, elem->values[i], 1024);
313  id[1023] = '\0';
314  if (stringprep_nameprep(id, 1024) != 0) {
315  log_write(c2s->log, LOG_ERR, "cannot stringprep id %s, aborting", id);
316  exit(1);
317  }
318 
319  host->realm = (realm != NULL) ? realm : pstrdup(xhash_pool(c2s->hosts), id);
320 
321  host->host_pemfile = j_attr((const char **) elem->attrs[i], "pemfile");
322 
323  host->host_cachain = j_attr((const char **) elem->attrs[i], "cachain");
324 
325  host->host_verify_mode = j_atoi(j_attr((const char **) elem->attrs[i], "verify-mode"), 0);
326 
327  host->host_private_key_password = j_attr((const char **) elem->attrs[i], "private-key-password");
328 
329 #ifdef HAVE_SSL
330  if(host->host_pemfile != NULL) {
331  if(c2s->sx_ssl == NULL) {
333  if(c2s->sx_ssl == NULL) {
334  log_write(c2s->log, LOG_ERR, "failed to load %s SSL pemfile", host->realm);
335  host->host_pemfile = NULL;
336  }
337  } else {
338  if(sx_ssl_server_addcert(c2s->sx_ssl, host->realm, host->host_pemfile, host->host_cachain, host->host_verify_mode, host->host_private_key_password) != 0) {
339  log_write(c2s->log, LOG_ERR, "failed to load %s SSL pemfile", host->realm);
340  host->host_pemfile = NULL;
341  }
342  }
343  }
344 #endif
345 
346  host->host_require_starttls = (j_attr((const char **) elem->attrs[i], "require-starttls") != NULL);
347 
348  host->ar_register_enable = (j_attr((const char **) elem->attrs[i], "register-enable") != NULL);
349  host->ar_register_oob = j_attr((const char **) elem->attrs[i], "register-oob");
350  if(host->ar_register_enable || host->ar_register_oob) {
351  host->ar_register_instructions = j_attr((const char **) elem->attrs[i], "instructions");
352  if(host->ar_register_instructions == NULL) {
353  if(host->ar_register_oob)
354  host->ar_register_instructions = "Only web based registration is possible with this server.";
355  else
356  host->ar_register_instructions = "Enter a username and password to register with this server.";
357  }
358  } else
359  host->ar_register_password = (j_attr((const char **) elem->attrs[i], "password-change") != NULL);
360 
361  /* check for empty <id/> CDATA - XXX this "1" is VERY config.c dependant !!! */
362  if(! strcmp(id, "1")) {
363  /* remove the realm even if set */
364  host->realm = NULL;
365 
366  /* skip if vHost already configured */
367  if(! c2s->vhost)
368  c2s->vhost = host;
369 
370  /* add meaningful log "id" */
371  strcpy(id, "default vHost");
372  } else {
373  /* insert into vHosts xhash */
374  xhash_put(c2s->hosts, pstrdup(xhash_pool(c2s->hosts), id), host);
375  }
376 
377  log_write(c2s->log, LOG_NOTICE, "[%s] configured; realm=%s, registration %s, using PEM:%s",
378  id, (host->realm != NULL ? host->realm : "no realm set"), (host->ar_register_enable ? "enabled" : "disabled"),
379  (host->host_pemfile ? host->host_pemfile : "Default"));
380  }
381 }
382 
383 static int _c2s_router_connect(c2s_t c2s) {
384  log_write(c2s->log, LOG_NOTICE, "attempting connection to router at %s, port=%d", c2s->router_ip, c2s->router_port);
385 
386  c2s->fd = mio_connect(c2s->mio, c2s->router_port, c2s->router_ip, NULL, c2s_router_mio_callback, (void *) c2s);
387  if(c2s->fd == NULL) {
388  if(errno == ECONNREFUSED)
389  c2s_lost_router = 1;
390  log_write(c2s->log, LOG_NOTICE, "connection attempt to router failed: %s (%d)", MIO_STRERROR(MIO_ERROR), MIO_ERROR);
391  return 1;
392  }
393 
394  c2s->router = sx_new(c2s->sx_env, c2s->fd->fd, c2s_router_sx_callback, (void *) c2s);
395  sx_client_init(c2s->router, 0, NULL, NULL, NULL, "1.0");
396 
397  return 0;
398 }
399 
400 static int _c2s_sx_sasl_callback(int cb, void *arg, void **res, sx_t s, void *cbarg) {
401  c2s_t c2s = (c2s_t) cbarg;
402  const char *my_realm, *mech;
403  sx_sasl_creds_t creds;
404  static char buf[3072];
405  char mechbuf[256];
406  struct jid_st jid;
407  jid_static_buf jid_buf;
408  int i, r;
409  sess_t sess;
410  char skey[44];
411 
412  /* init static jid */
413  jid_static(&jid,&jid_buf);
414 
415  /* retrieve our session */
416  assert(s != NULL);
417  sprintf(skey, "%d", s->tag);
418 
419  /*
420  * Retrieve the session, note that depending on the operation,
421  * session may be null.
422  */
423  sess = xhash_get(c2s->sessions, skey);
424 
425  switch(cb) {
427 
428  if(s->req_to == NULL) /* this shouldn't happen */
429  my_realm = "";
430 
431  else {
432  host_t host;
433  /* get host for request */
434  host = xhash_get(c2s->hosts, s->req_to);
435  if(host == NULL) {
436  log_write(c2s->log, LOG_ERR, "SASL callback for non-existing host: %s", s->req_to);
437  *res = (void *)NULL;
438  return sx_sasl_ret_FAIL;
439  }
440 
441  my_realm = host->realm;
442  if(my_realm == NULL)
443  my_realm = s->req_to;
444  }
445 
446  strncpy(buf, my_realm, 256);
447  *res = (void *)buf;
448 
449  log_debug(ZONE, "sx sasl callback: get realm: realm is '%s'", buf);
450  return sx_sasl_ret_OK;
451  break;
452 
453  case sx_sasl_cb_GET_PASS:
454  assert(sess != NULL);
455  creds = (sx_sasl_creds_t) arg;
456 
457  log_debug(ZONE, "sx sasl callback: get pass (authnid=%s, realm=%s)", creds->authnid, creds->realm);
458 
459  if(c2s->ar->get_password && (c2s->ar->get_password)(
460  c2s->ar, sess, (char *)creds->authnid, (creds->realm != NULL) ? (char *)creds->realm: "", buf) == 0) {
461  *res = buf;
462  return sx_sasl_ret_OK;
463  }
464 
465  return sx_sasl_ret_FAIL;
466 
468  assert(sess != NULL);
469  creds = (sx_sasl_creds_t) arg;
470 
471  log_debug(ZONE, "sx sasl callback: check pass (authnid=%s, realm=%s)", creds->authnid, creds->realm);
472 
473  if(c2s->ar->check_password != NULL) {
474  if ((c2s->ar->check_password)(
475  c2s->ar, sess, (char *)creds->authnid, (creds->realm != NULL) ? (char *)creds->realm : "", (char *)creds->pass) == 0)
476  return sx_sasl_ret_OK;
477  else
478  return sx_sasl_ret_FAIL;
479  }
480 
481  if(c2s->ar->get_password != NULL) {
482  if ((c2s->ar->get_password)(c2s->ar, sess, (char *)creds->authnid, (creds->realm != NULL) ? (char *)creds->realm : "", buf) != 0)
483  return sx_sasl_ret_FAIL;
484 
485  if (strcmp(creds->pass, buf)==0)
486  return sx_sasl_ret_OK;
487  }
488 
489  return sx_sasl_ret_FAIL;
490  break;
491 
493  assert(sess != NULL);
494  creds = (sx_sasl_creds_t) arg;
495 
496  /* we need authzid to validate */
497  if(creds->authzid == NULL || creds->authzid[0] == '\0')
498  return sx_sasl_ret_FAIL;
499 
500  /* authzid must be a valid jid */
501  if(jid_reset(&jid, creds->authzid, -1) == NULL)
502  return sx_sasl_ret_FAIL;
503 
504  /* and have domain == stream to addr */
505  if(!s->req_to || (strcmp(jid.domain, s->req_to) != 0))
506  return sx_sasl_ret_FAIL;
507 
508  /* and have no resource */
509  if(jid.resource[0] != '\0')
510  return sx_sasl_ret_FAIL;
511 
512  /* and user has right to authorize as */
513  if (c2s->ar->user_authz_allowed) {
514  if (c2s->ar->user_authz_allowed(c2s->ar, sess, (char *)creds->authnid, (char *)creds->realm, (char *)creds->authzid))
515  return sx_sasl_ret_OK;
516  } else {
517  if (strcmp(creds->authnid, jid.node) == 0 &&
518  (c2s->ar->user_exists)(c2s->ar, sess, jid.node, jid.domain))
519  return sx_sasl_ret_OK;
520  }
521 
522  return sx_sasl_ret_FAIL;
523 
525  /* generate a jid for SASL ANONYMOUS */
526  jid_reset(&jid, s->req_to, -1);
527 
528  /* make node a random string */
529  jid_random_part(&jid, jid_NODE);
530 
531  strcpy(buf, jid.node);
532 
533  *res = (void *)buf;
534 
535  return sx_sasl_ret_OK;
536  break;
537 
539  mech = (char *)arg;
540 
541  i=0;
542  while(i<sizeof(mechbuf) && mech[i]!='\0') {
543  mechbuf[i]=tolower(mech[i]);
544  i++;
545  }
546  mechbuf[i]='\0';
547 
548  /* Determine if our configuration will let us use this mechanism.
549  * We support different mechanisms for both SSL and normal use */
550 
551  if (strcmp(mechbuf, "digest-md5") == 0) {
552  /* digest-md5 requires that our authreg support get_password */
553  if (c2s->ar->get_password == NULL)
554  return sx_sasl_ret_FAIL;
555  } else if (strcmp(mechbuf, "plain") == 0) {
556  /* plain requires either get_password or check_password */
557  if (c2s->ar->get_password == NULL && c2s->ar->check_password == NULL)
558  return sx_sasl_ret_FAIL;
559  }
560 
561  /* Using SSF is potentially dangerous, as SASL can also set the
562  * SSF of the connection. However, SASL shouldn't do so until after
563  * we've finished mechanism establishment
564  */
565  if (s->ssf>0) {
566  r = snprintf(buf, sizeof(buf), "authreg.ssl-mechanisms.sasl.%s",mechbuf);
567  if (r < -1 || r > sizeof(buf))
568  return sx_sasl_ret_FAIL;
569  if(config_get(c2s->config,buf) != NULL)
570  return sx_sasl_ret_OK;
571  }
572 
573  r = snprintf(buf, sizeof(buf), "authreg.mechanisms.sasl.%s",mechbuf);
574  if (r < -1 || r > sizeof(buf))
575  return sx_sasl_ret_FAIL;
576 
577  /* Work out if our configuration will let us use this mechanism */
578  if(config_get(c2s->config,buf) != NULL)
579  return sx_sasl_ret_OK;
580  else
581  return sx_sasl_ret_FAIL;
582  default:
583  break;
584  }
585 
586  return sx_sasl_ret_FAIL;
587 }
588 static void _c2s_time_checks(c2s_t c2s) {
589  sess_t sess;
590  time_t now;
591  union xhashv xhv;
592 
593  now = time(NULL);
594 
595  if(xhash_iter_first(c2s->sessions))
596  do {
597  xhv.sess_val = &sess;
598  xhash_iter_get(c2s->sessions, NULL, NULL, xhv.val);
599 
600  if(c2s->io_check_idle > 0 && sess->s && now > sess->last_activity + c2s->io_check_idle) {
601  log_write(c2s->log, LOG_NOTICE, "[%d] [%s, port=%d] timed out", sess->fd->fd, sess->ip, sess->port);
602 
603  sx_error(sess->s, stream_err_HOST_GONE, "connection timed out");
604  sx_close(sess->s);
605 
606  continue;
607  }
608 
609  if(c2s->io_check_keepalive > 0 && now > sess->last_activity + c2s->io_check_keepalive && sess->s->state >= state_STREAM) {
610  log_debug(ZONE, "sending keepalive for %d", sess->fd->fd);
611 
612  sx_raw_write(sess->s, " ", 1);
613  }
614 
615  if(sess->rate != NULL && sess->rate->bad != 0 && rate_check(sess->rate) != 0) {
616  /* read the pending bytes when rate limit is no longer in effect */
617  log_debug(ZONE, "reading throttled %d", sess->fd->fd);
618  sess->s->want_read = 1;
619  sx_can_read(sess->s);
620  }
621 
622  } while(xhash_iter_next(c2s->sessions));
623 }
624 
625 JABBER_MAIN("jabberd2c2s", "Jabber 2 C2S", "Jabber Open Source Server: Client to Server", "jabberd2router\0")
626 {
627  c2s_t c2s;
628  char *config_file;
629  int optchar;
630  int mio_timeout;
631  sess_t sess;
632  bres_t res;
633  union xhashv xhv;
634  time_t check_time = 0;
635  const char *cli_id = 0;
636 
637 #ifdef HAVE_UMASK
638  umask((mode_t) 0027);
639 #endif
640 
641  srand(time(NULL));
642 
643 #ifdef HAVE_WINSOCK2_H
644 /* get winsock running */
645  {
646  WORD wVersionRequested;
647  WSADATA wsaData;
648  int err;
649 
650  wVersionRequested = MAKEWORD( 2, 2 );
651 
652  err = WSAStartup( wVersionRequested, &wsaData );
653  if ( err != 0 ) {
654  /* !!! tell user that we couldn't find a usable winsock dll */
655  return 0;
656  }
657  }
658 #endif
659 
660  jabber_signal(SIGINT, _c2s_signal);
661  jabber_signal(SIGTERM, _c2s_signal);
662 #ifdef SIGHUP
664 #endif
665 #ifdef SIGPIPE
666  jabber_signal(SIGPIPE, SIG_IGN);
667 #endif
670 
671 
672  c2s = (c2s_t) calloc(1, sizeof(struct c2s_st));
673 
674  /* load our config */
675  c2s->config = config_new();
676 
677  config_file = CONFIG_DIR "/c2s.xml";
678 
679  /* cmdline parsing */
680  while((optchar = getopt(argc, argv, "Dc:hi:?")) >= 0)
681  {
682  switch(optchar)
683  {
684  case 'c':
685  config_file = optarg;
686  break;
687  case 'D':
688 #ifdef DEBUG
689  set_debug_flag(1);
690 #else
691  printf("WARN: Debugging not enabled. Ignoring -D.\n");
692 #endif
693  break;
694  case 'i':
695  cli_id = optarg;
696  break;
697  case 'h': case '?': default:
698  fputs(
699  "c2s - jabberd client-to-server connector (" VERSION ")\n"
700  "Usage: c2s <options>\n"
701  "Options are:\n"
702  " -c <config> config file to use [default: " CONFIG_DIR "/c2s.xml]\n"
703  " -i id Override <id> config element\n"
704 #ifdef DEBUG
705  " -D Show debug output\n"
706 #endif
707  ,
708  stdout);
709  config_free(c2s->config);
710  free(c2s);
711  return 1;
712  }
713  }
714 
715  if(config_load_with_id(c2s->config, config_file, cli_id) != 0)
716  {
717  fputs("c2s: couldn't load config, aborting\n", stderr);
718  config_free(c2s->config);
719  free(c2s);
720  return 2;
721  }
722 
723  c2s->stream_redirects = xhash_new(523);
724 
725  _c2s_config_expand(c2s);
726 
727  c2s->log = log_new(c2s->log_type, c2s->log_ident, c2s->log_facility);
728  log_write(c2s->log, LOG_NOTICE, "starting up");
729 
730  _c2s_pidfile(c2s);
731 
732  if(c2s->ar_module_name == NULL) {
733  log_write(c2s->log, LOG_NOTICE, "no authreg module specified in config file");
734  }
735  else if((c2s->ar = authreg_init(c2s, c2s->ar_module_name)) == NULL) {
736  access_free(c2s->access);
737  config_free(c2s->config);
738  log_free(c2s->log);
739  free(c2s);
740  exit(1);
741  }
742 
743  c2s->sessions = xhash_new(1023);
744 
745  c2s->conn_rates = xhash_new(101);
746 
747  c2s->dead = jqueue_new();
748 
749  c2s->dead_sess = jqueue_new();
750 
751  c2s->sx_env = sx_env_new();
752 
753 #ifdef HAVE_SSL
754  /* get the ssl context up and running */
755  if(c2s->local_pemfile != NULL) {
757  if(c2s->sx_ssl == NULL) {
758  log_write(c2s->log, LOG_ERR, "failed to load local SSL pemfile, SSL will not be available to clients");
759  c2s->local_pemfile = NULL;
760  }
761  }
762 
763  /* try and get something online, so at least we can encrypt to the router */
764  if(c2s->sx_ssl == NULL && c2s->router_pemfile != NULL) {
766  if(c2s->sx_ssl == NULL) {
767  log_write(c2s->log, LOG_ERR, "failed to load router SSL pemfile, channel to router will not be SSL encrypted");
768  c2s->router_pemfile = NULL;
769  }
770  }
771 #endif
772 
773 #ifdef HAVE_LIBZ
774  /* get compression up and running */
775  if(c2s->compression)
777 #endif
778 
779  /* get stanza ack up */
781 
782  /* and user IP address plugin */
784 
785  /* get sasl online */
786  c2s->sx_sasl = sx_env_plugin(c2s->sx_env, sx_sasl_init, "xmpp", _c2s_sx_sasl_callback, (void *) c2s);
787  if(c2s->sx_sasl == NULL) {
788  log_write(c2s->log, LOG_ERR, "failed to initialise SASL context, aborting");
789  exit(1);
790  }
791 
792  /* get bind up */
793  sx_env_plugin(c2s->sx_env, bind_init, c2s);
794 
795  c2s->mio = mio_new(c2s->io_max_fds);
796  if(c2s->mio == NULL) {
797  log_write(c2s->log, LOG_ERR, "failed to create MIO, aborting");
798  exit(1);
799  }
800 
801  /* hosts mapping */
802  c2s->hosts = xhash_new(1021);
803  _c2s_hosts_expand(c2s);
804  c2s->sm_avail = xhash_new(1021);
805 
806  c2s->retry_left = c2s->retry_init;
807  _c2s_router_connect(c2s);
808 
809  mio_timeout = ((c2s->io_check_interval != 0 && c2s->io_check_interval < 5) ?
810  c2s->io_check_interval : 5);
811 
812  while(!c2s_shutdown) {
813  mio_run(c2s->mio, mio_timeout);
814 
815  if(c2s_logrotate) {
817 
818  log_write(c2s->log, LOG_NOTICE, "reopening log ...");
819  log_free(c2s->log);
820  c2s->log = log_new(c2s->log_type, c2s->log_ident, c2s->log_facility);
821  log_write(c2s->log, LOG_NOTICE, "log started");
822 
823  c2s_logrotate = 0;
824  }
825 
826  if(c2s_sighup) {
827  log_write(c2s->log, LOG_NOTICE, "reloading some configuration items ...");
828  config_t conf;
829  conf = config_new();
830  if (conf && config_load(conf, config_file) == 0) {
832  c2s->stream_redirects = xhash_new(523);
833 
834  char *req_domain, *to_address, *to_port;
835  config_elem_t elem;
836  int i;
838 
839  elem = config_get(conf, "stream_redirect.redirect");
840  if(elem != NULL)
841  {
842  for(i = 0; i < elem->nvalues; i++)
843  {
845  if(!sr) {
846  log_write(c2s->log, LOG_ERR, "cannot allocate memory for new stream redirection record, aborting");
847  exit(1);
848  }
849  req_domain = j_attr((const char **) elem->attrs[i], "requested_domain");
850  to_address = j_attr((const char **) elem->attrs[i], "to_address");
851  to_port = j_attr((const char **) elem->attrs[i], "to_port");
852 
853  if(req_domain == NULL || to_address == NULL || to_port == NULL) {
854  log_write(c2s->log, LOG_ERR, "Error reading a stream_redirect.redirect element from file, skipping");
855  continue;
856  }
857 
858  // Note that to_address should be RFC 3986 compliant
859  sr->to_address = to_address;
860  sr->to_port = to_port;
861 
862  xhash_put(c2s->stream_redirects, pstrdup(xhash_pool(c2s->stream_redirects), req_domain), sr);
863  }
864  }
865  config_free(conf);
866  } else {
867  log_write(c2s->log, LOG_WARNING, "couldn't reload config (%s)", config_file);
868  if (conf) config_free(conf);
869  }
870  c2s_sighup = 0;
871  }
872 
873  if(c2s_lost_router) {
874  if(c2s->retry_left < 0) {
875  log_write(c2s->log, LOG_NOTICE, "attempting reconnect");
876  sleep(c2s->retry_sleep);
877  c2s_lost_router = 0;
878  if (c2s->router) sx_free(c2s->router);
879  _c2s_router_connect(c2s);
880  }
881 
882  else if(c2s->retry_left == 0) {
883  c2s_shutdown = 1;
884  }
885 
886  else {
887  log_write(c2s->log, LOG_NOTICE, "attempting reconnect (%d left)", c2s->retry_left);
888  c2s->retry_left--;
889  sleep(c2s->retry_sleep);
890  c2s_lost_router = 0;
891  if (c2s->router) sx_free(c2s->router);
892  _c2s_router_connect(c2s);
893  }
894  }
895 
896  /* cleanup dead sess (before sx_t as sess->result uses sx_t nad cache) */
897  while(jqueue_size(c2s->dead_sess) > 0) {
898  sess = (sess_t) jqueue_pull(c2s->dead_sess);
899 
900  /* free sess data */
901  if(sess->ip != NULL) free((void*)sess->ip);
902  if(sess->smcomp != NULL) free((void*)sess->smcomp);
903  if(sess->result != NULL) nad_free(sess->result);
904  if(sess->resources != NULL)
905  for(res = sess->resources; res != NULL;) {
906  bres_t tmp = res->next;
907  jid_free(res->jid);
908  free(res);
909  res = tmp;
910  }
911  if(sess->rate != NULL) rate_free(sess->rate);
912  if(sess->stanza_rate != NULL) rate_free(sess->stanza_rate);
913 
914  free(sess);
915  }
916 
917  /* cleanup dead sx_ts */
918  while(jqueue_size(c2s->dead) > 0)
919  sx_free((sx_t) jqueue_pull(c2s->dead));
920 
921  /* time checks */
922  if(c2s->io_check_interval > 0 && time(NULL) >= c2s->next_check) {
923  log_debug(ZONE, "running time checks");
924 
925  _c2s_time_checks(c2s);
926 
927  c2s->next_check = time(NULL) + c2s->io_check_interval;
928  log_debug(ZONE, "next time check at %d", c2s->next_check);
929  }
930 
931  if(time(NULL) > check_time + 60) {
932 #ifdef POOL_DEBUG
933  pool_stat(1);
934 #endif
935  if(c2s->packet_stats != NULL) {
936  int fd = open(c2s->packet_stats, O_TRUNC | O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP);
937  if (fd >= 0) {
938  char buf[100];
939  int len = snprintf(buf, 100, "%lld\n", c2s->packet_count);
940  if (write(fd, buf, len) != len) {
941  close(fd);
942  fd = -1;
943  } else close(fd);
944  }
945  if (fd < 0) {
946  log_write(c2s->log, LOG_ERR, "failed to write packet statistics to: %s", c2s->packet_stats);
947  c2s_shutdown = 1;
948  }
949  }
950 
951  check_time = time(NULL);
952  }
953  }
954 
955  log_write(c2s->log, LOG_NOTICE, "shutting down");
956 
957  if(xhash_iter_first(c2s->sessions))
958  do {
959  xhv.sess_val = &sess;
960  xhash_iter_get(c2s->sessions, NULL, NULL, xhv.val);
961 
962  if(sess->active && sess->s)
963  sx_close(sess->s);
964 
965  } while(xhash_iter_next(c2s->sessions));
966 
967  /* cleanup dead sess */
968  while(jqueue_size(c2s->dead_sess) > 0) {
969  sess = (sess_t) jqueue_pull(c2s->dead_sess);
970 
971  /* free sess data */
972  if(sess->ip != NULL) free((void*)sess->ip);
973  if(sess->result != NULL) nad_free(sess->result);
974  if(sess->resources != NULL)
975  for(res = sess->resources; res != NULL;) {
976  bres_t tmp = res->next;
977  jid_free(res->jid);
978  free(res);
979  res = tmp;
980  }
981 
982  free(sess);
983  }
984 
985  while(jqueue_size(c2s->dead) > 0)
986  sx_free((sx_t) jqueue_pull(c2s->dead));
987 
988  if (c2s->fd != NULL) mio_close(c2s->mio, c2s->fd);
989  sx_free(c2s->router);
990 
991  sx_env_free(c2s->sx_env);
992 
993  mio_free(c2s->mio);
994 
995  xhash_free(c2s->sessions);
996 
997  authreg_free(c2s->ar);
998 
999  xhash_free(c2s->conn_rates);
1000 
1002 
1003  xhash_free(c2s->sm_avail);
1004 
1005  xhash_free(c2s->hosts);
1006 
1007  jqueue_free(c2s->dead);
1008 
1009  jqueue_free(c2s->dead_sess);
1010 
1011  access_free(c2s->access);
1012 
1013  log_free(c2s->log);
1014 
1015  config_free(c2s->config);
1016 
1017  free(c2s);
1018 
1019 #ifdef POOL_DEBUG
1020  pool_stat(1);
1021 #endif
1022 
1023 #ifdef HAVE_WINSOCK2_H
1024  WSACleanup();
1025 #endif
1026 
1027  return 0;
1028 }
int(* check_password)(authreg_t ar, sess_t sess, const char *username, const char *realm, char password[257])
check the given password against the stored password, 0 if equal, !0 if not equal (password auth) ...
Definition: c2s.h:334
int address_init(sx_env_t env, sx_plugin_t p, va_list args)
args: none
Definition: address.c:42
bres_t resources
Definition: c2s.h:103
int io_check_interval
time checks
Definition: c2s.h:245
struct sess_st * sess_t
Definition: c2s.h:55
int sx_ssl_server_addcert(sx_plugin_t p, const char *name, const char *pemfile, const char *cachain, int mode, const char *password)
args: name, pemfile, cachain, mode
Definition: ssl.c:987
jid_t jid_reset(jid_t jid, const char *id, int len)
build a jid from an id
Definition: jid.c:113
#define sx_sasl_cb_CHECK_MECH
Definition: plugins.h:114
static void _c2s_signal_hup(int signum)
Definition: main.c:36
struct stream_redirect_st * stream_redirect_t
const char ** values
Definition: util.h:209
const char * log_facility
Definition: c2s.h:193
config_t config
config
Definition: c2s.h:186
_sx_state_t state
Definition: sx.h:313
int access_deny(access_t access, const char *ip, const char *mask)
Definition: access.c:183
int config_load_with_id(config_t c, const char *file, const char *id)
turn an xml file into a config hash
Definition: config.c:80
mio_fd_t fd
Definition: c2s.h:77
struct host_st * host_t
Definition: c2s.h:52
static int _c2s_sx_sasl_callback(int cb, void *arg, void **res, sx_t s, void *cbarg)
Definition: main.c:400
const char * http_forward
http forwarding URL
Definition: c2s.h:228
void xhash_free(xht h)
Definition: xhash.c:241
static void _c2s_pidfile(c2s_t c2s)
store the process id
Definition: main.c:53
int ar_register_enable
registration
Definition: c2s.h:144
int sx_ack_init(sx_env_t env, sx_plugin_t p, va_list args)
args: none
Definition: ack.c:103
const char * req_to
Definition: sx.h:280
void config_free(config_t c)
cleanup
Definition: config.c:410
access_t access
access controls
Definition: c2s.h:280
int(* get_password)(authreg_t ar, sess_t sess, const char *username, const char *realm, char password[257])
return this users cleartext password in the array (digest auth, password auth)
Definition: c2s.h:331
mio_t mio_new(int maxfd)
create/free the mio subsytem
Definition: mio.c:38
access_t access_new(int order)
Definition: access.c:25
#define sx_sasl_ret_FAIL
Definition: plugins.h:118
#define mio_run(m, timeout)
give some cpu time to mio to check it's sockets, 0 is non-blocking
Definition: mio.h:164
void jid_static(jid_t jid, jid_static_buf *buf)
Make jid to use static buffer (jid data won't be allocated dynamically, but given buffer will be alwa...
Definition: jid.c:102
int jqueue_size(jqueue_t q)
Definition: jqueue.c:126
xht conn_rates
Definition: c2s.h:264
int(* user_exists)(authreg_t ar, sess_t sess, const char *username, const char *realm)
returns 1 if the user exists, 0 if not
Definition: c2s.h:328
int compression
enable Stream Compression
Definition: c2s.h:242
void log_write(log_t log, int level, const char *msgfmt,...)
Definition: log.c:104
int retry_left
Definition: c2s.h:204
int conn_rate_seconds
Definition: c2s.h:261
static void _c2s_time_checks(c2s_t c2s)
Definition: main.c:588
#define AR_MECH_TRAD_DIGEST
Definition: c2s.h:121
sx_t sx_new(sx_env_t env, int tag, sx_callback_t cb, void *arg)
Definition: sx.c:23
config_t config_new(void)
new config structure
Definition: config.c:25
#define MIO_STRERROR(e)
Definition: mio.h:170
const char * log_ident
Definition: c2s.h:194
int tag
Definition: sx.h:256
#define mio_free(m)
Definition: mio.h:137
list of resources bound to session
Definition: c2s.h:59
int io_max_fds
max file descriptors
Definition: c2s.h:239
static char * config_file
Definition: main.c:34
char * host_private_key_password
private key password
Definition: c2s.h:135
int io_check_keepalive
Definition: c2s.h:247
nad_t result
Definition: c2s.h:108
int ar_mechanisms
allowed mechanisms
Definition: c2s.h:256
holder for the config hash and nad
Definition: util.h:200
time_t next_check
Definition: c2s.h:249
static void _c2s_config_expand(c2s_t c2s)
pull values out of the config file
Definition: main.c:80
void sx_raw_write(sx_t s, const char *buf, int len)
app version
Definition: io.c:454
const char * id
our id (hostname) with the router
Definition: c2s.h:153
int j_atoi(const char *a, int def)
Definition: str.c:87
char * resource
Definition: jid.h:46
int host_verify_mode
verify-mode
Definition: c2s.h:138
int bind_init(sx_env_t env, sx_plugin_t p, va_list args)
plugin initialiser
Definition: bind.c:69
void nad_free(nad_t nad)
free that nad
Definition: nad.c:178
int stanza_size_limit
maximum stanza size
Definition: c2s.h:277
void log_free(log_t log)
Definition: log.c:174
int xhash_iter_next(xht h)
Definition: xhash.c:320
void jid_random_part(jid_t jid, jid_part_t part)
create random resource
Definition: jid.c:492
static void _c2s_signal(int signum)
Definition: main.c:30
sx_env_t sx_env_new(void)
Definition: env.c:23
#define mio_connect(m, port, hostip, srcip, app, arg)
for creating a new socket connected to this ip:port (returns new fd or <0, use mio_read/write first) ...
Definition: mio.h:144
#define AR_MECH_TRAD_CRAMMD5
Definition: c2s.h:122
sx_t router
router's conn
Definition: c2s.h:176
jid_t jid
full bound jid
Definition: c2s.h:61
time_t last_activity
Definition: c2s.h:97
const char * authnid
Definition: plugins.h:125
authreg_t ar
Definition: c2s.h:253
#define AR_MECH_TRAD_PLAIN
Definition: c2s.h:120
void rate_free(rate_t rt)
Definition: rate.c:36
const char * router_pemfile
Definition: c2s.h:160
sx_t s
Definition: c2s.h:86
#define sx_sasl_ret_OK
Definition: plugins.h:117
char * config_get_attr(config_t c, const char *key, int num, const char *attr)
get an attr for this value
Definition: config.c:314
const char * ip
Definition: c2s.h:83
void jqueue_free(jqueue_t q)
Definition: jqueue.c:38
const char * router_cachain
Definition: c2s.h:161
static void _c2s_signal_usr2(int signum)
Definition: main.c:47
const char * router_ip
how to connect to the router
Definition: c2s.h:156
static void _c2s_signal_usr1(int signum)
Definition: main.c:42
const char * local_ip
ip to listen on
Definition: c2s.h:207
void access_free(access_t access)
Definition: access.c:34
Definition: log.h:42
#define MIO_ERROR
all MIO related routines should use those for error reporting
Definition: mio.h:168
int(* user_authz_allowed)(authreg_t ar, sess_t sess, const char *username, const char *realm, const char *requested_user)
returns 1 if the user is permitted to authorize as the requested_user, 0 if not.
Definition: c2s.h:352
const char * router_private_key_password
Definition: c2s.h:162
int router_port
Definition: c2s.h:157
int sx_can_read(sx_t s)
we can read
Definition: io.c:181
#define sx_sasl_cb_CHECK_AUTHZID
Definition: plugins.h:112
sx_plugin_t sx_ssl
Definition: c2s.h:172
mio_t mio
mio context
Definition: c2s.h:165
sx_plugin_t sx_env_plugin(sx_env_t env, sx_plugin_init_t init,...)
load a plugin into the environment
Definition: env.c:48
holds the state for a single stream
Definition: sx.h:251
int retry_sleep
Definition: c2s.h:203
const char * ar_register_instructions
Definition: c2s.h:145
int stanza_rate_wait
Definition: c2s.h:274
int port
Definition: c2s.h:84
const char * to_address
Definition: c2s.h:392
char jid_static_buf[3 *1025]
JID static buffer.
Definition: jid.h:77
void ** val
Definition: c2s.h:384
time_t bad
Definition: util.h:267
const char * smcomp
Definition: c2s.h:81
void * pmalloco(pool_t p, int size)
easy safety utility (for creating blank mem for structs, etc)
Definition: pool.c:183
void sx_client_init(sx_t s, unsigned int flags, const char *ns, const char *to, const char *from, const char *version)
Definition: client.c:111
struct c2s_st * c2s_t
Definition: c2s.h:53
Definition: jid.h:71
int io_check_idle
Definition: c2s.h:246
const char * router_pass
Definition: c2s.h:159
void set_debug_log_from_config(config_t c)
Definition: log.c:267
void jid_free(jid_t jid)
free a jid
Definition: jid.c:286
const char * realm
our realm (SASL)
Definition: c2s.h:126
void pool_stat(int full)
Definition: pool.c:285
void xhash_put(xht h, const char *key, void *val)
Definition: xhash.c:163
int ar_register_password
Definition: c2s.h:147
sess_t * sess_val
Definition: c2s.h:386
struct sx_sasl_creds_st * sx_sasl_creds_t
char * domain
Definition: jid.h:45
int local_verify_mode
verify-mode
Definition: c2s.h:225
Definition: jid.h:42
int byte_rate_seconds
Definition: c2s.h:268
int local_port
unencrypted port
Definition: c2s.h:210
Definition: c2s.h:124
#define stream_err_HOST_GONE
Definition: sx.h:128
xht hosts
hosts mapping
Definition: c2s.h:295
int xhash_iter_get(xht h, const char **key, int *keylen, void **val)
Definition: xhash.c:374
void sx_free(sx_t s)
Definition: sx.c:70
const char * host_pemfile
starttls pemfile
Definition: c2s.h:129
int conn_rate_total
connection rates
Definition: c2s.h:260
int c2s_router_sx_callback(sx_t s, sx_event_t e, void *data, void *arg)
Definition: c2s.c:711
void sx_close(sx_t s)
Definition: io.c:480
const char * authzid
Definition: plugins.h:127
JABBER_MAIN("jabberd2c2s","Jabber 2 C2S","Jabber Open Source Server: Client to Server","jabberd2router\0")
Definition: main.c:625
int byte_rate_wait
Definition: c2s.h:269
#define log_debug(...)
Definition: log.h:65
jsighandler_t * jabber_signal(int signo, jsighandler_t *func)
Definition: jsignal.c:33
sx_env_t sx_env
sx environment
Definition: c2s.h:171
int retry_init
connect retry
Definition: c2s.h:201
static int _c2s_router_connect(c2s_t c2s)
Definition: main.c:383
int rate_check(rate_t rt)
Definition: rate.c:78
const char * realm
Definition: plugins.h:126
int stanza_rate_seconds
Definition: c2s.h:273
xht sm_avail
availability of sms that we are servicing
Definition: c2s.h:299
Definition: c2s.h:151
host_t vhost
Definition: c2s.h:296
void sx_error(sx_t s, int err, const char *text)
Definition: error.c:88
xht stream_redirects
stream redirection (see-other-host) on session connect
Definition: c2s.h:236
int conn_rate_wait
Definition: c2s.h:262
JABBERD2_API int sx_sasl_init(sx_env_t env, sx_plugin_t p, va_list args)
init function
Definition: sasl.c:855
log_type_t log_type
log data
Definition: c2s.h:192
config_elem_t config_get(config_t c, const char *key)
get the config element for this key
Definition: config.c:271
int retry_lost
Definition: c2s.h:202
jqueue_t dead_sess
list of sess on the way out
Definition: c2s.h:286
#define sx_sasl_cb_GET_REALM
Definition: plugins.h:109
There is one instance of this struct per user who is logged in to this c2s instance.
Definition: c2s.h:74
int ssf
Definition: sx.h:337
void * jqueue_pull(jqueue_t q)
Definition: jqueue.c:96
mio_fd_t fd
Definition: c2s.h:177
int xhash_iter_first(xht h)
iteration
Definition: xhash.c:311
const char * to_port
Definition: c2s.h:393
int fd
Definition: mio.h:102
jqueue_t jqueue_new(void)
Definition: jqueue.c:25
long long int packet_count
packet counter
Definition: c2s.h:197
void set_debug_flag(int v)
Definition: log.c:264
int sx_ssl_init(sx_env_t env, sx_plugin_t p, va_list args)
args: name, pemfile, cachain, mode
Definition: ssl.c:833
int config_load(config_t c, const char *file)
turn an xml file into a config hash
Definition: config.c:74
xht sessions
sessions
Definition: c2s.h:168
int access_allow(access_t access, const char *ip, const char *mask)
Definition: access.c:163
const char *** attrs
Definition: util.h:211
rate_t rate
Definition: c2s.h:91
int sx_compress_init(sx_env_t env, sx_plugin_t p, va_list args)
args: none
Definition: compress.c:331
static sig_atomic_t c2s_shutdown
Definition: main.c:25
pool_t xhash_pool(xht h)
get our pool
Definition: xhash.c:305
const char * packet_stats
Definition: c2s.h:198
static sig_atomic_t c2s_logrotate
Definition: main.c:27
const char * ar_module_name
auth/reg module
Definition: c2s.h:252
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
rate_t stanza_rate
Definition: c2s.h:94
Definition: log.h:43
int local_ssl_port
encrypted port
Definition: c2s.h:213
Definition: log.h:44
void * xhash_get(xht h, const char *key)
Definition: xhash.c:184
#define mio_close(m, fd)
request that mio close this fd
Definition: mio.h:155
char * j_attr(const char **atts, const char *attr)
Definition: str.c:95
sx_plugin_t sx_sasl
Definition: c2s.h:173
void authreg_free(authreg_t ar)
shutdown the authreg system
Definition: authreg.c:116
log_t log_new(log_type_t type, const char *ident, const char *facility)
Definition: log.c:69
#define ZONE
Definition: mio_impl.h:76
int want_read
Definition: sx.h:304
session packet handling
Definition: c2s.h:382
const char * config_get_one(config_t c, const char *key, int num)
get config value n for this key
Definition: config.c:277
xht xhash_new(int prime)
Definition: xhash.c:96
const char * ar_register_oob
Definition: c2s.h:146
#define sx_sasl_cb_GEN_AUTHZID
Definition: plugins.h:113
jqueue_t dead
list of sx_t on the way out
Definition: c2s.h:283
const char * pass
Definition: plugins.h:128
log_t log
logging
Definition: c2s.h:189
const char * pbx_pipe
PBX integration named pipe.
Definition: c2s.h:231
void sx_env_free(sx_env_t env)
Definition: env.c:31
a single element
Definition: util.h:207
const char * router_user
Definition: c2s.h:158
int host_require_starttls
require starttls
Definition: c2s.h:141
authreg_t authreg_init(c2s_t c2s, const char *name)
get a handle for the named module
Definition: authreg.c:40
const char * local_private_key_password
private key password
Definition: c2s.h:222
sig_atomic_t c2s_lost_router
Definition: main.c:26
int ar_ssl_mechanisms
Definition: c2s.h:257
#define sx_sasl_cb_CHECK_PASS
Definition: plugins.h:111
int active
Definition: c2s.h:105
static sig_atomic_t c2s_sighup
Definition: main.c:28
int nvalues
Definition: util.h:210
char * node
Definition: jid.h:44
int c2s_router_mio_callback(mio_t m, mio_action_t a, mio_fd_t fd, void *data, void *arg)
Definition: c2s.c:1376
int stanza_rate_total
stanza rates
Definition: c2s.h:272
const char * local_pemfile
encrypted port pemfile
Definition: c2s.h:216
const char * local_cachain
encrypted port cachain file
Definition: c2s.h:219
static void _c2s_hosts_expand(c2s_t c2s)
Definition: main.c:290
#define sx_sasl_cb_GET_PASS
Definition: plugins.h:110
bres_t next
Definition: c2s.h:67
const char * host_cachain
certificate chain
Definition: c2s.h:132
int byte_rate_total
byte rates (karma)
Definition: c2s.h:267