23 #include <stringprep.h> 28 int rlen, len, ns, elem, attr;
50 if(sess->
rate != NULL) {
58 log_write(sess->
c2s->
log, LOG_NOTICE,
"[%d] [%s, port=%d] is being byte rate limited", sess->
fd->
fd, sess->
ip, sess->
port);
77 len = recv(sess->
fd->
fd, buf->
data, rlen, 0);
80 if(sess->
rate != NULL)
154 if (redirect != NULL) {
155 log_debug(
ZONE,
"redirecting client's stream using see-other-host for domain: '%s'", s->
req_to);
157 char *other_host = (
char *) malloc(len+1);
185 if(sess->
host == NULL) {
215 log_write(sess->
c2s->
log, LOG_NOTICE,
"[%d] [%s, port=%d] is being stanza rate limited", sess->
fd->
fd, sess->
ip, sess->
port);
230 (strcmp(root,
"message") != 0 && strcmp(root,
"presence") != 0 && strcmp(root,
"iq") != 0)) {
236 if((ns =
nad_find_scoped_namespace(nad,
uri_BIND, NULL)) >= 0 && (elem =
nad_find_elem(nad, 0, ns,
"bind", 1)) >= 0 &&
nad_find_attr(nad, 0, -1,
"type",
"set") >= 0) {
245 char resource_buf[1024];
321 if((ns =
nad_find_scoped_namespace(nad,
uri_BIND, NULL)) >= 0 && (elem =
nad_find_elem(nad, 0, ns,
"unbind", 1)) >= 0 &&
nad_find_attr(nad, 0, -1,
"type",
"set") >= 0) {
322 char resource_buf[1024];
336 if(stringprep_xmpp_resourceprep(resource_buf, 1024) != 0) {
380 log_write(sess->
c2s->
log, LOG_NOTICE,
"[%d] unrecognized pre-session packet, closing stream", sess->
s->
tag);
393 log_write(sess->
c2s->
log, LOG_NOTICE,
"[%d] got pre STARTTLS packet, dropping", sess->
s->
tag);
409 log_write(sess->
c2s->
log, LOG_NOTICE,
"[%d] packet sent before session start, closing stream", sess->
s->
tag);
420 if(sess->
bound > 1) {
431 log_debug(
ZONE,
"packet without 'from' on multiple resource stream");
462 log_write(sess->
c2s->
log, LOG_NOTICE,
"[%d] %s authentication succeeded: %s %s:%d %s",
484 log_write(c2s->
log, LOG_NOTICE,
"[%d] [%s] access denied by configuration", fd->
fd, ip);
497 log_write(c2s->
log, LOG_NOTICE,
"[%d] [%s] is being connect rate limited", fd->
fd, ip);
512 socklen_t namelen =
sizeof(sa);
513 int port, nbytes, flags = 0;
522 ioctl(fd->
fd, FIONREAD, &nbytes);
538 log_write(sess->
c2s->
log, LOG_NOTICE,
"[%d] [%s, port=%d] disconnect jid=%s, packets: %i, bytes: %d", sess->
fd->
fd, sess->
ip, sess->
port, ((sess->
resources)?((
char*)
jid_full(sess->
resources->
jid)):
"unbound"), sess->
packet_count, sess->
s->
tbytes);
567 if(getpeername(fd->
fd, (
struct sockaddr *) &sa, &namelen) < 0)
571 log_write(c2s->
log, LOG_NOTICE,
"[%d] [%s, port=%d] connect", fd->
fd, (
char *) data, port);
582 sess->ip = strdup((
char *) data);
586 sess->last_activity = time(NULL);
601 sess->s->ip = sess->ip;
602 sess->s->port = sess->port;
605 if(getsockname(fd->
fd, (
struct sockaddr *) &sa, &namelen) < 0)
610 sprintf(sess->skey,
"%d", fd->
fd);
664 log_debug(
ZONE,
"sm for serviced domain '%s' offline", from);
688 int len, elem, from, c2sid, smid, action, id, ns, attr, scan, replaced;
768 log_write(c2s->
log, LOG_NOTICE,
"connection to router established");
795 if(
NAD_NURI_L(nad,
NAD_ENS(nad, 0)) != strlen(
uri_STREAMS) || strncmp(
uri_STREAMS,
NAD_NURI(nad,
NAD_ENS(nad, 0)), strlen(
uri_STREAMS)) != 0 ||
NAD_ENAME_L(nad, 0) != 8 || strncmp(
"features",
NAD_ENAME(nad, 0), 8) != 0) {
796 log_debug(
ZONE,
"got a non-features packet on an unauth'd stream, dropping");
812 log_write(c2s->
log, LOG_ERR,
"unable to establish encrypted session with router");
830 if(
NAD_NURI_L(nad,
NAD_ENS(nad, 0)) != strlen(
uri_COMPONENT) || strncmp(
uri_COMPONENT,
NAD_NURI(nad,
NAD_ENS(nad, 0)), strlen(
uri_COMPONENT)) != 0 ||
NAD_ENAME_L(nad, 0) != 4 || strncmp(
"bind",
NAD_ENAME(nad, 0), 4) != 0) {
831 log_debug(
ZONE,
"got a packet from router, but we're not online, dropping");
847 if(c2s->
server_fd == 0 && c2s->server_ssl_fd == 0) {
853 if(c2s->server_fd == NULL)
854 log_write(c2s->log, LOG_ERR,
"[%s, port=%d] failed to listen", c2s->local_ip, c2s->local_port);
856 log_write(c2s->log, LOG_NOTICE,
"[%s, port=%d] listening for connections", c2s->local_ip, c2s->local_port);
863 if(c2s->server_ssl_fd == NULL)
864 log_write(c2s->log, LOG_ERR,
"[%s, port=%d] failed to listen", c2s->local_ip, c2s->local_ssl_port);
866 log_write(c2s->log, LOG_NOTICE,
"[%s, port=%d] listening for SSL connections", c2s->local_ip, c2s->local_ssl_port);
868 c2s->server_ssl_fd = NULL;
873 if(c2s->
server_fd == NULL && c2s->server_ssl_fd == NULL && c2s->
pbx_pipe == NULL) {
874 log_write(c2s->
log, LOG_ERR,
"both normal and SSL ports are disabled, nothing to do!");
877 log_write(c2s->
log, LOG_ERR,
"server port is disabled, nothing to do!");
888 log_write(c2s->
log, LOG_NOTICE,
"ready for connections", c2s->
id);
954 if(action >= 0 &&
NAD_AVAL_L(nad, action) == 7 && strncmp(
"started",
NAD_AVAL(nad, action), 7) == 0) {
959 log_write(c2s->
log, LOG_NOTICE,
"session %s does not exist; telling sm to close", skey);
965 if(target < 0 || smid < 0) {
969 log_write(c2s->
log, LOG_NOTICE,
"sm sent an invalid start packet: %.*s", len, buf );
985 strncpy(tsess->
skey, skey,
sizeof(tsess->
skey));
1016 if(action >= 0 &&
NAD_AVAL_L(nad, action) == 7 && strncmp(
"created",
NAD_AVAL(nad, action), 7) == 0) {
1025 log_write(sess->
c2s->
log, LOG_WARNING,
"user created for session %s which is already gone", skey);
1046 log_debug(
ZONE,
"received packet from sm without an sm ID, dropping");
1054 for(bres = sess->
resources; bres != NULL; bres = bres->
next){
1079 if(c2sid < 0 || target < 0) {
1080 log_debug(
ZONE,
"needed ids not found - c2sid:%d target:%d", c2sid, target);
1111 if(
NAD_ENS(nad, 1) == ns && action >= 0) {
1126 if(sess->
bound < 1){
1131 if(sess->
result != NULL) {
1143 if(sess->
result != NULL) {
1157 for(ires = sess->
resources; ires != NULL; ires = ires->
next)
1158 if(ires->
next == bres)
1160 assert(ires != NULL);
1170 if(sess->
result != NULL) {
1198 if((
NAD_AVAL_L(nad, action) == 5 && strncmp(
"start",
NAD_AVAL(nad, action), 5) == 0) ||
1199 (
NAD_AVAL_L(nad, action) == 6 && strncmp(
"create",
NAD_AVAL(nad, action), 6) == 0)) {
1204 log_write(c2s->
log, LOG_NOTICE,
"[%d] user creation failed, and unable to delete user credentials: user=%s, realm=%s", sess->
s->
tag, bres->
jid->
node, sess->
host->
realm);
1206 log_write(c2s->
log, LOG_NOTICE,
"[%d] user creation failed, so deleted user credentials: user=%s, realm=%s", sess->
s->
tag, bres->
jid->
node, sess->
host->
realm);
1217 for(ires = sess->
resources; ires != NULL; ires = ires->
next)
1218 if(ires->
next == bres)
1220 assert(ires != NULL);
1231 log_debug(
ZONE,
"weird, got a failed session response, with a matching id, but the action is bogus *shrug*");
1238 if(
NAD_AVAL_L(nad, action) == 7 && strncmp(
"started",
NAD_AVAL(nad, action), 7) == 0) {
1288 if(!sess->
active || !sess->
s) {
1290 log_debug(
ZONE,
"Got packet for %s - dropping", !sess->
s ?
"session without stream (PBX pipe session?)" :
"inactive session");
1353 ioctl(fd->
fd, FIONREAD, &nbytes);
1367 log_write(c2s->
log, LOG_NOTICE,
"connection to router closed");
struct nad_elem_st * elems
C2S_API void sm_end(sess_t sess, bres_t res)
nad_t nad_new(void)
create a new nad
int nad_append_attr(nad_t nad, int ns, const char *name, const char *val)
attach new attr to the last elem
struct stream_redirect_st * stream_redirect_t
#define NAD_CDATA_L(N, E)
char sm_request[41]
this holds the id of the current pending SM request
#define sx_nad_write(s, nad)
void * pmalloc(pool_t p, int size)
void sx_nad_write_elem(sx_t s, nad_t nad, int elem)
app version
const char * jid_user(jid_t jid)
expand and return the user
int started
this is true if we've connected to the router at least once
unsigned int packet_count
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
access_t access
access controls
void rate_add(rate_t rt, int count)
Add a number of events to the counter.
static int _c2s_client_sx_callback(sx_t s, sx_event_t e, void *data, void *arg)
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 nad_append_cdata(nad_t nad, const char *cdata, int len, int depth)
append new cdata to the last elem
int compression
enable Stream Compression
void log_write(log_t log, int level, const char *msgfmt,...)
#define stream_err_INTERNAL_SERVER_ERROR
rate_t rate_new(int total, int seconds, int wait)
error info for event_ERROR
C2S_API void sm_packet(sess_t sess, bres_t res, nad_t nad)
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
list of resources bound to session
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)
const char * id
our id (hostname) with the router
mio_action_t
these are the actions and a handler type assigned by the applicaiton using mio
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
int stanza_size_limit
maximum stanza size
int xhash_iter_next(xht h)
void jid_random_part(jid_t jid, jid_part_t part)
create random resource
sx_t router
router's conn
#define SX_COMPRESS_OFFER
mio_fd_t server_fd
listening sockets
void rate_free(rate_t rt)
const char * router_pemfile
#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
const char * local_ip
ip to listen on
int authreg_process(c2s_t c2s, sess_t sess, nad_t nad)
processor for iq:auth and iq:register packets return 0 if handled, 1 if not handled ...
#define MIO_ERROR
all MIO related routines should use those for error reporting
const char * router_private_key_password
void pool_cleanup(pool_t p, pool_cleanup_t f, void *arg)
public cleanup utils, insert in a way that they are run FIFO, before mem frees
int sx_can_read(sx_t s)
we can read
void(* sess_end)(authreg_t ar, sess_t sess)
called prior to session being closed, to cleanup session specific private data
jid_t jid_reset_components(jid_t jid, const char *node, const char *domain, const char *resource)
build a jid from components
#define stanza_err_UNKNOWN_SENDER
holds the state for a single stream
int j_inet_getport(struct sockaddr_storage *sa)
get the port number out of a struct sockaddr_storage
#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
const char * realm
our realm (SASL)
void xhash_put(xht h, const char *key, void *val)
#define SX_SSL_STARTTLS_OFFER
#define stanza_err_BAD_REQUEST
host_t host
host this session belongs to
#define mio_listen(m, port, sourceip, app, arg)
for creating a new listen socket in this mio (returns new fd or <0)
int local_port
unencrypted port
void sx_error_extended(sx_t s, int err, const char *content)
#define stream_err_HOST_GONE
int xhash_iter_get(xht h, const char **key, int *keylen, void **val)
const char * host_pemfile
starttls pemfile
int conn_rate_total
connection rates
int c2s_router_sx_callback(sx_t s, sx_event_t e, void *data, void *arg)
static int _c2s_client_mio_callback(mio_t m, mio_action_t a, mio_fd_t fd, void *data, void *arg)
void xhash_zap(xht h, const char *key)
sx_env_t sx_env
sx environment
#define SX_WEBSOCKET_WRAPPER
#define SX_SSL_STARTTLS_REQUIRE
int rate_check(rate_t rt)
char c2s_id[44]
session id for this jid for us and them
nad_t stanza_error(nad_t nad, int elem, int err)
error the packet
xht sm_avail
availability of sms that we are servicing
struct _sx_buf_st * sx_buf_t
utility: buffer
C2S_API void sm_start(sess_t sess, bres_t res)
static int _c2s_client_accept_check(c2s_t c2s, mio_fd_t fd, const char *ip)
void sx_error(sx_t s, int err, const char *text)
xht stream_redirects
stream redirection (see-other-host) on session connect
#define stream_err_POLICY_VIOLATION
#define stanza_err_ITEM_NOT_FOUND
JABBERD2_API int sx_sasl_auth(sx_plugin_t p, sx_t s, const char *appname, const char *mech, const char *user, const char *pass)
trigger for client auth
sig_atomic_t c2s_lost_router
jqueue_t dead_sess
list of sess on the way out
There is one instance of this struct per user who is logged in to this c2s instance.
#define mio_app(m, fd, app, arg)
re-set the app handler
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
C2S_API void c2s_pbx_init(c2s_t c2s)
int xhash_iter_first(xht h)
iteration
long long int packet_count
packet counter
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...
int local_ssl_port
encrypted port
void * xhash_get(xht h, const char *key)
#define mio_close(m, fd)
request that mio close this fd
#define SX_SSL_WRAPPER
sx stream flags
#define stream_err_NOT_AUTHORIZED
#define mio_write(m, fd)
mio should try the write action on this fd now
sx_event_t
things that can happen
jqueue_t dead
list of sx_t on the way out
const char * pbx_pipe
PBX integration named pipe.
#define stream_err_CONFLICT
#define stream_err_HOST_UNKNOWN
void sx_auth(sx_t s, const char *auth_method, const char *auth_id)
force advance into auth state
#define stream_err_SEE_OTHER_HOST
int host_require_starttls
require starttls
int online
true if we're bound in the router
#define stanza_err_INTERNAL_SERVER_ERROR
int sx_ssl_client_starttls(sx_plugin_t p, sx_t s, const char *pemfile, const char *private_key_password)
void(* free)(authreg_t ar)
called prior to authreg shutdown
int c2s_router_mio_callback(mio_t m, mio_action_t a, mio_fd_t fd, void *data, void *arg)
int stanza_rate_total
stanza rates
const char * local_pemfile
encrypted port pemfile
int(* delete_user)(authreg_t ar, sess_t sess, const char *username, const char *realm)
static void _c2s_component_presence(c2s_t c2s, nad_t nad)
int nad_find_scoped_namespace(nad_t nad, const char *uri, const char *prefix)
find a namespace in scope
char * _sx_flags(sx_t s)
show sx flags as string - for logging
int byte_rate_total
byte rates (karma)