fixed Windows build errors
[public/netxms.git] / src / nxcproxy / session.cpp
CommitLineData
1a93e64a
VK
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 */
28ProxySession::ProxySession(SOCKET s)
29{
30 m_client = s;
31 m_server = INVALID_SOCKET;
32}
33
34/**
35 * Destructor
36 */
37ProxySession::~ProxySession()
38{
39}
40
41/**
42 * Run session
43 */
44void ProxySession::run()
45{
46 ThreadCreate(ProxySession::clientThreadStarter, 0, this);
47}
48
49/**
50 * Client thread starter
51 */
52THREAD_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 */
63THREAD_RESULT THREAD_CALL ProxySession::serverThreadStarter(void *arg)
64{
65 ((ProxySession *)arg)->serverThread();
66 return THREAD_OK;
67}
68
69/**
70 * Client thread
71 */
72void ProxySession::clientThread()
73{
74 DebugPrintf(7, _T("Client thread started, connecting to server"));
688b5dc2
VK
75 InetAddress addr = InetAddress::resolveHostName(g_serverAddress);
76 if (addr.isValidUnicast())
1a93e64a 77 {
688b5dc2
VK
78 m_server = socket(addr.getFamily(), SOCK_STREAM, 0);
79 if (m_server != INVALID_SOCKET)
1a93e64a 80 {
688b5dc2
VK
81 SockAddrBuffer sa;
82 addr.fillSockAddr(&sa, g_serverPort);
83 if (ConnectEx(m_server, (struct sockaddr *)&sa, SA_LEN((struct sockaddr *)&sa), 5000) != -1)
1a93e64a
VK
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 {
688b5dc2 94 DebugPrintf(5, _T("Cannot create socket for server connection"));
1a93e64a
VK
95 }
96 }
688b5dc2
VK
97 else
98 {
99 DebugPrintf(4, _T("Cannot resolve server address %s"), g_serverAddress);
100 }
1a93e64a
VK
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 */
110void 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 */
121void 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}