Changeset 10578


Ignore:
Timestamp:
May 1, 2010, 4:21:41 AM (11 years ago)
Author:
charles
Message:

(1.9x third-party) upgrade our miniupnp snapshot for #3125 "UPnP fails on Linksys AM300 modem/router"

Location:
branches/1.9x/third-party/miniupnp
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • branches/1.9x/third-party/miniupnp/Changelog.txt

    r10285 r10578  
    1 $Id: Changelog.txt,v 1.105 2010/01/06 10:03:53 nanard Exp $
     1$Id: Changelog.txt,v 1.113 2010/04/12 20:39:40 nanard Exp $
    22miniUPnP client Changelog.
    33
     42010/04/12:
     5  Retrying with HTTP/1.1 if HTTP/1.0 failed. see
     6  http://miniupnp.tuxfamily.org/forum/viewtopic.php?p=1703
     7
     82010/04/07:
     9  avoid returning duplicates in upnpDiscover()
     10
     112010/04/05:
     12  Create a connecthostport.h/.c with connecthostport() function
     13  and use it in miniwget and miniupnpc.
     14  Use getnameinfo() instead of inet_ntop or inet_ntoa
     15  Work to make miniupnpc IPV6 compatible...
     16  Add java test code.
     17  Big changes in order to support device having both WANIPConnection
     18  and WANPPPConnection.
     19
     202010/04/04:
     21  Use getaddrinfo() instead of gethostbyname() in miniwget.
     22
    4232010/01/06:
    5   #define _DARWIN_C_SOURCE for macosx
     24  #define _DARWIN_C_SOURCE for Mac OS X
    625
    7262009/12/19:
  • branches/1.9x/third-party/miniupnp/igd_desc_parse.c

    r10285 r10578  
    1 /* $Id: igd_desc_parse.c,v 1.9 2009/12/03 13:50:06 nanard Exp $ */
     1/* $Id: igd_desc_parse.c,v 1.10 2010/04/05 20:36:59 nanard Exp $ */
    22/* Project : miniupnp
    33 * http://miniupnp.free.fr/
    44 * Author : Thomas Bernard
    5  * Copyright (c) 2005-2008 Thomas Bernard
     5 * Copyright (c) 2005-2010 Thomas Bernard
    66 * This software is subject to the conditions detailed in the
    7  * LICENCE file provided in this distribution.
    8  * */
     7 * LICENCE file provided in this distribution. */
     8
    99#include "igd_desc_parse.h"
    1010#include <stdio.h>
    1111#include <string.h>
    12 
    13 /* TODO : rewrite this code so it correctly handle descriptions with
    14  * both WANIPConnection and/or WANPPPConnection */
    1512
    1613/* Start element handler :
     
    2320        datas->level++;
    2421        if( (l==7) && !memcmp(name, "service", l) ) {
    25                 datas->controlurl_tmp[0] = '\0';
    26                 datas->eventsuburl_tmp[0] = '\0';
    27                 datas->scpdurl_tmp[0] = '\0';
    28                 datas->servicetype_tmp[0] = '\0';
     22                datas->tmp.controlurl[0] = '\0';
     23                datas->tmp.eventsuburl[0] = '\0';
     24                datas->tmp.scpdurl[0] = '\0';
     25                datas->tmp.servicetype[0] = '\0';
    2926        }
    3027}
     
    4744                        datas->state ++;
    4845                */
    49                 if(0==strcmp(datas->servicetype_tmp,
     46                if(0==strcmp(datas->tmp.servicetype,
    5047                                "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1")) {
    51                         memcpy(datas->controlurl_CIF, datas->controlurl_tmp, MINIUPNPC_URL_MAXSIZE);
    52                         memcpy(datas->eventsuburl_CIF, datas->eventsuburl_tmp, MINIUPNPC_URL_MAXSIZE);
    53                         memcpy(datas->scpdurl_CIF, datas->scpdurl_tmp, MINIUPNPC_URL_MAXSIZE);
    54                         memcpy(datas->servicetype_CIF, datas->servicetype_tmp, MINIUPNPC_URL_MAXSIZE);
    55                 } else if(0==strcmp(datas->servicetype_tmp,
     48                        memcpy(&datas->CIF, &datas->tmp, sizeof(struct IGDdatas_service));
     49                } else if(0==strcmp(datas->tmp.servicetype,
    5650                                "urn:schemas-upnp-org:service:WANIPConnection:1")
    57                                  || 0==strcmp(datas->servicetype_tmp,
     51                                 || 0==strcmp(datas->tmp.servicetype,
    5852                                "urn:schemas-upnp-org:service:WANPPPConnection:1") ) {
    59                         memcpy(datas->controlurl, datas->controlurl_tmp, MINIUPNPC_URL_MAXSIZE);
    60                         memcpy(datas->eventsuburl, datas->eventsuburl_tmp, MINIUPNPC_URL_MAXSIZE);
    61                         memcpy(datas->scpdurl, datas->scpdurl_tmp, MINIUPNPC_URL_MAXSIZE);
    62                         memcpy(datas->servicetype, datas->servicetype_tmp, MINIUPNPC_URL_MAXSIZE);
     53                        if(datas->first.servicetype[0] == '\0') {
     54                                memcpy(&datas->first, &datas->tmp, sizeof(struct IGDdatas_service));
     55                        } else {
     56                                memcpy(&datas->second, &datas->tmp, sizeof(struct IGDdatas_service));
     57                        }
    6358                }
    6459        }
     
    7671                dstmember = datas->urlbase;
    7772        else if( !strcmp(datas->cureltname, "serviceType") )
    78                 dstmember = datas->servicetype_tmp;
     73                dstmember = datas->tmp.servicetype;
    7974        else if( !strcmp(datas->cureltname, "controlURL") )
    80                 dstmember = datas->controlurl_tmp;
     75                dstmember = datas->tmp.controlurl;
    8176        else if( !strcmp(datas->cureltname, "eventSubURL") )
    82                 dstmember = datas->eventsuburl_tmp;
     77                dstmember = datas->tmp.eventsuburl;
    8378        else if( !strcmp(datas->cureltname, "SCPDURL") )
    84                 dstmember = datas->scpdurl_tmp;
     79                dstmember = datas->tmp.scpdurl;
    8580/*      else if( !strcmp(datas->cureltname, "deviceType") )
    8681                dstmember = datas->devicetype_tmp;*/
     
    9893        printf("urlbase = '%s'\n", d->urlbase);
    9994        printf("WAN Device (Common interface config) :\n");
    100         /*printf(" deviceType = '%s'\n", d->devicetype_CIF);*/
    101         printf(" serviceType = '%s'\n", d->servicetype_CIF);
    102         printf(" controlURL = '%s'\n", d->controlurl_CIF);
    103         printf(" eventSubURL = '%s'\n", d->eventsuburl_CIF);
    104         printf(" SCPDURL = '%s'\n", d->scpdurl_CIF);
     95        /*printf(" deviceType = '%s'\n", d->CIF.devicetype);*/
     96        printf(" serviceType = '%s'\n", d->CIF.servicetype);
     97        printf(" controlURL = '%s'\n", d->CIF.controlurl);
     98        printf(" eventSubURL = '%s'\n", d->CIF.eventsuburl);
     99        printf(" SCPDURL = '%s'\n", d->CIF.scpdurl);
    105100        printf("WAN Connection Device (IP or PPP Connection):\n");
    106         /*printf(" deviceType = '%s'\n", d->devicetype);*/
    107         printf(" servicetype = '%s'\n", d->servicetype);
    108         printf(" controlURL = '%s'\n", d->controlurl);
    109         printf(" eventSubURL = '%s'\n", d->eventsuburl);
    110         printf(" SCPDURL = '%s'\n", d->scpdurl);
     101        /*printf(" deviceType = '%s'\n", d->first.devicetype);*/
     102        printf(" servicetype = '%s'\n", d->first.servicetype);
     103        printf(" controlURL = '%s'\n", d->first.controlurl);
     104        printf(" eventSubURL = '%s'\n", d->first.eventsuburl);
     105        printf(" SCPDURL = '%s'\n", d->first.scpdurl);
     106        printf("secondary WAN Connection Device (IP or PPP Connection):\n");
     107        /*printf(" deviceType = '%s'\n", d->second.devicetype);*/
     108        printf(" servicetype = '%s'\n", d->second.servicetype);
     109        printf(" controlURL = '%s'\n", d->second.controlurl);
     110        printf(" eventSubURL = '%s'\n", d->second.eventsuburl);
     111        printf(" SCPDURL = '%s'\n", d->second.scpdurl);
    111112}
    112113
  • branches/1.9x/third-party/miniupnp/igd_desc_parse.h

    r5743 r10578  
    1 /* $Id: igd_desc_parse.h,v 1.6 2008/04/23 11:51:07 nanard Exp $ */
     1/* $Id: igd_desc_parse.h,v 1.7 2010/04/05 20:36:59 nanard Exp $ */
    22/* Project : miniupnp
    33 * http://miniupnp.free.fr/
    44 * Author : Thomas Bernard
    5  * Copyright (c) 2005-2008 Thomas Bernard
     5 * Copyright (c) 2005-2010 Thomas Bernard
    66 * This software is subject to the conditions detailed in the
    77 * LICENCE file provided in this distribution.
     
    1313 * descriptions of Internet Gateway Devices */
    1414#define MINIUPNPC_URL_MAXSIZE (128)
     15struct IGDdatas_service {
     16        char controlurl[MINIUPNPC_URL_MAXSIZE];
     17        char eventsuburl[MINIUPNPC_URL_MAXSIZE];
     18        char scpdurl[MINIUPNPC_URL_MAXSIZE];
     19        char servicetype[MINIUPNPC_URL_MAXSIZE];
     20        /*char devicetype[MINIUPNPC_URL_MAXSIZE];*/
     21};
     22
    1523struct IGDdatas {
    1624        char cureltname[MINIUPNPC_URL_MAXSIZE];
     
    1927        /*int state;*/
    2028        /* "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1" */
    21         char controlurl_CIF[MINIUPNPC_URL_MAXSIZE];
    22         char eventsuburl_CIF[MINIUPNPC_URL_MAXSIZE];
    23         char scpdurl_CIF[MINIUPNPC_URL_MAXSIZE];
    24         char servicetype_CIF[MINIUPNPC_URL_MAXSIZE];
    25         /*char devicetype_CIF[MINIUPNPC_URL_MAXSIZE];*/
     29        struct IGDdatas_service CIF;
    2630        /* "urn:schemas-upnp-org:service:WANIPConnection:1"
    2731         * "urn:schemas-upnp-org:service:WANPPPConnection:1" */
    28         char controlurl[MINIUPNPC_URL_MAXSIZE];
    29         char eventsuburl[MINIUPNPC_URL_MAXSIZE];
    30         char scpdurl[MINIUPNPC_URL_MAXSIZE];
    31         char servicetype[MINIUPNPC_URL_MAXSIZE];
    32         /*char devicetype[MINIUPNPC_URL_MAXSIZE];*/
     32        struct IGDdatas_service first;
     33        /* if both WANIPConnection and WANPPPConnection are present */
     34        struct IGDdatas_service second;
    3335        /* tmp */
    34         char controlurl_tmp[MINIUPNPC_URL_MAXSIZE];
    35         char eventsuburl_tmp[MINIUPNPC_URL_MAXSIZE];
    36         char scpdurl_tmp[MINIUPNPC_URL_MAXSIZE];
    37         char servicetype_tmp[MINIUPNPC_URL_MAXSIZE];
    38         /*char devicetype_tmp[MINIUPNPC_URL_MAXSIZE];*/
     36        struct IGDdatas_service tmp;
    3937};
    4038
  • branches/1.9x/third-party/miniupnp/minisoap.c

    r10285 r10578  
    1 /* $Id: minisoap.c,v 1.18 2009/12/04 11:29:18 nanard Exp $ */
     1/* $Id: minisoap.c,v 1.19 2010/04/12 20:39:41 nanard Exp $ */
    22/* Project : miniupnp
    33 * Author : Thomas Bernard
     
    7676                                   unsigned short port,
    7777                                   const char * action,
    78                                    const char * body)
     78                                   const char * body,
     79                                   const char * httpversion)
    7980{
    8081        int bodysize;
     
    9495                snprintf(portstr, sizeof(portstr), ":%hu", port);
    9596        headerssize = snprintf(headerbuf, sizeof(headerbuf),
    96 /*                       "POST %s HTTP/1.1\r\n" */
    97                        "POST %s HTTP/1.0\r\n"
     97                       "POST %s HTTP/%s\r\n"
    9898                           "Host: %s%s\r\n"
    9999                                           "User-Agent: " OS_STRING ", UPnP/1.0, MiniUPnPc/" MINIUPNPC_VERSION_STRING "\r\n"
     
    105105                                           "Pragma: no-cache\r\n"
    106106                                           "\r\n",
    107                                            url, host, portstr, bodysize, action);
     107                                           url, httpversion, host, portstr, bodysize, action);
    108108#ifdef DEBUG
    109109        printf("SOAP request : headersize=%d bodysize=%d\n",
  • branches/1.9x/third-party/miniupnp/minisoap.h

    r3731 r10578  
    1 /* $Id: minisoap.h,v 1.3 2006/11/19 22:32:34 nanard Exp $ */
     1/* $Id: minisoap.h,v 1.4 2010/04/12 20:39:41 nanard Exp $ */
    22/* Project : miniupnp
    33 * Author : Thomas Bernard
     
    1010/*int httpWrite(int, const char *, int, const char *);*/
    1111int soapPostSubmit(int, const char *, const char *, unsigned short,
    12                                   const char *, const char *);
     12                   const char *, const char *, const char *);
    1313
    1414#endif
  • branches/1.9x/third-party/miniupnp/miniupnpc.c

    r10285 r10578  
    1 /* $Id: miniupnpc.c,v 1.74 2010/01/09 23:54:40 nanard Exp $ */
     1/* $Id: miniupnpc.c,v 1.80 2010/04/12 20:39:41 nanard Exp $ */
    22/* Project : miniupnp
    33 * Author : Thomas BERNARD
     
    1515#define __BSD_VISIBLE 1
    1616#endif
    17 #endif
    18 
    19 #ifdef __APPLE__
    20 #define _DARWIN_C_SOURCE
    2117#endif
    2218
     
    5147#include <netinet/in.h>
    5248#include <arpa/inet.h>
     49#include <netdb.h>
    5350#if !defined(__amigaos__) && !defined(__amigaos4__)
    5451#include <poll.h>
    5552#endif
    56 #include <netdb.h>
    5753#include <strings.h>
    5854#include <errno.h>
     
    7470#include "minixml.h"
    7571#include "upnpcommands.h"
     72#include "connecthostport.h"
    7673
    7774#ifdef WIN32
     
    172169}
    173170
    174 /* simpleUPnPcommand :
     171/* simpleUPnPcommand2 :
    175172 * not so simple !
    176173 * return values :
    177174 *   0 - OK
    178175 *  -1 - error */
    179 int simpleUPnPcommand(int s, const char * url, const char * service,
    180                       const char * action, struct UPNParg * args,
    181                       char * buffer, int * bufsize)
    182 {
    183         struct sockaddr_in dest;
     176static int simpleUPnPcommand2(int s, const char * url, const char * service,
     177                       const char * action, struct UPNParg * args,
     178                       char * buffer, int * bufsize, const char * httpversion)
     179{
    184180        char hostname[MAXHOSTNAMELEN+1];
    185181        unsigned short port = 0;
     
    191187    int n;
    192188        int contentlen, headerlen;      /* for the response */
    193 #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
    194         struct timeval timeout;
    195 #endif
     189
    196190        snprintf(soapact, sizeof(soapact), "%s#%s", service, action);
    197191        if(args==NULL)
     
    262256        if(s<0)
    263257        {
    264                 s = socket(PF_INET, SOCK_STREAM, 0);
    265                 if(s<0)
     258                s = connecthostport(hostname, port);
     259                if(s < 0)
    266260                {
    267                         PRINT_SOCKET_ERROR("socket");
    268261                        *bufsize = 0;
    269262                        return -1;
    270263                }
    271 #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
    272                 /* setting a 3 seconds timeout for the connect() call */
    273                 timeout.tv_sec = 3;
    274                 timeout.tv_usec = 0;
    275                 if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0)
    276                 {
    277                         PRINT_SOCKET_ERROR("setsockopt");
    278                 }
    279                 timeout.tv_sec = 3;
    280                 timeout.tv_usec = 0;
    281                 if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0)
    282                 {
    283                         PRINT_SOCKET_ERROR("setsockopt");
    284                 }
    285 #endif
    286                 dest.sin_family = AF_INET;
    287                 dest.sin_port = htons(port);
    288                 dest.sin_addr.s_addr = inet_addr(hostname);
    289         n = connect(s, (struct sockaddr *)&dest, sizeof(struct sockaddr));
    290 #ifdef MINIUPNPC_IGNORE_EINTR
    291         while(n < 0 && errno == EINTR)
    292                 {
    293                         socklen_t len;
    294                         fd_set wset;
    295                         int err;
    296                         FD_ZERO(&wset);
    297                         FD_SET(s, &wset);
    298                         if((n = select(s + 1, NULL, &wset, NULL, NULL)) == -1 && errno == EINTR)
    299                                 continue;
    300                         /*len = 0;*/
    301                         /*n = getpeername(s, NULL, &len);*/
    302                         len = sizeof(err);
    303                         if(getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &len) < 0) {
    304                                 PRINT_SOCKET_ERROR("getsockopt");
    305                                 closesocket(s);
    306                                 return -1;
    307                         }
    308                         if(err != 0) {
    309                                 errno = err;
    310                                 n = -1;
    311                         } else {
    312                                 n = 0;
    313                         }
    314                 }
    315 #endif
    316                 if(n < 0)
    317         {
    318                         PRINT_SOCKET_ERROR("connect");
    319                         closesocket(s);
    320                         *bufsize = 0;
    321                         return -1;
    322                 }
    323         }
    324 
    325         n = soapPostSubmit(s, path, hostname, port, soapact, soapbody);
     264        }
     265
     266        n = soapPostSubmit(s, path, hostname, port, soapact, soapbody, httpversion);
    326267        if(n<=0) {
    327268#ifdef DEBUG
     
    354295        closesocket(s);
    355296        return 0;
     297}
     298
     299/* simpleUPnPcommand :
     300 * not so simple !
     301 * return values :
     302 *   0 - OK
     303 *  -1 - error */
     304int simpleUPnPcommand(int s, const char * url, const char * service,
     305                       const char * action, struct UPNParg * args,
     306                       char * buffer, int * bufsize)
     307{
     308        int result;
     309        int origbufsize = *bufsize;
     310
     311        result = simpleUPnPcommand2(s, url, service, action, args, buffer, bufsize, "1.0");
     312        if (result < 0 || *bufsize == 0)
     313        {
     314#ifdef DEBUG
     315            printf("Error or no result from SOAP request; retrying with HTTP/1.1\n");
     316#endif
     317                *bufsize = origbufsize;
     318                result = simpleUPnPcommand2(s, url, service, action, args, buffer, bufsize, "1.1");
     319        }
     320        return result;
    356321}
    357322
     
    451416        int sudp;
    452417        int n;
    453         struct sockaddr_in sockudp_r, sockudp_w;
     418        struct sockaddr sockudp_r;
    454419        unsigned int mx;
     420        int rv;
     421        struct addrinfo hints, *servinfo, *p;
    455422#ifdef WIN32
    456423        /*MIB_IPFORWARDROW ip_forward;*/
     
    482449                return NULL;
    483450        }
    484     /* reception */
    485     memset(&sockudp_r, 0, sizeof(struct sockaddr_in));
    486     sockudp_r.sin_family = AF_INET;
    487         if(sameport)
    488         sockudp_r.sin_port = htons(PORT);
    489     sockudp_r.sin_addr.s_addr = INADDR_ANY;
    490     /* emission */
    491     memset(&sockudp_w, 0, sizeof(struct sockaddr_in));
    492     sockudp_w.sin_family = AF_INET;
    493     sockudp_w.sin_port = htons(PORT);
    494     sockudp_w.sin_addr.s_addr = inet_addr(UPNP_MCAST_ADDR);
     451        /* reception */
     452        memset(&sockudp_r, 0, sizeof(struct sockaddr));
     453        if(0/*ipv6*/) {
     454                struct sockaddr_in6 * p = (struct sockaddr_in6 *)&sockudp_r;
     455                p->sin6_family = AF_INET6;
     456                if(sameport)
     457                        p->sin6_port = htons(PORT);
     458                p->sin6_addr = in6addr_any;//IN6ADDR_ANY_INIT;/*INADDR_ANY;*/
     459        } else {
     460                struct sockaddr_in * p = (struct sockaddr_in *)&sockudp_r;
     461                p->sin_family = AF_INET;
     462                if(sameport)
     463                        p->sin_port = htons(PORT);
     464                p->sin_addr.s_addr = INADDR_ANY;
     465        }
     466#if 0
     467        /* emission */
     468        memset(&sockudp_w, 0, sizeof(struct sockaddr_in));
     469        sockudp_w.sin_family = AF_INET;
     470        sockudp_w.sin_port = htons(PORT);
     471        sockudp_w.sin_addr.s_addr = inet_addr(UPNP_MCAST_ADDR);
     472#endif
    495473#ifdef WIN32
    496474/* This code could help us to use the right Network interface for
     
    547525                struct in_addr mc_if;
    548526                mc_if.s_addr = inet_addr(multicastif);
    549         sockudp_r.sin_addr.s_addr = mc_if.s_addr;
     527                if(0/*ipv6*/) {
     528                } else {
     529                        ((struct sockaddr_in *)&sockudp_r)->sin_addr.s_addr = mc_if.s_addr;
     530                }
    550531                if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0)
    551532                {
     
    555536
    556537        /* Avant d'envoyer le paquet on bind pour recevoir la reponse */
    557     if (bind(sudp, (struct sockaddr *)&sockudp_r, sizeof(struct sockaddr_in)) != 0)
     538    if (bind(sudp, &sockudp_r, 0/*ipv6*/?sizeof(struct sockaddr_in6):sizeof(struct sockaddr_in)) != 0)
    558539        {
    559540        PRINT_SOCKET_ERROR("bind");
     
    573554                             MSearchMsgFmt, deviceList[deviceIndex++], mx);
    574555                /*printf("Sending %s", bufr);*/
     556#if 0
    575557                n = sendto(sudp, bufr, n, 0,
    576558                           (struct sockaddr *)&sockudp_w, sizeof(struct sockaddr_in));
    577559                if (n < 0) {
    578560                        PRINT_SOCKET_ERROR("sendto");
     561                        closesocket(sudp);
     562                        return devlist;
     563                }
     564#endif
     565                memset(&hints, 0, sizeof(hints));
     566                hints.ai_family = AF_UNSPEC; // AF_INET6 or AF_INET
     567                hints.ai_socktype = SOCK_DGRAM;
     568                /*hints.ai_flags = */
     569                if ((rv = getaddrinfo(UPNP_MCAST_ADDR, XSTR(PORT), &hints, &servinfo)) != 0) {
     570#ifdef WIN32
     571                    fprintf(stderr, "getaddrinfo() failed: %d\n", rv);
     572#else
     573                    fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
     574#endif
     575                    return devlist;
     576                }
     577                for(p = servinfo; p; p = p->ai_next) {
     578                        n = sendto(sudp, bufr, n, 0, p->ai_addr, p->ai_addrlen);
     579                        if (n < 0) {
     580                                PRINT_SOCKET_ERROR("sendto");
     581                                continue;
     582                        }
     583                }
     584                freeaddrinfo(servinfo);
     585                if(n < 0) {
    579586                        closesocket(sudp);
    580587                        return devlist;
     
    603610                if(st&&descURL)
    604611                {
    605                         /*printf("M-SEARCH Reply:\nST: %.*s\nLocation: %.*s\n",
    606                                stsize, st, urlsize, descURL); */
     612#ifdef DEBUG
     613                        printf("M-SEARCH Reply:\nST: %.*s\nLocation: %.*s\n",
     614                               stsize, st, urlsize, descURL);
     615#endif
     616                        for(tmp=devlist; tmp; tmp = tmp->pNext) {
     617                                if(memcmp(tmp->descURL, descURL, urlsize) == 0 &&
     618                                   tmp->descURL[urlsize] == '\0' &&
     619                                   memcmp(tmp->st, st, stsize) == 0 &&
     620                                   tmp->st[stsize] == '\0')
     621                                        break;
     622                        }
     623                        /* at the exit of the loop above, tmp is null if
     624                         * no duplicate device was found */
     625                        if(tmp)
     626                                continue;
    607627                        tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize);
    608628                        tmp->pNext = devlist;
     
    667687        n1 += 2;        /* 1 byte more for Null terminator, 1 byte for '/' if needed */
    668688        n2 = n1; n3 = n1;
    669         n1 += strlen(data->scpdurl);
    670         n2 += strlen(data->controlurl);
    671         n3 += strlen(data->controlurl_CIF);
     689        n1 += strlen(data->first.scpdurl);
     690        n2 += strlen(data->first.controlurl);
     691        n3 += strlen(data->CIF.controlurl);
    672692
    673693        urls->ipcondescURL = (char *)malloc(n1);
     
    684704        strncpy(urls->controlURL_CIF, urls->ipcondescURL, n3);
    685705       
    686         url_cpy_or_cat(urls->ipcondescURL, data->scpdurl, n1);
    687 
    688         url_cpy_or_cat(urls->controlURL, data->controlurl, n2);
    689 
    690         url_cpy_or_cat(urls->controlURL_CIF, data->controlurl_CIF, n3);
    691 
    692 #ifdef DEBUG
    693         printf("urls->ipcondescURL='%s' %d n1=%d\n", urls->ipcondescURL,
    694                strlen(urls->ipcondescURL), n1);
    695         printf("urls->controlURL='%s' %d n2=%d\n", urls->controlURL,
    696                strlen(urls->controlURL), n2);
    697         printf("urls->controlURL_CIF='%s' %d n3=%d\n", urls->controlURL_CIF,
    698                strlen(urls->controlURL_CIF), n3);
     706        url_cpy_or_cat(urls->ipcondescURL, data->first.scpdurl, n1);
     707
     708        url_cpy_or_cat(urls->controlURL, data->first.controlurl, n2);
     709
     710        url_cpy_or_cat(urls->controlURL_CIF, data->CIF.controlurl, n3);
     711
     712#ifdef DEBUG
     713        printf("urls->ipcondescURL='%s' %u n1=%d\n", urls->ipcondescURL,
     714               (unsigned)strlen(urls->ipcondescURL), n1);
     715        printf("urls->controlURL='%s' %u n2=%d\n", urls->controlURL,
     716               (unsigned)strlen(urls->controlURL), n2);
     717        printf("urls->controlURL_CIF='%s' %u n3=%d\n", urls->controlURL_CIF,
     718               (unsigned)strlen(urls->controlURL_CIF), n3);
    699719#endif
    700720}
     
    769789        unsigned int uptime;
    770790        status[0] = '\0';
    771         UPNP_GetStatusInfo(urls->controlURL, data->servicetype,
     791        UPNP_GetStatusInfo(urls->controlURL, data->first.servicetype,
    772792                           status, &uptime, NULL);
    773793        if(0 == strcmp("Connected", status))
     
    826846                                free(descXML);
    827847                                descXML = NULL;
    828                                 if(0==strcmp(data->servicetype_CIF,
     848                                if(0==strcmp(data->CIF.servicetype,
    829849                                   "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1")
    830850                                   || state >= 3 )
     
    840860                                        return state;
    841861                                  FreeUPNPUrls(urls);
     862                                  if(data->second.servicetype[0] != '\0') {
     863#ifdef DEBUG
     864                                    printf("We tried %s, now we try %s !\n",
     865                                           data->first.servicetype, data->second.servicetype);
     866#endif
     867                                    /* swaping WANPPPConnection and WANIPConnection ! */
     868                                    memcpy(&data->tmp, &data->first, sizeof(struct IGDdatas_service));
     869                                    memcpy(&data->first, &data->second, sizeof(struct IGDdatas_service));
     870                                    memcpy(&data->second, &data->tmp, sizeof(struct IGDdatas_service));
     871                                    GetUPNPUrls(urls, data, dev->descURL);
     872#ifdef DEBUG
     873                                    printf("UPNPIGD_IsConnected(%s) = %d\n",
     874                                       urls->controlURL,
     875                                   UPNPIGD_IsConnected(urls, data));
     876#endif
     877                                    if((state >= 2) || UPNPIGD_IsConnected(urls, data))
     878                                          return state;
     879                                    FreeUPNPUrls(urls);
     880                                  }
    842881                                }
    843882                                memset(data, 0, sizeof(struct IGDdatas));
  • branches/1.9x/third-party/miniupnp/miniwget.c

    r10285 r10578  
    1 /* $Id: miniwget.c,v 1.31 2009/12/04 11:29:19 nanard Exp $ */
     1/* $Id: miniwget.c,v 1.37 2010/04/12 20:39:42 nanard Exp $ */
    22/* Project : miniupnp
    33 * Author : Thomas Bernard
    4  * Copyright (c) 2005-2009 Thomas Bernard
     4 * Copyright (c) 2005-2010 Thomas Bernard
    55 * This software is subject to the conditions detailed in the
    6  * LICENCE file provided in this distribution.
    7  * */
     6 * LICENCE file provided in this distribution. */
     7 
    88#include <stdio.h>
    99#include <stdlib.h>
     
    1212#ifdef WIN32
    1313#include <winsock2.h>
     14#include <ws2tcpip.h>
    1415#include <io.h>
    1516#define MAXHOSTNAMELEN 64
    1617#define MIN(x,y) (((x)<(y))?(x):(y))
    1718#define snprintf _snprintf
    18 #define herror
    1919#define socklen_t int
    20 #else
     20#else /* #ifdef WIN32 */
    2121#include <unistd.h>
    2222#include <sys/param.h>
    2323#if defined(__amigaos__) && !defined(__amigaos4__)
    2424#define socklen_t int
    25 #else
     25#else /* #if defined(__amigaos__) && !defined(__amigaos4__) */
    2626#include <sys/select.h>
    27 #endif
     27#endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */
    2828#include <sys/socket.h>
     29#include <arpa/inet.h>
    2930#include <netdb.h>
    30 #include <netinet/in.h>
    31 #include <arpa/inet.h>
    32 #include <errno.h>
    33 #include <time.h>
    3431#define closesocket close
     32/* defining MINIUPNPC_IGNORE_EINTR enable the ignore of interruptions
     33 * during the connect() call */
    3534#define MINIUPNPC_IGNORE_EINTR
    36 #endif
     35#endif /* #else WIN32 */
    3736#if defined(__sun) || defined(sun)
    3837#define MIN(x,y) (((x)<(y))?(x):(y))
    3938#endif
    40 #if defined(__amigaos__) || defined(__amigaos4__)
    41 #define herror(A) printf("%s\n", A)
    42 #endif
    4339
    4440#include "miniupnpcstrings.h"
    4541#include "miniwget.h"
    46 
    47 /* miniwget2() :
    48  * */
     42#include "connecthostport.h"
     43
     44/* miniwget3() :
     45 * do all the work.
     46 * Return NULL if something failed. */
    4947static void *
    50 miniwget2(const char * url, const char * host,
     48miniwget3(const char * url, const char * host,
    5149                  unsigned short port, const char * path,
    52                   int * size, char * addr_str, int addr_str_len)
     50                  int * size, char * addr_str, int addr_str_len, const char * httpversion)
    5351{
    5452        char buf[2048];
    5553    int s;
    56         struct sockaddr_in dest;
    57         struct hostent *hp;
    5854        int n;
    5955        int len;
    6056        int sent;
    61 #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
    62         struct timeval timeout;
    63 #endif
     57
    6458        *size = 0;
    65         hp = gethostbyname(host);
    66         if(hp==NULL)
    67         {
    68                 herror(host);
     59        s = connecthostport(host, port);
     60        if(s < 0)
    6961                return NULL;
    70         }
    71         /*  memcpy((char *)&dest.sin_addr, hp->h_addr, hp->h_length);  */
    72         memcpy(&dest.sin_addr, hp->h_addr, sizeof(dest.sin_addr));
    73         memset(dest.sin_zero, 0, sizeof(dest.sin_zero));
    74         s = socket(PF_INET, SOCK_STREAM, 0);
    75         if(s < 0)
    76         {
    77                 perror("socket");
    78                 return NULL;
    79         }
    80 #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
    81         /* setting a 3 seconds timeout for the connect() call */
    82         timeout.tv_sec = 3;
    83         timeout.tv_usec = 0;
    84         if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0)
    85         {
    86                 perror("setsockopt");
    87         }
    88         timeout.tv_sec = 3;
    89         timeout.tv_usec = 0;
    90         if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0)
    91         {
    92                 perror("setsockopt");
    93         }
    94 #endif
    95         dest.sin_family = AF_INET;
    96         dest.sin_port = htons(port);
    97         n = connect(s, (struct sockaddr *)&dest, sizeof(struct sockaddr_in));
    98 #ifdef MINIUPNPC_IGNORE_EINTR
    99         while(n < 0 && errno == EINTR)
    100         {
    101                 socklen_t len;
    102                 fd_set wset;
    103                 int err;
    104                 FD_ZERO(&wset);
    105                 FD_SET(s, &wset);
    106                 if((n = select(s + 1, NULL, &wset, NULL, NULL)) == -1 && errno == EINTR)
    107                         continue;
    108                 /*len = 0;*/
    109                 /*n = getpeername(s, NULL, &len);*/
    110                 len = sizeof(err);
    111                 if(getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &len) < 0) {
    112                         perror("getsockopt");
    113                         closesocket(s);
    114                         return NULL;
    115                 }
    116                 if(err != 0) {
    117                         errno = err;
    118                         n = -1;
    119                 }
    120         }
    121 #endif
    122         if(n<0)
    123         {
    124                 perror("connect");
    125                 closesocket(s);
    126                 return NULL;
    127         }
    12862
    12963        /* get address for caller ! */
    13064        if(addr_str)
    13165        {
    132                 struct sockaddr_in saddr;
     66                struct sockaddr saddr;
    13367                socklen_t saddrlen;
    13468
    13569                saddrlen = sizeof(saddr);
    136                 if(getsockname(s, (struct sockaddr *)&saddr, &saddrlen) < 0)
     70                if(getsockname(s, &saddr, &saddrlen) < 0)
    13771                {
    13872                        perror("getsockname");
     
    14074                else
    14175                {
    142 #if defined(WIN32) || (defined(__amigaos__) && !defined(__amigaos4__))
     76#if defined(__amigaos__) && !defined(__amigaos4__)
    14377        /* using INT WINAPI WSAAddressToStringA(LPSOCKADDR, DWORD, LPWSAPROTOCOL_INFOA, LPSTR, LPDWORD);
    14478     * But his function make a string with the port :  nn.nn.nn.nn:port */
     
    14882                    printf("WSAAddressToStringA() failed : %d\n", WSAGetLastError());
    14983                }*/
    150                         strncpy(addr_str, inet_ntoa(saddr.sin_addr), addr_str_len);
     84                        strncpy(addr_str, inet_ntoa(((struct sockaddr_in *)&saddr)->sin_addr), addr_str_len);
    15185#else
    152                         inet_ntop(AF_INET, &saddr.sin_addr, addr_str, addr_str_len);
     86                        /*inet_ntop(AF_INET, &saddr.sin_addr, addr_str, addr_str_len);*/
     87                        n = getnameinfo(&saddr, saddrlen,
     88                                        addr_str, addr_str_len,
     89                                        NULL, 0,
     90                                        NI_NUMERICHOST | NI_NUMERICSERV);
     91                        if(n != 0) {
     92#ifdef WIN32
     93                                fprintf(stderr, "getnameinfo() failed : %d\n", n);
     94#else
     95                                fprintf(stderr, "getnameinfo() failed : %s\n", gai_strerror(n));
     96#endif
     97                        }
    15398#endif
    15499                }
     
    159104
    160105        len = snprintf(buf, sizeof(buf),
    161                  "GET %s HTTP/1.0\r\n"
     106                 "GET %s HTTP/%s\r\n"
    162107                             "Host: %s:%d\r\n"
    163108                                 "Connection: Close\r\n"
     
    165110
    166111                                 "\r\n",
    167                     path, host, port);
     112                           path, httpversion, host, port);
    168113        sent = 0;
    169114        /* sending the HTTP request */
     
    232177}
    233178
     179/* miniwget2() :
     180 * Call miniwget3(); retry with HTTP/1.1 if 1.0 fails. */
     181static void *
     182miniwget2(const char * url, const char * host,
     183                  unsigned short port, const char * path,
     184                  int * size, char * addr_str, int addr_str_len)
     185{
     186        char * respbuffer;
     187
     188        respbuffer = miniwget3(url, host, port, path, size, addr_str, addr_str_len, "1.0");
     189        if (*size == 0)
     190        {
     191#ifdef DEBUG
     192                printf("Retrying with HTTP/1.1\n");
     193#endif
     194                free(respbuffer);
     195                respbuffer = miniwget3(url, host, port, path, size, addr_str, addr_str_len, "1.1");
     196        }
     197        return respbuffer;
     198}
     199
     200
     201
     202
    234203/* parseURL()
    235204 * arguments :
Note: See TracChangeset for help on using the changeset viewer.