时隔几个月才发这篇下文是因为期间比较忙, 其次又花了一个月的时间在对完成的第一份Jabberd2s后做了非常大的改动.但是为了能衔接Jabberd2 添加动态域名管理功能 (上) 内容, 本文还是接着它的方法把对c2s的更改post出来, 其实也非常简单, 有看过代码的应该就很了解了. 最后, 对现在Jabberd2s的修改现状做了点简单描述.
最复杂的sm部分在上篇已经讲过了, 和sm一样, c2s也维护了一个hosts的列表(其实另一个hosts列表c2s->sm_avail 在上一节已经由sm维护了)代表可用的服务域名, 在对XML配置文件修改后同样要使其生效也是在c2s/main.c里重新加载配置, 加载配置的函数大部分已经有了.
首先用同样的方法触发ReConfig:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 if (c2s_reconf) { log_write(c2s->log , LOG_NOTICE, "reloading some configuration items ..." ); config_t conf; conf = config_new(); if (conf && config_load(conf, config_file) == 0 ) { _c2s_hosts_expand_with_config(c2s, conf); config_free(conf); log_write(c2s->log , LOG_NOTICE, "reconfig hosts mapping ..." ); }else { log_write(c2s->log , LOG_WARNING, "couldn't reload config (%s)" , config_file); if (conf) config_free(conf); } c2s_reconf = 0 ; }
_c2s_hosts_expand_with_config
是新增的函数, 其关键代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 static void _c2s_hosts_expand_with_config(c2s_t c2s, config_t conf){ ... newhosts = xhash_new(1021 ); for (i = 0 ; i < elem->nvalues; i++) { host_t host = (host_t ) pmalloco(xhash_pool(newhosts), sizeof (struct host_st)); ... } if (xhash_iter_first(c2s->sessions)) do { xhv.sess_val = &sess; xhash_iter_get(c2s->sessions, NULL , NULL , xhv.val); if (sess->resources != NULL ) { host_t currhost = xhash_get(newhosts, sess->resources->jid->domain); if (currhost!= NULL ){ sess->host = currhost; }else { sess->active = 0 ; if (sess->s) sx_close(sess->s); } } } while (xhash_iter_next(c2s->sessions)); xhash_free(c2s->hosts); c2s->hosts = newhosts; }
这样就更新了c2s->hosts, 最主要的是要更新c2s->sessions里的host指针值, 剩下的c2s都会自己处理.
但是这里还有一个缺点, 在sx_ssl_server_addcert
添加SSL证书信息中,如果对重复即已存在的证书信息会删除原有并替换:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 int sx_ssl_server_addcert (...) { ... tmp = xhash_get(contexts, name); if (tmp != NULL ) SSL_CTX_free((SSL_CTX *) tmp); xhash_put(contexts, name, ctx); return 0 ; }
这可以自动更新证书, 但是对已经移除的domain证书却没有删除, 要实现这个并不难, 后期会修复这个bug.
————————————–分割线————————————–
目前对Jabberd2s已经有了很大的修改, 已经不再从XML配置文件里读取hosts的配置信息, 取而代之在数据库里添加了一张host表, 有更强的可控性, 不过目前只有对mysql支持, 没有照顾其它的数据库(没有更新到GitHub的原因之一).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 MariaDB [jabberd2]> desc host; +------------------+------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------------+------------+------+-----+---------+----------------+ | domain | text | NO | PRI | NULL | | | realm | tinytext | NO | MUL | NULL | | | object-sequence | bigint(20) | NO | MUL | NULL | auto_increment | | pemfile | text | YES | | NULL | | | verify-mode | tinyint(4) | YES | | 0 | | | cachain | text | YES | | NULL | | | require-starttls | tinyint(4) | YES | | 0 | | | register-enable | tinyint(4) | YES | | 0 | | | register-oob | text | YES | | NULL | | | instructions | mediumtext | YES | | NULL | | | password-change | tinyint(4) | YES | | 0 | | | status | tinytext | YES | | NULL | | +------------------+------------+------+-----+---------+----------------+
sm和c2s都会读取该表, 但该表由c2s维护负责删改,最后一个字段表明状态, 可以有normal, add, mod, offline, delete. 正常是normal, 切换状态可以直接修改其status值, 然后发送SIGUSR1信号触发ReConfig. 由于router的机制缘故, 无法从offline状态切换到delete, 要删除的话得先切换到normal状态, 然后再delete. 我也在想或许不需要delete状态, 直接从表删除条目也是可以更新的(没有更新到GitHub的原因之二), 或许待更完善或者有空了会更新到git上.