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

📄 dialback_out.c

📁 jabber server jabber server jabber server jabber server
💻 C
📖 第 1 页 / 共 3 页
字号:
    xmlnode x;    spool errmsg = NULL;    char *connect_results = NULL;    char *bounce_reason = NULL;    xhash_zap(c->d->out_connecting,jid_full(c->key));    /* get the results of connection attempts */    if (c->connect_results != NULL) {	connect_results = spool_print(c->connect_results);    }    /* if there was never any ->m set but there's a queue yet, then we probably never got connected, just make a note of it */    if(c->m == NULL && c->q != NULL) {	log_notice(c->d->i->id, "failed to establish connection to %s, %s: %s", c->key->server, dialback_out_connection_state_string(c->connection_state), connect_results);    }    /* if there's any packets in the queue, flush them! */    cur = c->q;    if (cur != NULL) {	/* generate bounce message, but only if there are queued messages */	errmsg = spool_new(c->p);	spool_add(errmsg, "Failed to deliver stanza to other server while ");	spool_add(errmsg, dialback_out_connection_state_string(c->connection_state));	spool_add(errmsg, ": ");	spool_add(errmsg, connect_results);	bounce_reason = spool_print(errmsg);    }    while(cur != NULL) {        next = cur->next;        deliver_fail(dpacket_new(cur->x), bounce_reason ? bounce_reason : "Could not send stanza to other server");        cur = next;    }    /* also kill any validations still waiting */    for(x = xmlnode_get_firstchild(c->verifies); x != NULL; x = xmlnode_get_nextsibling(x)) {        jutil_tofrom(x);        dialback_in_verify(c->d, xmlnode_dup(x)); /* it'll take these verifies and trash them */    }    pool_free(c->p);}/** * handle packets we receive from our router for other hosts * * (packets to our instances address are not handled here, but in dialback_in_verify()) * * We have to: * - revert some magic we are using to talk to the dns resolver for db:verify packets * - check if there is already a connection and establish one else * - send or queue the packet (depending if we already authorized and if it's a db:verify) * * @param d the dialback instance * @param x the packet * @param ip where to connect to (if necessary) */void dialback_out_packet(db d, xmlnode x, char *ip){    jid to, from, key;    miod md;    int verify = 0;    dboq q;    dboc c;    to = jid_new(xmlnode_pool(x),xmlnode_get_attrib(x,"to"));    from = jid_new(xmlnode_pool(x),xmlnode_get_attrib(x,"from"));    if(to == NULL || from == NULL)    {        log_warn(d->i->id, "dropping packet, invalid to or from: %s", xmlnode2str(x));        xmlnode_free(x);        return;    }    log_debug2(ZONE, LOGT_IO, "dbout packet[%s]: %s",ip,xmlnode2str(x));    /* db:verify packets come in with us as the sender */    if(j_strcmp(from->server,d->i->id) == 0)    {        verify = 1;        /* fix the headers, restore the real from */	/* (I think we wouldn't need to from/ofrom thing anymore because we have dnsqueryby, that we need for s2s clustering) */        xmlnode_put_attrib(x,"from",xmlnode_get_attrib(x,"ofrom"));        xmlnode_hide_attrib(x,"ofrom");	xmlnode_hide_attrib(x,"dnsqueryby");        from = jid_new(xmlnode_pool(x),xmlnode_get_attrib(x,"from"));    }    /* build the standard key */    key = jid_new(xmlnode_pool(x),to->server);    jid_set(key, from->server, JID_RESOURCE);    /* try to get an active connection */    md = xhash_get(d->out_ok_db, jid_full(key));    log_debug2(ZONE, LOGT_IO, "outgoing packet with key %s and located existing %X",jid_full(key),md);    /* yay! that was easy, just send the packet :) */    if(md != NULL)    {        /* if we've got an ip sent, and a connected host, we should be registered! */        if(ip != NULL)            register_instance(md->d->i, key->server);        dialback_miod_write(md, x);        return;    }    /* get a connection to the other server */    c = dialback_out_connection(d, key, dialback_ip_get(d, key, ip), verify ? not_requested : want_request);    log_debug2(ZONE, LOGT_IO, "got connection %x for request %s (%s)", c, jid_full(key), verify ? "not_requested" : "want_request");    /* verify requests can't be queued, they need to be sent outright */    if(verify)    {        if(c == NULL)        {            jutil_tofrom(x); /* pretend it bounced */            dialback_in_verify(d, x); /* no connection to send db:verify to, bounce back to in to send failure */            return;        }        /* if the server is already connected, just write it */        if(c->m != NULL)        {            mio_write(c->m, x, NULL, -1);        }else{  /* queue it so that it's written after we're connected */            xmlnode_insert_tag_node(c->verifies,x);            xmlnode_free(x);        }        return;    }    if(c == NULL)    {        log_warn(d->i->id,"dropping a packet that was missing an ip to connect to: %s",xmlnode2str(x));        xmlnode_free(x);        return;    }    /* insert into the queue */    q = pmalloco(xmlnode_pool(x), sizeof(_dboq));    q->stamp = time(NULL);    q->x = x;    q->next = c->q;    c->q = q;}/** * handle the events (incoming stanzas) on an outgoing dialback socket, which isn't much of a job * * The only packets we have to expect on an outgoing dialback socket are db:verify and maybe stream:error * * @param m the connection the packet has been received on * @param flags the mio action, we ignore anything but MIO_XML_NODE * @param arg the dialback instance * @param the packet that has been received */void dialback_out_read_db(mio m, int flags, void *arg, xmlnode x) {    db d = (db)arg;    if(flags != MIO_XML_NODE) return;    /* it's either a valid verify response, or bust! */    if(j_strcmp(xmlnode_get_name(x),"db:verify") == 0) {        dialback_in_verify(d, x);        return;    }    if(j_strcmp(xmlnode_get_name(x),"stream:error") == 0) {	spool s = spool_new(x->p);	streamerr errstruct = pmalloco(x->p, sizeof(_streamerr));	char *errmsg = NULL;	/* generate the error message */	xstream_parse_error(x->p, x, errstruct);	xstream_format_error(s, errstruct);	errmsg = spool_print(s);	/* logging */	switch (errstruct->severity) {	    case normal:		log_debug2(ZONE, LOGT_IO, "stream error on outgoing db conn to %s: %s", mio_ip(m), errmsg);		break;	    case configuration:	    case feature_lack:	    case unknown:		log_warn(d->i->id, "received stream error on outgoing db conn to %s: %s", mio_ip(m), errmsg);		break;	    case error:	    default:		log_error(d->i->id, "received stream error on outgoing db conn to %s: %s", mio_ip(m), errmsg);	}    } else {        mio_write(m, NULL, "<stream:error><undefined-condition xmlns='urn:ietf:params:xml:ns:xmpp-streams'/><text xmlns='urn:ietf:params:xml:ns:xmpp-streams' xml:lang='en'>Received data on a send-only socket. You are not Allowed to send data on this socket!</text></stream:error>", -1);    }        mio_close(m);    xmlnode_free(x);}/** * util to flush queue to mio * * Take elements from the queue and send it to a miod connection. * * @param md the miod connection * @param q the queue to flush */void dialback_out_qflush(miod md, dboq q){    dboq cur, next;    cur = q;    while(cur != NULL)    {        next = cur->next;        dialback_miod_write(md, cur->x);        cur = next;    }}/** * handle the early connection process * * What to do: * - Send stream header after mio connected a socket for us * - Process the incoming stream header * - Check for incoming stream:features * - Generate db:result queries to start authorizing for a domain * - Process incoming db:verify queries * - Process incoming db:result responses (flush/send queue of waiting stanzas) */void dialback_out_read(mio m, int flags, void *arg, xmlnode x){    dboc c = (dboc)arg;    xmlnode cur;    miod md;    int version = 0;    char *dbns = NULL;    log_debug2(ZONE, LOGT_IO, "dbout read: fd %d flag %d key %s",m->fd, flags, jid_full(c->key));    switch(flags) {	case MIO_NEW:	    log_debug2(ZONE, LOGT_IO, "NEW outgoing server socket connected at %d",m->fd);	    /* add to the connect result messages */	    if (c->connect_results != NULL) {		spool_add(c->connect_results, "Connected");	    }	    c->connection_state = connected;	    /* outgoing conneciton, write the header */	    cur = xstream_header("jabber:server", c->key->server, NULL);	    xmlnode_hide_attrib(cur, "id");					/* no, we don't need the id on this stream */	    xmlnode_put_attrib(cur,"xmlns:db","jabber:server:dialback");	/* flag ourselves as dialback capable */	    if (c->xmpp_version == 1) {					/* should we flag XMPP support? */		xmlnode_put_attrib(cur, "version", "1.0");	    }	    mio_write(m, NULL, xstream_header_char(cur), -1);	    xmlnode_free(cur);	    return;	case MIO_XML_ROOT:	    log_debug2(ZONE, LOGT_IO, "Incoming root %s",xmlnode2str(x));	    c->connection_state = got_streamroot;	    /* validate namespace */	    if(j_strcmp(xmlnode_get_attrib(x,"xmlns"),"jabber:server") != 0) {		mio_write(m, NULL, "<stream:error><invalid-namespace xmlns='urn:ietf:params:xml:ns:xmpp-streams'/><text xmlns='urn:ietf:params:xml:ns:xmpp-streams' xml:lang='en'>Invalid Stream Header!</text></stream:error>", -1);		mio_close(m);		break;	    }	    /* remember the stream id the connected entity assigned ... required to do dialback */	    c->stream_id = pstrdup(c->p, xmlnode_get_attrib(x,"id"));	    if (c->stream_id == NULL) {		mio_write(m, NULL, "<stream:error><invalid-id xmlns='urn:ietf:params:xml:ns:xmpp-streams'/><text xmlns='urn:ietf:params:xml:ns:xmpp-streams' xml:lang='en'>You are missing the id attribute in your stream header!</text></stream:error>", -1);		mio_close(m);		break;	    }	    /* make sure we're not connecting to ourselves */	    if(xhash_get(c->d->in_id,c->stream_id) != NULL)	    {		log_alert(c->key->server,"hostname maps back to ourselves!- No service defined for this hostname, can not handle request. Check jabberd configuration.");		mio_write(m, NULL, "<stream:error><internal-server-error xmlns='urn:ietf:params:xml:ns:xmpp-streams'/><text xmlns='urn:ietf:params:xml:ns:xmpp-streams' xml:lang='en'>Mirror Mirror on the wall (we connected to ourself)</text></stream:error>", -1);		mio_close(m);		break;	    }	    /* check version */	    version = j_atoi(xmlnode_get_attrib(x, "version"), 0);	    dbns = xmlnode_get_attrib(x, "xmlns:db");

⌨️ 快捷键说明

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