OPAL Version 3.10.4

- Main Page
- Related Pages
- Namespaces
- Data Structures
- Files

- File List
- Globals

transports.h
Go to the documentation of this file.
1 /*
2 * transport.h
3 *
4 * Transport declarations
5 *
6 * Open Phone Abstraction Library (OPAL)
7 * Formally known as the Open H323 project.
8 *
9 * Copyright (c) 2001 Equivalence Pty. Ltd.
10 * Portions Copyright (C) 2006 by Post Increment
11 *
12 * The contents of this file are subject to the Mozilla Public License
13 * Version 1.0 (the "License"); you may not use this file except in
14 * compliance with the License. You may obtain a copy of the License at
15 * http://www.mozilla.org/MPL/
16 *
17 * Software distributed under the License is distributed on an "AS IS"
18 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
19 * the License for the specific language governing rights and limitations
20 * under the License.
21 *
22 * The Original Code is Open Phone Abstraction Library.
23 *
24 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
25 *
26 * Contributor(s): Post Increment
27 * Portions of this code were written with the assistance of funding from
28 * US Joint Forces Command Joint Concept Development & Experimentation (J9)
29 * http://www.jfcom.mil/about/abt_j9.htm
30 *
31 * $Revision: 26231 $
32 * $Author: rjongbloed $
33 * $Date: 2011-07-19 21:23:34 -0500 (Tue, 19 Jul 2011) $
34 */
35
36 #ifndef OPAL_OPAL_TRANSPORT_H
37 #define OPAL_OPAL_TRANSPORT_H
38
39 #ifdef P_USE_PRAGMA
40 #pragma interface
41 #endif
42
43 #include <opal/buildopts.h>
44
45 #include <ptlib/sockets.h>
46 #include <ptclib/psockbun.h>
47
48
49 class OpalManager;
50 class OpalEndPoint;
51 class OpalListener;
52 class OpalTransport;
53 class OpalInternalTransport;
54
55
57
149 class OpalTransportAddress : public PCaselessString
150 {
151 PCLASSINFO(OpalTransportAddress, PCaselessString);
152 public:
155 OpalTransportAddress();
156 OpalTransportAddress(
157 const char * address,
158 WORD port = 0,
159 const char * proto = NULL
160 );
161 OpalTransportAddress(
162 const PString & address,
163 WORD port = 0,
164 const char * proto = NULL
165 );
166 OpalTransportAddress(
167 const PIPSocket::Address & ip,
168 WORD port,
169 const char * proto = NULL
170 );
172
180 PBoolean IsEquivalent(
181 const OpalTransportAddress & address,
182 bool wildcards = false
183 ) const;
184
187 PBoolean IsCompatible(
188 const OpalTransportAddress & address
189 ) const;
190
193 PCaselessString GetProto(bool withDollar = false) const { return Left(Find('$')+(withDollar?1:0)); }
194
198 PBoolean GetIpAddress(PIPSocket::Address & ip) const;
199
203 PBoolean GetIpAndPort(PIPSocket::Address & ip, WORD & port) const;
204 PBoolean GetIpAndPort(PIPSocketAddressAndPort & ipPort) const;
205
209 virtual PString GetHostName() const;
210
211 enum BindOptions {
212 NoBinding,
213 HostOnly,
214 FullTSAP,
215 Streamed,
216 Datagram,
217 RouteInterface,
218 NumBindOptions
219 };
220
252 OpalListener * CreateListener(
253 OpalEndPoint & endpoint,
254 BindOptions option
255 ) const;
256
284 virtual OpalTransport * CreateTransport(
285 OpalEndPoint & endpoint,
286 BindOptions option = HostOnly
287 ) const;
289
290
291 protected:
292 void SetInternalTransport(
293 WORD port,
294 const char * proto
295 );
296
297 OpalInternalTransport * transport;
298 };
299
300
301 PDECLARE_ARRAY(OpalTransportAddressArray, OpalTransportAddress)
302 public:
303 OpalTransportAddressArray(
304 const OpalTransportAddress & address
305 ) { AppendAddress(address); }
306 OpalTransportAddressArray(
307 const PStringArray & array
308 ) { AppendStringCollection(array); }
309 OpalTransportAddressArray(
310 const PStringList & list
311 ) { AppendStringCollection(list); }
312 OpalTransportAddressArray(
313 const PSortedStringList & list
314 ) { AppendStringCollection(list); }
315
316 void AppendString(
317 const char * address
318 );
319 void AppendString(
320 const PString & address
321 );
322 void AppendAddress(
323 const OpalTransportAddress & address
324 );
325
326 protected:
327 void AppendStringCollection(
328 const PCollection & coll
329 );
330 };
331
332
333
334
336
349 class OpalListener : public PObject
350 {
351 PCLASSINFO(OpalListener, PObject);
352 public:
357 OpalListener(
358 OpalEndPoint & endpoint
359 );
361
366 void PrintOn(
367 ostream & strm
368 ) const;
370
373 enum ThreadMode {
374 SpawnNewThreadMode,
375 HandOffThreadMode,
376 SingleThreadMode
377 };
378
393 virtual PBoolean Open(
394 const PNotifier & acceptHandler,
395 ThreadMode mode = SpawnNewThreadMode
396 ) = 0;
397
400 virtual PBoolean IsOpen() = 0;
401
404 virtual void Close() = 0;
405
408 virtual OpalTransport * Accept(
409 const PTimeInterval & timeout
410 ) = 0;
411
414 virtual OpalTransport * CreateTransport(
415 const OpalTransportAddress & localAddress,
416 const OpalTransportAddress & remoteAddress
417 ) const = 0;
418
424 virtual OpalTransportAddress GetLocalAddress(
425 const OpalTransportAddress & remoteAddress = OpalTransportAddress()
426 ) const = 0;
427
430 void CloseWait();
431
435 void CleanUpOnTermination() { CloseWait(); }
437
438
439 protected:
448 PDECLARE_NOTIFIER(PThread, OpalListener, ListenForConnections);
449 PBoolean StartThread(
450 const PNotifier & acceptHandler,
451 ThreadMode mode
452 );
453
454 OpalEndPoint & endpoint;
455 PThread * thread;
456 PNotifier acceptHandler;
457 ThreadMode threadMode;
458 };
459
460
461 PLIST(OpalListenerList, OpalListener);
462
463
464 class OpalListenerIP : public OpalListener
465 {
466 PCLASSINFO(OpalListenerIP, OpalListener);
467 public:
472 OpalListenerIP(
473 OpalEndPoint & endpoint,
474 PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(),
475 WORD port = 0,
476 PBoolean exclusive = true
477 );
478 OpalListenerIP(
479 OpalEndPoint & endpoint,
480 const OpalTransportAddress & binding,
481 OpalTransportAddress::BindOptions option
482 );
484
492 virtual OpalTransportAddress GetLocalAddress(
493 const OpalTransportAddress & remoteAddress = OpalTransportAddress()
494 ) const;
496
499 WORD GetListenerPort() const { return listenerPort; }
500
501 virtual const char * GetProtoPrefix() const = 0;
503
504
505 protected:
506 PIPSocket::Address localAddress;
507 WORD listenerPort;
508 PBoolean exclusiveListener;
509 };
510
511
512 class OpalListenerTCP : public OpalListenerIP
513 {
514 PCLASSINFO(OpalListenerTCP, OpalListenerIP);
515 public:
520 OpalListenerTCP(
521 OpalEndPoint & endpoint,
522 PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(),
523 WORD port = 0,
524 PBoolean exclusive = true
525 );
526 OpalListenerTCP(
527 OpalEndPoint & endpoint,
528 const OpalTransportAddress & binding,
529 OpalTransportAddress::BindOptions option
530 );
531
534 ~OpalListenerTCP();
536
559 virtual PBoolean Open(
560 const PNotifier & acceptHandler,
561 ThreadMode mode = SpawnNewThreadMode
562 );
563
566 virtual PBoolean IsOpen();
567
570 virtual void Close();
571
574 virtual OpalTransport * Accept(
575 const PTimeInterval & timeout
576 );
577
580 virtual OpalTransport * CreateTransport(
581 const OpalTransportAddress & localAddress,
582 const OpalTransportAddress & remoteAddress
583 ) const;
585
586
587 protected:
588 virtual const char * GetProtoPrefix() const;
589
590 PTCPSocket listener;
591 };
592
593
594 class OpalListenerUDP : public OpalListenerIP
595 {
596 PCLASSINFO(OpalListenerUDP, OpalListenerIP);
597 public:
602 OpalListenerUDP(
603 OpalEndPoint & endpoint,
604 PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(),
605 WORD port = 0,
606 PBoolean exclusive = true
607 );
608 OpalListenerUDP(
609 OpalEndPoint & endpoint,
610 const OpalTransportAddress & binding,
611 OpalTransportAddress::BindOptions option
612 );
613
616 ~OpalListenerUDP();
618
641 virtual PBoolean Open(
642 const PNotifier & acceptHandler,
643 ThreadMode mode = SpawnNewThreadMode
644 );
645
648 virtual PBoolean IsOpen();
649
652 virtual void Close();
653
656 virtual OpalTransport * Accept(
657 const PTimeInterval & timeout
658 );
659
662 virtual OpalTransport * CreateTransport(
663 const OpalTransportAddress & localAddress,
664 const OpalTransportAddress & remoteAddress
665 ) const;
666
672 virtual OpalTransportAddress GetLocalAddress(
673 const OpalTransportAddress & remoteAddress = OpalTransportAddress()
674 ) const;
676
681 void SetBufferSize(
682 PINDEX size
683 ) { m_bufferSize = size; }
685
686
687 protected:
688 virtual const char * GetProtoPrefix() const;
689
690 PMonitoredSocketsPtr listenerBundle;
691 PINDEX m_bufferSize;
692 };
693
694
696
701 class OpalTransport : public PIndirectChannel
702 {
703 PCLASSINFO(OpalTransport, PIndirectChannel);
704 public:
709 OpalTransport(OpalEndPoint & endpoint);
710
713 ~OpalTransport();
715
720 void PrintOn(
721 ostream & strm
722 ) const;
724
729 virtual PBoolean IsReliable() const = 0;
730
737 virtual PString GetInterface() const;
738
745 virtual bool SetInterface(
746 const PString & iface
747 );
748
751 virtual OpalTransportAddress GetLocalAddress(
752 bool allowNAT = true
753 ) const = 0;
754
759 virtual PBoolean SetLocalAddress(
760 const OpalTransportAddress & address
761 ) = 0;
762
765 virtual OpalTransportAddress GetRemoteAddress() const = 0;
766
772 virtual PBoolean SetRemoteAddress(
773 const OpalTransportAddress & address
774 ) = 0;
775
778 virtual PBoolean Connect() = 0;
779
782 PBoolean ConnectTo(
783 const OpalTransportAddress & address
784 ) { return SetRemoteAddress(address) && Connect(); }
785
788 virtual PBoolean Close();
789
792 void CloseWait();
793
797 void CleanUpOnTermination() { CloseWait(); }
798
801 virtual PBoolean IsCompatibleTransport(
802 const OpalTransportAddress & address
803 ) const = 0;
804
806 enum PromisciousModes {
807 AcceptFromRemoteOnly,
808 AcceptFromAnyAutoSet,
809 AcceptFromAny,
810 NumPromisciousModes
811 };
812
823 virtual void SetPromiscuous(
824 PromisciousModes promiscuous
825 );
826
831 virtual OpalTransportAddress GetLastReceivedAddress() const;
832
837 virtual PString GetLastReceivedInterface() const;
838
848 virtual PBoolean ReadPDU(
849 PBYTEArray & packet
850 ) = 0;
851
857 virtual PBoolean WritePDU(
858 const PBYTEArray & pdu
859 ) = 0;
860
861 typedef PBoolean (*WriteConnectCallback)(OpalTransport & transport, void * userData);
862
875 virtual PBoolean WriteConnect(
876 WriteConnectCallback function,
877 void * userData
878 );
879
882 virtual void AttachThread(
883 PThread * thread
884 );
885
888 virtual PBoolean IsRunning() const;
890
891 OpalEndPoint & GetEndPoint() const { return endpoint; }
892
895 virtual const char * GetProtoPrefix() const = 0;
896
897 PMutex & GetWriteMutex() { return m_writeMutex; }
898
899 protected:
900 OpalEndPoint & endpoint;
901 PThread * thread;
902 PMutex m_writeMutex;
903 };
904
905
906 class OpalTransportIP : public OpalTransport
907 {
908 PCLASSINFO(OpalTransportIP, OpalTransport);
909 public:
914 OpalTransportIP(
915 OpalEndPoint & endpoint,
916 PIPSocket::Address binding,
917 WORD port
918 );
920
925 virtual OpalTransportAddress GetLocalAddress(
926 bool allowNAT = true
927 ) const;
928
933 virtual PBoolean SetLocalAddress(
934 const OpalTransportAddress & address
935 );
936
939 virtual OpalTransportAddress GetRemoteAddress() const;
940
946 virtual PBoolean SetRemoteAddress(
947 const OpalTransportAddress & address
948 );
949
951
952 protected:
955 virtual const char * GetProtoPrefix() const = 0;
956
957 PIPSocket::Address localAddress; // Address of the local interface
958 WORD localPort;
959 PIPSocket::Address remoteAddress; // Address of the remote host
960 WORD remotePort;
961 };
962
963
964 class OpalTransportTCP : public OpalTransportIP
965 {
966 PCLASSINFO(OpalTransportTCP, OpalTransportIP);
967 public:
972 OpalTransportTCP(
973 OpalEndPoint & endpoint,
974 PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(),
975 WORD port = 0,
976 PBoolean reuseAddr = false
977 );
978 OpalTransportTCP(
979 OpalEndPoint & endpoint,
980 PTCPSocket * socket
981 );
982
984 ~OpalTransportTCP();
986
991 virtual PBoolean IsReliable() const;
992
995 virtual PBoolean IsCompatibleTransport(
996 const OpalTransportAddress & address
997 ) const;
998
1001 virtual PBoolean Connect();
1002
1012 virtual PBoolean ReadPDU(
1013 PBYTEArray & pdu
1014 );
1015
1021 virtual PBoolean WritePDU(
1022 const PBYTEArray & pdu
1023 );
1025
1026
1027 protected:
1030 virtual const char * GetProtoPrefix() const;
1031
1041 virtual PBoolean OnOpen();
1042
1043
1044 PBoolean reuseAddressFlag;
1045 };
1046
1047
1048 class OpalTransportUDP : public OpalTransportIP
1049 {
1050 PCLASSINFO(OpalTransportUDP, OpalTransportIP);
1051 public:
1056 OpalTransportUDP(
1057 OpalEndPoint & endpoint,
1058 PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(),
1059 WORD port = 0,
1060 bool reuseAddr = false,
1061 bool preOpen = false
1062 );
1063
1066 OpalTransportUDP(
1067 OpalEndPoint & endpoint,
1068 const PMonitoredSocketsPtr & sockets,
1069 const PString & iface
1070 );
1071
1073 ~OpalTransportUDP();
1075
1078 virtual PBoolean Read(
1079 void * buffer,
1080 PINDEX length
1081 );
1083
1088 virtual PBoolean IsReliable() const;
1089
1092 virtual PBoolean IsCompatibleTransport(
1093 const OpalTransportAddress & address
1094 ) const;
1095
1103 virtual PBoolean Connect();
1104
1107 virtual PString GetInterface() const;
1108
1115 virtual bool SetInterface(
1116 const PString & iface
1117 );
1118
1121 virtual OpalTransportAddress GetLocalAddress(
1122 bool allowNAT = true
1123 ) const;
1124
1129 virtual PBoolean SetLocalAddress(
1130 const OpalTransportAddress & address
1131 );
1132
1138 virtual PBoolean SetRemoteAddress(
1139 const OpalTransportAddress & address
1140 );
1141
1153 virtual void SetPromiscuous(
1154 PromisciousModes promiscuous
1155 );
1156
1161 virtual OpalTransportAddress GetLastReceivedAddress() const;
1162
1167 virtual PString GetLastReceivedInterface() const;
1168
1178 virtual PBoolean ReadPDU(
1179 PBYTEArray & packet
1180 );
1181
1187 virtual PBoolean WritePDU(
1188 const PBYTEArray & pdu
1189 );
1190
1201 virtual PBoolean WriteConnect(
1202 WriteConnectCallback function,
1203 void * userData
1204 );
1205
1208 void SetBufferSize(
1209 PINDEX size
1210 ) { m_bufferSize = size; }
1212
1213 protected:
1216 virtual const char * GetProtoPrefix() const;
1217
1218 OpalManager & manager;
1219 PINDEX m_bufferSize;
1220 PBYTEArray m_preReadPacket;
1221 bool m_preReadOK;
1222
1223 friend class OpalListenerUDP;
1224 };
1225
1226
1228
1229 class OpalInternalTransport : public PObject
1230 {
1231 PCLASSINFO(OpalInternalTransport, PObject);
1232 public:
1233 virtual PString GetHostName(
1234 const OpalTransportAddress & address
1235 ) const;
1236
1237 virtual PBoolean GetIpAndPort(
1238 const OpalTransportAddress & address,
1239 PIPSocket::Address & ip,
1240 WORD & port
1241 ) const;
1242
1243 virtual OpalListener * CreateListener(
1244 const OpalTransportAddress & address,
1245 OpalEndPoint & endpoint,
1246 OpalTransportAddress::BindOptions options
1247 ) const = 0;
1248
1249 virtual OpalTransport * CreateTransport(
1250 const OpalTransportAddress & address,
1251 OpalEndPoint & endpoint,
1252 OpalTransportAddress::BindOptions options
1253 ) const = 0;
1254 };
1255
1256
1258
1259 class OpalInternalIPTransport : public OpalInternalTransport
1260 {
1261 PCLASSINFO(OpalInternalIPTransport, OpalInternalTransport);
1262 public:
1263 virtual PString GetHostName(
1264 const OpalTransportAddress & address
1265 ) const;
1266 virtual PBoolean GetIpAndPort(
1267 const OpalTransportAddress & address,
1268 PIPSocket::Address & ip,
1269 WORD & port
1270 ) const;
1271
1272 static PBoolean GetAdjustedIpAndPort(const OpalTransportAddress & address,
1273 OpalEndPoint & endpoint,
1274 OpalTransportAddress::BindOptions option,
1275 PIPSocket::Address & ip,
1276 WORD & port,
1277 PBoolean & reuseAddr);
1278 };
1279
1280 template <class ListenerType, class TransportType, unsigned AltTypeOption, class AltTypeClass>
1281 class OpalInternalIPTransportTemplate : public OpalInternalIPTransport
1282 {
1283 public:
1284 OpalListener * CreateListener(
1285 const OpalTransportAddress & address,
1286 OpalEndPoint & endpoint,
1287 OpalTransportAddress::BindOptions options
1288 ) const
1289 {
1290 return new ListenerType(endpoint, address, options);
1291 }
1292
1293 OpalTransport * CreateTransport(
1294 const OpalTransportAddress & address,
1295 OpalEndPoint & endpoint,
1296 OpalTransportAddress::BindOptions options
1297 ) const
1298 {
1299 PIPSocket::Address ip;
1300 WORD port;
1301 PBoolean reuseAddr;
1302 if (GetAdjustedIpAndPort(address, endpoint, options, ip, port, reuseAddr)) {
1303 if (options == AltTypeOption)
1304 return new AltTypeClass(endpoint, ip, 0, reuseAddr);
1305 else
1306 return new TransportType(endpoint, ip, 0, reuseAddr);
1307 }
1308 return NULL;
1309 }
1310 };
1311
1312 typedef OpalInternalIPTransportTemplate<OpalListenerTCP, OpalTransportTCP, OpalTransportAddress::Datagram, OpalTransportUDP> OpalInternalTCPTransport;
1313 typedef OpalInternalIPTransportTemplate<OpalListenerUDP, OpalTransportUDP, OpalTransportAddress::Streamed, OpalTransportTCP> OpalInternalUDPTransport;
1314
1315 #if OPAL_PTLIB_SSL
1316
1317 class PSSLContext;
1318
1319 class OpalListenerTCPS : public OpalListenerTCP
1320 {
1321 PCLASSINFO(OpalListenerTCPS, OpalListenerTCP);
1322 public:
1323 OpalListenerTCPS(
1324 OpalEndPoint & endpoint,
1325 PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(),
1326 WORD port = 0,
1327 PBoolean exclusive = true
1328 );
1329 OpalListenerTCPS(
1330 OpalEndPoint & endpoint,
1331 const OpalTransportAddress & binding,
1332 OpalTransportAddress::BindOptions option
1333 );
1334
1337 ~OpalListenerTCPS();
1338
1339 OpalTransport * Accept(const PTimeInterval & timeout);
1340 const char * GetProtoPrefix() const;
1341
1342 protected:
1343 void Construct();
1344
1345 PSSLContext * sslContext;
1346 };
1347
1348 class OpalTransportTCPS : public OpalTransportTCP
1349 {
1350 PCLASSINFO(OpalTransportTCPS, OpalTransportTCP);
1351 public:
1352 OpalTransportTCPS(
1353 OpalEndPoint & endpoint,
1354 PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(),
1355 WORD port = 0,
1356 PBoolean reuseAddr = false
1357 );
1358 OpalTransportTCPS(
1359 OpalEndPoint & endpoint,
1360 PTCPSocket * socket
1361 );
1362
1364 ~OpalTransportTCPS();
1365
1366 PBoolean IsCompatibleTransport(const OpalTransportAddress & address) const;
1367 PBoolean Connect();
1368 PBoolean OnOpen();
1369 const char * GetProtoPrefix() const;
1370
1371 protected:
1372 PSSLContext * sslContext;
1373 };
1374
1375 typedef OpalInternalIPTransportTemplate<OpalListenerTCPS, OpalTransportTCPS, OpalTransportAddress::Datagram, OpalTransportUDP> OpalInternalTCPSTransport;
1376
1377
1378 #endif // OPAL_PTLIB_SSL
1379
1380
1381 #endif // OPAL_OPAL_TRANSPORT_H
1382
1383
1384 // End of File ///////////////////////////////////////////////////////////////