1*9203SMark.Logan@Sun.COM /******************************************************************************* 2*9203SMark.Logan@Sun.COM * Copyright (C) 2004-2008 Intel Corp. All rights reserved. 3*9203SMark.Logan@Sun.COM * 4*9203SMark.Logan@Sun.COM * Redistribution and use in source and binary forms, with or without 5*9203SMark.Logan@Sun.COM * modification, are permitted provided that the following conditions are met: 6*9203SMark.Logan@Sun.COM * 7*9203SMark.Logan@Sun.COM * - Redistributions of source code must retain the above copyright notice, 8*9203SMark.Logan@Sun.COM * this list of conditions and the following disclaimer. 9*9203SMark.Logan@Sun.COM * 10*9203SMark.Logan@Sun.COM * - Redistributions in binary form must reproduce the above copyright notice, 11*9203SMark.Logan@Sun.COM * this list of conditions and the following disclaimer in the documentation 12*9203SMark.Logan@Sun.COM * and/or other materials provided with the distribution. 13*9203SMark.Logan@Sun.COM * 14*9203SMark.Logan@Sun.COM * - Neither the name of Intel Corp. nor the names of its 15*9203SMark.Logan@Sun.COM * contributors may be used to endorse or promote products derived from this 16*9203SMark.Logan@Sun.COM * software without specific prior written permission. 17*9203SMark.Logan@Sun.COM * 18*9203SMark.Logan@Sun.COM * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' 19*9203SMark.Logan@Sun.COM * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20*9203SMark.Logan@Sun.COM * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21*9203SMark.Logan@Sun.COM * ARE DISCLAIMED. IN NO EVENT SHALL Intel Corp. OR THE CONTRIBUTORS 22*9203SMark.Logan@Sun.COM * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23*9203SMark.Logan@Sun.COM * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24*9203SMark.Logan@Sun.COM * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25*9203SMark.Logan@Sun.COM * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26*9203SMark.Logan@Sun.COM * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27*9203SMark.Logan@Sun.COM * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28*9203SMark.Logan@Sun.COM * POSSIBILITY OF SUCH DAMAGE. 29*9203SMark.Logan@Sun.COM *******************************************************************************/ 30*9203SMark.Logan@Sun.COM 31*9203SMark.Logan@Sun.COM #ifdef HAVE_CONFIG_H 32*9203SMark.Logan@Sun.COM #include "config.h" 33*9203SMark.Logan@Sun.COM #endif 34*9203SMark.Logan@Sun.COM #if defined(__sun) || defined(_LINUX) 35*9203SMark.Logan@Sun.COM #include <cerrno> 36*9203SMark.Logan@Sun.COM #include <sys/socket.h> 37*9203SMark.Logan@Sun.COM #include <arpa/inet.h> 38*9203SMark.Logan@Sun.COM #include <netinet/in.h> 39*9203SMark.Logan@Sun.COM #include <net/if.h> 40*9203SMark.Logan@Sun.COM #include <sys/ioctl.h> 41*9203SMark.Logan@Sun.COM #include <unistd.h> 42*9203SMark.Logan@Sun.COM #include <fcntl.h> 43*9203SMark.Logan@Sun.COM #include <netdb.h> 44*9203SMark.Logan@Sun.COM #include <syslog.h> 45*9203SMark.Logan@Sun.COM 46*9203SMark.Logan@Sun.COM #define _stprintf_s snprintf 47*9203SMark.Logan@Sun.COM #define strnicmp strncasecmp 48*9203SMark.Logan@Sun.COM #else 49*9203SMark.Logan@Sun.COM 50*9203SMark.Logan@Sun.COM #include <winsock2.h> 51*9203SMark.Logan@Sun.COM #include <iphlpapi.h> 52*9203SMark.Logan@Sun.COM #include <Ws2tcpip.h> 53*9203SMark.Logan@Sun.COM #include <tchar.h> 54*9203SMark.Logan@Sun.COM 55*9203SMark.Logan@Sun.COM #endif // __sun || _LINUX 56*9203SMark.Logan@Sun.COM 57*9203SMark.Logan@Sun.COM #include <fstream> 58*9203SMark.Logan@Sun.COM #include <algorithm> 59*9203SMark.Logan@Sun.COM #include "Protocol.h" 60*9203SMark.Logan@Sun.COM #include "LMS_if.h" 61*9203SMark.Logan@Sun.COM #include "LMS_if_compat.h" 62*9203SMark.Logan@Sun.COM #include "Lock.h" 63*9203SMark.Logan@Sun.COM #include "ATNetworkTool.h" 64*9203SMark.Logan@Sun.COM 65*9203SMark.Logan@Sun.COM const LMEProtocolVersionMessage Protocol::MIN_PROT_VERSION(1, 0); 66*9203SMark.Logan@Sun.COM const LMEProtocolVersionMessage Protocol::MAX_PROT_VERSION(1, 0); 67*9203SMark.Logan@Sun.COM 68*9203SMark.Logan@Sun.COM Protocol::Protocol() : 69*9203SMark.Logan@Sun.COM #if DEBUGLOG 70*9203SMark.Logan@Sun.COM _lme(true), 71*9203SMark.Logan@Sun.COM #else 72*9203SMark.Logan@Sun.COM _lme(false), 73*9203SMark.Logan@Sun.COM #endif 74*9203SMark.Logan@Sun.COM _rxSocketBuffer(NULL), 75*9203SMark.Logan@Sun.COM _rxSocketBufferSize(0) 76*9203SMark.Logan@Sun.COM #ifdef _REMOTE_SUPPORT 77*9203SMark.Logan@Sun.COM , _cfg(true) 78*9203SMark.Logan@Sun.COM #endif 79*9203SMark.Logan@Sun.COM { 80*9203SMark.Logan@Sun.COM _serverSignalSocket = INVALID_SOCKET; 81*9203SMark.Logan@Sun.COM _clientSignalSocket = INVALID_SOCKET; 82*9203SMark.Logan@Sun.COM _sockets_active = false; 83*9203SMark.Logan@Sun.COM _handshakingStatus = NOT_INITIATED; 84*9203SMark.Logan@Sun.COM _pfwdService = NOT_STARTED; 85*9203SMark.Logan@Sun.COM _AmtProtVersion.MajorVersion = 0; 86*9203SMark.Logan@Sun.COM _AmtProtVersion.MinorVersion = 0; 87*9203SMark.Logan@Sun.COM #ifdef _REMOTE_SUPPORT 88*9203SMark.Logan@Sun.COM _remoteAccessEnabled = false; 89*9203SMark.Logan@Sun.COM #endif 90*9203SMark.Logan@Sun.COM memset(_AMTFQDN, 0, sizeof(_AMTFQDN)); 91*9203SMark.Logan@Sun.COM oldProtocolMode = false; 92*9203SMark.Logan@Sun.COM _deinitReq = false; 93*9203SMark.Logan@Sun.COM _listenFailReported.clear(); 94*9203SMark.Logan@Sun.COM } 95*9203SMark.Logan@Sun.COM 96*9203SMark.Logan@Sun.COM Protocol::~Protocol() 97*9203SMark.Logan@Sun.COM { 98*9203SMark.Logan@Sun.COM if (!oldProtocolMode) { 99*9203SMark.Logan@Sun.COM _lme.Disconnect(APF_DISCONNECT_BY_APPLICATION); 100*9203SMark.Logan@Sun.COM } 101*9203SMark.Logan@Sun.COM DeinitFull(); 102*9203SMark.Logan@Sun.COM DestroySockets(); 103*9203SMark.Logan@Sun.COM _listenFailReported.clear(); 104*9203SMark.Logan@Sun.COM } 105*9203SMark.Logan@Sun.COM 106*9203SMark.Logan@Sun.COM bool Protocol::Init(EventLogCallback cb, void *param) 107*9203SMark.Logan@Sun.COM { 108*9203SMark.Logan@Sun.COM _eventLog = cb; 109*9203SMark.Logan@Sun.COM _eventLogParam = param; 110*9203SMark.Logan@Sun.COM 111*9203SMark.Logan@Sun.COM DeinitFull(); 112*9203SMark.Logan@Sun.COM 113*9203SMark.Logan@Sun.COM { 114*9203SMark.Logan@Sun.COM Lock dl(_deinitLock); 115*9203SMark.Logan@Sun.COM _deinitReq = false; 116*9203SMark.Logan@Sun.COM } 117*9203SMark.Logan@Sun.COM 118*9203SMark.Logan@Sun.COM if (!_lme.Init(_LmeCallback, this)) { 119*9203SMark.Logan@Sun.COM return false; 120*9203SMark.Logan@Sun.COM } 121*9203SMark.Logan@Sun.COM 122*9203SMark.Logan@Sun.COM oldProtocolMode = (LMS_PROCOL_VERSION != _lme.protocolVer); 123*9203SMark.Logan@Sun.COM 124*9203SMark.Logan@Sun.COM { 125*9203SMark.Logan@Sun.COM Lock l(_versionLock); 126*9203SMark.Logan@Sun.COM 127*9203SMark.Logan@Sun.COM if (_handshakingStatus == NOT_INITIATED) { 128*9203SMark.Logan@Sun.COM if (oldProtocolMode) { 129*9203SMark.Logan@Sun.COM _lme.CompatProtocolVersion(); 130*9203SMark.Logan@Sun.COM } else { 131*9203SMark.Logan@Sun.COM _lme.ProtocolVersion(MAX_PROT_VERSION); 132*9203SMark.Logan@Sun.COM } 133*9203SMark.Logan@Sun.COM _handshakingStatus = INITIATED; 134*9203SMark.Logan@Sun.COM } 135*9203SMark.Logan@Sun.COM } 136*9203SMark.Logan@Sun.COM 137*9203SMark.Logan@Sun.COM if (!oldProtocolMode) { 138*9203SMark.Logan@Sun.COM #ifdef _REMOTE_SUPPORT 139*9203SMark.Logan@Sun.COM if (!_cfg.Init(true)) { 140*9203SMark.Logan@Sun.COM #else 141*9203SMark.Logan@Sun.COM if (!_cfg.IsAMTEnabled(false)) { 142*9203SMark.Logan@Sun.COM #endif 143*9203SMark.Logan@Sun.COM _lme.Deinit(); 144*9203SMark.Logan@Sun.COM return false; 145*9203SMark.Logan@Sun.COM } 146*9203SMark.Logan@Sun.COM } 147*9203SMark.Logan@Sun.COM 148*9203SMark.Logan@Sun.COM long bufSize = _lme.GetHeciBufferSize() - sizeof(APF_CHANNEL_DATA_MESSAGE); 149*9203SMark.Logan@Sun.COM if (bufSize > 0) { 150*9203SMark.Logan@Sun.COM _rxSocketBuffer = new char[bufSize]; 151*9203SMark.Logan@Sun.COM _rxSocketBufferSize = bufSize; 152*9203SMark.Logan@Sun.COM } else { 153*9203SMark.Logan@Sun.COM DeinitFull(); 154*9203SMark.Logan@Sun.COM return false; 155*9203SMark.Logan@Sun.COM } 156*9203SMark.Logan@Sun.COM 157*9203SMark.Logan@Sun.COM #ifdef _REMOTE_SUPPORT 158*9203SMark.Logan@Sun.COM if (!oldProtocolMode) { 159*9203SMark.Logan@Sun.COM _checkRemoteSupport(true); 160*9203SMark.Logan@Sun.COM } 161*9203SMark.Logan@Sun.COM #endif 162*9203SMark.Logan@Sun.COM return true; 163*9203SMark.Logan@Sun.COM } 164*9203SMark.Logan@Sun.COM 165*9203SMark.Logan@Sun.COM Channel *Protocol::_getSockOpenChannel(SOCKET s) 166*9203SMark.Logan@Sun.COM { 167*9203SMark.Logan@Sun.COM if (oldProtocolMode) { 168*9203SMark.Logan@Sun.COM ChannelMap::iterator it = _openChannels.begin(); 169*9203SMark.Logan@Sun.COM for (; it != _openChannels.end(); it++) { 170*9203SMark.Logan@Sun.COM if (it->second->GetSocket() == s) { 171*9203SMark.Logan@Sun.COM return it->second; 172*9203SMark.Logan@Sun.COM } 173*9203SMark.Logan@Sun.COM } 174*9203SMark.Logan@Sun.COM } else { 175*9203SMark.Logan@Sun.COM ChannelMap::iterator it = _openChannels.find(s); 176*9203SMark.Logan@Sun.COM if (it != _openChannels.end()) { 177*9203SMark.Logan@Sun.COM return it->second; 178*9203SMark.Logan@Sun.COM } 179*9203SMark.Logan@Sun.COM } 180*9203SMark.Logan@Sun.COM return NULL; 181*9203SMark.Logan@Sun.COM } 182*9203SMark.Logan@Sun.COM 183*9203SMark.Logan@Sun.COM bool Protocol::IsDeInitialized() 184*9203SMark.Logan@Sun.COM { 185*9203SMark.Logan@Sun.COM Lock dl(_deinitLock); 186*9203SMark.Logan@Sun.COM return _deinitReq; 187*9203SMark.Logan@Sun.COM } 188*9203SMark.Logan@Sun.COM 189*9203SMark.Logan@Sun.COM 190*9203SMark.Logan@Sun.COM bool Protocol::IsInitialized() 191*9203SMark.Logan@Sun.COM { 192*9203SMark.Logan@Sun.COM if (IsDeInitialized()) { 193*9203SMark.Logan@Sun.COM return false; 194*9203SMark.Logan@Sun.COM } 195*9203SMark.Logan@Sun.COM 196*9203SMark.Logan@Sun.COM return _lme.IsInitialized(); 197*9203SMark.Logan@Sun.COM } 198*9203SMark.Logan@Sun.COM 199*9203SMark.Logan@Sun.COM void Protocol::Deinit() 200*9203SMark.Logan@Sun.COM { 201*9203SMark.Logan@Sun.COM Lock dl(_deinitLock); 202*9203SMark.Logan@Sun.COM _deinitReq = true; 203*9203SMark.Logan@Sun.COM 204*9203SMark.Logan@Sun.COM ATNetworkTool::CloseSocket(_serverSignalSocket); 205*9203SMark.Logan@Sun.COM ATNetworkTool::CloseSocket(_clientSignalSocket); 206*9203SMark.Logan@Sun.COM 207*9203SMark.Logan@Sun.COM { 208*9203SMark.Logan@Sun.COM Lock l(_channelsLock); 209*9203SMark.Logan@Sun.COM 210*9203SMark.Logan@Sun.COM ChannelMap::iterator it = _openChannels.begin(); 211*9203SMark.Logan@Sun.COM 212*9203SMark.Logan@Sun.COM for (; it != _openChannels.end(); it++) { 213*9203SMark.Logan@Sun.COM ATNetworkTool::CloseSocket(it->second->GetSocket()); 214*9203SMark.Logan@Sun.COM delete it->second; 215*9203SMark.Logan@Sun.COM } 216*9203SMark.Logan@Sun.COM 217*9203SMark.Logan@Sun.COM _openChannels.clear(); 218*9203SMark.Logan@Sun.COM } 219*9203SMark.Logan@Sun.COM 220*9203SMark.Logan@Sun.COM { 221*9203SMark.Logan@Sun.COM Lock l(_portsLock); 222*9203SMark.Logan@Sun.COM PortMap::iterator it = _openPorts.begin(); 223*9203SMark.Logan@Sun.COM 224*9203SMark.Logan@Sun.COM for (; it != _openPorts.end(); it++) { 225*9203SMark.Logan@Sun.COM if (it->second.size() > 0) { 226*9203SMark.Logan@Sun.COM ATNetworkTool::CloseSocket(it->second[0]->GetListeningSocket()); 227*9203SMark.Logan@Sun.COM 228*9203SMark.Logan@Sun.COM PortForwardRequestList::iterator it2 = it->second.begin(); 229*9203SMark.Logan@Sun.COM for (; it2 != it->second.end(); it2++) { 230*9203SMark.Logan@Sun.COM delete *it2; 231*9203SMark.Logan@Sun.COM } 232*9203SMark.Logan@Sun.COM } 233*9203SMark.Logan@Sun.COM } 234*9203SMark.Logan@Sun.COM _openPorts.clear(); 235*9203SMark.Logan@Sun.COM } 236*9203SMark.Logan@Sun.COM 237*9203SMark.Logan@Sun.COM _lme.Deinit(); 238*9203SMark.Logan@Sun.COM 239*9203SMark.Logan@Sun.COM #ifdef _REMOTE_SUPPORT 240*9203SMark.Logan@Sun.COM if (!oldProtocolMode) { 241*9203SMark.Logan@Sun.COM _cfg.Deinit(); 242*9203SMark.Logan@Sun.COM } 243*9203SMark.Logan@Sun.COM #endif 244*9203SMark.Logan@Sun.COM 245*9203SMark.Logan@Sun.COM { 246*9203SMark.Logan@Sun.COM Lock vl(_versionLock); 247*9203SMark.Logan@Sun.COM _handshakingStatus = NOT_INITIATED; 248*9203SMark.Logan@Sun.COM _pfwdService = NOT_STARTED; 249*9203SMark.Logan@Sun.COM _AmtProtVersion.MajorVersion = 0; 250*9203SMark.Logan@Sun.COM _AmtProtVersion.MinorVersion = 0; 251*9203SMark.Logan@Sun.COM } 252*9203SMark.Logan@Sun.COM 253*9203SMark.Logan@Sun.COM } 254*9203SMark.Logan@Sun.COM 255*9203SMark.Logan@Sun.COM void Protocol::DeinitFull() 256*9203SMark.Logan@Sun.COM { 257*9203SMark.Logan@Sun.COM Deinit(); 258*9203SMark.Logan@Sun.COM 259*9203SMark.Logan@Sun.COM if (_rxSocketBuffer != NULL) { 260*9203SMark.Logan@Sun.COM delete []_rxSocketBuffer; 261*9203SMark.Logan@Sun.COM _rxSocketBuffer = NULL; 262*9203SMark.Logan@Sun.COM _rxSocketBufferSize = 0; 263*9203SMark.Logan@Sun.COM } 264*9203SMark.Logan@Sun.COM 265*9203SMark.Logan@Sun.COM _serverSignalSocket = INVALID_SOCKET; 266*9203SMark.Logan@Sun.COM _clientSignalSocket = INVALID_SOCKET; 267*9203SMark.Logan@Sun.COM _sockets_active = false; 268*9203SMark.Logan@Sun.COM 269*9203SMark.Logan@Sun.COM #ifdef _REMOTE_SUPPORT 270*9203SMark.Logan@Sun.COM _remoteAccessEnabled = false; 271*9203SMark.Logan@Sun.COM #endif 272*9203SMark.Logan@Sun.COM memset(_AMTFQDN, 0, sizeof(_AMTFQDN)); 273*9203SMark.Logan@Sun.COM } 274*9203SMark.Logan@Sun.COM 275*9203SMark.Logan@Sun.COM bool Protocol::_checkListen(std::string address, in_port_t port, int &socket) 276*9203SMark.Logan@Sun.COM { 277*9203SMark.Logan@Sun.COM bool exists = false; 278*9203SMark.Logan@Sun.COM 279*9203SMark.Logan@Sun.COM PortMap::iterator it = _openPorts.find(port); 280*9203SMark.Logan@Sun.COM if (it != _openPorts.end()) { 281*9203SMark.Logan@Sun.COM if (it->second.size() > 0) { 282*9203SMark.Logan@Sun.COM socket = it->second[0]->GetListeningSocket(); 283*9203SMark.Logan@Sun.COM PortForwardRequestList::iterator it2 = it->second.begin(); 284*9203SMark.Logan@Sun.COM 285*9203SMark.Logan@Sun.COM for (; it2 != it->second.end(); it2++) { 286*9203SMark.Logan@Sun.COM if (((*it2)->GetStatus() != PortForwardRequest::NOT_ACTIVE) && 287*9203SMark.Logan@Sun.COM ((*it2)->GetBindedAddress().compare(address) == 0)) { 288*9203SMark.Logan@Sun.COM exists = true; 289*9203SMark.Logan@Sun.COM break; 290*9203SMark.Logan@Sun.COM } 291*9203SMark.Logan@Sun.COM } 292*9203SMark.Logan@Sun.COM 293*9203SMark.Logan@Sun.COM } 294*9203SMark.Logan@Sun.COM } else { 295*9203SMark.Logan@Sun.COM PortForwardRequestList portForwardRequestList; 296*9203SMark.Logan@Sun.COM _openPorts[port] = portForwardRequestList; 297*9203SMark.Logan@Sun.COM } 298*9203SMark.Logan@Sun.COM 299*9203SMark.Logan@Sun.COM return exists; 300*9203SMark.Logan@Sun.COM } 301*9203SMark.Logan@Sun.COM 302*9203SMark.Logan@Sun.COM int Protocol::_listenPort(in_port_t port, int &error) 303*9203SMark.Logan@Sun.COM { 304*9203SMark.Logan@Sun.COM return ATNetworkTool::CreateServerSocket( 305*9203SMark.Logan@Sun.COM port, 306*9203SMark.Logan@Sun.COM error, 307*9203SMark.Logan@Sun.COM false, true, PF_INET); 308*9203SMark.Logan@Sun.COM } 309*9203SMark.Logan@Sun.COM 310*9203SMark.Logan@Sun.COM bool Protocol::_localListen(in_port_t port) 311*9203SMark.Logan@Sun.COM { 312*9203SMark.Logan@Sun.COM int error; 313*9203SMark.Logan@Sun.COM int socket = INVALID_SOCKET; 314*9203SMark.Logan@Sun.COM bool exists = _checkListen("127.0.0.1", port, socket); 315*9203SMark.Logan@Sun.COM 316*9203SMark.Logan@Sun.COM int serverSocket = _listenPort(port, error); 317*9203SMark.Logan@Sun.COM if (serverSocket == INVALID_SOCKET) { 318*9203SMark.Logan@Sun.COM PRINT("[Compat]LMS Service cannot listen at port %d.\n", (int)port); 319*9203SMark.Logan@Sun.COM if (exists) { 320*9203SMark.Logan@Sun.COM //already listening 321*9203SMark.Logan@Sun.COM } 322*9203SMark.Logan@Sun.COM return false; 323*9203SMark.Logan@Sun.COM } 324*9203SMark.Logan@Sun.COM PRINT("[Compat]Listening at port %d at local interface.\n", (int)port); 325*9203SMark.Logan@Sun.COM 326*9203SMark.Logan@Sun.COM PortForwardRequest *portForwardRequest = 327*9203SMark.Logan@Sun.COM new PortForwardRequest("127.0.0.1", port, 328*9203SMark.Logan@Sun.COM serverSocket, _isLocalCallback, true); 329*9203SMark.Logan@Sun.COM 330*9203SMark.Logan@Sun.COM _openPorts[port].push_back(portForwardRequest); 331*9203SMark.Logan@Sun.COM portForwardRequest->SetStatus(PortForwardRequest::LISTENING); 332*9203SMark.Logan@Sun.COM 333*9203SMark.Logan@Sun.COM return true; 334*9203SMark.Logan@Sun.COM } 335*9203SMark.Logan@Sun.COM 336*9203SMark.Logan@Sun.COM bool Protocol::CreateSockets() 337*9203SMark.Logan@Sun.COM { 338*9203SMark.Logan@Sun.COM int error; 339*9203SMark.Logan@Sun.COM _sockets_active = false; 340*9203SMark.Logan@Sun.COM 341*9203SMark.Logan@Sun.COM ATNetworkTool::CloseSocket(_serverSignalSocket); 342*9203SMark.Logan@Sun.COM _serverSignalSocket = ATNetworkTool::CreateServerSocket((in_port_t)0, error, true); 343*9203SMark.Logan@Sun.COM if (_serverSignalSocket == INVALID_SOCKET) { 344*9203SMark.Logan@Sun.COM return false; 345*9203SMark.Logan@Sun.COM } 346*9203SMark.Logan@Sun.COM 347*9203SMark.Logan@Sun.COM ATNetworkTool::CloseSocket(_clientSignalSocket); 348*9203SMark.Logan@Sun.COM _clientSignalSocket = ATNetworkTool::ConnectToSocket(_serverSignalSocket, error); 349*9203SMark.Logan@Sun.COM if (_clientSignalSocket == INVALID_SOCKET) { 350*9203SMark.Logan@Sun.COM ATNetworkTool::CloseSocket(_serverSignalSocket); 351*9203SMark.Logan@Sun.COM _serverSignalSocket = INVALID_SOCKET; 352*9203SMark.Logan@Sun.COM return false; 353*9203SMark.Logan@Sun.COM } 354*9203SMark.Logan@Sun.COM 355*9203SMark.Logan@Sun.COM struct sockaddr_storage addr; 356*9203SMark.Logan@Sun.COM socklen_t addrLen = sizeof(addr); 357*9203SMark.Logan@Sun.COM SOCKET s_new = accept(_serverSignalSocket, (struct sockaddr *)&addr, &addrLen); 358*9203SMark.Logan@Sun.COM if (s_new == INVALID_SOCKET) { 359*9203SMark.Logan@Sun.COM ATNetworkTool::CloseSocket(_serverSignalSocket); 360*9203SMark.Logan@Sun.COM ATNetworkTool::CloseSocket(_clientSignalSocket); 361*9203SMark.Logan@Sun.COM _serverSignalSocket = INVALID_SOCKET; 362*9203SMark.Logan@Sun.COM _clientSignalSocket = INVALID_SOCKET; 363*9203SMark.Logan@Sun.COM return false; 364*9203SMark.Logan@Sun.COM } 365*9203SMark.Logan@Sun.COM 366*9203SMark.Logan@Sun.COM ATNetworkTool::CloseSocket(_serverSignalSocket); 367*9203SMark.Logan@Sun.COM _serverSignalSocket = s_new; 368*9203SMark.Logan@Sun.COM 369*9203SMark.Logan@Sun.COM if (oldProtocolMode) { 370*9203SMark.Logan@Sun.COM if (!_localListen(16992)) { 371*9203SMark.Logan@Sun.COM return false; 372*9203SMark.Logan@Sun.COM } 373*9203SMark.Logan@Sun.COM if (!_localListen(16993)) { 374*9203SMark.Logan@Sun.COM return false; 375*9203SMark.Logan@Sun.COM } 376*9203SMark.Logan@Sun.COM } 377*9203SMark.Logan@Sun.COM 378*9203SMark.Logan@Sun.COM _sockets_active = true; 379*9203SMark.Logan@Sun.COM return true; 380*9203SMark.Logan@Sun.COM } 381*9203SMark.Logan@Sun.COM 382*9203SMark.Logan@Sun.COM void Protocol::DestroySockets() 383*9203SMark.Logan@Sun.COM { 384*9203SMark.Logan@Sun.COM _sockets_active = false; 385*9203SMark.Logan@Sun.COM 386*9203SMark.Logan@Sun.COM if (_serverSignalSocket != INVALID_SOCKET) { 387*9203SMark.Logan@Sun.COM ATNetworkTool::CloseSocket(_serverSignalSocket); 388*9203SMark.Logan@Sun.COM _serverSignalSocket = INVALID_SOCKET; 389*9203SMark.Logan@Sun.COM } 390*9203SMark.Logan@Sun.COM } 391*9203SMark.Logan@Sun.COM 392*9203SMark.Logan@Sun.COM bool Protocol::_acceptConnection(SOCKET s, unsigned int port) 393*9203SMark.Logan@Sun.COM { 394*9203SMark.Logan@Sun.COM ATAddress addr; 395*9203SMark.Logan@Sun.COM int error = 0; 396*9203SMark.Logan@Sun.COM char buf[NI_MAXHOST]; 397*9203SMark.Logan@Sun.COM 398*9203SMark.Logan@Sun.COM if (!IsInitialized()) { 399*9203SMark.Logan@Sun.COM return false; 400*9203SMark.Logan@Sun.COM } 401*9203SMark.Logan@Sun.COM 402*9203SMark.Logan@Sun.COM SOCKET s_new = ATNetworkTool::Accept(s, addr, error); 403*9203SMark.Logan@Sun.COM if (s_new == INVALID_SOCKET) { 404*9203SMark.Logan@Sun.COM #if DEBUGLOG 405*9203SMark.Logan@Sun.COM char *msg = _getErrMsg(error); 406*9203SMark.Logan@Sun.COM PRINT("Error accepting new connection (%d): %s\n", error, msg); 407*9203SMark.Logan@Sun.COM #endif 408*9203SMark.Logan@Sun.COM return false; 409*9203SMark.Logan@Sun.COM } 410*9203SMark.Logan@Sun.COM 411*9203SMark.Logan@Sun.COM const char *addrStr = addr.inNtoP(buf, NI_MAXHOST); 412*9203SMark.Logan@Sun.COM if (addrStr == NULL) { 413*9203SMark.Logan@Sun.COM PRINT("Error: ntop failed for new connection\n"); 414*9203SMark.Logan@Sun.COM ATNetworkTool::CloseSocket(s_new); 415*9203SMark.Logan@Sun.COM return false; 416*9203SMark.Logan@Sun.COM } 417*9203SMark.Logan@Sun.COM 418*9203SMark.Logan@Sun.COM PortForwardRequest *portForwardRequest = NULL; 419*9203SMark.Logan@Sun.COM 420*9203SMark.Logan@Sun.COM //_portsLock is already aquired by the calling function: Select(). 421*9203SMark.Logan@Sun.COM PortMap::iterator it = _openPorts.find(port); 422*9203SMark.Logan@Sun.COM if (it != _openPorts.end()) { 423*9203SMark.Logan@Sun.COM PortForwardRequestList::iterator it2 = it->second.begin(); 424*9203SMark.Logan@Sun.COM 425*9203SMark.Logan@Sun.COM for (; it2 != it->second.end(); it2++) { 426*9203SMark.Logan@Sun.COM if (((*it2)->GetStatus() == PortForwardRequest::LISTENING) && 427*9203SMark.Logan@Sun.COM (1 == (*it2)->IsConnectionPermitted(this, s_new))) { 428*9203SMark.Logan@Sun.COM portForwardRequest = *it2; 429*9203SMark.Logan@Sun.COM break; 430*9203SMark.Logan@Sun.COM } 431*9203SMark.Logan@Sun.COM } 432*9203SMark.Logan@Sun.COM 433*9203SMark.Logan@Sun.COM } 434*9203SMark.Logan@Sun.COM 435*9203SMark.Logan@Sun.COM if (portForwardRequest == NULL) { 436*9203SMark.Logan@Sun.COM PRINT("Error: new connection is denied (addr %s)\n", addrStr); 437*9203SMark.Logan@Sun.COM ATNetworkTool::CloseSocket(s_new); 438*9203SMark.Logan@Sun.COM return false; 439*9203SMark.Logan@Sun.COM } 440*9203SMark.Logan@Sun.COM 441*9203SMark.Logan@Sun.COM if (oldProtocolMode) { 442*9203SMark.Logan@Sun.COM unsigned int connId; 443*9203SMark.Logan@Sun.COM bool oret = _lme.CompatOpenConnection(port, addr, connId); 444*9203SMark.Logan@Sun.COM if (!oret) { 445*9203SMark.Logan@Sun.COM PRINT("[Compat]Error: failed to open new LME MEI connection\n"); 446*9203SMark.Logan@Sun.COM ATNetworkTool::CloseSocket(s_new); 447*9203SMark.Logan@Sun.COM return false; 448*9203SMark.Logan@Sun.COM } 449*9203SMark.Logan@Sun.COM PRINT("[Compat]Send open connection to LME. Sender %d.\n", (int)s_new); 450*9203SMark.Logan@Sun.COM 451*9203SMark.Logan@Sun.COM Channel *c = new Channel(portForwardRequest, s_new); 452*9203SMark.Logan@Sun.COM c->SetStatus(Channel::OPEN); 453*9203SMark.Logan@Sun.COM c->SetRecipientChannel(connId); 454*9203SMark.Logan@Sun.COM c->AddBytesTxWindow(1024); 455*9203SMark.Logan@Sun.COM 456*9203SMark.Logan@Sun.COM Lock l(_channelsLock); 457*9203SMark.Logan@Sun.COM _openChannels[connId] = c; 458*9203SMark.Logan@Sun.COM c->GetPortForwardRequest()->IncreaseChannelCount(); 459*9203SMark.Logan@Sun.COM } else { 460*9203SMark.Logan@Sun.COM Channel *c = new Channel(portForwardRequest, s_new); 461*9203SMark.Logan@Sun.COM c->SetStatus(Channel::NOT_OPENED); 462*9203SMark.Logan@Sun.COM 463*9203SMark.Logan@Sun.COM Lock l(_channelsLock); 464*9203SMark.Logan@Sun.COM _openChannels[s_new] = c; 465*9203SMark.Logan@Sun.COM c->GetPortForwardRequest()->IncreaseChannelCount(); 466*9203SMark.Logan@Sun.COM 467*9203SMark.Logan@Sun.COM _lme.ChannelOpenForwardedRequest((UINT32)s_new, 468*9203SMark.Logan@Sun.COM port, 469*9203SMark.Logan@Sun.COM ((portForwardRequest->IsLocal()) ? "127.0.0.1" : addrStr), 470*9203SMark.Logan@Sun.COM addr.inPort()); 471*9203SMark.Logan@Sun.COM PRINT("Send channel open request to LME. Sender %d.\n", (int)s_new); 472*9203SMark.Logan@Sun.COM } 473*9203SMark.Logan@Sun.COM 474*9203SMark.Logan@Sun.COM return true; 475*9203SMark.Logan@Sun.COM } 476*9203SMark.Logan@Sun.COM 477*9203SMark.Logan@Sun.COM int Protocol::Select() 478*9203SMark.Logan@Sun.COM { 479*9203SMark.Logan@Sun.COM fd_set rset; 480*9203SMark.Logan@Sun.COM struct timeval tv; 481*9203SMark.Logan@Sun.COM int res; 482*9203SMark.Logan@Sun.COM int fdCount = 0; 483*9203SMark.Logan@Sun.COM int fdMin = -1; 484*9203SMark.Logan@Sun.COM 485*9203SMark.Logan@Sun.COM tv.tv_sec = 1; 486*9203SMark.Logan@Sun.COM tv.tv_usec = 0; 487*9203SMark.Logan@Sun.COM 488*9203SMark.Logan@Sun.COM FD_ZERO(&rset); 489*9203SMark.Logan@Sun.COM 490*9203SMark.Logan@Sun.COM FD_SET(_serverSignalSocket, &rset); 491*9203SMark.Logan@Sun.COM if ((int)_serverSignalSocket > fdCount) { 492*9203SMark.Logan@Sun.COM fdCount = (int)_serverSignalSocket; 493*9203SMark.Logan@Sun.COM } 494*9203SMark.Logan@Sun.COM 495*9203SMark.Logan@Sun.COM { 496*9203SMark.Logan@Sun.COM Lock l(_portsLock); 497*9203SMark.Logan@Sun.COM PortMap::iterator it = _openPorts.begin(); 498*9203SMark.Logan@Sun.COM 499*9203SMark.Logan@Sun.COM for (; it != _openPorts.end(); it++) { 500*9203SMark.Logan@Sun.COM if (it->second.size() > 0) { 501*9203SMark.Logan@Sun.COM SOCKET serverSocket = it->second[0]->GetListeningSocket(); 502*9203SMark.Logan@Sun.COM FD_SET(serverSocket, &rset); 503*9203SMark.Logan@Sun.COM if ((int)serverSocket > fdCount) { 504*9203SMark.Logan@Sun.COM fdCount = (int)serverSocket; 505*9203SMark.Logan@Sun.COM } 506*9203SMark.Logan@Sun.COM } 507*9203SMark.Logan@Sun.COM } 508*9203SMark.Logan@Sun.COM } 509*9203SMark.Logan@Sun.COM 510*9203SMark.Logan@Sun.COM { 511*9203SMark.Logan@Sun.COM Lock l(_channelsLock); 512*9203SMark.Logan@Sun.COM 513*9203SMark.Logan@Sun.COM ChannelMap::iterator it = _openChannels.begin(); 514*9203SMark.Logan@Sun.COM 515*9203SMark.Logan@Sun.COM for (; it != _openChannels.end(); it++) { 516*9203SMark.Logan@Sun.COM if ((it->second->GetStatus() == Channel::OPEN) && 517*9203SMark.Logan@Sun.COM (it->second->GetTxWindow() > 0)) { 518*9203SMark.Logan@Sun.COM SOCKET socket = it->second->GetSocket(); 519*9203SMark.Logan@Sun.COM FD_SET(socket, &rset); 520*9203SMark.Logan@Sun.COM if ((int)socket > fdCount) { 521*9203SMark.Logan@Sun.COM fdCount = (int)socket; 522*9203SMark.Logan@Sun.COM } 523*9203SMark.Logan@Sun.COM if ((fdMin == -1) || ((int)socket < fdMin)) { 524*9203SMark.Logan@Sun.COM fdMin = (int)socket; 525*9203SMark.Logan@Sun.COM } 526*9203SMark.Logan@Sun.COM } 527*9203SMark.Logan@Sun.COM } 528*9203SMark.Logan@Sun.COM } 529*9203SMark.Logan@Sun.COM 530*9203SMark.Logan@Sun.COM fdCount++; 531*9203SMark.Logan@Sun.COM res = select(fdCount, &rset, NULL, NULL, &tv); 532*9203SMark.Logan@Sun.COM if (res == -1) { 533*9203SMark.Logan@Sun.COM #if DEBUGLOG 534*9203SMark.Logan@Sun.COM #if defined(__sun) || defined(_LINUX) 535*9203SMark.Logan@Sun.COM int err = errno; 536*9203SMark.Logan@Sun.COM #else 537*9203SMark.Logan@Sun.COM int err = GetLastError(); 538*9203SMark.Logan@Sun.COM #endif // __sun || _LINUX 539*9203SMark.Logan@Sun.COM 540*9203SMark.Logan@Sun.COM char *msg = _getErrMsg(err); 541*9203SMark.Logan@Sun.COM PRINT("Select error (%d): %s\n", err, msg); 542*9203SMark.Logan@Sun.COM #endif 543*9203SMark.Logan@Sun.COM return -1; 544*9203SMark.Logan@Sun.COM } 545*9203SMark.Logan@Sun.COM 546*9203SMark.Logan@Sun.COM if (res == 0) { 547*9203SMark.Logan@Sun.COM return 0; 548*9203SMark.Logan@Sun.COM } 549*9203SMark.Logan@Sun.COM 550*9203SMark.Logan@Sun.COM if (!IsInitialized()) { 551*9203SMark.Logan@Sun.COM return 0; 552*9203SMark.Logan@Sun.COM } 553*9203SMark.Logan@Sun.COM 554*9203SMark.Logan@Sun.COM if (FD_ISSET(_serverSignalSocket, &rset)) { // Received a 'signal' 555*9203SMark.Logan@Sun.COM char c = 0; 556*9203SMark.Logan@Sun.COM res = recv(_serverSignalSocket, &c, 1, 0); 557*9203SMark.Logan@Sun.COM FD_CLR(_serverSignalSocket, &rset); 558*9203SMark.Logan@Sun.COM res--; 559*9203SMark.Logan@Sun.COM } 560*9203SMark.Logan@Sun.COM 561*9203SMark.Logan@Sun.COM { 562*9203SMark.Logan@Sun.COM Lock l(_portsLock); 563*9203SMark.Logan@Sun.COM PortMap::iterator it = _openPorts.begin(); 564*9203SMark.Logan@Sun.COM 565*9203SMark.Logan@Sun.COM for (; it != _openPorts.end(); it++) { 566*9203SMark.Logan@Sun.COM if (it->second.size() > 0) { 567*9203SMark.Logan@Sun.COM SOCKET serverSocket = it->second[0]->GetListeningSocket(); 568*9203SMark.Logan@Sun.COM if (FD_ISSET(serverSocket, &rset)) { 569*9203SMark.Logan@Sun.COM // connection request 570*9203SMark.Logan@Sun.COM PRINT("Connection requested on port %d\n", it->first); 571*9203SMark.Logan@Sun.COM _acceptConnection(serverSocket, it->first); 572*9203SMark.Logan@Sun.COM FD_CLR(serverSocket, &rset); 573*9203SMark.Logan@Sun.COM res--; 574*9203SMark.Logan@Sun.COM } 575*9203SMark.Logan@Sun.COM } 576*9203SMark.Logan@Sun.COM } 577*9203SMark.Logan@Sun.COM } 578*9203SMark.Logan@Sun.COM 579*9203SMark.Logan@Sun.COM int i; 580*9203SMark.Logan@Sun.COM for (i = fdMin/*0*/; (res > 0) && (i < fdCount); i++) { 581*9203SMark.Logan@Sun.COM if (FD_ISSET(i, &rset)) { 582*9203SMark.Logan@Sun.COM _rxFromSocket(i); 583*9203SMark.Logan@Sun.COM res--; 584*9203SMark.Logan@Sun.COM } 585*9203SMark.Logan@Sun.COM } 586*9203SMark.Logan@Sun.COM 587*9203SMark.Logan@Sun.COM return 1; 588*9203SMark.Logan@Sun.COM } 589*9203SMark.Logan@Sun.COM 590*9203SMark.Logan@Sun.COM int Protocol::_rxFromSocket(SOCKET s) 591*9203SMark.Logan@Sun.COM { 592*9203SMark.Logan@Sun.COM Channel *c = NULL; 593*9203SMark.Logan@Sun.COM 594*9203SMark.Logan@Sun.COM if (!IsInitialized()) { 595*9203SMark.Logan@Sun.COM return 0; 596*9203SMark.Logan@Sun.COM } 597*9203SMark.Logan@Sun.COM 598*9203SMark.Logan@Sun.COM { 599*9203SMark.Logan@Sun.COM Lock l(_channelsLock); 600*9203SMark.Logan@Sun.COM 601*9203SMark.Logan@Sun.COM Channel *cx = _getSockOpenChannel(s); 602*9203SMark.Logan@Sun.COM 603*9203SMark.Logan@Sun.COM if (cx == NULL) { 604*9203SMark.Logan@Sun.COM // Data received from a socket that is not in the map. 605*9203SMark.Logan@Sun.COM // Since we only select on our sockets, this means it was 606*9203SMark.Logan@Sun.COM // in the map, but was removed, probably because we received 607*9203SMark.Logan@Sun.COM // an End Connection message from the HECI. 608*9203SMark.Logan@Sun.COM return 0; 609*9203SMark.Logan@Sun.COM } 610*9203SMark.Logan@Sun.COM 611*9203SMark.Logan@Sun.COM c = new Channel(*cx); 612*9203SMark.Logan@Sun.COM } 613*9203SMark.Logan@Sun.COM 614*9203SMark.Logan@Sun.COM int res = 0; 615*9203SMark.Logan@Sun.COM 616*9203SMark.Logan@Sun.COM int len = std::min(c->GetTxWindow(), _rxSocketBufferSize); 617*9203SMark.Logan@Sun.COM res = recv(s, _rxSocketBuffer, len, 0); 618*9203SMark.Logan@Sun.COM if (res > 0) { 619*9203SMark.Logan@Sun.COM // send data to LME 620*9203SMark.Logan@Sun.COM PRINT("Received %d bytes from socket %d. Sending to LME\n", res, (int)s); 621*9203SMark.Logan@Sun.COM if (oldProtocolMode) { 622*9203SMark.Logan@Sun.COM _lme.CompatSendMessage((UINT8)c->GetRecipientChannel(), res, (unsigned char *)_rxSocketBuffer); 623*9203SMark.Logan@Sun.COM } else { 624*9203SMark.Logan@Sun.COM _lme.ChannelData(c->GetRecipientChannel(), res, (unsigned char *)_rxSocketBuffer); 625*9203SMark.Logan@Sun.COM } 626*9203SMark.Logan@Sun.COM goto out; 627*9203SMark.Logan@Sun.COM } else if (res == 0) { 628*9203SMark.Logan@Sun.COM // connection closed 629*9203SMark.Logan@Sun.COM PRINT("Received 0 bytes from socket %d.\n", (int)s); 630*9203SMark.Logan@Sun.COM goto out; 631*9203SMark.Logan@Sun.COM } else { 632*9203SMark.Logan@Sun.COM #if DEBUGLOG 633*9203SMark.Logan@Sun.COM #if defined(__sun) || defined(_LINUX) 634*9203SMark.Logan@Sun.COM int err = errno; 635*9203SMark.Logan@Sun.COM #else 636*9203SMark.Logan@Sun.COM int err = GetLastError(); 637*9203SMark.Logan@Sun.COM #endif // __sun || _LINUX 638*9203SMark.Logan@Sun.COM 639*9203SMark.Logan@Sun.COM char *msg = _getErrMsg(err); 640*9203SMark.Logan@Sun.COM PRINT("Receive error on socket %d (%d): %s\n", (int)s, err, msg); 641*9203SMark.Logan@Sun.COM #endif 642*9203SMark.Logan@Sun.COM #ifdef __sun 643*9203SMark.Logan@Sun.COM ATNetworkTool::CloseSocket(s); 644*9203SMark.Logan@Sun.COM #endif 645*9203SMark.Logan@Sun.COM goto out; 646*9203SMark.Logan@Sun.COM } 647*9203SMark.Logan@Sun.COM 648*9203SMark.Logan@Sun.COM out: 649*9203SMark.Logan@Sun.COM { 650*9203SMark.Logan@Sun.COM Lock l(_channelsLock); 651*9203SMark.Logan@Sun.COM 652*9203SMark.Logan@Sun.COM Channel *cx = _getSockOpenChannel(s); 653*9203SMark.Logan@Sun.COM 654*9203SMark.Logan@Sun.COM if (cx == NULL) { 655*9203SMark.Logan@Sun.COM // Data received from a socket that is not in the map. 656*9203SMark.Logan@Sun.COM // Since we only select on our sockets, this means it was 657*9203SMark.Logan@Sun.COM // in the map, but was removed, probably because we received 658*9203SMark.Logan@Sun.COM // an End Connection message from the HECI. 659*9203SMark.Logan@Sun.COM delete c; 660*9203SMark.Logan@Sun.COM return 0; 661*9203SMark.Logan@Sun.COM } 662*9203SMark.Logan@Sun.COM if (res > 0) { 663*9203SMark.Logan@Sun.COM if (!oldProtocolMode) { 664*9203SMark.Logan@Sun.COM cx->AddBytesTxWindow(-res); 665*9203SMark.Logan@Sun.COM } 666*9203SMark.Logan@Sun.COM } 667*9203SMark.Logan@Sun.COM else { 668*9203SMark.Logan@Sun.COM cx->SetStatus(Channel::WAITING_CLOSE); 669*9203SMark.Logan@Sun.COM if (oldProtocolMode) { 670*9203SMark.Logan@Sun.COM if (res == 0) { 671*9203SMark.Logan@Sun.COM _closeMChannel(cx); 672*9203SMark.Logan@Sun.COM 673*9203SMark.Logan@Sun.COM ChannelMap::iterator it = _openChannels.begin(); 674*9203SMark.Logan@Sun.COM for (; it != _openChannels.end(); it++) { 675*9203SMark.Logan@Sun.COM if (it->second == cx) { 676*9203SMark.Logan@Sun.COM break; 677*9203SMark.Logan@Sun.COM } 678*9203SMark.Logan@Sun.COM } 679*9203SMark.Logan@Sun.COM if (it != _openChannels.end()) { 680*9203SMark.Logan@Sun.COM _openChannels.erase(it); 681*9203SMark.Logan@Sun.COM } 682*9203SMark.Logan@Sun.COM } 683*9203SMark.Logan@Sun.COM _lme.CompatCloseConnection(c->GetRecipientChannel(), 684*9203SMark.Logan@Sun.COM ((res == 0) ? LMS_CLOSE_STATUS_CLIENT : 685*9203SMark.Logan@Sun.COM LMS_CLOSE_STATUS_SOCKET)); 686*9203SMark.Logan@Sun.COM } else { 687*9203SMark.Logan@Sun.COM _lme.ChannelClose(c->GetRecipientChannel()); 688*9203SMark.Logan@Sun.COM } 689*9203SMark.Logan@Sun.COM } 690*9203SMark.Logan@Sun.COM } 691*9203SMark.Logan@Sun.COM delete c; 692*9203SMark.Logan@Sun.COM 693*9203SMark.Logan@Sun.COM return 0; 694*9203SMark.Logan@Sun.COM } 695*9203SMark.Logan@Sun.COM 696*9203SMark.Logan@Sun.COM void Protocol::_signalSelect() 697*9203SMark.Logan@Sun.COM { 698*9203SMark.Logan@Sun.COM int senderr = 0; 699*9203SMark.Logan@Sun.COM 700*9203SMark.Logan@Sun.COM _send(_clientSignalSocket, "s", 1, senderr); //Enforce a new execution of Select() 701*9203SMark.Logan@Sun.COM } 702*9203SMark.Logan@Sun.COM 703*9203SMark.Logan@Sun.COM void Protocol::_closePortForwardRequest(PortForwardRequest *p) 704*9203SMark.Logan@Sun.COM { 705*9203SMark.Logan@Sun.COM PortMap::iterator it = _openPorts.find(p->GetPort()); 706*9203SMark.Logan@Sun.COM if (it == _openPorts.end()) { 707*9203SMark.Logan@Sun.COM return; 708*9203SMark.Logan@Sun.COM } 709*9203SMark.Logan@Sun.COM 710*9203SMark.Logan@Sun.COM bool found = false; 711*9203SMark.Logan@Sun.COM PortForwardRequestList::iterator it2 = it->second.begin(); 712*9203SMark.Logan@Sun.COM for (; it2 != it->second.end(); it2++) { 713*9203SMark.Logan@Sun.COM if ((*it2) == p) { 714*9203SMark.Logan@Sun.COM found = true; 715*9203SMark.Logan@Sun.COM break; 716*9203SMark.Logan@Sun.COM } 717*9203SMark.Logan@Sun.COM } 718*9203SMark.Logan@Sun.COM 719*9203SMark.Logan@Sun.COM if ((*it2)->GetStatus() == PortForwardRequest::NOT_ACTIVE) { 720*9203SMark.Logan@Sun.COM 721*9203SMark.Logan@Sun.COM SOCKET serverSocket = (*it2)->GetListeningSocket(); 722*9203SMark.Logan@Sun.COM delete (*it2); 723*9203SMark.Logan@Sun.COM it->second.erase(it2); 724*9203SMark.Logan@Sun.COM 725*9203SMark.Logan@Sun.COM if (it->second.size() == 0) { 726*9203SMark.Logan@Sun.COM int res = ATNetworkTool::CloseSocket(serverSocket); 727*9203SMark.Logan@Sun.COM if (res != 0) { 728*9203SMark.Logan@Sun.COM int err; 729*9203SMark.Logan@Sun.COM 730*9203SMark.Logan@Sun.COM #if defined(__sun) || defined(_LINUX) 731*9203SMark.Logan@Sun.COM err = errno; 732*9203SMark.Logan@Sun.COM #else 733*9203SMark.Logan@Sun.COM err = WSAGetLastError() 734*9203SMark.Logan@Sun.COM #endif 735*9203SMark.Logan@Sun.COM PRINT("Error %d in closing server socket at port %d.\n", err, p->GetPort()); 736*9203SMark.Logan@Sun.COM } 737*9203SMark.Logan@Sun.COM _openPorts.erase(it); 738*9203SMark.Logan@Sun.COM } 739*9203SMark.Logan@Sun.COM } 740*9203SMark.Logan@Sun.COM } 741*9203SMark.Logan@Sun.COM 742*9203SMark.Logan@Sun.COM bool Protocol::_checkProtocolFlow(LMEMessage *message) 743*9203SMark.Logan@Sun.COM { 744*9203SMark.Logan@Sun.COM switch (message->MessageType) { 745*9203SMark.Logan@Sun.COM case APF_SERVICE_REQUEST: 746*9203SMark.Logan@Sun.COM case APF_USERAUTH_REQUEST: 747*9203SMark.Logan@Sun.COM { 748*9203SMark.Logan@Sun.COM Lock l(_versionLock); 749*9203SMark.Logan@Sun.COM if (_handshakingStatus != AGREED) { 750*9203SMark.Logan@Sun.COM _lme.Disconnect(APF_DISCONNECT_PROTOCOL_ERROR); 751*9203SMark.Logan@Sun.COM Deinit(); 752*9203SMark.Logan@Sun.COM return false; 753*9203SMark.Logan@Sun.COM } 754*9203SMark.Logan@Sun.COM return true; 755*9203SMark.Logan@Sun.COM } 756*9203SMark.Logan@Sun.COM break; 757*9203SMark.Logan@Sun.COM 758*9203SMark.Logan@Sun.COM case APF_GLOBAL_REQUEST: 759*9203SMark.Logan@Sun.COM case APF_CHANNEL_OPEN: 760*9203SMark.Logan@Sun.COM case APF_CHANNEL_OPEN_CONFIRMATION: 761*9203SMark.Logan@Sun.COM case APF_CHANNEL_OPEN_FAILURE: 762*9203SMark.Logan@Sun.COM case APF_CHANNEL_CLOSE: 763*9203SMark.Logan@Sun.COM case APF_CHANNEL_DATA: 764*9203SMark.Logan@Sun.COM case APF_CHANNEL_WINDOW_ADJUST: 765*9203SMark.Logan@Sun.COM { 766*9203SMark.Logan@Sun.COM Lock l(_versionLock); 767*9203SMark.Logan@Sun.COM if ((_handshakingStatus != AGREED) || (_pfwdService != STARTED)) { 768*9203SMark.Logan@Sun.COM _lme.Disconnect(APF_DISCONNECT_PROTOCOL_ERROR); 769*9203SMark.Logan@Sun.COM Deinit(); 770*9203SMark.Logan@Sun.COM return false; 771*9203SMark.Logan@Sun.COM } 772*9203SMark.Logan@Sun.COM return true; 773*9203SMark.Logan@Sun.COM } 774*9203SMark.Logan@Sun.COM break; 775*9203SMark.Logan@Sun.COM 776*9203SMark.Logan@Sun.COM case APF_DISCONNECT: 777*9203SMark.Logan@Sun.COM case APF_PROTOCOLVERSION: 778*9203SMark.Logan@Sun.COM return true; 779*9203SMark.Logan@Sun.COM break; 780*9203SMark.Logan@Sun.COM 781*9203SMark.Logan@Sun.COM default: 782*9203SMark.Logan@Sun.COM { 783*9203SMark.Logan@Sun.COM _lme.Disconnect(APF_DISCONNECT_PROTOCOL_ERROR); 784*9203SMark.Logan@Sun.COM Deinit(); 785*9203SMark.Logan@Sun.COM return false; 786*9203SMark.Logan@Sun.COM } 787*9203SMark.Logan@Sun.COM break; 788*9203SMark.Logan@Sun.COM } 789*9203SMark.Logan@Sun.COM 790*9203SMark.Logan@Sun.COM return false; 791*9203SMark.Logan@Sun.COM } 792*9203SMark.Logan@Sun.COM 793*9203SMark.Logan@Sun.COM unsigned int Protocol::_getMinMessageLen(LMEMessage *message) 794*9203SMark.Logan@Sun.COM { 795*9203SMark.Logan@Sun.COM switch (message->MessageType) { 796*9203SMark.Logan@Sun.COM case APF_SERVICE_REQUEST: 797*9203SMark.Logan@Sun.COM return sizeof(LMEServiceRequestMessage); 798*9203SMark.Logan@Sun.COM break; 799*9203SMark.Logan@Sun.COM case APF_USERAUTH_REQUEST: 800*9203SMark.Logan@Sun.COM return sizeof(LMEUserAuthRequestMessage); 801*9203SMark.Logan@Sun.COM break; 802*9203SMark.Logan@Sun.COM case APF_GLOBAL_REQUEST: 803*9203SMark.Logan@Sun.COM return sizeof(LMEGlobalRequestMessage); 804*9203SMark.Logan@Sun.COM break; 805*9203SMark.Logan@Sun.COM case APF_CHANNEL_OPEN: 806*9203SMark.Logan@Sun.COM return sizeof(LMEChannelOpenRequestMessage); 807*9203SMark.Logan@Sun.COM break; 808*9203SMark.Logan@Sun.COM case APF_CHANNEL_OPEN_CONFIRMATION: 809*9203SMark.Logan@Sun.COM return sizeof(LMEChannelOpenReplaySuccessMessage); 810*9203SMark.Logan@Sun.COM break; 811*9203SMark.Logan@Sun.COM case APF_CHANNEL_OPEN_FAILURE: 812*9203SMark.Logan@Sun.COM return sizeof(LMEChannelOpenReplayFailureMessage); 813*9203SMark.Logan@Sun.COM break; 814*9203SMark.Logan@Sun.COM case APF_CHANNEL_CLOSE: 815*9203SMark.Logan@Sun.COM return sizeof(LMEChannelCloseMessage); 816*9203SMark.Logan@Sun.COM break; 817*9203SMark.Logan@Sun.COM case APF_CHANNEL_DATA: 818*9203SMark.Logan@Sun.COM return sizeof(LMEChannelDataMessage); 819*9203SMark.Logan@Sun.COM break; 820*9203SMark.Logan@Sun.COM case APF_CHANNEL_WINDOW_ADJUST: 821*9203SMark.Logan@Sun.COM return sizeof(LMEChannelWindowAdjustMessage); 822*9203SMark.Logan@Sun.COM break; 823*9203SMark.Logan@Sun.COM case APF_DISCONNECT: 824*9203SMark.Logan@Sun.COM return sizeof(LMEDisconnectMessage); 825*9203SMark.Logan@Sun.COM break; 826*9203SMark.Logan@Sun.COM case APF_PROTOCOLVERSION: 827*9203SMark.Logan@Sun.COM return sizeof(LMEProtocolVersionMessage); 828*9203SMark.Logan@Sun.COM break; 829*9203SMark.Logan@Sun.COM default: 830*9203SMark.Logan@Sun.COM return 0; 831*9203SMark.Logan@Sun.COM } 832*9203SMark.Logan@Sun.COM 833*9203SMark.Logan@Sun.COM return 0; 834*9203SMark.Logan@Sun.COM } 835*9203SMark.Logan@Sun.COM 836*9203SMark.Logan@Sun.COM bool Protocol::_checkMessageAndProtocol(LMEMessage *message, unsigned int len) 837*9203SMark.Logan@Sun.COM { 838*9203SMark.Logan@Sun.COM if (len < sizeof(LMEMessage)) { 839*9203SMark.Logan@Sun.COM _lme.Disconnect(APF_DISCONNECT_PROTOCOL_ERROR); 840*9203SMark.Logan@Sun.COM Deinit(); 841*9203SMark.Logan@Sun.COM return false; 842*9203SMark.Logan@Sun.COM } 843*9203SMark.Logan@Sun.COM 844*9203SMark.Logan@Sun.COM if (!_checkProtocolFlow(message)) { 845*9203SMark.Logan@Sun.COM return false; 846*9203SMark.Logan@Sun.COM } 847*9203SMark.Logan@Sun.COM if (len < _getMinMessageLen(message)) { 848*9203SMark.Logan@Sun.COM _lme.Disconnect(APF_DISCONNECT_PROTOCOL_ERROR); 849*9203SMark.Logan@Sun.COM Deinit(); 850*9203SMark.Logan@Sun.COM return false; 851*9203SMark.Logan@Sun.COM } 852*9203SMark.Logan@Sun.COM return true; 853*9203SMark.Logan@Sun.COM } 854*9203SMark.Logan@Sun.COM 855*9203SMark.Logan@Sun.COM void Protocol::_LmeCallback(void *param, void *buffer, unsigned int len, int *status) 856*9203SMark.Logan@Sun.COM { 857*9203SMark.Logan@Sun.COM Protocol *prot = (Protocol *)param; 858*9203SMark.Logan@Sun.COM 859*9203SMark.Logan@Sun.COM if (prot->oldProtocolMode) { 860*9203SMark.Logan@Sun.COM prot->_LmeReceiveCompat((char *)buffer, len, status); 861*9203SMark.Logan@Sun.COM } else { 862*9203SMark.Logan@Sun.COM prot->_LmeReceive(buffer, len, status); 863*9203SMark.Logan@Sun.COM } 864*9203SMark.Logan@Sun.COM } 865*9203SMark.Logan@Sun.COM 866*9203SMark.Logan@Sun.COM void Protocol::_LmeReceive(void *buffer, unsigned int len, int *status) 867*9203SMark.Logan@Sun.COM { 868*9203SMark.Logan@Sun.COM LMEMessage *message = (LMEMessage *)buffer; 869*9203SMark.Logan@Sun.COM *status = 0; 870*9203SMark.Logan@Sun.COM 871*9203SMark.Logan@Sun.COM if (!_checkMessageAndProtocol(message, len)) { 872*9203SMark.Logan@Sun.COM return; 873*9203SMark.Logan@Sun.COM } 874*9203SMark.Logan@Sun.COM 875*9203SMark.Logan@Sun.COM switch (message->MessageType) { 876*9203SMark.Logan@Sun.COM case APF_DISCONNECT: 877*9203SMark.Logan@Sun.COM { 878*9203SMark.Logan@Sun.COM PRINT("LME requested to disconnect with reason code 0x%08x\n", 879*9203SMark.Logan@Sun.COM ((LMEDisconnectMessage *)message)->ReasonCode); 880*9203SMark.Logan@Sun.COM Deinit(); 881*9203SMark.Logan@Sun.COM return; 882*9203SMark.Logan@Sun.COM } 883*9203SMark.Logan@Sun.COM break; 884*9203SMark.Logan@Sun.COM 885*9203SMark.Logan@Sun.COM case APF_SERVICE_REQUEST: 886*9203SMark.Logan@Sun.COM { 887*9203SMark.Logan@Sun.COM LMEServiceRequestMessage *sRMsg = 888*9203SMark.Logan@Sun.COM (LMEServiceRequestMessage *)message; 889*9203SMark.Logan@Sun.COM 890*9203SMark.Logan@Sun.COM if ((sRMsg->ServiceName.compare(APF_SERVICE_AUTH) == 0) || 891*9203SMark.Logan@Sun.COM (sRMsg->ServiceName.compare(APF_SERVICE_PFWD) == 0)) { 892*9203SMark.Logan@Sun.COM 893*9203SMark.Logan@Sun.COM _lme.ServiceAccept(sRMsg->ServiceName); 894*9203SMark.Logan@Sun.COM PRINT("Accepting service: %s\n", 895*9203SMark.Logan@Sun.COM sRMsg->ServiceName.c_str()); 896*9203SMark.Logan@Sun.COM if (sRMsg->ServiceName.compare(APF_SERVICE_PFWD) == 0) { 897*9203SMark.Logan@Sun.COM Lock l(_versionLock); 898*9203SMark.Logan@Sun.COM _pfwdService = STARTED; 899*9203SMark.Logan@Sun.COM } 900*9203SMark.Logan@Sun.COM } else { 901*9203SMark.Logan@Sun.COM PRINT("Requesting to disconnect from LME with reason code 0x%08x\n", 902*9203SMark.Logan@Sun.COM APF_DISCONNECT_SERVICE_NOT_AVAILABLE); 903*9203SMark.Logan@Sun.COM _lme.Disconnect(APF_DISCONNECT_SERVICE_NOT_AVAILABLE); 904*9203SMark.Logan@Sun.COM Deinit(); 905*9203SMark.Logan@Sun.COM return; 906*9203SMark.Logan@Sun.COM } 907*9203SMark.Logan@Sun.COM } 908*9203SMark.Logan@Sun.COM break; 909*9203SMark.Logan@Sun.COM 910*9203SMark.Logan@Sun.COM case APF_USERAUTH_REQUEST: 911*9203SMark.Logan@Sun.COM { 912*9203SMark.Logan@Sun.COM PRINT("Sending Userauth success message\n"); 913*9203SMark.Logan@Sun.COM _lme.UserAuthSuccess(); 914*9203SMark.Logan@Sun.COM } 915*9203SMark.Logan@Sun.COM break; 916*9203SMark.Logan@Sun.COM 917*9203SMark.Logan@Sun.COM case APF_PROTOCOLVERSION: 918*9203SMark.Logan@Sun.COM _apfProtocolVersion((LMEProtocolVersionMessage *)message); 919*9203SMark.Logan@Sun.COM break; 920*9203SMark.Logan@Sun.COM 921*9203SMark.Logan@Sun.COM case APF_GLOBAL_REQUEST: 922*9203SMark.Logan@Sun.COM _apfGlobalRequest((LMEGlobalRequestMessage *)message, len, status); 923*9203SMark.Logan@Sun.COM break; 924*9203SMark.Logan@Sun.COM 925*9203SMark.Logan@Sun.COM case APF_CHANNEL_OPEN: 926*9203SMark.Logan@Sun.COM _apfChannelOpen((LMEChannelOpenRequestMessage *)message, status); 927*9203SMark.Logan@Sun.COM break; 928*9203SMark.Logan@Sun.COM 929*9203SMark.Logan@Sun.COM case APF_CHANNEL_OPEN_CONFIRMATION: 930*9203SMark.Logan@Sun.COM { 931*9203SMark.Logan@Sun.COM LMEChannelOpenReplaySuccessMessage *chOpenSuccMsg = 932*9203SMark.Logan@Sun.COM (LMEChannelOpenReplaySuccessMessage *)message; 933*9203SMark.Logan@Sun.COM 934*9203SMark.Logan@Sun.COM Lock l(_channelsLock); 935*9203SMark.Logan@Sun.COM 936*9203SMark.Logan@Sun.COM ChannelMap::iterator it = _openChannels.find(chOpenSuccMsg->RecipientChannel); 937*9203SMark.Logan@Sun.COM if (it != _openChannels.end()) { 938*9203SMark.Logan@Sun.COM it->second->SetStatus(Channel::OPEN); 939*9203SMark.Logan@Sun.COM it->second->SetRecipientChannel(chOpenSuccMsg->SenderChannel); 940*9203SMark.Logan@Sun.COM it->second->AddBytesTxWindow(chOpenSuccMsg->InitialWindow); 941*9203SMark.Logan@Sun.COM } 942*9203SMark.Logan@Sun.COM 943*9203SMark.Logan@Sun.COM _signalSelect(); 944*9203SMark.Logan@Sun.COM } 945*9203SMark.Logan@Sun.COM break; 946*9203SMark.Logan@Sun.COM 947*9203SMark.Logan@Sun.COM case APF_CHANNEL_OPEN_FAILURE: 948*9203SMark.Logan@Sun.COM { 949*9203SMark.Logan@Sun.COM PortForwardRequest *clPFwdReq = 950*9203SMark.Logan@Sun.COM _apfChannelOFail((LMEChannelOpenReplayFailureMessage *)message); 951*9203SMark.Logan@Sun.COM if (clPFwdReq != NULL) { 952*9203SMark.Logan@Sun.COM Lock l(_portsLock); 953*9203SMark.Logan@Sun.COM _closePortForwardRequest(clPFwdReq); 954*9203SMark.Logan@Sun.COM } 955*9203SMark.Logan@Sun.COM } 956*9203SMark.Logan@Sun.COM break; 957*9203SMark.Logan@Sun.COM 958*9203SMark.Logan@Sun.COM case APF_CHANNEL_CLOSE: 959*9203SMark.Logan@Sun.COM { 960*9203SMark.Logan@Sun.COM PortForwardRequest *clPFwdReq = 961*9203SMark.Logan@Sun.COM _apfChannelClose((LMEChannelCloseMessage *)message); 962*9203SMark.Logan@Sun.COM if (clPFwdReq != NULL) { 963*9203SMark.Logan@Sun.COM Lock l(_portsLock); 964*9203SMark.Logan@Sun.COM _closePortForwardRequest(clPFwdReq); 965*9203SMark.Logan@Sun.COM } 966*9203SMark.Logan@Sun.COM } 967*9203SMark.Logan@Sun.COM break; 968*9203SMark.Logan@Sun.COM 969*9203SMark.Logan@Sun.COM case APF_CHANNEL_DATA: 970*9203SMark.Logan@Sun.COM { 971*9203SMark.Logan@Sun.COM PortForwardRequest *clPFwdReq = 972*9203SMark.Logan@Sun.COM _apfChannelData((LMEChannelDataMessage *)message, status); 973*9203SMark.Logan@Sun.COM if (clPFwdReq != NULL) { 974*9203SMark.Logan@Sun.COM Lock l(_portsLock); 975*9203SMark.Logan@Sun.COM _closePortForwardRequest(clPFwdReq); 976*9203SMark.Logan@Sun.COM } 977*9203SMark.Logan@Sun.COM } 978*9203SMark.Logan@Sun.COM break; 979*9203SMark.Logan@Sun.COM 980*9203SMark.Logan@Sun.COM case APF_CHANNEL_WINDOW_ADJUST: 981*9203SMark.Logan@Sun.COM { 982*9203SMark.Logan@Sun.COM LMEChannelWindowAdjustMessage *channelWindowMessage = (LMEChannelWindowAdjustMessage *)message; 983*9203SMark.Logan@Sun.COM 984*9203SMark.Logan@Sun.COM Lock l(_channelsLock); 985*9203SMark.Logan@Sun.COM 986*9203SMark.Logan@Sun.COM ChannelMap::iterator it = _openChannels.find(channelWindowMessage->RecipientChannel); 987*9203SMark.Logan@Sun.COM if (it != _openChannels.end()) { 988*9203SMark.Logan@Sun.COM it->second->AddBytesTxWindow(channelWindowMessage->BytesToAdd); 989*9203SMark.Logan@Sun.COM _signalSelect(); 990*9203SMark.Logan@Sun.COM } 991*9203SMark.Logan@Sun.COM } 992*9203SMark.Logan@Sun.COM break; 993*9203SMark.Logan@Sun.COM 994*9203SMark.Logan@Sun.COM default: 995*9203SMark.Logan@Sun.COM _lme.Disconnect(APF_DISCONNECT_PROTOCOL_ERROR); 996*9203SMark.Logan@Sun.COM Deinit(); 997*9203SMark.Logan@Sun.COM break; 998*9203SMark.Logan@Sun.COM } 999*9203SMark.Logan@Sun.COM } 1000*9203SMark.Logan@Sun.COM 1001*9203SMark.Logan@Sun.COM unsigned int Protocol::_getMinGlobalMsgLen(LMEGlobalRequestMessage *globalMessage) 1002*9203SMark.Logan@Sun.COM { 1003*9203SMark.Logan@Sun.COM switch (globalMessage->RequestType) { 1004*9203SMark.Logan@Sun.COM case LMEGlobalRequestMessage::TCP_FORWARD_REQUEST: 1005*9203SMark.Logan@Sun.COM return sizeof(LMETcpForwardRequestMessage); 1006*9203SMark.Logan@Sun.COM break; 1007*9203SMark.Logan@Sun.COM case LMEGlobalRequestMessage::TCP_FORWARD_CANCEL_REQUEST: 1008*9203SMark.Logan@Sun.COM return sizeof(LMETcpForwardCancelRequestMessage); 1009*9203SMark.Logan@Sun.COM break; 1010*9203SMark.Logan@Sun.COM case LMEGlobalRequestMessage::UDP_SEND_TO: 1011*9203SMark.Logan@Sun.COM return sizeof(LMEUdpSendToMessage); 1012*9203SMark.Logan@Sun.COM break; 1013*9203SMark.Logan@Sun.COM default: 1014*9203SMark.Logan@Sun.COM return 0; 1015*9203SMark.Logan@Sun.COM } 1016*9203SMark.Logan@Sun.COM return 0; 1017*9203SMark.Logan@Sun.COM } 1018*9203SMark.Logan@Sun.COM 1019*9203SMark.Logan@Sun.COM void Protocol::_apfGlobalRequest(LMEGlobalRequestMessage *globalMessage, 1020*9203SMark.Logan@Sun.COM unsigned int len, int *status) 1021*9203SMark.Logan@Sun.COM { 1022*9203SMark.Logan@Sun.COM PRINT("Global Request type 0x%02x\n", globalMessage->RequestType); 1023*9203SMark.Logan@Sun.COM 1024*9203SMark.Logan@Sun.COM if (len < _getMinGlobalMsgLen(globalMessage)) { 1025*9203SMark.Logan@Sun.COM _lme.Disconnect(APF_DISCONNECT_PROTOCOL_ERROR); 1026*9203SMark.Logan@Sun.COM Deinit(); 1027*9203SMark.Logan@Sun.COM return; 1028*9203SMark.Logan@Sun.COM } 1029*9203SMark.Logan@Sun.COM 1030*9203SMark.Logan@Sun.COM switch (globalMessage->RequestType) { 1031*9203SMark.Logan@Sun.COM case LMEGlobalRequestMessage::TCP_FORWARD_REQUEST: 1032*9203SMark.Logan@Sun.COM _apfTcpForwardRequest((LMETcpForwardRequestMessage *)globalMessage, status); 1033*9203SMark.Logan@Sun.COM break; 1034*9203SMark.Logan@Sun.COM 1035*9203SMark.Logan@Sun.COM case LMEGlobalRequestMessage::TCP_FORWARD_CANCEL_REQUEST: 1036*9203SMark.Logan@Sun.COM _apfTcpForwardCancel((LMETcpForwardCancelRequestMessage *)globalMessage); 1037*9203SMark.Logan@Sun.COM break; 1038*9203SMark.Logan@Sun.COM 1039*9203SMark.Logan@Sun.COM case LMEGlobalRequestMessage::UDP_SEND_TO: 1040*9203SMark.Logan@Sun.COM _aptSendUdp((LMEUdpSendToMessage *)globalMessage, status); 1041*9203SMark.Logan@Sun.COM break; 1042*9203SMark.Logan@Sun.COM 1043*9203SMark.Logan@Sun.COM default: 1044*9203SMark.Logan@Sun.COM _lme.Disconnect(APF_DISCONNECT_PROTOCOL_ERROR); 1045*9203SMark.Logan@Sun.COM Deinit(); 1046*9203SMark.Logan@Sun.COM break; 1047*9203SMark.Logan@Sun.COM } 1048*9203SMark.Logan@Sun.COM } 1049*9203SMark.Logan@Sun.COM 1050*9203SMark.Logan@Sun.COM void Protocol::_apfTcpForwardRequest(LMETcpForwardRequestMessage *tcpFwdReqMsg, int *status) 1051*9203SMark.Logan@Sun.COM { 1052*9203SMark.Logan@Sun.COM IsConnectionPermittedCallback cb = NULL; 1053*9203SMark.Logan@Sun.COM bool failure = false; 1054*9203SMark.Logan@Sun.COM 1055*9203SMark.Logan@Sun.COM #ifdef _REMOTE_SUPPORT 1056*9203SMark.Logan@Sun.COM if (tcpFwdReqMsg->Address.compare("0.0.0.0") == 0) { 1057*9203SMark.Logan@Sun.COM cb = _isRemoteCallback; 1058*9203SMark.Logan@Sun.COM } 1059*9203SMark.Logan@Sun.COM else 1060*9203SMark.Logan@Sun.COM #endif 1061*9203SMark.Logan@Sun.COM { 1062*9203SMark.Logan@Sun.COM cb = _isLocalCallback; 1063*9203SMark.Logan@Sun.COM } 1064*9203SMark.Logan@Sun.COM 1065*9203SMark.Logan@Sun.COM { 1066*9203SMark.Logan@Sun.COM Lock l(_portsLock); 1067*9203SMark.Logan@Sun.COM SOCKET serverSocket = INVALID_SOCKET; 1068*9203SMark.Logan@Sun.COM listenPortSet::iterator lpi; 1069*9203SMark.Logan@Sun.COM 1070*9203SMark.Logan@Sun.COM if (_checkListen(tcpFwdReqMsg->Address, tcpFwdReqMsg->Port, serverSocket)) { 1071*9203SMark.Logan@Sun.COM *status = 1; 1072*9203SMark.Logan@Sun.COM // Log in Event Log 1073*9203SMark.Logan@Sun.COM TCHAR message[1024]; 1074*9203SMark.Logan@Sun.COM _stprintf_s(message, 1024, 1075*9203SMark.Logan@Sun.COM TEXT("LMS Service already accepted a request at %s:%d\n"), 1076*9203SMark.Logan@Sun.COM tcpFwdReqMsg->Address.c_str(), 1077*9203SMark.Logan@Sun.COM tcpFwdReqMsg->Port); 1078*9203SMark.Logan@Sun.COM _eventLog(_eventLogParam, message, EVENTLOG_ERROR_TYPE); 1079*9203SMark.Logan@Sun.COM PRINT(message); 1080*9203SMark.Logan@Sun.COM // Send Failure replay to LME 1081*9203SMark.Logan@Sun.COM _lme.TcpForwardReplyFailure(); 1082*9203SMark.Logan@Sun.COM return; 1083*9203SMark.Logan@Sun.COM } 1084*9203SMark.Logan@Sun.COM 1085*9203SMark.Logan@Sun.COM lpi = _listenFailReported.find(tcpFwdReqMsg->Port); 1086*9203SMark.Logan@Sun.COM 1087*9203SMark.Logan@Sun.COM if (serverSocket == INVALID_SOCKET) { 1088*9203SMark.Logan@Sun.COM int error; 1089*9203SMark.Logan@Sun.COM serverSocket = _listenPort(tcpFwdReqMsg->Port, error); 1090*9203SMark.Logan@Sun.COM if (serverSocket == INVALID_SOCKET) { 1091*9203SMark.Logan@Sun.COM *status = 1; 1092*9203SMark.Logan@Sun.COM // Log in Event Log 1093*9203SMark.Logan@Sun.COM TCHAR message[1024]; 1094*9203SMark.Logan@Sun.COM _stprintf_s(message, 1024, 1095*9203SMark.Logan@Sun.COM TEXT("LMS Service cannot listen at port %d.\n"), 1096*9203SMark.Logan@Sun.COM tcpFwdReqMsg->Port); 1097*9203SMark.Logan@Sun.COM if (lpi == _listenFailReported.end()) { 1098*9203SMark.Logan@Sun.COM _eventLog(_eventLogParam, message, EVENTLOG_ERROR_TYPE); 1099*9203SMark.Logan@Sun.COM _listenFailReported.insert(tcpFwdReqMsg->Port); 1100*9203SMark.Logan@Sun.COM } 1101*9203SMark.Logan@Sun.COM PRINT(message); 1102*9203SMark.Logan@Sun.COM // Send Failure replay to LME 1103*9203SMark.Logan@Sun.COM _lme.TcpForwardReplyFailure(); 1104*9203SMark.Logan@Sun.COM failure = true; 1105*9203SMark.Logan@Sun.COM } 1106*9203SMark.Logan@Sun.COM } 1107*9203SMark.Logan@Sun.COM 1108*9203SMark.Logan@Sun.COM if (failure != true) { 1109*9203SMark.Logan@Sun.COM PRINT("Listening at port %d at %s interface.\n", 1110*9203SMark.Logan@Sun.COM tcpFwdReqMsg->Port, 1111*9203SMark.Logan@Sun.COM ((cb == _isLocalCallback) ? "local" : "remote")); 1112*9203SMark.Logan@Sun.COM 1113*9203SMark.Logan@Sun.COM PortForwardRequest *portForwardRequest = 1114*9203SMark.Logan@Sun.COM new PortForwardRequest(tcpFwdReqMsg->Address, 1115*9203SMark.Logan@Sun.COM tcpFwdReqMsg->Port, 1116*9203SMark.Logan@Sun.COM serverSocket, cb, (cb == _isLocalCallback)); 1117*9203SMark.Logan@Sun.COM 1118*9203SMark.Logan@Sun.COM _openPorts[tcpFwdReqMsg->Port].push_back(portForwardRequest); 1119*9203SMark.Logan@Sun.COM 1120*9203SMark.Logan@Sun.COM // Send Success replay to LME 1121*9203SMark.Logan@Sun.COM _lme.TcpForwardReplySuccess(tcpFwdReqMsg->Port); 1122*9203SMark.Logan@Sun.COM 1123*9203SMark.Logan@Sun.COM portForwardRequest->SetStatus( 1124*9203SMark.Logan@Sun.COM (cb == _isLocalCallback) ? 1125*9203SMark.Logan@Sun.COM PortForwardRequest::LISTENING : 1126*9203SMark.Logan@Sun.COM PortForwardRequest::PENDING_REQUEST); 1127*9203SMark.Logan@Sun.COM if (lpi != _listenFailReported.end()) { 1128*9203SMark.Logan@Sun.COM _listenFailReported.erase(lpi); 1129*9203SMark.Logan@Sun.COM } 1130*9203SMark.Logan@Sun.COM 1131*9203SMark.Logan@Sun.COM _signalSelect(); 1132*9203SMark.Logan@Sun.COM } 1133*9203SMark.Logan@Sun.COM } 1134*9203SMark.Logan@Sun.COM 1135*9203SMark.Logan@Sun.COM if (failure == true) { 1136*9203SMark.Logan@Sun.COM _lme.Disconnect(APF_DISCONNECT_PROTOCOL_ERROR); 1137*9203SMark.Logan@Sun.COM Deinit(); 1138*9203SMark.Logan@Sun.COM return; 1139*9203SMark.Logan@Sun.COM } 1140*9203SMark.Logan@Sun.COM 1141*9203SMark.Logan@Sun.COM if (cb == _isLocalCallback) { 1142*9203SMark.Logan@Sun.COM if (_listenFailReported.empty()) { 1143*9203SMark.Logan@Sun.COM _updateIPFQDN(tcpFwdReqMsg->Address.c_str()); 1144*9203SMark.Logan@Sun.COM } 1145*9203SMark.Logan@Sun.COM } 1146*9203SMark.Logan@Sun.COM #ifdef _REMOTE_SUPPORT 1147*9203SMark.Logan@Sun.COM else { 1148*9203SMark.Logan@Sun.COM _checkRemoteSupport(true); 1149*9203SMark.Logan@Sun.COM } 1150*9203SMark.Logan@Sun.COM #endif 1151*9203SMark.Logan@Sun.COM } 1152*9203SMark.Logan@Sun.COM 1153*9203SMark.Logan@Sun.COM void Protocol::_apfTcpForwardCancel(LMETcpForwardCancelRequestMessage *tcpFwdCnclMsg) 1154*9203SMark.Logan@Sun.COM { 1155*9203SMark.Logan@Sun.COM bool found = false; 1156*9203SMark.Logan@Sun.COM Lock l(_portsLock); 1157*9203SMark.Logan@Sun.COM 1158*9203SMark.Logan@Sun.COM PortMap::iterator it = _openPorts.find(tcpFwdCnclMsg->Port); 1159*9203SMark.Logan@Sun.COM if (it == _openPorts.end()) { 1160*9203SMark.Logan@Sun.COM PRINT("Previous request on address %s and port %d doesn't exist.\n", 1161*9203SMark.Logan@Sun.COM tcpFwdCnclMsg->Address.c_str(), tcpFwdCnclMsg->Port); 1162*9203SMark.Logan@Sun.COM _lme.TcpForwardCancelReplyFailure(); 1163*9203SMark.Logan@Sun.COM return; 1164*9203SMark.Logan@Sun.COM } 1165*9203SMark.Logan@Sun.COM 1166*9203SMark.Logan@Sun.COM PortForwardRequestList::iterator it2 = it->second.begin(); 1167*9203SMark.Logan@Sun.COM for (; it2 != it->second.end(); it2++) { 1168*9203SMark.Logan@Sun.COM if (((*it2)->GetBindedAddress().compare(tcpFwdCnclMsg->Address) == 0) && 1169*9203SMark.Logan@Sun.COM //((*it2)->GetPort() == tcpFwdCnclMsg->Port)) { 1170*9203SMark.Logan@Sun.COM ((*it2)->GetStatus() != PortForwardRequest::NOT_ACTIVE)) { 1171*9203SMark.Logan@Sun.COM found = true; 1172*9203SMark.Logan@Sun.COM break; 1173*9203SMark.Logan@Sun.COM } 1174*9203SMark.Logan@Sun.COM } 1175*9203SMark.Logan@Sun.COM 1176*9203SMark.Logan@Sun.COM if (found) { 1177*9203SMark.Logan@Sun.COM (*it2)->SetStatus(PortForwardRequest::NOT_ACTIVE); 1178*9203SMark.Logan@Sun.COM if ((*it2)->GetChannelCount() == 0) { 1179*9203SMark.Logan@Sun.COM _closePortForwardRequest(*it2); 1180*9203SMark.Logan@Sun.COM } 1181*9203SMark.Logan@Sun.COM _lme.TcpForwardCancelReplySuccess(); 1182*9203SMark.Logan@Sun.COM } else { 1183*9203SMark.Logan@Sun.COM PRINT("Previous request on address %s and port %d doesn't exist.\n", 1184*9203SMark.Logan@Sun.COM tcpFwdCnclMsg->Address.c_str(), tcpFwdCnclMsg->Port); 1185*9203SMark.Logan@Sun.COM _lme.TcpForwardCancelReplyFailure(); 1186*9203SMark.Logan@Sun.COM } 1187*9203SMark.Logan@Sun.COM } 1188*9203SMark.Logan@Sun.COM 1189*9203SMark.Logan@Sun.COM void Protocol::_aptSendUdp(LMEUdpSendToMessage *udpSendToMessage, int *status) 1190*9203SMark.Logan@Sun.COM { 1191*9203SMark.Logan@Sun.COM int error = 0; 1192*9203SMark.Logan@Sun.COM 1193*9203SMark.Logan@Sun.COM SOCKET s = ATNetworkTool::Connect(udpSendToMessage->Address.c_str(), 1194*9203SMark.Logan@Sun.COM udpSendToMessage->Port, error, 1195*9203SMark.Logan@Sun.COM PF_INET, SOCK_DGRAM); 1196*9203SMark.Logan@Sun.COM if (s == INVALID_SOCKET) { 1197*9203SMark.Logan@Sun.COM *status = 1; 1198*9203SMark.Logan@Sun.COM PRINT("Unable to send UDP data.\n"); 1199*9203SMark.Logan@Sun.COM return; 1200*9203SMark.Logan@Sun.COM } 1201*9203SMark.Logan@Sun.COM 1202*9203SMark.Logan@Sun.COM int count = _send(s, (char *)udpSendToMessage->Data, udpSendToMessage->DataLength, error); 1203*9203SMark.Logan@Sun.COM PRINT("Sent UDP data: %d bytes of %d.\n", count, udpSendToMessage->DataLength); 1204*9203SMark.Logan@Sun.COM 1205*9203SMark.Logan@Sun.COM ATNetworkTool::CloseSocket(s); 1206*9203SMark.Logan@Sun.COM } 1207*9203SMark.Logan@Sun.COM 1208*9203SMark.Logan@Sun.COM void Protocol::_apfProtocolVersion(LMEProtocolVersionMessage *verMsg) 1209*9203SMark.Logan@Sun.COM { 1210*9203SMark.Logan@Sun.COM Lock l(_versionLock); 1211*9203SMark.Logan@Sun.COM 1212*9203SMark.Logan@Sun.COM switch (_handshakingStatus) { 1213*9203SMark.Logan@Sun.COM case AGREED: 1214*9203SMark.Logan@Sun.COM case NOT_INITIATED: 1215*9203SMark.Logan@Sun.COM _lme.ProtocolVersion(MAX_PROT_VERSION); 1216*9203SMark.Logan@Sun.COM case INITIATED: 1217*9203SMark.Logan@Sun.COM if (*verMsg < MIN_PROT_VERSION) { 1218*9203SMark.Logan@Sun.COM PRINT("Version %d.%d is not supported.\n", 1219*9203SMark.Logan@Sun.COM verMsg->MajorVersion, verMsg->MinorVersion); 1220*9203SMark.Logan@Sun.COM _lme.Disconnect(APF_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED); 1221*9203SMark.Logan@Sun.COM Deinit(); 1222*9203SMark.Logan@Sun.COM return; 1223*9203SMark.Logan@Sun.COM } 1224*9203SMark.Logan@Sun.COM if (*verMsg > MAX_PROT_VERSION) { 1225*9203SMark.Logan@Sun.COM _AmtProtVersion = MAX_PROT_VERSION; 1226*9203SMark.Logan@Sun.COM } else { 1227*9203SMark.Logan@Sun.COM _AmtProtVersion = (*verMsg); 1228*9203SMark.Logan@Sun.COM } 1229*9203SMark.Logan@Sun.COM _handshakingStatus = AGREED; 1230*9203SMark.Logan@Sun.COM break; 1231*9203SMark.Logan@Sun.COM 1232*9203SMark.Logan@Sun.COM default: 1233*9203SMark.Logan@Sun.COM _lme.Disconnect(APF_DISCONNECT_BY_APPLICATION); 1234*9203SMark.Logan@Sun.COM Deinit(); 1235*9203SMark.Logan@Sun.COM break; 1236*9203SMark.Logan@Sun.COM } 1237*9203SMark.Logan@Sun.COM } 1238*9203SMark.Logan@Sun.COM 1239*9203SMark.Logan@Sun.COM void Protocol::_apfChannelOpen(LMEChannelOpenRequestMessage *chOpenMsg, int *status) 1240*9203SMark.Logan@Sun.COM { 1241*9203SMark.Logan@Sun.COM int error = 0; 1242*9203SMark.Logan@Sun.COM 1243*9203SMark.Logan@Sun.COM PRINT("Got channel request from AMT. " 1244*9203SMark.Logan@Sun.COM " Recipient channel %d for address %s, port %d.\n", 1245*9203SMark.Logan@Sun.COM chOpenMsg->SenderChannel, 1246*9203SMark.Logan@Sun.COM chOpenMsg->Address.c_str(), chOpenMsg->Port); 1247*9203SMark.Logan@Sun.COM 1248*9203SMark.Logan@Sun.COM SOCKET s = ATNetworkTool::Connect(chOpenMsg->Address.c_str(), 1249*9203SMark.Logan@Sun.COM chOpenMsg->Port, error, PF_INET); 1250*9203SMark.Logan@Sun.COM if (s == INVALID_SOCKET) { 1251*9203SMark.Logan@Sun.COM *status = 1; 1252*9203SMark.Logan@Sun.COM PRINT("Unable to open direct channel to address %s.\n", 1253*9203SMark.Logan@Sun.COM chOpenMsg->Address.c_str()); 1254*9203SMark.Logan@Sun.COM return; 1255*9203SMark.Logan@Sun.COM } 1256*9203SMark.Logan@Sun.COM 1257*9203SMark.Logan@Sun.COM ATNetworkTool::SetNonBlocking(s); 1258*9203SMark.Logan@Sun.COM 1259*9203SMark.Logan@Sun.COM Channel *c = new Channel(NULL, s); 1260*9203SMark.Logan@Sun.COM c->AddBytesTxWindow(chOpenMsg->InitialWindow); 1261*9203SMark.Logan@Sun.COM c->SetRecipientChannel(chOpenMsg->SenderChannel); 1262*9203SMark.Logan@Sun.COM c->SetStatus(Channel::OPEN); 1263*9203SMark.Logan@Sun.COM 1264*9203SMark.Logan@Sun.COM { 1265*9203SMark.Logan@Sun.COM Lock l(_channelsLock); 1266*9203SMark.Logan@Sun.COM _openChannels[c->GetSenderChannel()] = c; 1267*9203SMark.Logan@Sun.COM _lme.ChannelOpenReplaySuccess(c->GetRecipientChannel(), c->GetSenderChannel()); 1268*9203SMark.Logan@Sun.COM } 1269*9203SMark.Logan@Sun.COM 1270*9203SMark.Logan@Sun.COM _signalSelect(); 1271*9203SMark.Logan@Sun.COM } 1272*9203SMark.Logan@Sun.COM 1273*9203SMark.Logan@Sun.COM PortForwardRequest *Protocol::_closeMChannel(Channel *c) 1274*9203SMark.Logan@Sun.COM { 1275*9203SMark.Logan@Sun.COM PortForwardRequest *clPFwdReq = NULL; 1276*9203SMark.Logan@Sun.COM 1277*9203SMark.Logan@Sun.COM ATNetworkTool::CloseSocket(c->GetSocket()); 1278*9203SMark.Logan@Sun.COM PortForwardRequest *p = c->GetPortForwardRequest(); 1279*9203SMark.Logan@Sun.COM if ((p != NULL) && (p->DecreaseChannelCount() == 0)) { 1280*9203SMark.Logan@Sun.COM clPFwdReq = p; 1281*9203SMark.Logan@Sun.COM } 1282*9203SMark.Logan@Sun.COM delete c; 1283*9203SMark.Logan@Sun.COM 1284*9203SMark.Logan@Sun.COM return clPFwdReq; 1285*9203SMark.Logan@Sun.COM } 1286*9203SMark.Logan@Sun.COM 1287*9203SMark.Logan@Sun.COM PortForwardRequest *Protocol::_apfChannelOFail(LMEChannelOpenReplayFailureMessage *chFailMsg) 1288*9203SMark.Logan@Sun.COM { 1289*9203SMark.Logan@Sun.COM PortForwardRequest *clPFwdReq = NULL; 1290*9203SMark.Logan@Sun.COM 1291*9203SMark.Logan@Sun.COM Lock l(_channelsLock); 1292*9203SMark.Logan@Sun.COM 1293*9203SMark.Logan@Sun.COM ChannelMap::iterator it = _openChannels.find(chFailMsg->RecipientChannel); 1294*9203SMark.Logan@Sun.COM if (it != _openChannels.end()) { 1295*9203SMark.Logan@Sun.COM clPFwdReq = _closeMChannel(it->second); 1296*9203SMark.Logan@Sun.COM _openChannels.erase(it); 1297*9203SMark.Logan@Sun.COM PRINT("Channel open request was refused. Reason code: 0x%02x reason.\n", 1298*9203SMark.Logan@Sun.COM chFailMsg->ReasonCode); 1299*9203SMark.Logan@Sun.COM } 1300*9203SMark.Logan@Sun.COM 1301*9203SMark.Logan@Sun.COM return clPFwdReq; 1302*9203SMark.Logan@Sun.COM } 1303*9203SMark.Logan@Sun.COM 1304*9203SMark.Logan@Sun.COM PortForwardRequest *Protocol::_apfChannelClose(LMEChannelCloseMessage *chClMsg) 1305*9203SMark.Logan@Sun.COM { 1306*9203SMark.Logan@Sun.COM PortForwardRequest *clPFwdReq = NULL; 1307*9203SMark.Logan@Sun.COM 1308*9203SMark.Logan@Sun.COM Lock l(_channelsLock); 1309*9203SMark.Logan@Sun.COM 1310*9203SMark.Logan@Sun.COM ChannelMap::iterator it = _openChannels.find(chClMsg->RecipientChannel); 1311*9203SMark.Logan@Sun.COM if (it != _openChannels.end()) { 1312*9203SMark.Logan@Sun.COM Channel *c = it->second; 1313*9203SMark.Logan@Sun.COM switch(c->GetStatus()) { 1314*9203SMark.Logan@Sun.COM case Channel::OPEN: 1315*9203SMark.Logan@Sun.COM c->SetStatus(Channel::CLOSED); 1316*9203SMark.Logan@Sun.COM _lme.ChannelClose(c->GetRecipientChannel()); 1317*9203SMark.Logan@Sun.COM PRINT("Channel %d was closed by AMT.\n", c->GetSenderChannel()); 1318*9203SMark.Logan@Sun.COM break; 1319*9203SMark.Logan@Sun.COM 1320*9203SMark.Logan@Sun.COM case Channel::WAITING_CLOSE: 1321*9203SMark.Logan@Sun.COM PRINT("Received reply by AMT on closing channel %d.\n", c->GetSenderChannel()); 1322*9203SMark.Logan@Sun.COM break; 1323*9203SMark.Logan@Sun.COM 1324*9203SMark.Logan@Sun.COM case Channel::CLOSED: 1325*9203SMark.Logan@Sun.COM case Channel::NOT_OPENED: 1326*9203SMark.Logan@Sun.COM break; 1327*9203SMark.Logan@Sun.COM } 1328*9203SMark.Logan@Sun.COM 1329*9203SMark.Logan@Sun.COM clPFwdReq = _closeMChannel(c); 1330*9203SMark.Logan@Sun.COM _openChannels.erase(it); 1331*9203SMark.Logan@Sun.COM } 1332*9203SMark.Logan@Sun.COM 1333*9203SMark.Logan@Sun.COM return clPFwdReq; 1334*9203SMark.Logan@Sun.COM } 1335*9203SMark.Logan@Sun.COM 1336*9203SMark.Logan@Sun.COM PortForwardRequest *Protocol::_apfChannelData(LMEChannelDataMessage *chDMsg, int *status) 1337*9203SMark.Logan@Sun.COM { 1338*9203SMark.Logan@Sun.COM PortForwardRequest *clPFwdReq = NULL; 1339*9203SMark.Logan@Sun.COM 1340*9203SMark.Logan@Sun.COM do { 1341*9203SMark.Logan@Sun.COM Lock l(_channelsLock); 1342*9203SMark.Logan@Sun.COM 1343*9203SMark.Logan@Sun.COM ChannelMap::iterator it = _openChannels.find(chDMsg->RecipientChannel); 1344*9203SMark.Logan@Sun.COM if (it == _openChannels.end()) { 1345*9203SMark.Logan@Sun.COM break; 1346*9203SMark.Logan@Sun.COM } 1347*9203SMark.Logan@Sun.COM 1348*9203SMark.Logan@Sun.COM if ((it->second->GetStatus() != Channel::OPEN) && 1349*9203SMark.Logan@Sun.COM (it->second->GetStatus() != Channel::WAITING_CLOSE)) { 1350*9203SMark.Logan@Sun.COM break; 1351*9203SMark.Logan@Sun.COM } 1352*9203SMark.Logan@Sun.COM 1353*9203SMark.Logan@Sun.COM if (it->second->GetRxWindow() < chDMsg->DataLength) { 1354*9203SMark.Logan@Sun.COM break; 1355*9203SMark.Logan@Sun.COM } 1356*9203SMark.Logan@Sun.COM 1357*9203SMark.Logan@Sun.COM int senderr = 0; 1358*9203SMark.Logan@Sun.COM int count = _send(it->second->GetSocket(), (char *)chDMsg->Data, 1359*9203SMark.Logan@Sun.COM chDMsg->DataLength, senderr); 1360*9203SMark.Logan@Sun.COM PRINT("Sent %d bytes of %d from AMT to channel %d with socket %d.\n", 1361*9203SMark.Logan@Sun.COM count, chDMsg->DataLength, chDMsg->RecipientChannel, 1362*9203SMark.Logan@Sun.COM it->second->GetSocket()); 1363*9203SMark.Logan@Sun.COM 1364*9203SMark.Logan@Sun.COM if ((count == -1) && (senderr == EPIPE)) { 1365*9203SMark.Logan@Sun.COM *status = 1; 1366*9203SMark.Logan@Sun.COM clPFwdReq = _closeMChannel(it->second); 1367*9203SMark.Logan@Sun.COM _openChannels.erase(it); 1368*9203SMark.Logan@Sun.COM PRINT("Channel send data request was refused. Broken pipe.\n"); 1369*9203SMark.Logan@Sun.COM break; 1370*9203SMark.Logan@Sun.COM } 1371*9203SMark.Logan@Sun.COM //it->second->AddBytesRxWindow(-count); 1372*9203SMark.Logan@Sun.COM //if (it->second->GetRxWindow() < Channel::LMS_WINDOW_SIZE / 2) { 1373*9203SMark.Logan@Sun.COM _lme.ChannelWindowAdjust(it->second->GetRecipientChannel(), chDMsg->DataLength); 1374*9203SMark.Logan@Sun.COM //Channel::LMS_WINDOW_SIZE - it->second->GetRxWindow()); 1375*9203SMark.Logan@Sun.COM //} 1376*9203SMark.Logan@Sun.COM } while (0); 1377*9203SMark.Logan@Sun.COM 1378*9203SMark.Logan@Sun.COM return clPFwdReq; 1379*9203SMark.Logan@Sun.COM } 1380*9203SMark.Logan@Sun.COM 1381*9203SMark.Logan@Sun.COM #ifdef _REMOTE_SUPPORT 1382*9203SMark.Logan@Sun.COM 1383*9203SMark.Logan@Sun.COM bool Protocol::_compareDNSSuffix(std::string AMTDNSSuffix, std::string suffix) 1384*9203SMark.Logan@Sun.COM { 1385*9203SMark.Logan@Sun.COM if (AMTDNSSuffix.size() > suffix.size()) { 1386*9203SMark.Logan@Sun.COM return false; 1387*9203SMark.Logan@Sun.COM } 1388*9203SMark.Logan@Sun.COM 1389*9203SMark.Logan@Sun.COM if ((AMTDNSSuffix.size() < suffix.size()) && 1390*9203SMark.Logan@Sun.COM (suffix[suffix.size()-AMTDNSSuffix.size()-1] != '.')) { 1391*9203SMark.Logan@Sun.COM return false; 1392*9203SMark.Logan@Sun.COM } 1393*9203SMark.Logan@Sun.COM 1394*9203SMark.Logan@Sun.COM if (strnicmp(suffix.c_str() + suffix.size()-AMTDNSSuffix.size(), 1395*9203SMark.Logan@Sun.COM AMTDNSSuffix.c_str(), 1396*9203SMark.Logan@Sun.COM AMTDNSSuffix.size()) == 0) { 1397*9203SMark.Logan@Sun.COM return true; 1398*9203SMark.Logan@Sun.COM } 1399*9203SMark.Logan@Sun.COM 1400*9203SMark.Logan@Sun.COM return false; 1401*9203SMark.Logan@Sun.COM } 1402*9203SMark.Logan@Sun.COM 1403*9203SMark.Logan@Sun.COM bool Protocol::_checkRemoteSupport(bool requestDnsFromAmt) 1404*9203SMark.Logan@Sun.COM { 1405*9203SMark.Logan@Sun.COM if (requestDnsFromAmt) { 1406*9203SMark.Logan@Sun.COM std::list<std::string> amtDnsSuffixes; 1407*9203SMark.Logan@Sun.COM 1408*9203SMark.Logan@Sun.COM AMT_STATUS status = _cfg.RequestEntDNSSuffixList(amtDnsSuffixes); 1409*9203SMark.Logan@Sun.COM 1410*9203SMark.Logan@Sun.COM if (status != AMT_STATUS_SUCCESS) { 1411*9203SMark.Logan@Sun.COM PRINT("Remote access is disabled - AMT is not configured [%x]\n", status); 1412*9203SMark.Logan@Sun.COM return false; 1413*9203SMark.Logan@Sun.COM } 1414*9203SMark.Logan@Sun.COM 1415*9203SMark.Logan@Sun.COM _AMTDNSLock.acquire(); 1416*9203SMark.Logan@Sun.COM _AMTDNSSuffixes.clear(); 1417*9203SMark.Logan@Sun.COM _AMTDNSSuffixes.assign(amtDnsSuffixes.begin(), amtDnsSuffixes.end()); 1418*9203SMark.Logan@Sun.COM _AMTDNSLock.release(); 1419*9203SMark.Logan@Sun.COM 1420*9203SMark.Logan@Sun.COM amtDnsSuffixes.clear(); 1421*9203SMark.Logan@Sun.COM } 1422*9203SMark.Logan@Sun.COM 1423*9203SMark.Logan@Sun.COM ATDomainMap domains; 1424*9203SMark.Logan@Sun.COM int error = 0; 1425*9203SMark.Logan@Sun.COM ATNetworkTool::GetLocalNetDomains(domains, error, PF_INET); 1426*9203SMark.Logan@Sun.COM _updateEnterpriseAccessStatus(domains); 1427*9203SMark.Logan@Sun.COM 1428*9203SMark.Logan@Sun.COM return true; 1429*9203SMark.Logan@Sun.COM } 1430*9203SMark.Logan@Sun.COM 1431*9203SMark.Logan@Sun.COM void Protocol::_updateEnterpriseAccessStatus(const ATDomainMap &localDNSSuffixes) 1432*9203SMark.Logan@Sun.COM { 1433*9203SMark.Logan@Sun.COM _AMTDNSLock.acquire(); 1434*9203SMark.Logan@Sun.COM 1435*9203SMark.Logan@Sun.COM std::list<std::string>::iterator remIt; 1436*9203SMark.Logan@Sun.COM std::list<std::string>::iterator startIt = _AMTDNSSuffixes.begin(); 1437*9203SMark.Logan@Sun.COM std::list<std::string>::iterator endIt = _AMTDNSSuffixes.end(); 1438*9203SMark.Logan@Sun.COM ATDomainMap::const_iterator locIt; 1439*9203SMark.Logan@Sun.COM 1440*9203SMark.Logan@Sun.COM bool access = false; 1441*9203SMark.Logan@Sun.COM ATAddress localIp; 1442*9203SMark.Logan@Sun.COM 1443*9203SMark.Logan@Sun.COM for (locIt = localDNSSuffixes.begin(); locIt != localDNSSuffixes.end(); locIt++) { 1444*9203SMark.Logan@Sun.COM remIt = find_if(startIt, endIt, bind2nd(ptr_fun(_compareDNSSuffix), locIt->second)); 1445*9203SMark.Logan@Sun.COM if (remIt != _AMTDNSSuffixes.end()) { 1446*9203SMark.Logan@Sun.COM access = true; 1447*9203SMark.Logan@Sun.COM localIp = locIt->first; 1448*9203SMark.Logan@Sun.COM break; 1449*9203SMark.Logan@Sun.COM } 1450*9203SMark.Logan@Sun.COM } 1451*9203SMark.Logan@Sun.COM 1452*9203SMark.Logan@Sun.COM _AMTDNSLock.release(); 1453*9203SMark.Logan@Sun.COM 1454*9203SMark.Logan@Sun.COM bool sendEntAccessMessage = true; 1455*9203SMark.Logan@Sun.COM if (access) { 1456*9203SMark.Logan@Sun.COM Lock l(_portsLock); 1457*9203SMark.Logan@Sun.COM for (PortMap::iterator it = _openPorts.begin(); it != _openPorts.end(); it++) { 1458*9203SMark.Logan@Sun.COM for (PortForwardRequestList::iterator it2 = it->second.begin(); 1459*9203SMark.Logan@Sun.COM it2 != it->second.end(); it2++) { 1460*9203SMark.Logan@Sun.COM 1461*9203SMark.Logan@Sun.COM if ((*it2)->GetStatus() == PortForwardRequest::PENDING_REQUEST) { 1462*9203SMark.Logan@Sun.COM (*it2)->SetStatus(PortForwardRequest::LISTENING); 1463*9203SMark.Logan@Sun.COM sendEntAccessMessage = false; 1464*9203SMark.Logan@Sun.COM break; // Assuming that there is a such request one per port 1465*9203SMark.Logan@Sun.COM } 1466*9203SMark.Logan@Sun.COM } 1467*9203SMark.Logan@Sun.COM } 1468*9203SMark.Logan@Sun.COM 1469*9203SMark.Logan@Sun.COM _signalSelect(); 1470*9203SMark.Logan@Sun.COM } 1471*9203SMark.Logan@Sun.COM 1472*9203SMark.Logan@Sun.COM if (sendEntAccessMessage == false) { 1473*9203SMark.Logan@Sun.COM return; 1474*9203SMark.Logan@Sun.COM } 1475*9203SMark.Logan@Sun.COM 1476*9203SMark.Logan@Sun.COM AMT_STATUS status = _cfg.SendEnterpriseAccess(access, localIp); 1477*9203SMark.Logan@Sun.COM 1478*9203SMark.Logan@Sun.COM Lock l(_remoteAccessLock); 1479*9203SMark.Logan@Sun.COM _remoteAccessEnabled = (status == AMT_STATUS_SUCCESS); 1480*9203SMark.Logan@Sun.COM switch (status) { 1481*9203SMark.Logan@Sun.COM case AMT_STATUS_SUCCESS: 1482*9203SMark.Logan@Sun.COM PRINT("Remote access is allowed.\n"); 1483*9203SMark.Logan@Sun.COM break; 1484*9203SMark.Logan@Sun.COM case AMT_STATUS_REMOTE_ACCESS_NOT_GRANTED: 1485*9203SMark.Logan@Sun.COM PRINT("Remote access is denied because AMT is directly connected " 1486*9203SMark.Logan@Sun.COM "to enterprise network.\n"); 1487*9203SMark.Logan@Sun.COM break; 1488*9203SMark.Logan@Sun.COM case AMT_STATUS_REMOTE_ACCESS_HOST_VPN_IS_DISABLED: 1489*9203SMark.Logan@Sun.COM PRINT("Remote access is disabled.\n"); 1490*9203SMark.Logan@Sun.COM break; 1491*9203SMark.Logan@Sun.COM default: 1492*9203SMark.Logan@Sun.COM PRINT("Remote access is disabled.\n"); 1493*9203SMark.Logan@Sun.COM break; 1494*9203SMark.Logan@Sun.COM } 1495*9203SMark.Logan@Sun.COM 1496*9203SMark.Logan@Sun.COM //if (_remoteAccessEnabled) { 1497*9203SMark.Logan@Sun.COM // Lock l(_portsLock); 1498*9203SMark.Logan@Sun.COM // for (PortMap::iterator it = _openPorts.begin(); it != _openPorts.end(); it++) { 1499*9203SMark.Logan@Sun.COM // for (PortForwardRequestList::iterator it2 = it->second.begin(); 1500*9203SMark.Logan@Sun.COM // it2 != it->second.end(); it2++) { 1501*9203SMark.Logan@Sun.COM 1502*9203SMark.Logan@Sun.COM // if ((*it2)->GetStatus() == PortForwardRequest::PENDING_REQUEST) { 1503*9203SMark.Logan@Sun.COM // (*it2)->SetStatus(PortForwardRequest::LISTENING); 1504*9203SMark.Logan@Sun.COM // break; // Assuming that there is a such request one per port 1505*9203SMark.Logan@Sun.COM // } 1506*9203SMark.Logan@Sun.COM // } 1507*9203SMark.Logan@Sun.COM // } 1508*9203SMark.Logan@Sun.COM 1509*9203SMark.Logan@Sun.COM // _signalSelect(); 1510*9203SMark.Logan@Sun.COM //} 1511*9203SMark.Logan@Sun.COM 1512*9203SMark.Logan@Sun.COM } 1513*9203SMark.Logan@Sun.COM 1514*9203SMark.Logan@Sun.COM #endif 1515*9203SMark.Logan@Sun.COM 1516*9203SMark.Logan@Sun.COM int Protocol::_isLocalCallback(void *const param, SOCKET s) 1517*9203SMark.Logan@Sun.COM { 1518*9203SMark.Logan@Sun.COM int error = 0; 1519*9203SMark.Logan@Sun.COM 1520*9203SMark.Logan@Sun.COM return ((1 == ATNetworkTool::IsSockPeerLocal(s, error, PF_INET)) ? 1 : -1); 1521*9203SMark.Logan@Sun.COM } 1522*9203SMark.Logan@Sun.COM 1523*9203SMark.Logan@Sun.COM #ifdef _REMOTE_SUPPORT 1524*9203SMark.Logan@Sun.COM 1525*9203SMark.Logan@Sun.COM int Protocol::_isRemoteCallback(void *const param, SOCKET s) 1526*9203SMark.Logan@Sun.COM { 1527*9203SMark.Logan@Sun.COM Protocol *prot = (Protocol *)param; 1528*9203SMark.Logan@Sun.COM 1529*9203SMark.Logan@Sun.COM return prot->_isRemote(s); 1530*9203SMark.Logan@Sun.COM } 1531*9203SMark.Logan@Sun.COM 1532*9203SMark.Logan@Sun.COM int Protocol::_isRemote(SOCKET s) const 1533*9203SMark.Logan@Sun.COM { 1534*9203SMark.Logan@Sun.COM int result = 0; 1535*9203SMark.Logan@Sun.COM int error = 0; 1536*9203SMark.Logan@Sun.COM int ret; 1537*9203SMark.Logan@Sun.COM std::string dnsSuffix; 1538*9203SMark.Logan@Sun.COM 1539*9203SMark.Logan@Sun.COM ret = ATNetworkTool::GetSockDomain(s, dnsSuffix, error); 1540*9203SMark.Logan@Sun.COM if (ret != 1) { 1541*9203SMark.Logan@Sun.COM return ret; 1542*9203SMark.Logan@Sun.COM } 1543*9203SMark.Logan@Sun.COM 1544*9203SMark.Logan@Sun.COM Lock l(_remoteAccessLock); 1545*9203SMark.Logan@Sun.COM 1546*9203SMark.Logan@Sun.COM if (_remoteAccessEnabled) { 1547*9203SMark.Logan@Sun.COM 1548*9203SMark.Logan@Sun.COM _AMTDNSLock.acquire(); 1549*9203SMark.Logan@Sun.COM 1550*9203SMark.Logan@Sun.COM std::list<std::string>::const_iterator it = _AMTDNSSuffixes.begin(); 1551*9203SMark.Logan@Sun.COM for (; it != _AMTDNSSuffixes.end(); it++) { 1552*9203SMark.Logan@Sun.COM if (_compareDNSSuffix(*it, dnsSuffix)) { 1553*9203SMark.Logan@Sun.COM result = 1; 1554*9203SMark.Logan@Sun.COM break; 1555*9203SMark.Logan@Sun.COM } 1556*9203SMark.Logan@Sun.COM } 1557*9203SMark.Logan@Sun.COM 1558*9203SMark.Logan@Sun.COM _AMTDNSLock.release(); 1559*9203SMark.Logan@Sun.COM } 1560*9203SMark.Logan@Sun.COM 1561*9203SMark.Logan@Sun.COM return result; 1562*9203SMark.Logan@Sun.COM } 1563*9203SMark.Logan@Sun.COM #endif 1564*9203SMark.Logan@Sun.COM 1565*9203SMark.Logan@Sun.COM int Protocol::_updateIPFQDN(const char *fqdn) 1566*9203SMark.Logan@Sun.COM { 1567*9203SMark.Logan@Sun.COM if (strcmp(fqdn, _AMTFQDN) != 0) { 1568*9203SMark.Logan@Sun.COM char localName[FQDN_MAX_SIZE] = "\0"; 1569*9203SMark.Logan@Sun.COM int res = gethostname(localName, sizeof(localName)); 1570*9203SMark.Logan@Sun.COM 1571*9203SMark.Logan@Sun.COM // If AMT FQDN is equal to local FQDN than we don't do anything 1572*9203SMark.Logan@Sun.COM if ((res == -1) || (strcmp(fqdn, localName) != 0)) { 1573*9203SMark.Logan@Sun.COM if (_handleFQDNChange(fqdn) < 0) { 1574*9203SMark.Logan@Sun.COM ERROR("Error: failed to update FQDN info\n"); 1575*9203SMark.Logan@Sun.COM return -1; 1576*9203SMark.Logan@Sun.COM } 1577*9203SMark.Logan@Sun.COM } else { 1578*9203SMark.Logan@Sun.COM if (_handleFQDNChange("") < 0) { 1579*9203SMark.Logan@Sun.COM ERROR("Error: failed to update FQDN info\n"); 1580*9203SMark.Logan@Sun.COM return -1; 1581*9203SMark.Logan@Sun.COM } 1582*9203SMark.Logan@Sun.COM } 1583*9203SMark.Logan@Sun.COM } 1584*9203SMark.Logan@Sun.COM 1585*9203SMark.Logan@Sun.COM memcpy(_AMTFQDN, fqdn, sizeof(_AMTFQDN)); 1586*9203SMark.Logan@Sun.COM 1587*9203SMark.Logan@Sun.COM PRINT("Got FQDN: %s\n", _AMTFQDN); 1588*9203SMark.Logan@Sun.COM 1589*9203SMark.Logan@Sun.COM return 0; 1590*9203SMark.Logan@Sun.COM } 1591*9203SMark.Logan@Sun.COM 1592*9203SMark.Logan@Sun.COM 1593*9203SMark.Logan@Sun.COM char *Protocol::_getErrMsg(DWORD err) 1594*9203SMark.Logan@Sun.COM { 1595*9203SMark.Logan@Sun.COM static char buffer[1024]; 1596*9203SMark.Logan@Sun.COM 1597*9203SMark.Logan@Sun.COM #if defined(__sun) || defined(_LINUX) 1598*9203SMark.Logan@Sun.COM strerror_r(err, buffer, sizeof(buffer) - 1); 1599*9203SMark.Logan@Sun.COM #else 1600*9203SMark.Logan@Sun.COM FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 1601*9203SMark.Logan@Sun.COM NULL, 1602*9203SMark.Logan@Sun.COM err, 1603*9203SMark.Logan@Sun.COM 0, 1604*9203SMark.Logan@Sun.COM buffer, 1605*9203SMark.Logan@Sun.COM sizeof(buffer) - 1, 1606*9203SMark.Logan@Sun.COM 0); 1607*9203SMark.Logan@Sun.COM #endif // __sun || _LINUX 1608*9203SMark.Logan@Sun.COM 1609*9203SMark.Logan@Sun.COM return buffer; 1610*9203SMark.Logan@Sun.COM } 1611*9203SMark.Logan@Sun.COM 1612*9203SMark.Logan@Sun.COM 1613*9203SMark.Logan@Sun.COM int Protocol::_handleFQDNChange(const char *fqdn) 1614*9203SMark.Logan@Sun.COM { 1615*9203SMark.Logan@Sun.COM const char *hostFile = "hosts"; 1616*9203SMark.Logan@Sun.COM const char *tmpFile = "hosts-lms.tmp"; 1617*9203SMark.Logan@Sun.COM bool hasFqdn = false; 1618*9203SMark.Logan@Sun.COM #define LMS_MAX_FILENAME_LEN 1024 1619*9203SMark.Logan@Sun.COM char inFileName[LMS_MAX_FILENAME_LEN] = ""; 1620*9203SMark.Logan@Sun.COM char oldFqdn[FQDN_MAX_SIZE + 1]; 1621*9203SMark.Logan@Sun.COM char outFileName[LMS_MAX_FILENAME_LEN] = ""; 1622*9203SMark.Logan@Sun.COM char host[FQDN_MAX_SIZE + 1]; 1623*9203SMark.Logan@Sun.COM #define LMS_MAX_LINE_LEN 1023 1624*9203SMark.Logan@Sun.COM char line[LMS_MAX_LINE_LEN + 1]; 1625*9203SMark.Logan@Sun.COM #define LMS_LINE_SIG_FIRST_WORDS "# LMS GENERATED " 1626*9203SMark.Logan@Sun.COM #define LMS_LINE_SIG_LAST_WORD "LINE" 1627*9203SMark.Logan@Sun.COM #define LMS_LINE_SIG_LAST_WORD_LEN 4 1628*9203SMark.Logan@Sun.COM #define LMS_LINE_SIG LMS_LINE_SIG_FIRST_WORDS LMS_LINE_SIG_LAST_WORD 1629*9203SMark.Logan@Sun.COM #define lmsstr(s) lmsname(s) 1630*9203SMark.Logan@Sun.COM #define lmsname(s) #s 1631*9203SMark.Logan@Sun.COM #define LMS_LINE_FORMAT "127.0.0.1 %s %s " LMS_LINE_SIG 1632*9203SMark.Logan@Sun.COM #define LMS_LINE_SCAN_FORMAT "127.0.0.1 %" lmsstr(FQDN_MAX_SIZE) "s %" lmsstr(FQDN_MAX_SIZE) "s " LMS_LINE_SIG_FIRST_WORDS "%" lmsstr(LMS_LINE_SIG_LAST_WORD_LEN) "c" 1633*9203SMark.Logan@Sun.COM char tmpsige[LMS_LINE_SIG_LAST_WORD_LEN]; 1634*9203SMark.Logan@Sun.COM 1635*9203SMark.Logan@Sun.COM #if defined(__sun) || defined(_LINUX) 1636*9203SMark.Logan@Sun.COM 1637*9203SMark.Logan@Sun.COM const char *dir = "/etc/"; 1638*9203SMark.Logan@Sun.COM 1639*9203SMark.Logan@Sun.COM #else 1640*9203SMark.Logan@Sun.COM 1641*9203SMark.Logan@Sun.COM char *sysDrive; 1642*9203SMark.Logan@Sun.COM const char *dir = "\\system32\\drivers\\etc\\"; 1643*9203SMark.Logan@Sun.COM 1644*9203SMark.Logan@Sun.COM sysDrive = getenv("SystemRoot"); 1645*9203SMark.Logan@Sun.COM if (NULL == sysDrive) { 1646*9203SMark.Logan@Sun.COM return -1; 1647*9203SMark.Logan@Sun.COM } 1648*9203SMark.Logan@Sun.COM 1649*9203SMark.Logan@Sun.COM // sanity check before string copying 1650*9203SMark.Logan@Sun.COM if (LMS_MAX_FILENAME_LEN < (strnlen(sysDrive, LMS_MAX_FILENAME_LEN) 1651*9203SMark.Logan@Sun.COM + strnlen(dir, LMS_MAX_FILENAME_LEN) 1652*9203SMark.Logan@Sun.COM + strnlen(hostFile, LMS_MAX_FILENAME_LEN) + 1)) { 1653*9203SMark.Logan@Sun.COM return -1; 1654*9203SMark.Logan@Sun.COM } 1655*9203SMark.Logan@Sun.COM // sanity check before string copying 1656*9203SMark.Logan@Sun.COM if (LMS_MAX_FILENAME_LEN < (strnlen(sysDrive, LMS_MAX_FILENAME_LEN) 1657*9203SMark.Logan@Sun.COM + strnlen(dir, LMS_MAX_FILENAME_LEN) 1658*9203SMark.Logan@Sun.COM + strnlen(tmpFile, LMS_MAX_FILENAME_LEN) + 1)) { 1659*9203SMark.Logan@Sun.COM return -1; 1660*9203SMark.Logan@Sun.COM } 1661*9203SMark.Logan@Sun.COM 1662*9203SMark.Logan@Sun.COM strncpy(inFileName, sysDrive, LMS_MAX_FILENAME_LEN - 1); 1663*9203SMark.Logan@Sun.COM strncpy(outFileName, sysDrive, LMS_MAX_FILENAME_LEN - 1); 1664*9203SMark.Logan@Sun.COM 1665*9203SMark.Logan@Sun.COM #endif // __sun || _LINUX 1666*9203SMark.Logan@Sun.COM 1667*9203SMark.Logan@Sun.COM strncat(inFileName, dir, LMS_MAX_FILENAME_LEN - 1); 1668*9203SMark.Logan@Sun.COM strncat(outFileName, dir, LMS_MAX_FILENAME_LEN - 1); 1669*9203SMark.Logan@Sun.COM strncat(inFileName, hostFile, LMS_MAX_FILENAME_LEN - 1); 1670*9203SMark.Logan@Sun.COM strncat(outFileName, tmpFile, LMS_MAX_FILENAME_LEN - 1); 1671*9203SMark.Logan@Sun.COM 1672*9203SMark.Logan@Sun.COM FILE *ifp = fopen(inFileName, "r"); 1673*9203SMark.Logan@Sun.COM if (NULL == ifp) { 1674*9203SMark.Logan@Sun.COM _eventLog(_eventLogParam, TEXT("Error: Can't open hosts file"), EVENTLOG_ERROR_TYPE); 1675*9203SMark.Logan@Sun.COM return -1; 1676*9203SMark.Logan@Sun.COM } 1677*9203SMark.Logan@Sun.COM 1678*9203SMark.Logan@Sun.COM FILE *ofp = fopen(outFileName, "w"); 1679*9203SMark.Logan@Sun.COM if (NULL == ofp) { 1680*9203SMark.Logan@Sun.COM _eventLog(_eventLogParam, TEXT("Error: Can't create temporary hosts file"), EVENTLOG_ERROR_TYPE); 1681*9203SMark.Logan@Sun.COM fclose(ifp); 1682*9203SMark.Logan@Sun.COM return -1; 1683*9203SMark.Logan@Sun.COM } 1684*9203SMark.Logan@Sun.COM 1685*9203SMark.Logan@Sun.COM // First create a copy of the hosts file, without lines that were 1686*9203SMark.Logan@Sun.COM // previously added by the LMS. 1687*9203SMark.Logan@Sun.COM // Go over each line and copy it to the tmp file. 1688*9203SMark.Logan@Sun.COM while (fgets(line, sizeof(line), ifp)) { 1689*9203SMark.Logan@Sun.COM // don't copy the line if it was generated by the LMS 1690*9203SMark.Logan@Sun.COM memset(oldFqdn, 0, sizeof(oldFqdn)); 1691*9203SMark.Logan@Sun.COM memset(tmpsige, 0, sizeof(tmpsige)); 1692*9203SMark.Logan@Sun.COM if (0 == ( 1693*9203SMark.Logan@Sun.COM (3 == sscanf(line, LMS_LINE_SCAN_FORMAT, oldFqdn, host, tmpsige)) 1694*9203SMark.Logan@Sun.COM ? strncmp(tmpsige, LMS_LINE_SIG_LAST_WORD, LMS_LINE_SIG_LAST_WORD_LEN) 1695*9203SMark.Logan@Sun.COM : (-2)) 1696*9203SMark.Logan@Sun.COM ) { 1697*9203SMark.Logan@Sun.COM if (0 == strncmp((char *)fqdn, oldFqdn, FQDN_MAX_SIZE)) { 1698*9203SMark.Logan@Sun.COM // copy the old LMS line too, since it's up to date 1699*9203SMark.Logan@Sun.COM fprintf(ofp, "%s", line); 1700*9203SMark.Logan@Sun.COM hasFqdn = true; 1701*9203SMark.Logan@Sun.COM } 1702*9203SMark.Logan@Sun.COM continue; 1703*9203SMark.Logan@Sun.COM } 1704*9203SMark.Logan@Sun.COM 1705*9203SMark.Logan@Sun.COM fprintf(ofp, "%s", line); 1706*9203SMark.Logan@Sun.COM 1707*9203SMark.Logan@Sun.COM while ((LMS_MAX_LINE_LEN == strnlen(line, LMS_MAX_LINE_LEN)) 1708*9203SMark.Logan@Sun.COM && ('\n' != line[LMS_MAX_LINE_LEN - 1]) 1709*9203SMark.Logan@Sun.COM && (fgets(line, sizeof(line), ifp))) { 1710*9203SMark.Logan@Sun.COM fprintf(ofp, "%s", line); 1711*9203SMark.Logan@Sun.COM } 1712*9203SMark.Logan@Sun.COM } 1713*9203SMark.Logan@Sun.COM 1714*9203SMark.Logan@Sun.COM if (hasFqdn) { 1715*9203SMark.Logan@Sun.COM fclose(ofp); 1716*9203SMark.Logan@Sun.COM fclose(ifp); 1717*9203SMark.Logan@Sun.COM unlink(outFileName); 1718*9203SMark.Logan@Sun.COM return 0; 1719*9203SMark.Logan@Sun.COM } 1720*9203SMark.Logan@Sun.COM 1721*9203SMark.Logan@Sun.COM // If the original hosts file does not end with a new line character, 1722*9203SMark.Logan@Sun.COM // add a new line at the end of the new file before adding our line. 1723*9203SMark.Logan@Sun.COM fseek(ifp, -1, SEEK_END); 1724*9203SMark.Logan@Sun.COM char lastChar = fgetc(ifp); 1725*9203SMark.Logan@Sun.COM if ('\n' != lastChar) { 1726*9203SMark.Logan@Sun.COM fprintf(ofp, "\n"); 1727*9203SMark.Logan@Sun.COM } 1728*9203SMark.Logan@Sun.COM 1729*9203SMark.Logan@Sun.COM memset(host, 0, FQDN_MAX_SIZE + 1); 1730*9203SMark.Logan@Sun.COM strncpy(host, fqdn, FQDN_MAX_SIZE); 1731*9203SMark.Logan@Sun.COM char *lmsdot = strchr(host, '.'); 1732*9203SMark.Logan@Sun.COM if (NULL != lmsdot) { 1733*9203SMark.Logan@Sun.COM lmsdot[0] = '\0'; 1734*9203SMark.Logan@Sun.COM } 1735*9203SMark.Logan@Sun.COM 1736*9203SMark.Logan@Sun.COM if ((fqdn != NULL) && (fqdn[0] != 0)) { 1737*9203SMark.Logan@Sun.COM // Add the specified FQDN to the end of the tmp file 1738*9203SMark.Logan@Sun.COM fprintf(ofp, LMS_LINE_FORMAT "\n", fqdn, host); 1739*9203SMark.Logan@Sun.COM } 1740*9203SMark.Logan@Sun.COM 1741*9203SMark.Logan@Sun.COM fclose(ofp); 1742*9203SMark.Logan@Sun.COM fclose(ifp); 1743*9203SMark.Logan@Sun.COM 1744*9203SMark.Logan@Sun.COM if (0 != std::rename(outFileName, inFileName)) { 1745*9203SMark.Logan@Sun.COM std::string tmp2FileName = std::string(inFileName) + ".~tmp"; 1746*9203SMark.Logan@Sun.COM std::ifstream mfile(inFileName, std::ios_base::in); 1747*9203SMark.Logan@Sun.COM if (!mfile.is_open()) { 1748*9203SMark.Logan@Sun.COM _eventLog(_eventLogParam, TEXT("Error: Can't update hosts file [1]"), EVENTLOG_ERROR_TYPE); 1749*9203SMark.Logan@Sun.COM return -1; 1750*9203SMark.Logan@Sun.COM } 1751*9203SMark.Logan@Sun.COM std::ofstream wfile(tmp2FileName.c_str(), std::ios_base::out | std::ios_base::trunc); 1752*9203SMark.Logan@Sun.COM if (!wfile.is_open()) { 1753*9203SMark.Logan@Sun.COM mfile.close(); 1754*9203SMark.Logan@Sun.COM _eventLog(_eventLogParam, TEXT("Error: Can't update hosts file [2]"), EVENTLOG_ERROR_TYPE); 1755*9203SMark.Logan@Sun.COM return -1; 1756*9203SMark.Logan@Sun.COM } 1757*9203SMark.Logan@Sun.COM wfile << mfile.rdbuf(); 1758*9203SMark.Logan@Sun.COM if (wfile.bad()) { 1759*9203SMark.Logan@Sun.COM mfile.close(); 1760*9203SMark.Logan@Sun.COM wfile.close(); 1761*9203SMark.Logan@Sun.COM _eventLog(_eventLogParam, TEXT("Error: Can't update hosts file [3]"), EVENTLOG_ERROR_TYPE); 1762*9203SMark.Logan@Sun.COM return -1; 1763*9203SMark.Logan@Sun.COM } 1764*9203SMark.Logan@Sun.COM mfile.close(); 1765*9203SMark.Logan@Sun.COM wfile.close(); 1766*9203SMark.Logan@Sun.COM std::ifstream sfile(outFileName, std::ios_base::in); 1767*9203SMark.Logan@Sun.COM if (!sfile.is_open()) { 1768*9203SMark.Logan@Sun.COM _eventLog(_eventLogParam, TEXT("Error: Can't update hosts file [4]"), EVENTLOG_ERROR_TYPE); 1769*9203SMark.Logan@Sun.COM return -1; 1770*9203SMark.Logan@Sun.COM } 1771*9203SMark.Logan@Sun.COM std::ofstream dfile(inFileName, std::ios_base::out | std::ios_base::trunc); 1772*9203SMark.Logan@Sun.COM if (!dfile.is_open()) { 1773*9203SMark.Logan@Sun.COM sfile.close(); 1774*9203SMark.Logan@Sun.COM _eventLog(_eventLogParam, TEXT("Error: Can't update hosts file [5]"), EVENTLOG_ERROR_TYPE); 1775*9203SMark.Logan@Sun.COM return -1; 1776*9203SMark.Logan@Sun.COM } 1777*9203SMark.Logan@Sun.COM dfile << sfile.rdbuf(); 1778*9203SMark.Logan@Sun.COM if (dfile.bad()) { 1779*9203SMark.Logan@Sun.COM sfile.close(); 1780*9203SMark.Logan@Sun.COM dfile.close(); 1781*9203SMark.Logan@Sun.COM unlink(inFileName); 1782*9203SMark.Logan@Sun.COM if (0 != std::rename(outFileName, inFileName)) { 1783*9203SMark.Logan@Sun.COM std::rename(tmp2FileName.c_str(), inFileName); 1784*9203SMark.Logan@Sun.COM _eventLog(_eventLogParam, TEXT("Error: Can't update hosts file [6]"), EVENTLOG_ERROR_TYPE); 1785*9203SMark.Logan@Sun.COM return -1; 1786*9203SMark.Logan@Sun.COM } 1787*9203SMark.Logan@Sun.COM } 1788*9203SMark.Logan@Sun.COM sfile.close(); 1789*9203SMark.Logan@Sun.COM dfile.close(); 1790*9203SMark.Logan@Sun.COM } 1791*9203SMark.Logan@Sun.COM 1792*9203SMark.Logan@Sun.COM _eventLog(_eventLogParam, TEXT("hosts file updated"), EVENTLOG_INFORMATION_TYPE); 1793*9203SMark.Logan@Sun.COM 1794*9203SMark.Logan@Sun.COM return 0; 1795*9203SMark.Logan@Sun.COM } 1796*9203SMark.Logan@Sun.COM 1797*9203SMark.Logan@Sun.COM ssize_t Protocol::_send(int s, const void *buf, size_t len, int &senderr) 1798*9203SMark.Logan@Sun.COM { 1799*9203SMark.Logan@Sun.COM ssize_t result; 1800*9203SMark.Logan@Sun.COM 1801*9203SMark.Logan@Sun.COM #if defined(_LINUX) 1802*9203SMark.Logan@Sun.COM if (-1 == (result = send(s, buf, len, MSG_NOSIGNAL))) { 1803*9203SMark.Logan@Sun.COM senderr = errno; 1804*9203SMark.Logan@Sun.COM } 1805*9203SMark.Logan@Sun.COM #elif defined(__sun) 1806*9203SMark.Logan@Sun.COM if (-1 == (result = send(s, buf, len, 0))) { 1807*9203SMark.Logan@Sun.COM senderr = errno; 1808*9203SMark.Logan@Sun.COM } 1809*9203SMark.Logan@Sun.COM #else 1810*9203SMark.Logan@Sun.COM result = send(s, buf, len); 1811*9203SMark.Logan@Sun.COM #endif // _LINUX 1812*9203SMark.Logan@Sun.COM 1813*9203SMark.Logan@Sun.COM return result; 1814*9203SMark.Logan@Sun.COM } 1815*9203SMark.Logan@Sun.COM 1816