00001 /* 00002 00003 Copyright (C) 2005-2007 by Peter Dimov. 00004 00005 This file is part of Calitko (http://www.calitko.org). 00006 00007 Calitko is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 2 of the License, or 00010 (at your option) any later version. 00011 00012 Calitko is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with Calitko; if not, write to the Free Software 00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00020 00021 */ 00022 00023 #include "Qt.h" 00024 #include "Imports.h" 00025 #include "Connection.h" 00026 00027 using namespace Protocols::Transports; 00028 00029 namespace Protocols { 00030 namespace Transports { 00031 00032 class ConnectionPrivate 00033 { 00034 public: 00035 NodeAddress remoteNodeAddress; 00036 Connection::State state; 00037 00038 ConnectionPrivate() 00039 : remoteNodeAddress(), state (Connection::DisconnectedState) 00040 {} 00041 } p; 00042 00043 } // namespace Transports; 00044 } // namespace Protocols; 00045 00046 Connection::State Connection::state() const 00047 { return p->state; } 00048 00049 NodeAddress Connection::remoteNodeAddress() const 00050 { return p->remoteNodeAddress; } 00051 00052 void Connection::setState (Connection::State state) 00053 { p->state = state; } 00054 00055 void Connection::setRemoteNodeAddress (const NodeAddress &remoteNodeAddress) 00056 { p->remoteNodeAddress = remoteNodeAddress; } 00057 00058 Connection::Connection() 00059 : p (new ConnectionPrivate) 00060 { 00061 } 00062 00063 Connection::~Connection() 00064 { 00065 //Q_ASSERT (state() == DisconnectedState); 00066 } 00067 00068 void Connection::connectToNode (NodeAddress nodeAddress) 00069 { 00070 Q_ASSERT (!nodeAddress.isNull()); 00071 Q_ASSERT (p->state == DisconnectedState); 00072 00073 p->remoteNodeAddress = nodeAddress; 00074 QHostAddress hostAddress = nodeAddress.hostAddress(); 00075 if (hostAddress.isNull()) { 00076 setState (ResolvingHostNameState); 00077 qDebug() << "Resolving " << nodeAddress.hostName(); 00078 QHostInfo::lookupHost (nodeAddress.hostName(), this, 00079 SLOT (lookupFinished (QHostInfo))); 00080 } else { 00081 setState (ConnectingState); 00082 doConnectToNode (nodeAddress); 00083 } 00084 } 00085 00086 void Connection::lookupFinished (QHostInfo hostInfo) 00087 { 00088 if (hostInfo.addresses().count() == 0) { 00089 qDebug() << "Name resolution failed for " << hostInfo.hostName(); 00090 emit connectionFailed(); 00091 setState (DisconnectedState); 00092 } else { 00093 setState (ConnectingState); 00094 // \todo We now only try the first IP. Should we try more? How long to wait? 00095 QHostAddress hostAddress = hostInfo.addresses().first(); 00096 qDebug() << "Found address " << hostAddress.toString() << " for "<< hostInfo.hostName(); 00097 // This call overwrites the hostName field of remoteNodeAddress: 00098 p->remoteNodeAddress.setHostAddress (hostAddress); 00099 // Call implementation: 00100 doConnectToNode (p->remoteNodeAddress); 00101 } 00102 } 00103 00104 void Connection::disconnectFromNode() 00105 { 00106 setState (DisconnectingState); 00107 doDisconnectFromNode(); 00108 } 00109 00110 bool Connection::isSequential() const 00111 { 00112 return true; 00113 }