diff options
Diffstat (limited to 'plugins/upnp/upnprouter.cpp')
-rw-r--r-- | plugins/upnp/upnprouter.cpp | 459 |
1 files changed, 0 insertions, 459 deletions
diff --git a/plugins/upnp/upnprouter.cpp b/plugins/upnp/upnprouter.cpp deleted file mode 100644 index 0e18e92..0000000 --- a/plugins/upnp/upnprouter.cpp +++ /dev/null @@ -1,459 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Joris Guisson * - * joris.guisson@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - ***************************************************************************/ -#include <stdlib.h> -#include <tdelocale.h> -#include <tdeglobal.h> -#include <kstandarddirs.h> -#include <tqstringlist.h> -#include <tdeio/netaccess.h> -#include <tdeio/job.h> -#include <torrent/globals.h> -#include <util/log.h> -#include <util/array.h> -#include <util/error.h> -#include <util/functions.h> -#include <util/fileops.h> -#include <util/httprequest.h> -#include <util/waitjob.h> -#include "upnprouter.h" -#include "upnpdescriptionparser.h" -#include "soap.h" - -using namespace bt; -using namespace net; - -namespace kt -{ - UPnPService::UPnPService() - { - } - - UPnPService::UPnPService(const UPnPService & s) - { - this->servicetype = s.servicetype; - this->controlurl = s.controlurl; - this->eventsuburl = s.eventsuburl; - this->serviceid = s.serviceid; - this->scpdurl = s.scpdurl; - } - - void UPnPService::setProperty(const TQString & name,const TQString & value) - { - if (name == "serviceType") - servicetype = value; - else if (name == "controlURL") - controlurl = value; - else if (name == "eventSubURL") - eventsuburl = value; - else if (name == "SCPDURL") - scpdurl = value; - else if (name == "serviceId") - serviceid = value; - } - - void UPnPService::clear() - { - servicetype = controlurl = eventsuburl = scpdurl = serviceid = ""; - } - - void UPnPService::debugPrintData() - { - Out(SYS_PNP|LOG_DEBUG) << " servicetype = " << servicetype << endl; - Out(SYS_PNP|LOG_DEBUG) << " controlurl = " << controlurl << endl; - Out(SYS_PNP|LOG_DEBUG) << " eventsuburl = " << eventsuburl << endl; - Out(SYS_PNP|LOG_DEBUG) << " scpdurl = " << scpdurl << endl; - Out(SYS_PNP|LOG_DEBUG) << " serviceid = " << serviceid << endl; - } - - UPnPService & UPnPService::operator = (const UPnPService & s) - { - this->servicetype = s.servicetype; - this->controlurl = s.controlurl; - this->eventsuburl = s.eventsuburl; - this->serviceid = s.serviceid; - this->scpdurl = s.scpdurl; - return *this; - } - - /////////////////////////////////////// - - void UPnPDeviceDescription::setProperty(const TQString & name,const TQString & value) - { - if (name == "friendlyName") - friendlyName = value; - else if (name == "manufacturer") - manufacturer = value; - else if (name == "modelDescription") - modelDescription = value; - else if (name == "modelName") - modelName = value; - else if (name == "modelNumber") - modelNumber == value; - } - - /////////////////////////////////////// - - UPnPRouter::UPnPRouter(const TQString & server,const KURL & location,bool verbose) : server(server),location(location),verbose(verbose) - { - // make the tmp_file unique, current time * a random number should be enough - tmp_file = TQString("/tmp/ktorrent_upnp_description-%1.xml").arg(bt::GetCurrentTime() * rand()); - } - - - UPnPRouter::~UPnPRouter() - { - TQValueList<HTTPRequest*>::iterator i = active_reqs.begin(); - while (i != active_reqs.end()) - { - (*i)->deleteLater(); - i++; - } - } - - void UPnPRouter::addService(const UPnPService & s) - { - TQValueList<UPnPService>::iterator i = services.begin(); - while (i != services.end()) - { - UPnPService & os = *i; - if (s.servicetype == os.servicetype) - return; - i++; - } - services.append(s); - } - - void UPnPRouter::downloadFinished(TDEIO::Job* j) - { - if (j->error()) - { - Out(SYS_PNP|LOG_IMPORTANT) << "Failed to download " << location << " : " << j->errorString() << endl; - return; - } - - TQString target = tmp_file; - // load in the file (target is always local) - UPnPDescriptionParser desc_parse; - bool ret = desc_parse.parse(target,this); - if (!ret) - { - Out(SYS_PNP|LOG_IMPORTANT) << "Error parsing router description !" << endl; - TQString dest = TDEGlobal::dirs()->saveLocation("data","ktorrent") + "upnp_failure"; - TDEIO::file_copy(target,dest,-1,true,false,false); - } - else - { - if (verbose) - debugPrintData(); - } - xmlFileDownloaded(this,ret); - bt::Delete(target); - } - - void UPnPRouter::downloadXMLFile() - { - // downlaod XML description into a temporary file in /tmp - TDEIO::Job* job = TDEIO::file_copy(location,tmp_file,-1,true,false,false); - connect(job,TQT_SIGNAL(result(TDEIO::Job *)),this,TQT_SLOT(downloadFinished( TDEIO::Job* ))); - } - - void UPnPRouter::debugPrintData() - { - Out(SYS_PNP|LOG_DEBUG) << "UPnPRouter : " << endl; - Out(SYS_PNP|LOG_DEBUG) << "Friendly name = " << desc.friendlyName << endl; - Out(SYS_PNP|LOG_DEBUG) << "Manufacterer = " << desc.manufacturer << endl; - Out(SYS_PNP|LOG_DEBUG) << "Model description = " << desc.modelDescription << endl; - Out(SYS_PNP|LOG_DEBUG) << "Model name = " << desc.modelName << endl; - Out(SYS_PNP|LOG_DEBUG) << "Model number = " << desc.modelNumber << endl; - for (TQValueList<UPnPService>::iterator i = services.begin();i != services.end();i++) - { - UPnPService & s = *i; - Out() << "Service : " << endl; - s.debugPrintData(); - Out(SYS_PNP|LOG_DEBUG) << "Done" << endl; - } - Out(SYS_PNP|LOG_DEBUG) << "Done" << endl; - } - - - void UPnPRouter::forward(UPnPService* srv,const net::Port & port) - { - // add all the arguments for the command - TQValueList<SOAP::Arg> args; - SOAP::Arg a; - a.element = "NewRemoteHost"; - args.append(a); - - // the external port - a.element = "NewExternalPort"; - a.value = TQString::number(port.number); - args.append(a); - - // the protocol - a.element = "NewProtocol"; - a.value = port.proto == TCP ? "TCP" : "UDP"; - args.append(a); - - // the local port - a.element = "NewInternalPort"; - a.value = TQString::number(port.number); - args.append(a); - - // the local IP address - a.element = "NewInternalClient"; - a.value = "$LOCAL_IP";// will be replaced by our local ip in bt::HTTPRequest - args.append(a); - - a.element = "NewEnabled"; - a.value = "1"; - args.append(a); - - a.element = "NewPortMappingDescription"; - static Uint32 cnt = 0; - a.value = TQString("KTorrent UPNP %1").arg(cnt++); // TODO: change this - args.append(a); - - a.element = "NewLeaseDuration"; - a.value = "0"; - args.append(a); - - TQString action = "AddPortMapping"; - TQString comm = SOAP::createCommand(action,srv->servicetype,args); - - Forwarding fw = {port,0,srv}; - // erase old forwarding if one exists - TQValueList<Forwarding>::iterator itr = fwds.begin(); - while (itr != fwds.end()) - { - Forwarding & fwo = *itr; - if (fwo.port == port && fwo.service == srv) - itr = fwds.erase(itr); - else - itr++; - } - - fw.pending_req = sendSoapQuery(comm,srv->servicetype + "#" + action,srv->controlurl); - fwds.append(fw); - } - - void UPnPRouter::forward(const net::Port & port) - { - Out(SYS_PNP|LOG_NOTICE) << "Forwarding port " << port.number << " (" << (port.proto == UDP ? "UDP" : "TCP") << ")" << endl; - // first find the right service - TQValueList<UPnPService>::iterator i = services.begin(); - while (i != services.end()) - { - UPnPService & s = *i; - if (s.servicetype == "urn:schemas-upnp-org:service:WANIPConnection:1" || - s.servicetype == "urn:schemas-upnp-org:service:WANPPPConnection:1") - { - forward(&s,port); - } - i++; - } - - } - - void UPnPRouter::undoForward(UPnPService* srv,const net::Port & port,bt::WaitJob* waitjob) - { - // add all the arguments for the command - TQValueList<SOAP::Arg> args; - SOAP::Arg a; - a.element = "NewRemoteHost"; - args.append(a); - - // the external port - a.element = "NewExternalPort"; - a.value = TQString::number(port.number); - args.append(a); - - // the protocol - a.element = "NewProtocol"; - a.value = port.proto == TCP ? "TCP" : "UDP"; - args.append(a); - - - TQString action = "DeletePortMapping"; - TQString comm = SOAP::createCommand(action,srv->servicetype,args); - bt::HTTPRequest* r = sendSoapQuery(comm,srv->servicetype + "#" + action,srv->controlurl,waitjob != 0); - - if (waitjob) - waitjob->addExitOperation(r); - - updateGUI(); - } - - - void UPnPRouter::undoForward(const net::Port & port,bt::WaitJob* waitjob) - { - Out(SYS_PNP|LOG_NOTICE) << "Undoing forward of port " << port.number - << " (" << (port.proto == UDP ? "UDP" : "TCP") << ")" << endl; - - TQValueList<Forwarding>::iterator itr = fwds.begin(); - while (itr != fwds.end()) - { - Forwarding & wd = *itr; - if (wd.port == port) - { - undoForward(wd.service,wd.port,waitjob); - itr = fwds.erase(itr); - } - else - { - itr++; - } - } - } - - bt::HTTPRequest* UPnPRouter::sendSoapQuery(const TQString & query,const TQString & soapact,const TQString & controlurl,bool at_exit) - { - // if port is not set, 0 will be returned - // thanks to Diego R. Brogna for spotting this bug - if (location.port()==0) - location.setPort(80); - - TQString http_hdr = TQString( - "POST %1 HTTP/1.1\r\n" - "HOST: %2:%3\r\n" - "Content-length: $CONTENT_LENGTH\r\n" - "Content-Type: text/xml\r\n" - "SOAPAction: \"%4\"\r\n" - "\r\n").arg(controlurl).arg(location.host()).arg(location.port()).arg(soapact); - - - HTTPRequest* r = new HTTPRequest(http_hdr,query,location.host(),location.port(),verbose); - connect(r,TQT_SIGNAL(replyError(bt::HTTPRequest* ,const TQString& )), - this,TQT_SLOT(onReplyError(bt::HTTPRequest* ,const TQString& ))); - connect(r,TQT_SIGNAL(replyOK(bt::HTTPRequest* ,const TQString& )), - this,TQT_SLOT(onReplyOK(bt::HTTPRequest* ,const TQString& ))); - connect(r,TQT_SIGNAL(error(bt::HTTPRequest*, bool )), - this,TQT_SLOT(onError(bt::HTTPRequest*, bool ))); - r->start(); - if (!at_exit) - active_reqs.append(r); - return r; - } - - void UPnPRouter::httpRequestDone(bt::HTTPRequest* r,bool erase_fwd) - { - TQValueList<Forwarding>::iterator i = fwds.begin(); - while (i != fwds.end()) - { - Forwarding & fw = *i; - if (fw.pending_req == r) - { - fw.pending_req = 0; - if (erase_fwd) - fwds.erase(i); - break; - } - i++; - } - - updateGUI(); - active_reqs.remove(r); - r->deleteLater(); - } - - void UPnPRouter::onReplyOK(bt::HTTPRequest* r,const TQString &) - { - if (verbose) - Out(SYS_PNP|LOG_NOTICE) << "UPnPRouter : OK" << endl; - - httpRequestDone(r,false); - } - - void UPnPRouter::onReplyError(bt::HTTPRequest* r,const TQString &) - { - if (verbose) - Out(SYS_PNP|LOG_IMPORTANT) << "UPnPRouter : Error" << endl; - - httpRequestDone(r,true); - - } - - void UPnPRouter::onError(bt::HTTPRequest* r,bool) - { - httpRequestDone(r,true); - } - -#if 0 - TQValueList<UPnPService>::iterator UPnPRouter::findPortForwardingService() - { - TQValueList<UPnPService>::iterator i = services.begin(); - while (i != services.end()) - { - UPnPService & s = *i; - if (s.servicetype == "urn:schemas-upnp-org:service:WANIPConnection:1" || - s.servicetype == "urn:schemas-upnp-org:service:WANPPPConnection:1") - return i; - i++; - } - return services.end(); - } - - - void UPnPRouter::getExternalIP() - { - // first find the right service - TQValueList<UPnPService>::iterator i = findPortForwardingService(); - if (i == services.end()) - throw Error(i18n("Cannot find port forwarding service in the device's description!")); - - UPnPService & s = *i; - TQString action = "GetExternalIPAddress"; - TQString comm = SOAP::createCommand(action,s.servicetype); - sendSoapQuery(comm,s.servicetype + "#" + action,s.controlurl); - } - - void UPnPRouter::isPortForwarded(const net::Port & port) - { - // first find the right service - TQValueList<UPnPService>::iterator i = findPortForwardingService(); - if (i == services.end()) - throw Error(i18n("Cannot find port forwarding service in the device's description!")); - - // add all the arguments for the command - TQValueList<SOAP::Arg> args; - SOAP::Arg a; - a.element = "NewRemoteHost"; - args.append(a); - - // the external port - a.element = "NewExternalPort"; - a.value = TQString::number(port.number); - args.append(a); - - // the protocol - a.element = "NewProtocol"; - a.value = port.proto == TCP ? "TCP" : "UDP"; - args.append(a); - - UPnPService & s = *i; - TQString action = "GetSpecificPortMappingEntry"; - TQString comm = SOAP::createCommand(action,s.servicetype,args); - sendSoapQuery(comm,s.servicetype + "#" + action,s.controlurl); - } -#endif - - -} - -#include "upnprouter.moc" |