upnpDiscover( ) :"sendto: Operation not permitted" && getaddrinfo() error : “Bad value for ai_flags”

sendto: Operation not permitted


在miniupnpc -1.6 的sourcecode 中 有个upnpDiscover( )函数 是向多播地址地址 UPNP_MCAST_ADDR "239.255.255.250" ,端口为 PORT 1900的socket 发多播包,编译的可执行档 upnpc 在pc上运行良好:


[vinco@IPPBX-Server miniupnpc]$ ./upnpc-static -s
List of UPNP devices found on the network :
 desc: http://172.16.1.115:2869/upnphost/udhisapi.dll?content=uuid:a8cfb97b-2b2b-4768-8d56-b96687b40899
 st: upnp:rootdevice

UPnP device found. Is it an IGD ? : http://172.16.1.115:2869/
Trying to continue anyway
Local LAN ip address : 172.16.0.248
Connection Type : 
Status : ôï¿, uptime=3219584368s, LastConnectionError : 
  Time started : Fri May  6 19:34:47 1910
MaxBitRateDown : 11201788 bps (11.2 Mbps)   MaxBitRateUp 153932400 bps (153.9 Mbps)
GetExternalIPAddress() returned -3
ExternalIPAddress = Àô¿

                        Bytes:   Sent: 4294967293       Recv: 4294967293
Packets: Sent: 4294967293       Recv: 4294967293
[vinco@IPPBX-Server miniupnpc]$ 
[vinco@IPPBX-Server miniupnpc]$ 

但是一旦编译放到板子上运行,在sendto( )系统调用处就会出现令人头痛的 sendto: Operation not permitted:

# upnpc -s
Sending 
M-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900
ST: urn:schemas-upnp-org:device:InternetGatewayDevice:1
MAN: "ssdp:discover"
MX: 2

host:239.255.255.250 port:1900
sendto: Operation not permitted
upnpDiscover-line 520
No IGD UPnP Device found on the network !
# 

查看相应的iptables 信息(当然是filter表,OUTPUT chain啦):

# 
# iptables -nvL OUTPUT
Chain OUTPUT (policy ACCEPT 835 packets, 395K bytes)
 pkts bytes target     prot opt in     out     source               destination         
    1   165 DROP       all  --  *      eth2    0.0.0.0/0            239.255.255.250     
# 
# 

发现了这坑爹的一幕,终于知道原因了。于是do as follow:

# 
# iptables -D OUTPUT 1
# iptables -nvL OUTPUT
Chain OUTPUT (policy ACCEPT 919 packets, 453K bytes)
 pkts bytes target     prot opt in     out     source               destination         
# 
# 

确保将这条该死的drop规则去掉(或者修改为其他具体的规则),发现sento()多播的问题解决了:

# upnpc -s
Sending
M-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900
ST: urn:schemas-upnp-org:device:InternetGatewayDevice:1
MAN: "ssdp:discover"
MX: 2

M-SEARCH Reply:
ST: urn:schemas-upnp-org:device:InternetGatewayDevice:1
Location: http://172.16.12.50:5431/dyndev/uuid:00191507-0023-2300-0715-19001907230000
List of UPNP devices found on the network :
 desc: http://172.16.12.50:5431/dyndev/uuid:00191507-0023-2300-0715-19001907230000
 st: urn:schemas-upnp-org:device:InternetGatewayDevice:1

getaddrinfo() error : Bad value for ai_flags
error getting XML description http://172.16.12.50:5431/dyndev/uuid:00191507-0023-2300-0715-19001907230000
No valid UPNP Internet Gateway Device found.
#
# 


这里还有个坑爹问题,就是 getaddrinfo() error : Bad value for ai_flags 这个很邪恶问题。

在源代码 connecthostport.c 的connecthostport( ) 函数中有的是getaddrinfo( )(不是用gethostbyname( ),源码中有一个宏 USE_GETHOSTBYNAME 控制), 同时用一个宏在hints初始化过程中控制ai_flags的赋值。的确有了这个AI_NUMERICSERV定义。

#ifdef AI_NUMERICSERV
    hints.ai_flags = AI_NUMERICSERV;
#endif

但是就是这个 ai_flags初始得有问题啊,干脆注释掉:


#ifdef AI_NUMERICSERV
    // damn it:getaddrinfo() error : Bad value for ai_flags
    //hints.ai_flags = AI_NUMERICSERV;
#endif

板子上运行:

# 
# upnpc -s
List of UPNP devices found on the network :
 desc: http://172.16.12.50:5431/dyndev/uuid:00191507-0023-2300-0715-19001907230000
 st: urn:schemas-upnp-org:device:InternetGatewayDevice:1

Found valid IGD : http://172.16.12.50:5431/uuid:00191507-0023-2300-0715-19001907230002/WANPPPConnection:1
Local LAN ip address : 172.16.15.55
Connection Type : IP_Routed
Status : Connected, uptime=55s, LastConnectionError : 
  Time started : Mon May 14 03:39:01 2012
MaxBitRateDown : 11068000 bps (11.0 Mbps)   MaxBitRateUp 1120000 bps (1.1 Mbps)
ExternalIPAddress = 111.174.238.218
Bytes:   Sent:        0 Recv:        0
Packets: Sent:        0 Recv:        0
# 
# 
# 



http://permalink.gmane.org/gmane.comp.web.privoxy.devel/10735  这个链接中有一种说法:


It seems that one or both of the flags AI_NUMERICSERV and AI_ADDRCONFIG
is/are defined but not actually supported.

To work around the problem you could try adding:

#undef AI_NUMERICSERV
#define AI_NUMERICSERV 0

below the line "#define MAX_LISTEN_BACKLOG 128" in jbsockets.c.

If it still doesn't work, add:

#undef AI_ADDRCONFIG
#define AI_ADDRCONFIG 0

and if it still fails use all four lines.

这个貌似也可以解决,但我没试过。





你可能感兴趣的:(Open,Source)