dead
authorChristian Grothoff <christian@grothoff.org>
Wed, 4 May 2011 12:22:55 +0000 (12:22 +0000)
committerChristian Grothoff <christian@grothoff.org>
Wed, 4 May 2011 12:22:55 +0000 (12:22 +0000)
12 files changed:
src/upnp/Makefile.am [deleted file]
src/upnp/draft-cheshire-nat-pmp.txt [deleted file]
src/upnp/test_upnp.c [deleted file]
src/upnp/upnp.c [deleted file]
src/upnp/upnp.h [deleted file]
src/upnp/upnp_init.c [deleted file]
src/upnp/upnp_ip.c [deleted file]
src/upnp/upnp_ip.h [deleted file]
src/upnp/upnp_util.c [deleted file]
src/upnp/upnp_util.h [deleted file]
src/upnp/upnp_xmlnode.c [deleted file]
src/upnp/upnp_xmlnode.h [deleted file]

diff --git a/src/upnp/Makefile.am b/src/upnp/Makefile.am
deleted file mode 100644 (file)
index 83ccf5b..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-INCLUDES = -I$(top_srcdir)/src/include
-
-if MINGW
-  WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols
-endif
-
-if USE_COVERAGE
-  AM_CFLAGS = -fprofile-arcs -ftest-coverage
-endif
-
-lib_LTLIBRARIES = libgnunetupnp.la
-
-libgnunetupnp_la_SOURCES = \
-  upnp.c upnp.h \
-  upnp_ip.c upnp_ip.h \
-  upnp_util.c upnp_util.h \
-  upnp_xmlnode.c upnp_xmlnode.h 
-libgnunetupnp_la_CFLAGS = \
- -I$(top_scrdir)/include \
- @LIBCURL_CPPFLAGS@ @XML_CPPFLAGS@
-libgnunetupnp_la_LIBADD = \
-  $(top_builddir)/src/util/libgnunetutil.la \
-  $(GN_LIBINTL) @EXT_LIBS@ @XML_LIBS@ @LIBCURL@
-libgnunetupnp_la_LDFLAGS = \
-  $(GN_LIB_LDFLAGS) $(WINFLAGS) \
-  -version-info 0:0:0
-
-
-bin_PROGRAMS = \
- gnunet-upnp \
- gnunet-service-upnp
-
-gnunet_upnp_SOURCES = \
- gnunet-upnp.c         
-gnunet_upnp_LDADD = \
-  $(top_builddir)/src/upnp/libgnunetupnp.la \
-  $(top_builddir)/src/util/libgnunetutil.la \
-  $(GN_LIBINTL)
-
-gnunet_service_upnp_SOURCES = \
- gnunet-service-upnp.c 
-gnunet_service_upnp_LDADD = \
-  $(top_builddir)/src/util/libgnunetutil.la \
-  $(GN_LIBINTL)
-
-
-check_PROGRAMS = \
- test_upnp
-
-if !DISABLE_TEST_RUN
-TESTS = $(check_PROGRAMS)
-endif
-
-test_upnp_SOURCES = \
- test_upnp.c
-test_upnp_LDADD = \
- $(top_builddir)/src/transport/libgnunetupnp.la \
- $(top_builddir)/src/util/libgnunetutil.la  
-
-
-# EXTRA_DIST = test_upnp_data.conf 
diff --git a/src/upnp/draft-cheshire-nat-pmp.txt b/src/upnp/draft-cheshire-nat-pmp.txt
deleted file mode 100644 (file)
index 727b5fa..0000000
+++ /dev/null
@@ -1,1160 +0,0 @@
-Document: draft-cheshire-nat-pmp-02.txt                  Stuart Cheshire
-Internet-Draft                                             Marc Krochmal
-Category: Standards Track                           Apple Computer, Inc.
-Expires 14th March 2007                                      Kiren Sekar
-                                                         Sharpcast, Inc.
-                                                     14th September 2006
-
-                   NAT Port Mapping Protocol (NAT-PMP)
-
-                     <draft-cheshire-nat-pmp-02.txt>
-
-Status of this Memo
-
-   By submitting this Internet-Draft, each author represents that any
-   applicable patent or other IPR claims of which he or she is aware
-   have been or will be disclosed, and any of which he or she becomes
-   aware will be disclosed, in accordance with Section 6 of BCP 79.
-   For the purposes of this document, the term "BCP 79" refers
-   exclusively to RFC 3979, "Intellectual Property Rights in IETF
-   Technology", published March 2005.
-
-   Internet-Drafts are working documents of the Internet Engineering
-   Task Force (IETF), its areas, and its working groups.  Note that
-   other groups may also distribute working documents as Internet-
-   Drafts.
-
-   Internet-Drafts are draft documents valid for a maximum of six months
-   and may be updated, replaced, or obsoleted by other documents at any
-   time.  It is inappropriate to use Internet-Drafts as reference
-   material or to cite them other than as "work in progress."
-
-   The list of current Internet-Drafts can be accessed at
-   http://www.ietf.org/1id-abstracts.html
-
-   The list of Internet-Draft Shadow Directories can be accessed at
-   http://www.ietf.org/shadow.html
-
-
-Abstract
-
-   This document describes a protocol for automating the process of
-   creating Network Address Translation (NAT) port mappings. Included
-   in the protocol is a method for retrieving the public IP address of
-   a NAT gateway, thus allowing a client to make this public IP address
-   and port number known to peers that may wish to communicate with it.
-   This protocol is implemented in current Apple products including
-   Mac OS X, Bonjour for Windows, and AirPort wireless base stations.
-
-
-
-
-
-
-
-
-
-
-Expires 14th March 2007        Cheshire, et al.                 [Page 1]
-\f
-Internet Draft          NAT Port Mapping Protocol    14th September 2006
-
-
-1. Introduction
-
-   Network Address Translation (NAT) is a method of sharing one public
-   internet address with a number of devices. This document is focused
-   on what "IP Network Address Translator (NAT) Terminology and
-   Considerations" [RFC 2663] calls "NAPTs" (Network Address/Port
-   Translators). A full description of NAT is beyond the scope of this
-   document. The following brief overview will cover the aspects
-   relevant to this port mapping protocol. For more information on
-   NAT, see "Traditional IP Network Address Translator" [RFC 3022].
-
-   NATs have one or more public IP addresses. A private network is set
-   up behind the NAT. Devices behind the NAT are assigned private
-   addresses and the private address of the NAT device is used as the
-   gateway.
-
-   When a packet from any device behind the NAT is sent to an address on
-   the public internet, the packet first passes through the NAT box. The
-   NAT box looks at the source port and address. In some cases, a NAT
-   will also keep track of the destination port and address. The NAT
-   then creates a mapping from the private address and private port to a
-   public address and public port if a mapping does not already exist. 
-   The NAT box replaces the private address and port number in the
-   packet with the public entries from the mapping and sends the packet
-   on to the next gateway.
-
-   When a packet from any address on the internet is received on the
-   NAT's public side, the NAT will look up the destination port (public
-   port) in the list of mappings. If an entry is found, it will contain
-   the private address and port that the packet should be sent to. The
-   NAT gateway will then rewrite the destination address and port with
-   those from the mapping. The packet will then be forwarded to the new
-   destination addresses. If the packet did not match any mapping, the
-   packet will most likely be dropped. Various NATs implement different
-   strategies to handle this. The important thing to note is that if
-   there is no mapping, the NAT does not know which private address the
-   packet should be sent to.
-
-   Mappings are usually created automatically as a result of observing
-   outbound traffic. There are a few exceptions. Some NATs may allow
-   manually-created permanent mappings that map a public port to a
-   specific private IP address and port. Such a mapping allows incoming
-   connections to the device with that private address. Some NATs also
-   implement a default mapping where any inbound traffic that does not
-   match a mapping will always be forwarded to a specific private
-   address. Both types of mappings are usually set up manually through
-   some configuration tool.
-
-   Without these manually-created inbound port mappings, clients behind
-   the NAT would be unable to receive inbound connections, which
-   represents a loss of connectivity when compared to the original
-
-
-Expires 14th March 2007        Cheshire, et al.                 [Page 2]
-\f
-Internet Draft          NAT Port Mapping Protocol    14th September 2006
-
-
-   Internet architecture [ETEAISD]. For those who view this loss of
-   connectivity as a bad thing, NAT-PMP allows clients to operate much
-   more like a host directly connected to the unrestricted public
-   Internet, with an unrestricted public IP address. NAT-PMP allows
-   client hosts to communicate with the NAT gateway to request the
-   creation of inbound mappings on demand. Having created a NAT mapping
-   to allow inbound connections, the client can then record its public
-   IP address and public port number in a public registry (e.g. the
-   world-wide Domain Name System) or otherwise make it accessible to
-   peers that wish to communicate with it.
-
-
-2. Conventions and Terminology Used in this Document
-
-   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
-   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
-   document are to be interpreted as described in "Key words for use in
-   RFCs to Indicate Requirement Levels" [RFC 2119].
-
-
-3. Protocol and Packet Format
-
-   NAT Port Mapping Protocol runs over UDP. Every packet starts with an
-   8 bit version followed by an 8 bit operation code.
-
-   This document specifies version 0 of the protocol. Any NAT-PMP
-   gateway implementing this version of the protocol, receiving a
-   packet with a version number other than 0, MUST return result code 1
-   (Unsupported Version).
-
-   Opcodes between 0 and 127 are client requests. Opcodes from 128 to
-   255 are server responses. Responses always contain a 16 bit result
-   code in network byte order. A result code of zero indicates success. 
-   Responses also contain a 32 bit unsigned integer corresponding to the
-   number of seconds since the NAT gateway was rebooted or since its
-   port mapping state was reset.
-
-   This protocol SHOULD only be used when the client determines that
-   its primary IPv4 address is in one of the private IP address ranges
-   defined in "Address Allocation for Private Internets" [RFC 1918].
-   This includes the address ranges 10/8, 172.16/12, and 192.168/16.
-
-   Clients always send their Port Mapping Protocol requests to their
-   default gateway, as learned via DHCP [RFC 2131], or similar means.
-   This protocol is designed for small home networks, with a single
-   logical link (subnet) where the client's default gateway is also the
-   NAT translator for that network. For more complicated networks where
-   the NAT translator is some device other than the client's default
-   gateway, this protocol is not appropriate.
-
-
-
-
-Expires 14th March 2007        Cheshire, et al.                 [Page 3]
-\f
-Internet Draft          NAT Port Mapping Protocol    14th September 2006
-
-
-3.1 Requests and Responses
-
-   NAT gateways are often low-cost devices, with limited memory and
-   CPU speed. For this reason, to avoid making excessive demands on
-   the NAT gateway, clients machines SHOULD NOT issue multiple requests
-   simultaneously in parallel. If a client needs to perform multiple
-   requests (e.g. on boot, wake from sleep, network connection, etc.)
-   it SHOULD queue them and issue them serially one at a time. Once the
-   NAT gateway responds to one request the client machine may issue the
-   next. In the case of a fast NAT gateway, the client may be able to
-   complete requests at a rate of hundreds per second. In the case of
-   a slow NAT gateway that takes perhaps half a second to respond to
-   a NAT-PMP request, the client SHOULD respect this and allow the
-   NAT gateway to operate at the pace it can manage, and not overload
-   it by issuing requests faster than the rate it's answering them.
-
-   To determine the puclic IP address or request a port mapping,
-   a NAT-PMP client sends its request packet to port 5351 of its
-   configured gateway address, and waits 250ms for a response. If no
-   NAT-PMP response is received from the gateway after 250ms, the client
-   retransmits its request and waits 500ms. The client SHOULD repeat
-   this process with the interval between attempts doubling each time.
-   If, after sending its 9th attempt (and then waiting for 64 seconds),
-   the client has still received no response, then it SHOULD conclude
-   that this gateway does not support NAT Port Mapping Protocol and
-   MAY log an error message indicating this fact. In addition, if the
-   NAT-PMP client receives an "ICMP Port Unreachable" message from the
-   gateway for port 5351 then it can skip any remaining retransmissions
-   and conclude immediately that the gateway does not support NAT-PMP.
-
-   As a performance optimization the client MAY record this information
-   and use it to suppress further attempts to use NAT-PMP, but the
-   client should not retain this information for too long. In
-   particular, any event that may indicate a potential change of gateway
-   or a change in gateway configuration (hardware link change
-   indication, change of gateway MAC address, acquisition of new DHCP
-   lease, receipt of NAT-PMP announcement packet from gateway, etc.)
-   should cause the client to discard its previous information regarding
-   the gateway's lack of NAT-PMP support, and send its next NAT-PMP
-   request packet normally.
-
-
-3.2 Determining the Public Address
-
-   To determine the public address, the client behind the NAT sends the
-   following UDP payload to port 5351 of the configured gateway address:
-
-    0                   1
-    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   | Vers = 0      | OP = 0        |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-Expires 14th March 2007        Cheshire, et al.                 [Page 4]
-\f
-Internet Draft          NAT Port Mapping Protocol    14th September 2006
-
-
-   A compatible NAT gateway MUST generate a response with the following
-   format:
-
-    0                   1                   2                   3
-    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   | Vers = 0      | OP = 128 + 0  | Result Code                   |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   | Seconds Since Start of Epoch                                  |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   | Public IP Address (a.b.c.d)                                   |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-   This response indicates that the NAT gateway implements this version
-   of the protocol and returns the public IP address of the NAT gateway.
-   If the result code is non-zero, the value of Public IP Address is
-   undefined (MUST be set to zero on transmission, and MUST be ignored
-   on reception).
-
-   The NAT gateway MUST fill in the "Seconds Since Start of Epoch" field
-   with the time elapsed since its port mapping table was initialized on
-   startup or reset for any other reason (see Section 3.6 "Seconds Since
-   Start of Epoch").
-
-   Upon receiving the response packet, the client MUST check the source
-   IP address, and silently discard the packet if the address is not the
-   address of the gateway to which the request was sent.
-
-
-3.2.1 Announcing Address Changes
-
-   When the public IP address of the NAT changes, the NAT gateway MUST
-   send a gratuitous response to the link-local multicast address
-   224.0.0.1, port 5351 with the packet format above to notify clients
-   of the new public IP address. To accommodate packet loss, the
-   NAT gateway SHOULD multicast 10 address change notifications.
-   The interval between the first two notifications SHOULD be 250ms,
-   and the interval between each subsequent notification SHOULD double.
-
-   Upon receiving a gratuitous address change announcement packet,
-   the client MUST check the source IP address, and silently discard
-   the packet if the address is not the address of the client's
-   current configured gateway. This is to guard against inadvertent
-   misconfigurations where there may be more than one NAT gateway
-   active on the network.
-
-
-
-
-
-
-
-
-Expires 14th March 2007        Cheshire, et al.                 [Page 5]
-\f
-Internet Draft          NAT Port Mapping Protocol    14th September 2006
-
-
-3.3 Creating a Mapping
-
-   To create a mapping, the client sends a UDP packet to port 5351
-   of the gateway's private IP address with the following format:
-
-    0                   1                   2                   3
-    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   | Vers = 0      | OP = x        | Reserved (MUST be zero)       |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   | Private Port                  | Requested Public Port         |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   | Requested Port Mapping Lifetime in Seconds                    |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-   Opcodes supported:
-   1 - Map UDP
-   2 - Map TCP
-
-   The Reserved field MUST be set to zero on transmission and MUST
-   be ignored on reception.
-
-   The Private Port is set to the local port on which the client is
-   listening.
-
-   The Requested Public Port SHOULD usually be set to the same value as
-   the local Private Port, or zero if the client has no preference for
-   what port is assigned. However, the gateway is not obliged to assign
-   the port requested, and may choose not to, either for policy reasons
-   (e.g. port 80 is reserved and clients may not request it) or because
-   that port has already been assigned to some other client. Because
-   of this, some product developers have questioned the value of having
-   the Requested Public Port field at all. The reason is for failure
-   recovery. Most low-cost home NAT gateways do not record temporary
-   port mappings in persistent storage, so if the gateway crashes or is
-   rebooted, all the mappings are lost. A renewal packet is formatted
-   identically to an initial mapping request packet, except that for
-   renewals the client sets the Requested Public Port field to the
-   port the gateway actually assigned, rather than the port the client
-   originally wanted. When a freshly-rebooted NAT gateway receives a
-   renewal packet from a client, it appears to the gateway just like
-   an ordinary initial request for a port mapping, except that in this
-   case the Requested Public Port is likely to be one that the NAT
-   gateway *is* willing to allocate (it allocated it to this client
-   right before the reboot, so it should presumably be willing to
-   allocate it again).
-
-   The RECOMMENDED Port Mapping Lifetime is 3600 seconds.
-
-
-
-
-
-Expires 14th March 2007        Cheshire, et al.                 [Page 6]
-\f
-Internet Draft          NAT Port Mapping Protocol    14th September 2006
-
-
-   After sending the port mapping request, the client then waits for the
-   NAT gateway to respond. If after 250ms, the gateway doesn't respond,
-   the client SHOULD re-issue its request as described above in Section
-   3.1 "Requests and Responses".
-
-   The NAT gateway responds with the following packet format:
-
-    0                   1                   2                   3
-    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   | Vers = 0      | OP = 128 + x  | Result Code                   |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   | Seconds Since Start of Epoch                                  |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   | Private Port                  | Mapped Public Port            |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   | Port Mapping Lifetime in Seconds                              |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-   The 'x' in the OP field MUST match what the client requested. Some
-   NAT gateways are incapable of creating a UDP port mapping without
-   also creating a corresponding TCP port mapping, and vice versa, and
-   these gateways MUST NOT implement NAT Port Mapping Protocol until
-   this deficiency is fixed. A NAT gateway which implements this
-   protocol MUST be able to create TCP-only and UDP-only port mappings. 
-
-   If a NAT gateway silently creates a pair of mappings for a client
-   that only requested one mapping, then it may expose that client to
-   receiving inbound UDP packets or inbound TCP connection requests
-   that it did not ask for and does not want.
-
-   While a NAT gateway MUST NOT automatically create mappings for TCP
-   when the client requests UDP, and vice versa, the NAT gateway MUST
-   reserve the companion port so the same client can choose to map it
-   in the future. For example, if a client requests to map TCP port 80,
-   as long as the client maintains the lease for that TCP port mapping,
-   another client with a different IP address MUST NOT be able to
-   successfully acquire the mapping for UDP port 80.
-
-   The client normally requests the public port matching the private
-   port. If that public port is not available, the NAT gateway MUST
-   return a public port that is available or return an error code if
-   no ports are available.
-
-   The source address of the packet MUST be used for the private address
-   in the mapping. This protocol is not intended to facilitate one
-   device behind a NAT creating mappings for other devices. If there
-   are legacy devices that require inbound mappings, permanent mappings
-   can be created manually by the administrator, just as they are today.
-
-
-
-
-Expires 14th March 2007        Cheshire, et al.                 [Page 7]
-\f
-Internet Draft          NAT Port Mapping Protocol    14th September 2006
-
-
-   If a mapping already exists for a given private port on a given local
-   client (whether that mapping was created explicitly using NAT-PMP,
-   implicitly as a result of an outgoing TCP SYN packet, or manually by
-   a human administrator) and that client requests another mapping for
-   the same private port (possibly requesting a different public port)
-   then the mapping request should succeed, returning the already-
-   assigned public port. This is necessary to handle the case where
-   a client requests a mapping with requested public port X, and is
-   granted a mapping with actual public port Y, but the acknowledgement
-   packet gets lost. When the client retransmits its mapping request,
-   it should get back the same positive acknowledgement as was sent (and
-   lost) the first time.
-
-   The NAT gateway SHOULD NOT accept mapping requests destined to the
-   NAT gateway's public IP address or received on its public network
-   interface. Only packets received on the private interface(s) with
-   a destination address matching the private address(es) of the NAT
-   gateway should be allowed.
-
-   The NAT gateway MUST fill in the "Seconds Since Start of Epoch" field
-   with the time elapsed since its port mapping table was initialized on
-   startup or reset for any other reason (see Section 3.6 "Seconds Since
-   Start of Epoch").
-
-   The Port Mapping Lifetime is an unsigned integer in seconds. The NAT
-   gateway MAY reduce the lifetime from what the client requested. The
-   NAT gateway SHOULD NOT offer a lease lifetime greater than that
-   requested by the client.
-
-   Upon receiving the response packet, the client MUST check the source
-   IP address, and silently discard the packet if the address is not the
-   address of the gateway to which the request was sent.
-
-   The client SHOULD begin trying to renew the mapping halfway to expiry
-   time, like DHCP. The renewal packet should look exactly the same as
-   a request packet, except that the client SHOULD set the requested
-   public port to what the NAT gateway previously mapped, not what the
-   client originally requested. As described above, this enables the
-   gateway to automatically recover its mapping state after a crash or
-   reboot.
-
-
-3.4 Destroying a Mapping
-
-   A mapping may be destroyed in a variety of ways. If a client fails
-   to renew a mapping, then when its lifetime expires the mapping MUST
-   be automatically deleted. In the common case where the gateway
-   device is a combined DHCP server and NAT gateway, when a client's
-   DHCP address lease expires, the gateway device MAY automatically
-   delete any mappings belonging to that client. Otherwise a new client
-   being assigned the same IP address could receive unexpected inbound
-
-
-Expires 14th March 2007        Cheshire, et al.                 [Page 8]
-\f
-Internet Draft          NAT Port Mapping Protocol    14th September 2006
-
-
-   UDP packets or inbound TCP connection requests that it did not ask
-   for and does not want.
-
-   A client MAY also send an explicit packet to request deletion of a
-   mapping that is no longer needed. A client requests explicit
-   deletion of a mapping by sending a message to the NAT gateway
-   requesting the mapping, with the Requested Lifetime in Seconds set
-   to 0. The requested public port MUST be set to zero by the client
-   on sending, and MUST be ignored by the gateway on reception.
-
-   When a mapping is destroyed successfully as a result of the client
-   explicitly requesting the deletion, the NAT gateway MUST send a
-   response packet which is formatted as defined in section 3.3
-   "Creating a Mapping". The response MUST contain a result code of 0,
-   the private port as indicated in the deletion request, a public port
-   of 0, and a lifetime of 0. The NAT gateway MUST respond to a request
-   to destroy a mapping that does not exist as if the request were
-   successful. This is because of the case where the acknowledgement is
-   lost, and the client retransmits its request to delete the mapping. 
-   In this case the second request to delete the mapping MUST return the
-   same response packet as the first request.
-
-   If the deletion request was unsuccessful, the response MUST contain a
-   non-zero result code and the requested mapping; the lifetime is
-   undefined (MUST be set to zero on transmission, and MUST be ignored
-   on reception). If the client attempts to delete a port mapping which
-   was manually assigned by some kind of configuration tool, the NAT
-   gateway MUST respond with a 'Not Authorized' error, result code 2.
-
-   When a mapping is destroyed as a result of its lifetime expiring or
-   for any other reason, if the NAT gateway's internal state indicates
-   that there are still active TCP connections traversing that now-
-   defunct mapping, then the NAT gateway SHOULD send appropriately-
-   constructed TCP RST (reset) packets both to the local client and to
-   the remote peer on the Internet to terminate that TCP connection.
-
-   A client can request the explicit deletion of all its UDP or TCP
-   mappings by sending the same deletion request to the NAT gateway
-   with public port, private port, and lifetime set to 0. A client MAY
-   choose to do this when it first acquires a new IP address in order to
-   protect itself from port mappings that were performed by a previous
-   owner of the IP address. After receiving such a deletion request,
-   the gateway MUST delete all its UDP or TCP port mappings (depending
-   on the opcode). The gateway responds to such a deletion request with
-   a response as described above, with the private port set to zero. If
-   the gateway is unable to delete a port mapping, for example, because
-   the mapping was manually configured by the administrator, the gateway
-   MUST still delete as many port mappings as possible, but respond with
-   a non-zero result code. The exact result code to return depends on
-   the cause of the failure. If the gateway is able to successfully
-   delete all port mappings as requested, it MUST respond with a result
-   code of 0.
-
-Expires 14th March 2007        Cheshire, et al.                 [Page 9]
-\f
-Internet Draft          NAT Port Mapping Protocol    14th September 2006
-
-
-3.5 Result Codes
-
-   Currently defined result codes:
-   0 - Success
-   1 - Unsupported Version
-   2 - Not Authorized/Refused
-       (e.g. box supports mapping, but user has turned feature off)
-   3 - Network Failure
-       (e.g. NAT box itself has not obtained a DHCP lease)
-   4 - Out of resources
-       (NAT box cannot create any more mappings at this time)
-   5 - Unsupported opcode
-
-   If the result code is non-zero, the format of the packet following
-   the result code may be truncated. For example, if the client sends a
-   request to the server with an opcode of 17 and the server does not
-   recognize that opcode, the server SHOULD respond with a message where
-   the opcode is 17 + 128 and the result code is 5 (opcode not
-   supported). Since the server does not understand the format of
-   opcode 17, it may not know what to place after the result code. In
-   some cases, relevant data may follow the opcode to identify the
-   operation that failed. For example, a client may request a mapping
-   but that mapping may fail due to resource exhaustion. The server
-   SHOULD respond with the result code to indicate resource exhaustion
-   (4) followed by the requested port mapping so the client may identify
-   which operation failed.
-
-   Clients MUST be able to properly handle result codes not defined in
-   this document. Undefined results codes MUST be treated as fatal
-   errors of the request.
-
-
-3.6 Seconds Since Start of Epoch
-
-   Every packet sent by the NAT gateway includes a "Seconds since start
-   of epoch" field (SSSOE). If the NAT gateway resets or loses the
-   state of its port mapping table, due to reboot, power failure, or any
-   other reason, it MUST reset its epoch time and begin counting SSSOE
-   from 0 again. Whenever a client receives any packet from the NAT
-   gateway, either gratuitously or in response to a client request, the
-   client computes its own conservative estimate of the expected SSSOE
-   value by taking the SSSOE value in the last packet it received from
-   the gateway and adding 7/8 (87.5%) of the time elapsed since that
-   packet was received. If the SSSOE in the newly received packet is
-   less than the client's conservative estimate by more than one second,
-   then the client concludes that the NAT gateway has undergone a reboot
-   or other loss of port mapping state, and the client MUST immediately
-   renew all its active port mapping leases as described in Section 3.7
-   "Recreating Mappings On NAT Gateway Reboot".
-
-
-
-
-Expires 14th March 2007        Cheshire, et al.                [Page 10]
-\f
-Internet Draft          NAT Port Mapping Protocol    14th September 2006
-
-
-3.7 Recreating Mappings On NAT Gateway Reboot
-
-   The NAT gateway MAY store mappings in persistent storage so when it
-   is powered off or rebooted, it remembers the port mapping state of
-   the network.
-
-   However, maintaining this state is not essential for correct
-   operation. When the NAT gateway powers on or clears its port mapping
-   state as the result of a configuration change, it MUST reset the
-   epoch time and re-announce its IP address as described in Section
-   3.2.1 "Announcing Address Changes". Reception of this packet where
-   time has apparently gone backwards serves as a hint to clients
-   on the network that they SHOULD immediately send renewal packets
-   (to immediately recreate their mappings) instead of waiting until
-   the originally scheduled time for those renewals. Clients who miss
-   receiving those gateway announcement packets for any reason will
-   still renew their mappings at the originally scheduled time and cause
-   their mappings to be recreated; it will just take a little longer for
-   these clients.
-
-   A mapping renewal packet is formatted identically to an original
-   mapping request; from the point of view of the client it is a
-   renewal of an existing mapping, but from the point of view of the
-   freshly-rebooted NAT gateway it appears as a new mapping request.
-
-   This self-healing property of the protocol is very important.
-
-   The remarkable reliability of the Internet as a whole derives
-   in large part from the fact that important state is held in the
-   endpoints, not in the network itself [ETEAISD]. Power-cycling an
-   Ethernet switch results only in a brief interruption in the flow
-   of packets; established TCP connections through that switch are not
-   broken, merely delayed for a few seconds. Indeed, an old Ethernet
-   switch can even be replaced with a new one, and as long as the cables
-   are transferred over reasonably quickly, after the upgrade all the
-   TCP connections that were previously going though the old switch will
-   be unbroken and now going through the new one. The same is true of
-   IP routers, wireless base stations, etc. The one exception is NAT
-   gateways. Because the port mapping state is required for the NAT
-   gateway to know where to forward inbound packets, loss of that state
-   breaks connectivity through the NAT gateway. By allowing clients to
-   detect when this loss of NAT gateway state has occurred, and recreate
-   it on demand, we turn hard state in the network into soft state, and
-   allow it to be recovered automatically when needed.
-
-   Without this automatic recreation of soft state in the NAT gateway,
-   reliable long-term networking would not be achieved. As mentioned
-   above, the reliability of the Internet does not come from trying
-   to build a perfect network in which errors never happen, but from
-   accepting that in any sufficiently large system there will always be
-   some component somewhere that's failing, and designing mechanisms
-
-
-Expires 14th March 2007        Cheshire, et al.                [Page 11]
-\f
-Internet Draft          NAT Port Mapping Protocol    14th September 2006
-
-
-   that can handle those failures and recover. To illustrate this point
-   with an example, consider the following scenario: Imagine a network
-   security camera that has a web interface and accepts incoming
-   connections from web browser clients. Imagine this network security
-   camera uses NAT-PMP or a similar protocol to set up an inbound
-   port mapping in the NAT gateway so that it can receive incoming
-   connections from clients the other side of the NAT gateway.
-   Now, this camera may well operate for weeks, months, or even years.
-   During that time it's possible that the NAT gateway could experience
-   a power failure or be rebooted. The user could upgrade the NAT
-   gateway's firmware, or even replace the entire NAT gateway device
-   with a newer model. The general point is that if the camera operates
-   for a long enough period of time, some kind of disruption to the NAT
-   gateway becomes inevitable. The question is not whether the NAT
-   gateway will lose its port mappings, but when, and how often.
-   If the network camera and devices like it on the network can detect
-   when the NAT gateway has lost its port mappings, and recreate them
-   automatically, then these disruptions are self-correcting and
-   invisible to the end user. If, on the other hand, the disruptions are
-   not self-correcting, and after a NAT gateway reboot the user has to
-   manually reset or reboot all the other devices on the network too,
-   then these disruptions are *very* visible to the end user. This
-   aspect of the design is what makes the difference between a protocol
-   that keeps on working indefinitely over a time scale of months or
-   years, and a protocol that works in brief testing, but in the real
-   world is continually failing and requiring manual intervention to get
-   it going again.
-
-   When a client renews its port mappings as the result of receiving
-   a packet where the "Seconds since start of epoch" field (SSSOE)
-   indicates that a reboot or similar loss of state has occurred,
-   the client MUST first delay by a random amount of time selected
-   with uniform random distribution in the range 0 to 5 seconds, and
-   then send its first port mapping request. After that request is
-   acknowledged by the gateway, the client may then send its second
-   request, and so on, as rapidly as the gateway allows. The requests
-   SHOULD be issued serially, one at a time; the client SHOULD NOT issue
-   multiple requests simultaneously in parallel.
-
-   The discussion in this section focusses on recreating inbound port
-   mappings after loss of NAT gateway state, because that is the more
-   serious problem. Losing port mappings for outgoing connections
-   destroys those currently active connections, but does not prevent
-   clients from establishing new outgoing connections. In contrast,
-   losing inbound port mappings not only destroys all existing inbound
-   connections, but also prevents the reception of any new inbound
-   connections until the port mapping is recreated. Accordingly,
-   we consider recovery of inbound port mappings the more important
-   priority. However, clients that want outgoing connections to survive
-   a NAT gateway reboot can also achieve that using NAT-PMP. After
-   initiating an outbound TCP connection (which will cause the NAT
-
-
-Expires 14th March 2007        Cheshire, et al.                [Page 12]
-\f
-Internet Draft          NAT Port Mapping Protocol    14th September 2006
-
-
-   gateway to establish an implicit port mapping) the client should send
-   the NAT gateway a port mapping request for the source port of its TCP
-   connection, which will cause the NAT gateway to send a response
-   giving the public port it allocated for that mapping. The client can
-   then store this information, and use later to recreate the mapping
-   if it determines that the NAT gateway has lost its mapping state.
-
-
-3.8 NAT Gateways with NAT Function Disabled
-
-   Note that *only* devices currently acting in the role of NAT gateway
-   should participate in NAT-PMP protocol exchanges with clients.
-   A network device that is capable of NAT (and NAT-PMP), but is
-   currently configured not to perform that function, (e.g. it is
-   acting as a traditional IP router, forwarding packets without
-   modifying them), MUST NOT respond to NAT-PMP requests from clients,
-   or send spontaneous NAT-PMP address-change announcements.
-
-   In particular, a network device not currently acting in the role of
-   NAT gateway should not even respond to NAT-PMP requests by returning
-   an error code such as "2 - Not Authorized/Refused", since to do so
-   is misleading to clients -- it suggests that NAT port mapping is
-   necessary on this network for the client to successfully receive
-   inbound connections, but is not available because the administrator
-   has chosen to disable that functionality.
-
-   Clients should also be careful to avoid making unfounded assumptions,
-   such as the assumption that if the client has an IPv4 address in
-   one of the RFC 1918 private IP address ranges then that means
-   NAT necessarily must be in use. Net 10/8 has enough addresses
-   to build a private network with millions of hosts and thousands
-   of interconnected subnets, all without any use of NAT. Many
-   organizations have built such private networks that benefit from
-   using standard TCP/IP technology, but by choice do not connect
-   to the public Internet. The purpose of NAT-PMP is to mitigate some
-   of the damage caused by NAT. It would be an ironic and unwanted
-   side-effect of this protocol if it were to lead well-meaning but
-   misguided developers to create products that refuse to work on a
-   private network *unless* they can find a NAT gateway to talk to.
-   Consequently, a client finding that NAT-PMP is not available on its
-   network should not give up, but should proceed on the assumption
-   that the network may be a traditional routed IP network, with no
-   address translation being used. This assumption may not always be
-   true, but it is better than the alternative of falsely assuming
-   the worst and not even trying to use normal (non-NAT) IP networking.
-
-   If a network device not currently acting in the role of NAT gateway
-   receives UDP packets addressed to port 5351, it SHOULD respond
-   immediately with an "ICMP Port Unreachable" message to tell the
-   client that it needn't continue with timeouts and retransmissions,
-   and it should assume that NAT-PMP is not available and not needed
-   on this network.
-
-Expires 14th March 2007        Cheshire, et al.                [Page 13]
-\f
-Internet Draft          NAT Port Mapping Protocol    14th September 2006
-
-
-4. UNSAF Considerations
-
-   The document "IAB Considerations for UNSAF Across NAT" [RFC 3424]
-   covers a number of issues when working with NATs. RFC 3424 outlines
-   some requirements for any document that attempts to work around
-   problems associated with NATs. This section addresses those
-   requirements.
-
-
-4.1 Scope
-
-   This protocol addresses the needs of TCP and UDP transport peers that
-   are separated from the public internet by exactly one NAT. Such
-   peers must have access to some form of directory server for
-   registering the public IP address and port at which they can be
-   reached.
-
-
-4.2 Transition Plan
-
-   Any client making use of this protocol SHOULD implement IPv6 support.
-   If a client supports IPv6 and is running on a device with a global
-   IPv6 address, that IPv6 address SHOULD be preferred to the IPv4
-   public address using this NAT mapping protocol. In case other
-   clients do not have IPv6 connectivity, both the IPv4 and IPv6
-   addresses SHOULD be registered with whatever form of directory server
-   is used. Preference SHOULD be given to IPv6 addresses when
-   available. By implementing support for IPv6 and using this protocol
-   for IPv4, vendors can ship products today that will work under both
-   scenarios. As IPv6 is more widely deployed, clients of this protocol
-   following these recommendations will transparently make use of IPv6.
-
-
-4.3 Failure Cases
-
-   Aside from NATs that do not implement this protocol, there are a
-   number of situations where this protocol may not work.
-
-
-4.3.1 NAT Behind NAT
-
-   Some people's primary IP address, assigned by their ISP, may itself
-   be a NAT address. In addition, some people may have a public IP
-   address, but may then double NAT themselves, perhaps by choice or
-   perhaps by accident. Although it might be possible in principle for
-   one NAT gateway to recursively request a mapping from the next one,
-   this document does not advocate that and does not try to prescribe
-   how it would be done.
-
-   It would be a lot of work to implement nested NAT port mapping
-   correctly, and there are a number of reasons why the end result might
-
-
-Expires 14th March 2007        Cheshire, et al.                [Page 14]
-\f
-Internet Draft          NAT Port Mapping Protocol    14th September 2006
-
-
-   not be as useful as we might hope. Consider the case of an ISP that
-   offers each of its customers only a single NAT address. This ISP
-   could instead have chosen to provide each customer with a single
-   public IP address, or, if the ISP insists on running NAT, it could
-   have chosen to allow each customer a reasonable number of addresses,
-   enough for each customer device to have its own NAT address directly
-   from the ISP. If instead this ISP chooses to allow each customer
-   just one and only one NAT address, forcing said customer to run
-   nested NAT in order to use more than one device, it seems unlikely
-   that such an ISP would be so obliging as to provide a NAT service
-   that supports NAT Port Mapping Protocol. Supposing that such an ISP
-   did wish to offer its customers NAT service with NAT-PMP so as to
-   give them the ability to receive inbound connections, this ISP could
-   easily choose to allow each client to request a reasonable number of
-   DHCP addresses from that gateway. Remember that Net 10/8 [RFC 1918]
-   allows for over 16 million addresses, so NAT addresses are not in any
-   way in short supply. A single NAT gateway with 16 million available
-   addresses is likely to run out of packet forwarding capacity before
-   it runs out of private addresses to hand out. In this way the ISP
-   could offer single-level NAT with NAT-PMP, obviating the need to
-   support nested NAT-PMP. In addition, an ISP that is motivated to
-   provide their customers with unhindered access to the Internet by
-   allowing incoming as well as outgoing connections has better ways
-   to offer this service. Such an ISP could offer its customers real
-   public IP addresses instead of NAT addresses, or could even choose
-   to offer its customers full IPv6 connectivity, where no mapping or
-   translation is required at all.
-
-
-4.3.2 NATs with Multiple Public IP Addresses
-
-   If a NAT maps private addresses to multiple public addresses,
-   then it SHOULD pick one of those addresses as the one it will
-   support for inbound connections, and for the purposes of this
-   protocol it SHOULD act as if that address were its only address.
-
-
-4.3.3 NATs and Routed Private Networks
-
-   In some cases, a large network may be subnetted. Some sites
-   may install a NAT gateway and subnet the private network.
-   Such subnetting breaks this protocol because the router address
-   is not necessarily the address of the device performing NAT.
-
-   Addressing this problem is not a high priority. Any site with the
-   resources to set up such a configuration should have the resources to
-   add manual mappings or attain a range of globally unique addresses.
-
-   Not all NATs will support this protocol. In the case where a client
-   is run behind a NAT that does not support this protocol, the software
-   relying on the functionality of this protocol may be unusable.
-
-
-Expires 14th March 2007        Cheshire, et al.                [Page 15]
-\f
-Internet Draft          NAT Port Mapping Protocol    14th September 2006
-
-
-4.3.4 Communication Between Hosts Behind the Same NAT
-
-   NAT gateways supporting NAT-PMP should also implement "hairpin
-   translation". Hairpin translation means supporting communication
-   between two local clients being served by the same NAT gateway.
-
-   Suppose device A is listening on private address and port 10.0.0.2:80
-   for incoming connections. Using NAT-PMP, device A has obtained a
-   mapping to public address and port x.x.x.x:80, and has recorded this
-   public address and port in a public directory of some kind. For
-   example, it could have created a DNS SRV record containing this
-   information, and recorded it, using DNS Dynamic Update [RFC 3007], in
-   a publicly accessible DNS server. Suppose then that device B, behind
-   the same NAT gateway as device A, but unknowing or uncaring of this
-   fact, retrieves device A's DNS SRV record and attempts to open a TCP
-   connection to x.x.x.x:80. The outgoing packets addressed to this
-   public Internet address will be sent to the NAT gateway for
-   translation and forwarding. Having translated the source address and
-   port number on the outgoing packet, the NAT gateway needs to be smart
-   enough to recognize that the destination address is in fact itself,
-   and then feed this packet back into its packet reception engine, to
-   perform the destination port mapping lookup to translate and forward
-   this packet to device A at address and port 10.0.0.2:80.
-
-4.3.5 Non UDP/TCP Transport Traffic
-
-   Any communication over transport protocols other than TCP and UDP
-   will not be served by this protocol. Examples are Generic Routing
-   Encapsulation (GRE), Authentication Header (AH) and Encapsulating
-   Security Payload (ESP).
-
-4.4 Long Term Solution
-
-   As IPv6 is deployed, clients of this protocol supporting IPv6 will be
-   able to bypass this protocol and the NAT when communicating with
-   other IPv6 devices. In order to ensure this transition, any client
-   implementing this protocol SHOULD also implement IPv6 and use this
-   solution only when IPv6 is not available to both peers.
-
-4.5 Existing Deployed NATs
-
-   Existing deployed NATs will not support this protocol. This protocol
-   will only work with NATs that are upgraded to support it.
-
-
-
-
-
-
-
-
-
-
-Expires 14th March 2007        Cheshire, et al.                [Page 16]
-\f
-Internet Draft          NAT Port Mapping Protocol    14th September 2006
-
-
-5. Security Considerations
-
-   As discussed in section 3.2 "Determining the Public Address", only
-   clients on the private side of the NAT may create port mappings, and
-   only on behalf of themselves. By using IP address spoofing, it's
-   possible for one client to delete the port mappings of another
-   client. It's also possible for one client to create port mappings on
-   behalf of another client. The best way to deal with this
-   vulnerability is to use IPSec [RFC 2401].
-
-   Since allowing incoming connections is often a policy decision, any
-   NAT gateway implementing this protocol SHOULD have an administrative
-   mechanism to disable it.
-
-   Some people view the property that NATs block inbound connections as
-   a security benefit which is undermined by this protocol. The authors
-   of this document have a different point of view. In the days before
-   NAT, all hosts had unique public IP addresses, and had unhindered
-   ability to communicate with any other host on the Internet. When NAT
-   came along it broke this unhindered connectivity, relegating many
-   hosts to second-class status, unable to receive inbound connections.
-   This protocol goes some way to undo some of that damage. The purpose
-   of a NAT gateway should be to allow several hosts to share a single
-   address, not to simultaneously impede those host's ability to
-   communicate freely. Security is most properly provided by end-to-end
-   cryptographic security, and/or by explicit firewall functionality, as
-   appropriate. Blocking of certain connections should occur only as a
-   result of explicit and intentional firewall policy, not as an
-   accidental side-effect of some other technology.
-
-
-6. IANA Considerations
-
-   No IANA services are required by this document.
-
-
-7. Acknowledgments
-
-   The concepts described in this document have been explored, developed
-   and implemented with help from Bob Bradley, Josh Graessley, Rob
-   Newberry, Roger Pantos, John Saxton, and James Woodyatt.
-
-
-8. Deployment History
-
-   NAT-PMP client software first became available to the public
-   through Apple's Darwin Open Source code in August 2004.
-   NAT-PMP implementations began shipping to end users in large
-   volumes (i.e. millions) with the launch of Mac OS X 10.4 Tiger
-   and Bonjour for Windows 1.0 in April 2005.
-
-
-
-Expires 14th March 2007        Cheshire, et al.                [Page 17]
-\f
-Internet Draft          NAT Port Mapping Protocol    14th September 2006
-
-
-   The NAT-PMP client in Mac OS X 10.4 Tiger and Bonjour for Windows
-   exists as part of the mDNSResponder system service. When a client
-   advertises a service using Wide Area Bonjour [DNS-SD], and the
-   machine is behind a NAT-PMP-capable NAT gateway, then if the machine
-   is so configured, the mDNSResponder system service automatically uses
-   NAT-PMP to set up an inbound port mapping, and then records the
-   public IP address and port in the global DNS. Existing client
-   software using the existing Bonjour programming APIs [Bonjour]
-   gets this functionality automatically. The logic is that if client
-   software publishes its information into the global DNS via Wide Area
-   Bonjour service advertising, then it's reasonable to infer an
-   expectation that this information should be usable by the peers
-   retrieving it. Generally speaking, recording a private IP address
-   like 10.0.0.2 in the public DNS is completely pointless because that
-   address is not reachable from clients on the other side of the NAT
-   gateway. In the case of a home user with a single computer directly
-   connected to their Cable or DSL modem, with a single global IPv4
-   address and no NAT gateway (a surprisingly common configuration),
-   publishing that IP address into the global DNS is useful because that
-   IP address is reachable. In contrast, a home user using a NAT gateway
-   to share a single global IPv4 address between several computers loses
-   this ability to receive inbound connections easily. This breaks many
-   peer-to-peer collaborative applications, like the multi-user text
-   editor SubEthaEdit [SEE]. Automatically creating the necessary
-   inbound port mappings helps remedy this unintended side-effect of
-   NAT.
-
-   The server side of the NAT-PMP protocol is implemented in Apple's
-   "AirPort Extreme" and "AirPort Express" wireless base stations.
-
-
-9. Copyright Notice
-
-   Copyright (C) The Internet Society (2006).
-
-   This document is subject to the rights, licenses and restrictions
-   contained in BCP 78, and except as set forth therein, the authors
-   retain all their rights. For the purposes of this document,
-   the term "BCP 78" refers exclusively to RFC 3978, "IETF Rights
-   in Contributions", published March 2005.
-
-   This document and the information contained herein are provided on
-   an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE
-   REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE
-   INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR
-   IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF
-   THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
-   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-
-
-
-
-Expires 14th March 2007        Cheshire, et al.                [Page 18]
-\f
-Internet Draft          NAT Port Mapping Protocol    14th September 2006
-
-
-10. Normative References
-
-   [RFC 1918] Y. Rekhter et.al., "Address Allocation for Private
-              Internets", RFC 1918, February 1996.
-
-   [RFC 2119] RFC 2119 - Key words for use in RFCs to Indicate
-              Requirement Levels
-
-
-11. Informative References
-
-   [Bonjour]  Apple "Bonjour" <http://developer.apple.com/bonjour/>
-
-   [ETEAISD]  J. Saltzer, D. Reed and D. Clark: "End-to-end arguments in
-              system design", ACM Trans. Comp. Sys., 2(4):277-88, Nov.
-              1984
-
-   [DNS-SD]   Cheshire, S., and M. Krochmal, "DNS-Based Service
-              Discovery", Internet-Draft (work in progress),
-              draft-cheshire-dnsext-dns-sd-04.txt, August 2006.
-
-   [mDNS]     Cheshire, S., and M. Krochmal, "Multicast DNS",
-              Internet-Draft (work in progress),
-              draft-cheshire-dnsext-multicastdns-06.txt, August 2006.
-
-   [RFC 2131] R. Droms, "Dynamic Host Configuration Protocol", RFC 2131,
-              March 1997.
-
-   [RFC 2401] Atkinson, R. and S. Kent, "Security Architecture for the
-              Internet Protocol", RFC 2401, November 1998.
-
-   [RFC 2663] Srisuresh, P. and M. Holdrege, "IP Network Address
-              Translator (NAT) Terminology and Considerations", RFC
-              2663, August 1999.
-
-   [RFC 3007] Wellington, B., "Simple Secure Domain Name System
-              (DNS) Dynamic Update", RFC 3007, November 2000.
-
-   [SEE]      <http://www.codingmonkeys.de/subethaedit/>
-
-   [RFC 3022] RFC 3022 - Network Address Translator
-
-   [RFC 3424] RFC 3424 - IAB Considerations for UNilateral Self-Address
-              Fixing (UNSAF) Across Network Address Translation
-
-
-
-
-
-
-
-
-
-Expires 14th March 2007        Cheshire, et al.                [Page 19]
-\f
-Internet Draft          NAT Port Mapping Protocol    14th September 2006
-
-
-12. Authors' Addresses
-
-   Stuart Cheshire
-   Apple Computer, Inc.
-   1 Infinite Loop
-   Cupertino
-   California 95014
-   USA
-
-   Phone: +1 408 974 3207
-   EMail: rfc [at] stuartcheshire [dot] org
-
-
-   Marc Krochmal
-   Apple Computer, Inc.
-   1 Infinite Loop
-   Cupertino
-   California 95014
-   USA
-
-   Phone: +1 408 974 4368
-   EMail: marc [at] apple [dot] com
-
-
-   Kiren Sekar
-   Sharpcast, Inc.
-   250 Cambridge Ave, Suite 101
-   Palo Alto
-   California 94306
-   USA
-
-   Phone: +1 650 323 1960
-   EMail: ksekar [at] sharpcast [dot] com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Expires 14th March 2007        Cheshire, et al.                [Page 20]
diff --git a/src/upnp/test_upnp.c b/src/upnp/test_upnp.c
deleted file mode 100644 (file)
index f20028d..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
-     This file is part of GNUnet.
-     (C) 2006 Christian Grothoff (and other contributing authors)
-
-     GNUnet 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 3, or (at your
-     option) any later version.
-
-     GNUnet 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 GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-     Boston, MA 02111-1307, USA.
-*/
-/**
- * @file upnp/test_upnp.c
- * @brief Testcase for UPnP
- * @author Christian Grothoff
- */
-
-#include "gnunet_util.h"
-#include "gnunet_upnp_service.h"
-#include "gnunet_core.h"
-#include "platform.h"
-
-
-
-int
-main (int argc, const char *argv[])
-{
-  static GNUNET_CoreAPIForPlugins capi;
-  struct GNUNET_GE_Context *ectx;
-  struct GNUNET_GC_Configuration *cfg;
-  struct in_addr addr;
-  int i;
-  GNUNET_UPnP_ServiceAPI *upnp;
-  struct GNUNET_PluginHandle *plug;
-  GNUNET_ServicePluginInitializationMethod init;
-  GNUNET_ServicePluginShutdownMethod done;
-  char ntop_buf[INET_ADDRSTRLEN];
-
-  ectx = GNUNET_GE_create_context_stderr (GNUNET_NO,
-                                          GNUNET_GE_WARNING | GNUNET_GE_ERROR
-                                          | GNUNET_GE_FATAL | GNUNET_GE_USER |
-                                          GNUNET_GE_ADMIN |
-                                          GNUNET_GE_DEVELOPER |
-                                          GNUNET_GE_IMMEDIATE |
-                                          GNUNET_GE_BULK);
-  GNUNET_GE_setDefaultContext (ectx);
-  cfg = GNUNET_GC_create ();
-  GNUNET_GE_ASSERT (ectx, cfg != NULL);
-  GNUNET_os_init (ectx);
-  capi.ectx = ectx;
-  capi.cfg = cfg;
-  plug = GNUNET_plugin_load (ectx, "libgnunet", "module_upnp");
-  if (plug == NULL)
-    {
-      GNUNET_GC_free (cfg);
-      GNUNET_GE_free_context (ectx);
-      return 1;
-    }
-  init = GNUNET_plugin_resolve_function (plug, "provide_", GNUNET_YES);
-  if (init == NULL)
-    {
-      GNUNET_plugin_unload (plug);
-      GNUNET_GC_free (cfg);
-      GNUNET_GE_free_context (ectx);
-      return 1;
-    }
-  upnp = init (&capi);
-  if (upnp == NULL)
-    {
-      GNUNET_plugin_unload (plug);
-      GNUNET_GC_free (cfg);
-      GNUNET_GE_free_context (ectx);
-      return 1;
-    }
-  for (i = 0; i < 10; i++)
-    {
-      if (GNUNET_shutdown_test () != GNUNET_NO)
-        break;
-      if (GNUNET_OK == upnp->get_ip (2086, "TCP", &addr))
-        {
-          printf ("UPnP returned external IP %s\n",
-                  inet_ntop (AF_INET, &addr, ntop_buf, INET_ADDRSTRLEN));
-        }
-      else
-        {
-          /* we cannot be sure that there is a UPnP-capable
-             NAT-box out there, so test should not fail
-             just because of this! */
-          printf ("No UPnP response (yet).\n");
-        }
-      GNUNET_thread_sleep (2 * GNUNET_CRON_SECONDS);
-    }
-  done = GNUNET_plugin_resolve_function (plug, "release_", GNUNET_YES);
-  if (done != NULL)
-    done ();
-  GNUNET_plugin_unload (plug);
-  GNUNET_GC_free (cfg);
-  GNUNET_GE_free_context (ectx);
-  return 0;
-}
-
-/* end of upnptest.c */
diff --git a/src/upnp/upnp.c b/src/upnp/upnp.c
deleted file mode 100644 (file)
index 5e15b12..0000000
+++ /dev/null
@@ -1,721 +0,0 @@
-/**
- * @file upnp/upnp.c UPnP Implementation
- * @ingroup core
- *
- * gaim
- *
- * Gaim is the legal property of its developers, whose names are too numerous
- * to list here.  Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include "platform.h"
-#include "upnp_xmlnode.h"
-#include "upnp_util.h"
-#include "upnp.h"
-
-#include <curl/curl.h>
-
-#define TRUE GNUNET_YES
-#define FALSE GNUNET_NO
-#define g_return_if_fail(a) if(!(a)) return;
-#define g_return_val_if_fail(a, val) if(!(a)) return (val);
-
-#define HTTP_OK "200 OK"
-#define NUM_UDP_ATTEMPTS 2
-#define HTTPMU_HOST_ADDRESS "239.255.255.250"
-#define HTTPMU_HOST_PORT 1900
-#define SEARCH_REQUEST_DEVICE "urn:schemas-upnp-org:service:%s"
-#define SEARCH_REQUEST_STRING \
-  "M-SEARCH * HTTP/1.1\r\n" \
-  "MX: 2\r\n" \
-  "HOST: 239.255.255.250:1900\r\n" \
-  "MAN: \"ssdp:discover\"\r\n" \
-  "ST: urn:schemas-upnp-org:service:%s\r\n" \
-  "\r\n"
-#define WAN_IP_CONN_SERVICE "WANIPConnection:1"
-#define WAN_PPP_CONN_SERVICE "WANPPPConnection:1"
-#define HTTP_POST_SOAP_HEADER \
-        "SOAPACTION: \"urn:schemas-upnp-org:service:%s#%s\""
-#define HTTP_POST_SIZE_HEADER "CONTENT-LENGTH: %u"
-#define SOAP_ACTION \
-  "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" \
-  "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" " \
-       "s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\r\n" \
-    "<s:Body>\r\n" \
-      "<u:%s xmlns:u=\"urn:schemas-upnp-org:service:%s\">\r\n" \
-        "%s" \
-      "</u:%s>\r\n" \
-    "</s:Body>\r\n" \
-  "</s:Envelope>"
-#define PORT_MAPPING_LEASE_TIME "0"
-#define PORT_MAPPING_DESCRIPTION "GNUNET_UPNP_PORT_FORWARD"
-#define ADD_PORT_MAPPING_PARAMS \
-  "<NewRemoteHost></NewRemoteHost>\r\n" \
-  "<NewExternalPort>%i</NewExternalPort>\r\n" \
-  "<NewProtocol>%s</NewProtocol>\r\n" \
-  "<NewInternalPort>%i</NewInternalPort>\r\n" \
-  "<NewInternalClient>%s</NewInternalClient>\r\n" \
-  "<NewEnabled>1</NewEnabled>\r\n" \
-  "<NewPortMappingDescription>" \
-  PORT_MAPPING_DESCRIPTION \
-  "</NewPortMappingDescription>\r\n" \
-  "<NewLeaseDuration>" \
-  PORT_MAPPING_LEASE_TIME \
-  "</NewLeaseDuration>\r\n"
-#define DELETE_PORT_MAPPING_PARAMS \
-  "<NewRemoteHost></NewRemoteHost>\r\n" \
-  "<NewExternalPort>%i</NewExternalPort>\r\n" \
-  "<NewProtocol>%s</NewProtocol>\r\n"
-
-typedef enum
-{
-  GAIM_UPNP_STATUS_UNDISCOVERED = -1,
-  GAIM_UPNP_STATUS_UNABLE_TO_DISCOVER,
-  GAIM_UPNP_STATUS_DISCOVERING,
-  GAIM_UPNP_STATUS_DISCOVERED
-} GaimUPnPStatus;
-
-typedef struct
-{
-  GaimUPnPStatus status;
-  char *control_url;
-  const char *service_type;
-  char publicip[16];
-} GaimUPnPControlInfo;
-
-typedef struct
-{
-  const char *service_type;
-  char *full_url;
-  char *buf;
-  unsigned int buf_len;
-  struct GNUNET_NETWORK_Handle *sock;
-} UPnPDiscoveryData;
-
-static GaimUPnPControlInfo control_info = {
-  GAIM_UPNP_STATUS_UNDISCOVERED,
-  NULL,
-  NULL,
-  "",
-};
-
-/**
- * This is the signature used for functions that act as a callback
- * to CURL.
- */
-typedef size_t (*GaimUtilFetchUrlCallback) (void *url_data,
-                                            size_t size,
-                                            size_t nmemb, void *user_data);
-
-
-
-static char *
-g_strstr_len (const char *haystack, int haystack_len, const char *needle)
-{
-  int i;
-
-  g_return_val_if_fail (haystack != NULL, NULL);
-  g_return_val_if_fail (needle != NULL, NULL);
-
-  if (haystack_len < 0)
-    return strstr (haystack, needle);
-  else
-    {
-      const char *p = haystack;
-      int needle_len = strlen (needle);
-      const char *end = haystack + haystack_len - needle_len;
-
-      if (needle_len == 0)
-        return (char *) haystack;
-
-      while (*p && p <= end)
-        {
-          for (i = 0; i < needle_len; i++)
-            if (p[i] != needle[i])
-              goto next;
-
-          return (char *) p;
-
-        next:
-          p++;
-        }
-    }
-
-  return NULL;
-}
-
-static int
-gaim_upnp_compare_device (const xmlnode * device, const char *deviceType)
-{
-  xmlnode *deviceTypeNode = xmlnode_get_child (device, "deviceType");
-  char *tmp;
-  int ret;
-
-  if (deviceTypeNode == NULL)
-    return FALSE;
-  tmp = xmlnode_get_data (deviceTypeNode);
-  ret = !strcasecmp (tmp, deviceType);
-  GNUNET_free (tmp);
-  return ret;
-}
-
-static int
-gaim_upnp_compare_service (const xmlnode * service, const char *serviceType)
-{
-  xmlnode *serviceTypeNode;
-  char *tmp;
-  int ret;
-
-  if (service == NULL)
-    return FALSE;
-  serviceTypeNode = xmlnode_get_child (service, "serviceType");
-  if (serviceTypeNode == NULL)
-    return FALSE;
-  tmp = xmlnode_get_data (serviceTypeNode);
-  ret = !strcasecmp (tmp, serviceType);
-  GNUNET_free (tmp);
-  return ret;
-}
-
-static char *
-gaim_upnp_parse_description_response (const char *httpResponse,
-                                      size_t len,
-                                      const char *httpURL,
-                                      const char *serviceType)
-{
-  char *xmlRoot, *baseURL, *controlURL, *service;
-  xmlnode *xmlRootNode, *serviceTypeNode, *controlURLNode, *baseURLNode;
-  char *tmp;
-
-  /* find the root of the xml document */
-  xmlRoot = g_strstr_len (httpResponse, len, "<root");
-  if (xmlRoot == NULL)
-    return NULL;
-  if (g_strstr_len (httpResponse, len, "</root") == NULL)
-    return NULL;
-
-  /* create the xml root node */
-  xmlRootNode = xmlnode_from_str (xmlRoot, len - (xmlRoot - httpResponse));
-  if (xmlRootNode == NULL)
-    return NULL;
-
-  /* get the baseURL of the device */
-  baseURLNode = xmlnode_get_child (xmlRootNode, "URLBase");
-  if (baseURLNode != NULL)
-    {
-      baseURL = xmlnode_get_data (baseURLNode);
-    }
-  else
-    {
-      baseURL = GNUNET_strdup (httpURL);
-    }
-
-  /* get the serviceType child that has the service type as its data */
-  /* get urn:schemas-upnp-org:device:InternetGatewayDevice:1 and its devicelist */
-  serviceTypeNode = xmlnode_get_child (xmlRootNode, "device");
-  while (!gaim_upnp_compare_device (serviceTypeNode,
-                                    "urn:schemas-upnp-org:device:InternetGatewayDevice:1")
-         && serviceTypeNode != NULL)
-    {
-      serviceTypeNode = xmlnode_get_next_twin (serviceTypeNode);
-    }
-  if (serviceTypeNode == NULL)
-    {
-      GNUNET_free (baseURL);
-      xmlnode_free (xmlRootNode);
-      return NULL;
-    }
-  serviceTypeNode = xmlnode_get_child (serviceTypeNode, "deviceList");
-  if (serviceTypeNode == NULL)
-    {
-      GNUNET_free (baseURL);
-      xmlnode_free (xmlRootNode);
-      return NULL;
-    }
-
-  /* get urn:schemas-upnp-org:device:WANDevice:1 and its devicelist */
-  serviceTypeNode = xmlnode_get_child (serviceTypeNode, "device");
-  while (!gaim_upnp_compare_device (serviceTypeNode,
-                                    "urn:schemas-upnp-org:device:WANDevice:1")
-         && serviceTypeNode != NULL)
-    {
-      serviceTypeNode = xmlnode_get_next_twin (serviceTypeNode);
-    }
-  if (serviceTypeNode == NULL)
-    {
-      GNUNET_free (baseURL);
-      xmlnode_free (xmlRootNode);
-      return NULL;
-    }
-  serviceTypeNode = xmlnode_get_child (serviceTypeNode, "deviceList");
-  if (serviceTypeNode == NULL)
-    {
-      GNUNET_free (baseURL);
-      xmlnode_free (xmlRootNode);
-      return NULL;
-    }
-
-  /* get urn:schemas-upnp-org:device:WANConnectionDevice:1 and its servicelist */
-  serviceTypeNode = xmlnode_get_child (serviceTypeNode, "device");
-  while (serviceTypeNode && !gaim_upnp_compare_device (serviceTypeNode,
-                                                       "urn:schemas-upnp-org:device:WANConnectionDevice:1"))
-    {
-      serviceTypeNode = xmlnode_get_next_twin (serviceTypeNode);
-    }
-  if (serviceTypeNode == NULL)
-    {
-      GNUNET_free (baseURL);
-      xmlnode_free (xmlRootNode);
-      return NULL;
-    }
-  serviceTypeNode = xmlnode_get_child (serviceTypeNode, "serviceList");
-  if (serviceTypeNode == NULL)
-    {
-      GNUNET_free (baseURL);
-      xmlnode_free (xmlRootNode);
-      return NULL;
-    }
-
-  /* get the serviceType variable passed to this function */
-  service = g_strdup_printf (SEARCH_REQUEST_DEVICE, serviceType);
-  serviceTypeNode = xmlnode_get_child (serviceTypeNode, "service");
-  while (!gaim_upnp_compare_service (serviceTypeNode, service) &&
-         serviceTypeNode != NULL)
-    {
-      serviceTypeNode = xmlnode_get_next_twin (serviceTypeNode);
-    }
-
-  GNUNET_free (service);
-  if (serviceTypeNode == NULL)
-    {
-      GNUNET_free (baseURL);
-      xmlnode_free (xmlRootNode);
-      return NULL;
-    }
-
-  /* get the controlURL of the service */
-  if ((controlURLNode = xmlnode_get_child (serviceTypeNode,
-                                           "controlURL")) == NULL)
-    {
-      GNUNET_free (baseURL);
-      xmlnode_free (xmlRootNode);
-      return NULL;
-    }
-
-  tmp = xmlnode_get_data (controlURLNode);
-  if (baseURL && !gaim_str_has_prefix (tmp, "http://") &&
-      !gaim_str_has_prefix (tmp, "HTTP://"))
-    {
-      if (tmp[0] == '/')
-        {
-          size_t len;
-          const char *end;
-          /* absolute path */
-          end = strstr (&baseURL[strlen ("http://")], "/");
-          if (end == NULL)
-            len = strlen (&baseURL[strlen ("http://")]);
-          else
-            len = end - &baseURL[strlen ("http://")];
-          controlURL = g_strdup_printf ("http://%.*s%s",
-                                        len,
-                                        &baseURL[strlen ("http://")], tmp);
-        }
-      else
-        {
-          controlURL = g_strdup_printf ("%s%s", baseURL, tmp);
-        }
-      GNUNET_free (tmp);
-    }
-  else
-    {
-      controlURL = tmp;
-    }
-  GNUNET_free (baseURL);
-  xmlnode_free (xmlRootNode);
-
-  return controlURL;
-}
-
-#define CURL_EASY_SETOPT(c, a, b) do { ret = curl_easy_setopt(c, a, b); if (ret != CURLE_OK) GNUNET_log(GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, _("%s failed at %s:%d: `%s'\n"), "curl_easy_setopt", __FILE__, __LINE__, curl_easy_strerror(ret)); } while (0);
-
-/**
- * Do the generic curl setup.
- */
-static int
-setup_curl (const char *proxy, CURL * curl)
-{
-  int ret;
-
-  CURL_EASY_SETOPT (curl, CURLOPT_FAILONERROR, 1);
-  if (strlen (proxy) > 0)
-    CURL_EASY_SETOPT (curl, CURLOPT_PROXY, proxy);
-  CURL_EASY_SETOPT (curl, CURLOPT_BUFFERSIZE, 1024);    /* a bit more than one HELLO */
-  CURL_EASY_SETOPT (curl, CURLOPT_CONNECTTIMEOUT, 150L);
-  /* NOTE: use of CONNECTTIMEOUT without also
-     setting NOSIGNAL results in really weird
-     crashes on my system! */
-  CURL_EASY_SETOPT (curl, CURLOPT_NOSIGNAL, 1);
-  return GNUNET_OK;
-}
-
-static int
-gaim_upnp_generate_action_message_and_send (const char *proxy,
-                                            const char *actionName,
-                                            const char *actionParams,
-                                            GaimUtilFetchUrlCallback cb,
-                                            void *cb_data)
-{
-  CURL *curl;
-  int ret;
-  char *soapHeader;
-  char *sizeHeader;
-  char *soapMessage;
-  struct curl_slist *headers = NULL;
-
-  GNUNET_assert (cb != NULL);
-  if (0 != curl_global_init (CURL_GLOBAL_WIN32))
-    return GNUNET_SYSERR;
-  /* set the soap message */
-  soapMessage = g_strdup_printf (SOAP_ACTION,
-                                 actionName,
-                                 control_info.service_type,
-                                 actionParams, actionName);
-  soapHeader = g_strdup_printf (HTTP_POST_SOAP_HEADER,
-                                control_info.service_type, actionName);
-  sizeHeader = g_strdup_printf (HTTP_POST_SIZE_HEADER, strlen (soapMessage));
-  curl = curl_easy_init ();
-  setup_curl (proxy, curl);
-  CURL_EASY_SETOPT (curl, CURLOPT_URL, control_info.control_url);
-  CURL_EASY_SETOPT (curl, CURLOPT_WRITEFUNCTION, cb);
-  CURL_EASY_SETOPT (curl, CURLOPT_WRITEDATA, cb_data);
-  CURL_EASY_SETOPT (curl, CURLOPT_POST, 1);
-  headers = curl_slist_append (headers,
-                               "CONTENT-TYPE: text/xml ; charset=\"utf-8\"");
-  headers = curl_slist_append (headers, soapHeader);
-  headers = curl_slist_append (headers, sizeHeader);
-  CURL_EASY_SETOPT (curl, CURLOPT_HTTPHEADER, headers);
-  CURL_EASY_SETOPT (curl, CURLOPT_POSTFIELDS, soapMessage);
-  CURL_EASY_SETOPT (curl, CURLOPT_POSTFIELDSIZE, strlen (soapMessage));
-  CURL_EASY_SETOPT (curl, CURLOPT_MAXREDIRS, 1L);
-  CURL_EASY_SETOPT (curl, CURLOPT_CONNECTTIMEOUT, 1L);
-  CURL_EASY_SETOPT (curl, CURLOPT_TIMEOUT, 2L);
-  /* NOTE: use of CONNECTTIMEOUT without also
-     setting NOSIGNAL results in really weird
-     crashes on my system! */
-  CURL_EASY_SETOPT (curl, CURLOPT_NOSIGNAL, 1);
-  if (ret == CURLE_OK)
-    ret = curl_easy_perform (curl);
-#if 0
-  if (ret != CURLE_OK)
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
-                _
-                ("%s failed for url `%s' and post-data `%s' at %s:%d: `%s'\n"),
-                "curl_easy_perform", control_info.control_url, soapMessage,
-                __FILE__, __LINE__, curl_easy_strerror (ret));
-#endif
-  curl_slist_free_all (headers);
-  curl_easy_cleanup (curl);
-  curl_global_cleanup ();
-  GNUNET_free (sizeHeader);
-  GNUNET_free (soapMessage);
-  GNUNET_free (soapHeader);
-  if (ret != CURLE_OK)
-    return GNUNET_SYSERR;
-  return GNUNET_OK;
-}
-
-
-static size_t
-looked_up_public_ip_cb (void *url_data,
-                        size_t size, size_t nmemb, void *user_data)
-{
-  UPnPDiscoveryData *dd = user_data;
-  size_t len = size * nmemb;
-  const char *temp;
-  const char *temp2;
-
-  if (len + dd->buf_len > 1024 * 1024 * 4)
-    return 0;                   /* refuse to process - too big! */
-  GNUNET_array_grow (dd->buf, dd->buf_len, dd->buf_len + len);
-  memcpy (&dd->buf[dd->buf_len - len], url_data, len);
-  if (dd->buf_len == 0)
-    return len;
-  /* extract the ip, or see if there is an error */
-  if ((temp = g_strstr_len (dd->buf,
-                            dd->buf_len, "<NewExternalIPAddress")) == NULL)
-    return len;
-  if (!(temp = g_strstr_len (temp, dd->buf_len - (temp - dd->buf), ">")))
-    return len;
-  if (!(temp2 = g_strstr_len (temp, dd->buf_len - (temp - dd->buf), "<")))
-    return len;
-  memset (control_info.publicip, 0, sizeof (control_info.publicip));
-  if (temp2 - temp >= sizeof (control_info.publicip))
-    temp2 = temp + sizeof (control_info.publicip) - 1;
-  memcpy (control_info.publicip, temp + 1, temp2 - (temp + 1));
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO | GNUNET_ERROR_TYPE_BULK,
-              _("upnp: NAT Returned IP: %s\n"), control_info.publicip);
-  return len;
-}
-
-
-static size_t
-ignore_response (void *url_data, size_t size, size_t nmemb, void *user_data)
-{
-  return size * nmemb;
-}
-
-/**
- * Process downloaded bits of service description.
- */
-static size_t
-upnp_parse_description_cb (void *httpResponse,
-                           size_t size, size_t nmemb, void *user_data)
-{
-  UPnPDiscoveryData *dd = user_data;
-  size_t len = size * nmemb;
-  char *control_url = NULL;
-
-  if (len + dd->buf_len > 1024 * 1024 * 4)
-    return len;                 /* refuse to process - too big! */
-  GNUNET_array_grow (dd->buf, dd->buf_len, dd->buf_len + len);
-  memcpy (&dd->buf[dd->buf_len - len], httpResponse, len);
-  if (dd->buf_len > 0)
-    control_url = gaim_upnp_parse_description_response (dd->buf,
-                                                        dd->buf_len,
-                                                        dd->full_url,
-                                                        dd->service_type);
-  control_info.status = control_url ? GAIM_UPNP_STATUS_DISCOVERED
-    : GAIM_UPNP_STATUS_UNABLE_TO_DISCOVER;
-  GNUNET_free_non_null (control_info.control_url);
-  control_info.control_url = control_url;
-  control_info.service_type = dd->service_type;
-  return len;
-}
-
-static int
-gaim_upnp_parse_description (char *proxy, UPnPDiscoveryData * dd)
-{
-  CURL *curl;
-  int ret;
-
-  if (0 != curl_global_init (CURL_GLOBAL_WIN32))
-    return GNUNET_SYSERR;
-  curl = curl_easy_init ();
-  setup_curl (proxy, curl);
-  ret = CURLE_OK;
-  CURL_EASY_SETOPT (curl, CURLOPT_URL, dd->full_url);
-  CURL_EASY_SETOPT (curl, CURLOPT_WRITEFUNCTION, &upnp_parse_description_cb);
-  CURL_EASY_SETOPT (curl, CURLOPT_WRITEDATA, dd);
-  CURL_EASY_SETOPT (curl, CURLOPT_MAXREDIRS, 1L);
-  CURL_EASY_SETOPT (curl, CURLOPT_CONNECTTIMEOUT, 1L);
-  CURL_EASY_SETOPT (curl, CURLOPT_TIMEOUT, 2L);
-
-  /* NOTE: use of CONNECTTIMEOUT without also
-     setting NOSIGNAL results in really weird
-     crashes on my system! */
-  CURL_EASY_SETOPT (curl, CURLOPT_NOSIGNAL, 1);
-  ret = curl_easy_perform (curl);
-  if (ret != CURLE_OK)
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
-                _("%s failed at %s:%d: `%s'\n"),
-                "curl_easy_perform", __FILE__, __LINE__,
-                curl_easy_strerror (ret));
-  curl_easy_cleanup (curl);
-  curl_global_cleanup ();
-  if (control_info.control_url == NULL)
-    return GNUNET_SYSERR;
-  return GNUNET_OK;
-}
-
-int
-gaim_upnp_discover (struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_NETWORK_Handle *sock)
-{
-  char *proxy;
-  socklen_t avail;
-  struct sockaddr_in server;
-  int retry_count;
-  char *sendMessage;
-  size_t totalSize;
-  int sentSuccess;
-  char buf[65536];
-  int buf_len;
-  const char *startDescURL;
-  const char *endDescURL;
-  int ret;
-  UPnPDiscoveryData dd;
-  struct sockaddr *sa;
-
-  memset (&dd, 0, sizeof (UPnPDiscoveryData));
-  if (control_info.status == GAIM_UPNP_STATUS_DISCOVERING)
-    return GNUNET_NO;
-  dd.sock = sock;
-  memset (&server, 0, sizeof (struct sockaddr_in));
-  server.sin_family = AF_INET;
-  avail = sizeof (struct sockaddr_in);
-  sa = (struct sockaddr *) &server;
-  if (GNUNET_OK !=
-      GNUNET_get_ip_from_hostname (HTTPMU_HOST_ADDRESS, AF_INET, &sa, &avail))
-    {
-      return GNUNET_SYSERR;
-    }
-  server.sin_port = htons (HTTPMU_HOST_PORT);
-  control_info.status = GAIM_UPNP_STATUS_DISCOVERING;
-
-  /* because we are sending over UDP, if there is a failure
-     we should retry the send NUM_UDP_ATTEMPTS times. Also,
-     try different requests for WANIPConnection and WANPPPConnection */
-  for (retry_count = 0; retry_count < NUM_UDP_ATTEMPTS; retry_count++)
-    {
-      sentSuccess = FALSE;
-      if ((retry_count % 2) == 0)
-        dd.service_type = WAN_IP_CONN_SERVICE;
-      else
-        dd.service_type = WAN_PPP_CONN_SERVICE;
-      sendMessage = g_strdup_printf (SEARCH_REQUEST_STRING, dd.service_type);
-      totalSize = strlen (sendMessage);
-      do
-        {
-          if (SENDTO (dd.sock,
-                      sendMessage,
-                      totalSize,
-                      0,
-                      (struct sockaddr *) &server,
-                      sizeof (struct sockaddr_in)) == totalSize)
-            {
-              sentSuccess = TRUE;
-              break;
-            }
-        }
-      while (((errno == EINTR) || (errno == EAGAIN)) &&
-             (GNUNET_shutdown_test () == GNUNET_NO));
-      GNUNET_free (sendMessage);
-      if (sentSuccess)
-        break;
-    }
-  if (sentSuccess == FALSE)
-    return GNUNET_SYSERR;
-
-  /* try to read response */
-  do
-    {
-      buf_len = GNUNET_IO_recv (dd.sock, buf, sizeof (buf) - 1, 0);
-      if (buf_len > 0)
-        {
-          buf[buf_len] = '\0';
-          break;
-        }
-      else if (errno != EINTR)
-        {
-          continue;
-        }
-    }
-  while ((errno == EINTR) && (GNUNET_shutdown_test () == GNUNET_NO));
-
-  /* parse the response, and see if it was a success */
-  if (g_strstr_len (buf, buf_len, HTTP_OK) == NULL)
-    return GNUNET_SYSERR;
-  if ((startDescURL = g_strstr_len (buf, buf_len, "http://")) == NULL)
-    return GNUNET_SYSERR;
-
-  endDescURL = g_strstr_len (startDescURL,
-                             buf_len - (startDescURL - buf), "\r");
-  if (endDescURL == NULL)
-    endDescURL = g_strstr_len (startDescURL,
-                               buf_len - (startDescURL - buf), "\n");
-  if (endDescURL == NULL)
-    return GNUNET_SYSERR;
-  if (endDescURL == startDescURL)
-    return GNUNET_SYSERR;
-  dd.full_url = GNUNET_strdup (startDescURL);
-  dd.full_url[endDescURL - startDescURL] = '\0';
-  proxy = NULL;
-  GNUNET_CONFIGURATION_get_value_string (cfg,
-                                         "GNUNETD", "HTTP-PROXY", &proxy);
-  ret = gaim_upnp_parse_description (proxy, &dd);
-  GNUNET_free (dd.full_url);
-  GNUNET_array_grow (dd.buf, dd.buf_len, 0);
-  if (ret == GNUNET_OK)
-    {
-      ret = gaim_upnp_generate_action_message_and_send (proxy,
-                                                        "GetExternalIPAddress",
-                                                        "",
-                                                        looked_up_public_ip_cb,
-                                                        &dd);
-      GNUNET_array_grow (dd.buf, dd.buf_len, 0);
-    }
-  GNUNET_free (proxy);
-  return ret;
-}
-
-const char *
-gaim_upnp_get_public_ip ()
-{
-  if ((control_info.status == GAIM_UPNP_STATUS_DISCOVERED)
-      && (strlen (control_info.publicip) > 0))
-    return control_info.publicip;
-  return NULL;
-}
-
-int
-gaim_upnp_change_port_mapping (struct GNUNET_CONFIGURATION_Handle *cfg,
-                               int do_add,
-                               unsigned short portmap, const char *protocol)
-{
-  const char *action_name;
-  char *action_params;
-  char *internal_ip;
-  char *proxy;
-  int ret;
-
-  if (control_info.status != GAIM_UPNP_STATUS_DISCOVERED)
-    return GNUNET_NO;
-  if (do_add)
-    {
-      internal_ip = GNUNET_upnp_get_internal_ip (cfg);
-      if (internal_ip == NULL)
-        {
-          gaim_debug_error ("upnp",
-                            "gaim_upnp_set_port_mapping(): couldn't get local ip\n");
-          return GNUNET_NO;
-        }
-      action_name = "AddPortMapping";
-      action_params = g_strdup_printf (ADD_PORT_MAPPING_PARAMS,
-                                       portmap,
-                                       protocol, portmap, internal_ip);
-      GNUNET_free (internal_ip);
-    }
-  else
-    {
-      action_name = "DeletePortMapping";
-      action_params = g_strdup_printf (DELETE_PORT_MAPPING_PARAMS,
-                                       portmap, protocol);
-    }
-  proxy = NULL;
-  GNUNET_CONFIGURATION_get_value_string (cfg,
-                                         "GNUNETD", "HTTP-PROXY", &proxy);
-  ret =
-    gaim_upnp_generate_action_message_and_send (proxy, action_name,
-                                                action_params,
-                                                &ignore_response, NULL);
-
-  GNUNET_free (action_params);
-  GNUNET_free (proxy);
-  return ret;
-}
-
-/* end of upnp.c */
diff --git a/src/upnp/upnp.h b/src/upnp/upnp.h
deleted file mode 100644 (file)
index 537f9f3..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/**
- * @file upnp/upnp.h Universal Plug N Play API
- * @ingroup core
- *
- * gaim
- *
- * Gaim is the legal property of its developers, whose names are too numerous
- * to list here.  Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef _GAIM_UPNP_H_
-#define _GAIM_UPNP_H_
-
-#include <libxml/parser.h>
-#include <string.h>
-#include "gnunet_util_lib.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#if 0                           /* keep Emacsens' auto-indent happy */
-}
-#endif
-#endif
-
-/**
- * Sends a discovery request to search for a UPnP enabled IGD that
- * contains the WANIPConnection service that will allow us to receive the
- * public IP address of the IGD, and control it for forwarding ports.
- * The result will be cached for further use.
- */
-int gaim_upnp_discover (struct GNUNET_CONFIGURATION_Handle *cfg, int sock);
-
-/**
- * Gets the IP address from a UPnP enabled IGD that sits on the local
- * network, so when getting the network IP, instead of returning the
- * local network IP, the public IP is retrieved.  This is a cached value from
- * the time of the UPnP discovery.
- *
- * @return The IP address of the network, or NULL if something went wrong
- */
-const char *gaim_upnp_get_public_ip (void);
-
-/**
- * Maps Ports in a UPnP enabled IGD that sits on the local network to
- * this gaim client. Essentially, this function takes care of the port
- * forwarding so things like file transfers can work behind NAT firewalls
- *
- * @param cfg configuration to use
- * @param do_add TRUE/GNUNET_YES to add, FALSE/GNUNET_NO to remove
- * @param portmap The port to map to this client
- * @param protocol The protocol to map, either "TCP" or "UDP"
- */
-int gaim_upnp_change_port_mapping (struct GNUNET_CONFIGURATION_Handle *cfg,
-                                   int do_add,
-                                   uint16_t portmap, const char *protocol);
-
-#if 0                           /* keep Emacsens' auto-indent happy */
-{
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _GAIM_UPNP_H_ */
diff --git a/src/upnp/upnp_init.c b/src/upnp/upnp_init.c
deleted file mode 100644 (file)
index 2c612e1..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
-     This file is part of GNUnet
-     (C) 2006 Christian Grothoff (and other contributing authors)
-
-     GNUnet 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 3, or (at your
-     option) any later version.
-
-     GNUnet 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 GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-     Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file upnp/upnp_init.c
- * @brief API for UPnP access
- * @author Christian Grothoff
- */
-
-#include "platform.h"
-#include "gnunet_util.h"
-#include "upnp.h"
-#include "gnunet_upnp_service.h"
-#include "gnunet_core.h"
-
-static struct GNUNET_GE_Context *ectx;
-
-static struct GNUNET_GC_Configuration *cfg;
-
-static struct GNUNET_CronManager *cron;
-
-static struct GNUNET_Mutex *lock;
-
-typedef struct
-{
-  unsigned short port;
-  const char *proto;
-} PMap;
-
-static PMap *maps;
-
-static unsigned int maps_size;
-
-static struct GNUNET_ThreadHandle *discovery;
-
-static struct GNUNET_NETWORK_Handle *discovery_socket;
-
-/**
- * Obtain the public/external IP address.
- *
- * @return GNUNET_SYSERR on error, GNUNET_OK on success
- */
-static int
-gnunet_upnp_get_public_ip (struct in_addr *address)
-{
-  const char *ip;
-  socklen_t socklen;
-  struct sockaddr *sa;
-  struct sockaddr_in s4;
-  int ret;
-
-  ip = gaim_upnp_get_public_ip ();
-  if (ip == NULL)
-    return GNUNET_SYSERR;
-  socklen = sizeof (struct sockaddr_in);
-  sa = (struct sockaddr *) &s4;
-  ret = GNUNET_get_ip_from_hostname (NULL, ip, AF_INET, &sa, &socklen);
-  if (ret == GNUNET_OK)
-    *address = s4.sin_addr;
-  return ret;
-}
-
-static void
-kill_discovery ()
-{
-  void *unused;
-
-  if (discovery != NULL)
-    {
-      GNUNET_IO_shutdown (discovery_socket, SHUT_RDWR);
-      GNUNET_IO_close (&discovery_socket);
-      GNUNET_thread_join (discovery, &unused);
-      discovery = NULL;
-    }
-}
-
-static void *
-discover_thread ()
-{
-  gaim_upnp_discover (ectx, cfg, discovery_socket);
-  return NULL;
-}
-
-/**
- * Periodically try to (re)discover UPnP access points.
- */
-static void
-discover (void *unused)
-{
-  kill_discovery ();
-  discovery_socket = GNUNET_IO_socket (PF_INET, SOCK_DGRAM, 0);
-  if (NULL == discovery_socket)
-    return;
-  discovery = GNUNET_thread_create (&discover_thread, NULL, 1024 * 128);
-}
-
-/**
- * Periodically repeat our requests for port mappings.
- */
-static void
-portmap (void *unused)
-{
-  unsigned int i;
-
-  GNUNET_mutex_lock (lock);
-  for (i = 0; i < maps_size; i++)
-    gaim_upnp_change_port_mapping (ectx,
-                                   cfg, GNUNET_NO, maps[i].port,
-                                   maps[i].proto);
-  GNUNET_mutex_unlock (lock);
-}
-
-
-/**
- * Get the external IP address for the local machine.
- *
- * @return GNUNET_SYSERR on error, GNUNET_OK on success
- */
-static int
-gnunet_upnp_get_ip (unsigned short port,
-                    const char *protocol, struct in_addr *address)
-{
-  unsigned int i;
-
-  GNUNET_mutex_lock (lock);
-  for (i = 0; i < maps_size; i++)
-    if ((0 == strcmp (maps[i].proto, protocol)) && (maps[i].port == port))
-      break;
-  if (i == maps_size)
-    {
-      /* new entry! */
-      GNUNET_array_grow (maps, maps_size, maps_size + 1);
-      maps[i].proto = protocol;
-      maps[i].port = port;
-      gaim_upnp_change_port_mapping (ectx, cfg, GNUNET_YES, port, protocol);
-    }
-  GNUNET_mutex_unlock (lock);
-  return gnunet_upnp_get_public_ip (address);
-}
-
-
-/**
- * Get the external IP address for the local machine.
- */
-GNUNET_UPnP_ServiceAPI *
-provide_module_upnp (GNUNET_CoreAPIForPlugins * capi)
-{
-  static GNUNET_UPnP_ServiceAPI api;
-
-  ectx = capi->ectx;
-  cfg = capi->cfg;
-  cron = GNUNET_cron_create (ectx);
-  lock = GNUNET_mutex_create (GNUNET_NO);
-  GNUNET_cron_start (cron);
-  GNUNET_cron_add_job (cron, &discover, 0, 5 * GNUNET_CRON_MINUTES, NULL);
-  GNUNET_cron_add_job (cron, &portmap, 150 * GNUNET_CRON_SECONDS,
-                       5 * GNUNET_CRON_MINUTES, NULL);
-  api.get_ip = gnunet_upnp_get_ip;
-  return &api;
-}
-
-/**
- * Shutdown UPNP.
- */
-int
-release_module_upnp ()
-{
-  unsigned int i;
-
-  if (cron == NULL)
-    return GNUNET_SYSERR;       /* not loaded! */
-  for (i = 0; i < maps_size; i++)
-    gaim_upnp_change_port_mapping (ectx,
-                                   cfg, GNUNET_NO, maps[i].port,
-                                   maps[i].proto);
-  GNUNET_cron_stop (cron);
-  GNUNET_cron_del_job (cron, &discover, 5 * GNUNET_CRON_MINUTES, NULL);
-  GNUNET_cron_del_job (cron, &portmap, 5 * GNUNET_CRON_MINUTES, NULL);
-  GNUNET_cron_destroy (cron);
-  kill_discovery ();
-  cron = NULL;
-  GNUNET_mutex_destroy (lock);
-  lock = NULL;
-  GNUNET_array_grow (maps, maps_size, 0);
-  ectx = NULL;
-  cfg = NULL;
-  return GNUNET_OK;
-}
-
-
-/* end of init.c */
diff --git a/src/upnp/upnp_ip.c b/src/upnp/upnp_ip.c
deleted file mode 100644 (file)
index 928f02b..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
-     This file is part of GNUnet.
-     (C) 2006, 2007 Christian Grothoff (and other contributing authors)
-
-     GNUnet 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 3, or (at your
-     option) any later version.
-
-     GNUnet 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 GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-     Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file upnp/upnp_ip.c
- * @brief code to determine the IP of the local machine
- *
- * @author Christian Grothoff
- */
-
-#include <stdlib.h>
-#include "platform.h"
-#include "gnunet_util.h"
-#include "ip.h"
-
-/**
- * Get the IP address for the local machine.
- * @return NULL on error
- */
-char *
-GNUNET_upnp_get_internal_ip (struct GNUNET_GC_Configuration *cfg,
-                             struct GNUNET_GE_Context *ectx)
-{
-  struct in_addr address;
-
-  return GNUNET_get_local_ip (cfg, ectx, &address);
-}
-
-
-/* end of ip.c */
diff --git a/src/upnp/upnp_ip.h b/src/upnp/upnp_ip.h
deleted file mode 100644 (file)
index 1b80d32..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
-     This file is part of GNUnet.
-     (C) 2001, 2002, 2003, 2004, 2005 Christian Grothoff (and other contributing authors)
-
-     GNUnet 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 3, or (at your
-     option) any later version.
-
-     GNUnet 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 GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-     Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file upnp/upnp_ip.h
- * @brief
- *
- * @author Christian Grothoff
- */
-
-#ifndef IP_H
-#define IP_H
-
-
-/**
- * Get the IP address for the local machine.
- * @return NULL on error
- */
-char *GNUNET_upnp_get_internal_ip (struct GNUNET_GC_Configuration *cfg,
-                                   struct GNUNET_GE_Context *ectx);
-
-
-#endif
diff --git a/src/upnp/upnp_util.c b/src/upnp/upnp_util.c
deleted file mode 100644 (file)
index a080b64..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * @file upnp_util.cUtility Functions
- * @ingroup core
- *
- * Gaim is the legal property of its developers, whose names are too numerous
- * to list here.  Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include "platform.h"
-#include "util.h"
-#include "gnunet_util.h"
-
-/* Returns a NULL-terminated string after unescaping an entity
- * (eg. &amp;, &lt; &#38 etc.) starting at s. Returns NULL on failure.*/
-static char *
-detect_entity (const char *text, int *length)
-{
-  const char *pln;
-  int len;
-  int pound;
-  char b[7];
-  char *buf;
-
-  if (!text || *text != '&')
-    return NULL;
-
-#define IS_ENTITY(s)  (!strncasecmp(text, s, (len = sizeof(s) - 1)))
-
-  if (IS_ENTITY ("&amp;"))
-    pln = "&";
-  else if (IS_ENTITY ("&lt;"))
-    pln = "<";
-  else if (IS_ENTITY ("&gt;"))
-    pln = ">";
-  else if (IS_ENTITY ("&nbsp;"))
-    pln = " ";
-  else if (IS_ENTITY ("&copy;"))
-    pln = "\302\251";           /* or use g_unichar_to_utf8(0xa9); */
-  else if (IS_ENTITY ("&quot;"))
-    pln = "\"";
-  else if (IS_ENTITY ("&reg;"))
-    pln = "\302\256";           /* or use g_unichar_to_utf8(0xae); */
-  else if (IS_ENTITY ("&apos;"))
-    pln = "\'";
-  else if (*(text + 1) == '#' && (sscanf (text, "&#%u;", &pound) == 1) &&
-           pound != 0 && *(text + 3 + (int) log10 (pound)) == ';')
-    {
-      buf = GNUNET_convert_string_to_utf8 (NULL,
-                                           (const char *) &pound,
-                                           2, "UNICODE");
-      if (strlen (buf) > 6)
-        buf[6] = '\0';
-      strcpy (b, buf);
-      pln = b;
-      GNUNET_free (buf);
-      len = 2;
-      while (isdigit ((int) text[len]))
-        len++;
-      if (text[len] == ';')
-        len++;
-    }
-  else
-    return NULL;
-
-  if (length)
-    *length = len;
-  return GNUNET_strdup (pln);
-}
-
-char *
-g_strdup_printf (const char *fmt, ...)
-{
-  size_t size;
-  char *buf;
-  va_list va;
-
-  va_start (va, fmt);
-  size = VSNPRINTF (NULL, 0, fmt, va) + 1;
-  va_end (va);
-  buf = GNUNET_malloc (size);
-  va_start (va, fmt);
-  VSNPRINTF (buf, size, fmt, va);
-  va_end (va);
-  return buf;
-}
-
-char *
-gaim_unescape_html (const char *html)
-{
-  if (html != NULL)
-    {
-      const char *c = html;
-      char *ret = GNUNET_strdup ("");
-      char *app;
-      while (*c)
-        {
-          int len;
-          char *ent;
-
-          if ((ent = detect_entity (c, &len)) != NULL)
-            {
-              app = g_strdup_printf ("%s%s", ret, ent);
-              GNUNET_free (ret);
-              ret = app;
-              c += len;
-              GNUNET_free (ent);
-            }
-          else if (!strncmp (c, "<br>", 4))
-            {
-              app = g_strdup_printf ("%s%s", ret, "\n");
-              GNUNET_free (ret);
-              ret = app;
-              c += 4;
-            }
-          else
-            {
-              app = g_strdup_printf ("%s%c", ret, *c);
-              GNUNET_free (ret);
-              ret = app;
-              c++;
-            }
-        }
-      return ret;
-    }
-  return NULL;
-}
-
-
-int
-gaim_str_has_prefix (const char *s, const char *p)
-{
-  if ((s == NULL) || (p == NULL))
-    return 0;
-  return !strncmp (s, p, strlen (p));
-}
-
-/* end of util.c */
diff --git a/src/upnp/upnp_util.h b/src/upnp/upnp_util.h
deleted file mode 100644 (file)
index 1c7555b..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * @file upnp/upnp_util.h Utility Functions
- * @ingroup core
- *
- * gaim
- *
- * Gaim is the legal property of its developers, whose names are too numerous
- * to list here.  Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * @todo Rename the functions so that they live somewhere in the gaim
- *       namespace.
- */
-#ifndef _GAIM_UTIL_H_
-#define _GAIM_UTIL_H_
-
-#include <stdio.h>
-#include <string.h>
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/**
- * Unescapes HTML entities to their literal characters.
- * For example "&amp;" is replaced by '&' and so on.
- * Actually only "&amp;", "&quot;", "&lt;" and "&gt;" are currently
- * supported.
- *
- * @param html The string in which to unescape any HTML entities
- *
- * @return the text with HTML entities literalized
- */
-  char *gaim_unescape_html (const char *html);
-
-/**
- * Compares two strings to see if the first contains the second as
- * a proper prefix.
- *
- * @param s  The string to check.
- * @param p  The prefix in question.
- *
- * @return   TRUE if p is a prefix of s, otherwise FALSE.
- */
-  int gaim_str_has_prefix (const char *s, const char *p);
-
-  char *g_strdup_printf (const char *fmt, ...);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/src/upnp/upnp_xmlnode.c b/src/upnp/upnp_xmlnode.c
deleted file mode 100644 (file)
index 46e66e1..0000000
+++ /dev/null
@@ -1,487 +0,0 @@
-/**
- * @file upnp/upnp_xmlnode.c XML DOM functions
- *
- * gaim
- *
- * Gaim is the legal property of its developers, whose names are too numerous
- * to list here.  Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-/* A lot of this code at least resembles the code in libxode, but since
- * libxode uses memory pools that we simply have no need for, I decided to
- * write my own stuff.  Also, re-writing this lets me be as lightweight
- * as I want to be.  Thank you libxode for giving me a good starting point */
-
-#include "platform.h"
-
-#include "util.h"
-#include "gnunet_util.h"
-#include "xmlnode.h"
-
-#include <libxml/parser.h>
-#include <string.h>
-
-
-#ifdef _WIN32
-# define NEWLINE_S "\r\n"
-#else
-# define NEWLINE_S "\n"
-#endif
-
-#define TRUE GNUNET_YES
-#define FALSE GNUNET_NO
-
-#define g_return_if_fail(a) if(!(a)) return;
-#define g_return_val_if_fail(a, val) if(!(a)) return (val);
-
-/**
- * The valid types for an xmlnode
- */
-typedef enum _XMLNodeType
-{
-  XMLNODE_TYPE_TAG,     /**< Just a tag */
-  XMLNODE_TYPE_ATTRIB,          /**< Has attributes */
-  XMLNODE_TYPE_DATA     /**< Has data */
-} XMLNodeType;
-
-typedef struct
-{
-  xmlnode *current;
-  xmlnode **nodes;
-  unsigned int pos;
-  unsigned int size;
-} XMLNodePool;
-
-struct _xmlnode
-{
-  char *name;           /**< The name of the node. */
-  char *xmlns;          /**< The namespace of the node */
-  XMLNodeType type;     /**< The type of the node. */
-  char *data;           /**< The data for the node. */
-  size_t data_sz;               /**< The size of the data. */
-  struct _xmlnode *parent;  /**< The parent node or @c NULL.*/
-  struct _xmlnode *child;       /**< The child node or @c NULL.*/
-  struct _xmlnode *lastchild;  /**< The last child node or @c NULL.*/
-  struct _xmlnode *next;        /**< The next node or @c NULL. */
-  XMLNodePool *pool;
-  int free_pool;                /* set to GNUNET_YES for the root node, which must free the pool */
-};
-
-
-static void *
-g_memdup (const void *data, size_t s)
-{
-  void *ret;
-
-  ret = GNUNET_malloc (s);
-  memcpy (ret, data, s);
-  return ret;
-}
-
-static char *
-g_string_append_len (char *prefix, const void *data, size_t s)
-{
-  char *ret;
-
-  ret = g_strdup_printf ("%s%.*s", prefix, s, data);
-  GNUNET_free (prefix);
-  return ret;
-}
-
-static xmlnode *
-new_node (const char *name, XMLNodeType type, void *user_data)
-{
-  xmlnode *node = GNUNET_malloc (sizeof (xmlnode));
-
-  node->name = name == NULL ? NULL : GNUNET_strdup (name);
-  node->type = type;
-  node->pool = user_data;
-  if (node->pool->size == node->pool->pos)
-    GNUNET_array_grow (node->pool->nodes, node->pool->size,
-                       node->pool->size * 2 + 64);
-  node->pool->nodes[node->pool->pos++] = node;
-  node->free_pool = 0;
-  return node;
-}
-
-static xmlnode *
-xmlnode_new (const char *name, void *user_data)
-{
-  g_return_val_if_fail (name != NULL, NULL);
-  return new_node (name, XMLNODE_TYPE_TAG, user_data);
-}
-
-static void
-xmlnode_insert_child (xmlnode * parent, xmlnode * child)
-{
-  g_return_if_fail (parent != NULL);
-  g_return_if_fail (child != NULL);
-
-  child->parent = parent;
-  if (parent->lastchild)
-    parent->lastchild->next = child;
-  else
-    parent->child = child;
-  parent->lastchild = child;
-}
-
-static xmlnode *
-xmlnode_new_child (xmlnode * parent, const char *name, void *user_data)
-{
-  xmlnode *node;
-
-  g_return_val_if_fail (parent != NULL, NULL);
-  g_return_val_if_fail (name != NULL, NULL);
-  node = new_node (name, XMLNODE_TYPE_TAG, user_data);
-  xmlnode_insert_child (parent, node);
-  return node;
-}
-
-static void
-xmlnode_insert_data (xmlnode * node,
-                     const char *data, int size, void *user_data)
-{
-  xmlnode *child;
-  size_t real_size;
-
-  g_return_if_fail (node != NULL);
-  g_return_if_fail (data != NULL);
-  g_return_if_fail (size != 0);
-  real_size = size == -1 ? strlen (data) : size;
-  child = new_node (NULL, XMLNODE_TYPE_DATA, user_data);
-  child->data = g_memdup (data, real_size);
-  child->data_sz = real_size;
-  xmlnode_insert_child (node, child);
-}
-
-static void
-xmlnode_remove_attrib (xmlnode * node, const char *attr)
-{
-  xmlnode *attr_node, *sibling = NULL;
-
-  g_return_if_fail (node != NULL);
-  g_return_if_fail (attr != NULL);
-
-  for (attr_node = node->child; attr_node; attr_node = attr_node->next)
-    {
-      if (attr_node->type == XMLNODE_TYPE_ATTRIB &&
-          !strcmp (attr_node->name, attr))
-        {
-          if (node->child == attr_node)
-            {
-              node->child = attr_node->next;
-            }
-          else
-            {
-              sibling->next = attr_node->next;
-            }
-          if (node->lastchild == attr_node)
-            {
-              node->lastchild = sibling;
-            }
-          xmlnode_free (attr_node);
-          return;
-        }
-      sibling = attr_node;
-    }
-}
-
-static void
-xmlnode_set_attrib (xmlnode * node,
-                    const char *attr, const char *value, void *user_data)
-{
-  xmlnode *attrib_node;
-
-  g_return_if_fail (node != NULL);
-  g_return_if_fail (attr != NULL);
-  g_return_if_fail (value != NULL);
-  xmlnode_remove_attrib (node, attr);
-  attrib_node = new_node (attr, XMLNODE_TYPE_ATTRIB, user_data);
-  attrib_node->data = GNUNET_strdup (value);
-  xmlnode_insert_child (node, attrib_node);
-}
-
-static void
-xmlnode_set_namespace (xmlnode * node, const char *xmlns)
-{
-  g_return_if_fail (node != NULL);
-  GNUNET_free_non_null (node->xmlns);
-  node->xmlns = GNUNET_strdup (xmlns);
-}
-
-static const char *
-xmlnode_get_namespace (xmlnode * node)
-{
-  g_return_val_if_fail (node != NULL, NULL);
-  return node->xmlns;
-}
-
-static void
-freePool (XMLNodePool * pool)
-{
-  unsigned int i;
-  xmlnode *x;
-
-  for (i = 0; i < pool->pos; i++)
-    {
-      x = pool->nodes[i];
-      GNUNET_free_non_null (x->name);
-      GNUNET_free_non_null (x->data);
-      GNUNET_free_non_null (x->xmlns);
-      GNUNET_free (x);
-    }
-  GNUNET_array_grow (pool->nodes, pool->size, 0);
-  GNUNET_free (pool);
-}
-
-void
-xmlnode_free (xmlnode * node)
-{
-  g_return_if_fail (node != NULL);
-  if (node->free_pool != GNUNET_YES)
-    return;
-  freePool (node->pool);
-}
-
-static xmlnode *
-xmlnode_get_child_with_namespace (const xmlnode * parent,
-                                  const char *name, const char *ns)
-{
-  xmlnode *x;
-  xmlnode *ret = NULL;
-  char *parent_name;
-  char *child_name;
-
-  if (parent == NULL)
-    return NULL;
-  if (name == NULL)
-    return NULL;
-
-  parent_name = GNUNET_strdup (name);
-  child_name = strstr (parent_name, "/");
-  if (child_name != NULL)
-    {
-      child_name[0] = '\0';
-      child_name++;
-    }
-
-  for (x = parent->child; x; x = x->next)
-    {
-      const char *xmlns = NULL;
-      if (ns)
-        xmlns = xmlnode_get_namespace (x);
-
-      if (x->type == XMLNODE_TYPE_TAG && name
-          && !strcmp (parent_name, x->name) && (!ns
-                                                || (xmlns
-                                                    && !strcmp (ns, xmlns))))
-        {
-          ret = x;
-          break;
-        }
-    }
-
-  if (child_name && ret)
-    ret = xmlnode_get_child (ret, child_name);
-
-  GNUNET_free (parent_name);
-  return ret;
-}
-
-xmlnode *
-xmlnode_get_child (const xmlnode * parent, const char *name)
-{
-  return xmlnode_get_child_with_namespace (parent, name, NULL);
-}
-
-char *
-xmlnode_get_data (xmlnode * node)
-{
-  char *str = NULL;
-  xmlnode *c;
-
-  if (node == NULL)
-    return NULL;
-  for (c = node->child; c; c = c->next)
-    {
-      if (c->type == XMLNODE_TYPE_DATA)
-        {
-          if (!str)
-            str = GNUNET_strdup ("");
-          str = g_string_append_len (str, c->data, c->data_sz);
-        }
-    }
-  if (str == NULL)
-    return NULL;
-
-  return str;
-}
-
-static void
-xmlnode_parser_element_start_libxml (void *user_data,
-                                     const xmlChar * element_name,
-                                     const xmlChar * prefix,
-                                     const xmlChar * xmlns,
-                                     int nb_namespaces,
-                                     const xmlChar ** namespaces,
-                                     int nb_attributes,
-                                     int nb_defaulted,
-                                     const xmlChar ** attributes)
-{
-  XMLNodePool *xpd = user_data;
-  xmlnode *node;
-  int i;
-
-  if (!element_name)
-    return;
-  if (xpd->current)
-    node =
-      xmlnode_new_child (xpd->current, (const char *) element_name,
-                         user_data);
-  else
-    node = xmlnode_new ((const char *) element_name, user_data);
-
-  xmlnode_set_namespace (node, (const char *) xmlns);
-
-  for (i = 0; i < nb_attributes * 5; i += 5)
-    {
-      char *txt;
-      int attrib_len = attributes[i + 4] - attributes[i + 3];
-      char *attrib = GNUNET_malloc (attrib_len + 1);
-      memcpy (attrib, attributes[i + 3], attrib_len);
-      attrib[attrib_len] = '\0';
-      txt = attrib;
-      attrib = gaim_unescape_html (txt);
-      GNUNET_free (txt);
-      xmlnode_set_attrib (node, (const char *) attributes[i], attrib,
-                          user_data);
-      GNUNET_free (attrib);
-    }
-  xpd->current = node;
-}
-
-static void
-xmlnode_parser_element_end_libxml (void *user_data,
-                                   const xmlChar * element_name,
-                                   const xmlChar * prefix,
-                                   const xmlChar * xmlns)
-{
-  XMLNodePool *xpd = user_data;
-
-  if (!element_name || !xpd->current)
-    return;
-  if (xpd->current->parent)
-    {
-      if (!xmlStrcmp ((xmlChar *) xpd->current->name, element_name))
-        xpd->current = xpd->current->parent;
-    }
-}
-
-static void
-xmlnode_parser_element_text_libxml (void *user_data,
-                                    const xmlChar * text, int text_len)
-{
-  XMLNodePool *xpd = user_data;
-
-  if (!xpd->current || !text || !text_len)
-    return;
-  xmlnode_insert_data (xpd->current,
-                       (const char *) text, text_len, user_data);
-}
-
-static xmlSAXHandler xmlnode_parser_libxml = {
-  .internalSubset = NULL,
-  .isStandalone = NULL,
-  .hasInternalSubset = NULL,
-  .hasExternalSubset = NULL,
-  .resolveEntity = NULL,
-  .getEntity = NULL,
-  .entityDecl = NULL,
-  .notationDecl = NULL,
-  .attributeDecl = NULL,
-  .elementDecl = NULL,
-  .unparsedEntityDecl = NULL,
-  .setDocumentLocator = NULL,
-  .startDocument = NULL,
-  .endDocument = NULL,
-  .startElement = NULL,
-  .endElement = NULL,
-  .reference = NULL,
-  .characters = xmlnode_parser_element_text_libxml,
-  .ignorableWhitespace = NULL,
-  .processingInstruction = NULL,
-  .comment = NULL,
-  .warning = NULL,
-  .error = NULL,
-  .fatalError = NULL,
-  .getParameterEntity = NULL,
-  .cdataBlock = NULL,
-  .externalSubset = NULL,
-  .initialized = XML_SAX2_MAGIC,
-  ._private = NULL,
-  .startElementNs = xmlnode_parser_element_start_libxml,
-  .endElementNs = xmlnode_parser_element_end_libxml,
-  .serror = NULL
-};
-
-xmlnode *
-xmlnode_from_str (const char *str, int size)
-{
-  XMLNodePool *xpd;
-  xmlnode *ret;
-  size_t real_size;
-
-  g_return_val_if_fail (str != NULL, NULL);
-
-  real_size = size < 0 ? strlen (str) : size;
-  xpd = GNUNET_malloc (sizeof (XMLNodePool));
-  memset (xpd, 0, sizeof (XMLNodePool));
-  if (xmlSAXUserParseMemory (&xmlnode_parser_libxml, xpd, str, real_size) < 0)
-    {
-      freePool (xpd);
-      return NULL;
-    }
-  ret = xpd->current;
-  ret->free_pool = GNUNET_YES;
-  return ret;
-}
-
-xmlnode *
-xmlnode_get_next_twin (xmlnode * node)
-{
-  xmlnode *sibling;
-  const char *ns = xmlnode_get_namespace (node);
-
-  g_return_val_if_fail (node != NULL, NULL);
-  g_return_val_if_fail (node->type == XMLNODE_TYPE_TAG, NULL);
-
-  for (sibling = node->next; sibling; sibling = sibling->next)
-    {
-      const char *xmlns = NULL;
-      if (ns)
-        xmlns = xmlnode_get_namespace (sibling);
-
-      if (sibling->type == XMLNODE_TYPE_TAG
-          && !strcmp (node->name, sibling->name) && (!ns
-                                                     || (xmlns
-                                                         && !strcmp (ns,
-                                                                     xmlns))))
-        return sibling;
-    }
-  return NULL;
-}
diff --git a/src/upnp/upnp_xmlnode.h b/src/upnp/upnp_xmlnode.h
deleted file mode 100644 (file)
index e3b9136..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/**
- * @file upnp/upnp_xmlnode.h XML DOM functions
- * @ingroup core
- *
- * gaim
- *
- * Gaim is the legal property of its developers, whose names are too numerous
- * to list here.  Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#ifndef _GGAIM_XMLNODE_H_
-#define _GGAIM_XMLNODE_H_
-
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/**
- * An xmlnode.
- */
-  typedef struct _xmlnode xmlnode;
-
-/**
- * Gets a child node named name.
- *
- * @param parent The parent node.
- * @param name   The child's name.
- *
- * @return The child or NULL.
- */
-  xmlnode *xmlnode_get_child (const xmlnode * parent, const char *name);
-
-/**
- * Gets the next node with the same name as node.
- *
- * @param node The node of a twin to find.
- *
- * @return The twin of node or NULL.
- */
-  xmlnode *xmlnode_get_next_twin (xmlnode * node);
-
-/**
- * Gets data from a node.
- *
- * @param node The node to get data from.
- *
- * @return The data from the node.  You must g_free
- *         this string when finished using it.
- */
-  char *xmlnode_get_data (xmlnode * node);
-
-/**
- * Creates a node from a string of XML.  Calling this on the
- * root node of an XML document will parse the entire document
- * into a tree of nodes, and return the xmlnode of the root.
- *
- * @param str  The string of xml.
- * @param size The size of the string, or -1 if @a str is
- *             NUL-terminated.
- *
- * @return The new node.
- */
-  xmlnode *xmlnode_from_str (const char *str, int size);
-
-/**
- * Frees a node and all of it's children.
- *
- * @param node The node to free.
- */
-  void xmlnode_free (xmlnode * node);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif                          /* _GAIM_XMLNODE_H_ */