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

📄 router.c

📁 这是一个完全开放的
💻 C
📖 第 1 页 / 共 3 页
字号:
        case event_OPEN:                        log_write(comp->r->log, LOG_NOTICE, "[%s, port=%d] authenticated as %s", comp->ip, comp->port, comp->s->auth_id);            /* make a route for legacy components */            if(comp->legacy) {                /* make sure the name is available */                if(xhash_get(comp->r->routes, s->req_to) != NULL) {                    sx_error(s, stream_err_HOST_UNKNOWN, "requested name is already in use");   /* !!! correct error? */                    sx_close(s);                    return 0;                }                for(alias = comp->r->aliases; alias != NULL; alias = alias->next)                    if(strcmp(alias->name, s->req_to) == 0) {                        sx_error(s, stream_err_HOST_UNKNOWN, "requested name is already in use");   /* !!! correct error? */                        sx_close(s);                        return 0;                    }                xhash_put(comp->r->routes, pstrdup(xhash_pool(comp->r->routes), s->req_to), (void *) comp);                xhash_put(comp->routes, pstrdup(xhash_pool(comp->routes), s->req_to), (void *) comp);                log_write(comp->r->log, LOG_NOTICE, "[%s] online (bound to %s, port %d)", s->req_to, comp->ip, comp->port);                /* advertise the name */                _router_advertise(comp->r, s->req_to, comp, 0);                /* this is a legacy component, so we don't tell it about other routes */                /* bind aliases */                for(alias = comp->r->aliases; alias != NULL; alias = alias->next) {                    if(strcmp(alias->target, s->req_to) == 0) {                        xhash_put(comp->r->routes, pstrdup(xhash_pool(comp->r->routes), alias->name), (void *) comp);                        xhash_put(comp->routes, pstrdup(xhash_pool(comp->r->routes), alias->name), (void *) comp);                                    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);                        /* advertise name */                        _router_advertise(comp->r, alias->name, comp, 0);                    }                }            }            break;        case event_PACKET:            nad = (nad_t) data;            /* preauth */            if(comp->s->state == state_STREAM) {                /* non-legacy components can't do anything before auth */                if(!comp->legacy) {                    log_debug(ZONE, "stream is preauth, dropping packet");                    nad_free(nad);                    return 0;                }                /* watch for handshake requests */                if(NAD_ENAME_L(nad, 0) != 9 || strncmp("handshake", NAD_ENAME(nad, 0), NAD_ENAME_L(nad, 0)) != 0) {                     log_debug(ZONE, "unknown preauth packet %.*s, dropping", NAD_ENAME_L(nad, 0), NAD_ENAME(nad, 0));                    nad_free(nad);                    return 0;                }                /* process incoming handshakes */                _router_process_handshake(comp, nad);                return 0;            }            /* legacy processing */            if(comp->legacy) {                log_debug(ZONE, "packet from legacy component, munging it");                sto.pc = sfrom.pc = comp->r->pc;                attr = nad_find_attr(nad, 0, -1, "to", NULL);                if(attr < 0 || (to = jid_reset(&sto, NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr))) == NULL) {                    log_debug(ZONE, "invalid or missing 'to' address on legacy packet, dropping it");                    nad_free(nad);                    return 0;                }                attr = nad_find_attr(nad, 0, -1, "from", NULL);                if(attr < 0 || (from = jid_reset(&sfrom, NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr))) == NULL) {                    log_debug(ZONE, "invalid or missing 'from' address on legacy packet, dropping it");                    nad_free(nad);                    return 0;                }                /* rewrite component packets into client packets */                ns = nad_find_namespace(nad, 0, "jabber:component:accept", NULL);                if(ns >= 0) {                    if(nad->elems[0].ns == ns)                        nad->elems[0].ns = nad->nss[nad->elems[0].ns].next;                    else {                        for(sns = nad->elems[0].ns; sns >= 0 && nad->nss[sns].next != ns; sns = nad->nss[sns].next);                        nad->nss[sns].next = nad->nss[nad->nss[sns].next].next;                    }                }                ns = nad_find_namespace(nad, 0, uri_CLIENT, NULL);                if(ns < 0) {                    ns = nad_add_namespace(nad, uri_CLIENT, NULL);                    nad->scope = -1;                    nad->nss[ns].next = nad->elems[0].ns;                    nad->elems[0].ns = ns;                }                nad->elems[0].my_ns = ns;                /* wrap up the packet */                ns = nad_add_namespace(nad, uri_COMPONENT, "comp");                nad_wrap_elem(nad, 0, ns, "route");                nad_set_attr(nad, 0, -1, "to", to->domain, 0);                nad_set_attr(nad, 0, -1, "from", from->domain, 0);            }            /* top element must be router scoped */            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, "invalid packet namespace, dropping");                nad_free(nad);                return 0;            }            /* bind a name to this component */            if(NAD_ENAME_L(nad, 0) == 4 && strncmp("bind", NAD_ENAME(nad, 0), 4) == 0) {                _router_process_bind(comp, nad);                return 0;            }            /* unbind a name from this component */            if(NAD_ENAME_L(nad, 0) == 6 && strncmp("unbind", NAD_ENAME(nad, 0), 6) == 0) {                _router_process_unbind(comp, nad);                return 0;            }            /* route packets */            if(NAD_ENAME_L(nad, 0) == 5 && strncmp("route", NAD_ENAME(nad, 0), 5) == 0) {                _router_process_route(comp, nad);                return 0;            }            /* throttle packets */            if(NAD_ENAME_L(nad, 0) == 8 && strncmp("throttle", NAD_ENAME(nad, 0), 8) == 0) {                _router_process_throttle(comp, nad);                return 0;            }            log_debug(ZONE, "unknown packet, dropping");            nad_free(nad);            return 0;        case event_CLOSED:            mio_close(comp->r->mio, comp->fd);            break;    }    return 0;}static int _router_accept_check(router_t r, int fd, char *ip) {    rate_t rt;    if(access_check(r->access, ip) == 0) {        log_write(r->log, LOG_NOTICE, "[%d] [%s] access denied by configuration", fd, ip);        return 1;    }    if(r->conn_rate_total != 0) {        rt = (rate_t) xhash_get(r->conn_rates, ip);        if(rt == NULL) {            rt = rate_new(r->conn_rate_total, r->conn_rate_seconds, r->conn_rate_wait);            xhash_put(r->conn_rates, pstrdup(xhash_pool(r->conn_rates), ip), (void *) rt);        }        if(rate_check(rt) == 0) {            log_write(r->log, LOG_NOTICE, "[%d] [%s] is being rate limited", fd, ip);            return 1;        }        rate_add(rt, 1);    }    return 0;}static void _router_route_unbind_walker(xht routes, const char *key, void *val, void *arg) {    component_t comp = (component_t) arg;    xhash_zap(comp->r->routes, key);    xhash_zap(comp->routes, key);    if(comp->r->default_route != NULL && strcmp(key, comp->r->default_route) == 0) {        log_write(comp->r->log, LOG_NOTICE, "[%s] default route offline", key);        free(comp->r->default_route);        comp->r->default_route = NULL;    }    log_write(comp->r->log, LOG_NOTICE, "[%s] offline", key);    /* deadvertise name */    _router_advertise(comp->r, (char *) key, comp, 1);}int router_mio_callback(mio_t m, mio_action_t a, int fd, void *data, void *arg) {    component_t comp = (component_t) arg;    router_t r = (router_t) arg;    struct sockaddr_storage sa;    int namelen = sizeof(sa), port, nbytes;    switch(a) {        case action_READ:            log_debug(ZONE, "read action on fd %d", fd);            ioctl(fd, FIONREAD, &nbytes);            if(nbytes == 0) {                sx_kill(comp->s);                return 0;            }            return sx_can_read(comp->s);        case action_WRITE:            log_debug(ZONE, "write action on fd %d", fd);            return sx_can_write(comp->s);        case action_CLOSE:            log_debug(ZONE, "close action on fd %d", fd);            r = comp->r;            log_write(r->log, LOG_NOTICE, "[%s, port=%d] disconnect", comp->ip, comp->port);            /* unbind names */            xhash_walk(comp->routes, _router_route_unbind_walker, (void *) comp);            /* deregister component */            xhash_zap(r->components, comp->ipport);            xhash_free(comp->routes);            if(comp->tq != NULL)                /* !!! bounce packets */                jqueue_free(comp->tq);            rate_free(comp->rate);            jqueue_push(comp->r->dead, (void *) comp->s, 0);            free(comp);            break;        case action_ACCEPT:            log_debug(ZONE, "accept action on fd %d", fd);            getpeername(fd, (struct sockaddr *) &sa, &namelen);            port = j_inet_getport(&sa);            log_write(r->log, LOG_NOTICE, "[%s, port=%d] connect", (char *) data, port);            if(_router_accept_check(r, fd, (char *) data) != 0)                return 1;            comp = (component_t) malloc(sizeof(struct component_st));            memset(comp, 0, sizeof(struct component_st));            comp->r = r;            comp->fd = fd;            snprintf(comp->ip, INET6_ADDRSTRLEN, "%s", (char *) data);            comp->port = port;            snprintf(comp->ipport, INET6_ADDRSTRLEN, "%s:%d", comp->ip, comp->port);            comp->s = sx_new(r->sx_env, fd, _router_sx_callback, (void *) comp);            mio_app(m, fd, router_mio_callback, (void *) comp);            if(r->byte_rate_total != 0)                comp->rate = rate_new(r->byte_rate_total, r->byte_rate_seconds, r->byte_rate_wait);            comp->routes = xhash_new(51);            /* register component */            xhash_put(r->components, comp->ipport, (void *) comp);#ifdef HAVE_SSL            sx_server_init(comp->s, SX_SSL_STARTTLS_OFFER | SX_SASL_OFFER | SX_SASL_MECH_PLAIN | SX_SASL_MECH_DIGESTMD5);#else            sx_server_init(comp->s, SX_SASL_OFFER | SX_SASL_MECH_PLAIN | SX_SASL_MECH_DIGESTMD5);#endif            break;    }    return 0;}

⌨️ 快捷键说明

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