📄 client.c
字号:
{ /* they didn't send a to="" and no valid alias */ mio_write(m, NULL, "<stream:error><improper-addressing xmlns='urn:ietf:params:xml:ns:xmpp-streams'/><text xmlns='urn:ietf:params:xml:ns:xmpp-streams' xml:lang='en'>Did not specify a valid to argument</text></stream:error></stream:stream>", -1); mio_close(m); } else if(j_strncasecmp(xmlnode_get_attrib(x, "xmlns:stream"), "http://etherx.jabber.org/streams", 32) != 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 Namespace</text></stream:error></stream:stream>", -1); mio_close(m); } /* send stream features for XMPP version 1.0 streams */ if (version>=1) { xmlnode features = xmlnode_new_tag("stream:features");#ifdef HAVE_SSL /* TLS possible on this connection? */ if (mio_ssl_starttls_possible(m, cd->session_id->server)) { xmlnode starttls = NULL; starttls = xmlnode_insert_tag(features, "starttls"); xmlnode_put_attrib(starttls, "xmlns", NS_XMPP_TLS); }#endif /* HAVE_SSL */ /* advertise registration of accounts? */ if (cd->si->register_feature != 0) { xmlnode register_element = NULL; register_element = xmlnode_insert_tag(features, "register"); xmlnode_put_attrib(register_element, "xmlns", NS_REGISTER_FEATURE); } /* Non-SASL Authentication JEP-0078 */ xmlnode_put_attrib(xmlnode_insert_tag(features, "auth"), "xmlns", NS_IQ_AUTH); /* send the stream:features */ mio_write(m, features, NULL, 0); } xmlnode_free(x); break; case MIO_XML_NODE: /* make sure alias is upheld */ if(cd->aliased) { jid j = jid_new(xmlnode_pool(x), xmlnode_get_attrib(x, "to")); if(j != NULL && j_strcmp(j->server, cd->sending_id->server) == 0) { jid_set(j, cd->session_id->server, JID_SERVER); xmlnode_put_attrib(x, "to", jid_full(j)); } j = jid_new(xmlnode_pool(x), xmlnode_get_attrib(x, "from")); if(j != NULL && j_strcmp(j->server, cd->sending_id->server) == 0) { jid_set(j, cd->session_id->server, JID_SERVER); xmlnode_put_attrib(x, "from", jid_full(j)); } } cd = (cdata)arg; if (cd->state == state_UNKNOWN) { /* only allow auth and registration queries at this point */ xmlnode q = xmlnode_get_tag(x, "query"); if (j_strcmp(xmlnode_get_name(x), "starttls") == 0 && j_strcmp(xmlnode_get_attrib(x, "xmlns"), NS_XMPP_TLS) == 0) { /* starting TLS possible? */#ifdef HAVE_SSL if (mio_ssl_starttls_possible(m, cd->session_id->server)) { /* ACK the start */ xmlnode proceed = xmlnode_new_tag("proceed"); xmlnode_put_attrib(proceed, "xmlns", NS_XMPP_TLS); mio_write(m, proceed, NULL, 0); /* start TLS on this connection */ if (mio_xml_starttls(m, 0, cd->session_id->server) != 0) { /* starttls failed */ mio_close(m); } } else {#endif /* NACK */ mio_write(m, NULL, "<failure xmlns='" NS_XMPP_TLS "'/></stream:stream>", -1); mio_close(m);#ifdef HAVE_SSL }#endif /* free the <starttls/> element and return */ xmlnode_free(x); return; } else if (!NSCHECK(q, NS_AUTH) && !NSCHECK(q, NS_REGISTER)) { mio_wbq q; /* queue packet until authed */ q = pmalloco(xmlnode_pool(x), sizeof(_mio_wbq)); q->x = x; pth_msgport_put(cd->pre_auth_mp, (void*)q); return; } else if (NSCHECK(q, NS_AUTH)) { if(j_strcmp(xmlnode_get_attrib(x, "type"), "set") == 0) { /* if we are authing against the server */ xmlnode_put_attrib(xmlnode_get_tag(q, "digest"), "sid", cd->sid); cd->auth_id = pstrdup(m->p, xmlnode_get_attrib(x, "id")); if(cd->auth_id == NULL) { cd->auth_id = pstrdup(m->p, "pthsock_client_auth_ID"); xmlnode_put_attrib(x, "id", "pthsock_client_auth_ID"); } jid_set(cd->session_id, xmlnode_get_data(xmlnode_get_tag(xmlnode_get_tag(x, "query?xmlns=jabber:iq:auth"), "username")), JID_USER); jid_set(cd->session_id, xmlnode_get_data(xmlnode_get_tag(xmlnode_get_tag(x, "query?xmlns=jabber:iq:auth"), "resource")), JID_RESOURCE); x = pthsock_make_route(x, jid_full(cd->session_id), cd->client_id, "auth"); deliver(dpacket_new(x), cd->si->i); } else if(j_strcmp(xmlnode_get_attrib(x, "type"), "get") == 0) { /* we are just doing an auth get */ /* just deliver the packet */ jid_set(cd->session_id, xmlnode_get_data(xmlnode_get_tag(xmlnode_get_tag(x, "query?xmlns=jabber:iq:auth"), "username")), JID_USER); x = pthsock_make_route(x, jid_full(cd->session_id), cd->client_id, "auth"); deliver(dpacket_new(x), cd->si->i); } } else if (NSCHECK(q, NS_REGISTER)) { jid_set(cd->session_id, xmlnode_get_data(xmlnode_get_tag(xmlnode_get_tag(x, "query?xmlns=jabber:iq:register"), "username")), JID_USER); x = pthsock_make_route(x, jid_full(cd->session_id), cd->client_id, "auth"); deliver(dpacket_new(x), cd->si->i); } } else { /* normal delivery of packets after authed */ x = pthsock_make_route(x, jid_full(cd->session_id), cd->client_id, NULL); deliver(dpacket_new(x), cd->si->i); cd->last_activity = time(NULL); } break; }}void pthsock_client_listen(mio m, int flag, void *arg, xmlnode x){ smi s__i = (void*)arg; cdata cd; if(flag != MIO_NEW) return; s__i = (smi)arg; cd = pthsock_client_cdata(m, s__i); xhash_put(cd->si->users, cd->client_id, cd); mio_reset(m, pthsock_client_read, (void*)cd);}void _pthsock_client_timeout(xht h, const char *key, void *data, void *arg){ time_t timeout; cdata cd = (cdata)data; if(cd->state == state_AUTHD) return; timeout = time(NULL) - cd->si->auth_timeout; log_debug2(ZONE, LOGT_IO, "[%s] timeout: %d, connect time %d: fd %d", ZONE, timeout, cd->connect_time, cd->m->fd); if(cd->connect_time < timeout) { mio_write(cd->m, NULL, "<stream:error><connection-timeout xmlns='urn:ietf:params:xml:ns:xmpp-streams'/><text xmlns='urn:ietf:params:xml:ns:xmpp-streams' xml:lang='en'>Timeout waiting for authentication</text></stream:error></stream:stream>", -1); xhash_zap(cd->si->users, mio_ip(cd->m)); mio_close(cd->m); }}/* auth timeout beat function */result pthsock_client_timeout(void *arg){ smi s__i = (smi)arg; if(s__i->users == NULL) return r_UNREG; xhash_walk(s__i->users, _pthsock_client_timeout, NULL); return r_DONE;}void _pthsock_client_heartbeat(xht h, const char *key, void *data, void *arg){ time_t skipbeat; cdata cd = (cdata)data; skipbeat = time(NULL) - cd->si->heartbeat; if ( (cd->state == state_AUTHD) && (cd->last_activity < skipbeat) ) { log_debug2(ZONE, LOGT_IO, "[%s] heartbeat on fd %d", ZONE, cd->m->fd); mio_write(cd->m, NULL, " \n", -1); }}/* auth timeout beat function */result pthsock_client_heartbeat(void *arg){ smi s__i = (smi)arg; if(s__i->users == NULL) return r_UNREG; xhash_walk(s__i->users, _pthsock_client_heartbeat, NULL); return r_DONE;}void _pthsock_client_shutdown(xht h, const char *key, void *data, void *arg){ cdata cd = (cdata)data; log_debug2(ZONE, LOGT_CLEANUP, "[%s] closing down user %s from ip: %s", ZONE, jid_full(cd->session_id), mio_ip(cd->m)); mio_close(cd->m);}/* cleanup function */void pthsock_client_shutdown(void *arg){ smi s__i = (smi)arg; xmlnode_free(s__i->cfg); log_debug2(ZONE, LOGT_CLEANUP, "[%s] Shutting Down", ZONE); xhash_walk(s__i->users, _pthsock_client_shutdown, NULL); xhash_free(s__i->users); s__i->users = NULL; if (s__i->aliases) xhash_free(s__i->aliases);}/* everything starts here */void pthsock_client(instance i, xmlnode x){ smi s__i; xdbcache xc; xmlnode cur; int set_rate = 0; /* Default false; did they want to change the rate parameters */ int rate_time, rate_points; char *host; struct karma *k = karma_new(i->p); /* Get new inialized karma */ int set_karma = 0; /* Default false; Did they want to change the karma parameters */ log_debug2(ZONE, LOGT_INIT, "[%s] pthsock_client loading", ZONE); s__i = pmalloco(i->p, sizeof(_smi)); s__i->auth_timeout = DEFAULT_AUTH_TIMEOUT; s__i->heartbeat = DEFAULT_HEARTBEAT; s__i->i = i; s__i->aliases = xhash_new(7); s__i->users = xhash_new(503); s__i->register_feature = 1; /* get the config */ xc = xdb_cache(i); s__i->cfg = xdb_get(xc, jid_new(xmlnode_pool(x), "config@-internal"), "jabber:config:pth-csock"); s__i->host = host = i->id; for(cur = xmlnode_get_firstchild(s__i->cfg); cur != NULL; cur = cur->next) { if(cur->type != NTYPE_TAG) continue; if(j_strcmp(xmlnode_get_name(cur), "alias") == 0) { char *host, *to; if((to = xmlnode_get_attrib(cur, "to")) == NULL) continue; host = xmlnode_get_data(cur); if(host != NULL) { xhash_put(s__i->aliases, host, to); } else { xhash_put(s__i->aliases, "default", to); } } else if(j_strcmp(xmlnode_get_name(cur), "authtime") == 0) { s__i->auth_timeout = j_atoi(xmlnode_get_data(cur), 0); } else if(j_strcmp(xmlnode_get_name(cur), "heartbeat") == 0) { s__i->heartbeat = j_atoi(xmlnode_get_data(cur), 0); } else if(j_strcmp(xmlnode_get_name(cur), "rate") == 0) { 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 */ } else if(j_strcmp(xmlnode_get_name(cur), "karma") == 0) { 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 */ } else if (j_strcmp(xmlnode_get_name(cur), "noregister") == 0) { s__i->register_feature = 0; } } /* start listening */ if((cur = xmlnode_get_tag(s__i->cfg, "ip")) != NULL) { for(; cur != NULL; xmlnode_hide(cur), cur = xmlnode_get_tag(s__i->cfg, "ip")) { mio m; m = mio_listen(j_atoi(xmlnode_get_attrib(cur, "port"), 5222), xmlnode_get_data(cur), pthsock_client_listen, (void*)s__i, 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); } }#ifdef HAVE_SSL /* listen on SSL sockets */ if((cur = xmlnode_get_tag(s__i->cfg, "ssl")) != NULL) { for(; cur != NULL; xmlnode_hide(cur), cur = xmlnode_get_tag(s__i->cfg, "ssl")) { mio m; m = mio_listen(j_atoi(xmlnode_get_attrib(cur, "port"), 5223), xmlnode_get_data(cur), pthsock_client_listen, (void*)s__i, MIO_SSL_ACCEPT, mio_handlers_new(MIO_SSL_READ, MIO_SSL_WRITE, MIO_XML_PARSER)); if(m == NULL) return; /* Set New rate and points */ if(set_rate == 1) mio_rate(m, rate_time, rate_points); /* set karma valuse */ if(set_karma == 1) mio_karma2(m, k); } } #endif /* register data callbacks */ register_phandler(i, o_DELIVER, pthsock_client_packets, (void*)s__i); pool_cleanup(i->p, pthsock_client_shutdown, (void*)s__i); if(s__i->auth_timeout) register_beat(5, pthsock_client_timeout, (void*)s__i); if(s__i->heartbeat) { log_debug2(ZONE, LOGT_INIT, "Registering heartbeat: %d", s__i->heartbeat); /* Register a heartbeat to catch dead sockets. */ register_beat(s__i->heartbeat, pthsock_client_heartbeat, (void*)s__i); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -