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

📄 deliver.c

📁 jabber server jabber server jabber server jabber server
💻 C
📖 第 1 页 / 共 2 页
字号:
result deliver_null(instance i, dpacket p, void* arg){    pool_free(p->p);    return r_DONE;}result deliver_config_null(instance i, xmlnode x, void *arg){    if(i == NULL)        return r_PASS;    register_phandler(i, o_DELIVER, deliver_null, NULL);    return r_DONE;}void deliver(dpacket p, instance i){    ilist a, b;    if(deliver__flag == 1 && p == NULL && i == NULL)    { /* begin delivery of postponed messages */        deliver_msg d;        while((d=(deliver_msg)pth_msgport_get(deliver__mp))!=NULL)        {            deliver(d->p,d->i);        }        pth_msgport_destroy(deliver__mp);        deliver__mp = NULL;        deliver__flag = -1; /* disable all queueing crap */    }    /* Ensure the packet is valid */    if (p == NULL)	 return;    /* catch the @-internal xdb crap */    if(p->type == p_XDB && *(p->host) == '-')    {        deliver_internal(p, i);        return;    }    if(deliver__flag == 0)    { /* postpone delivery till later */        deliver_msg d = pmalloco(xmlnode_pool(p->x) ,sizeof(_deliver_msg));                if(deliver__mp == NULL)            deliver__mp = pth_msgport_create("deliver__");                d->i = i;        d->p = p;                pth_msgport_put(deliver__mp, (void*)d);        return;    }    log_debug2(ZONE, LOGT_DELIVER, "DELIVER %d:%s %s", p->type, p->host, xmlnode2str(p->x));    b = NULL;    a = deliver_hashmatch(deliver_hashtable(p->type), p->host);    if(p->type == p_XDB)        b = deliver_hashmatch(deliver__ns, xmlnode_get_attrib(p->x,"ns"));    else if(p->type == p_LOG)        b = deliver_hashmatch(deliver__logtype, xmlnode_get_attrib(p->x,"type"));    deliver_instance(deliver_intersect(a, b), p);}/* util to check and see which instance this hostname is going to get mapped to for normal packets */instance deliver_hostcheck(char *host){    ilist l;    if(host == NULL) return NULL;    if((l = deliver_hashmatch(deliver__hnorm,host)) == NULL || l->next != NULL) return NULL;    return l->i;}void deliver_init(void){    deliver__hnorm = xhash_new(401);    deliver__hlog = xhash_new(401);    deliver__hxdb = xhash_new(401);    register_config("host",deliver_config_host,NULL);    register_config("ns",deliver_config_ns,NULL);    register_config("logtype",deliver_config_logtype,NULL);    register_config("uplink",deliver_config_uplink,NULL);    register_config("null",deliver_config_null,NULL);}/** * free the delivery structures ... this is called when we already have shutdown the server * therefore we cannot register it with register_shutdown() */void deliver_shutdown(void) {    if (deliver__hnorm)	xhash_free(deliver__hnorm);    if (deliver__hxdb)	xhash_free(deliver__hxdb);    if (deliver__hlog)	xhash_free(deliver__hlog);    if (deliver__ns)	xhash_free(deliver__ns);    if (deliver__logtype)	xhash_free(deliver__logtype);}/* register a function to handle delivery for this instance */void register_phandler(instance id, order o, phandler f, void *arg){    handel newh, h1, last;    pool p;    /* create handel and setup */    p = pool_new(); /* use our own little pool */    newh = pmalloco(p, sizeof(_handel));    newh->p = p;    newh->f = f;    newh->arg = arg;    newh->o = o;    /* if we're the only handler, easy */    if(id->hds == NULL)    {        id->hds = newh;        return;    }    /* place according to handler preference */    switch(o)    {    case o_PRECOND:        /* always goes to front of list */        newh->next = id->hds;        id->hds = newh;        break;    case o_COND:        h1 = id->hds;        last = NULL;        while(h1->o < o_PREDELIVER)        {            last = h1;            h1 = h1->next;            if(h1 == NULL)                break;         }        if(last == NULL)        { /* goes to front of list */            newh->next = h1;            id->hds = newh;        }        else if(h1 == NULL)        { /* goes at end of list */            last->next = newh;        }        else        { /* goes between last and h1 */            newh->next = h1;            last->next = newh;        }        break;    case o_PREDELIVER:        h1 = id->hds;        last = NULL;        while(h1->o < o_DELIVER)        {            last = h1;            h1 = h1->next;            if(h1 == NULL)                break;         }        if(last == NULL)        { /* goes to front of list */            newh->next = h1;            id->hds = newh;        }        else if(h1 == NULL)        { /* goes at end of list */            last->next = newh;        }        else        { /* goes between last and h1 */            newh->next = h1;            last->next = newh;        }        break;    case o_DELIVER:        /* always add to the end */        for(h1 = id->hds; h1->next != NULL; h1 = h1->next);        h1->next = newh;        break;    default:        ;    }}/* bounce on the delivery, use the result to better gague what went wrong */void deliver_fail(dpacket p, char *err){    xterror xt;    char message[MAX_LOG_SIZE];    log_debug2(ZONE, LOGT_DELIVER, "delivery failed (%s)", err);    if(p==NULL) return;    switch(p->type)    {    case p_LOG:        /* stderr and drop */        snprintf(message, MAX_LOG_SIZE, "WARNING!  Logging Failed: %s\n",xmlnode2str(p->x));        fprintf(stderr, "%s\n", message);        pool_free(p->p);        break;    case p_XDB:        /* log_warning and drop */        log_warn(p->host,"dropping a %s xdb request to %s for %s",xmlnode_get_attrib(p->x,"type"),xmlnode_get_attrib(p->x,"to"),xmlnode_get_attrib(p->x,"ns"));        /* drop through and treat like a route failure */    case p_ROUTE:        /* route packet bounce */        if(j_strcmp(xmlnode_get_attrib(p->x,"type"),"error") == 0)        {   /* already bounced once, drop */            log_warn(p->host,"dropping a routed packet to %s from %s: %s",xmlnode_get_attrib(p->x,"to"),xmlnode_get_attrib(p->x,"from"),err);            pool_free(p->p);        }else{            log_notice(p->host,"bouncing a routed packet to %s from %s: %s",xmlnode_get_attrib(p->x,"to"),xmlnode_get_attrib(p->x,"from"),err);            /* turn into an error and bounce */            jutil_tofrom(p->x);            xmlnode_put_attrib(p->x,"type","error");            xmlnode_put_attrib(p->x,"error",err);            deliver(dpacket_new(p->x),NULL);        }        break;    case p_NORM:        /* normal packet bounce */        if(j_strcmp(xmlnode_get_attrib(p->x,"type"),"error") == 0)        { /* can't bounce an error */            log_warn(p->host,"dropping a packet to %s from %s: %s",xmlnode_get_attrib(p->x,"to"),xmlnode_get_attrib(p->x,"from"),err);            pool_free(p->p);        }else{            log_notice(p->host,"bouncing a packet to %s from %s: %s",xmlnode_get_attrib(p->x,"to"),xmlnode_get_attrib(p->x,"from"),err);            /* turn into an error */            if(err == NULL)            {                jutil_error_xmpp(p->x,XTERROR_EXTERNAL);            }else{		xt = XTERROR_EXTERNAL;		strncpy(xt.msg, err, sizeof(xt.msg));		xt.msg[sizeof(xt.msg)-1] = 0;                jutil_error_xmpp(p->x,xt);            }            deliver(dpacket_new(p->x),NULL);        }        break;    default:        ;    }}/* actually perform the delivery to an instance */void deliver_instance(instance i, dpacket p){    handel h, hlast;    result r;    dpacket pig = p;    if(i == NULL)    {        deliver_fail(p, "Unable to deliver, destination unknown");        return;    }    log_debug2(ZONE, LOGT_DELIVER, "delivering to instance '%s'", i->id);    /* try all the handlers */    hlast = h = i->hds;    while(h != NULL)    {        /* there may be multiple delivery handlers, make a backup copy first if we have to */        if(h->o == o_DELIVER && h->next != NULL)            pig = dpacket_copy(p);        /* call the handler */        if((r = (h->f)(i,p,h->arg)) == r_ERR)        {            deliver_fail(p, "Internal Delivery Error");            break;        }        /* if a non-delivery handler says it handled it, we have to be done */        if(h->o != o_DELIVER && r == r_DONE)            break;        /* if a conditional handler wants to halt processing */        if(h->o == o_COND && r == r_LAST)            break;        /* deal with that backup copy we made */        if(h->o == o_DELIVER && h->next != NULL)        {            if(r == r_DONE) /* they ate it, use copy */                p = pig;            else                pool_free(pig->p); /* they never used it, trash copy */        }        /* unregister this handler */        if(r == r_UNREG)        {            if(h == i->hds)            { /* removing the first in the list */                i->hds = h->next;                pool_free(h->p);                hlast = h = i->hds;            }else{ /* removing from anywhere in the list */                hlast->next = h->next;                pool_free(h->p);                h = hlast->next;            }            continue;        }        hlast = h;        h = h->next;    }}dpacket dpacket_new(xmlnode x){    dpacket p;    char *str;    if(x == NULL)        return NULL;    /* create the new packet */    p = pmalloco(xmlnode_pool(x),sizeof(_dpacket));    p->x = x;    p->p = xmlnode_pool(x);    /* determine it's type */    p->type = p_NORM;    if(*(xmlnode_get_name(x)) == 'r')        p->type = p_ROUTE;    else if(*(xmlnode_get_name(x)) == 'x')        p->type = p_XDB;    else if(*(xmlnode_get_name(x)) == 'l')        p->type = p_LOG;    /* xdb results are shipped as normal packets */    if(p->type == p_XDB && (str = xmlnode_get_attrib(p->x,"type")) != NULL && (*str == 'r' || *str == 'e' ))        p->type = p_NORM;    /* determine who to route it to, overriding the default to="" attrib only for logs where we use from */    if(p->type == p_LOG)        p->id = jid_new(p->p, xmlnode_get_attrib(x, "from"));    else        p->id = jid_new(p->p, xmlnode_get_attrib(x, "to"));    if(p->id == NULL)    {        log_warn(NULL,"Packet Delivery Failed, invalid packet, dropping %s",xmlnode2str(x));        xmlnode_free(x);        return NULL;    }    /* make sure each packet has the basics, norm has a to/from, log has a type, xdb has a namespace */    switch(p->type)    {    case p_LOG:        if(xmlnode_get_attrib(x,"type")==NULL)            p=NULL;        break;    case p_XDB:        if(xmlnode_get_attrib(x,"ns") == NULL)            p=NULL;        /* fall through */    case p_NORM:        if(xmlnode_get_attrib(x,"to")==NULL||xmlnode_get_attrib(x,"from")==NULL)            p=NULL;        break;    case p_ROUTE:        if(xmlnode_get_attrib(x,"to")==NULL)            p=NULL;        break;    case p_NONE:        p=NULL;        break;    }    if(p==NULL)    {        log_warn(NULL,"Packet Delivery Failed, invalid packet, dropping %s",xmlnode2str(x));        xmlnode_free(x);        return NULL;    }    p->host = p->id->server;    return p;}dpacket dpacket_copy(dpacket p){    dpacket p2;    p2 = dpacket_new(xmlnode_dup(p->x));    return p2;}

⌨️ 快捷键说明

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