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

📄 dialback_out.c

📁 jabber server jabber server jabber server jabber server
💻 C
📖 第 1 页 / 共 3 页
字号:
/* -------------------------------------------------------------------------- * * License * * The contents of this file are subject to the Jabber Open Source License * Version 1.0 (the "JOSL").  You may not copy or use this file, in either * source code or executable form, except in compliance with the JOSL. You * may obtain a copy of the JOSL at http://www.jabber.org/ or at * http://www.opensource.org/.   * * Software distributed under the JOSL is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the JOSL * for the specific language governing rights and limitations under the * JOSL. * * Copyrights *  * Portions created by or assigned to Jabber.com, Inc. are  * Copyright (c) 1999-2002 Jabber.com, Inc.  All Rights Reserved.  Contact * information for Jabber.com, Inc. is available at http://www.jabber.com/. * * Portions Copyright (c) 1998-1999 Jeremie Miller. *  * Acknowledgements *  * Special thanks to the Jabber Open Source Contributors for their * suggestions and support of Jabber. *  * Alternatively, the contents of this file may be used under the terms of the * GNU General Public License Version 2 or later (the "GPL"), in which case * the provisions of the GPL are applicable instead of those above.  If you * wish to allow use of your version of this file only under the terms of the * GPL and not to allow others to use your version of this file under the JOSL, * indicate your decision by deleting the provisions above and replace them * with the notice and other provisions required by the GPL.  If you do not * delete the provisions above, a recipient may use your version of this file * under either the JOSL or the GPL.  *  *  * --------------------------------------------------------------------------*//** * @file dialback_out.c * @brief handle outgoing server to server connections * * This is where the server to server connection manager handles outgoing connections. * * There might be two types of outgoing connections: * - We want to send stanzas to the user of an other server, we then have to *   convince the peer, that we are who we claim to be (using dialback) * - We want to verify the identity of a peer that connected to us, using the *   dialback protocol. (We might reuse an outgoing connection of the other type *   if there is already one.) * * On outgoing connections, we need to send: * - An initial db:result element to tell the peer, that we want to authorize for *   the use of a domain, that the peer should verify that we are allowed to use *   this sending domain - and watch for the results to this * - db:verify elements to verify if a peer is allowed to use a domain as *   sender - and watch for the results * - After we are authorized by the peer to send stanzas from a domain, we send them. * - The starttls command, if the peer and we are supporting TLS. */#include "dialback.h"/** simple queue for out_queue */typedef struct dboq_struct{    int stamp;    xmlnode x;    struct dboq_struct *next;} *dboq, _dboq;/** * enumeration of dialback request states an outgoing connection can have */typedef enum {    not_requested,	/**< there was no packet yet, for that we want to request doing dialback (just sending db:verifys), and we could not yet send them  */    could_request,	/**< there was no packet yet, that requested doing dialback, but we could send out dialback requests */    want_request,	/**< we want to send a dialback request */    sent_request	/**< we did sent a dialback request */} db_request;/** * enumeration of connection establishment states an outgoing connection can have * * used for more detailed logging of failed connections */typedef enum {    created,		/**< outgoing connection request created, but not yet started to connect */    connecting,		/**< we started to connect, but have no connection yet */    connected,		/**< we have connected to the other host */    got_streamroot,	/**< we got the stream root of the other server */    waiting_features,	/**< we are waiting for the stream features on a XMPP1.0 connection */    got_features,	/**< we got the stream features on a XMPP1.0 connection */    sent_db_request,	/**< we sent out a dialback request */    db_succeeded,	/**< we had success with our dialback request */    db_failed,		/**< dialback failed */} db_connection_state;/* for connecting db sockets *//** * structure holding information about an outgoing connection */typedef struct {    char *ip;	/**< where to connect to (list of comma separated addresses of the format [ip]:port, [ip], ip:port, or ip) */    int stamp;	/**< when we started to connect to this peer */    db d;	/**< our dialback instance */    jid key;	/**< destination and source for this connection, format: dest/src */    xmlnode verifies; /**< waiting db:verify elements we have to send to the peer */    pool p;	/**< memory pool we are using for this connections data */    dboq q;	/**< pending stanzas, that need to be sent to the peer */    mio m;	/**< the mio connection this outgoing stream is using */    		/* original comment: for that short time when we're connected and open, but haven't auth'd ourselves yet */    int xmpp_version; /**< 0 if no version should be advertized, 1 if XMPP 1.0 should be advertized */    int xmpp_no_tls; /**< 0 if starting TLS is allowed, 1 if TLS should not be established */    char *stream_id; /**< the stream id the connected entity assigned */    db_request db_state; /**< if we want to send a <db:result/> and if we already did */    db_connection_state connection_state; /**< how far did we proceed in connecting to the other host */    spool connect_results; /**< result messages for the connection attempts */} *dboc, _dboc;/* forward declaration */void dialback_out_read(mio m, int flags, void *arg, xmlnode x);/** * try to start a connection based upon a given connect object * * Tell mio to connect to the peer and make dialback_out_read() the first mio handler * * @param c the connect object */void dialback_out_connect(dboc c){    char *ip, *col;    int port = 5269;    if(c->ip == NULL)        return;    ip = c->ip;    c->ip = strchr(ip,',');    if(c->ip != NULL) {	/* chop off this ip if there is another, track the other */        *c->ip = '\0';        c->ip++;    }    log_debug2(ZONE, LOGT_IO, "Attempting to connect to %s at %s",jid_full(c->key),ip);    /* to which IP we connect, for logging */    if (c->connect_results != NULL) {	spool_add(c->connect_results, ip);	spool_add(c->connect_results, ": ");    }    /* get the ip/port for io_select */#ifdef WITH_IPV6    if(ip[0] == '[') {	/* format "[ipaddr]:port" or "[ipaddr]" */	ip++;	col=strchr(ip,']');	if(col != NULL) {	    *col = '\0';	    if(col[1]==':') {		col++;	    }	}    } else {	/* format "ipaddr" or "ipaddr:port" */	col = strchr(ip, ':');	/* if it has at least two colons it is an IPv6 address */	if(col!=NULL && strchr(col+1,':')) {	    col = NULL;	}    }#else    col = strchr(ip,':');#endif    if(col != NULL) {        *col = '\0';        col++;        port = atoi(col);    }    /* we are now in the state of connecting */    c->connection_state = connecting;        mio_connect(ip, port, dialback_out_read, (void *)c, 20, MIO_CONNECT_XML);}/** * make a new outgoing connect(ion) object, and start to connect to the peer * * @param d the dialback instance * @param key destination and source for this connection * @param ip where to connect to (format see description to the _dboc structure) * @param db_state if sending a <db:result/> is requested * @return the newly created object */dboc dialback_out_connection(db d, jid key, char *ip, db_request db_state) {    dboc c;    pool p;    if((c = xhash_get(d->out_connecting, jid_full(key))) != NULL) {	/* db:request now wanted? */	if (db_state == want_request) {	    if (c->db_state == not_requested) {		log_debug2(ZONE, LOGT_IO, "packet for existing connection: state change not_requested -> want_request");		c->db_state = want_request;	    } else if (c->db_state == could_request) {		/* send <db:result/> to request dialback */		xmlnode db_result = xmlnode_new_tag("db:result");		xmlnode_put_attrib(db_result, "to", c->key->server);		xmlnode_put_attrib(db_result, "from", c->key->resource);		xmlnode_insert_cdata(db_result,  dialback_merlin(xmlnode_pool(db_result), c->d->secret, c->key->server, c->stream_id), -1);		mio_write(c->m,db_result, NULL, 0);		c->db_state = sent_request;		log_debug2(ZONE, LOGT_IO, "packet for existing connection: state change could_request -> sent_request");	    }	}        return c;    }    if(ip == NULL)        return NULL;    /* none, make a new one */    p = pool_heap(2*1024);    c = pmalloco(p, sizeof(_dboc));    c->p = p;    c->d = d;    c->key = jid_new(p,jid_full(key));    c->stamp = time(NULL);    c->verifies = xmlnode_new_tag_pool(p,"v");    c->ip = pstrdup(p,ip);    c->xmpp_version = j_strcmp(xhash_get(d->hosts_xmpp, c->key->server), "no")==0 ? 0 : 1;    if (c->xmpp_version == 0) {	log_debug2(ZONE, LOGT_IO, "disabled XMPP due to configuration for host %s", c->key->server);    }    c->xmpp_no_tls = j_strcmp(xhash_get(d->hosts_tls, c->key->server), "no")==0 ? 1 : 0;    if (c->xmpp_no_tls != 0) {	log_debug2(ZONE, LOGT_IO, "disabled STARTTLS due to configuration for host %s", c->key->server);    }    c->db_state = db_state;    c->connection_state = created;    c->connect_results = spool_new(p);    /* insert in the hash */    xhash_put(d->out_connecting, jid_full(c->key), (void *)c);    /* start the conneciton process */    dialback_out_connect(c);    return c;}/** * get the textual representation of a db_connection_state * * @param state the state * @return the textual representation */char *dialback_out_connection_state_string(db_connection_state state) {    switch (state) {	case created:	    return "connection object just created";	case connecting:	    return "connecting to other host";	case connected:	    return "connected to other host";	case got_streamroot:	    return "got the stream root";	case waiting_features:	    return "waiting for stream features on XMPP stream";	case got_features:	    return "got stream features on XMPP stream";	case sent_db_request:	    return "sent out dialback request";	case db_succeeded:	    return "dialback succeeded";	case db_failed:	    return "dialback failed";    }    return "unknown connection state";}/** * handle failed connection attempts, bounce pending stanzas and db:verify elements * * either we're connected, or failed, or something like that, but the connection process is kaput * * @param c the outgoing connect that failed */void dialback_out_connection_cleanup(dboc c){    dboq cur, next;

⌨️ 快捷键说明

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