source: trunk/libtransmission/upnp.c @ 3815

Last change on this file since 3815 was 3815, checked in by charles, 15 years ago

minor tweaks.

  • Property svn:keywords set to Date Rev Author Id
File size: 3.6 KB
Line 
1/*
2 * This file Copyright (C) 2007 Charles Kerr <charles@rebelbase.com>
3 *
4 * This file is licensed by the GPL version 2.  Works owned by the
5 * Transmission project are granted a special exemption to clause 2(b)
6 * so that the bulk of its code can remain under the MIT license.
7 * This exemption does not extend to derived works not owned by
8 * the Transmission project.
9 *
10 * $Id: upnp.c 3815 2007-11-12 22:26:10Z charles $
11 */
12
13#include <stdio.h> /* printf */
14
15#include <miniupnp/miniwget.h>
16#include <miniupnp/miniupnpc.h>
17#include <miniupnp/upnpcommands.h>
18
19#include "transmission.h"
20#include "internal.h"
21#include "utils.h"
22#include "upnp.h"
23
24struct tr_upnp
25{
26    struct UPNPUrls urls;
27    struct IGDdatas data;
28    int port;
29    char lanaddr[16];
30    unsigned int isForwarding : 1;
31    unsigned int isEnabled : 1;
32    unsigned int hasDiscovered : 1;
33};
34
35/**
36***
37**/
38
39tr_upnp*
40tr_upnpInit( void )
41{
42    tr_upnp * ret = tr_new0( tr_upnp, 1 );
43    ret->port = -1;
44    return ret;
45}
46
47void
48tr_upnpClose( tr_upnp * handle )
49{
50    tr_upnpStop( handle );
51    if( handle->hasDiscovered )
52        FreeUPNPUrls( &handle->urls );
53    tr_free( handle );
54}
55
56/**
57***
58**/
59
60void
61tr_upnpStart( tr_upnp * handle )
62{
63    if( !handle->hasDiscovered )
64    {
65        struct UPNPDev * devlist = upnpDiscover( 2000, NULL );
66        if( UPNP_GetValidIGD( devlist, &handle->urls, &handle->data, handle->lanaddr, sizeof(handle->lanaddr))) {
67            tr_dbg( "UPNP: Found Internet Gateway Device '%s'", handle->urls.controlURL );
68            tr_dbg( "UPNP: Local LAN IP Address is '%s'", handle->lanaddr );
69        }
70        freeUPNPDevlist( devlist );
71        handle->hasDiscovered = 1;
72    }
73
74    handle->isEnabled = 1;
75
76    if( handle->port >= 0 )
77    {
78        char portStr[16];
79        snprintf( portStr, sizeof(portStr), "%d", handle->port );
80        handle->isForwarding = ( handle->urls.controlURL != NULL ) && 
81                               ( handle->data.servicetype != NULL ) &&
82                               ( UPNP_AddPortMapping( handle->urls.controlURL,
83                                                      handle->data.servicetype,
84                                                      portStr, portStr, handle->lanaddr,
85                                                      "Transmission", "TCP" ) );
86
87        tr_inf( "UPNP: Port Forwarding via '%s', service '%s'.  (local address: %s:%d)",
88                handle->urls.controlURL, handle->data.servicetype, handle->lanaddr, handle->port );
89        tr_inf( "UPNP: Port Forwarding Enabled?  %s", (handle->isForwarding?"Yes":"No") );
90    }
91}
92
93void
94tr_upnpRemoveForwarding ( tr_upnp * handle )
95{
96    handle->port = -1;
97
98    if( handle->isForwarding )
99    {
100        char portStr[16];
101        snprintf( portStr, sizeof(portStr), "%d", handle->port );
102
103        UPNP_DeletePortMapping( handle->urls.controlURL,
104                                handle->data.servicetype,
105                                portStr, "TCP" );
106        tr_dbg( "Stopping port forwarding of '%s', service '%s'",
107                handle->urls.controlURL, handle->data.servicetype );
108
109        handle->isForwarding = FALSE;
110    }
111}
112
113void
114tr_upnpForwardPort( tr_upnp * handle, int publicPort )
115{
116    tr_upnpRemoveForwarding( handle ); /* remove the old forwarding */
117
118    handle->port = publicPort;
119
120    if( handle->isEnabled )
121        tr_upnpStart( handle );
122}
123
124void
125tr_upnpStop( tr_upnp * handle )
126{
127    tr_upnpRemoveForwarding( handle );
128    handle->isEnabled = 0;
129}
130
131int
132tr_upnpStatus( tr_upnp * handle )
133{
134    if( !handle->isEnabled )
135        return TR_NAT_TRAVERSAL_DISABLED;
136
137    if( !handle->isForwarding )
138        return TR_NAT_TRAVERSAL_ERROR;
139
140    return TR_NAT_TRAVERSAL_MAPPED;
141}
142
143void
144tr_upnpPulse( tr_upnp * handle UNUSED )
145{
146    /* no-op */
147}
Note: See TracBrowser for help on using the repository browser.