]>
git.ipfire.org Git - thirdparty/squid.git/blob - tools/purge/socket.cc
2 // $Id: socket.cc,v 1.3 1999/01/19 11:00:50 voeckler Exp $
4 // Author: Jens-S. Vöckler <voeckler@rvs.uni-hannover.de>
9 // (c) 1998 Lehrgebiet Rechnernetze und Verteilte Systeme
10 // Universität Hannover, Germany
12 // Books: W. Richard Steven, "Advanced Programming in the UNIX Environment",
13 // Addison-Wesley, 1992.
15 // Permission to use, copy, modify, distribute, and sell this software
16 // and its documentation for any purpose is hereby granted without fee,
17 // provided that (i) the above copyright notices and this permission
18 // notice appear in all copies of the software and related documentation,
19 // and (ii) the names of the Lehrgebiet Rechnernetze und Verteilte
20 // Systeme and the University of Hannover may not be used in any
21 // advertising or publicity relating to the software without the
22 // specific, prior written permission of Lehrgebiet Rechnernetze und
23 // Verteilte Systeme and the University of Hannover.
25 // THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
27 // WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
29 // IN NO EVENT SHALL THE LEHRGEBIET RECHNERNETZE UND VERTEILTE SYSTEME OR
30 // THE UNIVERSITY OF HANNOVER BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
31 // INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES
32 // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT
33 // ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY,
34 // ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
37 // $Log: socket.cc,v $
38 // Revision 1.3 1999/01/19 11:00:50 voeckler
39 // Linux glibc2 fixes for socket size parameters.
41 // Revision 1.2 1998/08/27 15:23:39 voeckler
42 // added TCP_NODELAY options at several places.
44 // Revision 1.1 1998/08/13 21:52:55 voeckler
48 #if defined(__GNUC__) || defined(__GNUG__)
49 #pragma implementation
53 #include <netinet/tcp.h>
54 #include <arpa/inet.h>
64 static const char* RCS_ID
=
65 "$Id: socket.cc,v 1.3 1999/01/19 11:00:50 voeckler Exp $";
68 setSocketBuffers( int sockfd
, int size
)
69 // purpose: set socket buffers for both directions to the specified size
70 // paramtr: sockfd (IN): socket file descriptor
71 // size (IN): new socket buffer size
72 // returns: -1 on setsockopt() errors, 0 otherwise
73 // warning: prints error message on stderr, errno will be changed
75 if ( setsockopt( sockfd
, SOL_SOCKET
, SO_RCVBUF
,
76 (char*) &size
, sizeof(size
) ) == -1 ) {
77 perror( "setsockopt( SO_RCVBUF )" );
81 if ( setsockopt( sockfd
, SOL_SOCKET
, SO_SNDBUF
,
82 (char*) &size
, sizeof(size
) ) == -1 ) {
83 perror( "setsockopt( SO_SNDBUF )" );
91 getSocketNoDelay( int sockfd
)
92 // purpose: get state of the TCP_NODELAY of the socket
93 // paramtr: sockfd (IN): socket descriptor
94 // returns: 1, if TCP_NODELAY is set,
95 // 0, if TCP_NODELAY is not set,
96 // -1, if an error occurred (e.g. datagram socket)
99 SOCKLEN len
= sizeof(delay
);
100 if ( getsockopt( sockfd
, IPPROTO_TCP
, TCP_NODELAY
,
101 (char*) &delay
, &len
) == -1 ) {
102 perror( "# getsockopt( TCP_NODELAY ) failed" );
105 return ( delay
? 1 : 0 );
109 setSocketNoDelay( int sockfd
, bool nodelay
)
110 // purpose: get state of the TCP_NODELAY of the socket
111 // paramtr: sockfd (IN): socket descriptor
112 // nodelay (IN): true, if TCP_NODELAY is to be set, false otherwise.
113 // returns: 0, if everything worked out o.k.
114 // -1, if an error occurred (e.g. datagram socket)
117 if ( setsockopt( sockfd
, IPPROTO_TCP
, TCP_NODELAY
,
118 (const char*) &delay
, sizeof(delay
) ) == -1 ) {
119 perror( "setsockopt( TCP_NODELAY ) failed" );
127 commonCode( int& sockfd
, bool nodelay
, int sendBufferSize
, int recvBufferSize
)
128 // purpose: common code in server sockets and client sockets
129 // paramtr: sockfd (IO): socket filedescriptor
130 // nodelay (IN): true=set TCP_NODELAY option.
131 // sendBufferSize (IN): don't set (use sys defaults) if < 0
132 // recvBufferSize (IN): don't set (use sys defaults) if < 0
133 // returns: 0 == if everthing went ok, -1 otherwise
134 // warning: sockfd will be closed, if -1 is returned!
136 // set TCP_NODELAY option, if that is wanted.
137 // The socket API default is unset.
140 if ( setsockopt( sockfd
, IPPROTO_TCP
, TCP_NODELAY
,
141 (const char*) &delay
, sizeof(delay
) ) == -1 ) {
142 perror( "setsockopt( TCP_NODELAY ) failed" );
148 // set the socket send buffer size explicitly, or use the system default
149 if ( sendBufferSize
>= 0 ) {
150 if ( setsockopt( sockfd
, SOL_SOCKET
, SO_SNDBUF
, (char*) &sendBufferSize
,
151 sizeof(sendBufferSize
) ) == -1 ) {
152 perror( "setsockopt( SO_SNDBUF )" );
158 // set the socket recv buffer size explicitly, or use the system default
159 if ( recvBufferSize
>= 0 ) {
160 if ( setsockopt( sockfd
, SOL_SOCKET
, SO_RCVBUF
, (char*) &recvBufferSize
,
161 sizeof(recvBufferSize
) ) == -1 ) {
162 perror( "setsockopt( SO_RCVBUF )" );
171 connectTo( struct in_addr host
, unsigned short port
, bool nodelay
,
172 int sendBufferSize
, int recvBufferSize
)
173 // purpose: connect to a server as a client
174 // paramtr: host (IN): address describing the server
175 // port (IN): port to connect at the server
176 // nodelay (IN): true=set TCP_NODELAY option.
177 // sendBufferSize (IN): don't set (use sys defaults) if < 0
178 // recvBufferSize (IN): don't set (use sys defaults) if < 0
179 // returns: >=0 is the descriptor of the opened, connected socket,
180 // -1 is an indication of an error (errno may have been reset).
182 int sockfd
= socket( PF_INET
, SOCK_STREAM
, IPPROTO_TCP
);
183 if ( sockfd
== -1 ) {
184 perror( "socket() failed" );
188 if ( commonCode( sockfd
, nodelay
, sendBufferSize
, recvBufferSize
) == -1 )
191 struct sockaddr_in server
;
192 memset( &server
, 0, sizeof(server
) );
193 server
.sin_family
= AF_INET
;
194 server
.sin_addr
= host
;
195 server
.sin_port
= port
;
196 if ( connect( sockfd
, (struct sockaddr
*) &server
, sizeof(server
) ) == -1 ) {
197 perror( "connect() failure" );
206 serverSocket( struct in_addr host
, unsigned short port
,
207 int backlog
, bool reuse
, bool nodelay
,
208 int sendBufferSize
, int recvBufferSize
)
209 // purpose: open a server socket for listening
210 // paramtr: host (IN): host to bind locally to, use INADDRY_ANY for *
211 // port (IN): port to bind to, use 0 for system assigned
212 // backlog (IN): listen backlog queue length
213 // reuse (IN): set SO_REUSEADDR option - default usefully
214 // nodelay (IN): true=set TCP_NODELAY option.
215 // SETTING TCP_NODELAY ON A SERVER SOCKET DOES NOT MAKE SENSE!
216 // sendBufferSize (IN): don't set (use sys defaults) if < 0
217 // recvBufferSize (IN): don't set (use sys defaults) if < 0
218 // returns: opened listening fd, or -1 on error.
219 // warning: error message will be printed on stderr and errno reset.
221 int sockfd
= socket( AF_INET
, SOCK_STREAM
, 0 );
222 if ( sockfd
== -1 ) {
229 if ( setsockopt( sockfd
, SOL_SOCKET
, SO_REUSEADDR
,
230 (char*) &reuse
, sizeof(int) ) == -1) {
231 perror( "setsockopt( SO_REUSEADDR )" );
237 if ( commonCode( sockfd
, nodelay
, sendBufferSize
, recvBufferSize
) == -1 )
240 struct sockaddr_in server
;
241 memset( &server
, 0, sizeof(server
) );
242 server
.sin_family
= AF_INET
;
243 server
.sin_port
= port
;
244 server
.sin_addr
= host
;
245 if ( bind( sockfd
, (SA
*) &server
, sizeof(server
) ) == -1 ) {
247 fprintf( stderr
, "bind(%s): %s\n",
248 my_sock_ntoa(server
,socket
), strerror(errno
) );
253 if ( listen( sockfd
, backlog
) == -1 ) {