1 /*
2 * Copyright (c) 2013-2020, The PurpleI2P Project
3 *
4 * This file is part of Purple i2pd project and licensed under BSD3
5 *
6 * See full license text in LICENSE file at top of project tree
7 */
8 
9 #ifndef __UPNP_H__
10 #define __UPNP_H__
11 
12 #ifdef USE_UPNP
13 #include <string>
14 #include <thread>
15 #include <condition_variable>
16 #include <mutex>
17 #include <memory>
18 
19 #include <miniupnpc/miniwget.h>
20 #include <miniupnpc/miniupnpc.h>
21 #include <miniupnpc/upnpcommands.h>
22 #include <miniupnpc/upnperrors.h>
23 
24 #include <boost/asio.hpp>
25 
26 namespace i2p
27 {
28 namespace transport
29 {
30 	const int UPNP_RESPONSE_TIMEOUT = 2000; // in milliseconds
31 
32 	enum
33 	{
34 		UPNP_IGD_NONE = 0,
35 		UPNP_IGD_VALID_CONNECTED = 1,
36 		UPNP_IGD_VALID_NOT_CONNECTED = 2,
37 		UPNP_IGD_INVALID = 3
38 	};
39 
40 	class UPnP
41 	{
42 		public:
43 
44 			UPnP ();
45 			~UPnP ();
46 			void Close ();
47 
48 			void Start ();
49 			void Stop ();
50 
51 		private:
52 
53 			void Discover ();
54 			int  CheckMapping (const char* port, const char* type);
55 			void PortMapping ();
56 			void TryPortMapping (std::shared_ptr<i2p::data::RouterInfo::Address> address);
57 			void CloseMapping ();
58 			void CloseMapping (std::shared_ptr<i2p::data::RouterInfo::Address> address);
59 
60 			void Run ();
61 			std::string GetProto (std::shared_ptr<i2p::data::RouterInfo::Address> address);
62 
63 		private:
64 
65 			bool m_IsRunning;
66 			std::unique_ptr<std::thread> m_Thread;
67 			std::condition_variable m_Started;
68 			std::mutex m_StartedMutex;
69 			boost::asio::io_service m_Service;
70 			boost::asio::deadline_timer m_Timer;
71 			bool m_upnpUrlsInitialized = false;
72 			struct UPNPUrls m_upnpUrls;
73 			struct IGDdatas m_upnpData;
74 
75 			// For miniupnpc
76 			struct UPNPDev * m_Devlist = 0;
77 			char m_NetworkAddr[64];
78 			char m_externalIPAddress[40];
79 	};
80 }
81 }
82 
83 #else  // USE_UPNP
84 namespace i2p {
85 namespace transport {
86 	/* class stub */
87 	class UPnP {
88 		public:
89 
UPnP()90 			UPnP () {};
~UPnP()91 			~UPnP () {};
Start()92 			void Start () { LogPrint(eLogWarning, "UPnP: this module was disabled at compile-time"); }
Stop()93 			void Stop () {};
94 	};
95 }
96 }
97 #endif // USE_UPNP
98 #endif // __UPNP_H__
99