24
24
* @brief stream / io callbacks
25
25
* @author Robert Norris
26
* $Date: 2005/01/07 11:46:52 $
27
* $Revision: 1.41.2.5 $
26
* $Date: 2005/08/17 07:48:28 $
30
sig_atomic_t sm_lost_router = 0;
30
32
/** our master callback */
31
33
int sm_sx_callback(sx_t s, sx_event_t e, void *data, void *arg) {
32
34
sm_t sm = (sm_t) arg;
51
log_debug(ZONE, "reading from %d", sm->fd);
53
log_debug(ZONE, "reading from %d", sm->fd->fd);
54
len = recv(sm->fd, buf->data, buf->len, 0);
56
len = recv(sm->fd->fd, buf->data, buf->len, 0);
57
if(errno == EWOULDBLOCK || errno == EINTR || errno == EAGAIN) {
62
log_write(sm->log, LOG_NOTICE, "[%d] [router] read error: %s (%d)", sm->fd, strerror(errno), errno);
64
log_write(sm->log, LOG_NOTICE, "[%d] [router] read error: %s (%d)", sm->fd->fd, MIO_STRERROR(MIO_ERROR), MIO_ERROR);
70
72
/* they went away */
83
log_debug(ZONE, "writing to %d", sm->fd);
85
log_debug(ZONE, "writing to %d", sm->fd->fd);
85
len = send(sm->fd, buf->data, buf->len, 0);
87
len = send(sm->fd->fd, buf->data, buf->len, 0);
87
89
log_debug(ZONE, "%d bytes written", len);
91
if(errno == EWOULDBLOCK || errno == EINTR || errno == EAGAIN)
94
log_write(sm->log, LOG_NOTICE, "[%d] [router] write error: %s (%d)", sm->fd, strerror(errno), errno);
96
log_write(sm->log, LOG_NOTICE, "[%d] [router] write error: %s (%d)", sm->fd->fd, MIO_STRERROR(MIO_ERROR), MIO_ERROR);
130
132
nad = (nad_t) data;
132
134
/* drop unqualified packets */
133
if(NAD_ENS(nad, 0) < 0) {
135
if (NAD_ENS(nad, 0) < 0) {
137
139
/* watch for the features packet */
138
if(s->state == state_STREAM) {
139
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) {
140
if (s->state == state_STREAM) {
141
if (NAD_NURI_L(nad, NAD_ENS(nad, 0)) != strlen(uri_STREAMS)
142
|| strncmp(uri_STREAMS, NAD_NURI(nad, NAD_ENS(nad, 0)), strlen(uri_STREAMS)) != 0
143
|| NAD_ENAME_L(nad, 0) != 8 || strncmp("features", NAD_ENAME(nad, 0), 8) != 0) {
140
144
log_debug(ZONE, "got a non-features packet on an unauth'd stream, dropping");
146
150
/* starttls if we can */
147
if(sm->sx_ssl != NULL && s->ssf == 0) {
151
if (sm->sx_ssl != NULL && s->ssf == 0) {
148
152
ns = nad_find_scoped_namespace(nad, uri_TLS, NULL);
150
154
elem = nad_find_elem(nad, 0, ns, "starttls", 1);
152
if(sx_ssl_client_starttls(sm->sx_ssl, s, NULL) == 0) {
156
if (sx_ssl_client_starttls(sm->sx_ssl, s, NULL) == 0) {
163
167
* if there isn't an appropriate one, error and bail */
165
169
/* authenticate */
166
sx_sasl_auth(sm->sx_sasl, s, "DIGEST-MD5", sm->router_user, sm->router_pass, NULL);
170
sx_sasl_auth(sm->sx_sasl, s, "jabberd-router", "DIGEST-MD5", sm->router_user, sm->router_pass);
172
176
/* watch for the bind response */
173
if(s->state == state_OPEN && !sm->online) {
174
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)) {
177
if (s->state == state_OPEN && !sm->online) {
178
if (NAD_NURI_L(nad, NAD_ENS(nad, 0)) != strlen(uri_COMPONENT)
179
|| strncmp(uri_COMPONENT, NAD_NURI(nad, NAD_ENS(nad, 0)), strlen(uri_COMPONENT)) != 0
180
|| NAD_ENAME_L(nad, 0) != 4 || strncmp("bind", NAD_ENAME(nad, 0), 4)) {
175
181
log_debug(ZONE, "got a packet from router, but we're not online, dropping");
197
203
log_debug(ZONE, "got a packet");
199
205
pkt = pkt_new(sm, (nad_t) data);
201
207
log_debug(ZONE, "invalid packet, dropping");
212
218
case event_CLOSED:
213
219
mio_close(sm->mio, sm->fd);
220
int sm_mio_callback(mio_t m, mio_action_t a, int fd, void *data, void *arg) {
226
int sm_mio_callback(mio_t m, mio_action_t a, mio_fd_t fd, void *data, void *arg) {
221
227
sm_t sm = (sm_t) arg;
225
231
case action_READ:
226
log_debug(ZONE, "read action on fd %d", fd);
232
log_debug(ZONE, "read action on fd %d", fd->fd);
228
ioctl(fd, FIONREAD, &nbytes);
234
ioctl(fd->fd, FIONREAD, &nbytes);
229
235
if(nbytes == 0) {
230
236
sx_kill(sm->router);
234
240
return sx_can_read(sm->router);
236
242
case action_WRITE:
237
log_debug(ZONE, "write action on fd %d", fd);
243
log_debug(ZONE, "write action on fd %d", fd->fd);
238
244
return sx_can_write(sm->router);
240
246
case action_CLOSE:
241
log_debug(ZONE, "close action on fd %d", fd);
247
log_debug(ZONE, "close action on fd %d", fd->fd);
242
248
log_write(sm->log, LOG_NOTICE, "connection to router closed");
244
250
sm_lost_router = 1;
258
/** this was jutil_timestamp in a former life */
259
void sm_timestamp(time_t t, char timestamp[18])
261
struct tm *gm = gmtime(&t);
263
snprintf(timestamp, 18, "%d%02d%02dT%02d:%02d:%02d", 1900 + gm->tm_year,
264
gm->tm_mon + 1, gm->tm_mday, gm->tm_hour, gm->tm_min, gm->tm_sec);
269
264
/** send a new action route */
270
265
void sm_c2s_action(sess_t dest, char *action, char *target) {
282
277
sns = nad_add_namespace(nad, uri_SESSION, "sc");
283
278
nad_append_elem(nad, sns, "session", 1);
285
if(dest->c2s_id[0] != '\0')
280
if (dest->c2s_id[0] != '\0')
286
281
nad_append_attr(nad, sns, "c2s", dest->c2s_id);
287
if(dest->sm_id[0] != '\0')
282
if (dest->sm_id[0] != '\0')
288
283
nad_append_attr(nad, sns, "sm", dest->sm_id);
290
285
nad_append_attr(nad, -1, "action", action);
292
287
nad_append_attr(nad, -1, "target", target);
294
log_debug(ZONE, "routing nad to %s from %s c2s %s s2s %s action %s target %s", dest->c2s, dest->user->sm->id, dest->c2s_id, dest->sm_id, action, target);
290
"routing nad to %s from %s c2s %s s2s %s action %s target %s",
291
dest->c2s, dest->user->sm->id, dest->c2s_id, dest->sm_id,
296
294
sx_nad_write(dest->user->sm->router, nad);
299
297
/** this is gratuitous, but apache gets one, so why not? */
300
298
void sm_signature(sm_t sm, char *str) {
301
if(sm->siglen == 0) {
299
if (sm->siglen == 0) {
302
300
snprintf(&sm->signature[sm->siglen], 2048 - sm->siglen, "%s", str);
303
301
sm->siglen += strlen(str);
306
304
sm->siglen += strlen(str) + 1;
308
/** register a new global ns */
309
int sm_register_ns(sm_t sm, char *uri) {
312
ns_idx = (int) xhash_get(sm->xmlns, uri);
314
ns_idx = xhash_count(sm->xmlns) + 2;
315
xhash_put(sm->xmlns, pstrdup(xhash_pool(sm->xmlns), uri), (void *) ns_idx);
317
xhash_put(sm->xmlns_refcount, uri, (void *) ((int) xhash_get(sm->xmlns_refcount, uri) + 1));
322
/** unregister a global ns */
323
void sm_unregister_ns(sm_t sm, char *uri) {
324
int refcount = (int) xhash_get(sm->xmlns_refcount, uri);
326
xhash_zap(sm->xmlns, uri);
327
xhash_zap(sm->xmlns_refcount, uri);
328
} else if (refcount > 1) {
329
xhash_put(sm->xmlns_refcount, uri, (void *) ((int) xhash_get(sm->xmlns_refcount, uri) - 1));
333
/** get a globally registered ns */
334
int sm_get_ns(sm_t sm, char *uri) {
335
return (int) xhash_get(sm->xmlns, uri);