📄 dialback.c
字号:
char *dialback_ip_get(db d, jid host, char *ip){ char *ret; if(host == NULL) return NULL; if(ip != NULL) return ip; ret = pstrdup(host->p,xmlnode_get_attrib((xmlnode)xhash_get(d->nscache,host->server),"i")); log_debug2(ZONE, LOGT_IO, "returning cached ip %s for %s",ret,host->server); return ret;}/** * put an IP address in our DNS cache * * @param d db structure which contains the context of the dialback component instance * @param host the host for which we put the IP address * @param ip the IP address */void dialback_ip_set(db d, jid host, char *ip){ xmlnode cache, old; if(host == NULL || ip == NULL) return; /* first, get existing cache so we can dump it later */ old = (xmlnode)xhash_get(d->nscache,host->server); /* new cache */ cache = xmlnode_new_tag("d"); xmlnode_put_attrib(cache,"h",host->server); xmlnode_put_attrib(cache,"i",ip); xhash_put(d->nscache,xmlnode_get_attrib(cache,"h"),(void*)cache); log_debug2(ZONE, LOGT_IO, "cached ip %s for %s",ip,host->server); /* free any old entry that's been replaced */ xmlnode_free(old);}/** * phandler callback, send packets to another server * * This is where the dialback instance receives packets from the jabberd framework * * @param i the dialback instance we are running in * @param dp the dialback packet * @param arg pointer to the db structure with the context of the dialback component instance * @return always r_DONE */result dialback_packets(instance i, dpacket dp, void *arg){ db d = (db)arg; xmlnode x = dp->x; char *ip = NULL; /* routes are from dnsrv w/ the needed ip */ if(dp->type == p_ROUTE) { x = xmlnode_get_firstchild(x); ip = xmlnode_get_attrib(dp->x,"ip"); } /* all packets going to our "id" go to the incoming handler, * it uses that id to send out db:verifies to other servers, * and end up here when they bounce */ if(j_strcmp(xmlnode_get_attrib(x,"to"),d->i->id) == 0) { xmlnode_put_attrib(x,"to",xmlnode_get_attrib(x,"ofrom")); xmlnode_hide_attrib(x,"ofrom"); /* repair the addresses */ xmlnode_hide_attrib(x,"dnsqueryby"); /* not needed anymore */ dialback_in_verify(d, x); return r_DONE; } dialback_out_packet(d, x, ip); return r_DONE;}/** * callback for walking each miod-value host hash tree, close connections that have been idle to long * * The timeout value is configured in the dialback component configuration using the <idletimeout/> * element. * * @param h the hash table containing all connections * @param key unused/ignored (the key of the value in the hash table) * @param data the value in the hash table = the structure holding the connection * @param arg unused/ignored */void _dialback_beat_idle(xht h, const char *key, void *data, void *arg){ miod md = (miod)data; if(((int)*(time_t*)arg - md->last) >= md->d->timeout_idle) { log_debug2(ZONE, LOGT_IO, "Idle Timeout on socket %d to %s",md->m->fd, md->m->ip); mio_write(md->m, NULL, "<stream:error><connection-timeout xmlns='urn:ietf:params:xml:ns:xmpp-streams'/><text xml:lang='en' xmlns='urn:ietf:params:xml:ns:xmpp-streams'>Closing an idle connection.</text></stream:error></stream:stream>", -1); mio_close(md->m); }}/** * initiate walking the hash of existing s2s connections to check if they have been idle to long * * called as a heartbeat function * * @param arg pointer to the structure holding the context of the dialback component instance * @return always r_DONE */result dialback_beat_idle(void *arg){ db d = (db)arg; time_t ttmp; log_debug2(ZONE, LOGT_EXECFLOW, "dialback idle check"); time(&ttmp); xhash_walk(d->out_ok_db,_dialback_beat_idle,(void*)&ttmp); xhash_walk(d->in_ok_db,_dialback_beat_idle,(void*)&ttmp); return r_DONE;}/** * init and register the dialback component in the server * * @param i the jabber server's data about this instance * @param x xmlnode of this instances configuration (???) */void dialback(instance i, xmlnode x){ db d; xmlnode cfg, cur; struct karma k; int max; int rate_time, rate_points; int set_rate = 0, set_karma=0; log_debug2(ZONE, LOGT_INIT, "dialback loading"); srand(time(NULL)); /* get the config */ cfg = xdb_get(xdb_cache(i),jid_new(xmlnode_pool(x),"config@-internal"),"jabber:config:dialback"); max = j_atoi(xmlnode_get_tag_data(cfg,"maxhosts"),997); d = pmalloco(i->p,sizeof(_db)); d->nscache = xhash_new(max); pool_cleanup(i->p, (pool_cleaner)xhash_free, d->nscache); d->out_connecting = xhash_new(67); pool_cleanup(i->p, (pool_cleaner)xhash_free, d->out_connecting); d->out_ok_db = xhash_new(max); pool_cleanup(i->p, (pool_cleaner)xhash_free, d->out_ok_db); d->in_id = xhash_new(max); pool_cleanup(i->p, (pool_cleaner)xhash_free, d->in_id); d->in_ok_db = xhash_new(max); pool_cleanup(i->p, (pool_cleaner)xhash_free, d->in_ok_db); d->hosts_xmpp = xhash_new(max); d->hosts_tls = xhash_new(max); d->i = i; d->timeout_idle = j_atoi(xmlnode_get_tag_data(cfg,"idletimeout"),900); d->timeout_packets = j_atoi(xmlnode_get_tag_data(cfg,"queuetimeout"),30); d->secret = pstrdup(i->p,xmlnode_get_tag_data(cfg,"secret")); if(d->secret == NULL) /* if there's no configured secret, make one on the fly */ d->secret = pstrdup(i->p,dialback_randstr()); /* Get rate info if it exists */ if((cur = xmlnode_get_tag(cfg, "rate")) != NULL) { rate_time = j_atoi(xmlnode_get_attrib(cur, "time"), 0); rate_points = j_atoi(xmlnode_get_attrib(cur, "points"), 0); set_rate = 1; /* set to true */ } /* Get karma info if it exists */ if((cur = xmlnode_get_tag(cfg, "karma")) != NULL) { k.val = j_atoi(xmlnode_get_tag_data(cur, "init"), KARMA_INIT); k.max = j_atoi(xmlnode_get_tag_data(cur, "max"), KARMA_MAX); k.inc = j_atoi(xmlnode_get_tag_data(cur, "inc"), KARMA_INC); k.dec = j_atoi(xmlnode_get_tag_data(cur, "dec"), KARMA_DEC); k.restore = j_atoi(xmlnode_get_tag_data(cur, "restore"), KARMA_RESTORE); k.penalty = j_atoi(xmlnode_get_tag_data(cur, "penalty"), KARMA_PENALTY); k.reset_meter = j_atoi(xmlnode_get_tag_data(cur, "resetmeter"), KARMA_RESETMETER); set_karma = 1; /* set to true */ } if((cur = xmlnode_get_tag(cfg,"ip")) != NULL) { for(;cur != NULL; xmlnode_hide(cur), cur = xmlnode_get_tag(cfg,"ip")) { mio m; m = mio_listen(j_atoi(xmlnode_get_attrib(cur,"port"),5269),xmlnode_get_data(cur),dialback_in_read,(void*)d, MIO_LISTEN_XML); if(m == NULL) return; /* Set New rate and points */ if(set_rate == 1) mio_rate(m, rate_time, rate_points); /* Set New karma values */ if(set_karma == 1) mio_karma2(m, &k); } } else { /* no special config, use defaults */ mio m; m = mio_listen(5269,NULL,dialback_in_read,(void*)d, MIO_LISTEN_XML); if(m == NULL) return; /* Set New rate and points */ if(set_rate == 1) mio_rate(m, rate_time, rate_points); /* Set New karma values */ if(set_karma == 1) mio_karma2(m, &k); } /* check for hosts where we don't want to use XMPP streams or STARTTLS */ for (cur = xmlnode_get_tag(cfg, "host"); cur != NULL; cur = xmlnode_get_tag(cfg, "host")) { char *hostname = pstrdup(i->p, xmlnode_get_attrib(cur, "name")); if (hostname != NULL) { char *xmpp = pstrdup(i->p, xmlnode_get_attrib(cur, "xmpp")); char *tls = pstrdup(i->p, xmlnode_get_attrib(cur, "tls")); if (xmpp != NULL) { xhash_put(d->hosts_xmpp, hostname, xmpp); } if (tls != NULL) { xhash_put(d->hosts_tls, hostname, tls); } } xmlnode_hide(cur); } register_phandler(i,o_DELIVER,dialback_packets,(void*)d); register_beat(d->timeout_idle, dialback_beat_idle, (void *)d); register_beat(d->timeout_packets, dialback_out_beat_packets, (void *)d); xmlnode_free(cfg);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -