in.c
来自「这是一个完全开放的」· C语言 代码 · 共 541 行 · 第 1/2 页
C
541 行
/* * jabberd - Jabber Open Source Server * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney, * Ryan Eatmon, Robert Norris * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA */#include "s2s.h"/* * we handle incoming connections, and the packets that arrive on them. * * action points: * * event_STREAM - new incoming connection * - create new dbconn (key stream id) * - DONE * * event_PACKET: <result from='them' to='us'>key</result> - auth request * - get dbconn for this sx * - if dbconn state is valid * - send result: <result to='them' from='us' type='valid'/> * - DONE * - out_packet(s2s, <verify to='them' from='us' id='stream id'>key</verify>) * - DONE * * event_PACKET: <verify from='them' to='us' id='123'>key</verify> - validate their key * - generate dbkey: sha1(secret+remote+id) * - if their key matches dbkey * - send them: <verify to='them' from='us' id='123' type='valid'/> * - else * - send them: <verify to='them' from='us' id='123' type='invalid'/> * - DONE * * event_PACKET - they're trying to send us something * - get dbconn for this sx * - if dbconn state is invalid * - drop packet * - DONE * - write packet to router * - DONE *//* forward decls */static int _in_sx_callback(sx_t s, sx_event_t e, void *data, void *arg);static void _in_result(conn_t in, nad_t nad);static void _in_verify(conn_t in, nad_t nad);static void _in_packet(conn_t in, nad_t nad);int in_mio_callback(mio_t m, mio_action_t a, int fd, void *data, void *arg) { conn_t in = (conn_t) arg; s2s_t s2s = (s2s_t) arg; struct sockaddr_storage sa; int namelen = sizeof(sa), port, nbytes; switch(a) { case action_READ: log_debug(ZONE, "read action on fd %d", fd); ioctl(fd, FIONREAD, &nbytes); if(nbytes == 0) { sx_kill(in->s); return 0; } return sx_can_read(in->s); case action_WRITE: log_debug(ZONE, "write action on fd %d", fd); return sx_can_write(in->s); case action_CLOSE: log_debug(ZONE, "close action on fd %d", fd); /* !!! logging */ log_write(in->s2s->log, LOG_NOTICE, "[%d] [%s, port=%d] disconnect", fd, in->ip, in->port); jqueue_push(in->s2s->dead, (void *) in->s, 0); xhash_zap(in->s2s->in, in->key); xhash_free(in->states); xhash_free(in->routes); if(in->key != NULL) free(in->key); free(in); break; case action_ACCEPT: s2s = (s2s_t) arg; log_debug(ZONE, "accept action on fd %d", fd); getpeername(fd, (struct sockaddr *) &sa, &namelen); port = j_inet_getport(&sa); log_write(s2s->log, LOG_NOTICE, "[%d] [%s, port=%d] incoming connection", fd, (char *) data, port); /* new conn */ in = (conn_t) malloc(sizeof(struct conn_st)); memset(in, 0, sizeof(struct conn_st)); in->s2s = s2s; strcpy(in->ip, (char *) data); in->port = port; in->states = xhash_new(101); in->fd = fd; in->init_time = time(NULL); in->s = sx_new(s2s->sx_env, in->fd, _in_sx_callback, (void *) in); mio_app(m, in->fd, in_mio_callback, (void *) in);#ifdef HAVE_SSL sx_server_init(in->s, S2S_DB_HEADER | ((s2s->local_pemfile != NULL) ? SX_SSL_STARTTLS_OFFER : 0) );#else sx_server_init(in->s, S2S_DB_HEADER);#endif break; } return 0;}static int _in_sx_callback(sx_t s, sx_event_t e, void *data, void *arg) { conn_t in = (conn_t) arg; sx_buf_t buf = (sx_buf_t) data; int len; sx_error_t *sxe; nad_t nad; switch(e) { case event_WANT_READ: log_debug(ZONE, "want read"); mio_read(in->s2s->mio, in->fd); break; case event_WANT_WRITE: log_debug(ZONE, "want write"); mio_write(in->s2s->mio, in->fd); break; case event_READ: log_debug(ZONE, "reading from %d", in->fd); /* do the read */ len = recv(in->fd, buf->data, buf->len, 0); if(len < 0) { if(errno == EWOULDBLOCK || errno == EINTR || errno == EAGAIN) { buf->len = 0; return 0; } log_write(in->s2s->log, LOG_NOTICE, "[%d] [%s, port=%d] read error: %s (%d)", in->fd, in->ip, in->port, strerror(errno), errno); sx_kill(s); return -1; } else if(len == 0) { /* they went away */ sx_kill(s); return -1; } log_debug(ZONE, "read %d bytes", len); buf->len = len; return len; case event_WRITE: log_debug(ZONE, "writing to %d", in->fd); len = send(in->fd, buf->data, buf->len, 0); if(len >= 0) { log_debug(ZONE, "%d bytes written", len); return len; } if(errno == EWOULDBLOCK || errno == EINTR || errno == EAGAIN) return 0; log_write(in->s2s->log, LOG_NOTICE, "[%d] [%s, port=%d] write error: %s (%d)", in->fd, in->ip, in->port, strerror(errno), errno); sx_kill(s); return -1; case event_ERROR: sxe = (sx_error_t *) data; log_write(in->s2s->log, LOG_NOTICE, "[%d] [%s, port=%d] error: %s (%s)", in->fd, in->ip, in->port, sxe->generic, sxe->specific); break; case event_STREAM: case event_OPEN: log_debug(ZONE, "STREAM or OPEN event from %s port %d (id %s)", in->ip, in->port, s->id); /* first time, bring them online */ if ((!in->online)||(strcmp(in->key,s->id)!=0)) { log_debug(ZONE, "incoming conn from %s port %d is online (id %s)", in->ip, in->port, s->id); in->online = 1; /* record the id */ if (in->key != NULL) log_debug(ZONE,"adding new SSL stream id %s for stream id %s", s->id, in->key); in->key = strdup(s->id); /* track it */ xhash_put(in->s2s->in, in->key, (void *) in); } break; case event_PACKET: nad = (nad_t) data; /* dialback packets */ if(NAD_NURI_L(nad, NAD_ENS(nad, 0)) == strlen(uri_DIALBACK) && strncmp(uri_DIALBACK, NAD_NURI(nad, NAD_ENS(nad, 0)), strlen(uri_DIALBACK)) == 0) { /* only result and verify mean anything */ if(NAD_ENAME_L(nad, 0) == 6) { if(strncmp("result", NAD_ENAME(nad, 0), 6) == 0) { _in_result(in, nad); return 0; } if(strncmp("verify", NAD_ENAME(nad, 0), 6) == 0) { _in_verify(in, nad); return 0; } } log_debug(ZONE, "unknown dialback packet, dropping it"); nad_free(nad); return 0; } /* * not dialback, so it has to be a normal-ish jabber packet: * - jabber:client or jabber:server * - message, presence or iq * - has to and from attributes */ if(!( /* must be jabber:client or jabber:server */ NAD_ENS(nad, 0) >= 0 &&
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?