23 #define MAX_JID 3072 // node(1023) + '@'(1) + domain(1023) + '/'(1) + resource(1023) + '\0'(1) 24 #define MAX_MESSAGE 65535 25 #define SECS_PER_DAY 86400 26 #define BYTES_PER_MEG 1048576 41 for(i = 0; i < routes->
ncomp; i++) {
55 log_debug(
ZONE,
"advertising %s to all routes (unavail=%d)", domain, unavail);
80 assert((
int) (routes->
name != NULL));
81 assert((
int) (routes->
comp != NULL));
82 assert(routes->
ncomp);
85 for(i = 0; i < routes->
ncomp; i++)
86 if(routes->
comp[i] == dest)
89 log_debug(
ZONE,
"informing component about %.*s", keylen, key);
106 log_debug(
ZONE,
"handshake isn't long enough to be a sha1 hash");
120 hash = (
char *) malloc(
sizeof(
char) * hashlen);
127 if(strncmp(hash,
NAD_CDATA(nad, 0), 40) == 0) {
154 if(routes->
name) free((
void*)routes->
name);
155 if(routes->
comp) free(routes->
comp);
165 routes->
name = strdup(name);
166 routes->
rtype = rtype;
173 if(routes->rtype != rtype)
174 log_write(comp->
r->
log, LOG_ERR,
"Mixed route types for '%s' bind request", name);
176 return routes->ncomp;
184 if(routes == NULL)
return;
186 if(routes->
ncomp > 1) {
187 for(i = 0; i < routes->
ncomp; i++) {
188 if(routes->
comp[i] == comp) {
189 if(i != routes->
ncomp - 1) {
210 log_debug(
ZONE,
"no or invalid 'name' on bind packet, bouncing");
217 c = strchr(user,
'@');
218 if(c != NULL) *c =
'\0';
221 log_write(comp->
r->
log, LOG_NOTICE,
"[%s, port=%d] tried to bind '%s', but their username (%s) is not permitted to bind other names", comp->
ip, comp->
port, name->
domain, user);
232 log_write(comp->
r->
log, LOG_NOTICE,
"[%s, port=%d] tried to bind '%s', but it's already bound", comp->
ip, comp->
port, name->
domain);
241 for(alias = comp->
r->
aliases; alias != NULL; alias = alias->
next)
243 log_write(comp->
r->
log, LOG_NOTICE,
"[%s, port=%d] tried to bind '%s', but that name is aliased", comp->
ip, comp->
port);
255 log_write(comp->
r->
log, LOG_NOTICE,
"[%s, port=%d] tried to bind '%s' as the default route, but their username (%s) is not permitted to set a default route", comp->
ip, comp->
port, name->
domain, user);
265 log_write(comp->
r->
log, LOG_NOTICE,
"[%s, port=%d] tried to bind '%s' as the default route, but one already exists", comp->
ip, comp->
port, name->
domain);
281 log_write(comp->
r->
log, LOG_NOTICE,
"[%s, port=%d] tried to bind '%s' as a log sink, but their username (%s) is not permitted to do this", comp->
ip, comp->
port, name->
domain, user);
301 log_write(comp->r->log, LOG_NOTICE,
"[%s]:%d online (bound to %s, port %d)", name->
domain, n, comp->ip, comp->port);
303 log_write(comp->r->log, LOG_NOTICE,
"[%s] online (bound to %s, port %d)", name->
domain, comp->ip, comp->port);
315 for(alias = comp->r->aliases; alias != NULL; alias = alias->
next) {
320 log_write(comp->r->log, LOG_NOTICE,
"[%s] online (alias of '%s', bound to %s, port %d)", alias->
name, name->
domain, comp->ip, comp->port);
337 log_debug(
ZONE,
"no or invalid 'name' on unbind packet, bouncing");
344 log_write(comp->
r->
log, LOG_NOTICE,
"[%s, port=%d] tried to unbind '%s', but it's not bound to this component", comp->
ip, comp->
port, name->
domain);
377 if(comp->
tq != NULL) {
406 log_debug(
ZONE,
"copying route to '%.*s' (%s, port %d)", keylen, key, comp->
ip, comp->
port);
414 int atype, ato, afrom;
418 jid_t to = NULL, from = NULL;
428 log_debug(
ZONE,
"dropping error packet, trying to avoid loops");
442 if(to == NULL || from == NULL) {
443 log_debug(
ZONE,
"unicast route with missing or invalid to or from, bouncing");
453 log_write(comp->
r->
log, LOG_NOTICE,
"[%s, port=%d] tried to send a packet from '%s', but that name is not bound to this component", comp->
ip, comp->
port, from->domain);
476 if(targets == NULL) {
486 if(targets == NULL) {
498 if(targets->
ncomp == 1) {
502 switch(targets->
rtype) {
510 const char *out;
int len;
512 log_write(comp->
r->
log, LOG_ERR,
"Cannot get destination for multiple route: %.*s", len, out);
520 const char *out;
int len;
522 log_write(comp->
r->
log, LOG_ERR,
"Cannot get source for multiple route: %.*s", len, out);
526 log_write(comp->
r->
log, LOG_ERR,
"Multiple components bound to single component route '%s'", targets->
name);
529 if(to->
node == NULL || strlen(to->
node) == 0) {
536 unsigned char hashval[20];
542 val = (
unsigned int *) hashval;
544 for(i=1; i < 20 / (
sizeof(
unsigned int)/
sizeof(
unsigned char)); i++, val++) {
552 if (to->
_user != NULL )
554 if (to->
_full != NULL )
557 dest = dest % targets->
ncomp;
560 target = targets->
comp[dest];
571 jid_t jid_msg_from = NULL;
572 jid_t jid_msg_to = NULL;
573 jid_t jid_route_from = NULL;
574 jid_t jid_route_to = NULL;
577 ((attr_route_from =
nad_find_attr(nad, 0, -1,
"from", NULL)) >= 0) &&
578 ((attr_route_to =
nad_find_attr(nad, 0, -1,
"to", NULL)) >= 0) &&
579 ((strncmp(
NAD_AVAL(nad, attr_route_to),
"c2s", 3)) != 0) &&
582 ((attr_msg_from =
nad_find_attr(nad, 1, -1,
"from", NULL)) >= 0) &&
583 ((attr_msg_to =
nad_find_attr(nad, 1, -1,
"to", NULL)) >= 0) &&
589 if (jid_msg_from != NULL)
591 if (jid_msg_to != NULL)
593 if (jid_route_from != NULL)
595 if (jid_route_to != NULL)
605 if(
NAD_AVAL_L(nad, atype) == 9 && strncmp(
"broadcast",
NAD_AVAL(nad, atype), 9) == 0) {
607 log_debug(
ZONE,
"broadcast route with missing or invalid from, bouncing");
617 log_write(comp->
r->
log, LOG_NOTICE,
"[%s, port=%d] tried to send a packet from '%s', but that name is not bound to this component", comp->
ip, comp->
port, from->domain);
650 if(comp->
tq == NULL) {
653 log_write(comp->
r->
log, LOG_NOTICE,
"[%s, port=%d] throttling packets on request", comp->
ip, comp->
port);
658 log_write(comp->
r->
log, LOG_NOTICE,
"[%s, port=%d] unthrottling packets on request", comp->
ip, comp->
port);
674 int rlen, len, attr, ns, sns, n;
701 if(comp->
rate != NULL) {
706 log_write(comp->
r->
log, LOG_NOTICE,
"[%s, port=%d] is being byte rate limited", comp->
ip, comp->
port);
728 len = recv(comp->
fd->
fd, buf->
data, rlen, 0);
731 if(comp->
rate != NULL && len > 0) {
789 if(s->
ns == NULL || strcmp(
"jabber:component:accept", s->
ns) != 0)
817 for(alias = comp->
r->
aliases; alias != NULL; alias = alias->
next)
829 log_write(comp->r->log, LOG_NOTICE,
"[%s]:%d online (bound to %s, port %d)", s->
req_to, n, comp->ip, comp->port);
831 log_write(comp->r->log, LOG_NOTICE,
"[%s] online (bound to %s, port %d)", s->
req_to, comp->ip, comp->port);
839 for(alias = comp->r->aliases; alias != NULL; alias = alias->
next) {
844 log_write(comp->r->log, LOG_NOTICE,
"[%s] online (alias of '%s', bound to %s, port %d)", alias->
name, s->
req_to, comp->ip, comp->port);
886 log_debug(
ZONE,
"invalid or missing 'to' address on legacy packet, dropping it");
893 log_debug(
ZONE,
"invalid or missing 'from' address on legacy packet, dropping it");
968 if (n->
data == comp->
fd)
break;
981 log_write(r->
log, LOG_NOTICE,
"[%d] [%s] access denied by configuration", fd->
fd, ip);
993 log_write(r->
log, LOG_NOTICE,
"[%d] [%s] is being rate limited", fd->
fd, ip);
1008 local_key = (
char *) malloc(keylen + 1);
1009 memcpy(local_key, key, keylen);
1010 local_key[keylen] = 0;
1015 log_write(comp->
r->
log, LOG_NOTICE,
"[%.*s] default route offline", keylen, key);
1020 log_write(comp->
r->
log, LOG_NOTICE,
"[%.*s] offline", keylen, key);
1032 socklen_t namelen =
sizeof(sa);
1042 ioctl(fd->
fd, FIONREAD, &nbytes);
1073 if(comp->tq != NULL)
1088 if(getpeername(fd->
fd, (
struct sockaddr *) &sa, &namelen) < 0)
1092 log_write(r->
log, LOG_NOTICE,
"[%s, port=%d] connect", (
char *) data, port);
1106 snprintf(comp->ipport,
INET6_ADDRSTRLEN + 6,
"%s:%d", comp->ip, comp->port);
1117 log_debug(
ZONE,
"new component (%p) \"%s\"", comp, comp->ipport);
1135 struct tm *time_pos;
1137 struct stat filestat;
1139 short int new_msg_file = 0;
1141 int nad_body_len = 0;
1142 char *nad_body = NULL;
1145 assert((
int) (nad != NULL));
1162 for (i = 0; i < nad_body_len; i++) {
1163 if (nad_body[i] ==
'\n') {
1169 umask((mode_t) 0077);
1175 log_write(r->
log, LOG_ERR,
"Unable to open message log for writing: %s", strerror(errno));
1180 if (! fprintf(message_file,
"# This message log is created by the jabberd router.\n"))
1182 log_write(r->
log, LOG_ERR,
"Unable to write to message log: %s", strerror(errno));
1183 fclose(message_file);
1186 fprintf(message_file,
"# See router.xml for logging options.\n");
1187 fprintf(message_file,
"# Format: DateTime FromJID ToJID MessageBody<line end>\n");
1192 time_pos = localtime(&t);
1193 if (strftime(timestamp,
sizeof(timestamp),
"%Y-%m-%dT%H:%M:%S%z", time_pos) == 0) {
1194 log_write(r->
log, LOG_ERR,
"strftime failed: %s", strerror(errno));
1197 elem = fprintf(message_file,
"%s %s %s %.*s\n", timestamp, msg_from, msg_to, nad_body_len, nad_body);
1199 fclose(message_file);
1202 for (i = 0; i < nad_body_len; i++) {
1203 if (nad_body[i] == 0x01) {
1209 log_write(r->
log, LOG_ERR,
"Unable to write to message log: %s", strerror(errno));
sx_env_t sx_env
sx environment
jqueue_t closefd
list of mio_fd_t waiting to be closed
#define INET6_ADDRSTRLEN
maximum length of the string representation of an IPv6 address
xht routes
valid routes, key is route name (packet "to" address), var is component_t
void nad_wrap_elem(nad_t nad, unsigned int elem, int ns, const char *name)
wrap an element with another element
struct nad_elem_st * elems
struct router_st * router_t
struct _stanza_error_st _stanza_errors[]
if you change these, reflect your changes in the defines in util.h
nad_t nad_new(void)
create a new nad
jid_t jid_reset(jid_t jid, const char *id, int len)
build a jid from an id
static void _router_advertise(router_t r, const char *domain, component_t src, int unavail)
domain advertisement
int nad_append_attr(nad_t nad, int ns, const char *name, const char *val)
attach new attr to the last elem
xht aci
access control lists
jqueue_t deadroutes
list of routes_t waiting to be cleaned up
#define NAD_CDATA_L(N, E)
#define sx_nad_write(s, nad)
void sx_nad_write_elem(sx_t s, nad_t nad, int elem)
app version
multi component route - route by 'from'
const char * jid_user(jid_t jid)
expand and return the user
const char * jid_full(jid_t jid)
expand and return the full
jid_t jid_new(const char *id, int len)
make a new jid
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
void rate_add(rate_t rt, int count)
Add a number of events to the counter.
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
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...
void * xhash_getx(xht h, const char *key, int len)
void log_write(log_t log, int level, const char *msgfmt,...)
static void _router_process_handshake(component_t comp, nad_t nad)
const char * default_route
default route, only one
rate_t rate_new(int total, int seconds, int wait)
error info for event_ERROR
void routes_free(routes_t routes)
struct routes_st * routes_t
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
int legacy
true if this is an old component:accept stream
void shahash_r(const char *str, char hashbuf[41])
convenience (originally by Thomas Muldowney)
int nad_add_namespace(nad_t nad, const char *uri, const char *prefix)
bring a new namespace into scope
void nad_print(nad_t nad, unsigned int elem, const char **xml, int *len)
create a string representation of the given element (and children), point references to it ...
void sx_server_init(sx_t s, unsigned int flags)
access_t access
access controls
#define stream_err_INVALID_NAMESPACE
jqueue_t tq
throttle queue
mio_action_t
these are the actions and a handler type assigned by the applicaiton using mio
int message_logging_enabled
simple message logging
int nad_append_elem(nad_t nad, int ns, const char *name, int depth)
create a new elem on the list
void nad_free(nad_t nad)
free that nad
nad_t nad_copy(nad_t nad)
copy a nad
int xhash_iter_next(xht h)
struct component_st * component_t
char ip[INET6_ADDRSTRLEN]
remote ip and port
void rate_free(rate_t rt)
#define mio_read(m, fd)
process read events for this fd
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
void jqueue_free(jqueue_t q)
time_t last_activity
timestamps for idle timeouts
static void _router_process_bind(component_t comp, nad_t nad)
mio_fd_t fd
listening socket
static void _route_remove(xht hroutes, const char *name, component_t comp)
int sx_can_read(sx_t s)
we can read
static void _router_route_log_sink(const char *key, int keylen, void *val, void *arg)
static void _router_process_route(component_t comp, nad_t nad)
xht routes
valid routes to this component, key is route name
holds the state for a single stream
void shahash_raw(const char *str, unsigned char hashval[20])
int j_inet_getport(struct sockaddr_storage *sa)
get the port number out of a struct sockaddr_storage
char jid_static_buf[3 *1025]
JID static buffer.
static void _router_process_throttle(component_t comp, nad_t nad)
#define NAD_ENAME_L(N, E)
void jqueue_push(jqueue_t q, void *data, int priority)
#define NAD_NURI_L(N, NS)
void jid_free(jid_t jid)
free a jid
int aci_check(xht aci, const char *type, const char *name)
see if a username is in an acl
static void _router_process_unbind(component_t comp, nad_t nad)
void xhash_put(xht h, const char *key, void *val)
#define SX_SSL_STARTTLS_OFFER
static int _router_accept_check(router_t r, mio_fd_t fd, const char *ip)
#define stanza_err_BAD_REQUEST
#define stanza_err_REDIRECT
multi component route - route by 'to'
struct broadcast_st * broadcast_t
info for broadcasts
alias_t aliases
configured aliases
int xhash_iter_get(xht h, const char **key, int *keylen, void **val)
int byte_rate_total
default byte rates (karma)
mio_fd_t fd
file descriptor
void xhash_zap(xht h, const char *key)
void xhash_zapx(xht h, const char *key, int len)
int rate_check(rate_t rt)
nad_t stanza_error(nad_t nad, int elem, int err)
error the packet
struct _sx_buf_st * sx_buf_t
utility: buffer
void sx_error(sx_t s, int err, const char *text)
int router_mio_callback(mio_t m, mio_action_t a, mio_fd_t fd, void *data, void *arg)
static void _router_broadcast(const char *key, int keylen, void *val, void *arg)
broadcast a packet
int message_log(nad_t nad, router_t r, const char *msg_from, const char *msg_to)
#define mio_app(m, fd, app, arg)
re-set the app handler
void * jqueue_pull(jqueue_t q)
int nad_find_elem(nad_t nad, unsigned int elem, int ns, const char *name, int depth)
locate the next elem at a given depth with an optional matching name
int xhash_count(xht h)
return the total number of entries in this xht
int xhash_iter_first(xht h)
iteration
void xhash_walk(xht h, xhash_walker w, void *arg)
jqueue_t jqueue_new(void)
int filter_packet(router_t r, nad_t nad)
xht log_sinks
log sinks, key is route name, var is component_t
pool_t xhash_pool(xht h)
get our pool
int access_check(access_t access, const char *ip)
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...
static void _router_advertise_reverse(const char *key, int keylen, void *val, void *arg)
tell a component about all the others
void * xhash_get(xht h, const char *key)
#define stream_err_NOT_AUTHORIZED
#define mio_write(m, fd)
mio should try the write action on this fd now
static int _route_add(xht hroutes, const char *name, component_t comp, route_type_t rtype)
sx_event_t
things that can happen
int conn_rate_total
connection rates
#define stream_err_HOST_UNKNOWN
void sx_auth(sx_t s, const char *auth_method, const char *auth_id)
force advance into auth state
const char * local_secret
#define stanza_err_SERVICE_UNAVAILABLE
xht components
attached components, key is 'ip:port', var is component_t
static void _router_route_unbind_walker(const char *key, int keylen, void *val, void *arg)
static int _router_sx_callback(sx_t s, sx_event_t e, void *data, void *arg)
static void _router_comp_write(component_t comp, nad_t nad)
const char * message_logging_file