jabberd2  2.3.1
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 
410  /* init static jid */
411  jid_static(&jid,&jid_buf);
412 
413  switch(cb) {
415 
416  if(s->req_to == NULL) /* this shouldn't happen */
417  my_realm = "";
418 
419  else {
420  host_t host;
421  /* get host for request */
422  host = xhash_get(c2s->hosts, s->req_to);
423  if(host == NULL) {
424  log_write(c2s->log, LOG_ERR, "SASL callback for non-existing host: %s", s->req_to);
425  *res = (void *)NULL;
426  return sx_sasl_ret_FAIL;
427  }
428 
429  my_realm = host->realm;
430  if(my_realm == NULL)
431  my_realm = s->req_to;
432  }
433 
434  strncpy(buf, my_realm, 256);
435  *res = (void *)buf;
436 
437  log_debug(ZONE, "sx sasl callback: get realm: realm is '%s'", buf);
438  return sx_sasl_ret_OK;
439  break;
440 
441  case sx_sasl_cb_GET_PASS:
442  creds = (sx_sasl_creds_t) arg;
443 
444  log_debug(ZONE, "sx sasl callback: get pass (authnid=%s, realm=%s)", creds->authnid, creds->realm);
445 
446  if(c2s->ar->get_password && (c2s->ar->get_password)(c2s->ar, (char *)creds->authnid, (creds->realm != NULL) ? (char *)creds->realm: "", buf) == 0) {
447  *res = buf;
448  return sx_sasl_ret_OK;
449  }
450 
451  return sx_sasl_ret_FAIL;
452 
454  creds = (sx_sasl_creds_t) arg;
455 
456  log_debug(ZONE, "sx sasl callback: check pass (authnid=%s, realm=%s)", creds->authnid, creds->realm);
457 
458  if(c2s->ar->check_password != NULL) {
459  if ((c2s->ar->check_password)(c2s->ar, (char *)creds->authnid, (creds->realm != NULL) ? (char *)creds->realm : "", (char *)creds->pass) == 0)
460  return sx_sasl_ret_OK;
461  else
462  return sx_sasl_ret_FAIL;
463  }
464 
465  if(c2s->ar->get_password != NULL) {
466  if ((c2s->ar->get_password)(c2s->ar, (char *)creds->authnid, (creds->realm != NULL) ? (char *)creds->realm : "", buf) != 0)
467  return sx_sasl_ret_FAIL;
468 
469  if (strcmp(creds->pass, buf)==0)
470  return sx_sasl_ret_OK;
471  }
472 
473  return sx_sasl_ret_FAIL;
474  break;
475 
477  creds = (sx_sasl_creds_t) arg;
478 
479  /* we need authzid to validate */
480  if(creds->authzid == NULL || creds->authzid[0] == '\0')
481  return sx_sasl_ret_FAIL;
482 
483  /* authzid must be a valid jid */
484  if(jid_reset(&jid, creds->authzid, -1) == NULL)
485  return sx_sasl_ret_FAIL;
486 
487  /* and have domain == stream to addr */
488  if(!s->req_to || (strcmp(jid.domain, s->req_to) != 0))
489  return sx_sasl_ret_FAIL;
490 
491  /* and have no resource */
492  if(jid.resource[0] != '\0')
493  return sx_sasl_ret_FAIL;
494 
495  /* and user has right to authorize as */
496  if (c2s->ar->user_authz_allowed) {
497  if (c2s->ar->user_authz_allowed(c2s->ar, (char *)creds->authnid, (char *)creds->realm, (char *)creds->authzid))
498  return sx_sasl_ret_OK;
499  } else {
500  if (strcmp(creds->authnid, jid.node) == 0 &&
501  (c2s->ar->user_exists)(c2s->ar, jid.node, jid.domain))
502  return sx_sasl_ret_OK;
503  }
504 
505  return sx_sasl_ret_FAIL;
506 
508  /* generate a jid for SASL ANONYMOUS */
509  jid_reset(&jid, s->req_to, -1);
510 
511  /* make node a random string */
512  jid_random_part(&jid, jid_NODE);
513 
514  strcpy(buf, jid.node);
515 
516  *res = (void *)buf;
517 
518  return sx_sasl_ret_OK;
519  break;
520 
522  mech = (char *)arg;
523 
524  i=0;
525  while(i<sizeof(mechbuf) && mech[i]!='\0') {
526  mechbuf[i]=tolower(mech[i]);
527  i++;
528  }
529  mechbuf[i]='\0';
530 
531  /* Determine if our configuration will let us use this mechanism.
532  * We support different mechanisms for both SSL and normal use */
533 
534  if (strcmp(mechbuf, "digest-md5") == 0) {
535  /* digest-md5 requires that our authreg support get_password */
536  if (c2s->ar->get_password == NULL)
537  return sx_sasl_ret_FAIL;
538  } else if (strcmp(mechbuf, "plain") == 0) {
539  /* plain requires either get_password or check_password */
540  if (c2s->ar->get_password == NULL && c2s->ar->check_password == NULL)
541  return sx_sasl_ret_FAIL;
542  }
543 
544  /* Using SSF is potentially dangerous, as SASL can also set the
545  * SSF of the connection. However, SASL shouldn't do so until after
546  * we've finished mechanism establishment
547  */
548  if (s->ssf>0) {
549  r = snprintf(buf, sizeof(buf), "authreg.ssl-mechanisms.sasl.%s",mechbuf);
550  if (r < -1 || r > sizeof(buf))
551  return sx_sasl_ret_FAIL;
552  if(config_get(c2s->config,buf) != NULL)
553  return sx_sasl_ret_OK;
554  }
555 
556  r = snprintf(buf, sizeof(buf), "authreg.mechanisms.sasl.%s",mechbuf);
557  if (r < -1 || r > sizeof(buf))
558  return sx_sasl_ret_FAIL;
559 
560  /* Work out if our configuration will let us use this mechanism */
561  if(config_get(c2s->config,buf) != NULL)
562  return sx_sasl_ret_OK;
563  else
564  return sx_sasl_ret_FAIL;
565  default:
566  break;
567  }
568 
569  return sx_sasl_ret_FAIL;
570 }
571 static void _c2s_time_checks(c2s_t c2s) {
572  sess_t sess;
573  time_t now;
574  union xhashv xhv;
575 
576  now = time(NULL);
577 
578  if(xhash_iter_first(c2s->sessions))
579  do {
580  xhv.sess_val = &sess;
581  xhash_iter_get(c2s->sessions, NULL, NULL, xhv.val);
582 
583  if(c2s->io_check_idle > 0 && sess->s && now > sess->last_activity + c2s->io_check_idle) {
584  log_write(c2s->log, LOG_NOTICE, "[%d] [%s, port=%d] timed out", sess->fd->fd, sess->ip, sess->port);
585 
586  sx_error(sess->s, stream_err_HOST_GONE, "connection timed out");
587  sx_close(sess->s);
588 
589  continue;
590  }
591 
592  if(c2s->io_check_keepalive > 0 && now > sess->last_activity + c2s->io_check_keepalive && sess->s->state >= state_STREAM) {
593  log_debug(ZONE, "sending keepalive for %d", sess->fd->fd);
594 
595  sx_raw_write(sess->s, " ", 1);
596  }
597 
598  if(sess->rate != NULL && sess->rate->bad != 0 && rate_check(sess->rate) != 0) {
599  /* read the pending bytes when rate limit is no longer in effect */
600  log_debug(ZONE, "reading throttled %d", sess->fd->fd);
601  sess->s->want_read = 1;
602  sx_can_read(sess->s);
603  }
604 
605  } while(xhash_iter_next(c2s->sessions));
606 }
607 
608 JABBER_MAIN("jabberd2c2s", "Jabber 2 C2S", "Jabber Open Source Server: Client to Server", "jabberd2router\0")
609 {
610  c2s_t c2s;
611  char *config_file;
612  int optchar;
613  int mio_timeout;
614  sess_t sess;
615  bres_t res;
616  union xhashv xhv;
617  time_t check_time = 0;
618  const char *cli_id = 0;
619 
620 #ifdef HAVE_UMASK
621  umask((mode_t) 0027);
622 #endif
623 
624  srand(time(NULL));
625 
626 #ifdef HAVE_WINSOCK2_H
627 /* get winsock running */
628  {
629  WORD wVersionRequested;
630  WSADATA wsaData;
631  int err;
632 
633  wVersionRequested = MAKEWORD( 2, 2 );
634 
635  err = WSAStartup( wVersionRequested, &wsaData );
636  if ( err != 0 ) {
637  /* !!! tell user that we couldn't find a usable winsock dll */
638  return 0;
639  }
640  }
641 #endif
642 
643  jabber_signal(SIGINT, _c2s_signal);
644  jabber_signal(SIGTERM, _c2s_signal);
645 #ifdef SIGHUP
647 #endif
648 #ifdef SIGPIPE
649  jabber_signal(SIGPIPE, SIG_IGN);
650 #endif
653 
654 
655  c2s = (c2s_t) calloc(1, sizeof(struct c2s_st));
656 
657  /* load our config */
658  c2s->config = config_new();
659 
660  config_file = CONFIG_DIR "/c2s.xml";
661 
662  /* cmdline parsing */
663  while((optchar = getopt(argc, argv, "Dc:hi:?")) >= 0)
664  {
665  switch(optchar)
666  {
667  case 'c':
668  config_file = optarg;
669  break;
670  case 'D':
671 #ifdef DEBUG
672  set_debug_flag(1);
673 #else
674  printf("WARN: Debugging not enabled. Ignoring -D.\n");
675 #endif
676  break;
677  case 'i':
678  cli_id = optarg;
679  break;
680  case 'h': case '?': default:
681  fputs(
682  "c2s - jabberd client-to-server connector (" VERSION ")\n"
683  "Usage: c2s <options>\n"
684  "Options are:\n"
685  " -c <config> config file to use [default: " CONFIG_DIR "/c2s.xml]\n"
686  " -i id Override <id> config element\n"
687 #ifdef DEBUG
688  " -D Show debug output\n"
689 #endif
690  ,
691  stdout);
692  config_free(c2s->config);
693  free(c2s);
694  return 1;
695  }
696  }
697 
698  if(config_load_with_id(c2s->config, config_file, cli_id) != 0)
699  {
700  fputs("c2s: couldn't load config, aborting\n", stderr);
701  config_free(c2s->config);
702  free(c2s);
703  return 2;
704  }
705 
706  c2s->stream_redirects = xhash_new(523);
707 
708  _c2s_config_expand(c2s);
709 
710  c2s->log = log_new(c2s->log_type, c2s->log_ident, c2s->log_facility);
711  log_write(c2s->log, LOG_NOTICE, "starting up");
712 
713  _c2s_pidfile(c2s);
714 
715  if(c2s->ar_module_name == NULL) {
716  log_write(c2s->log, LOG_NOTICE, "no authreg module specified in config file");
717  }
718  else if((c2s->ar = authreg_init(c2s, c2s->ar_module_name)) == NULL) {
719  access_free(c2s->access);
720  config_free(c2s->config);
721  log_free(c2s->log);
722  free(c2s);
723  exit(1);
724  }
725 
726  c2s->sessions = xhash_new(1023);
727 
728  c2s->conn_rates = xhash_new(101);
729 
730  c2s->dead = jqueue_new();
731 
732  c2s->dead_sess = jqueue_new();
733 
734  c2s->sx_env = sx_env_new();
735 
736 #ifdef HAVE_SSL
737  /* get the ssl context up and running */
738  if(c2s->local_pemfile != NULL) {
740  if(c2s->sx_ssl == NULL) {
741  log_write(c2s->log, LOG_ERR, "failed to load local SSL pemfile, SSL will not be available to clients");
742  c2s->local_pemfile = NULL;
743  }
744  }
745 
746  /* try and get something online, so at least we can encrypt to the router */
747  if(c2s->sx_ssl == NULL && c2s->router_pemfile != NULL) {
749  if(c2s->sx_ssl == NULL) {
750  log_write(c2s->log, LOG_ERR, "failed to load router SSL pemfile, channel to router will not be SSL encrypted");
751  c2s->router_pemfile = NULL;
752  }
753  }
754 #endif
755 
756 #ifdef HAVE_LIBZ
757  /* get compression up and running */
758  if(c2s->compression)
760 #endif
761 
762  /* get stanza ack up */
764 
765  /* and user IP address plugin */
767 
768  /* get sasl online */
769  c2s->sx_sasl = sx_env_plugin(c2s->sx_env, sx_sasl_init, "xmpp", _c2s_sx_sasl_callback, (void *) c2s);
770  if(c2s->sx_sasl == NULL) {
771  log_write(c2s->log, LOG_ERR, "failed to initialise SASL context, aborting");
772  exit(1);
773  }
774 
775  /* get bind up */
776  sx_env_plugin(c2s->sx_env, bind_init, c2s);
777 
778  c2s->mio = mio_new(c2s->io_max_fds);
779  if(c2s->mio == NULL) {
780  log_write(c2s->log, LOG_ERR, "failed to create MIO, aborting");
781  exit(1);
782  }
783 
784  /* hosts mapping */
785  c2s->hosts = xhash_new(1021);
786  _c2s_hosts_expand(c2s);
787  c2s->sm_avail = xhash_new(1021);
788 
789  c2s->retry_left = c2s->retry_init;
790  _c2s_router_connect(c2s);
791 
792  mio_timeout = ((c2s->io_check_interval != 0 && c2s->io_check_interval < 5) ?
793  c2s->io_check_interval : 5);
794 
795  while(!c2s_shutdown) {
796  mio_run(c2s->mio, mio_timeout);
797 
798  if(c2s_logrotate) {
800 
801  log_write(c2s->log, LOG_NOTICE, "reopening log ...");
802  log_free(c2s->log);
803  c2s->log = log_new(c2s->log_type, c2s->log_ident, c2s->log_facility);
804  log_write(c2s->log, LOG_NOTICE, "log started");
805 
806  c2s_logrotate = 0;
807  }
808 
809  if(c2s_sighup) {
810  log_write(c2s->log, LOG_NOTICE, "reloading some configuration items ...");
811  config_t conf;
812  conf = config_new();
813  if (conf && config_load(conf, config_file) == 0) {
815  c2s->stream_redirects = xhash_new(523);
816 
817  char *req_domain, *to_address, *to_port;
818  config_elem_t elem;
819  int i;
821 
822  elem = config_get(conf, "stream_redirect.redirect");
823  if(elem != NULL)
824  {
825  for(i = 0; i < elem->nvalues; i++)
826  {
828  if(!sr) {
829  log_write(c2s->log, LOG_ERR, "cannot allocate memory for new stream redirection record, aborting");
830  exit(1);
831  }
832  req_domain = j_attr((const char **) elem->attrs[i], "requested_domain");
833  to_address = j_attr((const char **) elem->attrs[i], "to_address");
834  to_port = j_attr((const char **) elem->attrs[i], "to_port");
835 
836  if(req_domain == NULL || to_address == NULL || to_port == NULL) {
837  log_write(c2s->log, LOG_ERR, "Error reading a stream_redirect.redirect element from file, skipping");
838  continue;
839  }
840 
841  // Note that to_address should be RFC 3986 compliant
842  sr->to_address = to_address;
843  sr->to_port = to_port;
844 
845  xhash_put(c2s->stream_redirects, pstrdup(xhash_pool(c2s->stream_redirects), req_domain), sr);
846  }
847  }
848  config_free(conf);
849  } else {
850  log_write(c2s->log, LOG_WARNING, "couldn't reload config (%s)", config_file);
851  if (conf) config_free(conf);
852  }
853  c2s_sighup = 0;
854  }
855 
856  if(c2s_lost_router) {
857  if(c2s->retry_left < 0) {
858  log_write(c2s->log, LOG_NOTICE, "attempting reconnect");
859  sleep(c2s->retry_sleep);
860  c2s_lost_router = 0;
861  if (c2s->router) sx_free(c2s->router);
862  _c2s_router_connect(c2s);
863  }
864 
865  else if(c2s->retry_left == 0) {
866  c2s_shutdown = 1;
867  }
868 
869  else {
870  log_write(c2s->log, LOG_NOTICE, "attempting reconnect (%d left)", c2s->retry_left);
871  c2s->retry_left--;
872  sleep(c2s->retry_sleep);
873  c2s_lost_router = 0;
874  if (c2s->router) sx_free(c2s->router);
875  _c2s_router_connect(c2s);
876  }
877  }
878 
879  /* cleanup dead sess (before sx_t as sess->result uses sx_t nad cache) */
880  while(jqueue_size(c2s->dead_sess) > 0) {
881  sess = (sess_t) jqueue_pull(c2s->dead_sess);
882 
883  /* free sess data */
884  if(sess->ip != NULL) free((void*)sess->ip);
885  if(sess->smcomp != NULL) free((void*)sess->smcomp);
886  if(sess->result != NULL) nad_free(sess->result);
887  if(sess->resources != NULL)
888  for(res = sess->resources; res != NULL;) {
889  bres_t tmp = res->next;
890  jid_free(res->jid);
891  free(res);
892  res = tmp;
893  }
894  if(sess->rate != NULL) rate_free(sess->rate);
895  if(sess->stanza_rate != NULL) rate_free(sess->stanza_rate);
896 
897  free(sess);
898  }
899 
900  /* cleanup dead sx_ts */
901  while(jqueue_size(c2s->dead) > 0)
902  sx_free((sx_t) jqueue_pull(c2s->dead));
903 
904  /* time checks */
905  if(c2s->io_check_interval > 0 && time(NULL) >= c2s->next_check) {
906  log_debug(ZONE, "running time checks");
907 
908  _c2s_time_checks(c2s);
909 
910  c2s->next_check = time(NULL) + c2s->io_check_interval;
911  log_debug(ZONE, "next time check at %d", c2s->next_check);
912  }
913 
914  if(time(NULL) > check_time + 60) {
915 #ifdef POOL_DEBUG
916  pool_stat(1);
917 #endif
918  if(c2s->packet_stats != NULL) {
919  int fd = open(c2s->packet_stats, O_TRUNC | O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP);
920  if (fd >= 0) {
921  char buf[100];
922  int len = snprintf(buf, 100, "%lld\n", c2s->packet_count);
923  if (write(fd, buf, len) != len) {
924  close(fd);
925  fd = -1;
926  } else close(fd);
927  }
928  if (fd < 0) {
929  log_write(c2s->log, LOG_ERR, "failed to write packet statistics to: %s", c2s->packet_stats);
930  c2s_shutdown = 1;
931  }
932  }
933 
934  check_time = time(NULL);
935  }
936  }
937 
938  log_write(c2s->log, LOG_NOTICE, "shutting down");
939 
940  if(xhash_iter_first(c2s->sessions))
941  do {
942  xhv.sess_val = &sess;
943  xhash_iter_get(c2s->sessions, NULL, NULL, xhv.val);
944 
945  if(sess->active && sess->s)
946  sx_close(sess->s);
947 
948  } while(xhash_iter_next(c2s->sessions));
949 
950  /* cleanup dead sess */
951  while(jqueue_size(c2s->dead_sess) > 0) {
952  sess = (sess_t) jqueue_pull(c2s->dead_sess);
953 
954  /* free sess data */
955  if(sess->ip != NULL) free((void*)sess->ip);
956  if(sess->result != NULL) nad_free(sess->result);
957  if(sess->resources != NULL)
958  for(res = sess->resources; res != NULL;) {
959  bres_t tmp = res->next;
960  jid_free(res->jid);
961  free(res);
962  res = tmp;
963  }
964 
965  free(sess);
966  }
967 
968  while(jqueue_size(c2s->dead) > 0)
969  sx_free((sx_t) jqueue_pull(c2s->dead));
970 
971  if (c2s->fd != NULL) mio_close(c2s->mio, c2s->fd);
972  sx_free(c2s->router);
973 
974  sx_env_free(c2s->sx_env);
975 
976  mio_free(c2s->mio);
977 
978  xhash_free(c2s->sessions);
979 
980  authreg_free(c2s->ar);
981 
982  xhash_free(c2s->conn_rates);
983 
985 
986  xhash_free(c2s->sm_avail);
987 
988  xhash_free(c2s->hosts);
989 
990  jqueue_free(c2s->dead);
991 
992  jqueue_free(c2s->dead_sess);
993 
994  access_free(c2s->access);
995 
996  log_free(c2s->log);
997 
998  config_free(c2s->config);
999 
1000  free(c2s);
1001 
1002 #ifdef POOL_DEBUG
1003  pool_stat(1);
1004 #endif
1005 
1006 #ifdef HAVE_WINSOCK2_H
1007  WSACleanup();
1008 #endif
1009 
1010  return 0;
1011 }
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:242
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:881
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:190
config_t config
config
Definition: c2s.h:183
_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:225
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:141
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:277
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&#39;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&#39;t be allocated dynamically, but given buffer will be alwa...
Definition: jid.c:102
int(* check_password)(authreg_t ar, 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:331
int jqueue_size(jqueue_t q)
Definition: jqueue.c:126
xht conn_rates
Definition: c2s.h:261
int compression
enable Stream Compression
Definition: c2s.h:239
void log_write(log_t log, int level, const char *msgfmt,...)
Definition: log.c:104
int retry_left
Definition: c2s.h:201
int conn_rate_seconds
Definition: c2s.h:258
static void _c2s_time_checks(c2s_t c2s)
Definition: main.c:571
#define AR_MECH_TRAD_DIGEST
Definition: c2s.h:118
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:191
#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:236
static char * config_file
Definition: main.c:34
char * host_private_key_password
private key password
Definition: c2s.h:132
int io_check_keepalive
Definition: c2s.h:244
nad_t result
Definition: c2s.h:108
int ar_mechanisms
allowed mechanisms
Definition: c2s.h:253
holder for the config hash and nad
Definition: util.h:200
time_t next_check
Definition: c2s.h:246
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:150
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:135
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:274
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 &lt;0, use mio_read/write first) ...
Definition: mio.h:144
#define AR_MECH_TRAD_CRAMMD5
Definition: c2s.h:119
sx_t router
router&#39;s conn
Definition: c2s.h:173
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:250
#define AR_MECH_TRAD_PLAIN
Definition: c2s.h:117
void rate_free(rate_t rt)
Definition: rate.c:36
const char * router_pemfile
Definition: c2s.h:157
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:158
static void _c2s_signal_usr2(int signum)
Definition: main.c:47
const char * router_ip
how to connect to the router
Definition: c2s.h:153
static void _c2s_signal_usr1(int signum)
Definition: main.c:42
const char * local_ip
ip to listen on
Definition: c2s.h:204
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
const char * router_private_key_password
Definition: c2s.h:159
int router_port
Definition: c2s.h:154
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:169
mio_t mio
mio context
Definition: c2s.h:162
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:200
const char * ar_register_instructions
Definition: c2s.h:142
int stanza_rate_wait
Definition: c2s.h:271
int port
Definition: c2s.h:84
const char * to_address
Definition: c2s.h:385
char jid_static_buf[3 *1025]
JID static buffer.
Definition: jid.h:77
void ** val
Definition: c2s.h:377
time_t bad
Definition: util.h:267
const char * smcomp
Definition: c2s.h:81
int(* user_exists)(authreg_t ar, const char *username, const char *realm)
returns 1 if the user exists, 0 if not
Definition: c2s.h:325
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:243
const char * router_pass
Definition: c2s.h:156
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:123
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:144
sess_t * sess_val
Definition: c2s.h:379
struct sx_sasl_creds_st * sx_sasl_creds_t
char * domain
Definition: jid.h:45
int local_verify_mode
verify-mode
Definition: c2s.h:222
Definition: jid.h:42
int byte_rate_seconds
Definition: c2s.h:265
int local_port
unencrypted port
Definition: c2s.h:207
Definition: c2s.h:121
#define stream_err_HOST_GONE
Definition: sx.h:128
xht hosts
hosts mapping
Definition: c2s.h:292
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:126
int conn_rate_total
connection rates
Definition: c2s.h:257
int c2s_router_sx_callback(sx_t s, sx_event_t e, void *data, void *arg)
Definition: c2s.c:700
void sx_close(sx_t s)
Definition: io.c:480
const char * authzid
Definition: plugins.h:127
int byte_rate_wait
Definition: c2s.h:266
#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:168
int retry_init
connect retry
Definition: c2s.h:198
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:270
xht sm_avail
availability of sms that we are servicing
Definition: c2s.h:296
Definition: c2s.h:148
host_t vhost
Definition: c2s.h:293
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:233
int conn_rate_wait
Definition: c2s.h:259
JABBERD2_API int sx_sasl_init(sx_env_t env, sx_plugin_t p, va_list args)
init function
Definition: sasl_cyrus.c:1153
log_type_t log_type
log data
Definition: c2s.h:189
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:199
sig_atomic_t c2s_lost_router
Definition: main.c:26
jqueue_t dead_sess
list of sess on the way out
Definition: c2s.h:283
#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:174
int xhash_iter_first(xht h)
iteration
Definition: xhash.c:311
const char * to_port
Definition: c2s.h:386
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:194
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:165
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:195
static sig_atomic_t c2s_logrotate
Definition: main.c:27
const char * ar_module_name
auth/reg module
Definition: c2s.h:249
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:210
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
#define JABBER_MAIN(name, display, description, depends)
Definition: util.h:443
char * j_attr(const char **atts, const char *attr)
Definition: str.c:95
sx_plugin_t sx_sasl
Definition: c2s.h:170
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:375
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:143
#define sx_sasl_cb_GEN_AUTHZID
Definition: plugins.h:113
jqueue_t dead
list of sx_t on the way out
Definition: c2s.h:280
const char * pass
Definition: plugins.h:128
log_t log
logging
Definition: c2s.h:186
int(* user_authz_allowed)(authreg_t ar, 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:345
const char * pbx_pipe
PBX integration named pipe.
Definition: c2s.h:228
void sx_env_free(sx_env_t env)
Definition: env.c:31
a single element
Definition: util.h:207
int(* get_password)(authreg_t ar, const char *username, const char *realm, char password[257])
return this users cleartext password in the array (digest auth, password auth)
Definition: c2s.h:328
const char * router_user
Definition: c2s.h:155
int host_require_starttls
require starttls
Definition: c2s.h:138
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:219
int ar_ssl_mechanisms
Definition: c2s.h:254
#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:1365
int stanza_rate_total
stanza rates
Definition: c2s.h:269
const char * local_pemfile
encrypted port pemfile
Definition: c2s.h:213
const char * local_cachain
encrypted port cachain file
Definition: c2s.h:216
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:129
int byte_rate_total
byte rates (karma)
Definition: c2s.h:264