blob: 0e5f16760853f9d9a7ec7be0bea8d99094e84785 [file] [log] [blame]
Emeric Vigier2f625822012-08-06 11:09:52 -04001// Copyright (C) 1999-2005 Open Source Telecom Corporation.
2// Copyright (C) 2009 Leandro Melo de Sales <leandroal@gmail.com>
3// Copyright (C) 2006-2010 David Sugar, Tycho Softworks,
4//
5// This program is free software; you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation; either version 2 of the License, or
8// (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19// As a special exception, you may use this file as part of a free software
20// library without restriction. Specifically, if other files instantiate
21// templates or use macros or inline functions from this file, or you compile
22// this file and link it with other files to produce an executable, this
23// file does not by itself cause the resulting executable to be covered by
24// the GNU General Public License. This exception does not however
25// invalidate any other reasons why the executable file might be covered by
26// the GNU General Public License.
27//
28// This exception applies only to the code released under the name GNU
29// Common C++. If you copy code from other releases into a copy of GNU
30// Common C++, as the General Public License permits, the exception does
31// not apply to the code that you add in this way. To avoid misleading
32// anyone as to the status of such modified files, you must delete
33// this exception notice from them.
34//
35// If you write modifications of your own for GNU Common C++, it is your choice
36// whether to permit this exception to apply to your modifications.
37// If you do not wish that, delete this exception notice.
38//
39
40/**
41 * @file socket.h
42 * @short Network addresses and sockets related classes.
43 **/
44
45#ifndef CCXX_SOCKET_H_
46#define CCXX_SOCKET_H_
47
48#ifndef CCXX_ADDRESS_H_
49#include <cc++/address.h>
50#endif
51
52#if defined(WIN32) && !defined(__CYGWIN32__)
53#include <io.h>
54#define _IOLEN64 (unsigned)
55#define _IORET64 (int)
56#define TIMEOUT_INF ~((timeout_t) 0)
57typedef int socklen_t;
58#else
59#define INVALID_SOCKET -1
60typedef int SOCKET;
61#endif
62
63#ifndef _IOLEN64
64#define _IOLEN64
65#endif
66
67#ifndef _IORET64
68#define _IORET64
69#endif
70
71#ifndef MSG_DONTWAIT
72#define MSG_DONTWAIT 0
73#endif
74
75#ifndef MSG_NOSIGNAL
76#define MSG_NOSIGNAL 0
77#endif
78
79#ifndef SOCK_DCCP
80#define SOCK_DCCP 6
81#endif
82#ifndef IPPROTO_DCCP
83#define IPPROTO_DCCP 33
84#endif
85#ifndef SOL_DCCP
86#define SOL_DCCP 269
87#endif
88#define DCCP_SOCKOPT_AVAILABLE_CCIDS 12
89#define DCCP_SOCKOPT_CCID 13
90#define DCCP_SOCKOPT_TX_CCID 14
91#define DCCP_SOCKOPT_RX_CCID 15
92
93#ifdef CCXX_NAMESPACES
94namespace ost {
95#endif
96
97/**
98 * Transport Protocol Ports.
99 */
100typedef unsigned short tpport_t;
101
102/**
103 * The Socket is used as the base for all Internet protocol services
104 * under Common C++. A socket is a system resource (or winsock descriptor)
105 * that occupies a specific port address (and may be bound to a specific
106 * network interface) on the local machine. The socket may also be
107 * directly connected to a specific socket on a remote internet host.
108 *
109 * This base class is not directly used, but is
110 * provided to offer properties common to other Common C++ socket classes,
111 * including the socket exception model and the ability to set socket
112 * properties such as QoS, "sockopts" properties like Dont-Route
113 * and Keep-Alive, etc.
114 *
115 *
116 * @author David Sugar <dyfet@ostel.com>
117 * @short base class of all sockets.
118 */
119class __EXPORT Socket
120{
121public:
122 enum Family {
123#ifdef CCXX_IPV6
124 IPV6 = AF_INET6,
125#endif
126 IPV4 = AF_INET
127 };
128
129 typedef enum Family Family;
130
131 enum Error {
132 errSuccess = 0,
133 errCreateFailed,
134 errCopyFailed,
135 errInput,
136 errInputInterrupt,
137 errResourceFailure,
138 errOutput,
139 errOutputInterrupt,
140 errNotConnected,
141 errConnectRefused,
142 errConnectRejected,
143 errConnectTimeout,
144 errConnectFailed,
145 errConnectInvalid,
146 errConnectBusy,
147 errConnectNoRoute,
148 errBindingFailed,
149 errBroadcastDenied,
150 errRoutingDenied,
151 errKeepaliveDenied,
152 errServiceDenied,
153 errServiceUnavailable,
154 errMulticastDisabled,
155 errTimeout,
156 errNoDelay,
157 errExtended,
158 errLookupFail,
159 errSearchErr,
160 errInvalidValue
161 };
162
163 typedef enum Error Error;
164
165 enum Tos {
166 tosLowDelay = 0,
167 tosThroughput,
168 tosReliability,
169 tosMinCost,
170 tosInvalid
171 };
172 typedef enum Tos Tos;
173
174 enum Pending {
175 pendingInput,
176 pendingOutput,
177 pendingError
178 };
179 typedef enum Pending Pending;
180
181protected:
182 enum State {
183 INITIAL,
184 AVAILABLE,
185 BOUND,
186 CONNECTED,
187 CONNECTING,
188 STREAM
189 };
190 typedef enum State State;
191
192private:
193 // used by exception handlers....
194 mutable Error errid;
195 mutable const char *errstr;
196 mutable long syserr;
197
198 void setSocket(void);
199 friend SOCKET dupSocket(SOCKET s,Socket::State state);
200
201protected:
202 static Mutex mutex;
203
204 mutable struct {
205 bool thrown: 1;
206 bool broadcast: 1;
207 bool route: 1;
208 bool keepalive: 1;
209 bool loopback: 1;
210 bool multicast: 1;
211 bool completion: 1;
212 bool linger: 1;
213 unsigned ttl: 8;
214 } flags;
215
216 /**
217 * the actual socket descriptor, in Windows, unlike posix it
218 * *cannot* be used as an file descriptor
219 * that way madness lies -- jfc
220 */
221 SOCKET volatile so;
222 State volatile state;
223
224 /**
225 * This service is used to throw all socket errors which usually
226 * occur during the socket constructor.
227 *
228 * @param error defined socket error id.
229 * @param err string or message to pass.
230 * @param systemError the system error# that caused the error
231 */
232 Error error(Error error, const char *err = NULL, long systemError = 0) const;
233
234 /**
235 * This service is used to throw application defined socket errors
236 * where the application specific error code is a string.
237 *
238 * @param err string or message to pass.
239 */
240 inline void error(const char *err) const
241 {error(errExtended, err);};
242
243 /**
244 * This service is used to turn the error handler on or off for
245 * "throwing" exceptions by manipulating the thrown flag.
246 *
247 * @param enable true to enable handler.
248 */
249 inline void setError(bool enable)
250 {flags.thrown = !enable;};
251
252 /**
253 * Used as the default destructor for ending a socket. This
254 * will cleanly terminate the socket connection. It is provided
255 * for use in derived virtual destructors.
256 */
257 void endSocket(void);
258
259 /**
260 * Used as a common handler for connection failure processing.
261 *
262 * @return correct failure code to apply.
263 */
264 Error connectError(void);
265
266 /**
267 * Set the send limit.
268 */
269 Error sendLimit(int limit = 2048);
270
271 /**
272 * Set thr receive limit.
273 */
274 Error receiveLimit(int limit = 1);
275
276 /**
277 * Set the send timeout for sending raw network data.
278 *
279 * @return errSuccess if set.
280 * @param timer value in millisec.
281 */
282 Error sendTimeout(timeout_t timer);
283
284 /**
285 * Receive timeout for receiving raw network data.
286 *
287 * @return errSuccess if set.
288 * @param timer value in milliseconds.
289 */
290 Error receiveTimeout(timeout_t timer);
291
292 /**
293 * Set the protocol stack network kernel send buffer size
294 * associated with the socket.
295 *
296 * @return errSuccess on success, or error.
297 * @param size of buffer in bytes.
298 */
299 Error sendBuffer(unsigned size);
300
301 /**
302 * Set the protocol stack network kernel receive buffer size
303 * associated with the socket.
304 *
305 * @return errSuccess on success, or error.
306 * @param size of buffer in bytes.
307 */
308 Error receiveBuffer(unsigned size);
309
310 /**
311 * Set the total protocol stack network kernel buffer size
312 * for both send and receive together.
313 *
314 * @return errSuccess on success
315 * @param size of buffer.
316 */
317 Error bufferSize(unsigned size);
318
319 /**
320 * Set the subnet broadcast flag for the socket. This enables
321 * sending to a subnet and may require special image privileges
322 * depending on the operating system.
323 *
324 * @return 0 (errSuccess) on success, else error code.
325 * @param enable when set to true.
326 */
327 Error setBroadcast(bool enable);
328
329 /**
330 * Setting multicast binds the multicast interface used for
331 * the socket to the interface the socket itself has been
332 * implicitly bound to. It is also used as a check flag
333 * to make sure multicast is enabled before multicast
334 * operations are used.
335 *
336 * @return 0 (errSuccess) on success, else error code.
337 * @param enable when set to true.
338 * @param family of protocol.
339 */
340 Error setMulticastByFamily(bool enable, Family family = IPV4);
341
342 /**
343 * Set the multicast loopback flag for the socket. Loopback
344 * enables a socket to hear what it is sending.
345 *
346 * @return 0 (errSuccess) on success, else error code.
347 * @param enable when set to true.
348 * @param family of protocol.
349 */
350 Error setLoopbackByFamily(bool enable, Family family = IPV4);
351
352 /**
353 * Set the multicast time to live for a multicast socket.
354 *
355 * @return 0 (errSuccess) on success, else error code.
356 * @param ttl time to live.
357 * @param fam family of protocol.
358 */
359 Error setTimeToLiveByFamily(unsigned char ttl, Family fam = IPV4);
360
361 /**
362 * Join a multicast group.
363 *
364 * @return 0 (errSuccess) on success, else error code.
365 * @param ia address of multicast group to join.
366 */
367 Error join(const IPV4Multicast &ia);
368#ifdef CCXX_IPV6
369 Error join(const IPV6Multicast &ia);
370#endif
371
372 /**
373 * Drop membership from a multicast group.
374 *
375 * @return 0 (errSuccess) on success, else error code.
376 * @param ia address of multicast group to drop.
377 */
378 Error drop(const IPV4Multicast &ia);
379#ifdef CCXX_IPV6
380 Error drop(const IPV6Multicast &ia);
381#endif
382
383 /**
384 * Set the socket routing to indicate if outgoing messages
385 * should bypass normal routing (set false).
386 *
387 * @return 0 on success.
388 * @param enable normal routing when set to true.
389 */
390 Error setRouting(bool enable);
391
392
393 /**
394 * Enable/disable delaying packets (Nagle algorithm)
395 *
396 * @return 0 on success.
397 * @param enable disable Nagle algorithm when set to true.
398 */
399 Error setNoDelay(bool enable);
400
401 /**
402 * An unconnected socket may be created directly on the local
403 * machine. Sockets can occupy both the internet domain (AF_INET)
404 * and UNIX socket domain (AF_UNIX) under unix. The socket type
405 * (SOCK_STREAM, SOCK_DGRAM) and protocol may also be specified.
406 * If the socket cannot be created, an exception is thrown.
407 *
408 * @param domain socket domain to use.
409 * @param type base type and protocol family of the socket.
410 * @param protocol specific protocol to apply.
411 */
412 Socket(int domain, int type, int protocol = 0);
413
414 /**
415 * A socket object may be created from a file descriptor when that
416 * descriptor was created either through a socket() or accept()
417 * call. This constructor is mostly for internal use.
418 *
419 * @param fd file descriptor of an already existing socket.
420 */
421 Socket(SOCKET fd);
422
423 /**
424 * Create an inactive socket object for base constructors.
425 */
426 Socket();
427
428 /**
429 * A socket can also be constructed from an already existing
430 * Socket object. On POSIX systems, the socket file descriptor
431 * is dup()'d. On Win32, DuplicateHandle() is used.
432 *
433 * @param source of existing socket to clone.
434 */
435 Socket(const Socket &source);
436
437 /**
438 * Process a logical input line from a socket descriptor
439 * directly.
440 *
441 * @param buf pointer to string.
442 * @param len maximum length to read.
443 * @param timeout for pending data in milliseconds.
444 * @return number of bytes actually read.
445 */
446 ssize_t readLine(char *buf, size_t len, timeout_t timeout = 0);
447
448 /**
449 * Read in a block of len bytes with specific separator. Can
450 * be zero, or any other char. If \\n or \\r, it's treated just
451 * like a readLine(). Otherwise it looks for the separator.
452 *
453 * @param buf pointer to byte allocation.
454 * @param len maximum length to read.
455 * @param separator separator for a particular ASCII character
456 * @param t timeout for pending data in milliseconds.
457 * @return number of bytes actually read.
458 */
459 virtual ssize_t readData(void * buf,size_t len,char separator=0,timeout_t t=0);
460
461 /**
462 * Write a block of len bytes to socket.
463 *
464 * @param buf pointer to byte allocation.
465 * @param len maximum length to write.
466 * @param t timeout for pending data in milliseconds.
467 * @return number of bytes actually written.
468 */
469 virtual ssize_t writeData(const void* buf,size_t len,timeout_t t=0);
470
471public:
472 /**
473 * The socket base class may be "thrown" as a result of an
474 * error, and the "catcher" may then choose to destroy the
475 * object. By assuring the socket base class is a virtual
476 * destructor, we can assure the full object is properly
477 * terminated.
478 */
479 virtual ~Socket();
480
481 /**
482 * See if a specific protocol family is available in the
483 * current runtime environment.
484 *
485 * @return true if family available.
486 */
487 static bool check(Family fam);
488
489 /**
490 * Sockets may also be duplicated by the assignment operator.
491 */
492 Socket &operator=(const Socket &from);
493
494 /**
495 * May be used to examine the origin of data waiting in the
496 * socket receive queue. This can tell a TCP server where pending
497 * "connect" requests are coming from, or a UDP socket where it's
498 * next packet arrived from.
499 *
500 * @param port ptr to port number of sender.
501 * @return host address, test with "isInetAddress()".
502 */
503 virtual IPV4Host getIPV4Sender(tpport_t *port = NULL) const;
504
505 inline IPV4Host getSender(tpport_t *port = NULL) const
506 {return getIPV4Sender(port);}
507
508#ifdef CCXX_IPV6
509 virtual IPV6Host getIPV6Sender(tpport_t *port = NULL) const;
510#endif
511
512 /**
513 * Get the host address and port of the socket this socket
514 * is connected to. If the socket is currently not in a
515 * connected state, then a host address of 0.0.0.0 is
516 * returned.
517 *
518 * @param port ptr to port number of remote socket.
519 * @return host address of remote socket.
520 */
521 IPV4Host getIPV4Peer(tpport_t *port = NULL) const;
522
523 inline IPV4Host getPeer(tpport_t *port = NULL) const
524 {return getIPV4Peer(port);}
525
526#ifdef CCXX_IPV6
527 IPV6Host getIPV6Peer(tpport_t *port = NULL) const;
528#endif
529
530 /**
531 * Get the local address and port number this socket is
532 * currently bound to.
533 *
534 * @param port ptr to port number on local host.
535 * @return host address of interface this socket is bound to.
536 */
537 IPV4Host getIPV4Local(tpport_t *port = NULL) const;
538
539 inline IPV4Host getLocal(tpport_t *port = NULL) const
540 {return getIPV4Local(port);}
541
542#ifdef CCXX_IPV6
543 IPV6Host getIPV6Local(tpport_t *port = NULL) const;
544#endif
545
546 /**
547 * Perform NAT table lookup for this socket.
548 * Used to allow an application to know the original ip:port
549 * pair the the client "thinks" it is connecting to. Used mostly
550 * to transparently impersonate a remote server/service.
551 *
552 * On error, 0.0.0.0:0 is returned and one of the following error codes
553 * is set: errServiceUnavailable - if nat is not supported on the
554 * current platform or if it was not compiled; errLookupFail - if the
555 * nat syscall failed for some reason (extended error code);
556 * errSearchErr - if the socket does not have nat information (i.e.
557 * is not nated).
558 *
559 * NAT lookup is supported on NetFilter for ipv4 and ipv6 (Linux),
560 * IPFilter for ipv4 (Solaris, *BSD except OpenBSD, HP-UX, etc.) and
561 * Packet Filter for ipv4 and ipv6 (OpenBSD).
562 * When using IPFilter or Packet Filter, the first NAT lookup must be
563 * performed as root (the NAT device is read only for root and is opened
564 * once, unless an error occurs). Permissions on the nat device may be
565 * changed to solve this.
566 *
567 * \warning When using IPFilter and Packet Filter, application data model
568 * must be the same as the running kernel (32/64 bits).
569 *
570 * @param port ptr to NATed port number on local host.
571 * @return NATed host address that this socket is related to.
572 */
573 IPV4Host getIPV4NAT(tpport_t *port = NULL) const;
574
575 inline IPV4Host getNAT(tpport_t *port) const
576 {return getIPV4NAT(port);}
577
578#ifdef CCXX_IPV6
579 IPV6Host getIPV6NAT(tpport_t *port = NULL) const;
580#endif
581
582 /**
583 * Used to specify blocking mode for the socket. A socket
584 * can be made non-blocking by setting setCompletion(false)
585 * or set to block on all access with setCompletion(true).
586 * I do not believe this form of non-blocking socket I/O is supported
587 * in winsock, though it provides an alternate asynchronous set of
588 * socket services.
589 *
590 * @param immediate mode specify socket I/O call blocking mode.
591 */
592 void setCompletion(bool immediate);
593
594 /**
595 * Enable lingering sockets on close.
596 *
597 * @param linger specify linger enable.
598 */
599 Error setLinger(bool linger);
600
601 /**
602 * Set the keep-alive status of this socket and if keep-alive
603 * messages will be sent.
604 *
605 * @return 0 on success.
606 * @param enable keep alive messages.
607 */
608 Error setKeepAlive(bool enable);
609
610 /**
611 * Set packet scheduling on platforms which support ip quality
612 * of service conventions. This effects how packets in the
613 * queue are scheduled through the interface.
614 *
615 * @return 0 on success, error code on failure.
616 * @param service type of service enumerated type.
617 */
618 Error setTypeOfService(Tos service);
619
620 /**
621 * Can test to see if this socket is "connected", and hence
622 * whether a "catch" can safely call getPeer(). Of course,
623 * an unconnected socket will return a 0.0.0.0 address from
624 * getPeer() as well.
625 *
626 * @return true when socket is connected to a peer.
627 */
628 bool isConnected(void) const;
629
630 /**
631 * Test to see if the socket is at least operating or if it
632 * is mearly initialized. "initialized" sockets may be the
633 * result of failed constructors.
634 *
635 * @return true if not in initial state.
636 */
637 bool isActive(void) const;
638
639 /**
640 * Operator based testing to see if a socket is currently
641 * active.
642 */
643 bool operator!() const;
644
645 /**
646 * Return if broadcast has been enabled for the specified
647 * socket.
648 *
649 * @return true if broadcast socket.
650 */
651 inline bool isBroadcast(void) const
652 {return flags.broadcast;};
653
654 /**
655 * Return if socket routing is enabled.
656 *
657 * @return true if routing enabled.
658 */
659 inline bool isRouted(void) const
660 {return flags.route;};
661
662 /**
663 * Often used by a "catch" to fetch the last error of a thrown
664 * socket.
665 *
666 * @return error number of Error error.
667 */
668 inline Error getErrorNumber(void) const {return errid;}
669
670 /**
671 * Often used by a "catch" to fetch the user set error string
672 * of a thrown socket, but only if EXTENDED error codes are used.
673 *
674 * @return string for error message.
675 */
676 inline const char *getErrorString(void) const {return errstr;}
677
678 inline long getSystemError(void) const {return syserr;}
679
680 const char *getSystemErrorString(void) const;
681
682 /**
683 * Get the status of pending operations. This can be used to
684 * examine if input or output is waiting, or if an error has
685 * occured on the descriptor.
686 *
687 * @return true if ready, false on timeout.
688 * @param pend ready check to perform.
689 * @param timeout in milliseconds, inf. if not specified.
690 */
691 virtual bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
692};
693
694/**
695 * DCCP sockets are used for stream based connected sessions between two
696 * sockets. Both error recovery and flow control operate transparently
697 * for a DCCP socket connection. The DCCP socket base class is used both
698 * for client connections and to bind a DCCP "server" for accepting DCCP
699 * streams.
700 *
701 * An implicit and unique DCCPSocket object exists in Common C++ to represent
702 * a bound DCCP socket acting as a "server" for receiving connection requests.
703 * This class is not part of DCCPStream because such objects normally perform
704 * no physical I/O (read or write operations) other than to specify a listen
705 * backlog queue and perform "accept" operations for pending connections.
706 * The Common C++ DCCPSocket offers a Peek method to examine where the next
707 * pending connection is coming from, and a Reject method to flush the next
708 * request from the queue without having to create a session.
709 *
710 * The DCCPSocket also supports a "OnAccept" method which can be called when a
711 * DCCPStream related object is created from a DCCPSocket. By creating a
712 * DCCPStream from a DCCPSocket, an accept operation automatically occurs, and
713 * the DCCPSocket can then still reject the client connection through the
714 * return status of it's OnAccept method.
715 *
716 * @author Leandro Sales <leandroal@gmail.com>
717 * @author Heverton Stuart <hevertonsns@gmail.com>
718 * @short bound server for DCCP streams and sessions.
719 */
720class __EXPORT DCCPSocket : public Socket
721{
722 union {
723 struct sockaddr_in ipv4;
724#ifdef CCXX_IPV6
725 struct sockaddr_in6 ipv6;
726#endif
727 } peer;
728
729 Family family;
730
731public:
732 /**
733 * A method to call in a derived DCCPSocket class that is acting
734 * as a server when a connection request is being accepted. The
735 * server can implement protocol specific rules to exclude the
736 * remote socket from being accepted by returning false. The
737 * Peek method can also be used for this purpose.
738 *
739 * @return true if client should be accepted.
740 * @param ia internet host address of the client.
741 * @param port number of the client.
742 */
743 virtual bool onAccept(const IPV4Host &ia, tpport_t port);
744#ifdef CCXX_IPV6
745 virtual bool onAccept(const IPV6Host &ia, tpport_t port);
746#endif
747
748 virtual IPV4Host getIPV4Sender(tpport_t *port = NULL) const;
749
750#ifdef CCXX_IPV6
751 virtual IPV6Host getIPV6Sender(tpport_t *port = NULL) const;
752#endif
753
754 /**
755 * A DCCP "server" is created as a DCCP socket that is bound
756 * to a hardware address and port number on the local machine
757 * and that has a backlog queue to listen for remote connection
758 * requests. If the server cannot be created, an exception is
759 * thrown.
760 *
761 * @param bind local ip address or interface to use.
762 * @param port number to bind socket under.
763 * @param backlog size of connection request queue.
764 */
765 DCCPSocket(const IPV4Address &bind, tpport_t port, unsigned backlog = 5);
766#ifdef CCXX_IPV6
767 DCCPSocket(const IPV6Address &bind, tpport_t port, unsigned backlog = 5);
768#endif
769
770 /**
771 * Create a named dccp socket by service and/or interface id.
772 * For IPV4 we use [host:]svc or [host/]svc for the string.
773 * If we have getaddrinfo, we use that to obtain the addr to
774 * bind for.
775 *
776 * @param name of host interface and service port to bind.
777 * @param backlog size of connection request queue.
778 */
779 DCCPSocket(const char *name, Family family = IPV4, unsigned backlog = 5);
780
781 /**
782 * Create an unconnected ephemeral DCCP client socket.
783 */
784 DCCPSocket(Family family = IPV4);
785
786 /**
787 * Create a server session by accepting a DCCP Socket.
788 */
789 DCCPSocket(DCCPSocket& server, timeout_t timeout = 0);
790
791 /**
792 * Used to reject the next incoming connection request.
793 */
794 void reject(void);
795
796 /**
797 * Disconnect active dccp connection (client use).
798 */
799 void disconnect(void);
800
801 /**
802 * Set CCID DCCP.
803 */
804 bool setCCID(uint8 ccid);
805
806 /**
807 * Get TX CCID DCCP.
808 */
809 int getTxCCID();
810
811 /**
812 * Get RX CCID DCCP.
813 */
814 int getRxCCID();
815
816 /**
817 * Return number of bytes to be read
818 */
819 size_t available();
820
821 /**
822 * Create a DCCP client connection to a DCCP socket (on
823 * a remote machine).
824 *
825 * @param host address of remote DCCP server.
826 * @param port number to connect.
827 */
828 void connect(const IPV4Host &host, tpport_t port, timeout_t timeout = 0);
829#ifdef CCXX_IPV6
830 void connect(const IPV6Host &host, tpport_t port, timeout_t timeout = 0);
831#endif
832
833 /**
834 * Connect to a named client.
835 */
836 void connect(const char *name);
837
838 /**
839 * Used to wait for pending connection requests.
840 * @return true if data packets available.
841 * @param timeout in milliseconds. TIMEOUT_INF if not specified.
842 */
843 inline bool isPendingConnection(timeout_t timeout = TIMEOUT_INF) /* not const -- jfc */
844 {return Socket::isPending(Socket::pendingInput, timeout);}
845
846 /**
847 * Use base socket handler for ending this socket.
848 */
849 virtual ~DCCPSocket();
850};
851
852/**
853 * UDP sockets implement the TCP SOCK_DGRAM UDP protocol. They can be
854 * used to pass unverified messages between hosts, or to broadcast a
855 * specific message to an entire subnet. Please note that Streaming of
856 * realtime data commonly use UDPDuplex related classes rather than
857 * UDPSocket.
858 *
859 * In addition to connected TCP sessions, Common C++ supports UDP sockets and
860 * these also cover a range of functionality. Like a TCPSocket, A UDPSocket
861 * can be created bound to a specific network interface and/or port address,
862 * though this is not required. UDP sockets also are usually either
863 * connected or otherwise "associated" with a specific "peer" UDP socket.
864 * Since UDP sockets operate through discreet packets, there are no streaming
865 * operators used with UDP sockets.
866 *
867 * In addition to the UDP "socket" class, there is a "UDPBroadcast" class.
868 * The UDPBroadcast is a socket that is set to send messages to a subnet as a
869 * whole rather than to an individual peer socket that it may be associated
870 * with.
871 *
872 * UDP sockets are often used for building "realtime" media streaming
873 * protocols and full duplex messaging services. When used in this manner,
874 * typically a pair of UDP sockets are used together; one socket is used to
875 * send and the other to receive data with an associated pair of UDP sockets
876 * on a "peer" host. This concept is represented through the Common C++
877 * UDPDuplex object, which is a pair of sockets that communicate with another
878 * UDPDuplex pair.
879 *
880 *
881 * @author David Sugar <dyfet@ostel.com>
882 * @short Unreliable Datagram Protocol sockets.
883 */
884class __EXPORT UDPSocket : public Socket
885{
886private:
887 inline Error setKeepAlive(bool enable)
888 {return Socket::setKeepAlive(enable);};
889
890protected:
891#ifdef CCXX_IPV6
892 union {
893 struct sockaddr_in6 ipv6;
894 struct sockaddr_in ipv4;
895 } peer;
896#else
897 union {
898 struct sockaddr_in ipv4;
899 } peer;
900#endif
901
902 Family family;
903
904public:
905 /**
906 * Create an unbound UDP socket, mostly for internal use.
907 */
908 UDPSocket(Family family = IPV4);
909
910 /**
911 * Create a UDP socket bound by a service name.
912 */
913 UDPSocket(const char *name, Family family = IPV4);
914
915 /**
916 * Create a UDP socket and bind it to a specific interface
917 * and port address so that other UDP sockets on remote
918 * machines (or the same host) may find and send UDP messages
919 * to it. On failure to bind, an exception is thrown.
920 *
921 * @param bind address to bind this socket to.
922 * @param port number to bind this socket to.
923 */
924 UDPSocket(const IPV4Address &bind, tpport_t port);
925#ifdef CCXX_IPV6
926 UDPSocket(const IPV6Address &bind, tpport_t port);
927#endif
928
929 /**
930 * Destroy a UDP socket as a socket.
931 */
932 virtual ~UDPSocket();
933
934 /**
935 * Set the loopback.
936 */
937 inline Error setLoopback(bool enable)
938 {return Socket::setLoopbackByFamily(enable, family);}
939
940 /**
941 * Set the multicast.
942 */
943 inline Error setMulticast(bool enable)
944 {return Socket::setMulticastByFamily(enable, family);}
945
946 /**
947 * Set time to live.
948 */
949 inline Error setTimeToLive(char ttl)
950 {return Socket::setTimeToLiveByFamily(ttl, family);}
951
952 /**
953 * set the peer address to send message packets to. This can be
954 * set before every send() call if nessisary.
955 *
956 * @param host address to send packets to.
957 * @param port number to deliver packets to.
958 */
959 void setPeer(const IPV4Host &host, tpport_t port);
960 void connect(const IPV4Host &host, tpport_t port);
961#ifdef CCXX_IPV6
962 void setPeer(const IPV6Host &host, tpport_t port);
963 void connect(const IPV6Host &host, tpport_t port);
964#endif
965
966 /**
967 * get the interface index for a named network device
968 *
969 * @param ethX is device name, like "eth0" or "eth1"
970 * @param InterfaceIndex is the index value returned by os
971 * @todo Win32 and ipv6 specific implementation.
972 */
973 Socket::Error getInterfaceIndex(const char *ethX,int& InterfaceIndex);
974
975 /**
976 * join a multicast group on a particular interface
977 *
978 * @param ia is the multicast address to use
979 * @param InterfaceIndex is the index value returned by
980 * getInterfaceIndex
981 * @todo Win32 and ipv6 specific implementation.
982 */
983 Socket::Error join(const IPV4Multicast &ia,int InterfaceIndex);
984
985
986 /**
987 * Send a message packet to a peer host.
988 *
989 * @param buf pointer to packet buffer to send.
990 * @param len of packet buffer to send.
991 * @return number of bytes sent.
992 */
993 ssize_t send(const void *buf, size_t len);
994
995 /**
996 * Receive a message from any host.
997 *
998 * @param buf pointer to packet buffer to receive.
999 * @param len of packet buffer to receive.
1000 * @param reply save sender address for reply if true.
1001 * @return number of bytes received.
1002 */
1003 ssize_t receive(void *buf, size_t len, bool reply = false);
1004
1005 /**
1006 * Examine address of sender of next waiting packet. This also
1007 * sets "peer" address to the sender so that the next "send"
1008 * message acts as a "reply". This additional behavior overides
1009 * the standard socket getSender behavior.
1010 *
1011 * @param port pointer to hold port number.
1012 */
1013 IPV4Host getIPV4Peer(tpport_t *port = NULL) const;
1014 inline IPV4Host getPeer(tpport_t *port = NULL) const
1015 {return getIPV4Peer(port);}
1016
1017#ifdef CCXX_IPV6
1018 IPV6Host getIPV6Peer(tpport_t *port = NULL) const;
1019#endif
1020
1021 /**
1022 * Examine contents of next waiting packet.
1023 *
1024 * @param buf pointer to packet buffer for contents.
1025 * @param len of packet buffer.
1026 * @return number of bytes examined.
1027 */
1028 inline ssize_t peek(void *buf, size_t len)
1029 {return _IORET64 ::recv(so, (char *)buf, _IOLEN64 len, MSG_PEEK);};
1030
1031 /**
1032 * Associate socket with a named connection
1033 */
1034 void setPeer(const char *service);
1035 void connect(const char *service);
1036
1037 /**
1038 * Disassociate this socket from any host connection. No data
1039 * should be read or written until a connection is established.
1040 */
1041 Error disconnect(void);
1042};
1043
1044
1045/**
1046 * Representing a UDP socket used for subnet broadcasts, this class
1047 * provides an alternate binding and setPeer() capability for UDP
1048 * sockets.
1049 *
1050 * @author David Sugar <dyfet@ostel.com>
1051 * @short Unreliable Datagram for subnet broadcasts.
1052 */
1053class __EXPORT UDPBroadcast : public UDPSocket
1054{
1055private:
1056 void setPeer(const IPV4Host &ia, tpport_t port);
1057
1058 Error setBroadcast(bool enable)
1059 {return Socket::setBroadcast(enable);};
1060
1061public:
1062 /**
1063 * Create and bind a subnet broadcast socket.
1064 *
1065 * @param ia address to bind socket under locally.
1066 * @param port to bind socket under locally.
1067 */
1068 UDPBroadcast(const IPV4Address &ia, tpport_t port);
1069
1070 /**
1071 * Set peer by subnet rather than specific host.
1072 *
1073 * @param subnet of peer hosts to send to.
1074 * @param port number to use.
1075 */
1076 void setPeer(const IPV4Broadcast &subnet, tpport_t port);
1077};
1078
1079/**
1080 * Representing half of a two-way UDP connection, the UDP transmitter
1081 * can broadcast data to another selected peer host or to an entire
1082 * subnet.
1083 *
1084 * @author David Sugar <dyfet@ostel.com>
1085 * @short Unreliable Datagram Peer Associations.
1086 */
1087class __EXPORT UDPTransmit : protected UDPSocket
1088{
1089private:
1090 /**
1091 * Common code for diferent flavours of Connect (host, broadcast,
1092 * multicast).
1093 *
1094 * @param ia network address to associate with
1095 * @param port port number to associate with
1096 */
1097 Error cConnect(const IPV4Address &ia, tpport_t port);
1098
1099protected:
1100 /**
1101 * Create a UDP transmitter.
1102 */
1103 UDPTransmit(Family family = IPV4);
1104
1105 /**
1106 * Create a UDP transmitter, bind it to a specific interface
1107 * and port address so that other UDP sockets on remote
1108 * machines (or the same host) may find and send UDP messages
1109 * to it, and associate it with a given port on a peer host.
1110 * On failure to bind, an exception is thrown. This class is
1111 * only used to build the UDP Duplex.
1112 *
1113 * @param bind address to bind this socket to.
1114 * @param port number to bind this socket to.
1115 */
1116 UDPTransmit(const IPV4Address &bind, tpport_t port = 5005);
1117#ifdef CCXX_IPV6
1118 UDPTransmit(const IPV6Address &bind, tpport_t port = 5005);
1119#endif
1120
1121 /**
1122 * Associate this socket with a specified peer host. The port
1123 * number from the constructor will be used. All UDP packets
1124 * will be sent to and received from the specified host.
1125 *
1126 * @return 0 on success, -1 on error.
1127 * @param host address to connect socket to.
1128 * @param port to connect socket to.
1129 */
1130 Error connect(const IPV4Host &host, tpport_t port);
1131#ifdef CCXX_IPV6
1132 Error connect(const IPV6Address &host, tpport_t port);
1133#endif
1134
1135 /**
1136 * Associate this socket with a subnet of peer hosts for
1137 * subnet broadcasting. The server must be able to assert
1138 * broadcast permission for the socket.
1139 *
1140 * @return 0 on success, -1 on error.
1141 * @param subnet subnet address to broadcast into.
1142 * @param port transport port to broadcast into.
1143 */
1144 Error connect(const IPV4Broadcast &subnet, tpport_t port);
1145
1146 /**
1147 * Associate this socket with a multicast group.
1148 *
1149 * @return 0 on success, -1 on error.
1150 * @param mgroup address of the multicast group to send to.
1151 * @param port port number
1152 */
1153 Error connect(const IPV4Multicast &mgroup, tpport_t port);
1154#ifdef CCXX_IPV6
1155 Error connect(const IPV6Multicast &mgroup, tpport_t port);
1156#endif
1157
1158 /**
1159 * Transmit "send" to use "connected" send rather than sendto.
1160 *
1161 * @return number of bytes sent.
1162 * @param buf address of buffer to send.
1163 * @param len of bytes to send.
1164 */
1165 inline ssize_t send(const void *buf, size_t len)
1166 {return _IORET64 ::send(so, (const char *)buf, _IOLEN64 len, MSG_NOSIGNAL);}
1167
1168 /**
1169 * Stop transmitter.
1170 */
1171 inline void endTransmitter(void)
1172 {Socket::endSocket();}
1173
1174 /*
1175 * Get transmitter socket.
1176 *
1177 * @return transmitter.
1178 */
1179 inline SOCKET getTransmitter(void)
1180 {return so;};
1181
1182 inline Error setMulticast(bool enable)
1183 {return Socket::setMulticastByFamily(enable, family);}
1184
1185 inline Error setTimeToLive(unsigned char ttl)
1186 {return Socket::setTimeToLiveByFamily(ttl, family);};
1187
1188public:
1189 /**
1190 * Transmit "send" to use "connected" send rather than sendto.
1191 *
1192 * @note Windows does not support MSG_DONTWAIT, so it is defined
1193 * as 0 on that platform.
1194 * @return number of bytes sent.
1195 * @param buffer address of buffer to send.
1196 * @param len of bytes to send.
1197 */
1198 inline ssize_t transmit(const char *buffer, size_t len)
1199 {return _IORET64 ::send(so, buffer, _IOLEN64 len, MSG_DONTWAIT|MSG_NOSIGNAL);}
1200
1201 /**
1202 * See if output queue is empty for sending more packets.
1203 *
1204 * @return true if output available.
1205 * @param timeout in milliseconds to wait.
1206 */
1207 inline bool isOutputReady(unsigned long timeout = 0l)
1208 {return Socket::isPending(Socket::pendingOutput, timeout);};
1209
1210
1211 inline Error setRouting(bool enable)
1212 {return Socket::setRouting(enable);};
1213
1214 inline Error setTypeOfService(Tos tos)
1215 {return Socket::setTypeOfService(tos);};
1216
1217 inline Error setBroadcast(bool enable)
1218 {return Socket::setBroadcast(enable);};
1219};
1220
1221/**
1222 * Representing half of a two-way UDP connection, the UDP receiver
1223 * can receive data from another peer host or subnet. This class is
1224 * used exclusivily to derive the UDPDuplex.
1225 *
1226 * @author David Sugar <dyfet@ostel.com>
1227 * @short Unreliable Datagram Peer Associations.
1228 */
1229class __EXPORT UDPReceive : protected UDPSocket
1230{
1231protected:
1232 /**
1233 * Create a UDP receiver, bind it to a specific interface
1234 * and port address so that other UDP sockets on remote
1235 * machines (or the same host) may find and send UDP messages
1236 * to it, and associate it with a given port on a peer host.
1237 * On failure to bind, an exception is thrown.
1238 *
1239 * @param bind address to bind this socket to.
1240 * @param port number to bind this socket to.
1241 */
1242 UDPReceive(const IPV4Address &bind, tpport_t port);
1243#ifdef CCXX_IPV6
1244 UDPReceive(const IPV6Address &bind, tpport_t port);
1245#endif
1246
1247 /**
1248 * Associate this socket with a specified peer host. The port
1249 * number from the constructor will be used. All UDP packets
1250 * will be sent received from the specified host.
1251 *
1252 * @return 0 on success, -1 on error.
1253 * @param host host network address to connect socket to.
1254 * @param port host transport port to connect socket to.
1255 */
1256 Error connect(const IPV4Host &host, tpport_t port);
1257#ifdef CCXX_IPV6
1258 Error connect(const IPV6Host &host, tpport_t port);
1259#endif
1260
1261 /**
1262 * Check for pending data.
1263 *
1264 * @return true if data is waiting.
1265 * @param timeout in milliseconds.
1266 */
1267 bool isPendingReceive(timeout_t timeout)
1268 {return Socket::isPending(Socket::pendingInput, timeout);};
1269
1270 /**
1271 * End receiver.
1272 */
1273 inline void endReceiver(void)
1274 {Socket::endSocket();}
1275
1276 inline SOCKET getReceiver(void) const
1277 {return so;};
1278
1279 inline Error setRouting(bool enable)
1280 {return Socket::setRouting(enable);}
1281
1282 inline Error setMulticast(bool enable)
1283 {return Socket::setMulticastByFamily(enable, family);}
1284
1285 inline Error join(const IPV4Multicast &ia)
1286 {return Socket::join(ia);}
1287
1288#ifdef CCXX_IPV6
1289 inline Error join(const IPV6Multicast &ia)
1290 {return Socket::join(ia);}
1291#endif
1292
1293 inline Error drop(const IPV4Multicast &ia)
1294 {return Socket::drop(ia);}
1295
1296#ifdef CCXX_IPV6
1297 inline Error drop(const IPV6Multicast &ia)
1298 {return Socket::drop(ia);}
1299#endif
1300
1301public:
1302 /**
1303 * Receive a data packet from the connected peer host.
1304 *
1305 * @return num of bytes actually received.
1306 * @param buf address of data receive buffer.
1307 * @param len size of data receive buffer.
1308 */
1309 inline ssize_t receive(void *buf, size_t len)
1310 {return _IORET64 ::recv(so, (char *)buf, _IOLEN64 len, 0);};
1311
1312 /**
1313 * See if input queue has data packets available.
1314 *
1315 * @return true if data packets available.
1316 * @param timeout in milliseconds.
1317 */
1318 inline bool isInputReady(timeout_t timeout = TIMEOUT_INF)
1319 {return Socket::isPending(Socket::pendingInput, timeout);};
1320};
1321
1322/**
1323 * UDP duplex connections impliment a bi-directional point-to-point UDP
1324 * session between two peer hosts. Two UDP sockets are typically used
1325 * on alternating port addresses to assure that sender and receiver
1326 * data does not collide or echo back. A UDP Duplex is commonly used
1327 * for full duplex real-time streaming of UDP data between hosts.
1328 *
1329 * @author David Sugar <dyfet@ostel.com>
1330 * @short Unreliable Datagram Peer Associations.
1331 */
1332class __EXPORT UDPDuplex : public UDPTransmit, public UDPReceive
1333{
1334public:
1335 /**
1336 * Create a UDP duplex as a pair of UDP simplex objects
1337 * bound to alternating and interconnected port addresses.
1338 *
1339 * @param bind address to bind this socket to.
1340 * @param port number to bind sender.
1341 */
1342 UDPDuplex(const IPV4Address &bind, tpport_t port);
1343#ifdef CCXX_IPV6
1344 UDPDuplex(const IPV6Address &bind, tpport_t port);
1345#endif
1346
1347 /**
1348 * Associate the duplex with a specified peer host. Both
1349 * the sender and receiver will be interconnected with
1350 * the remote host.
1351 *
1352 * @return 0 on success, error code on error.
1353 * @param host address to connect socket to.
1354 * @param port number to connect socket to.
1355 */
1356 Error connect(const IPV4Host &host, tpport_t port);
1357#ifdef CCXX_IPV6
1358 Error connect(const IPV6Host &host, tpport_t port);
1359#endif
1360
1361 /**
1362 * Disassociate this duplex from any host connection. No data
1363 * should be read or written until a connection is established.
1364 *
1365 * @return 0 on success, error code on error.
1366 */
1367 Error disconnect(void);
1368};
1369
1370
1371/**
1372 * TCP sockets are used for stream based connected sessions between two
1373 * sockets. Both error recovery and flow control operate transparently
1374 * for a TCP socket connection. The TCP socket base class is primary used
1375 * to bind a TCP "server" for accepting TCP streams.
1376 *
1377 * An implicit and unique TCPSocket object exists in Common C++ to represent
1378 * a bound TCP socket acting as a "server" for receiving connection requests.
1379 * This class is not part of TCPStream because such objects normally perform
1380 * no physical I/O (read or write operations) other than to specify a listen
1381 * backlog queue and perform "accept" operations for pending connections.
1382 * The Common C++ TCPSocket offers a Peek method to examine where the next
1383 * pending connection is coming from, and a Reject method to flush the next
1384 * request from the queue without having to create a session.
1385 *
1386 * The TCPSocket also supports a "OnAccept" method which can be called when a
1387 * TCPStream related object is created from a TCPSocket. By creating a
1388 * TCPStream from a TCPSocket, an accept operation automatically occurs, and
1389 * the TCPSocket can then still reject the client connection through the
1390 * return status of it's OnAccept method.
1391 *
1392 * @author David Sugar <dyfet@tycho.com>
1393 * @short bound server for TCP streams and sessions.
1394 */
1395class __EXPORT TCPSocket : protected Socket
1396{
1397protected:
1398 int segsize;
1399 void setSegmentSize(unsigned mss);
1400
1401public:
1402 /**
1403 * A method to call in a derived TCPSocket class that is acting
1404 * as a server when a connection request is being accepted. The
1405 * server can implement protocol specific rules to exclude the
1406 * remote socket from being accepted by returning false. The
1407 * Peek method can also be used for this purpose.
1408 *
1409 * @return true if client should be accepted.
1410 * @param ia internet host address of the client.
1411 * @param port number of the client.
1412 */
1413 virtual bool onAccept(const IPV4Host &ia, tpport_t port);
1414
1415 /**
1416 * Fetch out the socket.
1417 */
1418 inline SOCKET getSocket(void)
1419 {return so;};
1420
1421 /**
1422 * Get the buffer size for servers.
1423 */
1424 inline int getSegmentSize(void)
1425 {return segsize;};
1426
1427 /**
1428 * A TCP "server" is created as a TCP socket that is bound
1429 * to a hardware address and port number on the local machine
1430 * and that has a backlog queue to listen for remote connection
1431 * requests. If the server cannot be created, an exception is
1432 * thrown.
1433 *
1434 * @param bind local ip address or interface to use.
1435 * @param port number to bind socket under.
1436 * @param backlog size of connection request queue.
1437 * @param mss maximum segment size for accepted streams.
1438 */
1439 TCPSocket(const IPV4Address &bind, tpport_t port, unsigned backlog = 5, unsigned mss = 536);
1440
1441 /**
1442 * Create a named tcp socket by service and/or interface id.
1443 * For IPV4 we use [host:]svc or [host/]svc for the string.
1444 * If we have getaddrinfo, we use that to obtain the addr to
1445 * bind for.
1446 *
1447 * @param name of host interface and service port to bind.
1448 * @param backlog size of connection request queue.
1449 * @param mss maximum segment size for streaming buffers.
1450 */
1451 TCPSocket(const char *name, unsigned backlog = 5, unsigned mss = 536);
1452
1453 /**
1454 * Return address and port of next connection request. This
1455 * can be used instead of OnAccept() to pre-evaluate connection
1456 * requests.
1457 *
1458 * @return host requesting a connection.
1459 * @param port number of requestor.
1460 */
1461 inline IPV4Host getRequest(tpport_t *port = NULL) const
1462 {return Socket::getIPV4Sender(port);}
1463
1464 /**
1465 * Used to reject the next incoming connection request.
1466 */
1467 void reject(void);
1468
1469 /**
1470 * Used to get local bound address.
1471 */
1472 inline IPV4Host getLocal(tpport_t *port = NULL) const
1473 {return Socket::getIPV4Local(port);}
1474
1475 /**
1476 * Used to wait for pending connection requests.
1477 * @return true if data packets available.
1478 * @param timeout in milliseconds. TIMEOUT_INF if not specified.
1479 */
1480 inline bool isPendingConnection(timeout_t timeout = TIMEOUT_INF) /* not const -- jfc */
1481 {return Socket::isPending(Socket::pendingInput, timeout);}
1482
1483 /**
1484 * Use base socket handler for ending this socket.
1485 */
1486 virtual ~TCPSocket();
1487};
1488
1489#ifdef CCXX_IPV6
1490/**
1491 * TCPV6 sockets are used for stream based connected sessions between two
1492 * ipv6 sockets. Both error recovery and flow control operate transparently
1493 * for a TCP socket connection. The TCP socket base class is primary used
1494 * to bind a TCP "server" for accepting TCP streams.
1495 *
1496 * An implicit and unique TCPV6Socket object exists in Common C++ to represent
1497 * a bound ipv6 TCP socket acting as a "server" for receiving connection requests.
1498 * This class is not part of TCPStream because such objects normally perform
1499 * no physical I/O (read or write operations) other than to specify a listen
1500 * backlog queue and perform "accept" operations for pending connections.
1501 * The Common C++ TCPV6Socket offers a Peek method to examine where the next
1502 * pending connection is coming from, and a Reject method to flush the next
1503 * request from the queue without having to create a session.
1504 *
1505 * The TCPV6Socket also supports a "OnAccept" method which can be called when a
1506 * TCPStream related object is created from a TCPSocket. By creating a
1507 * TCPStream from a TCPV6Socket, an accept operation automatically occurs, and
1508 * the TCPV6Socket can then still reject the client connection through the
1509 * return status of it's OnAccept method.
1510 *
1511 * @author David Sugar <dyfet@tycho.com>
1512 * @short bound server for TCP streams and sessions.
1513 */
1514class __EXPORT TCPV6Socket : protected Socket
1515{
1516private:
1517 int segsize;
1518 void setSegmentSize(unsigned mss);
1519
1520public:
1521 /**
1522 * A method to call in a derived TCPSocket class that is acting
1523 * as a server when a connection request is being accepted. The
1524 * server can implement protocol specific rules to exclude the
1525 * remote socket from being accepted by returning false. The
1526 * Peek method can also be used for this purpose.
1527 *
1528 * @return true if client should be accepted.
1529 * @param ia internet host address of the client.
1530 * @param port number of the client.
1531 */
1532 virtual bool onAccept(const IPV6Host &ia, tpport_t port);
1533
1534 /**
1535 * Fetch out the socket.
1536 */
1537 inline SOCKET getSocket(void)
1538 {return so;};
1539
1540 inline int getSegmentSize(void)
1541 {return segsize;};
1542
1543 /**
1544 * A TCP "server" is created as a TCP socket that is bound
1545 * to a hardware address and port number on the local machine
1546 * and that has a backlog queue to listen for remote connection
1547 * requests. If the server cannot be created, an exception is
1548 * thrown.
1549 *
1550 * @param bind local ip address or interface to use.
1551 * @param port number to bind socket under.
1552 * @param backlog size of connection request queue.
1553 * @param mss maximum segment size of streaming buffer.
1554 */
1555 TCPV6Socket(const IPV6Address &bind, tpport_t port, unsigned backlog = 5, unsigned mss = 536);
1556
1557 /**
1558 * Create a TCP server for a named host interface and service
1559 * port. We use [host/]port for specifying the optional host
1560 * name and service port since ':' is a valid char for ipv6
1561 * addresses.
1562 *
1563 * @param name of host interface and service to use.
1564 * @param backlog size of connection request queue.
1565 * @param mss maximum segment size of streaming buffers.
1566 */
1567 TCPV6Socket(const char *name, unsigned backlog = 5, unsigned mss = 536);
1568
1569 /**
1570 * Return address and port of next connection request. This
1571 * can be used instead of OnAccept() to pre-evaluate connection
1572 * requests.
1573 *
1574 * @return host requesting a connection.
1575 * @param port number of requestor.
1576 */
1577 inline IPV6Host getRequest(tpport_t *port = NULL) const
1578 {return Socket::getIPV6Sender(port);}
1579
1580 /**
1581 * Used to reject the next incoming connection request.
1582 */
1583 void reject(void);
1584
1585 /**
1586 * Used to get local bound address.
1587 */
1588 inline IPV6Host getLocal(tpport_t *port = NULL) const
1589 {return Socket::getIPV6Local(port);}
1590
1591 /**
1592 * Used to wait for pending connection requests.
1593 * @return true if data packets available.
1594 * @param timeout in milliseconds. TIMEOUT_INF if not specified.
1595 */
1596 inline bool isPendingConnection(timeout_t timeout = TIMEOUT_INF) /* not const -- jfc */
1597 {return Socket::isPending(Socket::pendingInput, timeout);}
1598
1599 /**
1600 * Use base socket handler for ending this socket.
1601 */
1602 virtual ~TCPV6Socket();
1603};
1604
1605#endif
1606
1607/*
1608:\projects\libraries\cplusplus\commonc++\win32\socket.h(357) : warning C4275: non dll-interface class 'streambuf' used as base for dll-interface class 'TCPStream'
1609 c:\program files\microsoft visual studio\vc98\include\streamb.h(69) : see declaration of 'streambuf'
1610c:\projects\libraries\cplusplus\commonc++\win32\socket.h(358) : warning C4275: non dll-interface class 'iostream' used as base for dll-interface class 'TCPStream'
1611 c:\program files\microsoft visual studio\vc98\include\iostream.h(66) : see declaration of 'iostream'
1612*/
1613
1614#ifdef _MSC_VER
1615#pragma warning(disable:4275) // disable C4275 warning
1616#endif
1617
1618/**
1619 * TCP streams are used to represent TCP client connections to a server
1620 * by TCP protocol servers for accepting client connections. The TCP
1621 * stream is a C++ "stream" class, and can accept streaming of data to
1622 * and from other C++ objects using the << and >> operators.
1623 *
1624 * TCPStream itself can be formed either by connecting to a bound network
1625 * address of a TCP server, or can be created when "accepting" a
1626 * network connection from a TCP server.
1627 *
1628 * @author David Sugar <dyfet@ostel.com>
1629 * @short streamable TCP socket connection.
1630 */
1631class __EXPORT TCPStream : protected std::streambuf, public Socket, public std::iostream
1632{
1633private:
1634 int doallocate();
1635
1636 void segmentBuffering(unsigned mss);
1637
1638 friend TCPStream& crlf(TCPStream&);
1639 friend TCPStream& lfcr(TCPStream&);
1640
1641protected:
1642 timeout_t timeout;
1643 size_t bufsize;
1644 Family family;
1645 char *gbuf, *pbuf;
1646
1647public:
1648 /**
1649 * The constructor required for building other classes or to
1650 * start an unconnected TCPStream for connect.
1651 */
1652 TCPStream(Family family = IPV4, bool throwflag = true, timeout_t to = 0);
1653
1654 /**
1655 * Disconnect the current session and prepare for a new one.
1656 */
1657 void disconnect(void);
1658
1659 /**
1660 * Get protocol segment size.
1661 */
1662 int getSegmentSize(void);
1663
1664protected:
1665 /**
1666 * Used to allocate the buffer space needed for iostream
1667 * operations. This function is called by the constructor.
1668 *
1669 * @param size of stream buffers from constructor.
1670 */
1671 void allocate(size_t size);
1672
1673 /**
1674 * Used to terminate the buffer space and cleanup the socket
1675 * connection. This fucntion is called by the destructor.
1676 */
1677 void endStream(void);
1678
1679 /**
1680 * This streambuf method is used to load the input buffer
1681 * through the established tcp socket connection.
1682 *
1683 * @return char from get buffer, EOF if not connected.
1684 */
1685 int underflow();
1686
1687 /**
1688 * This streambuf method is used for doing unbuffered reads
1689 * through the establish tcp socket connection when in interactive mode.
1690 * Also this method will handle proper use of buffers if not in
1691 * interative mode.
1692 *
1693 * @return char from tcp socket connection, EOF if not connected.
1694 */
1695 int uflow();
1696
1697 /**
1698 * This streambuf method is used to write the output
1699 * buffer through the established tcp connection.
1700 *
1701 * @param ch char to push through.
1702 * @return char pushed through.
1703 */
1704 int overflow(int ch);
1705
1706 /**
1707 * Create a TCP stream by connecting to a TCP socket (on
1708 * a remote machine).
1709 *
1710 * @param host address of remote TCP server.
1711 * @param port number to connect.
1712 * @param mss maximum segment size of streaming buffers.
1713 */
1714 void connect(const IPV4Host &host, tpport_t port, unsigned mss = 536);
1715#ifdef CCXX_IPV6
1716 void connect(const IPV6Host &host, tpport_t port, unsigned mss = 536);
1717#endif
1718
1719 /**
1720 * Connect a TCP stream to a named destination host and port
1721 * number, using getaddrinfo interface if available.
1722 *
1723 * @param name of host and service to connect
1724 * @param mss maximum segment size of stream buffer
1725 */
1726 void connect(const char *name, unsigned mss = 536);
1727
1728 /**
1729 * Used in derived classes to refer to the current object via
1730 * it's iostream. For example, to send a set of characters
1731 * in a derived method, one might use *tcp() << "test".
1732 *
1733 * @return stream pointer of this object.
1734 */
1735 std::iostream *tcp(void)
1736 {return ((std::iostream *)this);};
1737
1738public:
1739 /**
1740 * Create a TCP stream by accepting a connection from a bound
1741 * TCP socket acting as a server. This performs an "accept"
1742 * call.
1743 *
1744 * @param server socket listening
1745 * @param throwflag flag to throw errors.
1746 * @param timeout for all operations.
1747 */
1748 TCPStream(TCPSocket &server, bool throwflag = true, timeout_t timeout = 0);
1749#ifdef CCXX_IPV6
1750 TCPStream(TCPV6Socket &server, bool throwflag = true, timeout_t timeout = 0);
1751#endif
1752
1753 /**
1754 * Accept a connection from a TCP Server.
1755 *
1756 * @param server socket listening
1757 */
1758 void connect(TCPSocket &server);
1759#ifdef CCXX_IPV6
1760 void connect(TCPV6Socket &server);
1761#endif
1762
1763 /**
1764 * Create a TCP stream by connecting to a TCP socket (on
1765 * a remote machine).
1766 *
1767 * @param host address of remote TCP server.
1768 * @param port number to connect.
1769 * @param mss maximum segment size of streaming buffers.
1770 * @param throwflag flag to throw errors.
1771 * @param timeout for all operations.
1772 */
1773 TCPStream(const IPV4Host &host, tpport_t port, unsigned mss = 536, bool throwflag = true, timeout_t timeout = 0);
1774#ifdef CCXX_IPV6
1775 TCPStream(const IPV6Host &host, tpport_t port, unsigned mss = 536, bool throwflag = true, timeout_t timeout = 0);
1776#endif
1777
1778 /**
1779 * Construct a named TCP Socket connected to a remote machine.
1780 *
1781 * @param name of remote service.
1782 * @param family of protocol.
1783 * @param mss maximum segment size of streaming buffers.
1784 * @param throwflag flag to throw errors.
1785 * @param timer for timeout for all operations.
1786 */
1787 TCPStream(const char *name, Family family = IPV4, unsigned mss = 536, bool throwflag = false, timeout_t timer = 0);
1788
1789 /**
1790 * Set the I/O operation timeout for socket I/O operations.
1791 *
1792 * @param timer to change timeout.
1793 */
1794 inline void setTimeout(timeout_t timer)
1795 {timeout = timer;};
1796
1797 /**
1798 * A copy constructor creates a new stream buffer.
1799 *
1800 * @param source reference of stream to copy from.
1801 *
1802 */
1803 TCPStream(const TCPStream &source);
1804
1805 /**
1806 * Flush and empty all buffers, and then remove the allocated
1807 * buffers.
1808 */
1809 virtual ~TCPStream();
1810
1811 /**
1812 * Flushes the stream input and output buffers, writes
1813 * pending output.
1814 *
1815 * @return 0 on success.
1816 */
1817 int sync(void);
1818
1819#ifdef HAVE_SNPRINTF
1820 /**
1821 * Print content into a socket.
1822 *
1823 * @return count of bytes sent.
1824 * @param format string
1825 */
1826 size_t printf(const char *format, ...);
1827#endif
1828
1829 /**
1830 * Get the status of pending stream data. This can be used to
1831 * examine if input or output is waiting, or if an error or
1832 * disconnect has occured on the stream. If a read buffer
1833 * contains data then input is ready and if write buffer
1834 * contains data it is first flushed and then checked.
1835 */
1836 bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
1837
1838 /**
1839 * Examine contents of next waiting packet.
1840 *
1841 * @param buf pointer to packet buffer for contents.
1842 * @param len of packet buffer.
1843 * @return number of bytes examined.
1844 */
1845 inline ssize_t peek(void *buf, size_t len)
1846 {return _IORET64 ::recv(so, (char *)buf, _IOLEN64 len, MSG_PEEK);};
1847
1848 /**
1849 * Return the size of the current stream buffering used.
1850 *
1851 * @return size of stream buffers.
1852 */
1853 inline size_t getBufferSize(void) const
1854 {return bufsize;};
1855};
1856
1857/**
1858 * The TCP session is used to primarily to represent a client connection
1859 * that can be managed on a seperate thread. The TCP session also supports
1860 * a non-blocking connection scheme which prevents blocking during the
1861 * constructor and moving the process of completing a connection into the
1862 * thread that executes for the session.
1863 *
1864 * @author David Sugar <dyfet@ostel.com>
1865 * @short Threaded streamable socket with non-blocking constructor.
1866 */
1867class __EXPORT TCPSession : public Thread, public TCPStream
1868{
1869private:
1870 TCPSession(const TCPSession &rhs); // not defined
1871protected:
1872 /**
1873 * Normally called during the thread Initial() method by default,
1874 * this will wait for the socket connection to complete when
1875 * connecting to a remote socket. One might wish to use
1876 * setCompletion() to change the socket back to blocking I/O
1877 * calls after the connection completes. To implement the
1878 * session one must create a derived class which implements
1879 * run().
1880 *
1881 * @return 0 if successful, -1 if timed out.
1882 * @param timeout to wait for completion in milliseconds.
1883 */
1884 int waitConnection(timeout_t timeout = TIMEOUT_INF);
1885
1886 /**
1887 * The initial method is used to esablish a connection when
1888 * delayed completion is used. This assures the constructor
1889 * terminates without having to wait for a connection request
1890 * to complete.
1891 */
1892 void initial(void);
1893
1894public:
1895 /**
1896 * Create a TCP socket that will be connected to a remote TCP
1897 * server and that will execute under it's own thread.
1898 *
1899 * @param host internet address of remote TCP server.
1900 * @param port number of remote server.
1901 * @param size of streaming buffer.
1902 * @param pri execution priority relative to parent.
1903 * @param stack allocation needed on some platforms.
1904 */
1905 TCPSession(const IPV4Host &host,
1906 tpport_t port, size_t size = 536, int pri = 0, size_t stack = 0);
1907#ifdef CCXX_IPV6
1908 TCPSession(const IPV6Host &host,
1909 tpport_t port, size_t size = 536, int pri = 0, size_t stack = 0);
1910#endif
1911
1912 /**
1913 * Create a TCP socket from a bound TCP server by accepting a pending
1914 * connection from that server and execute a thread for the accepted
1915 * connection.
1916 *
1917 * @param server tcp socket to accept a connection from.
1918 * @param pri execution priority relative to parent.
1919 * @param stack allocation needed on some platforms.
1920 */
1921 TCPSession(TCPSocket &server, int pri = 0, size_t stack = 0);
1922#ifdef CCXX_IPV6
1923 TCPSession(TCPV6Socket &server, int pri = 0, size_t stack = 0);
1924#endif
1925
1926 /**
1927 * Make sure destruction happens through a virtual...
1928 */
1929 virtual ~TCPSession();
1930};
1931
1932#if defined(WIN32)
1933
1934/**
1935 * class init_WSA used to initalise windows sockets specfifc stuff : there is
1936 * an MS - specific init sequence for Winsock 2 this class attempts to
1937 * initalise Winsock 2.2 - needed for non - blocking I/O. It will fall back
1938 * on 1.2 or lower if 2.0 or higher is not available, but < 2.0 does not
1939 * support non - blocking I/o
1940 * TO DO : might be an idea to have a method that reports version of
1941 * Winsock in use or a predicate to test if non - blocking is OK -- JFC
1942 */
1943class init_WSA
1944{
1945public:
1946 init_WSA();
1947 ~init_WSA();
1948};
1949
1950#endif // WIN32
1951
1952class __EXPORT SimpleTCPStream;
1953
1954/**
1955 * @class SimpleTCPStream
1956 * @brief Simple TCP Stream, to be used with Common C++ Library
1957 *
1958 * This source is derived from a proposal made by Ville Vainio
1959 * (vvainio@tp.spt.fi).
1960 *
1961 * @author Mark S. Millard (msm@wizzer.com)
1962 * @date 2002-08-15
1963 * Copyright (C) 2002 Wizzer Works.
1964 **/
1965class __EXPORT SimpleTCPStream : public Socket
1966{
1967private:
1968
1969 IPV4Host getSender(tpport_t *port) const;
1970
1971protected:
1972 /**
1973 * The constructor required for "SimpleTCPStream", a more C++ style
1974 * version of the SimpleTCPStream class.
1975 */
1976 SimpleTCPStream();
1977
1978 /**
1979 * Used to terminate the buffer space and cleanup the socket
1980 * connection. This fucntion is called by the destructor.
1981 */
1982 void endStream(void);
1983
1984 /**
1985 * Create a TCP stream by connecting to a TCP socket (on
1986 * a remote machine).
1987 *
1988 * @param host address of remote TCP server.
1989 * @param port number to connect.
1990 * @param size of streaming input and output buffers.
1991 */
1992 void Connect(const IPV4Host &host, tpport_t port, size_t size);
1993
1994
1995public:
1996 /**
1997 * Create a TCP stream by accepting a connection from a bound
1998 * TCP socket acting as a server. This performs an "accept"
1999 * call.
2000 *
2001 * @param server bound server tcp socket.
2002 * @param size of streaming input and output buffers.
2003 */
2004 SimpleTCPStream(TCPSocket &server, size_t size = 512);
2005
2006 /**
2007 * Create a TCP stream by connecting to a TCP socket (on
2008 * a remote machine).
2009 *
2010 * @param host address of remote TCP server.
2011 * @param port number to connect.
2012 * @param size of streaming input and output buffers.
2013 */
2014 SimpleTCPStream(const IPV4Host &host, tpport_t port, size_t size = 512);
2015
2016 /**
2017 * A copy constructor creates a new stream buffer.
2018 *
2019 * @param source A reference to the SimpleTCPStream to copy.
2020 */
2021 SimpleTCPStream(const SimpleTCPStream &source);
2022
2023 /**
2024 * Flush and empty all buffers, and then remove the allocated
2025 * buffers.
2026 */
2027 virtual ~SimpleTCPStream();
2028
2029 /**
2030 * @brief Get the status of pending stream data.
2031 *
2032 * This method can be used to examine if input or output is waiting,
2033 * or if an error or disconnect has occured on the stream.
2034 * If a read buffer contains data then input is ready. If write buffer
2035 * contains data, it is first flushed and then checked.
2036 *
2037 * @param pend Flag indicating means to pend.
2038 * @param timeout The length of time to wait.
2039 */
2040 bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
2041
2042 void flush() {}
2043
2044 /**
2045 * @brief Read bytes into a buffer.
2046 *
2047 * <long-description>
2048 *
2049 * @param bytes A pointer to buffer that will contain the bytes read.
2050 * @param length The number of bytes to read (exactly).
2051 * @param timeout Period to time out, in milleseconds.
2052 *
2053 * @return The number of bytes actually read, 0 on EOF.
2054 */
2055 ssize_t read(char *bytes, size_t length, timeout_t timeout = 0);
2056
2057 /**
2058 * @brief Write bytes to buffer
2059 *
2060 * <long-description>
2061 *
2062 * @param bytes A pointer to a buffer containing the bytes to write.
2063 * @param length The number of bytes to write (exactly).
2064 * @param timeout Period to time out, in milleseconds.
2065 *
2066 * @return The number of bytes actually written.
2067 */
2068 ssize_t write(const char *bytes, size_t length, timeout_t timeout = 0);
2069
2070 /**
2071 * @brief Peek at the incoming data.
2072 *
2073 * The data is copied into the buffer
2074 * but is not removed from the input queue. The function then returns
2075 * the number of bytes currently pending to receive.
2076 *
2077 * @param bytes A pointer to buffer that will contain the bytes read.
2078 * @param length The number of bytes to read (exactly).
2079 * @param timeout Period to time out, in milleseconds.
2080 *
2081 * @return The number of bytes pending on the input queue, 0 on EOF.
2082 */
2083 ssize_t peek(char *bytes, size_t length, timeout_t timeout = 0);
2084
2085};
2086
2087#ifdef COMMON_STD_EXCEPTION
2088class __EXPORT SockException : public IOException
2089{
2090private:
2091 Socket::Error _socketError;
2092
2093public:
2094 SockException(const String &str, Socket::Error socketError, long systemError = 0) :
2095 IOException(str, systemError), _socketError(socketError) {};
2096
2097 inline Socket::Error getSocketError() const
2098 { return _socketError; }
2099};
2100#endif
2101
2102#ifdef CCXX_NAMESPACES
2103}
2104#endif
2105
2106#endif
2107/** EMACS **
2108 * Local variables:
2109 * mode: c++
2110 * c-basic-offset: 4
2111 * End:
2112 */