source: trunk/libtransmission/upnp.c @ 3743

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

fix crash reported by hussam in #transmission

  • Property svn:keywords set to Date Rev Author Id
File size: 3.4 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 3743 2007-11-07 00:42:19Z 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};
33
34/**
35***
36**/
37
38tr_upnp*
39tr_upnpInit( void )
40{
41    tr_upnp * ret = tr_new0( tr_upnp, 1 );
42    struct UPNPDev * devlist = upnpDiscover( 2000, NULL );
43    if( UPNP_GetValidIGD( devlist, &ret->urls, &ret->data, ret->lanaddr, sizeof(ret->lanaddr))) {
44        tr_dbg( "Found Internet Gateway Device '%s'", ret->urls.controlURL );
45        tr_dbg( "Local LAN IP Address is '%s'", ret->lanaddr );
46    }
47    ret->port = -1;
48    freeUPNPDevlist( devlist );
49    return ret;
50}
51
52void
53tr_upnpClose( tr_upnp * handle )
54{
55    tr_upnpStop( handle );
56    FreeUPNPUrls( &handle->urls );
57    tr_free( handle );
58}
59
60/**
61***
62**/
63
64void
65tr_upnpStart( tr_upnp * handle )
66{
67    handle->isEnabled = 1;
68
69    if( handle->port >= 0 )
70    {
71        char portStr[16];
72        snprintf( portStr, sizeof(portStr), "%d", handle->port );
73        handle->isForwarding = ( handle->urls.controlURL != NULL ) && 
74                               ( handle->data.servicetype != NULL ) &&
75                               ( UPNP_AddPortMapping( handle->urls.controlURL,
76                                                      handle->data.servicetype,
77                                                      portStr, portStr, handle->lanaddr,
78                                                      "Transmission", "TCP" ) );
79
80        tr_dbg( "UPNP Port Forwarding via '%s', service '%s'.  (local address: %s:%d)",
81                handle->urls.controlURL, handle->data.servicetype, handle->lanaddr, handle->port );
82        tr_dbg( "UPNP Port Forwarding Enabled?  %s", (handle->isForwarding?"Yes":"No") );
83    }
84}
85
86void
87tr_upnpRemoveForwarding ( tr_upnp * handle )
88{
89    handle->port = -1;
90
91    if( handle->isForwarding )
92    {
93        char portStr[16];
94        snprintf( portStr, sizeof(portStr), "%d", handle->port );
95
96        UPNP_DeletePortMapping( handle->urls.controlURL,
97                                handle->data.servicetype,
98                                portStr, "TCP" );
99        tr_dbg( "Stopping port forwarding of '%s', service '%s'",
100                handle->urls.controlURL, handle->data.servicetype );
101
102        handle->isForwarding = FALSE;
103    }
104}
105
106void
107tr_upnpForwardPort( tr_upnp * handle, int publicPort )
108{
109    tr_upnpRemoveForwarding( handle ); /* remove the old forwarding */
110
111    handle->port = publicPort;
112
113    if( handle->isEnabled )
114        tr_upnpStart( handle );
115}
116
117void
118tr_upnpStop( tr_upnp * handle )
119{
120    tr_upnpRemoveForwarding( handle );
121    handle->isEnabled = 0;
122}
123
124int
125tr_upnpStatus( tr_upnp * handle )
126{
127    if( !handle->isEnabled )
128        return TR_NAT_TRAVERSAL_DISABLED;
129
130    if( !handle->isForwarding )
131        return TR_NAT_TRAVERSAL_ERROR;
132
133    return TR_NAT_TRAVERSAL_MAPPED;
134}
135
136void
137tr_upnpPulse( tr_upnp * handle UNUSED )
138{
139    /* no-op */
140}
Note: See TracBrowser for help on using the repository browser.