|
|
1.1 ! root 1: /* sockopts.c */ ! 2: ! 3: /* Set socket options based on contents of ctrl/sockopts.cfg */ ! 4: ! 5: /* $Id: sockopts.c,v 1.18 2003/05/09 01:30:41 rswindell Exp $ */ ! 6: ! 7: /**************************************************************************** ! 8: * @format.tab-size 4 (Plain Text/Source Code File Header) * ! 9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * ! 10: * * ! 11: * Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html * ! 12: * * ! 13: * This program is free software; you can redistribute it and/or * ! 14: * modify it under the terms of the GNU General Public License * ! 15: * as published by the Free Software Foundation; either version 2 * ! 16: * of the License, or (at your option) any later version. * ! 17: * See the GNU General Public License for more details: gpl.txt or * ! 18: * http://www.fsf.org/copyleft/gpl.html * ! 19: * * ! 20: * Anonymous FTP access to the most recent released source is available at * ! 21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * ! 22: * * ! 23: * Anonymous CVS access to the development source and modification history * ! 24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: * ! 25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login * ! 26: * (just hit return, no password is necessary) * ! 27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src * ! 28: * * ! 29: * For Synchronet coding style and modification guidelines, see * ! 30: * http://www.synchro.net/source.html * ! 31: * * ! 32: * You are encouraged to submit any modifications (preferably in Unix diff * ! 33: * format) via e-mail to [email protected] * ! 34: * * ! 35: * Note: If this box doesn't appear square, then you need to fix your tabs. * ! 36: ****************************************************************************/ ! 37: ! 38: #include "sbbs.h" ! 39: ! 40: typedef struct { ! 41: char* name; ! 42: int level; ! 43: int value; ! 44: } sockopt_name; ! 45: ! 46: static const sockopt_name option_names[] = { ! 47: { "TYPE", SOL_SOCKET, SO_TYPE }, ! 48: { "DEBUG", SOL_SOCKET, SO_DEBUG }, ! 49: { "LINGER", SOL_SOCKET, SO_LINGER }, ! 50: { "SNDBUF", SOL_SOCKET, SO_SNDBUF }, ! 51: { "RCVBUF", SOL_SOCKET, SO_RCVBUF }, ! 52: { "SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT }, ! 53: { "RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT }, ! 54: { "SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO }, ! 55: { "RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO }, ! 56: { "REUSEADDR", SOL_SOCKET, SO_REUSEADDR }, ! 57: { "KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE }, ! 58: { "DONTROUTE", SOL_SOCKET, SO_DONTROUTE }, ! 59: { "BROADCAST", SOL_SOCKET, SO_BROADCAST }, ! 60: { "OOBINLINE", SOL_SOCKET, SO_OOBINLINE }, ! 61: #ifdef SO_ACCEPTCONN ! 62: { "ACCEPTCONN", SOL_SOCKET, SO_ACCEPTCONN }, ! 63: #endif ! 64: ! 65: /* IPPROTO-level socket options */ ! 66: { "TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY }, ! 67: /* The following are platform-specific */ ! 68: #ifdef TCP_MAXSEG ! 69: { "TCP_MAXSEG", IPPROTO_TCP, TCP_MAXSEG }, ! 70: #endif ! 71: #ifdef TCP_CORK ! 72: { "TCP_CORK", IPPROTO_TCP, TCP_CORK }, ! 73: #endif ! 74: #ifdef TCP_KEEPIDLE ! 75: { "TCP_KEEPIDLE", IPPROTO_TCP, TCP_KEEPIDLE }, ! 76: #endif ! 77: #ifdef TCP_KEEPINTVL ! 78: { "TCP_KEEPINTVL", IPPROTO_TCP, TCP_KEEPINTVL }, ! 79: #endif ! 80: #ifdef TCP_KEEPCNT ! 81: { "TCP_KEEPCNT", IPPROTO_TCP, TCP_KEEPCNT }, ! 82: #endif ! 83: #ifdef TCP_SYNCNT ! 84: { "TCP_SYNCNT", IPPROTO_TCP, TCP_SYNCNT }, ! 85: #endif ! 86: #ifdef TCP_LINGER2 ! 87: { "TCP_LINGER2", IPPROTO_TCP, TCP_LINGER2 }, ! 88: #endif ! 89: #ifdef TCP_DEFER_ACCEPT ! 90: { "TCP_DEFER_ACCEPT", IPPROTO_TCP, TCP_DEFER_ACCEPT }, ! 91: #endif ! 92: #ifdef TCP_WINDOW_CLAMP ! 93: { "TCP_WINDOW_CLAMP", IPPROTO_TCP, TCP_WINDOW_CLAMP }, ! 94: #endif ! 95: #ifdef TCP_QUICKACK ! 96: { "TCP_QUICKACK", IPPROTO_TCP, TCP_QUICKACK }, ! 97: #endif ! 98: #ifdef TCP_NOPUSH ! 99: { "TCP_NOPUSH", IPPROTO_TCP, TCP_NOPUSH }, ! 100: #endif ! 101: #ifdef TCP_NOOPT ! 102: { "TCP_NOOPT", IPPROTO_TCP, TCP_NOOPT }, ! 103: #endif ! 104: { NULL } ! 105: }; ! 106: ! 107: int DLLCALL sockopt(char* str, int* level) ! 108: { ! 109: int i; ! 110: ! 111: *level=SOL_SOCKET; /* default option level */ ! 112: for(i=0;option_names[i].name;i++) { ! 113: if(stricmp(str,option_names[i].name)==0) { ! 114: *level = option_names[i].level; ! 115: return(option_names[i].value); ! 116: } ! 117: } ! 118: if(!isdigit(str[0])) /* unknown option name */ ! 119: return(-1); ! 120: return(strtoul(str,NULL,0)); ! 121: } ! 122: ! 123: int DLLCALL set_socket_options(scfg_t* cfg, SOCKET sock, char* error) ! 124: { ! 125: char cfgfile[MAX_PATH+1]; ! 126: char str[256]; ! 127: char* p; ! 128: char* name; ! 129: BYTE* vp; ! 130: FILE* fp; ! 131: int option; ! 132: int level; ! 133: int value; ! 134: int type; ! 135: int result=0; ! 136: LINGER linger; ! 137: socklen_t len; ! 138: ! 139: /* Set user defined socket options */ ! 140: sprintf(cfgfile,"%ssockopts.cfg",cfg->ctrl_dir); ! 141: if((fp=fopen(cfgfile,"r"))==NULL) ! 142: return(0); ! 143: ! 144: len = sizeof(type); ! 145: result=getsockopt(sock,SOL_SOCKET,SO_TYPE,(void*)&type,&len); ! 146: if(result) { ! 147: sprintf(error,"%d getting socket option (TYPE, %d)" ! 148: ,ERROR_VALUE, SO_TYPE); ! 149: return(result); ! 150: } ! 151: ! 152: while(!feof(fp)) { ! 153: if(!fgets(str,sizeof(str),fp)) ! 154: break; ! 155: name=str; ! 156: while(*name && *name<=' ') name++; ! 157: if(*name==';' || *name==0) /* blank line or comment */ ! 158: continue; ! 159: p=name; ! 160: while(*p && *p>' ') p++; ! 161: if(*p) *(p++)=0; ! 162: if((option=sockopt(name,&level))==-1) ! 163: continue; ! 164: if(level==IPPROTO_TCP && type!=SOCK_STREAM) ! 165: continue; ! 166: while(*p && *p<=' ') p++; ! 167: len=sizeof(value); ! 168: value=strtol(p,NULL,0); ! 169: vp=(BYTE*)&value; ! 170: while(*p && *p>' ') p++; ! 171: if(*p) p++; ! 172: while(*p && *p<=' ') p++; ! 173: switch(option) { ! 174: case SO_LINGER: ! 175: linger.l_onoff = value; ! 176: linger.l_linger = (int)strtol(p,NULL,0); ! 177: vp=(BYTE*)&linger; ! 178: len=sizeof(linger); ! 179: break; ! 180: case SO_KEEPALIVE: ! 181: if(type!=SOCK_STREAM) ! 182: continue; ! 183: break; ! 184: } ! 185: #if 0 ! 186: lprintf("%04d setting socket option: %s to %d", sock, str, value); ! 187: #endif ! 188: result=setsockopt(sock,level,option,vp,len); ! 189: if(result) { ! 190: sprintf(error,"%d setting socket option (%s, %d) to %d" ! 191: ,ERROR_VALUE, name, option, value); ! 192: break; ! 193: } ! 194: #if 0 ! 195: len = sizeof(value); ! 196: getsockopt(sock,level,option,(void*)&value,&len); ! 197: lprintf("%04d socket option: %s set to %d", sock, name, value); ! 198: #endif ! 199: } ! 200: fclose(fp); ! 201: return(result); ! 202: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.