summaryrefslogtreecommitdiffstats
path: root/plugins/upnp/upnprouter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/upnp/upnprouter.cpp')
-rw-r--r--plugins/upnp/upnprouter.cpp459
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"