]> git.vomp.tv Git - vompclient.git/blob - src/vdpc.h
Type updates:
[vompclient.git] / src / vdpc.h
1 /*
2     Copyright 2020 Chris Tallon
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP.  If not, see <https://www.gnu.org/licenses/>.
18 */
19
20 #ifndef VDPC_H
21 #define VDPC_H
22
23 // Vomp Discovery Protocol Client
24
25 #include <string>
26 #include <vector>
27 #include <mutex>
28 #include <thread>
29 #include <condition_variable>
30 #include <functional>
31
32 #ifdef WIN32
33   #include <WinSock2.h>
34 #endif
35
36 #include "defines.h"
37
38 #ifdef IPV4
39 #include "udp4.h"
40 #endif
41 #ifdef IPV6
42 #include "udp6.h"
43 #endif
44
45 struct VDRServer
46 {
47   int ipVersion;
48   std::string ip;
49   std::string name;
50   USHORT port;
51   u4 version;
52
53   VDRServer() {}
54
55   VDRServer(int tipVersion, const std::string tip, const std::string tname, USHORT tport, u4 tversion)
56   : ipVersion(tipVersion), ip(tip), name(tname), port(tport), version(tversion) {}
57 };
58
59 class ServerSorter
60 {
61   public:
62     ServerSorter() {}
63     bool operator() (const VDRServer& a, const VDRServer& b)
64     {
65       // First sort by name
66       if (a.name == b.name)
67       {
68         // Then by IP version
69         if (a.ipVersion == b.ipVersion)
70         {
71           // Then by IP
72           if (a.ip == b.ip)
73           {
74             // Then by port
75             return a.port < b.port;
76           }
77           else
78             return a.ip < b.ip; // yeah, weird
79         }
80         else
81           return a.ipVersion < b.ipVersion;
82       }
83       else
84         return a.name < b.name;
85     }
86 };
87
88 class LogNT;
89
90 class VDPC
91 {
92   private:
93     LogNT* logger{};
94     typedef std::function<void(int, const char*, const char*, USHORT, u4)> AddServerCallback;
95
96   // Nested classes
97 #ifdef IPV4
98     class VDPC4
99     {
100       public:
101         bool init(AddServerCallback& taddFunc);
102         void run(); // blocks
103         void stop();
104         void sendRequest();
105
106       private:
107         #ifdef WIN32
108           SOCKET quitPipe;
109         #else
110           int pfdsUDP4[2];
111         #endif
112
113         std::mutex startProtect;
114         std::thread receiveThread;
115         bool stopNow{};
116         void threadMethod();
117
118         UDP4 udp4;
119         AddServerCallback addFunc;
120     };
121 #endif
122
123 #ifdef IPV6
124     class VDPC6
125     {
126       public:
127         bool init(AddServerCallback& taddFunc);
128         void run(); // blocks
129         void stop();
130         void sendRequest();
131
132       private:
133         int pfdsUDP6[2];
134
135         std::mutex startProtect;
136         std::thread receiveThread;
137         bool stopNow{};
138         void threadMethod();
139
140         UDP6 udp6;
141         AddServerCallback addFunc;
142     };
143 #endif
144
145   public:
146     bool init();
147     int go();
148     void stop();
149     u4 numServers() const;
150     const VDRServer& operator[](u4 index) const;
151
152   private:
153     std::vector<VDRServer> servers;
154     std::mutex serversLock;
155
156     std::condition_variable waitCond;
157     std::mutex waitMutex;
158     bool stopNow{};
159
160     void filterServers();
161
162 #ifdef IPV4
163     VDPC4 vdpc4;
164 #endif
165 #ifdef IPV6
166     VDPC6 vdpc6;
167 #endif
168 };
169
170 #endif