fixed Windows build errors
[public/netxms.git] / src / nxcproxy / session.cpp
1 /*
2 ** NetXMS client proxy
3 ** Copyright (C) 2003-2013 Victor Kirhenshtein
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
14 **
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 **
19 ** File: session.cpp
20 **
21 **/
22
23 #include "nxcproxy.h"
24
25 /**
26 * Constructor
27 */
28 ProxySession::ProxySession(SOCKET s)
29 {
30 m_client = s;
31 m_server = INVALID_SOCKET;
32 }
33
34 /**
35 * Destructor
36 */
37 ProxySession::~ProxySession()
38 {
39 }
40
41 /**
42 * Run session
43 */
44 void ProxySession::run()
45 {
46 ThreadCreate(ProxySession::clientThreadStarter, 0, this);
47 }
48
49 /**
50 * Client thread starter
51 */
52 THREAD_RESULT THREAD_CALL ProxySession::clientThreadStarter(void *arg)
53 {
54 ((ProxySession *)arg)->clientThread();
55 // server thread is not running at this point, so it's safe to delete self
56 delete (ProxySession *)arg;
57 return THREAD_OK;
58 }
59
60 /**
61 * Server thread starter
62 */
63 THREAD_RESULT THREAD_CALL ProxySession::serverThreadStarter(void *arg)
64 {
65 ((ProxySession *)arg)->serverThread();
66 return THREAD_OK;
67 }
68
69 /**
70 * Client thread
71 */
72 void ProxySession::clientThread()
73 {
74 DebugPrintf(7, _T("Client thread started, connecting to server"));
75 InetAddress addr = InetAddress::resolveHostName(g_serverAddress);
76 if (addr.isValidUnicast())
77 {
78 m_server = socket(addr.getFamily(), SOCK_STREAM, 0);
79 if (m_server != INVALID_SOCKET)
80 {
81 SockAddrBuffer sa;
82 addr.fillSockAddr(&sa, g_serverPort);
83 if (ConnectEx(m_server, (struct sockaddr *)&sa, SA_LEN((struct sockaddr *)&sa), 5000) != -1)
84 {
85 DebugPrintf(7, _T("Connected to server %s:%d"), g_serverAddress, (int)g_serverPort);
86 THREAD serverThread = ThreadCreateEx(ProxySession::serverThreadStarter, 0, this);
87 forward(m_client, m_server);
88 ThreadJoin(serverThread);
89 }
90 closesocket(m_server);
91 }
92 else
93 {
94 DebugPrintf(5, _T("Cannot create socket for server connection"));
95 }
96 }
97 else
98 {
99 DebugPrintf(4, _T("Cannot resolve server address %s"), g_serverAddress);
100 }
101
102 shutdown(m_client, SHUT_RDWR);
103 closesocket(m_client);
104 DebugPrintf(7, _T("Client thread stopped"));
105 }
106
107 /**
108 * Server thread
109 */
110 void ProxySession::serverThread()
111 {
112 DebugPrintf(7, _T("Server thread started"));
113 SetSocketNonBlocking(m_server);
114 forward(m_server, m_client);
115 DebugPrintf(7, _T("Server thread stopped"));
116 }
117
118 /**
119 * Forward messages between two sockets
120 */
121 void ProxySession::forward(SOCKET rs, SOCKET ws)
122 {
123 fd_set rdfs;
124 struct timeval tv;
125 char buffer[8192];
126
127 while(true)
128 {
129 FD_ZERO(&rdfs);
130 FD_SET(rs, &rdfs);
131 tv.tv_sec = 0;
132 tv.tv_usec = 5000000; // Half-second timeout
133 int ret = select(SELECT_NFDS(rs + 1), &rdfs, NULL, NULL, &tv);
134 if (ret < 0)
135 break;
136 if (ret > 0)
137 {
138 ret = recv(rs, buffer, 8192, 0);
139 if (ret <= 0)
140 break;
141 SendEx(ws, buffer, ret, 0, NULL);
142 }
143 }
144
145 // shutdown other end
146 shutdown(ws, SHUT_RDWR);
147 }