|
|
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.