OPAL  Version 3.12.9
h46018_h225.h
Go to the documentation of this file.
1 /*
2  * h46018_h225.h
3  *
4  * H.460.18 H225 NAT Traversal class.
5  *
6  * h323plus library
7  *
8  * Copyright (c) 2008 ISVO (Asia) Pte. Ltd.
9  *
10  * The contents of this file are subject to the Mozilla Public License
11  * Version 1.1 (the "License"); you may not use this file except in
12  * compliance with the License. You may obtain a copy of the License at
13  * http://www.mozilla.org/MPL/
14  *
15  * Alternatively, the contents of this file may be used under the terms
16  * of the General Public License (the "GNU License"), in which case the
17  * provisions of GNU License are applicable instead of those
18  * above. If you wish to allow use of your version of this file only
19  * under the terms of the GNU License and not to allow others to use
20  * your version of this file under the MPL, indicate your decision by
21  * deleting the provisions above and replace them with the notice and
22  * other provisions required by the GNU License. If you do not delete
23  * the provisions above, a recipient may use your version of this file
24  * under either the MPL or the GNU License."
25  *
26  * Software distributed under the License is distributed on an "AS IS"
27  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
28  * the License for the specific language governing rights and limitations
29  * under the License.
30  *
31  *
32  * The Initial Developer of the Original Code is ISVO (Asia) Pte. Ltd.
33  *
34  * Portions of this code were written with the assisance of funding from
35  * triple-IT. http://www.triple-it.nl.
36  *
37  * Contributor(s): ______________________________________.
38  *
39  * $Revision: 28624 $
40  * $Author: rjongbloed $
41  * $Date: 2012-12-03 15:13:25 +1100 (Mon, 03 Dec 2012) $
42  */
43 
44 #ifndef OPAL_H46018_H225
45 #define OPAL_H46018_NAT
46 
47 #if _MSC_VER > 1000
48 #pragma once
49 #endif // _MSC_VER > 1000
50 
51 #if OPAL_H460_NAT
52 
53 #include <h323/h323pdu.h>
54 
55 
56 class H46018SignalPDU : public H323SignalPDU
57 {
58  public:
66  H46018SignalPDU(const OpalGloballyUniqueID & callIdentifier);
68 };
69 
70 
71 class H323EndPoint;
72 class H46018Handler;
73 
74 class H46018Transport : public OpalTransportTCP
75 {
76  PCLASSINFO(H46018Transport, OpalTransportTCP);
77 
78  public:
79  enum PDUType {
80  e_raw,
81  };
82 
87  H46018Transport(
88  H323EndPoint & endpoint
89  );
90 
91  ~H46018Transport();
93 
101  virtual PBoolean WritePDU(
102  const PBYTEArray & pdu
103  );
104 
110  virtual PBoolean ReadPDU(
111  PBYTEArray & pdu
112  );
114 
120  PBoolean HandleH46018SignallingChannelPDU();
121 
125  PBoolean HandleH46018SignallingSocket(H323SignalPDU & pdu);
126 
130  PBoolean InitialPDU(const OpalGloballyUniqueID & callIdentifier);
131 
135  PBoolean isCall() { return isConnected; };
136 
140  void ConnectionLost(PBoolean established);
141 
145  PBoolean IsConnectionLost();
147 
148  // Overrides
151  virtual PBoolean Connect(const OpalGloballyUniqueID & callIdentifier);
152 
155  virtual PBoolean Close();
156 
157  virtual PBoolean IsListening() const;
158 
159  virtual PBoolean IsOpen () const;
160 
161  PBoolean CloseTransport() { return closeTransport; };
162 
163  protected:
164  PMutex connectionsMutex;
165  PMutex WriteMutex;
166  PMutex IntMutex;
167  PTimeInterval ReadTimeOut;
168  PSyncPoint ReadMutex;
169 
170  H46018Handler * Feature;
171 
172  PBoolean isConnected;
173  PBoolean remoteShutDown;
174  PBoolean closeTransport;
175 };
176 
177 
178 class H323EndPoint;
179 class PNatMethod_H46019;
180 
181 class H46018Handler : public PObject
182 {
183  PCLASSINFO(H46018Handler, PObject);
184 
185  public:
186  H46018Handler(H323EndPoint * ep);
187  ~H46018Handler();
188 
189  void Enable();
190  PBoolean IsEnabled();
191 
192  H323EndPoint * GetEndPoint();
193 
194  PBoolean CreateH225Transport(const PASN_OctetString & information);
195 
196  void H46024ADirect(bool reply, const PString & token);
197 
198  protected:
199  H323EndPoint * EP;
200  PNatMethod_H46019 * nat;
201  PString lastCallIdentifer;
202 
203  PMutex m_h46024aMutex;
204  bool m_h46024a;
205 
206  private:
207  H323TransportAddress m_address;
208  OpalGloballyUniqueID m_callId;
209  PThread * SocketCreateThread;
210  PDECLARE_NOTIFIER(PThread, H46018Handler, SocketThread);
211  PBoolean m_h46018inOperation;
212 };
213 
214 
215 class PNatMethod_H46019 : public PNatMethod
216 {
217  PCLASSINFO(PNatMethod_H46019,PNatMethod);
218 
219  public:
224  PNatMethod_H46019();
225 
228  ~PNatMethod_H46019();
230 
236  static PString GetNatMethodName();
237  virtual PString GetName() const;
238 
241  virtual PString GetServer() const;
242 
246  virtual PBoolean CreateSocketPair(
247  PUDPSocket * & socket1,
248  PUDPSocket * & socket2,
249  const PIPSocket::Address & binding,
250  void * userData
251  );
252 
261  virtual bool IsAvailable(const PIPSocket::Address & address);
262 
263  /* Set Available
264  This will enable the natMethod to be enabled when opening the
265  sockets
266  */
267  void SetAvailable();
268 
272  virtual void Activate(bool act) { active = act; }
273 
277  PBoolean OpenSocket(PUDPSocket & socket, PortInfo & portInfo, const PIPSocket::Address & binding) const;
279 
285  void AttachHandler(H46018Handler * _handler);
286 
287  protected:
288  virtual NatTypes InternalGetNatType(bool forced, const PTimeInterval & maxAge);
289 
290 #if OPAL_H460_NAT
291 
298  void SetConnectionSockets(
299  PUDPSocket * data,
300  PUDPSocket * control,
301  H323Connection::SessionInformation * info
302  );
303 #endif
304 
305  PBoolean available;
306  PBoolean active;
307  H46018Handler * handler;
308 };
309 
310 #ifndef _WIN32_WCE
311  PPLUGIN_STATIC_LOAD(H46019,PNatMethod);
312 #endif
313 
314 
315 class H46019UDPSocket : public PUDPSocket
316 {
317  PCLASSINFO(H46019UDPSocket, PUDPSocket);
318  public:
324  H46019UDPSocket(
325  H46018Handler & _handler,
326  H323Connection::SessionInformation * info,
327  bool _rtpSocket
328  );
329 
333  ~H46019UDPSocket();
335 
336  PBoolean GetLocalAddress(Address & addr, WORD & port);
337 
340 
343  void Allocate(
344  const H323TransportAddress & keepalive,
345  unsigned _payload,
346  unsigned _ttl,
347  unsigned _muxId
348  );
349 
352  void Activate();
353 
356  void Activate(const H323TransportAddress & keepalive,
357  unsigned _payload,
358  unsigned _ttl,
359  unsigned _muxId
360  );
361 
364  unsigned GetPingPayload();
365 
368  void SetPingPayLoad(unsigned val);
369 
372  unsigned GetTTL();
373 
376  void SetTTL(unsigned val);
377 
381  virtual PBoolean ReadFrom(
382  void * buf,
383  PINDEX len,
384  Address & addr,
385  WORD & port
386  );
387 
391  virtual PBoolean WriteTo(
392  const void * buf,
393  PINDEX len,
394  const Address & addr,
395  WORD port
396  );
397 
398  enum probe_state {
399  e_notRequired,
400  e_initialising,
401  e_idle,
402  e_probing,
403  e_verify_receiver,
404  e_verify_sender,
405  e_wait,
406  e_direct
407  };
408 
409  struct probe_packet {
410  PUInt16b Length; // Length
411  PUInt32b SSRC; // Time Stamp
412  BYTE name[4]; // Name is limited to 32 (4 Bytes)
413  BYTE cui[20]; // SHA-1 is always 160 (20 Bytes)
414  };
415 
418  virtual void SetAlternateAddresses(const H323TransportAddress & address, const PString & cui);
419 
422  virtual void GetAlternateAddresses(H323TransportAddress & address, PString & cui);
423 
426  virtual PBoolean IsAlternateAddress(
427  const Address & address,
428  WORD port
429  );
432  void H46024Adirect(bool starter);
433 
436  void H46024Bdirect(const H323TransportAddress & address);
438 
439  protected:
440 
441  // H.460.19 Keepalives
442  void InitialiseKeepAlive();
443  void SendRTPPing(const PIPSocket::Address & ip, const WORD & port);
444  void SendRTCPPing();
445  PBoolean SendRTCPFrame(RTP_ControlFrame & report, const PIPSocket::Address & ip, WORD port);
446  PMutex PingMutex;
447 
448  // H46024 Annex A support
449  PBoolean ReceivedProbePacket(const RTP_ControlFrame & frame, bool & probe, bool & success);
450  void BuildProbe(RTP_ControlFrame & report, bool reply);
451  void StartProbe();
452  void ProbeReceived(bool probe, const PIPSocket::Address & addr, WORD & port);
453  void SetProbeState(probe_state newstate);
454  int GetProbeState() const;
455  probe_state m_state;
456  PMutex probeMutex;
457 
461  virtual PBoolean Internal_WriteTo(
462  const Slice * slices,
463  size_t nSlices,
464  const Address & addr,
465  WORD port
466  );
467 
471  virtual PBoolean Internal_WriteTo(
472  const void * buf,
473  PINDEX len,
474  const Address & addr,
475  WORD port
476  );
477 
478  private:
479  H46018Handler & m_Handler;
480  unsigned m_Session;
481  PString m_Token;
482  OpalGloballyUniqueID m_CallId;
483  PString m_CUI;
484 
485  // H.460.19 Keepalives
486  PIPSocket::Address keepip;
487  WORD keepport;
488  unsigned keeppayload;
489  unsigned keepTTL;
490  PUInt32b muxId;
491  WORD keepseqno;
492  PTime * keepStartTime;
493 
494  PDECLARE_NOTIFIER(PTimer, H46019UDPSocket, Ping);
495  PTimer Keep;
496 
497  // H46024 Annex A support
498  PString m_CUIrem;
499  PIPSocket::Address m_locAddr; WORD m_locPort;
500  PIPSocket::Address m_remAddr; WORD m_remPort;
501  PIPSocket::Address m_detAddr; WORD m_detPort;
502  PIPSocket::Address m_pendAddr; WORD m_pendPort;
503  PDECLARE_NOTIFIER(PTimer, H46019UDPSocket, Probe);
504  PTimer m_Probe;
505  PINDEX m_probes;
506  DWORD SSRC;
507  PIPSocket::Address m_altAddr; WORD m_altPort;
508  // H46024 Annex B support
509  PBoolean m_h46024b;
510 
511  bool rtpSocket;
512 };
513 
514 #endif // OPAL_H460_NAT
515 
516 #endif // OPAL_H46018_H225