r13840: Mark some functions as public.
[samba.git] / source / lib / util / util_sock.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Samba utility functions
4    Copyright (C) Andrew Tridgell 1992-1998
5    Copyright (C) Tim Potter      2000-2001
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23 #include "system/network.h"
24
25 /**
26  * @file
27  * @brief Socket utility functions
28  */
29
30 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
31
32 static const struct {
33         const char *name;
34         int level;
35         int option;
36         int value;
37         int opttype;
38 } socket_options[] = {
39   {"SO_KEEPALIVE",      SOL_SOCKET,    SO_KEEPALIVE,    0,                 OPT_BOOL},
40   {"SO_REUSEADDR",      SOL_SOCKET,    SO_REUSEADDR,    0,                 OPT_BOOL},
41   {"SO_BROADCAST",      SOL_SOCKET,    SO_BROADCAST,    0,                 OPT_BOOL},
42 #ifdef TCP_NODELAY
43   {"TCP_NODELAY",       IPPROTO_TCP,   TCP_NODELAY,     0,                 OPT_BOOL},
44 #endif
45 #ifdef IPTOS_LOWDELAY
46   {"IPTOS_LOWDELAY",    IPPROTO_IP,    IP_TOS,          IPTOS_LOWDELAY,    OPT_ON},
47 #endif
48 #ifdef IPTOS_THROUGHPUT
49   {"IPTOS_THROUGHPUT",  IPPROTO_IP,    IP_TOS,          IPTOS_THROUGHPUT,  OPT_ON},
50 #endif
51 #ifdef SO_REUSEPORT
52   {"SO_REUSEPORT",      SOL_SOCKET,    SO_REUSEPORT,    0,                 OPT_BOOL},
53 #endif
54 #ifdef SO_SNDBUF
55   {"SO_SNDBUF",         SOL_SOCKET,    SO_SNDBUF,       0,                 OPT_INT},
56 #endif
57 #ifdef SO_RCVBUF
58   {"SO_RCVBUF",         SOL_SOCKET,    SO_RCVBUF,       0,                 OPT_INT},
59 #endif
60 #ifdef SO_SNDLOWAT
61   {"SO_SNDLOWAT",       SOL_SOCKET,    SO_SNDLOWAT,     0,                 OPT_INT},
62 #endif
63 #ifdef SO_RCVLOWAT
64   {"SO_RCVLOWAT",       SOL_SOCKET,    SO_RCVLOWAT,     0,                 OPT_INT},
65 #endif
66 #ifdef SO_SNDTIMEO
67   {"SO_SNDTIMEO",       SOL_SOCKET,    SO_SNDTIMEO,     0,                 OPT_INT},
68 #endif
69 #ifdef SO_RCVTIMEO
70   {"SO_RCVTIMEO",       SOL_SOCKET,    SO_RCVTIMEO,     0,                 OPT_INT},
71 #endif
72   {NULL,0,0,0,0}};
73
74
75 /**
76  Set user socket options.
77 **/
78 _PUBLIC_ void set_socket_options(int fd, const char *options)
79 {
80         const char **options_list = str_list_make(NULL, options, " \t,");
81         int j;
82
83         if (!options_list)
84                 return;
85
86         for (j = 0; options_list[j]; j++) {
87                 const char *tok = options_list[j];
88                 int ret=0,i;
89                 int value = 1;
90                 char *p;
91                 BOOL got_value = False;
92
93                 if ((p = strchr_m(tok,'='))) {
94                         *p = 0;
95                         value = atoi(p+1);
96                         got_value = True;
97                 }
98
99                 for (i=0;socket_options[i].name;i++)
100                         if (strequal(socket_options[i].name,tok))
101                                 break;
102
103                 if (!socket_options[i].name) {
104                         DEBUG(0,("Unknown socket option %s\n",tok));
105                         continue;
106                 }
107
108                 switch (socket_options[i].opttype) {
109                 case OPT_BOOL:
110                 case OPT_INT:
111                         ret = setsockopt(fd,socket_options[i].level,
112                                                 socket_options[i].option,(char *)&value,sizeof(int));
113                         break;
114
115                 case OPT_ON:
116                         if (got_value)
117                                 DEBUG(0,("syntax error - %s does not take a value\n",tok));
118
119                         {
120                                 int on = socket_options[i].value;
121                                 ret = setsockopt(fd,socket_options[i].level,
122                                                         socket_options[i].option,(char *)&on,sizeof(int));
123                         }
124                         break;    
125                 }
126       
127                 if (ret != 0)
128                         DEBUG(0,("Failed to set socket option %s (Error %s)\n",tok, strerror(errno) ));
129         }
130
131         talloc_free(options_list);
132 }
133