feisty meow concerns codebase  2.140
raw_socket.h
Go to the documentation of this file.
1 #ifndef RAW_SOCKET_CLASS
2 #define RAW_SOCKET_CLASS
3 
4 /*****************************************************************************\
5 * *
6 * Name : raw_socket *
7 * Author : Chris Koeritz *
8 * *
9 *******************************************************************************
10 * Copyright (c) 1991-$now By Author. This program is free software; you can *
11 * redistribute it and/or modify it under the terms of the GNU General Public *
12 * License as published by the Free Software Foundation; either version 2 of *
13 * the License or (at your option) any later version. This is online at: *
14 * http://www.fsf.org/copyleft/gpl.html *
15 * Please send any updates to: fred@gruntose.com *
16 \*****************************************************************************/
17 
19 
29 #include <basis/array.h>
30 #include <basis/astring.h>
31 #include <basis/contracts.h>
32 
33 namespace sockets {
34 
35 // forward declarations.
36 class fd_set_wrapper;
37 class tcpip_stack;
38 
40 
41 // sockets can be intrigued by the occurrence of the following conditions:
43  SI_READABLE = 0x1, // the socket is readable; there's data there.
44  SI_WRITABLE = 0x2, // the socket will accept data if it's sent.
45  SI_CONNECTED = 0x4, // the socket is connected.
46  SI_DISCONNECTED = 0x8, // the socket is disconnected.
47  SI_ERRONEOUS = 0x10, // the socket is in an erroneous state.
48  SI_BASELINE = 0x20, // the socket seems okay but not interesting.
49 
50  SI_ALL_SOCK_INT = 0xFF // all socket interests are active.
51 };
52 
54 
55 class raw_socket : public virtual basis::root_object
56 {
57 public:
58  raw_socket();
59 
60  ~raw_socket();
61 
62  DEFINE_CLASS_NAME("raw_socket");
63 
64  int close(basis::un_int &socket);
65  // disconnects, destroys and resets the "socket" to zero.
66 
67  int ioctl(basis::un_int socket, int request, void *argp) const;
68  // manipulates the device parameters for the "socket".
69 
70  bool set_non_blocking(basis::un_int socket, bool non_blocking = true);
71  // makes the "socket" into a non-blocking socket if "non_blocking" is true.
72  // if "non_blocking" is false, then the socket is reset to blocking mode.
73 
74  bool set_nagle_algorithm(basis::un_int socket, bool use_nagle = true);
75  // sets the nagle algorithm on "socket" if "use_nagle" is true. note that
76  // true is the default when a socket is created; to change that for the
77  // socket, "use_nagle" should be false.
78 
79  bool set_broadcast(basis::un_int socket, bool broadcasting = true);
80  // sets broadcast mode on the socket so that it can receive packets that
81  // are broadcast to the network.
82 
83  bool set_reuse_address(basis::un_int socket, bool reuse = true);
84  // sets the socket to allow an address to be re-used when it's already
85  // in use, rather than getting a bind error.
86 
87  bool set_keep_alive(basis::un_int socket, bool keep_alive = true);
88  // marks a connected-mode socket so that keep alive packets will be sent
89  // occasionally to ensure that a disconnection is noticed.
90 
91  static basis::astring interest_name(int to_name);
92  // returns the textual form for the interests set in "to_name".
93 
94  // outlines any special constraints on the select invocation.
95  enum select_types {
98  };
99 
100  int select(basis::un_int socket, int selection_mode, int timeout = 0) const;
101  // this is similar to the low-level select on a bsd socket. usually this
102  // will return events of any type--read, write and exception. exceptions
103  // will always be cause for a return, but if you just want to look at a
104  // read condition, include the JUST_READ flag in the "selection_mode". to
105  // just check for write, add the JUST_WRITE flag. this function returns a
106  // bitwise ORed value from the different types of 'socket_interests' (see
107  // tcpip definitions, which is where the enum is currently stored). if
108  // there are no special conditions noted on the socket, then zero is
109  // returned. if the "timeout" is zero, the function will return right
110  // away. if "timeout" (measured in milliseconds) is non-zero, then the
111  // function will wait until the condition becomes true or the "timeout"
112  // elapses. note: no infinite timeouts are provided here.
113 
114  int select(basis::int_array &read_sox, basis::int_array &write_sox, int timeout = 0) const;
115  // similar to select above, but operates on a list of sockets in the
116  // "read_sox" and "write_sox". the "read_sox" are checked to see whether
117  // those sockets have data pending that could be read. the "write_sox" are
118  // checked to see if the sockets are currently writable without blocking.
119  // if any sockets have events applicable to the "selection_mode", then they
120  // will still be present in the lists when the call returns. zero is
121  // returned if absolutely nothing happened during the "timeout" period;
122  // otherwise, a non-zero number is returned but the individual sockets
123  // must still be inspected to determine what happened.
124 
125  int analyze_select_result(basis::un_int socket, int mode, fd_set_wrapper &read_list,
126  fd_set_wrapper &write_list, fd_set_wrapper &exceptions) const;
127  // examines the "socket" in the fd_sets passed in and returns a result
128  // based on those sets and the "mode".
129 
130 private:
131  tcpip_stack *_stack;
132 
133  int test_readability(basis::un_int socket) const;
134  // checks on the readability state for the "socket", assuming that select()
135  // reported the socket as readable, and returns either SI_ERRONEOUS,
136  // SI_READABLE or SI_DISCONNECTED based on what ioctl() says about it.
137 
138  int inner_select(basis::un_int socket, int selection_mode, int timeout,
139  fd_set_wrapper &read_list, fd_set_wrapper &write_list,
140  fd_set_wrapper &exceptions) const;
141  // intermediate function that doesn't attempt to fully analyze the select
142  // result. the returned value will be non-zero if something interesting
143  // is happening on the socket. if that value is SI_ERRONEOUS, then
144  // something bad happened to the socket. the other non-zero value is
145  // SI_BASELINE, which means the socket has something to report in the
146  // fd_set parameters.
147 };
148 
150 
151 /* wow, an ancient screw-up, leaving these in here after they were abstracted to tcpip_definitions.h; yargh.
152 #ifdef __UNIX__
153  // provide some unifying definitions.
154  #define INVALID_SOCKET -1
155  #define SOCKET_ERROR -1
156  typedef void sock_hop;
157 
158  // provide synonyms for errors so we don't conflict with the windows
159  // brain-deadness. they define error values like EACCESS but they're not
160  // the real values you need to use with tcp/ip. french fried gates time.
161  #define SOCK_EACCES EACCES
162  #define SOCK_EADDRINUSE EADDRINUSE
163  #define SOCK_EADDRNOTAVAIL EADDRNOTAVAIL
164  #define SOCK_EAFNOSUPPORT EAFNOSUPPORT
165  #define SOCK_EALREADY EALREADY
166  #define SOCK_EBADF EBADF
167  #define SOCK_ECONNABORTED ECONNABORTED
168  #define SOCK_ECONNREFUSED ECONNREFUSED
169  #define SOCK_ECONNRESET ECONNRESET
170  #define SOCK_EDESTADDRREQ EDESTADDRREQ
171  #define SOCK_EDQUOT EDQUOT
172  #define SOCK_EFAULT EFAULT
173  #define SOCK_EHOSTDOWN EHOSTDOWN
174  #define SOCK_EHOSTUNREACH EHOSTUNREACH
175  #define SOCK_EINPROGRESS EINPROGRESS
176  #define SOCK_EINTR EINTR
177  #define SOCK_EINVAL EINVAL
178  #define SOCK_EISCONN EISCONN
179  #define SOCK_ELOOP ELOOP
180  #define SOCK_EMFILE EMFILE
181  #define SOCK_EMSGSIZE EMSGSIZE
182  #define SOCK_ENAMETOOLONG ENAMETOOLONG
183  #define SOCK_ENETDOWN ENETDOWN
184  #define SOCK_ENETUNREACH ENETUNREACH
185  #define SOCK_ENETRESET ENETRESET
186  #define SOCK_ENOBUFS ENOBUFS
187  #define SOCK_ENOPROTOOPT ENOPROTOOPT
188  #define SOCK_ENOTCONN ENOTCONN
189  #define SOCK_ENOTEMPTY ENOTEMPTY
190  #define SOCK_ENOTSOCK ENOTSOCK
191  #define SOCK_EOPNOTSUPP EOPNOTSUPP
192  #define SOCK_EPFNOSUPPORT EPFNOSUPPORT
193  #define SOCK_EPROCLIM EPROCLIM
194  #define SOCK_EPROTOTYPE EPROTOTYPE
195  #define SOCK_EPROTONOSUPPORT EPROTONOSUPPORT
196  #define SOCK_EREMOTE EREMOTE
197  #define SOCK_ESHUTDOWN ESHUTDOWN
198  #define SOCK_ESOCKTNOSUPPORT ESOCKTNOSUPPORT
199  #define SOCK_ESTALE ESTALE
200  #define SOCK_ETIMEDOUT ETIMEDOUT
201  #define SOCK_ETOOMANYREFS ETOOMANYREFS
202  #define SOCK_EWOULDBLOCK EWOULDBLOCK
203  #define SOCK_EUSERS EUSERS
204 #endif //unix.
205 
207 
208 #ifdef __WIN32__
209  typedef char sock_hop;
210  typedef int socklen_t;
211 
212  // provide close to the real BSD error names using windows values.
213  #define SOCK_EACCES WSAEACCES
214  #define SOCK_EADDRINUSE WSAEADDRINUSE
215  #define SOCK_EADDRNOTAVAIL WSAEADDRNOTAVAIL
216  #define SOCK_EAFNOSUPPORT WSAEAFNOSUPPORT
217  #define SOCK_EALREADY WSAEALREADY
218  #define SOCK_EBADF WSAEBADF
219  #define SOCK_ECONNABORTED WSAECONNABORTED
220  #define SOCK_ECONNREFUSED WSAECONNREFUSED
221  #define SOCK_ECONNRESET WSAECONNRESET
222  #define SOCK_EDESTADDRREQ WSAEDESTADDRREQ
223  #define SOCK_EDQUOT WSAEDQUOT
224  #define SOCK_EFAULT WSAEFAULT
225  #define SOCK_EHOSTDOWN WSAEHOSTDOWN
226  #define SOCK_EHOSTUNREACH WSAEHOSTUNREACH
227  #define SOCK_EINPROGRESS WSAEINPROGRESS
228  #define SOCK_EINTR WSAEINTR
229  #define SOCK_EINVAL WSAEINVAL
230  #define SOCK_EISCONN WSAEISCONN
231  #define SOCK_ELOOP WSAELOOP
232  #define SOCK_EMFILE WSAEMFILE
233  #define SOCK_EMSGSIZE WSAEMSGSIZE
234  #define SOCK_ENAMETOOLONG WSAENAMETOOLONG
235  #define SOCK_ENETDOWN WSAENETDOWN
236  #define SOCK_ENETUNREACH WSAENETUNREACH
237  #define SOCK_ENETRESET WSAENETRESET
238  #define SOCK_ENOBUFS WSAENOBUFS
239  #define SOCK_ENOPROTOOPT WSAENOPROTOOPT
240  #define SOCK_ENOTCONN WSAENOTCONN
241  #define SOCK_ENOTEMPTY WSAENOTEMPTY
242  #define SOCK_ENOTSOCK WSAENOTSOCK
243  #define SOCK_EOPNOTSUPP WSAEOPNOTSUPP
244  #define SOCK_EPFNOSUPPORT WSAEPFNOSUPPORT
245  #define SOCK_EPROCLIM WSAEPROCLIM
246  #define SOCK_EPROTOTYPE WSAEPROTOTYPE
247  #define SOCK_EPROTONOSUPPORT WSAEPROTONOSUPPORT
248  #define SOCK_EREMOTE WSAEREMOTE
249  #define SOCK_ESHUTDOWN WSAESHUTDOWN
250  #define SOCK_ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT
251  #define SOCK_ESTALE WSAESTALE
252  #define SOCK_ETIMEDOUT WSAETIMEDOUT
253  #define SOCK_ETOOMANYREFS WSAETOOMANYREFS
254  #define SOCK_EUSERS WSAEUSERS
255 
256  // windows specific names.
257  #define SOCK_EWOULDBLOCK WSAEWOULDBLOCK
258  #define SOCK_HOST_NOT_FOUND WSAHOST_NOT_FOUND
259  #define SOCK_NO_DATA WSANO_DATA
260  #define SOCK_NO_RECOVERY WSANO_RECOVERY
261  #define SOCK_NOTINITIALISED WSANOTINITIALISED
262  #define SOCK_SYSNOTREADY WSASYSNOTREADY
263  #define SOCK_TRY_AGAIN WSATRY_AGAIN
264  #define SOCK_VERNOTSUPPORTED WSAVERNOTSUPPORTED
265 #endif //win32.
266 */
267 
269 
270 } //namespace.
271 
272 #endif // outer guard.
273 
Provides a dynamically resizable ASCII character string.
Definition: astring.h:35
A simple object that wraps a templated array of ints.
Definition: array.h:275
DEFINE_CLASS_NAME("raw_socket")
bool set_nagle_algorithm(basis::un_int socket, bool use_nagle=true)
Definition: raw_socket.cpp:155
int close(basis::un_int &socket)
Definition: raw_socket.cpp:89
int select(basis::un_int socket, int selection_mode, int timeout=0) const
Definition: raw_socket.cpp:203
int analyze_select_result(basis::un_int socket, int mode, fd_set_wrapper &read_list, fd_set_wrapper &write_list, fd_set_wrapper &exceptions) const
Definition: raw_socket.cpp:295
bool set_reuse_address(basis::un_int socket, bool reuse=true)
Definition: raw_socket.cpp:179
int ioctl(basis::un_int socket, int request, void *argp) const
Definition: raw_socket.cpp:123
bool set_keep_alive(basis::un_int socket, bool keep_alive=true)
Definition: raw_socket.cpp:191
static basis::astring interest_name(int to_name)
Definition: raw_socket.cpp:111
bool set_broadcast(basis::un_int socket, bool broadcasting=true)
Definition: raw_socket.cpp:167
bool set_non_blocking(basis::un_int socket, bool non_blocking=true)
Definition: raw_socket.cpp:139
Helpful functions for interacting with TCP/IP stacks.
Definition: tcpip_stack.h:38
unsigned int un_int
Abbreviated name for unsigned integers.
Definition: definitions.h:62
Provides access to the operating system's socket methods.
Definition: base_address.h:26
socket_interests
Definition: raw_socket.h:42
@ SI_CONNECTED
Definition: raw_socket.h:45
@ SI_DISCONNECTED
Definition: raw_socket.h:46
@ SI_ERRONEOUS
Definition: raw_socket.h:47
@ SI_BASELINE
Definition: raw_socket.h:48
@ SI_READABLE
Definition: raw_socket.h:43
@ SI_WRITABLE
Definition: raw_socket.h:44
@ SI_ALL_SOCK_INT
Definition: raw_socket.h:50