1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
/*
* $Id: server.c,v 1.1 2004/12/30 22:44:20 lordjaxom Exp $
*/
#include "server/server.h"
#include "server/componentVTP.h"
#include "server/componentHTTP.h"
#include "server/setup.h"
#include <vdr/tools.h>
#include <tools/select.h>
#include <string.h>
#include <errno.h>
cSVDRPhosts StreamdevHosts;
cStreamdevServer *cStreamdevServer::m_Instance = NULL;
cStreamdevServer::cStreamdevServer(void)
#if VDRVERSNUM >= 10300
: cThread("Streamdev: server")
#endif
{
m_Active = false;
StreamdevHosts.Load(AddDirectory(cPlugin::ConfigDirectory(),
"streamdevhosts.conf"), true);
}
cStreamdevServer::~cStreamdevServer() {
if (m_Active) Stop();
}
void cStreamdevServer::Init(void) {
if (m_Instance == NULL) {
m_Instance = new cStreamdevServer;
if (StreamdevServerSetup.StartVTPServer)
m_Instance->Register(new cComponentVTP);
if (StreamdevServerSetup.StartHTTPServer)
m_Instance->Register(new cComponentHTTP);
m_Instance->Start();
}
}
void cStreamdevServer::Exit(void) {
if (m_Instance != NULL) {
m_Instance->Stop();
DELETENULL(m_Instance);
}
}
void cStreamdevServer::Stop(void) {
m_Active = false;
Cancel(3);
}
void cStreamdevServer::Register(cServerComponent *Server) {
m_Servers.Add(Server);
}
void cStreamdevServer::Action(void) {
cTBSelect select;
#if VDRVERSNUM < 10300
isyslog("Streamdev: Server thread started (pid=%d)", getpid());
#endif
m_Active = true;
/* Initialize Server components, deleting those that failed */
for (cServerComponent *c = m_Servers.First(); c;) {
cServerComponent *next = m_Servers.Next(c);
if (!c->Init())
m_Servers.Del(c);
c = next;
}
if (!m_Servers.Count()) {
esyslog("Streamdev: No server components registered, exiting");
m_Active = false;
}
while (m_Active) {
select.Clear();
/* Ask all Server components to register to the selector */
for (cServerComponent *c = m_Servers.First(); c; c = m_Servers.Next(c))
c->AddSelect(select);
/* Ask all Client connections to register to the selector */
for (cServerConnection *s = m_Clients.First(); s; s = m_Clients.Next(s))
s->AddSelect(select);
if (select.Select(1000) < 0) {
if (!m_Active) // Exit was requested while polling
continue;
esyslog("Streamdev: Fatal error, server exiting: %s", strerror(errno));
m_Active = false;
}
/* Ask all Server components to act on signalled sockets */
for (cServerComponent *c = m_Servers.First(); c; c = m_Servers.Next(c)) {
cServerConnection *client;
if ((client = c->CanAct(select)) != NULL) {
m_Clients.Add(client);
if (m_Clients.Count() > StreamdevServerSetup.MaxClients) {
esyslog("Streamdev: Too many clients, rejecting %s:%d",
(const char*)client->RemoteIp(), client->RemotePort());
client->Reject();
} else if (!StreamdevHosts.Acceptable(client->RemoteIpAddr())) {
esyslog("Streamdev: Client from %s:%d not allowed to connect",
(const char*)client->RemoteIp(), client->RemotePort());
client->Reject();
} else
client->Welcome();
}
}
/* Ask all Client connections to act on signalled sockets */
for (cServerConnection *s = m_Clients.First(); s;) {
cServerConnection *next = m_Clients.Next(s);
if (!s->CanAct(select)) {
isyslog("Streamdev: Closing connection to %s:%d",
(const char*)s->RemoteIp(), s->RemotePort());
s->Close();
m_Clients.Del(s);
}
s = next;
}
}
while (m_Clients.Count()) {
cServerConnection *client = m_Clients.First();
client->Close();
m_Clients.Del(client);
}
while (m_Servers.Count()) {
cServerComponent *server = m_Servers.First();
server->Exit();
m_Servers.Del(server);
}
#if VDRVERSNUM < 10300
isyslog("Streamdev: Server thread stopped");
#endif
}
|