⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 c2s.c

📁 这是一个完全开放的
💻 C
📖 第 1 页 / 共 3 页
字号:
                        else                            log_write(c2s->log, LOG_NOTICE, "[%s, port=%d] listening for SSL connections", c2s->local_ip, c2s->local_ssl_port);                    } else                        c2s->server_ssl_fd = -1;#endif                }#ifdef HAVE_SSL                if(c2s->server_fd < 0 && c2s->server_ssl_fd < 0) {                    log_write(c2s->log, LOG_ERR, "both normal and SSL ports are disabled, nothing to do!");#else                if(c2s->server_fd < 0) {                    log_write(c2s->log, LOG_ERR, "server port is disabled, nothing to do!");#endif                    exit(1);                }                            /* we're online */                c2s->online = c2s->started = 1;                log_write(c2s->log, LOG_NOTICE, "ready for connections", c2s->id);                nad_free(nad);                return 0;            }            /* need component packets */            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) {                log_debug(ZONE, "wanted component packet, dropping");                nad_free(nad);                return 0;            }            /* component presence */            if(NAD_ENAME_L(nad, 0) == 8 && strncmp("presence", NAD_ENAME(nad, 0), 8) == 0) {                _c2s_component_presence(c2s, nad);                return 0;            }            /* we want route */            if(NAD_ENAME_L(nad, 0) != 5 || strncmp("route", NAD_ENAME(nad, 0), 5) != 0) {                 log_debug(ZONE, "wanted {component}route, dropping");                nad_free(nad);                return 0;            }            /* only handle unicasts */            if(nad_find_attr(nad, 0, -1, "type", NULL) >= 0) {                log_debug(ZONE, "non-unicast packet, dropping");                nad_free(nad);                return 0;            }            /* need some payload */            if(nad->ecur == 1) {                log_debug(ZONE, "no route payload, dropping");                nad_free(nad);                return 0;            }            ns = nad_find_namespace(nad, 1, uri_SESSION, NULL);            if(ns < 0) {                log_debug(ZONE, "not a c2s packet, dropping");                nad_free(nad);                return 0;            }            /* figure out the session */            c2sid = nad_find_attr(nad, 1, ns, "c2s", NULL);            if(c2sid < 0) {                log_debug(ZONE, "no c2s id on payload, dropping");                nad_free(nad);                return 0;            }            snprintf(skey, 10, "%.*s", NAD_AVAL_L(nad, c2sid), NAD_AVAL(nad, c2sid));            /* find the session, quietly drop if we don't have it */            sess = xhash_get(c2s->sessions, skey);            if(sess == NULL) {                /* !!! might want to send a stop to the sm; maybe it thinks we're still here? */                log_debug(ZONE, "no session for %s", skey);                nad_free(nad);                return 0;            }            /* if they're pre-stream, then this is leftovers from a previous session */            if(sess->s->state < state_STREAM) {                log_debug(ZONE, "session %s is pre-stream", skey);                nad_free(nad);                return 0;            }            /* check the sm session id if they gave us one */            smid = nad_find_attr(nad, 1, ns, "sm", NULL);            if(smid >= 0 && sess->sm_id[0] != '\0' && (strlen(sess->sm_id) != NAD_AVAL_L(nad, smid) || strncmp(sess->sm_id, NAD_AVAL(nad, smid), NAD_AVAL_L(nad, smid)) != 0)) {                log_debug(ZONE, "expected packet from sm session %s, but got one from %.*s, dropping", sess->sm_id, NAD_AVAL_L(nad, smid), NAD_AVAL(nad, smid));                nad_free(nad);                return 0;            }            /* it has to have come from the session manager */            from = nad_find_attr(nad, 0, -1, "from", NULL);            if(strlen(sess->s->req_to) != NAD_AVAL_L(nad, from) || strncmp(sess->s->req_to, NAD_AVAL(nad, from), NAD_AVAL_L(nad, from)) != 0) {                log_debug(ZONE, "packet from '%.*s' for %s, but they're not the sm for this sess", NAD_AVAL_L(nad, from), NAD_AVAL(nad, from), skey);                nad_free(nad);                return 0;            }            /* route errors */            if(nad_find_attr(nad, 0, -1, "error", NULL) >= 0) {                log_debug(ZONE, "routing error");                /* !!! kill the session */                nad_free(nad);                return 0;            }            /* session control packets */            if(NAD_ENS(nad, 1) == ns) {                action = nad_find_attr(nad, 1, -1, "action", NULL);                id = nad_find_attr(nad, 1, -1, "id", NULL);                /* failed requests */                if(nad_find_attr(nad, 1, ns, "failed", NULL) >= 0) {                    /* make sure the id matches */                    if(id < 0 || sess->sm_request[0] == '\0' || strlen(sess->sm_request) != NAD_AVAL_L(nad, id) || strncmp(sess->sm_request, NAD_AVAL(nad, id), NAD_AVAL_L(nad, id)) != 0) {                        log_debug(ZONE, "got a response with id %.*s, but we were expecting %s", NAD_AVAL_L(nad, id), NAD_AVAL(nad, id), sess->sm_request);                        nad_free(nad);                        return 0;                    }                    /* handled request */                    sess->sm_request[0] = '\0';                    /* we only care about failed start and create */                    if((NAD_AVAL_L(nad, action) == 5 && strncmp("start", NAD_AVAL(nad, action), 5) == 0) ||                       (NAD_AVAL_L(nad, action) == 6 && strncmp("create", NAD_AVAL(nad, action), 6) == 0)) {                        /* create failed, so we need to remove them from authreg */                        if(NAD_AVAL_L(nad, action) == 6 && c2s->ar->delete_user != NULL) {                            if((c2s->ar->delete_user)(c2s->ar, sess->jid->node, sess->realm) != 0)                                log_write(c2s->log, LOG_NOTICE, "[%d] user creation failed, and unable to delete user credentials: user=%s, realm=%s", sess->s->tag, sess->jid->node, sess->realm);                            else                                log_write(c2s->log, LOG_NOTICE, "[%d] user creation failed, so deleted user credentials: user=%s, realm=%s", sess->s->tag, sess->jid->node, sess->realm);                        }                        /* error the result and return it to the client */                        sx_nad_write(sess->s, stanza_error(sess->result, 0, stanza_err_INTERNAL_SERVER_ERROR));                        sess->result = NULL;                        jid_free(sess->jid);                        sess->jid = NULL;                        nad_free(nad);                        return 0;                    }                    log_debug(ZONE, "weird, got a failed session response, with a matching id, but the action is bogus *shrug*");                    nad_free(nad);                    return 0;                }                /* if we're not active yet, then we only want "started" or "created" responses */                if(!sess->active) {                    /* make sure the id matches */                    if(id < 0 || sess->sm_request[0] == '\0' || strlen(sess->sm_request) != NAD_AVAL_L(nad, id) || strncmp(sess->sm_request, NAD_AVAL(nad, id), NAD_AVAL_L(nad, id)) != 0) {                        log_debug(ZONE, "got a response with id %.*s, but we were expecting %s", NAD_AVAL_L(nad, id), NAD_AVAL(nad, id), sess->sm_request);                        nad_free(nad);                        return 0;                    }                    /* session started */                    if(NAD_AVAL_L(nad, action) == 7 && strncmp("started", NAD_AVAL(nad, action), 7) == 0) {                        /* handled request */                        sess->sm_request[0] = '\0';                        /* copy the sm id */                        if(smid >= 0)                            snprintf(sess->sm_id, 41, "%.*s", NAD_AVAL_L(nad, smid), NAD_AVAL(nad, smid));                        nad_free(nad);                        /* bring them online, old-skool */                        if(!sess->sasl_authd) {                            sx_auth(sess->s, "traditional", jid_user(sess->jid));                            return 0;                        }                        /* return the auth result to the client */                        sx_nad_write(sess->s, sess->result);                        sess->result = NULL;                        /* we're good to go */                        sess->active = 1;                        return 0;                    }                    /* user created */                    if(NAD_AVAL_L(nad, action) == 7 && strncmp("created", NAD_AVAL(nad, action), 7) == 0) {                        /* handled request */                        sess->sm_request[0] = '\0';                        nad_free(nad);                        /* return the result to the client */                        sx_nad_write(sess->s, sess->result);                        sess->result = NULL;                        return 0;                    }                    /* anything else gets thrown out */                    log_debug(ZONE, "got a packet for %s, but they don't have an active session yes", jid_full(sess->jid));                    nad_free(nad);                    return 0;                }                /* end responses */                /* !!! this "replaced" stuff is a hack - its really a subaction of "ended".                 *     hurrah, another control protocol rewrite is needed :(                 */                replaced = 0;                if(NAD_AVAL_L(nad, action) == 8 && strncmp("replaced", NAD_AVAL(nad, action), NAD_AVAL_L(nad, action)) == 0)                    replaced = 1;                if(replaced || (NAD_AVAL_L(nad, action) == 5 && strncmp("ended", NAD_AVAL(nad, action), NAD_AVAL_L(nad, action)) == 0)) {                    sess->active = 0;                                    if(replaced)                        sx_error(sess->s, stream_err_CONFLICT, NULL);                                        /* close them */                    sx_close(sess->s);                    nad_free(nad);                    return 0;                }                /* make sure the id matches */                if(id < 0 || sess->sm_request[0] == '\0' || strncmp(sess->sm_request, NAD_AVAL(nad, id), NAD_AVAL_L(nad, id)) != 0) {                    log_debug(ZONE, "got a response with id %.*s, but we were expecting %s", NAD_AVAL_L(nad, id), NAD_AVAL(nad, id), sess->sm_request);                    nad_free(nad);                    return 0;                }                /* handled request */                sess->sm_request[0] = '\0';                log_debug(ZONE, "unknown action %.*s", NAD_AVAL_L(nad, id), NAD_AVAL(nad, id));                nad_free(nad);                return 0;            }            /* client packets */            if(NAD_NURI_L(nad, NAD_ENS(nad, 1)) == strlen(uri_CLIENT) && strncmp(uri_CLIENT, NAD_NURI(nad, NAD_ENS(nad, 1)), strlen(uri_CLIENT)) == 0) {                if(!sess->active) {                    /* its a strange world .. */                    nad_free(nad);                    return 0;                }                /* sm is bouncing something */                if(nad_find_attr(nad, 1, ns, "failed", NULL) >= 0) {                    /* there's really no graceful way to handle this */                    sx_error(s, stream_err_INTERNAL_SERVER_ERROR, "session manager failed control action");                    sx_close(s);                    nad_free(nad);                    return 0;                }                /* remove sm specifics */                nad_set_attr(nad, 1, ns, "c2s", NULL, 0);                nad_set_attr(nad, 1, ns, "sm", NULL, 0);                /* forget about the internal namespace too */                if(nad->elems[1].ns == ns)                    nad->elems[1].ns = nad->nss[ns].next;                else {                    for(scan = nad->elems[1].ns; nad->nss[scan].next != -1 && nad->nss[scan].next != ns; scan = nad->nss[scan].next);                    /* got it */                    if(nad->nss[scan].next != -1)                        nad->nss[scan].next = nad->nss[ns].next;                }                sx_nad_write_elem(sess->s, nad, 1);                return 0;            }            /* its something else */            log_debug(ZONE, "unknown packet, dropping");            nad_free(nad);            return 0;        case event_CLOSED:            mio_close(c2s->mio, c2s->fd);            break;    }    return 0;}int c2s_router_mio_callback(mio_t m, mio_action_t a, int fd, void *data, void *arg) {    c2s_t c2s = (c2s_t) arg;    int nbytes;    switch(a) {        case action_READ:            log_debug(ZONE, "read action on fd %d", fd);            ioctl(fd, FIONREAD, &nbytes);            if(nbytes == 0) {                sx_kill(c2s->router);                return 0;            }            return sx_can_read(c2s->router);        case action_WRITE:            log_debug(ZONE, "write action on fd %d", fd);            return sx_can_write(c2s->router);        case action_CLOSE:            log_debug(ZONE, "close action on fd %d", fd);            log_write(c2s->log, LOG_NOTICE, "connection to router closed");            c2s_lost_router = 1;            /* we're offline */            c2s->online = 0;            break;        case action_ACCEPT:            break;    }    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -