Changeset 1783
- Timestamp:
- Apr 23, 2007, 7:47:49 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/0.7x/libtransmission/upnp.c
r1720 r1783 31 31 #define SSDP_FIRST_DELAY 3750 /* 3 3/4 seconds */ 32 32 #define SSDP_MAX_DELAY 1800000 /* 30 minutes */ 33 #define UPNP_SERVICE_TYPE "urn:schemas-upnp-org:service:WANIPConnection:1" 33 #define SERVICE_TYPE_IP "urn:schemas-upnp-org:service:WANIPConnection:1" 34 #define SERVICE_TYPE_PPP "urn:schemas-upnp-org:service:WANPPPConnection:1" 34 35 #define SOAP_ENVELOPE "http://schemas.xmlsoap.org/soap/envelope/" 35 36 #define LOOP_DETECT_THRESHOLD 10 /* error on 10 add/get/del state changes */ … … 46 47 { 47 48 char * name; 48 char * action;49 49 int len; 50 50 struct { char * name; char * var; char dir; } * args; … … 57 57 char * root; 58 58 int port; 59 int ppp; 59 60 char * soap; 60 61 char * scpd; … … 123 124 static int 124 125 parseRoot( const char * root, const char *buf, int len, 125 char ** soap, char ** scpd );126 char ** soap, char ** scpd, int * ppp ); 126 127 static void 127 128 addUrlbase( const char * base, char ** path ); … … 138 139 static tr_http_t * 139 140 soapRequest( int retry, const char * host, int port, const char * path, 140 tr_upnp_action_t * action, ... );141 const char * type, tr_upnp_action_t * action, ... ); 141 142 static void 142 143 actionSetup( tr_upnp_action_t * action, const char * name, int prealloc ); … … 674 675 } 675 676 else if( parseRoot( dev->root, body, len, 676 &dev->soap, &dev->scpd ) )677 &dev->soap, &dev->scpd, &dev->ppp ) ) 677 678 { 678 679 tr_dbg( "upnp device %s: parse root failed", dev->host ); … … 823 824 { 824 825 tr_http_t * ret; 825 char numstr[6]; 826 char numstr[6]; 827 const char * type; 826 828 827 829 ret = NULL; … … 847 849 } 848 850 snprintf( numstr, sizeof( numstr ), "%i", dev->mappedport ); 851 type = ( dev->ppp ? SERVICE_TYPE_PPP : SERVICE_TYPE_IP ); 849 852 ret = soapRequest( dev->soapretry, dev->host, dev->port, dev->soap, 850 &dev->addcmd,853 type, &dev->addcmd, 851 854 "PortMappingEnabled", "1", 852 855 "PortMappingLeaseDuration", "0", … … 861 864 case UPNPDEV_STATE_GET: 862 865 snprintf( numstr, sizeof( numstr ), "%i", dev->mappedport ); 866 type = ( dev->ppp ? SERVICE_TYPE_PPP : SERVICE_TYPE_IP ); 863 867 ret = soapRequest( dev->soapretry, dev->host, dev->port, dev->soap, 864 &dev->getcmd,868 type, &dev->getcmd, 865 869 "RemoteHost", "", 866 870 "ExternalPort", numstr, … … 870 874 case UPNPDEV_STATE_DEL: 871 875 snprintf( numstr, sizeof( numstr ), "%i", dev->mappedport ); 876 type = ( dev->ppp ? SERVICE_TYPE_PPP : SERVICE_TYPE_IP ); 872 877 ret = soapRequest( dev->soapretry, dev->host, dev->port, dev->soap, 873 &dev->delcmd,878 type, &dev->delcmd, 874 879 "RemoteHost", "", 875 880 "ExternalPort", numstr, … … 952 957 static int 953 958 parseRoot( const char * root, const char *buf, int len, 954 char ** soap, char ** scpd )959 char ** soap, char ** scpd, int * ppp ) 955 960 { 956 961 const char * end, * ii, * jj, * kk, * urlbase; … … 999 1004 buf = tr_xmlTagContents( kk, end ); 1000 1005 if( !tr_xmlFindTagVerifyContents( buf, end, "serviceType", 1001 UPNP_SERVICE_TYPE, 1 ) )1006 SERVICE_TYPE_IP, 1 ) ) 1002 1007 { 1003 1008 *soap = tr_xmlDupTagContents( buf, end, "controlURL"); 1004 1009 *scpd = tr_xmlDupTagContents( buf, end, "SCPDURL"); 1010 *ppp = 0; 1011 break; 1012 } 1013 /* XXX we should save all services of both types and 1014 try adding mappings for each in turn */ 1015 else if( !tr_xmlFindTagVerifyContents( buf, end, "serviceType", 1016 SERVICE_TYPE_PPP, 1 ) ) 1017 { 1018 *soap = tr_xmlDupTagContents( buf, end, "controlURL"); 1019 *scpd = tr_xmlDupTagContents( buf, end, "SCPDURL"); 1020 *ppp = 1; 1005 1021 break; 1006 1022 } … … 1208 1224 static tr_http_t * 1209 1225 soapRequest( int retry, const char * host, int port, const char * path, 1210 tr_upnp_action_t * action, ... )1226 const char * type, tr_upnp_action_t * action, ... ) 1211 1227 { 1212 1228 tr_http_t * http; … … 1214 1230 const char * name, * value; 1215 1231 int method; 1232 char * actstr; 1216 1233 1217 1234 method = ( retry ? TR_HTTP_M_POST : TR_HTTP_POST ); … … 1221 1238 tr_httpAddHeader( http, "Content-type", 1222 1239 "text/xml; encoding=\"utf-8\"" ); 1223 tr_httpAddHeader( http, "SOAPAction", action->action ); 1240 actstr = NULL; 1241 asprintf( &actstr, "\"%s#%s\"", type, action->name ); 1242 tr_httpAddHeader( http, "SOAPAction", actstr ); 1243 free( actstr ); 1224 1244 if( retry ) 1225 1245 { … … 1232 1252 " s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" 1233 1253 " <s:Body>" 1234 " <u:%s xmlns:u=\ "" UPNP_SERVICE_TYPE "\">", action->name );1254 " <u:%s xmlns:u=\%s\">", action->name, type ); 1235 1255 1236 1256 va_start( ap, action ); … … 1271 1291 { 1272 1292 action->name = strdup( name ); 1273 action->action = NULL;1274 asprintf( &action->action, "\"%s#%s\"", UPNP_SERVICE_TYPE, name );1275 1293 assert( NULL == action->args ); 1276 1294 action->args = malloc( sizeof( *action->args ) * prealloc ); … … 1283 1301 { 1284 1302 free( act->name ); 1285 free( act->action );1286 1303 while( 0 < act->len ) 1287 1304 { … … 1361 1378 return NULL; 1362 1379 } 1380 1381 #if 0 1382 /* this code is used for standalone root parsing for debugging purposes */ 1383 /* cc -g -Wall -D__TRANSMISSION__ -o upnp upnp.c xml.c utils.c */ 1384 int 1385 main( int argc, char * argv[] ) 1386 { 1387 struct stat sb; 1388 char * data, * soap, * scpd; 1389 int fd, ppp; 1390 ssize_t res; 1391 1392 if( 3 != argc ) 1393 { 1394 printf( "usage: %s root-url root-file\n", argv[0] ); 1395 return 0; 1396 } 1397 1398 tr_msgInit(); 1399 tr_setMessageLevel( 9 ); 1400 1401 if( 0 > stat( argv[2], &sb ) ) 1402 { 1403 tr_err( "failed to stat file %s: %s", argv[2], strerror( errno ) ); 1404 return 1; 1405 } 1406 1407 data = malloc( sb.st_size ); 1408 if( NULL == data ) 1409 { 1410 tr_err( "failed to malloc %zd bytes", ( size_t )sb.st_size ); 1411 return 1; 1412 } 1413 1414 fd = open( argv[2], O_RDONLY ); 1415 if( 0 > fd ) 1416 { 1417 tr_err( "failed to open file %s: %s", argv[2], strerror( errno ) ); 1418 free( data ); 1419 return 1; 1420 } 1421 1422 res = read( fd, data, sb.st_size ); 1423 if( sb.st_size > res ) 1424 { 1425 tr_err( "failed to read file %s: %s", argv[2], 1426 ( 0 > res ? strerror( errno ) : "short read count" ) ); 1427 close( fd ); 1428 free( data ); 1429 return 1; 1430 } 1431 1432 close( fd ); 1433 1434 if( parseRoot( argv[1], data, sb.st_size, &soap, &scpd, &ppp ) ) 1435 { 1436 tr_err( "root parsing failed" ); 1437 } 1438 else 1439 { 1440 tr_err( "soap=%s scpd=%s ppp=%s", soap, scpd, ( ppp ? "yes" : "no" ) ); 1441 free( soap ); 1442 free( scpd ); 1443 } 1444 free( data ); 1445 1446 return 0; 1447 } 1448 1449 int tr_netMcastOpen( int port, struct in_addr addr ) { assert( 0 ); } 1450 int tr_netBind ( int port, int type ) { assert( 0 ); } 1451 void tr_netClose ( int s ) { assert( 0 ); } 1452 int tr_netRecvFrom( int s, uint8_t * buf, int size, struct sockaddr_in * sin ) { assert( 0 ); } 1453 int tr_httpRequestType( const char * data, int len, 1454 char ** method, char ** uri ) { assert( 0 ); } 1455 int tr_httpResponseCode( const char * data, int len ) { assert( 0 ); } 1456 char * tr_httpParse( const char * data, int len, tr_http_header_t *headers ) { assert( 0 ); } 1457 int tr_httpIsUrl( const char * u, int l ) { assert( 0 ); } 1458 int tr_httpParseUrl( const char * u, int l, char ** h, int * p, char ** q ) { assert( 0 ); } 1459 tr_http_t * tr_httpClient( int t, const char * h, int p, const char * u, ... ) { assert( 0 ); } 1460 tr_http_t * tr_httpClientUrl( int t, const char * u, ... ) { assert( 0 ); } 1461 void tr_httpAddHeader( tr_http_t * h, const char * n, const char * v ) { assert( 0 ); } 1462 void tr_httpAddBody( tr_http_t * h, const char * b, ... ) { assert( 0 ); } 1463 tr_tristate_t tr_httpPulse( tr_http_t * h, const char ** b, int * l ) { assert( 0 ); } 1464 char * tr_httpWhatsMyAddress( tr_http_t * h ) { assert( 0 ); } 1465 void tr_httpClose( tr_http_t * h ) { assert( 0 ); } 1466 1467 void tr_lockInit ( tr_lock_t * l ) {} 1468 int pthread_mutex_lock( pthread_mutex_t * m ) { return 0; } 1469 int pthread_mutex_unlock( pthread_mutex_t * m ) { return 0; } 1470 1471 #endif
Note: See TracChangeset
for help on using the changeset viewer.