summaryrefslogtreecommitdiffstats
path: root/daemon/logind
diff options
context:
space:
mode:
authorpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2009-06-16 00:53:12 +0800
committerpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2009-06-16 00:53:12 +0800
commit6be3bb768566fc4aa816378736f6bc10d57f0a52 (patch)
treed2b4d9ffcc874fe96bf38a378c0ec79741961520 /daemon/logind
parentb578fa5777b6776129fc6893755df2e6dfda21d4 (diff)
downloadpttbbs-6be3bb768566fc4aa816378736f6bc10d57f0a52.tar
pttbbs-6be3bb768566fc4aa816378736f6bc10d57f0a52.tar.gz
pttbbs-6be3bb768566fc4aa816378736f6bc10d57f0a52.tar.bz2
pttbbs-6be3bb768566fc4aa816378736f6bc10d57f0a52.tar.lz
pttbbs-6be3bb768566fc4aa816378736f6bc10d57f0a52.tar.xz
pttbbs-6be3bb768566fc4aa816378736f6bc10d57f0a52.tar.zst
pttbbs-6be3bb768566fc4aa816378736f6bc10d57f0a52.zip
* performance improvements
* accept all connections in one event * cached guest number testing git-svn-id: http://opensvn.csie.org/pttbbs/trunk/pttbbs@4624 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
Diffstat (limited to 'daemon/logind')
-rw-r--r--daemon/logind/logind.c141
1 files changed, 75 insertions, 66 deletions
diff --git a/daemon/logind/logind.c b/daemon/logind/logind.c
index 50134092..5cf08a12 100644
--- a/daemon/logind/logind.c
+++ b/daemon/logind/logind.c
@@ -9,11 +9,12 @@
// All rights reserved
// TODO:
-// 1. cache guest's usernum and check if too many guests online
+// 1. [done] cache guest's usernum and check if too many guests online
// 2. [drop] change close connection to 'wait until user hit then close'
// 3. [done] regular check text screen files instead of HUP?
// 4. [done] re-start mbbsd if pipe broken?
// 5. [drop] clean mbbsd pid log files?
+// 6. handle non-block i/o
#include <stdio.h>
#include <ctype.h>
@@ -39,8 +40,9 @@
#define LOGIND_MAX_FDS (100000)
#endif
+// some systems has hard limit of this to 128.
#ifndef LOGIND_SOCKET_QLEN
-#define LOGIND_SOCKET_QLEN (10)
+#define LOGIND_SOCKET_QLEN (100)
#endif
#ifndef AUTHFAIL_SLEEP_SEC
@@ -539,23 +541,26 @@ _set_bind_opt(int sock)
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*)&on, sizeof(on));
_set_connection_opt(sock);
+ // XXX note: NONBLOCK is not always inherited (eg, not on Linux).
+ // fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) | O_NONBLOCK);
+
return 0;
}
///////////////////////////////////////////////////////////////////////
// Draw Screen
-#ifndef SITE_BANNER
-#define SITE_BANNER ANSI_RESET "\r\n【" BBSNAME "】◎(" MYHOSTNAME ", " MYIP ") \r\n"
+#ifndef INSCREEN
+# define INSCREEN ANSI_RESET "\r\n【" BBSNAME "】◎(" MYHOSTNAME ", " MYIP ") \r\n"
#endif
-#ifdef STR_GUEST
+#ifdef STR_GUEST
# define MSG_GUEST ",或以[" STR_GUEST "]參觀"
#else
# define MSG_GUEST ""
#endif
-#ifdef STR_REGNEW
+#ifdef STR_REGNEW
# define MSG_REGNEW ",或以[new]註冊"
#else
# define MSG_REGNEW
@@ -615,7 +620,6 @@ load_text_screen_file(const char *filename, char **pptr)
}
wsz = sz*2 +1; // *2 for cr+lf, extra one byte for safe strchr().
- // XXX TODO use realloc?
assert(pptr);
s = *pptr;
s = realloc(s, wsz);
@@ -858,8 +862,11 @@ regular_check()
last_check_time = now;
g_overload = 0;
g_banned = 0;
+
+#ifndef LOGIND_DONT_CHECK_FREE_USERID
g_guest_too_many = 0;
g_guest_usernum = 0;
+#endif
if (cpuload(NULL) > MAX_CPULOAD)
{
@@ -919,6 +926,11 @@ auth_is_free_userid(const char *userid)
static int
auth_check_free_userid_allowance(const char *userid)
{
+#ifdef LOGIND_DONT_CHECK_FREE_USERID
+ // XXX experimental to disable free id checking
+ return 1;
+#endif
+
#ifdef STR_REGNEW
// accept all 'new' command.
if (strcasecmp(userid, STR_REGNEW) == 0)
@@ -932,6 +944,7 @@ auth_check_free_userid_allowance(const char *userid)
g_guest_too_many = 0;
# else
// if already too many guest, fast reject until next regular check.
+ // XXX TODO also cache if guest is not too many?
if (g_guest_too_many)
return 0;
@@ -953,6 +966,7 @@ auth_check_free_userid_allowance(const char *userid)
// update the 'too many' status.
g_guest_too_many =
(!g_guest_usernum || (search_ulistn(g_guest_usernum, MAX_GUEST) != NULL));
+
if (g_verbose) fprintf(stderr, LOG_PREFIX " guests are %s\r\n",
g_guest_too_many ? "TOO MANY" : "ok.");
@@ -1338,79 +1352,74 @@ listen_cb(int lfd, short event, void *arg)
login_conn_ctx *conn;
bind_event *pbindev = (bind_event*) arg;
- if ((fd = accept(lfd, (struct sockaddr *)&xsin, &szxsin)) < 0 )
- return;
+ while ( (fd = accept(lfd, (struct sockaddr *)&xsin, &szxsin)) >= 0 ) {
- if ((conn = malloc(sizeof(login_conn_ctx))) == NULL) {
- close(fd);
- return;
- }
- memset(conn, 0, sizeof(login_conn_ctx));
+ // fast draw banner (don't use buffered i/o - this banner is not really important.)
+#ifdef INSCREEN
+ write(fd, INSCREEN, sizeof(INSCREEN));
+#endif
- if ((conn->bufev = bufferevent_new(fd, NULL, NULL, endconn_cb_buffer, conn)) == NULL) {
- free(conn);
- close(fd);
- return;
- }
+ if ((conn = malloc(sizeof(login_conn_ctx))) == NULL) {
+ close(fd);
+ return;
+ }
+ memset(conn, 0, sizeof(login_conn_ctx));
- g_opened_fd ++;
- reload_data();
- login_ctx_init(&conn->ctx);
+ if ((conn->bufev = bufferevent_new(fd, NULL, NULL, endconn_cb_buffer, conn)) == NULL) {
+ free(conn);
+ close(fd);
+ return;
+ }
+
+ g_opened_fd ++;
+ reload_data();
+ login_ctx_init(&conn->ctx);
- // initialize telnet protocol
- telnet_ctx_init(&conn->telnet, &telnet_callback, fd);
- telnet_ctx_set_write_arg (&conn->telnet, (void*) conn); // use conn for buffered events
- telnet_ctx_set_resize_arg(&conn->telnet, (void*) &conn->ctx);
+ // initialize telnet protocol
+ telnet_ctx_init(&conn->telnet, &telnet_callback, fd);
+ telnet_ctx_set_write_arg (&conn->telnet, (void*) conn); // use conn for buffered events
+ telnet_ctx_set_resize_arg(&conn->telnet, (void*) &conn->ctx);
#ifdef DETECT_CLIENT
- telnet_ctx_set_cc_arg(&conn->telnet, (void*) &conn->ctx);
+ telnet_ctx_set_cc_arg(&conn->telnet, (void*) &conn->ctx);
#endif
#ifdef LOGIND_OPENFD_IN_AYT
- telnet_ctx_set_ayt_arg(&conn->telnet, (void*) conn); // use conn for buffered events
+ telnet_ctx_set_ayt_arg(&conn->telnet, (void*) conn); // use conn for buffered events
#endif
- // better send after all parameters were set
- telnet_ctx_send_init_cmds(&conn->telnet);
+ // better send after all parameters were set
+ telnet_ctx_send_init_cmds(&conn->telnet);
- // get remote ip & local port info
- inet_ntop(AF_INET, &xsin.sin_addr, conn->ctx.hostip, sizeof(conn->ctx.hostip));
- snprintf(conn->ctx.port, sizeof(conn->ctx.port), "%u", pbindev->port); // ntohs(xsin.sin_port));
+ // get remote ip & local port info
+ inet_ntop(AF_INET, &xsin.sin_addr, conn->ctx.hostip, sizeof(conn->ctx.hostip));
+ snprintf(conn->ctx.port, sizeof(conn->ctx.port), "%u", pbindev->port); // ntohs(xsin.sin_port));
- if (g_verbose) fprintf(stderr, LOG_PREFIX
- "new connection: %s:%s (opened fd: %d)\r\n",
- conn->ctx.hostip, conn->ctx.port, g_opened_fd);
-
- // set events
- event_set(&conn->ev, fd, EV_READ|EV_PERSIST, client_cb, conn);
- event_add(&conn->ev, &idle_tv);
+ if (g_verbose) fprintf(stderr, LOG_PREFIX
+ "new connection: %s:%s (opened fd: %d)\r\n",
+ conn->ctx.hostip, conn->ctx.port, g_opened_fd);
- // check ban here? XXX can we directly use xsin.sin_addr instead of ASCII form?
- if (g_banned || check_banip(conn->ctx.hostip) )
- {
- // draw ban screen, if available. (for banip, this is empty).
- draw_text_screen (conn, ban_screen);
- login_conn_remove(conn, fd, BAN_SLEEP_SEC);
- return;
- }
+ // set events
+ event_set(&conn->ev, fd, EV_READ|EV_PERSIST, client_cb, conn);
+ event_add(&conn->ev, &idle_tv);
- // draw banner
- // XXX for systems that needs high performance, you must reduce the
- // string in banner.
- _buff_write(conn, SITE_BANNER, sizeof(SITE_BANNER));
+ // check ban here? XXX can we directly use xsin.sin_addr instead of ASCII form?
+ if (g_banned || check_banip(conn->ctx.hostip) )
+ {
+ // draw ban screen, if available. (for banip, this is empty).
+ draw_text_screen (conn, ban_screen);
+ login_conn_remove(conn, fd, BAN_SLEEP_SEC);
+ return;
+ }
- // XXX check system load here.
- if (g_overload)
- {
- // let's draw the big INSCREEN if defined.
-#ifdef INSCREEN
- _mt_clear (conn);
- _buff_write(conn, INSCREEN, sizeof(INSCREEN));
-#endif
- draw_overload (conn, g_overload);
- login_conn_remove(conn, fd, OVERLOAD_SLEEP_SEC);
- return;
+ // XXX check system load here.
+ if (g_overload)
+ {
+ draw_overload (conn, g_overload);
+ login_conn_remove(conn, fd, OVERLOAD_SLEEP_SEC);
+ return;
- } else {
- draw_text_screen (conn, welcome_screen);
- draw_userid_prompt(conn, NULL, 0);
+ } else {
+ draw_text_screen (conn, welcome_screen);
+ draw_userid_prompt(conn, NULL, 0);
+ }
}
}