From 4b3ba1f793bf4cd5c1d93d0042a29aaa816b5a2b Mon Sep 17 00:00:00 2001 From: rswindell <> Date: Thu, 13 Oct 2005 01:44:53 +0000 Subject: [PATCH] Support per-server/service/protocol socket option settings in ctrl/sockopts.ini (replacing sockopts.cfg). --- src/sbbs3/execnet.cpp | 4 +- src/sbbs3/ftpsrvr.c | 2 +- src/sbbs3/ident.c | 2 +- src/sbbs3/js_socket.c | 14 +++-- src/sbbs3/mailsrvr.c | 2 +- src/sbbs3/main.cpp | 8 +-- src/sbbs3/sbbs.h | 5 +- src/sbbs3/services.c | 9 +-- src/sbbs3/sockopts.c | 126 ++++++++++++++++++++++-------------------- src/sbbs3/telgate.cpp | 2 +- src/sbbs3/websrvr.c | 2 +- src/sbbs3/xtrn.cpp | 4 +- 12 files changed, 97 insertions(+), 83 deletions(-) diff --git a/src/sbbs3/execnet.cpp b/src/sbbs3/execnet.cpp index 8b6501f757..a9096235d4 100644 --- a/src/sbbs3/execnet.cpp +++ b/src/sbbs3/execnet.cpp @@ -61,7 +61,7 @@ int sbbs_t::exec_net(csi_t* csi) return(0); if(lp!=NULL) { - SOCKET sock=open_socket(SOCK_STREAM); + SOCKET sock=open_socket(SOCK_STREAM, NULL); if(sock!=INVALID_SOCKET) { SOCKADDR_IN addr; @@ -544,7 +544,7 @@ SOCKET sbbs_t::ftp_data_sock(csi_t* csi, SOCKET ctrl_sock, SOCKADDR_IN* addr) return(INVALID_SOCKET); } - if((data_sock=open_socket(SOCK_STREAM))==INVALID_SOCKET) { + if((data_sock=open_socket(SOCK_STREAM, NULL))==INVALID_SOCKET) { csi->socket_error=ERROR_VALUE; return(INVALID_SOCKET); } diff --git a/src/sbbs3/ftpsrvr.c b/src/sbbs3/ftpsrvr.c index f4ae3d858e..06bc13fd9c 100644 --- a/src/sbbs3/ftpsrvr.c +++ b/src/sbbs3/ftpsrvr.c @@ -231,7 +231,7 @@ static SOCKET ftp_open_socket(int type) if(sock!=INVALID_SOCKET && startup!=NULL && startup->socket_open!=NULL) startup->socket_open(startup->cbdata,TRUE); if(sock!=INVALID_SOCKET) { - if(set_socket_options(&scfg, sock, error)) + if(set_socket_options(&scfg, sock, "FTP", error, sizeof(error))) lprintf(LOG_ERR,"%04d !ERROR %s",sock, error); sockets++; #ifdef _DEBUG diff --git a/src/sbbs3/ident.c b/src/sbbs3/ident.c index 1138e15fdb..0739631f35 100644 --- a/src/sbbs3/ident.c +++ b/src/sbbs3/ident.c @@ -56,7 +56,7 @@ char* identify(SOCKADDR_IN* client_addr, u_short local_port, char* buf timeout=10; do { - if((sock = open_socket(SOCK_STREAM)) == INVALID_SOCKET) { + if((sock = open_socket(SOCK_STREAM, "ident")) == INVALID_SOCKET) { sprintf(buf,"ERROR %d creating socket",ERROR_VALUE); break; } diff --git a/src/sbbs3/js_socket.c b/src/sbbs3/js_socket.c index 7f5078751d..90ec8b731a 100644 --- a/src/sbbs3/js_socket.c +++ b/src/sbbs3/js_socket.c @@ -1307,18 +1307,24 @@ static JSBool js_socket_constructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { int32 type=SOCK_STREAM; /* default = TCP */ + uintN i; private_t* p; + char* sock_service=NULL; - if(argc) - JS_ValueToInt32(cx,argv[0],&type); - + for(i=0;i<argc;i++) { + if(JSVAL_IS_NUMBER(argv[i])) + JS_ValueToInt32(cx,argv[i],&type); + else if(sock_service==NULL) + sock_service=JS_GetStringBytes(JS_ValueToString(cx,argv[i])); + } + if((p=(private_t*)malloc(sizeof(private_t)))==NULL) { JS_ReportError(cx,"malloc failed"); return(JS_FALSE); } memset(p,0,sizeof(private_t)); - if((p->sock=open_socket(type))==INVALID_SOCKET) { + if((p->sock=open_socket(type,sock_service))==INVALID_SOCKET) { JS_ReportError(cx,"open_socket failed with error %d",ERROR_VALUE); return(JS_FALSE); } diff --git a/src/sbbs3/mailsrvr.c b/src/sbbs3/mailsrvr.c index e28f9b2a79..f74ad15b73 100644 --- a/src/sbbs3/mailsrvr.c +++ b/src/sbbs3/mailsrvr.c @@ -205,7 +205,7 @@ SOCKET mail_open_socket(int type) if(sock!=INVALID_SOCKET && startup!=NULL && startup->socket_open!=NULL) startup->socket_open(startup->cbdata,TRUE); if(sock!=INVALID_SOCKET) { - if(set_socket_options(&scfg, sock,error)) + if(set_socket_options(&scfg, sock, "mail", error, sizeof(error))) lprintf(LOG_ERR,"%04d !ERROR %s",sock,error); sockets++; diff --git a/src/sbbs3/main.cpp b/src/sbbs3/main.cpp index b04f60f2f9..d1402275e9 100644 --- a/src/sbbs3/main.cpp +++ b/src/sbbs3/main.cpp @@ -174,7 +174,7 @@ int eprintf(int level, char *fmt, ...) return(startup->event_lputs(level,sbuf)); } -SOCKET open_socket(int type) +SOCKET open_socket(int type, const char* service) { SOCKET sock; char error[256]; @@ -182,7 +182,7 @@ SOCKET open_socket(int type) sock=socket(AF_INET, type, IPPROTO_IP); if(sock!=INVALID_SOCKET && startup!=NULL && startup->socket_open!=NULL) startup->socket_open(startup->cbdata,TRUE); - if(sock!=INVALID_SOCKET && set_socket_options(&scfg, sock, error)) + if(sock!=INVALID_SOCKET && set_socket_options(&scfg, sock, service, error, sizeof(error))) lprintf(LOG_ERR,"%04d !ERROR %s",sock,error); return(sock); @@ -3958,7 +3958,7 @@ void DLLCALL bbs_thread(void* arg) /* open a socket and wait for a client */ - telnet_socket = open_socket(SOCK_STREAM); + telnet_socket = open_socket(SOCK_STREAM, "bbs"); if(telnet_socket == INVALID_SOCKET) { lprintf(LOG_ERR,"!ERROR %d creating Telnet socket", ERROR_VALUE); @@ -4002,7 +4002,7 @@ void DLLCALL bbs_thread(void* arg) /* open a socket and wait for a client */ - rlogin_socket = open_socket(SOCK_STREAM); + rlogin_socket = open_socket(SOCK_STREAM, "bbs"); if(rlogin_socket == INVALID_SOCKET) { lprintf(LOG_ERR,"!ERROR %d creating RLogin socket", ERROR_VALUE); diff --git a/src/sbbs3/sbbs.h b/src/sbbs3/sbbs.h index bfb2889241..2449effd51 100644 --- a/src/sbbs3/sbbs.h +++ b/src/sbbs3/sbbs.h @@ -874,7 +874,8 @@ extern "C" { /* sockopt.c */ DLLEXPORT int DLLCALL sockopt(char* str, int* level); - DLLEXPORT int DLLCALL set_socket_options(scfg_t* cfg, SOCKET sock, char* error); + DLLEXPORT int DLLCALL set_socket_options(scfg_t* cfg, SOCKET sock, const char* section + ,char* error, size_t errlen); /* xtrn.cpp */ DLLEXPORT char* DLLCALL cmdstr(scfg_t* cfg, user_t* user, const char* instr @@ -1046,7 +1047,7 @@ BOOL md(char *path); int lputs(int level, char *); /* log output */ int lprintf(int level, char *fmt, ...); /* log output */ int eprintf(int level, char *fmt, ...); /* event log */ - SOCKET open_socket(int type); + SOCKET open_socket(int type, const char* service); SOCKET accept_socket(SOCKET s, SOCKADDR* addr, socklen_t* addrlen); int close_socket(SOCKET); u_long resolve_ip(char *addr); diff --git a/src/sbbs3/services.c b/src/sbbs3/services.c index 1f9109c741..802e2cd46a 100644 --- a/src/sbbs3/services.c +++ b/src/sbbs3/services.c @@ -212,7 +212,7 @@ static void thread_down(void) startup->thread_up(startup->cbdata,FALSE,FALSE); } -static SOCKET open_socket(int type) +static SOCKET open_socket(int type, const char* service) { char error[256]; SOCKET sock; @@ -222,7 +222,7 @@ static SOCKET open_socket(int type) startup->socket_open(startup->cbdata,TRUE); if(sock!=INVALID_SOCKET) { sockets++; - if(set_socket_options(&scfg, sock, error)) + if(set_socket_options(&scfg, sock, service, error, sizeof(error))) lprintf(LOG_ERR,"%04d !ERROR %s",sock, error); #if 0 /*def _DEBUG */ @@ -1696,7 +1696,8 @@ void DLLCALL services_thread(void* arg) service[i].socket=INVALID_SOCKET; if((socket = open_socket( - (service[i].options&SERVICE_OPT_UDP) ? SOCK_DGRAM : SOCK_STREAM)) + (service[i].options&SERVICE_OPT_UDP) ? SOCK_DGRAM : SOCK_STREAM + ,service[i].protocol)) ==INVALID_SOCKET) { lprintf(LOG_ERR,"!ERROR %d opening %s socket" ,ERROR_VALUE, service[i].protocol); @@ -1892,7 +1893,7 @@ void DLLCALL services_thread(void* arg) continue; } - if((client_socket = open_socket(SOCK_DGRAM)) + if((client_socket = open_socket(SOCK_DGRAM, service[i].protocol)) ==INVALID_SOCKET) { FREE_AND_NULL(udp_buf); lprintf(LOG_ERR,"%04d %s !ERROR %d opening socket" diff --git a/src/sbbs3/sockopts.c b/src/sbbs3/sockopts.c index fe30e3a893..be79d44312 100644 --- a/src/sbbs3/sockopts.c +++ b/src/sbbs3/sockopts.c @@ -1,6 +1,6 @@ /* sockopts.c */ -/* Set socket options based on contents of ctrl/sockopts.cfg */ +/* Set socket options based on contents of ctrl/sockopts.ini */ /* $Id$ */ @@ -8,7 +8,7 @@ * @format.tab-size 4 (Plain Text/Source Code File Header) * * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * * * - * Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html * + * Copyright 2005 Rob Swindell - http://www.synchro.net/copyright.html * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License * @@ -36,14 +36,13 @@ ****************************************************************************/ #include "sbbs.h" +#include "ini_file.h" /* ini file API */ -typedef struct { +static struct { char* name; int level; int value; -} sockopt_name; - -static const sockopt_name option_names[] = { +} option_names[] = { { "TYPE", SOL_SOCKET, SO_TYPE }, { "DEBUG", SOL_SOCKET, SO_DEBUG }, { "LINGER", SOL_SOCKET, SO_LINGER }, @@ -104,6 +103,7 @@ static const sockopt_name option_names[] = { { NULL } }; +/* This function is used by js_socket.c -> js_get/setsockopt() */ int DLLCALL sockopt(char* str, int* level) { int i; @@ -120,60 +120,39 @@ int DLLCALL sockopt(char* str, int* level) return(strtoul(str,NULL,0)); } -int DLLCALL set_socket_options(scfg_t* cfg, SOCKET sock, char* error) +static int parse_sockopts_section(str_list_t list, SOCKET sock, int type, const char* section + ,char* error, size_t errlen) { - char cfgfile[MAX_PATH+1]; - char str[256]; - char* p; + int i; + int result; char* name; BYTE* vp; - FILE* fp; + socklen_t len; int option; int level; int value; - int type; - int result=0; LINGER linger; - socklen_t len; - /* Set user defined socket options */ - sprintf(cfgfile,"%ssockopts.cfg",cfg->ctrl_dir); - if((fp=fopen(cfgfile,"r"))==NULL) - return(0); - - len = sizeof(type); - result=getsockopt(sock,SOL_SOCKET,SO_TYPE,(void*)&type,&len); - if(result) { - sprintf(error,"%d getting socket option (TYPE, %d)" - ,ERROR_VALUE, SO_TYPE); - return(result); - } - - while(!feof(fp)) { - if(!fgets(str,sizeof(str),fp)) - break; - name=str; - while(*name && *name<=' ') name++; - if(*name==';' || *name==0) /* blank line or comment */ + for(i=0;option_names[i].name!=NULL;i++) { + name = option_names[i].name; + if(!iniValueExists(list,section,name)) continue; - p=name; - while(*p && *p>' ') p++; - if(*p) *(p++)=0; - if((option=sockopt(name,&level))==-1) - continue; - if(level==IPPROTO_TCP && type!=SOCK_STREAM) - continue; - while(*p && *p<=' ') p++; - len=sizeof(value); - value=strtol(p,NULL,0); + value=iniGetInteger(list, section, name, 0); + vp=(BYTE*)&value; - while(*p && *p>' ') p++; - if(*p) p++; - while(*p && *p<=' ') p++; + len=sizeof(value); + + level = option_names[i].level; + option = option_names[i].value; + switch(option) { case SO_LINGER: - linger.l_onoff = value; - linger.l_linger = (int)strtol(p,NULL,0); + if(value) { + linger.l_onoff = TRUE; + linger.l_linger = value; + } else { + ZERO_VAR(linger); + } vp=(BYTE*)&linger; len=sizeof(linger); break; @@ -182,21 +161,48 @@ int DLLCALL set_socket_options(scfg_t* cfg, SOCKET sock, char* error) continue; break; } -#if 0 - lprintf("%04d setting socket option: %s to %d", sock, str, value); -#endif - result=setsockopt(sock,level,option,vp,len); - if(result) { - sprintf(error,"%d setting socket option (%s, %d) to %d" + + if((result=setsockopt(sock,level,option,vp,len)) != 0) { + safe_snprintf(error,errlen,"%d setting socket option (%s, %d) to %d" ,ERROR_VALUE, name, option, value); - break; + return(result); } -#if 0 - len = sizeof(value); - getsockopt(sock,level,option,(void*)&value,&len); - lprintf("%04d socket option: %s set to %d", sock, name, value); -#endif } + + return(0); +} + + +int DLLCALL set_socket_options(scfg_t* cfg, SOCKET sock, const char* section, char* error, size_t errlen) +{ + char cfgfile[MAX_PATH+1]; + FILE* fp; + int type; + int result=0; + str_list_t list; + socklen_t len; + + /* Set user defined socket options */ + iniFileName(cfgfile,sizeof(cfgfile),cfg->ctrl_dir,"sockopts.ini"); + if((fp=iniOpenFile(cfgfile,FALSE))==NULL) + return(0); + list=iniReadFile(fp); fclose(fp); + + len = sizeof(type); + result=getsockopt(sock,SOL_SOCKET,SO_TYPE,(void*)&type,&len); + if(result) { + sprintf(error,"%d getting socket option (TYPE, %d)" + ,ERROR_VALUE, SO_TYPE); + return(result); + } + + result=parse_sockopts_section(list,sock,type,ROOT_SECTION,error,errlen); + + if(result==0 && section!=NULL) + result=parse_sockopts_section(list,sock,type,section,error,errlen); + + iniFreeStringList(list); + return(result); } diff --git a/src/sbbs3/telgate.cpp b/src/sbbs3/telgate.cpp index b98a26a25b..02af027cce 100644 --- a/src/sbbs3/telgate.cpp +++ b/src/sbbs3/telgate.cpp @@ -71,7 +71,7 @@ void sbbs_t::telnet_gate(char* destaddr, ulong mode) return; } - if((remote_socket = open_socket(SOCK_STREAM)) == INVALID_SOCKET) { + if((remote_socket = open_socket(SOCK_STREAM, "bbs")) == INVALID_SOCKET) { errormsg(WHERE,ERR_OPEN,"socket",0); return; } diff --git a/src/sbbs3/websrvr.c b/src/sbbs3/websrvr.c index 0dc0e03966..49c2b1c0cd 100644 --- a/src/sbbs3/websrvr.c +++ b/src/sbbs3/websrvr.c @@ -698,7 +698,7 @@ static SOCKET open_socket(int type) if(sock!=INVALID_SOCKET && startup!=NULL && startup->socket_open!=NULL) startup->socket_open(startup->cbdata,TRUE); if(sock!=INVALID_SOCKET) { - if(set_socket_options(&scfg, sock,error)) + if(set_socket_options(&scfg, sock, "web", error, sizeof(error))) lprintf(LOG_ERR,"%04d !ERROR %s",sock,error); sockets++; diff --git a/src/sbbs3/xtrn.cpp b/src/sbbs3/xtrn.cpp index c8dce4ce2f..fb9c2d66df 100644 --- a/src/sbbs3/xtrn.cpp +++ b/src/sbbs3/xtrn.cpp @@ -1039,7 +1039,7 @@ int sbbs_t::external(const char* cmdline, long mode, const char* startup_dir) ioctlsocket(client_socket, FIONBIO, &l); /* Re-set socket options */ - if(set_socket_options(&cfg, client_socket, str)) + if(set_socket_options(&cfg, client_socket, "bbs", str, sizeof(str))) lprintf(LOG_ERR,"%04d !ERROR %s",client_socket, str); if(input_thread_mutex_locked && input_thread_running) { @@ -1928,7 +1928,7 @@ int sbbs_t::external(const char* cmdline, long mode, const char* startup_dir) ioctlsocket(client_socket, FIONBIO, &l); /* Re-set socket options */ - if(set_socket_options(&cfg, client_socket, str)) + if(set_socket_options(&cfg, client_socket, "bbs", str, sizeof(str))) lprintf(LOG_ERR,"%04d !ERROR %s",client_socket, str); curatr=~0; // Can't guarantee current attributes -- GitLab