Changeset 1601


Ignore:
Timestamp:
Dec 1, 2007 8:52:57 AM (16 years ago)
Author:
bennylp
Message:

More ticket #415: more IPv6 and some reorganization of the source codes

Location:
pjproject/trunk/pjlib
Files:
1 added
17 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjlib/include/pj/addr_resolv.h

    r1599 r1601  
    8686/** 
    8787 * This function fills the structure of type pj_hostent for a given host name. 
     88 * For host resolution function that also works with IPv6, please see 
     89 * #pj_getaddrinfo(). 
    8890 * 
    89  * @param name      Host name, or IPv4 or IPv6 address in standard dot notation. 
    90  * @param he        The pj_hostent structure to be filled. 
     91 * @param name      Host name, or IPv4 address in standard dot notation. 
     92 * @param he        The pj_hostent structure to be filled. Note that 
     93 *                  the pointers in this structure points to temporary 
     94 *                  variables which value will be reset upon subsequent 
     95 *                  invocation. 
    9196 * 
    9297 * @return          PJ_SUCCESS, or the appropriate error codes. 
     
    98103 * Resolve the primary IP address of local host.  
    99104 * 
    100  * @param ip_addr   On successful resolution, this will be filled up with 
    101  *                  the host IP address, in network byte order. 
     105 * @param af        The desired address family to query. Valid values 
     106 *                  are pj_AF_INET() or pj_AF_INET6(). 
     107 * @param addr      On successful resolution, the address family and address 
     108 *                  part of this socket address will be filled up with the host 
     109 *                  IP address, in network byte order. Other parts of the socket 
     110 *                  address are untouched. 
    102111 * 
    103112 * @return          PJ_SUCCESS on success, or the appropriate error code. 
    104113 */ 
    105 PJ_DECL(pj_status_t) pj_gethostip(pj_in_addr *ip_addr); 
     114PJ_DECL(pj_status_t) pj_gethostip(int af, pj_sockaddr *addr); 
    106115 
    107116 
     
    110119 * interface of the default route. 
    111120 * 
    112  * @param ip_addr   On successful resolution, this will be filled up with 
    113  *                  the IP address, in network byte order. 
     121 * @param af        The desired address family to query. Valid values 
     122 *                  are pj_AF_INET() or pj_AF_INET6(). 
     123 * @param addr      On successful resolution, the address family and address 
     124 *                  part of this socket address will be filled up with the host 
     125 *                  IP address, in network byte order. Other parts of the socket 
     126 *                  address are untouched. 
    114127 * 
    115128 * @return          PJ_SUCCESS on success, or the appropriate error code. 
    116129 */ 
    117 PJ_DECL(pj_status_t) pj_getdefaultipinterface(pj_in_addr *ip_addr); 
     130PJ_DECL(pj_status_t) pj_getdefaultipinterface(int af, 
     131                                              pj_sockaddr *addr); 
    118132 
    119133 
     
    124138 * service. 
    125139 * 
     140 * @param af        The desired address family to query. Valid values 
     141 *                  are pj_AF_INET(), pj_AF_INET6(), or pj_AF_UNSPEC(). 
    126142 * @param name      Descriptive name or an address string, such as host 
    127143 *                  name. 
    128  * @param af        The desired address family to query. 
    129144 * @param count     On input, it specifies the number of elements in 
    130145 *                  \a ai array. On output, this will be set with the 
    131146 *                  number of address informations found for the 
    132147 *                  specified name. 
     148 * @param ai        Array of address info to be filled with the information 
     149 *                  about the host. 
    133150 * 
    134151 * @return          PJ_SUCCESS on success, or the appropriate error code. 
    135152 */ 
    136 PJ_DECL(pj_status_t) pj_getaddrinfo(const pj_str_t *nodename, int af, 
     153PJ_DECL(pj_status_t) pj_getaddrinfo(int af, const pj_str_t *name, 
    137154                                    unsigned *count, pj_addrinfo ai[]); 
    138155 
  • pjproject/trunk/pjlib/include/pj/compat/socket.h

    r1585 r1601  
    186186#endif 
    187187 
     188/* Regarding sin_len member of sockaddr_in: 
     189 *  BSD systems (including MacOS X requires that the sin_len member of  
     190 *  sockaddr_in be set to sizeof(sockaddr_in), while other systems (Windows 
     191 *  and Linux included) do not. 
     192 * 
     193 *  To maintain compatibility between systems, PJLIB will automatically 
     194 *  set this field before invoking native OS socket API, and it will 
     195 *  always reset the field to zero before returning pj_sockaddr_in to 
     196 *  application (such as in pj_getsockname() and pj_recvfrom()). 
     197 * 
     198 *  Application MUST always set this field to zero. 
     199 * 
     200 *  This way we can avoid hard to find problem such as when the socket  
     201 *  address is used as hash table key. 
     202 */ 
     203#if defined(PJ_SOCKADDR_HAS_LEN) && PJ_SOCKADDR_HAS_LEN!=0 
     204#   define PJ_SOCKADDR_SET_LEN(addr,len) (((pj_addr_hdr*)(addr))->sa_zero_len=(len)) 
     205#   define PJ_SOCKADDR_RESET_LEN(addr)   (((pj_addr_hdr*)(addr))->sa_zero_len=0) 
     206#else 
     207#   define PJ_SOCKADDR_SET_LEN(addr,len)  
     208#   define PJ_SOCKADDR_RESET_LEN(addr) 
     209#endif 
    188210 
    189211#endif  /* __PJ_COMPAT_SOCKET_H__ */ 
  • pjproject/trunk/pjlib/include/pj/errno.h

    r1585 r1601  
    315315 */ 
    316316#define PJ_EIPV6NOTSUP      (PJ_ERRNO_START_STATUS + 21)/* 70021 */ 
     317/** 
     318 * @hideinitializer 
     319 * Unsupported address family 
     320 */ 
     321#define PJ_EAFNOTSUP        (PJ_ERRNO_START_STATUS + 22)/* 70022 */ 
    317322 
    318323/** @} */   /* pj_errnum */ 
  • pjproject/trunk/pjlib/include/pj/ip_helper.h

    r1104 r1601  
    5454 
    5555/** 
    56  * Enumerate the local IP interface currently active in the host. 
     56 * Enumerate the local IP interfaces currently active in the host. 
    5757 * 
     58 * @param af        Family of the address to be retrieved. Application 
     59 *                  may specify pj_AF_UNSPEC() to retrieve all addresses, 
     60 *                  or pj_AF_INET() or pj_AF_INET6() to retrieve interfaces 
     61 *                  with specific address family. 
    5862 * @param count     On input, specify the number of entries. On output, 
    5963 *                  it will be filled with the actual number of entries. 
    60  * @param ifs       Array of IP addresses. 
     64 * @param ifs       Array of socket addresses, which address part will 
     65 *                  be filled with the interface address. The address 
     66 *                  family part will be initialized with the address 
     67 *                  family of the IP address. 
    6168 * 
    6269 * @return          PJ_SUCCESS on success, or the appropriate error code. 
    6370 */ 
    64 PJ_DECL(pj_status_t) pj_enum_ip_interface(unsigned *count, 
    65                                           pj_in_addr ifs[]); 
     71PJ_DECL(pj_status_t) pj_enum_ip_interface(int af, 
     72                                          unsigned *count, 
     73                                          pj_sockaddr ifs[]); 
    6674 
    6775 
  • pjproject/trunk/pjlib/include/pj/os.h

    r1589 r1601  
    335335    void        *rhostresolver; 
    336336      
     337    /** 
     338     * Optional RHostResolver for IPv6 instance to be used by PJLIB.  
     339     * If this value is NULL, a new RHostResolver instance will be created 
     340     * when pj_init() is called. 
     341     */ 
     342    void        *rhostresolver6; 
     343      
    337344} pj_symbianos_params; 
    338345 
  • pjproject/trunk/pjlib/include/pj/sock.h

    r1585 r1601  
    8888 */ 
    8989 
    90 /** Get #PJ_AF_UNSPEC value */ 
    91 PJ_DECL(pj_uint16_t) pj_AF_UNSPEC(void); 
    92 /** Get #PJ_AF_UNIX value. */ 
    93 PJ_DECL(pj_uint16_t) pj_AF_UNIX(void); 
    94 /** Get #PJ_AF_INET value. */ 
    95 PJ_DECL(pj_uint16_t) pj_AF_INET(void); 
    96 /** Get #PJ_AF_INET6 value. */ 
    97 PJ_DECL(pj_uint16_t) pj_AF_INET6(void); 
    98 /** Get #PJ_AF_PACKET value. */ 
    99 PJ_DECL(pj_uint16_t) pj_AF_PACKET(void); 
    100 /** Get #PJ_AF_IRDA value. */ 
    101 PJ_DECL(pj_uint16_t) pj_AF_IRDA(void); 
     90#if defined(PJ_DLL) 
     91    /** Get #PJ_AF_UNSPEC value */ 
     92    PJ_DECL(pj_uint16_t) pj_AF_UNSPEC(void); 
     93    /** Get #PJ_AF_UNIX value. */ 
     94    PJ_DECL(pj_uint16_t) pj_AF_UNIX(void); 
     95    /** Get #PJ_AF_INET value. */ 
     96    PJ_DECL(pj_uint16_t) pj_AF_INET(void); 
     97    /** Get #PJ_AF_INET6 value. */ 
     98    PJ_DECL(pj_uint16_t) pj_AF_INET6(void); 
     99    /** Get #PJ_AF_PACKET value. */ 
     100    PJ_DECL(pj_uint16_t) pj_AF_PACKET(void); 
     101    /** Get #PJ_AF_IRDA value. */ 
     102    PJ_DECL(pj_uint16_t) pj_AF_IRDA(void); 
     103#else 
     104    /* When pjlib is not built as DLL, these accessor functions are 
     105     * simply a macro to get their constants 
     106     */ 
     107    /** Get #PJ_AF_UNSPEC value */ 
     108#   define pj_AF_UNSPEC()   PJ_AF_UNSPEC 
     109    /** Get #PJ_AF_UNIX value. */ 
     110#   define pj_AF_UNIX()     PJ_AF_UNIX 
     111    /** Get #PJ_AF_INET value. */ 
     112#   define pj_AF_INET()     PJ_AF_INET 
     113    /** Get #PJ_AF_INET6 value. */ 
     114#   define pj_AF_INET6()    PJ_AF_INET6 
     115    /** Get #PJ_AF_PACKET value. */ 
     116#   define pj_AF_PACKET()   PJ_AF_PACKET 
     117    /** Get #PJ_AF_IRDA value. */ 
     118#   define pj_AF_IRDA()     PJ_AF_IRDA 
     119#endif 
    102120 
    103121 
     
    128146 */ 
    129147 
    130 /** Get #PJ_SOCK_STREAM constant */ 
    131 PJ_DECL(int) pj_SOCK_STREAM(void); 
    132 /** Get #PJ_SOCK_DGRAM constant */ 
    133 PJ_DECL(int) pj_SOCK_DGRAM(void); 
    134 /** Get #PJ_SOCK_RAW constant */ 
    135 PJ_DECL(int) pj_SOCK_RAW(void); 
    136 /** Get #PJ_SOCK_RDM constant */ 
    137 PJ_DECL(int) pj_SOCK_RDM(void); 
     148#if defined(PJ_DLL) 
     149    /** Get #PJ_SOCK_STREAM constant */ 
     150    PJ_DECL(int) pj_SOCK_STREAM(void); 
     151    /** Get #PJ_SOCK_DGRAM constant */ 
     152    PJ_DECL(int) pj_SOCK_DGRAM(void); 
     153    /** Get #PJ_SOCK_RAW constant */ 
     154    PJ_DECL(int) pj_SOCK_RAW(void); 
     155    /** Get #PJ_SOCK_RDM constant */ 
     156    PJ_DECL(int) pj_SOCK_RDM(void); 
     157#else 
     158    /** Get #PJ_SOCK_STREAM constant */ 
     159#   define pj_SOCK_STREAM() PJ_SOCK_STREAM 
     160    /** Get #PJ_SOCK_DGRAM constant */ 
     161#   define pj_SOCK_DGRAM()  PJ_SOCK_DGRAM 
     162    /** Get #PJ_SOCK_RAW constant */ 
     163#   define pj_SOCK_RAW()    PJ_SOCK_RAW 
     164    /** Get #PJ_SOCK_RDM constant */ 
     165#   define pj_SOCK_RDM()    PJ_SOCK_RDM 
     166#endif 
    138167 
    139168 
     
    159188 */ 
    160189 
    161 /** Get #PJ_SOL_SOCKET constant */ 
    162 PJ_DECL(pj_uint16_t) pj_SOL_SOCKET(void); 
    163 /** Get #PJ_SOL_IP constant */ 
    164 PJ_DECL(pj_uint16_t) pj_SOL_IP(void); 
    165 /** Get #PJ_SOL_TCP constant */ 
    166 PJ_DECL(pj_uint16_t) pj_SOL_TCP(void); 
    167 /** Get #PJ_SOL_UDP constant */ 
    168 PJ_DECL(pj_uint16_t) pj_SOL_UDP(void); 
    169 /** Get #PJ_SOL_IPV6 constant */ 
    170 PJ_DECL(pj_uint16_t) pj_SOL_IPV6(void); 
     190#if defined(PJ_DLL) 
     191    /** Get #PJ_SOL_SOCKET constant */ 
     192    PJ_DECL(pj_uint16_t) pj_SOL_SOCKET(void); 
     193    /** Get #PJ_SOL_IP constant */ 
     194    PJ_DECL(pj_uint16_t) pj_SOL_IP(void); 
     195    /** Get #PJ_SOL_TCP constant */ 
     196    PJ_DECL(pj_uint16_t) pj_SOL_TCP(void); 
     197    /** Get #PJ_SOL_UDP constant */ 
     198    PJ_DECL(pj_uint16_t) pj_SOL_UDP(void); 
     199    /** Get #PJ_SOL_IPV6 constant */ 
     200    PJ_DECL(pj_uint16_t) pj_SOL_IPV6(void); 
     201#else 
     202    /** Get #PJ_SOL_SOCKET constant */ 
     203#   define pj_SOL_SOCKET()  PJ_SOL_SOCKET 
     204    /** Get #PJ_SOL_IP constant */ 
     205#   define pj_SOL_IP()      PJ_SOL_IP 
     206    /** Get #PJ_SOL_TCP constant */ 
     207#   define pj_SOL_TCP()     PJ_SOL_TCP 
     208    /** Get #PJ_SOL_UDP constant */ 
     209#   define pj_SOL_UDP()     PJ_SOL_UDP 
     210    /** Get #PJ_SOL_IPV6 constant */ 
     211#   define pj_SOL_IPV6()    PJ_SOL_IPV6 
     212#endif 
    171213 
    172214 
     
    180222extern const pj_uint16_t PJ_IP_TOS; 
    181223 
    182 /** Get #PJ_IP_TOS constant */ 
    183 PJ_DECL(int) pj_IP_TOS(void); 
    184  
    185224/* 
    186225 * IP TOS related constats. 
     
    204243 
    205244 
    206 /** Get #PJ_IPTOS_LOWDELAY constant */ 
    207 PJ_DECL(int) pj_IPTOS_LOWDELAY(void); 
    208  
    209 /** Get #PJ_IPTOS_THROUGHPUT constant */ 
    210 PJ_DECL(int) pj_IPTOS_THROUGHPUT(void); 
    211  
    212 /** Get #PJ_IPTOS_RELIABILITY constant */ 
    213 PJ_DECL(int) pj_IPTOS_RELIABILITY(void); 
    214  
    215 /** Get #PJ_IPTOS_MINCOST constant */ 
    216 PJ_DECL(int) pj_IPTOS_MINCOST(void); 
     245#if defined(PJ_DLL) 
     246    /** Get #PJ_IP_TOS constant */ 
     247    PJ_DECL(int) pj_IP_TOS(void); 
     248 
     249    /** Get #PJ_IPTOS_LOWDELAY constant */ 
     250    PJ_DECL(int) pj_IPTOS_LOWDELAY(void); 
     251 
     252    /** Get #PJ_IPTOS_THROUGHPUT constant */ 
     253    PJ_DECL(int) pj_IPTOS_THROUGHPUT(void); 
     254 
     255    /** Get #PJ_IPTOS_RELIABILITY constant */ 
     256    PJ_DECL(int) pj_IPTOS_RELIABILITY(void); 
     257 
     258    /** Get #PJ_IPTOS_MINCOST constant */ 
     259    PJ_DECL(int) pj_IPTOS_MINCOST(void); 
     260#else 
     261    /** Get #PJ_IP_TOS constant */ 
     262#   define pj_IP_TOS()          PJ_IP_TOS 
     263 
     264    /** Get #PJ_IPTOS_LOWDELAY constant */ 
     265#   define pj_IPTOS_LOWDELAY()  PJ_IP_TOS_LOWDELAY 
     266 
     267    /** Get #PJ_IPTOS_THROUGHPUT constant */ 
     268#   define pj_IPTOS_THROUGHPUT() PJ_IP_TOS_THROUGHPUT 
     269 
     270    /** Get #PJ_IPTOS_RELIABILITY constant */ 
     271#   define pj_IPTOS_RELIABILITY() PJ_IP_TOS_RELIABILITY 
     272 
     273    /** Get #PJ_IPTOS_MINCOST constant */ 
     274#   define pj_IPTOS_MINCOST()   PJ_IP_TOS_MINCOST 
     275#endif 
    217276 
    218277 
     
    232291 
    233292 
    234 /** Get #PJ_SO_TYPE constant */ 
    235 PJ_DECL(pj_uint16_t) pj_SO_TYPE(void); 
    236  
    237 /** Get #PJ_SO_RCVBUF constant */ 
    238 PJ_DECL(pj_uint16_t) pj_SO_RCVBUF(void); 
    239  
    240 /** Get #PJ_SO_SNDBUF constant */ 
    241 PJ_DECL(pj_uint16_t) pj_SO_SNDBUF(void); 
     293#if defined(PJ_DLL) 
     294    /** Get #PJ_SO_TYPE constant */ 
     295    PJ_DECL(pj_uint16_t) pj_SO_TYPE(void); 
     296 
     297    /** Get #PJ_SO_RCVBUF constant */ 
     298    PJ_DECL(pj_uint16_t) pj_SO_RCVBUF(void); 
     299 
     300    /** Get #PJ_SO_SNDBUF constant */ 
     301    PJ_DECL(pj_uint16_t) pj_SO_SNDBUF(void); 
     302#else 
     303    /** Get #PJ_SO_TYPE constant */ 
     304#   define pj_SO_TYPE()     PJ_SO_TYPE 
     305 
     306    /** Get #PJ_SO_RCVBUF constant */ 
     307#   define pj_SO_RCVBUF()   PJ_SO_RCVBUF 
     308 
     309    /** Get #PJ_SO_SNDBUF constant */ 
     310#   define pj_SO_SNDBUF()   PJ_SO_SNDBUF 
     311#endif 
    242312 
    243313 
     
    256326 
    257327 
    258 /** Get #PJ_MSG_OOB constant */ 
    259 PJ_DECL(int) pj_MSG_OOB(void); 
    260  
    261 /** Get #PJ_MSG_PEEK constant */ 
    262 PJ_DECL(int) pj_MSG_PEEK(void); 
    263  
    264 /** Get #PJ_MSG_DONTROUTE constant */ 
    265 PJ_DECL(int) pj_MSG_DONTROUTE(void); 
     328#if defined(PJ_DLL) 
     329    /** Get #PJ_MSG_OOB constant */ 
     330    PJ_DECL(int) pj_MSG_OOB(void); 
     331 
     332    /** Get #PJ_MSG_PEEK constant */ 
     333    PJ_DECL(int) pj_MSG_PEEK(void); 
     334 
     335    /** Get #PJ_MSG_DONTROUTE constant */ 
     336    PJ_DECL(int) pj_MSG_DONTROUTE(void); 
     337#else 
     338    /** Get #PJ_MSG_OOB constant */ 
     339#   define pj_MSG_OOB()         PJ_MSG_OOB 
     340 
     341    /** Get #PJ_MSG_PEEK constant */ 
     342#   define pj_MSG_PEEK()        PJ_MSG_PEEK 
     343 
     344    /** Get #PJ_MSG_DONTROUTE constant */ 
     345#   define pj_MSG_DONTROUTE()   PJ_MSG_DONTROUTE 
     346#endif 
    266347 
    267348 
     
    307388#define PJ_INVALID_SOCKET   (-1) 
    308389 
     390/* Must undefine s_addr because of pj_in_addr below */ 
    309391#undef s_addr 
    310392 
     
    363445    /* While these are used for proper alignment */ 
    364446    pj_uint32_t u6_addr32[4]; 
    365 #if defined(PJ_HAS_INT64) && PJ_HAS_INT64!=0 
     447 
     448    /* Do not use this with Winsock2, as this will align pj_sockaddr_in6 
     449     * to 64-bit boundary and Winsock2 doesn't like it! 
     450     */ 
     451#if defined(PJ_HAS_INT64) && PJ_HAS_INT64!=0 && \ 
     452    (!defined(PJ_WIN32) || PJ_WIN32==0) 
    366453    pj_int64_t  u6_addr64[2]; 
    367454#endif 
     
    556643 
    557644/** 
    558  * Get the transport layer port number of an Internet socket address. 
    559  * The port is returned in host byte order. 
    560  * 
    561  * @param addr      The IP socket address. 
     645 * Initialize IPv4 socket address based on the address and port info. 
     646 * The string address may be in a standard numbers and dots notation or  
     647 * may be a hostname. If hostname is specified, then the function will  
     648 * resolve the host into the IP address. 
     649 * 
     650 * @see pj_sockaddr_init() 
     651 * 
     652 * @param addr      The IP socket address to be set. 
     653 * @param cp        The address string, which can be in a standard  
     654 *                  dotted numbers or a hostname to be resolved. 
     655 * @param port      The port number, in host byte order. 
     656 * 
     657 * @return          Zero on success. 
     658 */ 
     659PJ_DECL(pj_status_t) pj_sockaddr_in_init( pj_sockaddr_in *addr, 
     660                                          const pj_str_t *cp, 
     661                                          pj_uint16_t port); 
     662 
     663/** 
     664 * Initialize IP socket address based on the address and port info. 
     665 * The string address may be in a standard numbers and dots notation or  
     666 * may be a hostname. If hostname is specified, then the function will  
     667 * resolve the host into the IP address. 
     668 * 
     669 * @see pj_sockaddr_in_init() 
     670 * 
     671 * @param af        Internet address family. 
     672 * @param addr      The IP socket address to be set. 
     673 * @param cp        The address string, which can be in a standard  
     674 *                  dotted numbers or a hostname to be resolved. 
     675 * @param port      The port number, in host byte order. 
     676 * 
     677 * @return          Zero on success. 
     678 */ 
     679PJ_DECL(pj_status_t) pj_sockaddr_init(int af,  
     680                                      pj_sockaddr *addr, 
     681                                      const pj_str_t *cp, 
     682                                      pj_uint16_t port); 
     683 
     684/** 
     685 * Get pointer to the address part of a socket address. 
     686 *  
     687 * @param addr      Socket address. 
     688 * 
     689 * @return          Pointer to address part (sin_addr or sin6_addr, 
     690 *                  depending on address family) 
     691 */ 
     692PJ_DECL(void*) pj_sockaddr_get_addr(const pj_sockaddr_t *addr); 
     693 
     694/** 
     695 * Check that a socket address contains a non-zero address part. 
     696 * 
     697 * @param addr      Socket address. 
     698 * 
     699 * @return          Non-zero if address is set to non-zero. 
     700 */ 
     701PJ_DECL(pj_bool_t) pj_sockaddr_has_addr(const pj_sockaddr_t *addr); 
     702 
     703/** 
     704 * Get the address part length of a socket address, based on its address 
     705 * family. For PJ_AF_INET, the length will be sizeof(pj_in_addr), and 
     706 * for PJ_AF_INET6, the length will be sizeof(pj_in6_addr). 
     707 *  
     708 * @param addr      Socket address. 
     709 * 
    562710 * @return          Port number, in host byte order. 
    563711 */ 
    564 PJ_INLINE(pj_uint16_t) pj_sockaddr_in_get_port(const pj_sockaddr_in *addr) 
    565 { 
    566     return pj_ntohs(addr->sin_port); 
    567 } 
    568  
    569 /** 
    570  * Set the port number of an Internet socket address. 
    571  * 
    572  * @param addr      The IP socket address. 
    573  * @param hostport  The port number, in host byte order. 
    574  */ 
    575 PJ_INLINE(void) pj_sockaddr_in_set_port(pj_sockaddr_in *addr,  
    576                                         pj_uint16_t hostport) 
    577 { 
    578     addr->sin_port = pj_htons(hostport); 
    579 } 
    580  
    581 /** 
    582  * Get the IP address of an Internet socket address. 
     712PJ_DECL(unsigned) pj_sockaddr_get_addr_len(const pj_sockaddr_t *addr); 
     713 
     714/** 
     715 * Get the IP address of an IPv4 socket address. 
    583716 * The address is returned as 32bit value in host byte order. 
    584717 * 
     
    586719 * @return          32bit address, in host byte order. 
    587720 */ 
    588 PJ_INLINE(pj_in_addr) pj_sockaddr_in_get_addr(const pj_sockaddr_in *addr) 
    589 { 
    590     pj_in_addr in_addr; 
    591     in_addr.s_addr = pj_ntohl(addr->sin_addr.s_addr); 
    592     return in_addr; 
    593 } 
    594  
    595 /** 
    596  * Set the IP address of an Internet socket address. 
     721PJ_DECL(pj_in_addr) pj_sockaddr_in_get_addr(const pj_sockaddr_in *addr); 
     722 
     723/** 
     724 * Set the IP address of an IPv4 socket address. 
    597725 * 
    598726 * @param addr      The IP socket address. 
    599727 * @param hostaddr  The host address, in host byte order. 
    600728 */ 
    601 PJ_INLINE(void) pj_sockaddr_in_set_addr(pj_sockaddr_in *addr, 
    602                                         pj_uint32_t hostaddr) 
    603 { 
    604     addr->sin_addr.s_addr = pj_htonl(hostaddr); 
    605 } 
     729PJ_DECL(void) pj_sockaddr_in_set_addr(pj_sockaddr_in *addr, 
     730                                      pj_uint32_t hostaddr); 
    606731 
    607732/** 
     
    612737 * address. 
    613738 * 
     739 * @see pj_sockaddr_set_str_addr() 
     740 * 
    614741 * @param addr      The IP socket address to be set. 
    615742 * @param cp        The address string, which can be in a standard  
    616743 *                  dotted numbers or a hostname to be resolved. 
    617744 * 
    618  * @return          Zero on success. 
     745 * @return          PJ_SUCCESS on success. 
    619746 */ 
    620747PJ_DECL(pj_status_t) pj_sockaddr_in_set_str_addr( pj_sockaddr_in *addr, 
     
    622749 
    623750/** 
    624  * Set the IP address and port of an IP socket address. 
    625  * The string address may be in a standard numbers and dots notation or  
    626  * may be a hostname. If hostname is specified, then the function will  
    627  * resolve the host into the IP address. 
    628  * 
     751 * Set the IP address of an IPv4 or IPv6 socket address from string address, 
     752 * with resolving the host if necessary. The string address may be in a 
     753 * standard IPv6 or IPv6 address or may be a hostname. If hostname 
     754 * is specified, then the function will resolve the host into the IP 
     755 * address according to the address family. 
     756 * 
     757 * @param af        Address family. 
    629758 * @param addr      The IP socket address to be set. 
    630759 * @param cp        The address string, which can be in a standard  
    631  *                  dotted numbers or a hostname to be resolved. 
    632  * @param port      The port number, in host byte order. 
    633  * 
    634  * @return          Zero on success. 
    635  */ 
    636 PJ_DECL(pj_status_t) pj_sockaddr_in_init( pj_sockaddr_in *addr, 
    637                                           const pj_str_t *cp, 
    638                                           pj_uint16_t port); 
    639  
     760 *                  IP numbers (IPv4 or IPv6) or a hostname to be resolved. 
     761 * 
     762 * @return          PJ_SUCCESS on success. 
     763 */ 
     764PJ_DECL(pj_status_t) pj_sockaddr_set_str_addr(int af, 
     765                                              pj_sockaddr *addr, 
     766                                              const pj_str_t *cp); 
     767 
     768/** 
     769 * Get the port number of a socket address, in host byte order.  
     770 * This function can be used for both IPv4 and IPv6 socket address. 
     771 *  
     772 * @param addr      Socket address. 
     773 * 
     774 * @return          Port number, in host byte order. 
     775 */ 
     776PJ_DECL(pj_uint16_t) pj_sockaddr_get_port(const pj_sockaddr_t *addr); 
     777 
     778/** 
     779 * Get the transport layer port number of an Internet socket address. 
     780 * The port is returned in host byte order. 
     781 * 
     782 * @param addr      The IP socket address. 
     783 * @return          Port number, in host byte order. 
     784 */ 
     785PJ_DECL(pj_uint16_t) pj_sockaddr_in_get_port(const pj_sockaddr_in *addr); 
     786 
     787/** 
     788 * Set the port number of an Internet socket address. 
     789 * 
     790 * @param addr      The socket address. 
     791 * @param hostport  The port number, in host byte order. 
     792 */ 
     793PJ_DECL(pj_status_t) pj_sockaddr_set_port(pj_sockaddr *addr,  
     794                                          pj_uint16_t hostport); 
     795 
     796/** 
     797 * Set the port number of an IPv4 socket address. 
     798 * 
     799 * @see pj_sockaddr_set_port() 
     800 * 
     801 * @param addr      The IP socket address. 
     802 * @param hostport  The port number, in host byte order. 
     803 */ 
     804PJ_DECL(void) pj_sockaddr_in_set_port(pj_sockaddr_in *addr,  
     805                                      pj_uint16_t hostport); 
    640806 
    641807/***************************************************************************** 
  • pjproject/trunk/pjlib/src/pj/addr_resolv_sock.c

    r1599 r1601  
    5656} 
    5757 
    58 /* Get the default IP interface */ 
    59 PJ_DEF(pj_status_t) pj_getdefaultipinterface(pj_in_addr *addr) 
    60 { 
    61     pj_sock_t fd; 
    62     pj_str_t cp; 
    63     pj_sockaddr_in a; 
    64     int len; 
    65     pj_status_t status; 
    66  
    67     status = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &fd); 
    68     if (status != PJ_SUCCESS) { 
    69         return status; 
    70     } 
    71  
    72     cp = pj_str("1.1.1.1"); 
    73     pj_sockaddr_in_init(&a, &cp, 53); 
    74  
    75     status = pj_sock_connect(fd, &a, sizeof(a)); 
    76     if (status != PJ_SUCCESS) { 
    77         pj_sock_close(fd); 
    78         return status; 
    79     } 
    80  
    81     len = sizeof(a); 
    82     status = pj_sock_getsockname(fd, &a, &len); 
    83     if (status != PJ_SUCCESS) { 
    84         pj_sock_close(fd); 
    85         return status; 
    86     } 
    87  
    88     pj_sock_close(fd); 
    89  
    90     *addr = a.sin_addr; 
    91  
    92     /* Success */ 
    93     return PJ_SUCCESS; 
    94 } 
    95  
    96  
    97 /* Resolve the IP address of local machine */ 
    98 PJ_DEF(pj_status_t) pj_gethostip(pj_in_addr *addr) 
    99 { 
    100     const pj_str_t *hostname = pj_gethostname(); 
    101     struct pj_hostent he; 
    102     pj_status_t status; 
    103  
    104  
    105 #ifdef _MSC_VER 
    106     /* Get rid of "uninitialized he variable" with MS compilers */ 
    107     pj_bzero(&he, sizeof(he)); 
    108 #endif 
    109  
    110     /* Try with resolving local hostname first */ 
    111     status = pj_gethostbyname(hostname, &he); 
    112     if (status == PJ_SUCCESS) { 
    113         *addr = *(pj_in_addr*)he.h_addr; 
    114     } 
    115  
    116  
    117     /* If we end up with 127.x.x.x, resolve the IP by getting the default 
    118      * interface to connect to some public host. 
    119      */ 
    120     if (status != PJ_SUCCESS || (pj_ntohl(addr->s_addr) >> 24)==127 || 
    121         addr->s_addr == 0)  
    122     { 
    123         status = pj_getdefaultipinterface(addr); 
    124     } 
    125  
    126     /* As the last resort, get the first available interface */ 
    127     if (status != PJ_SUCCESS) { 
    128         pj_in_addr addrs[2]; 
    129         unsigned count = PJ_ARRAY_SIZE(addrs); 
    130  
    131         status = pj_enum_ip_interface(&count, addrs); 
    132         if (status == PJ_SUCCESS) { 
    133             if (count != 0) { 
    134                 *addr = addrs[0]; 
    135             } else { 
    136                 /* Just return 127.0.0.1 */ 
    137                 addr->s_addr = pj_htonl (0x7f000001); 
    138             } 
    139         } 
    140     } 
    141  
    142     return status; 
    143 } 
    144  
    145  
    14658/* Resolve IPv4/IPv6 address */ 
    147 PJ_DEF(pj_status_t) pj_getaddrinfo(const pj_str_t *nodename, int af, 
     59PJ_DEF(pj_status_t) pj_getaddrinfo(int af, const pj_str_t *nodename, 
    14860                                   unsigned *count, pj_addrinfo ai[]) 
    14961{ 
     
    15668    PJ_ASSERT_RETURN(nodename && count && *count && ai, PJ_EINVAL); 
    15769    PJ_ASSERT_RETURN(nodename->ptr && nodename->slen, PJ_EINVAL); 
    158     PJ_ASSERT_RETURN(af==PJ_AF_INET || af==PJ_AF_INET6, PJ_EINVAL); 
     70    PJ_ASSERT_RETURN(af==PJ_AF_INET || af==PJ_AF_INET6 || 
     71                     af==PJ_AF_UNSPEC, PJ_EINVAL); 
    15972 
    16073    /* Copy node name to null terminated string. */ 
     
    18093            continue; 
    18194 
    182         /* Ignore name that's too long */ 
    183         len = pj_ansi_strlen(res->ai_canonname); 
    184         if (len >= PJ_MAX_HOSTNAME) 
    185             continue; 
    186  
    187         /* Store canonical name */ 
    188         pj_ansi_strcpy(ai[i].ai_canonname, res->ai_canonname); 
     95        /* Store canonical name (possibly truncating the name) */ 
     96        pj_ansi_strncpy(ai[i].ai_canonname, res->ai_canonname, 
     97                        sizeof(ai[i].ai_canonname)); 
     98        ai[i].ai_canonname[sizeof(ai[i].ai_canonname)-1] = '\0'; 
    18999 
    190100        /* Store address */ 
     
    202112 
    203113#else   /* PJ_SOCK_HAS_GETADDRINFO */ 
    204     /* IPv6 is not supported */ 
    205     PJ_UNUSED_ARG(nodename); 
    206     PJ_UNUSED_ARG(af); 
    207     PJ_UNUSED_ARG(ai); 
    208114 
    209115    PJ_ASSERT_RETURN(count, PJ_EINVAL); 
    210     *count = 0; 
    211116 
    212     return PJ_EIPV6NOTSUP; 
     117    if (af == PJ_AF_INET || af == PJ_AF_UNSPEC) { 
     118        pj_hostent he; 
     119        unsigned i, max_count; 
     120        pj_status_t status; 
     121         
     122        status = pj_gethostbyname(nodename, &he); 
     123        if (status != PJ_SUCCESS) 
     124            return status; 
     125 
     126        max_count = *count; 
     127        *count = 0; 
     128 
     129        pj_bzero(ai, max_count * sizeof(pj_addrinfo)); 
     130 
     131        for (i=0; he.h_addr_list[i] && *count<max_count; ++i) { 
     132            pj_ansi_strncpy(ai[*count].ai_canonname, he.h_name, 
     133                            sizeof(ai[*count].ai_canonname)); 
     134            ai[*count].ai_canonname[sizeof(ai[*count].ai_canonname)-1] = '\0'; 
     135 
     136            ai[*count].ai_addr.ipv4.sin_family = PJ_AF_INET; 
     137            pj_memcpy(&ai[*count].ai_addr.ipv4.sin_addr, 
     138                      he.h_addr_list[i], he.h_length); 
     139 
     140            (*count)++; 
     141        } 
     142 
     143        return PJ_SUCCESS; 
     144 
     145    } else { 
     146        /* IPv6 is not supported */ 
     147        *count = 0; 
     148 
     149        return PJ_EIPV6NOTSUP; 
     150    } 
    213151#endif  /* PJ_SOCK_HAS_GETADDRINFO */ 
    214152} 
  • pjproject/trunk/pjlib/src/pj/addr_resolv_symbian.cpp

    r1599 r1601  
    2828  
    2929 
     30 
    3031// PJLIB API: resolve hostname 
    3132PJ_DEF(pj_status_t) pj_gethostbyname(const pj_str_t *name, pj_hostent *he) 
    3233{ 
    33     PJ_ASSERT_RETURN(name && he, PJ_EINVAL); 
     34    static pj_addrinfo ai; 
     35    static char *aliases[2]; 
     36    static char *addrlist[2]; 
     37    unsigned count = 1; 
     38    pj_status_t status; 
     39     
     40    status = pj_getaddrinfo(PJ_AF_INET, name, &count, &ai); 
     41    if (status != PJ_SUCCESS) 
     42        return status; 
     43     
     44    aliases[0] = ai.ai_canonname; 
     45    aliases[1] = NULL; 
     46     
     47    addrlist[0] = (char*) &ai.ai_addr.ipv4.sin_addr; 
     48    addrlist[1] = NULL; 
     49     
     50    pj_bzero(he, sizeof(*he)); 
     51    he->h_name = aliases[0]; 
     52    he->h_aliases = aliases; 
     53    he->h_addrtype = PJ_AF_INET; 
     54    he->h_length = 4; 
     55    he->h_addr_list = addrlist; 
     56     
     57    return PJ_SUCCESS; 
     58} 
    3459 
    35     RHostResolver &resv = PjSymbianOS::Instance()->GetResolver(); 
     60 
     61// Resolve for specific address family 
     62static pj_status_t getaddrinfo_by_af(int af, const pj_str_t *name, 
     63                                     unsigned *count, pj_addrinfo ai[])  
     64{ 
     65    unsigned i; 
     66    pj_status_t status; 
     67     
     68    PJ_ASSERT_RETURN(name && count && ai, PJ_EINVAL); 
     69 
     70    // Get resolver for the specified address family 
     71    RHostResolver &resv = PjSymbianOS::Instance()->GetResolver(af); 
    3672 
    3773    // Convert name to Unicode 
     
    4783    User::WaitForRequest(reqStatus); 
    4884     
    49     if (reqStatus != KErrNone) 
    50         return PJ_RETURN_OS_ERROR(reqStatus.Int()); 
     85    // Iterate each result 
     86    i = 0; 
     87    while (reqStatus == KErrNone && i < *count) { 
     88         
     89        // Get the resolved TInetAddr 
     90        TInetAddr inetAddr(nameEntry().iAddr); 
     91        int addrlen; 
    5192 
    52     // Get the resolved TInetAddr 
    53     // This doesn't work, see Martin email on 28/3/2007: 
    54     // const TNameRecord &rec = (const TNameRecord&) nameEntry; 
    55     // TInetAddr inetAddr(rec.iAddr); 
    56     TInetAddr inetAddr(nameEntry().iAddr); 
     93        // Ignore if this is not the same address family 
     94        if (inetAddr.Family() != af) { 
     95            resv.Next(nameEntry, reqStatus); 
     96            User::WaitForRequest(reqStatus); 
     97            continue; 
     98        } 
     99         
     100        // Convert the official address to ANSI. 
     101        pj_unicode_to_ansi((const wchar_t*)nameEntry().iName.Ptr(),  
     102                           nameEntry().iName.Length(), 
     103                           ai[i].ai_canonname, sizeof(ai[i].ai_canonname)); 
    57104 
    58     // 
    59     // This where we keep static variables. 
    60     // These should be kept in TLS probably, to allow multiple threads 
    61     // to call pj_gethostbyname() without interfering each other. 
    62     // But again, we don't support threads in Symbian! 
    63     // 
    64     static char resolved_name[PJ_MAX_HOSTNAME]; 
    65     static char *no_aliases[1]; 
    66     static pj_in_addr *addr_list[2]; 
    67     static pj_sockaddr_in resolved_addr; 
     105        // Convert IP address 
     106        addrlen = sizeof(ai[i].ai_addr); 
     107        status = PjSymbianOS::Addr2pj(inetAddr, ai[i].ai_addr, &addrlen); 
     108        if (status != PJ_SUCCESS) 
     109            return status; 
     110         
     111        // Next 
     112        ++i; 
     113        resv.Next(nameEntry, reqStatus); 
     114        User::WaitForRequest(reqStatus); 
     115    } 
    68116 
    69     // Convert the official address to ANSI. 
    70     pj_unicode_to_ansi((const wchar_t*)nameEntry().iName.Ptr(), nameEntry().iName.Length(), 
    71                        resolved_name, sizeof(resolved_name)); 
    72  
    73     // Convert IP address 
    74      
    75     PjSymbianOS::Addr2pj(inetAddr, resolved_addr); 
    76     addr_list[0] = &resolved_addr.sin_addr; 
    77  
    78     // Return hostent 
    79     he->h_name = resolved_name; 
    80     he->h_aliases = no_aliases; 
    81     he->h_addrtype = pj_AF_INET(); 
    82     he->h_length = 4; 
    83     he->h_addr_list = (char**) addr_list; 
    84  
     117    *count = i; 
    85118    return PJ_SUCCESS; 
    86119} 
    87120 
    88  
    89 /* Get the default IP interface */ 
    90 PJ_DEF(pj_status_t) pj_getdefaultipinterface(pj_in_addr *addr) 
     121/* Resolve IPv4/IPv6 address */ 
     122PJ_DEF(pj_status_t) pj_getaddrinfo(int af, const pj_str_t *nodename, 
     123                                   unsigned *count, pj_addrinfo ai[])  
    91124{ 
    92     pj_sock_t fd; 
    93     pj_str_t cp; 
    94     pj_sockaddr_in a; 
    95     int len; 
     125    unsigned start; 
    96126    pj_status_t status; 
    97  
    98     status = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &fd); 
    99     if (status != PJ_SUCCESS) { 
    100         return status; 
     127     
     128    PJ_ASSERT_RETURN(af==PJ_AF_INET || af==PJ_AF_INET6 || af==PJ_AF_UNSPEC, 
     129                     PJ_EAFNOTSUP); 
     130    PJ_ASSERT_RETURN(nodename && count && *count && ai, PJ_EINVAL); 
     131     
     132    start = 0; 
     133     
     134    if (af==PJ_AF_INET6 || af==PJ_AF_UNSPEC) { 
     135        unsigned max = *count; 
     136        status = getaddrinfo_by_af(PJ_AF_INET6, nodename,  
     137                                   &max, &ai[start]); 
     138        if (status == PJ_SUCCESS) { 
     139            (*count) -= max; 
     140            start += max; 
     141        } 
    101142    } 
    102  
    103     cp = pj_str("1.1.1.1"); 
    104     pj_sockaddr_in_init(&a, &cp, 53); 
    105  
    106     status = pj_sock_connect(fd, &a, sizeof(a)); 
    107     if (status != PJ_SUCCESS) { 
    108         pj_sock_close(fd); 
    109         return status; 
     143     
     144    if (af==PJ_AF_INET || af==PJ_AF_UNSPEC) { 
     145        unsigned max = *count; 
     146        status = getaddrinfo_by_af(PJ_AF_INET, nodename,  
     147                                   &max, &ai[start]); 
     148        if (status == PJ_SUCCESS) { 
     149            (*count) -= max; 
     150            start += max; 
     151        } 
    110152    } 
    111  
    112     len = sizeof(a); 
    113     status = pj_sock_getsockname(fd, &a, &len); 
    114     if (status != PJ_SUCCESS) { 
    115         pj_sock_close(fd); 
    116         return status; 
     153     
     154    *count = start; 
     155     
     156    if (*count) { 
     157        return PJ_SUCCESS; 
     158    } else { 
     159        return status!=PJ_SUCCESS ? status : PJ_ENOTFOUND; 
    117160    } 
    118  
    119     pj_sock_close(fd); 
    120  
    121     *addr = a.sin_addr; 
    122  
    123     /* Success */ 
    124     return PJ_SUCCESS; 
    125161} 
    126162 
    127  
    128 /* Resolve the IP address of local machine */ 
    129 PJ_DEF(pj_status_t) pj_gethostip(pj_in_addr *addr) 
    130 { 
    131     const pj_str_t *hostname = pj_gethostname(); 
    132     struct pj_hostent he; 
    133     pj_status_t status; 
    134  
    135  
    136     /* Try with resolving local hostname first */ 
    137     status = pj_gethostbyname(hostname, &he); 
    138     if (status == PJ_SUCCESS) { 
    139         *addr = *(pj_in_addr*)he.h_addr; 
    140     } 
    141  
    142  
    143     /* If we end up with 127.x.x.x, resolve the IP by getting the default 
    144      * interface to connect to some public host. 
    145      */ 
    146     if (status != PJ_SUCCESS || (pj_ntohl(addr->s_addr) >> 24)==127 || 
    147         addr->s_addr == 0)  
    148     { 
    149         status = pj_getdefaultipinterface(addr); 
    150     } 
    151  
    152     /* As the last resort, get the first available interface */ 
    153     if (status != PJ_SUCCESS) { 
    154         pj_in_addr addrs[2]; 
    155         unsigned count = PJ_ARRAY_SIZE(addrs); 
    156  
    157         status = pj_enum_ip_interface(&count, addrs); 
    158         if (status == PJ_SUCCESS) { 
    159             if (count != 0) { 
    160                 *addr = addrs[0]; 
    161             } else { 
    162                 /* Just return 127.0.0.1 */ 
    163                 addr->s_addr = pj_htonl(0x7f000001); 
    164             } 
    165         } 
    166     } 
    167  
    168     return status; 
    169 } 
    170  
    171  
  • pjproject/trunk/pjlib/src/pj/errno.c

    r1585 r1601  
    7272    PJ_BUILD_ERR(PJ_ETOOSMALL,     "Size is too short"), 
    7373    PJ_BUILD_ERR(PJ_EIGNORED,      "Ignored"), 
    74     PJ_BUILD_ERR(PJ_EIPV6NOTSUP,   "IPv6 is not supported") 
     74    PJ_BUILD_ERR(PJ_EIPV6NOTSUP,   "IPv6 is not supported"), 
     75    PJ_BUILD_ERR(PJ_EAFNOTSUP,     "Unsupported address family") 
    7576}; 
    7677#endif  /* PJ_HAS_ERROR_STRING */ 
  • pjproject/trunk/pjlib/src/pj/ioqueue_symbian.cpp

    r1384 r1601  
    233233    PJ_ASSERT_RETURN(pending_data_.common_.op_key_==NULL, PJ_EBUSY); 
    234234 
     235    // addrlen must be specified if local or remote is specified 
     236    PJ_ASSERT_RETURN((!local && !remote) || 
     237                     (addrlen && *addrlen), PJ_EINVAL); 
     238     
    235239    pending_data_.accept_.op_key_ = op_key; 
    236240    pending_data_.accept_.new_sock_ = new_sock; 
     
    255259void CIoqueueCallback::HandleReadCompletion()  
    256260{ 
    257     if (pending_data_.read_.addr_) { 
     261    if (pending_data_.read_.addr_ && pending_data_.read_.addrlen_) { 
    258262        PjSymbianOS::Addr2pj(aAddress_,  
    259                              *(pj_sockaddr_in*)pending_data_.read_.addr_); 
     263                             *(pj_sockaddr*)pending_data_.read_.addr_, 
     264                             pending_data_.read_.addrlen_); 
    260265        pending_data_.read_.addr_ = NULL; 
    261     } 
    262     if (pending_data_.read_.addrlen_) { 
    263         *pending_data_.read_.addrlen_ = sizeof(pj_sockaddr_in); 
    264266        pending_data_.read_.addrlen_ = NULL; 
    265267    } 
     
    274276CPjSocket *CIoqueueCallback::HandleAcceptCompletion()  
    275277{ 
    276         CPjSocket *pjNewSock = new CPjSocket(blank_sock_); 
    277  
     278        CPjSocket *pjNewSock = new CPjSocket(get_pj_socket()->GetAf(),  
     279                                             blank_sock_); 
     280        int addrlen = 0; 
     281         
    278282        if (pending_data_.accept_.new_sock_) { 
    279283            *pending_data_.accept_.new_sock_ = (pj_sock_t)pjNewSock; 
     
    283287        if (pending_data_.accept_.local_) { 
    284288            TInetAddr aAddr; 
    285             pj_sockaddr_in *ptr_sockaddr; 
    286  
     289            pj_sockaddr *ptr_sockaddr; 
     290             
    287291            blank_sock_.LocalName(aAddr); 
    288             ptr_sockaddr = (pj_sockaddr_in*)pending_data_.accept_.local_; 
    289             PjSymbianOS::Addr2pj(aAddr, *ptr_sockaddr); 
     292            ptr_sockaddr = (pj_sockaddr*)pending_data_.accept_.local_; 
     293            addrlen = *pending_data_.accept_.addrlen_; 
     294            PjSymbianOS::Addr2pj(aAddr, *ptr_sockaddr, &addrlen); 
    290295            pending_data_.accept_.local_ = NULL; 
    291296        } 
     
    293298        if (pending_data_.accept_.remote_) { 
    294299            TInetAddr aAddr; 
    295             pj_sockaddr_in *ptr_sockaddr; 
     300            pj_sockaddr *ptr_sockaddr; 
    296301 
    297302            blank_sock_.RemoteName(aAddr); 
    298             ptr_sockaddr = (pj_sockaddr_in*)pending_data_.accept_.remote_; 
    299             PjSymbianOS::Addr2pj(aAddr, *ptr_sockaddr); 
     303            ptr_sockaddr = (pj_sockaddr*)pending_data_.accept_.remote_; 
     304            addrlen = *pending_data_.accept_.addrlen_; 
     305            PjSymbianOS::Addr2pj(aAddr, *ptr_sockaddr, &addrlen); 
    300306            pending_data_.accept_.remote_ = NULL; 
    301307        } 
    302308 
    303309        if (pending_data_.accept_.addrlen_) { 
    304             *pending_data_.accept_.addrlen_ = sizeof(pj_sockaddr_in); 
     310            if (addrlen == 0) { 
     311                if (pjNewSock->GetAf() == PJ_AF_INET) 
     312                    addrlen = sizeof(pj_sockaddr_in); 
     313                else if (pjNewSock->GetAf() == PJ_AF_INET6) 
     314                    addrlen = sizeof(pj_sockaddr_in6); 
     315                else { 
     316                    pj_assert(!"Unsupported address family"); 
     317                } 
     318            } 
     319            *pending_data_.accept_.addrlen_ = addrlen; 
    305320            pending_data_.accept_.addrlen_ = NULL; 
    306321        } 
     
    606621                                        int addrlen ) 
    607622{ 
    608     PJ_ASSERT_RETURN(addrlen == sizeof(pj_sockaddr_in), PJ_EINVAL); 
    609  
     623    pj_status_t status; 
     624     
    610625    RSocket &rSock = key->cbObj->get_pj_socket()->Socket(); 
    611626    TInetAddr inetAddr; 
    612     PjSymbianOS::pj2Addr(*(const pj_sockaddr_in*)addr, inetAddr); 
    613627    TRequestStatus reqStatus; 
    614628 
     629    // Convert address 
     630    status = PjSymbianOS::pj2Addr(*(const pj_sockaddr*)addr, addrlen,  
     631                                  inetAddr); 
     632    if (status != PJ_SUCCESS) 
     633        return status; 
     634     
    615635    // We don't support async connect for now. 
    616636    PJ_TODO(IOQUEUE_SUPPORT_ASYNC_CONNECT); 
     
    675695                                         int *addrlen) 
    676696{ 
     697    CPjSocket *sock = key->cbObj->get_pj_socket(); 
     698     
     699    // If address is specified, check that the length match the 
     700    // address family 
     701    if (addr || addrlen) { 
     702        PJ_ASSERT_RETURN(addr && addrlen && *addrlen, PJ_EINVAL); 
     703        if (sock->GetAf() == PJ_AF_INET) { 
     704            PJ_ASSERT_RETURN(*addrlen >= sizeof(pj_sockaddr_in), PJ_EINVAL); 
     705        } else if (sock->GetAf() == PJ_AF_INET6) { 
     706            PJ_ASSERT_RETURN(*addrlen >= sizeof(pj_sockaddr_in6), PJ_EINVAL); 
     707        } 
     708    } 
     709     
    677710    // If socket has reader, delete it. 
    678     if (key->cbObj->get_pj_socket()->Reader()) 
    679         key->cbObj->get_pj_socket()->DestroyReader(); 
     711    if (sock->Reader()) 
     712        sock->DestroyReader(); 
    680713     
    681714    if (key->cbObj->IsActive()) 
     
    737770    TInetAddr inetAddr; 
    738771    TSockXfrLength aLen; 
     772    pj_status_t status; 
    739773     
    740774    PJ_UNUSED_ARG(op_key); 
     
    743777    PJ_ASSERT_RETURN((flags & PJ_IOQUEUE_ALWAYS_ASYNC)==0, PJ_EINVAL); 
    744778 
    745     // Must be pj_sockaddr_in for now. 
    746     PJ_ASSERT_RETURN(addrlen == sizeof(pj_sockaddr_in), PJ_EINVAL); 
    747  
     779    // Convert address 
     780    status = PjSymbianOS::pj2Addr(*(const pj_sockaddr*)addr, addrlen,  
     781                                  inetAddr); 
     782    if (status != PJ_SUCCESS) 
     783        return status; 
     784     
    748785    // Clear flag 
    749786    flags &= ~PJ_IOQUEUE_ALWAYS_ASYNC; 
    750787 
    751788    aBuffer.Set((const TUint8*)data, (TInt)*length); 
    752     PjSymbianOS::pj2Addr(*(const pj_sockaddr_in*)addr, inetAddr); 
    753789    CPjSocket *pjSock = key->cbObj->get_pj_socket(); 
    754790 
  • pjproject/trunk/pjlib/src/pj/ip_helper_generic.c

    r1599 r1601  
    2424#include <pj/compat/socket.h> 
    2525 
    26 static pj_status_t dummy_enum_ip_interface(unsigned *p_cnt, 
    27                                           pj_in_addr ifs[]) 
     26static pj_status_t dummy_enum_ip_interface(int af, 
     27                                           unsigned *p_cnt, 
     28                                           pj_sockaddr ifs[]) 
    2829{ 
    2930    pj_status_t status; 
     
    3435 
    3536    /* Just get one default route */ 
    36     status = pj_getdefaultipinterface(&ifs[0]); 
     37    status = pj_getdefaultipinterface(af, &ifs[0]); 
    3738    if (status != PJ_SUCCESS) 
    3839        return status; 
     
    4344 
    4445#ifdef SIOCGIFCONF 
    45 static pj_status_t sock_enum_ip_interface(unsigned *p_cnt, 
    46                                           pj_in_addr ifs[]) 
     46static pj_status_t sock_enum_ip_interface(int af, 
     47                                          unsigned *p_cnt, 
     48                                          pj_sockaddr ifs[]) 
    4749{ 
    4850    pj_sock_t sock; 
     
    5355    pj_status_t status; 
    5456 
    55     status = pj_sock_socket(PJ_AF_INET, PJ_SOCK_DGRAM, 0, &sock); 
     57    PJ_ASSERT_RETURN(af==PJ_AF_INET || af==PJ_AF_INET6, PJ_EINVAL); 
     58     
     59    status = pj_sock_socket(af, PJ_SOCK_DGRAM, 0, &sock); 
    5660    if (status != PJ_SUCCESS) 
    5761        return status; 
     
    7983    for (i=0; i<count; ++i) { 
    8084        struct ifreq *itf = &ifr[i]; 
    81         ifs[i].s_addr = ((struct sockaddr_in *)&itf->ifr_addr)->sin_addr.s_addr; 
     85        struct sockaddr *ad = itf->ifr_addr; 
     86         
     87        ifs[i].addr.sa_family = ad->sa_family; 
     88        pj_memcpy(pj_sockaddr_get_addr(&ifs[i]), 
     89                  pj_sockaddr_get_addr(ad), 
     90                  pj_sockaddr_get_addr_len(ad)); 
    8291    } 
    8392 
     
    8998 * Enumerate the local IP interface currently active in the host. 
    9099 */ 
    91 PJ_DEF(pj_status_t) pj_enum_ip_interface(unsigned *p_cnt, 
    92                                          pj_in_addr ifs[]) 
     100PJ_DEF(pj_status_t) pj_enum_ip_interface(int af, 
     101                                         unsigned *p_cnt, 
     102                                         pj_sockaddr ifs[]) 
    93103{ 
    94104#ifdef SIOCGIFCONF 
    95     if (sock_enum_ip_interface(p_cnt, ifs) == PJ_SUCCESS) 
     105    if (sock_enum_ip_interface(af, p_cnt, ifs) == PJ_SUCCESS) 
    96106        return PJ_SUCCESS; 
    97107#endif 
    98     return dummy_enum_ip_interface(p_cnt, ifs); 
     108    return dummy_enum_ip_interface(af, p_cnt, ifs); 
    99109} 
    100110 
     
    105115                                     pj_ip_route_entry routes[]) 
    106116{ 
     117    pj_sockaddr itf; 
    107118    pj_status_t status; 
    108119 
     
    112123 
    113124    /* Just get one default route */ 
    114     status = pj_getdefaultipinterface(&routes[0].ipv4.if_addr); 
     125    status = pj_getdefaultipinterface(PJ_AF_INET, &itf); 
    115126    if (status != PJ_SUCCESS) 
    116127        return status; 
    117  
     128     
     129    routes[0].ipv4.if_addr.s_addr = itf.ipv4.sin_addr.s_addr; 
    118130    routes[0].ipv4.dst_addr.s_addr = 0; 
    119131    routes[0].ipv4.mask.s_addr = 0; 
  • pjproject/trunk/pjlib/src/pj/ip_helper_win32.c

    r1450 r1601  
    2828#   define PMIB_ICMP_EX void* 
    2929#endif 
     30#include <winsock2.h> 
     31 
     32/* If you encounter error "Cannot open include file: 'Iphlpapi.h' here, 
     33 * you need to install newer Platform SDK. Presumably you're using 
     34 * Microsoft Visual Studio 6? 
     35 */ 
    3036#include <Iphlpapi.h> 
    3137 
     
    4248                                           PULONG pdwSize,  
    4349                                           BOOL bOrder); 
     50#if defined(PJ_HAS_IPV6) && PJ_HAS_IPV6!=0 
     51typedef DWORD (WINAPI *PFN_GetAdapterAddresses)(ULONG Family, 
     52                                                ULONG Flags, 
     53                                                PVOID Reserved, 
     54                                                PIP_ADAPTER_ADDRESSES AdapterAddresses, 
     55                                                PULONG SizePointer); 
     56#endif  /* PJ_HAS_IPV6 */ 
    4457typedef DWORD (WINAPI *PFN_GetIpForwardTable)(PMIB_IPFORWARDTABLE pIpForwardTable, 
    4558                                              PULONG pdwSize,  
     
    4962static HANDLE s_hDLL; 
    5063static PFN_GetIpAddrTable s_pfnGetIpAddrTable; 
     64#if defined(PJ_HAS_IPV6) && PJ_HAS_IPV6!=0 
     65    static PFN_GetAdapterAddresses s_pfnGetAdapterAddresses; 
     66#endif  /* PJ_HAS_IPV6 */ 
    5167static PFN_GetIpForwardTable s_pfnGetIpForwardTable; 
    5268static PFN_GetIfEntry s_pfnGetIfEntry; 
     69 
    5370 
    5471static void unload_iphlp_module(void) 
     
    5875    s_pfnGetIpAddrTable = NULL; 
    5976    s_pfnGetIpForwardTable = NULL; 
     77    s_pfnGetIfEntry = NULL; 
     78#if defined(PJ_HAS_IPV6) && PJ_HAS_IPV6!=0 
     79    s_pfnGetAdapterAddresses = NULL; 
     80#endif 
    6081} 
    6182 
     
    91112} 
    92113 
     114#if defined(PJ_HAS_IPV6) && PJ_HAS_IPV6!=0 
     115static DWORD MyGetAdapterAddresses(ULONG Family, 
     116                                   ULONG Flags, 
     117                                   PVOID Reserved, 
     118                                   PIP_ADAPTER_ADDRESSES AdapterAddresses, 
     119                                   PULONG SizePointer) 
     120{ 
     121    if(NULL == s_pfnGetAdapterAddresses) { 
     122        s_pfnGetAdapterAddresses = (PFN_GetAdapterAddresses)  
     123            GetIpHlpApiProc(PJ_T("GetAdapterAddresses")); 
     124    } 
     125     
     126    if(NULL != s_pfnGetAdapterAddresses) { 
     127        return s_pfnGetAdapterAddresses(Family, Flags, Reserved, 
     128                                        AdapterAddresses, SizePointer); 
     129    } 
     130     
     131    return ERROR_NOT_SUPPORTED; 
     132} 
     133#endif  /* PJ_HAS_IPV6 */ 
    93134 
    94135#if PJ_IP_HELPER_IGNORE_LOOPBACK_IF 
     
    125166} 
    126167 
    127 /* 
    128  * Enumerate the local IP interface currently active in the host. 
    129  */ 
    130 PJ_DEF(pj_status_t) pj_enum_ip_interface(unsigned *p_cnt, 
    131                                          pj_in_addr ifs[]) 
     168/* Enumerate local IP interface using GetIpAddrTable() 
     169 * for IPv4 addresses only. 
     170 */ 
     171static pj_status_t enum_ipv4_interface(unsigned *p_cnt, 
     172                                       pj_sockaddr ifs[]) 
    132173{ 
    133174    /* Provide enough buffer or otherwise it will fail with  
     
    160201        MIB_IFROW ifRow; 
    161202 
    162         /* Some Windows returns 0.0.0.0! */ 
     203        /* Ignore 0.0.0.0 address (interface is down?) */ 
    163204        if (pTab->table[i].dwAddr == 0) 
    164205            continue; 
     
    175216#endif 
    176217 
    177         ifs[*p_cnt].s_addr = pTab->table[i].dwAddr; 
     218        ifs[*p_cnt].ipv4.sin_family = PJ_AF_INET; 
     219        ifs[*p_cnt].ipv4.sin_addr.s_addr = pTab->table[i].dwAddr; 
    178220        (*p_cnt)++; 
    179221    } 
    180222 
    181223    return PJ_SUCCESS; 
    182  
    183 } 
    184  
     224} 
     225 
     226 
     227/* Enumerate local IP interface using GetAdapterAddresses(), 
     228 * which works for both IPv4 and IPv6. 
     229 */ 
     230#if defined(PJ_HAS_IPV6) && PJ_HAS_IPV6!=0 
     231static pj_status_t enum_ipv4_ipv6_interface(int af, 
     232                                            unsigned *p_cnt, 
     233                                            pj_sockaddr ifs[]) 
     234{ 
     235    pj_uint8_t buffer[1024]; 
     236    IP_ADAPTER_ADDRESSES *adapter = (IP_ADAPTER_ADDRESSES*)buffer; 
     237    ULONG size = sizeof(buffer); 
     238    unsigned i; 
     239    DWORD rc; 
     240 
     241    rc = MyGetAdapterAddresses(af, 0, NULL, adapter, &size); 
     242    if (rc != ERROR_SUCCESS) 
     243        return PJ_RETURN_OS_ERROR(rc); 
     244 
     245    for (i=0; i<*p_cnt && adapter; ++i, adapter = adapter->Next) { 
     246        SOCKET_ADDRESS *pAddr = &adapter->FirstUnicastAddress->Address; 
     247        ifs[i].addr.sa_family = pAddr->lpSockaddr->sa_family; 
     248        pj_memcpy(&ifs[i], pAddr->lpSockaddr, pAddr->iSockaddrLength); 
     249    } 
     250 
     251    return PJ_SUCCESS; 
     252} 
     253#endif 
     254 
     255 
     256/* 
     257 * Enumerate the local IP interface currently active in the host. 
     258 */ 
     259PJ_DEF(pj_status_t) pj_enum_ip_interface(int af, 
     260                                         unsigned *p_cnt, 
     261                                         pj_sockaddr ifs[]) 
     262{ 
     263    pj_status_t status = -1; 
     264 
     265    PJ_ASSERT_RETURN(p_cnt && ifs, PJ_EINVAL); 
     266    PJ_ASSERT_RETURN(af==PJ_AF_UNSPEC || af==PJ_AF_INET || af==PJ_AF_INET6, 
     267                     PJ_EAFNOTSUP); 
     268 
     269#if defined(PJ_HAS_IPV6) && PJ_HAS_IPV6!=0 
     270    status = enum_ipv4_ipv6_interface(af, p_cnt, ifs); 
     271    if (status != PJ_SUCCESS && (af==PJ_AF_INET || af==PJ_AF_UNSPEC)) 
     272        status = enum_ipv4_interface(p_cnt, ifs); 
     273    return status; 
     274#else 
     275    if (af==PJ_AF_INET6) 
     276        return PJ_EIPV6NOTSUP; 
     277    else if (af != PJ_AF_INET && af != PJ_AF_UNSPEC) 
     278        return PJ_EAFNOTSUP; 
     279 
     280    status = enum_ipv4_interface(p_cnt, ifs); 
     281    return status; 
     282#endif 
     283} 
    185284 
    186285/* 
  • pjproject/trunk/pjlib/src/pj/os_core_symbian.cpp

    r1589 r1601  
    155155: isSocketServInitialized_(false), isResolverInitialized_(false), 
    156156  console_(NULL), selectTimeoutTimer_(NULL), 
    157   appSocketServ_(NULL), appConnection_(NULL), appHostResolver_(NULL) 
     157  appSocketServ_(NULL), appConnection_(NULL), appHostResolver_(NULL), 
     158  appHostResolver6_(NULL) 
    158159{ 
    159160} 
     
    165166    appConnection_ = (RConnection*) params->rconnection; 
    166167    appHostResolver_ = (RHostResolver*) params->rhostresolver; 
     168    appHostResolver6_ = (RHostResolver*) params->rhostresolver6; 
    167169} 
    168170 
     
    200202    } 
    201203 
    202     if (!isResolverInitialized_ && appHostResolver_ == NULL) { 
    203         if (Connection()) 
    204             err = hostResolver_.Open(SocketServ(), KAfInet, KSockStream, 
    205                                      *Connection()); 
    206         else 
    207             err = hostResolver_.Open(SocketServ(), KAfInet, KSockStream); 
     204    if (!isResolverInitialized_) { 
     205        if (appHostResolver_ == NULL) { 
     206            if (Connection()) 
     207                err = hostResolver_.Open(SocketServ(), KAfInet, KSockStream, 
     208                                         *Connection()); 
     209            else 
     210                err = hostResolver_.Open(SocketServ(), KAfInet, KSockStream); 
    208211         
    209         if (err != KErrNone) 
    210             goto on_error; 
    211  
     212            if (err != KErrNone) 
     213                goto on_error; 
     214        } 
     215         
     216        if (appHostResolver6_ == NULL) { 
     217            if (Connection()) 
     218                err = hostResolver6_.Open(SocketServ(), KAfInet6, KSockStream, 
     219                                          *Connection()); 
     220            else 
     221                err = hostResolver6_.Open(SocketServ(), KAfInet6, KSockStream); 
     222         
     223            if (err != KErrNone) 
     224                goto on_error; 
     225        } 
     226         
    212227        isResolverInitialized_ = true; 
    213228    } 
     
    225240    if (isResolverInitialized_) { 
    226241        hostResolver_.Close(); 
     242        hostResolver6_.Close(); 
    227243        isResolverInitialized_ = false; 
    228244    } 
  • pjproject/trunk/pjlib/src/pj/os_symbian.h

    r1525 r1601  
    2020#define __OS_SYMBIAN_H__ 
    2121 
     22#include <pj/assert.h> 
     23#include <pj/errno.h> 
    2224#include <pj/sock.h> 
    2325#include <pj/os.h> 
     
    5254 
    5355    // Construct CPjSocket 
    54     CPjSocket(RSocket &sock) 
    55         : sock_(sock), connected_(false), sockReader_(NULL) 
     56    CPjSocket(int af, RSocket &sock) 
     57        : af_(af), sock_(sock), connected_(false), sockReader_(NULL) 
    5658    {  
    5759    } 
     
    6062    ~CPjSocket(); 
    6163 
     64    // Get address family 
     65    int GetAf() const  
     66    { 
     67        return af_;      
     68    } 
     69     
    6270    // Get the internal RSocket 
    6371    RSocket& Socket() 
     
    92100     
    93101private: 
     102    int              af_; 
    94103    RSocket          sock_;         // Must not be reference, or otherwise 
    95104                                    // it may point to local variable! 
     
    229238     
    230239    // Convert TInetAddr to pj_sockaddr_in 
    231     static inline void Addr2pj(const TInetAddr & sym_addr, 
    232                                pj_sockaddr_in &pj_addr) 
    233     { 
    234         pj_bzero(&pj_addr, sizeof(pj_sockaddr_in)); 
    235         pj_addr.sin_family = pj_AF_INET(); 
    236         pj_addr.sin_addr.s_addr = pj_htonl(sym_addr.Address()); 
    237         pj_addr.sin_port = pj_htons((pj_uint16_t) sym_addr.Port()); 
     240    static inline pj_status_t Addr2pj(const TInetAddr & sym_addr, 
     241                                      pj_sockaddr &pj_addr, 
     242                                      int *addr_len) 
     243    { 
     244        pj_bzero(&pj_addr, sizeof(pj_sockaddr)); 
     245        pj_addr.addr.sa_family = (pj_uint16_t)sym_addr.Family(); 
     246        if (pj_addr.addr.sa_family == PJ_AF_INET) { 
     247            PJ_ASSERT_RETURN(*addr_len >= sizeof(pj_sockaddr_in), PJ_ETOOSMALL); 
     248            pj_addr.ipv4.sin_addr.s_addr = pj_htonl(sym_addr.Address()); 
     249            pj_addr.ipv4.sin_port = pj_htons((pj_uint16_t) sym_addr.Port()); 
     250            *addr_len = sizeof(pj_sockaddr_in); 
     251        } else if (pj_addr.addr.sa_family == PJ_AF_INET6) { 
     252            PJ_ASSERT_RETURN(*addr_len >= sizeof(pj_sockaddr_in6), PJ_ETOOSMALL); 
     253            const TIp6Addr & ip6 = sym_addr.Ip6Address(); 
     254            pj_memcpy(&pj_addr.ipv6.sin6_addr, ip6.u.iAddr8, 16); 
     255            pj_addr.ipv6.sin6_port = pj_htons((pj_uint16_t) sym_addr.Port()); 
     256            pj_addr.ipv6.sin6_scope_id = pj_htonl(sym_addr.Scope()); 
     257            pj_addr.ipv6.sin6_flowinfo = pj_htonl(sym_addr.FlowLabel()); 
     258            *addr_len = sizeof(pj_sockaddr_in6); 
     259        } else { 
     260            pj_assert(!"Unsupported address family"); 
     261            return PJ_EAFNOTSUP; 
     262        } 
     263         
     264        return PJ_SUCCESS; 
    238265    } 
    239266 
    240267 
    241268    // Convert pj_sockaddr_in to TInetAddr 
    242     static inline void pj2Addr(const pj_sockaddr_in &pj_addr, 
    243                                TInetAddr & sym_addr) 
    244     { 
    245         sym_addr.Init(KAfInet); 
    246         sym_addr.SetAddress((TUint32)pj_ntohl(pj_addr.sin_addr.s_addr)); 
    247         sym_addr.SetPort(pj_ntohs(pj_addr.sin_port)); 
     269    static inline pj_status_t pj2Addr(const pj_sockaddr &pj_addr, 
     270                                      int addrlen, 
     271                                      TInetAddr & sym_addr) 
     272    { 
     273        if (pj_addr.addr.sa_family == PJ_AF_INET) { 
     274            PJ_ASSERT_RETURN(addrlen >= sizeof(pj_sockaddr_in), PJ_EINVAL); 
     275            sym_addr.Init(KAfInet); 
     276            sym_addr.SetAddress((TUint32)pj_ntohl(pj_addr.ipv4.sin_addr.s_addr)); 
     277            sym_addr.SetPort(pj_ntohs(pj_addr.ipv4.sin_port)); 
     278        } else if (pj_addr.addr.sa_family == PJ_AF_INET6) { 
     279            TIp6Addr ip6; 
     280         
     281            PJ_ASSERT_RETURN(addrlen >= sizeof(pj_sockaddr_in6), PJ_EINVAL); 
     282            pj_memcpy(ip6.u.iAddr8, &pj_addr.ipv6.sin6_addr, 16); 
     283            sym_addr.Init(KAfInet6); 
     284            sym_addr.SetAddress(ip6); 
     285            sym_addr.SetScope(pj_ntohl(pj_addr.ipv6.sin6_scope_id)); 
     286            sym_addr.SetFlowLabel(pj_ntohl(pj_addr.ipv6.sin6_flowinfo)); 
     287        } else { 
     288            pj_assert(!"Unsupported address family"); 
     289        } 
     290        return PJ_SUCCESS; 
    248291    } 
    249292 
     
    254297 
    255298    // Get RHostResolver instance 
    256     RHostResolver & GetResolver() 
    257     { 
    258         return appHostResolver_ ? *appHostResolver_ : hostResolver_; 
     299    RHostResolver & GetResolver(int af) 
     300    { 
     301        if (af==PJ_AF_INET6) { 
     302            return appHostResolver6_ ? *appHostResolver6_ : hostResolver6_; 
     303        } else { 
     304            return appHostResolver_ ? *appHostResolver_ : hostResolver_; 
     305        } 
    259306    } 
    260307 
     
    304351    bool isResolverInitialized_; 
    305352    RHostResolver hostResolver_; 
     353    RHostResolver hostResolver6_; 
    306354 
    307355    CConsoleBase* console_; 
     
    313361    RConnection *appConnection_; 
    314362    RHostResolver *appHostResolver_; 
     363    RHostResolver *appHostResolver6_; 
    315364     
    316365private: 
  • pjproject/trunk/pjlib/src/pj/sock_bsd.c

    r1587 r1601  
    124124 
    125125 
    126 #if defined(PJ_SOCKADDR_HAS_LEN) && PJ_SOCKADDR_HAS_LEN!=0 
    127 #   define SET_LEN(addr,len) (((pj_sockaddr_in*)(addr))->sin_zero_len=(len)) 
    128 #   define RESET_LEN(addr)   (((pj_sockaddr_in*)(addr))->sin_zero_len=0) 
    129 #else 
    130 #   define SET_LEN(addr,len)  
    131 #   define RESET_LEN(addr) 
    132 #endif 
    133  
    134  
    135126/* 
    136127 * Convert 16-bit value from network byte order to host byte order. 
     
    222213    char tempaddr[PJ_INET6_ADDRSTRLEN]; 
    223214 
    224     PJ_ASSERT_RETURN(af==PJ_AF_INET || af==PJ_AF_INET6, PJ_EINVAL); 
     215    PJ_ASSERT_RETURN(af==PJ_AF_INET || af==PJ_AF_INET6, PJ_EAFNOTSUP); 
    225216    PJ_ASSERT_RETURN(src && src->slen && dst, PJ_EINVAL); 
    226217 
     
    311302    *dst = '\0'; 
    312303 
    313     PJ_ASSERT_RETURN(af==PJ_AF_INET || af==PJ_AF_INET6, PJ_EINVAL); 
     304    PJ_ASSERT_RETURN(af==PJ_AF_INET || af==PJ_AF_INET6, PJ_EAFNOTSUP); 
    314305 
    315306#if defined(PJ_SOCK_HAS_INET_NTOP) && PJ_SOCK_HAS_INET_NTOP != 0 
     
    354345        } else { 
    355346            pj_assert(!"Unsupported address family"); 
    356             return PJ_EINVAL; 
     347            return PJ_EAFNOTSUP; 
    357348        } 
    358349 
     
    387378#endif 
    388379} 
    389  
    390 /* 
    391  * Convert address string with numbers and dots to binary IP address. 
    392  */  
    393 PJ_DEF(pj_in_addr) pj_inet_addr(const pj_str_t *cp) 
    394 { 
    395     pj_in_addr addr; 
    396  
    397     pj_inet_aton(cp, &addr); 
    398     return addr; 
    399 } 
    400  
    401 /* 
    402  * Convert address string with numbers and dots to binary IP address. 
    403  */  
    404 PJ_DEF(pj_in_addr) pj_inet_addr2(const char *cp) 
    405 { 
    406     pj_str_t str = pj_str((char*)cp); 
    407     return pj_inet_addr(&str); 
    408 } 
    409  
    410 /* 
    411  * Set the IP address of an IP socket address from string address,  
    412  * with resolving the host if necessary. The string address may be in a 
    413  * standard numbers and dots notation or may be a hostname. If hostname 
    414  * is specified, then the function will resolve the host into the IP 
    415  * address. 
    416  */ 
    417 PJ_DEF(pj_status_t) pj_sockaddr_in_set_str_addr( pj_sockaddr_in *addr, 
    418                                                  const pj_str_t *str_addr) 
    419 { 
    420     PJ_CHECK_STACK(); 
    421  
    422     PJ_ASSERT_RETURN(!str_addr || str_addr->slen < PJ_MAX_HOSTNAME,  
    423                      (addr->sin_addr.s_addr=PJ_INADDR_NONE, PJ_EINVAL)); 
    424  
    425     RESET_LEN(addr); 
    426     addr->sin_family = AF_INET; 
    427     pj_bzero(addr->sin_zero, sizeof(addr->sin_zero)); 
    428  
    429     if (str_addr && str_addr->slen) { 
    430         addr->sin_addr = pj_inet_addr(str_addr); 
    431         if (addr->sin_addr.s_addr == PJ_INADDR_NONE) { 
    432             pj_hostent he; 
    433             pj_status_t rc; 
    434  
    435             rc = pj_gethostbyname(str_addr, &he); 
    436             if (rc == 0) { 
    437                 addr->sin_addr.s_addr = *(pj_uint32_t*)he.h_addr; 
    438             } else { 
    439                 addr->sin_addr.s_addr = PJ_INADDR_NONE; 
    440                 return rc; 
    441             } 
    442         } 
    443  
    444     } else { 
    445         addr->sin_addr.s_addr = 0; 
    446     } 
    447  
    448     return PJ_SUCCESS; 
    449 } 
    450  
    451 /* 
    452  * Set the IP address and port of an IP socket address. 
    453  * The string address may be in a standard numbers and dots notation or  
    454  * may be a hostname. If hostname is specified, then the function will  
    455  * resolve the host into the IP address. 
    456  */ 
    457 PJ_DEF(pj_status_t) pj_sockaddr_in_init( pj_sockaddr_in *addr, 
    458                                          const pj_str_t *str_addr, 
    459                                          pj_uint16_t port) 
    460 { 
    461     PJ_ASSERT_RETURN(addr, (addr->sin_addr.s_addr=PJ_INADDR_NONE, PJ_EINVAL)); 
    462  
    463     RESET_LEN(addr); 
    464     addr->sin_family = PJ_AF_INET; 
    465     pj_bzero(addr->sin_zero, sizeof(addr->sin_zero)); 
    466     pj_sockaddr_in_set_port(addr, port); 
    467     return pj_sockaddr_in_set_str_addr(addr, str_addr); 
    468 } 
    469  
    470380 
    471381/* 
     
    491401} 
    492402 
    493 /* 
    494  * Get first IP address associated with the hostname. 
    495  */ 
    496 PJ_DEF(pj_in_addr) pj_gethostaddr(void) 
    497 { 
    498     pj_sockaddr_in addr; 
    499     const pj_str_t *hostname = pj_gethostname(); 
    500  
    501     pj_sockaddr_in_set_str_addr(&addr, hostname); 
    502     return addr.sin_addr; 
    503 } 
    504  
    505  
    506403#if defined(PJ_WIN32) 
    507404/* 
     
    583480    PJ_CHECK_STACK(); 
    584481 
    585     SET_LEN(&addr, sizeof(pj_sockaddr_in)); 
     482    PJ_SOCKADDR_SET_LEN(&addr, sizeof(pj_sockaddr_in)); 
    586483    addr.sin_family = PJ_AF_INET; 
    587484    pj_bzero(addr.sin_zero, sizeof(addr.sin_zero)); 
     
    625522        return PJ_RETURN_OS_ERROR(pj_get_native_netos_error()); 
    626523    else { 
    627         RESET_LEN(addr); 
     524        PJ_SOCKADDR_RESET_LEN(addr); 
    628525        return PJ_SUCCESS; 
    629526    } 
     
    641538        return PJ_RETURN_OS_ERROR(pj_get_native_netos_error()); 
    642539    else { 
    643         RESET_LEN(addr); 
     540        PJ_SOCKADDR_RESET_LEN(addr); 
    644541        return PJ_SUCCESS; 
    645542    } 
     
    727624        return PJ_RETURN_OS_ERROR(pj_get_native_netos_error()); 
    728625    else { 
    729         RESET_LEN(from); 
     626        PJ_SOCKADDR_RESET_LEN(from); 
    730627        return PJ_SUCCESS; 
    731628    } 
     
    821718#if defined(PJ_SOCKADDR_HAS_LEN) && PJ_SOCKADDR_HAS_LEN!=0 
    822719    if (addr) { 
    823         SET_LEN(addr, *addrlen); 
     720        PJ_SOCKADDR_SET_LEN(addr, *addrlen); 
    824721    } 
    825722#endif 
     
    832729#if defined(PJ_SOCKADDR_HAS_LEN) && PJ_SOCKADDR_HAS_LEN!=0 
    833730        if (addr) { 
    834             RESET_LEN(addr); 
     731            PJ_SOCKADDR_RESET_LEN(addr); 
    835732        } 
    836733#endif 
  • pjproject/trunk/pjlib/src/pj/sock_common.c

    r1585 r1601  
    1818 */ 
    1919#include <pj/sock.h> 
     20#include <pj/assert.h> 
     21#include <pj/errno.h> 
     22#include <pj/ip_helper.h> 
     23#include <pj/os.h> 
     24#include <pj/addr_resolv.h> 
     25#include <pj/string.h> 
     26#include <pj/compat/socket.h> 
     27 
     28 
     29/* 
     30 * Convert address string with numbers and dots to binary IP address. 
     31 */  
     32PJ_DEF(pj_in_addr) pj_inet_addr(const pj_str_t *cp) 
     33{ 
     34    pj_in_addr addr; 
     35 
     36    pj_inet_aton(cp, &addr); 
     37    return addr; 
     38} 
     39 
     40/* 
     41 * Convert address string with numbers and dots to binary IP address. 
     42 */  
     43PJ_DEF(pj_in_addr) pj_inet_addr2(const char *cp) 
     44{ 
     45    pj_str_t str = pj_str((char*)cp); 
     46    return pj_inet_addr(&str); 
     47} 
     48 
     49/* 
     50 * Set the IP address of an IP socket address from string address,  
     51 * with resolving the host if necessary. The string address may be in a 
     52 * standard numbers and dots notation or may be a hostname. If hostname 
     53 * is specified, then the function will resolve the host into the IP 
     54 * address. 
     55 */ 
     56PJ_DEF(pj_status_t) pj_sockaddr_in_set_str_addr( pj_sockaddr_in *addr, 
     57                                                 const pj_str_t *str_addr) 
     58{ 
     59    PJ_CHECK_STACK(); 
     60 
     61    PJ_ASSERT_RETURN(!str_addr || str_addr->slen < PJ_MAX_HOSTNAME,  
     62                     (addr->sin_addr.s_addr=PJ_INADDR_NONE, PJ_EINVAL)); 
     63 
     64    PJ_SOCKADDR_RESET_LEN(addr); 
     65    addr->sin_family = AF_INET; 
     66    pj_bzero(addr->sin_zero, sizeof(addr->sin_zero)); 
     67 
     68    if (str_addr && str_addr->slen) { 
     69        addr->sin_addr = pj_inet_addr(str_addr); 
     70        if (addr->sin_addr.s_addr == PJ_INADDR_NONE) { 
     71            pj_hostent he; 
     72            pj_status_t rc; 
     73 
     74            rc = pj_gethostbyname(str_addr, &he); 
     75            if (rc == 0) { 
     76                addr->sin_addr.s_addr = *(pj_uint32_t*)he.h_addr; 
     77            } else { 
     78                addr->sin_addr.s_addr = PJ_INADDR_NONE; 
     79                return rc; 
     80            } 
     81        } 
     82 
     83    } else { 
     84        addr->sin_addr.s_addr = 0; 
     85    } 
     86 
     87    return PJ_SUCCESS; 
     88} 
     89 
     90/* Set address from a name */ 
     91PJ_DEF(pj_status_t) pj_sockaddr_set_str_addr(int af, 
     92                                             pj_sockaddr *addr, 
     93                                             const pj_str_t *str_addr) 
     94{ 
     95    pj_status_t status; 
     96 
     97    if (af == PJ_AF_INET) { 
     98        return pj_sockaddr_in_set_str_addr(&addr->ipv4, str_addr); 
     99    } 
     100 
     101    PJ_ASSERT_RETURN(af==PJ_AF_INET6, PJ_EAFNOTSUP); 
     102 
     103    /* IPv6 specific */ 
     104 
     105    addr->ipv6.sin6_family = PJ_AF_INET6; 
     106    PJ_SOCKADDR_RESET_LEN(addr); 
     107 
     108    if (str_addr && str_addr->slen) { 
     109        status = pj_inet_pton(PJ_AF_INET6, str_addr, &addr->ipv6.sin6_addr); 
     110        if (status != PJ_SUCCESS) { 
     111            pj_addrinfo ai; 
     112            unsigned count = 1; 
     113 
     114            status = pj_getaddrinfo(PJ_AF_INET6, str_addr, &count, &ai); 
     115            if (status==PJ_SUCCESS) { 
     116                pj_memcpy(&addr->ipv6.sin6_addr, &ai.ai_addr.ipv6.sin6_addr, 
     117                          sizeof(pj_sockaddr_in6)); 
     118            } 
     119        } 
     120    } else { 
     121        status = PJ_SUCCESS; 
     122    } 
     123 
     124    return status; 
     125} 
     126 
     127/* 
     128 * Set the IP address and port of an IP socket address. 
     129 * The string address may be in a standard numbers and dots notation or  
     130 * may be a hostname. If hostname is specified, then the function will  
     131 * resolve the host into the IP address. 
     132 */ 
     133PJ_DEF(pj_status_t) pj_sockaddr_in_init( pj_sockaddr_in *addr, 
     134                                         const pj_str_t *str_addr, 
     135                                         pj_uint16_t port) 
     136{ 
     137    PJ_ASSERT_RETURN(addr, (addr->sin_addr.s_addr=PJ_INADDR_NONE, PJ_EINVAL)); 
     138 
     139    PJ_SOCKADDR_RESET_LEN(addr); 
     140    addr->sin_family = PJ_AF_INET; 
     141    pj_bzero(addr->sin_zero, sizeof(addr->sin_zero)); 
     142    pj_sockaddr_in_set_port(addr, port); 
     143    return pj_sockaddr_in_set_str_addr(addr, str_addr); 
     144} 
     145 
     146/* 
     147 * Initialize IP socket address based on the address and port info. 
     148 */ 
     149PJ_DEF(pj_status_t) pj_sockaddr_init(int af,  
     150                                     pj_sockaddr *addr, 
     151                                     const pj_str_t *cp, 
     152                                     pj_uint16_t port) 
     153{ 
     154    pj_status_t status; 
     155 
     156    if (af == PJ_AF_INET) { 
     157        return pj_sockaddr_in_init(&addr->ipv4, cp, port); 
     158    } 
     159 
     160    /* IPv6 specific */ 
     161    PJ_ASSERT_RETURN(af==PJ_AF_INET6, PJ_EAFNOTSUP); 
     162 
     163    pj_bzero(addr, sizeof(pj_sockaddr_in6)); 
     164    addr->addr.sa_family = PJ_AF_INET6; 
     165     
     166    status = pj_sockaddr_set_str_addr(af, addr, cp); 
     167    if (status != PJ_SUCCESS) 
     168        return status; 
     169 
     170    addr->ipv6.sin6_port = pj_htons(port); 
     171    return PJ_SUCCESS; 
     172} 
     173 
     174/* 
     175 * Get first IP address associated with the hostname. 
     176 */ 
     177PJ_DEF(pj_in_addr) pj_gethostaddr(void) 
     178{ 
     179    pj_sockaddr_in addr; 
     180    const pj_str_t *hostname = pj_gethostname(); 
     181 
     182    pj_sockaddr_in_set_str_addr(&addr, hostname); 
     183    return addr.sin_addr; 
     184} 
     185 
     186/* 
     187 * Get port number of a pj_sockaddr_in 
     188 */ 
     189PJ_DEF(pj_uint16_t) pj_sockaddr_in_get_port(const pj_sockaddr_in *addr) 
     190{ 
     191    return pj_ntohs(addr->sin_port); 
     192} 
     193 
     194/* 
     195 * Get the address part 
     196 */ 
     197PJ_DEF(void*) pj_sockaddr_get_addr(const pj_sockaddr_t *addr) 
     198{ 
     199    const pj_sockaddr *a = (const pj_sockaddr*)addr; 
     200 
     201    PJ_ASSERT_RETURN(a->addr.sa_family == PJ_AF_INET || 
     202                     a->addr.sa_family == PJ_AF_INET6, NULL); 
     203 
     204    if (a->addr.sa_family == PJ_AF_INET6) 
     205        return (void*) &a->ipv6.sin6_addr; 
     206    else 
     207        return (void*) &a->ipv4.sin_addr; 
     208} 
     209 
     210/* 
     211 * Check if sockaddr contains a non-zero address 
     212 */ 
     213PJ_DEF(pj_bool_t) pj_sockaddr_has_addr(const pj_sockaddr_t *addr) 
     214{ 
     215    const pj_sockaddr *a = (const pj_sockaddr*)addr; 
     216 
     217    PJ_ASSERT_RETURN(a->addr.sa_family == PJ_AF_INET || 
     218                     a->addr.sa_family == PJ_AF_INET6, PJ_EAFNOTSUP); 
     219 
     220    if (a->addr.sa_family == PJ_AF_INET6) { 
     221        pj_uint8_t zero[24]; 
     222        pj_bzero(zero, sizeof(zero)); 
     223        return pj_memcmp(a->ipv6.sin6_addr.s6_addr, zero,  
     224                         sizeof(pj_in6_addr)) != 0; 
     225    } else 
     226        return a->ipv4.sin_addr.s_addr != PJ_INADDR_ANY; 
     227} 
     228 
     229/* 
     230 * Get port number 
     231 */ 
     232PJ_DEF(pj_uint16_t) pj_sockaddr_get_port(const pj_sockaddr_t *addr) 
     233{ 
     234    const pj_sockaddr *a = (const pj_sockaddr*) addr; 
     235 
     236    PJ_ASSERT_RETURN(a->addr.sa_family == PJ_AF_INET || 
     237                     a->addr.sa_family == PJ_AF_INET6, (pj_uint16_t)0xFFFF); 
     238 
     239    return pj_ntohs((pj_uint16_t)(a->addr.sa_family == PJ_AF_INET6 ? 
     240                                    a->ipv6.sin6_port : a->ipv4.sin_port)); 
     241} 
     242 
     243/* 
     244 * Get the length of the address part. 
     245 */ 
     246PJ_DEF(unsigned) pj_sockaddr_get_addr_len(const pj_sockaddr_t *addr) 
     247{ 
     248    const pj_sockaddr *a = (const pj_sockaddr*) addr; 
     249    PJ_ASSERT_RETURN(a->addr.sa_family == PJ_AF_INET || 
     250                     a->addr.sa_family == PJ_AF_INET6, PJ_EAFNOTSUP); 
     251    return a->addr.sa_family == PJ_AF_INET6 ? 
     252            sizeof(pj_in6_addr) : sizeof(pj_in_addr); 
     253} 
     254 
     255/* 
     256 * Set port number of pj_sockaddr_in 
     257 */ 
     258PJ_DEF(void) pj_sockaddr_in_set_port(pj_sockaddr_in *addr,  
     259                                     pj_uint16_t hostport) 
     260{ 
     261    addr->sin_port = pj_htons(hostport); 
     262} 
     263 
     264/* 
     265 * Set port number of pj_sockaddr 
     266 */ 
     267PJ_DEF(pj_status_t) pj_sockaddr_set_port(pj_sockaddr *addr,  
     268                                         pj_uint16_t hostport) 
     269{ 
     270    int af = addr->addr.sa_family; 
     271 
     272    PJ_ASSERT_ON_FAIL(af == PJ_AF_INET || af == PJ_AF_INET6,  
     273                      PJ_EINVAL); 
     274 
     275    if (af == PJ_AF_INET6) 
     276        addr->ipv6.sin6_port = pj_htons(hostport); 
     277    else 
     278        addr->ipv4.sin_port = pj_htons(hostport); 
     279 
     280    return PJ_SUCCESS; 
     281} 
     282 
     283/* 
     284 * Get IPv4 address 
     285 */ 
     286PJ_DEF(pj_in_addr) pj_sockaddr_in_get_addr(const pj_sockaddr_in *addr) 
     287{ 
     288    pj_in_addr in_addr; 
     289    in_addr.s_addr = pj_ntohl(addr->sin_addr.s_addr); 
     290    return in_addr; 
     291} 
     292 
     293/* 
     294 * Set IPv4 address 
     295 */ 
     296PJ_DEF(void) pj_sockaddr_in_set_addr(pj_sockaddr_in *addr, 
     297                                     pj_uint32_t hostaddr) 
     298{ 
     299    addr->sin_addr.s_addr = pj_htonl(hostaddr); 
     300} 
     301 
     302/* Resolve the IP address of local machine */ 
     303PJ_DEF(pj_status_t) pj_gethostip(int af, pj_sockaddr *addr) 
     304{ 
     305    unsigned count; 
     306    pj_addrinfo ai; 
     307    pj_status_t status; 
     308 
     309 
     310#ifdef _MSC_VER 
     311    /* Get rid of "uninitialized he variable" with MS compilers */ 
     312    pj_bzero(&ai, sizeof(ai)); 
     313#endif 
     314 
     315    addr->addr.sa_family = (pj_uint16_t)af; 
     316    PJ_SOCKADDR_RESET_LEN(addr); 
     317 
     318    /* Try with resolving local hostname first */ 
     319    count = 1; 
     320    status = pj_getaddrinfo(af, pj_gethostname(), &count, &ai); 
     321    if (status == PJ_SUCCESS) { 
     322        pj_memcpy(pj_sockaddr_get_addr(addr), 
     323                  pj_sockaddr_get_addr(&ai.ai_addr), 
     324                  pj_sockaddr_get_addr_len(&ai.ai_addr)); 
     325    } 
     326 
     327 
     328    /* If we end up with 127.x.x.x, resolve the IP by getting the default 
     329     * interface to connect to some public host. 
     330     */ 
     331    if (status != PJ_SUCCESS || !pj_sockaddr_has_addr(addr) || 
     332        (af==PJ_AF_INET && (pj_ntohl(addr->ipv4.sin_addr.s_addr) >> 24)==127)) 
     333    { 
     334        status = pj_getdefaultipinterface(af, addr); 
     335    } 
     336 
     337    /* If failed, get the first available interface */ 
     338    if (status != PJ_SUCCESS) { 
     339        pj_sockaddr itf[1]; 
     340        unsigned count = PJ_ARRAY_SIZE(itf); 
     341 
     342        status = pj_enum_ip_interface(af, &count, itf); 
     343        if (status == PJ_SUCCESS) { 
     344            itf[0].addr.sa_family = (pj_uint16_t)af; 
     345            pj_memcpy(pj_sockaddr_get_addr(addr), 
     346                      pj_sockaddr_get_addr(&itf[0]), 
     347                      pj_sockaddr_get_addr_len(&itf[0])); 
     348        } 
     349    } 
     350 
     351    /* If else fails, returns loopback interface as the last resort */ 
     352    if (status != PJ_SUCCESS) { 
     353        if (af==PJ_AF_INET) { 
     354            addr->ipv4.sin_addr.s_addr = pj_htonl (0x7f000001); 
     355        } else { 
     356            pj_in6_addr *s6_addr; 
     357 
     358            s6_addr = (pj_in6_addr*) pj_sockaddr_get_addr(addr); 
     359            pj_bzero(s6_addr, sizeof(pj_in6_addr)); 
     360            s6_addr->s6_addr[15] = 1; 
     361        } 
     362        status = PJ_SUCCESS; 
     363    } 
     364 
     365    return status; 
     366} 
     367 
     368/* Get the default IP interface */ 
     369PJ_DEF(pj_status_t) pj_getdefaultipinterface(int af, pj_sockaddr *addr) 
     370{ 
     371    pj_sock_t fd; 
     372    pj_str_t cp; 
     373    pj_sockaddr a; 
     374    int len; 
     375    pj_uint8_t zero[64]; 
     376    pj_status_t status; 
     377 
     378    addr->addr.sa_family = (pj_uint16_t)af; 
     379 
     380    status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &fd); 
     381    if (status != PJ_SUCCESS) { 
     382        return status; 
     383    } 
     384 
     385    if (af == PJ_AF_INET) { 
     386        cp = pj_str("1.1.1.1"); 
     387    } else { 
     388        cp = pj_str("1::1"); 
     389    } 
     390    status = pj_sockaddr_init(af, &a, &cp, 53); 
     391    if (status != PJ_SUCCESS) { 
     392        pj_sock_close(fd); 
     393        return status; 
     394    } 
     395 
     396    status = pj_sock_connect(fd, &a, sizeof(a)); 
     397    if (status != PJ_SUCCESS) { 
     398        pj_sock_close(fd); 
     399        return status; 
     400    } 
     401 
     402    len = sizeof(a); 
     403    status = pj_sock_getsockname(fd, &a, &len); 
     404    if (status != PJ_SUCCESS) { 
     405        pj_sock_close(fd); 
     406        return status; 
     407    } 
     408 
     409    pj_sock_close(fd); 
     410 
     411    /* Check that the address returned is not zero */ 
     412    pj_bzero(zero, sizeof(zero)); 
     413    if (pj_memcmp(pj_sockaddr_get_addr(&a), zero, 
     414                  pj_sockaddr_get_addr_len(&a))==0) 
     415    { 
     416        return PJ_ENOTFOUND; 
     417    } 
     418 
     419    pj_memcpy(pj_sockaddr_get_addr(addr), 
     420              pj_sockaddr_get_addr(&a), 
     421              pj_sockaddr_get_addr_len(&a)); 
     422 
     423    /* Success */ 
     424    return PJ_SUCCESS; 
     425} 
     426 
     427 
     428/* Only need to implement these in DLL build */ 
     429#if defined(PJ_DLL) 
    20430 
    21431PJ_DEF(pj_uint16_t) pj_AF_UNSPEC(void) 
     
    149559} 
    150560 
     561#endif  /* PJ_DLL */ 
     562 
  • pjproject/trunk/pjlib/src/pj/sock_symbian.cpp

    r1588 r1601  
    443443 
    444444/* 
    445  * Convert address string with numbers and dots to binary IP address. 
    446  */  
    447 PJ_DEF(pj_in_addr) pj_inet_addr(const pj_str_t *cp) 
    448 { 
    449     pj_in_addr addr; 
    450  
    451     pj_inet_aton(cp, &addr); 
    452     return addr; 
    453 } 
    454  
    455 /* 
    456  * Convert address string with numbers and dots to binary IP address. 
    457  */  
    458 PJ_DEF(pj_in_addr) pj_inet_addr2(const char *cp) 
    459 { 
    460     pj_str_t str = pj_str((char*)cp); 
    461     return pj_inet_addr(&str); 
    462 } 
    463  
    464 /* 
    465  * Set the IP address of an IP socket address from string address,  
    466  * with resolving the host if necessary. The string address may be in a 
    467  * standard numbers and dots notation or may be a hostname. If hostname 
    468  * is specified, then the function will resolve the host into the IP 
    469  * address. 
    470  */ 
    471 PJ_DEF(pj_status_t) pj_sockaddr_in_set_str_addr( pj_sockaddr_in *addr, 
    472                                                  const pj_str_t *str_addr) 
    473 { 
    474     PJ_CHECK_STACK(); 
    475  
    476     PJ_ASSERT_RETURN(!str_addr || str_addr->slen < PJ_MAX_HOSTNAME,  
    477                      (addr->sin_addr.s_addr=PJ_INADDR_NONE, PJ_EINVAL)); 
    478  
    479     addr->sin_family = PJ_AF_INET; 
    480     pj_memset(addr->sin_zero, 0, sizeof(addr->sin_zero)); 
    481  
    482     if (str_addr && str_addr->slen) { 
    483         addr->sin_addr = pj_inet_addr(str_addr); 
    484         if (addr->sin_addr.s_addr == PJ_INADDR_NONE) { 
    485             pj_hostent he; 
    486             pj_status_t rc; 
    487  
    488             rc = pj_gethostbyname(str_addr, &he); 
    489             if (rc == 0) { 
    490                 addr->sin_addr.s_addr = *(pj_uint32_t*)he.h_addr; 
    491             } else { 
    492                 addr->sin_addr.s_addr = PJ_INADDR_NONE; 
    493                 return rc; 
    494             } 
    495         } 
    496  
    497     } else { 
    498         addr->sin_addr.s_addr = 0; 
    499     } 
    500  
    501     return PJ_SUCCESS; 
    502 } 
    503  
    504 /* 
    505  * Set the IP address and port of an IP socket address. 
    506  * The string address may be in a standard numbers and dots notation or  
    507  * may be a hostname. If hostname is specified, then the function will  
    508  * resolve the host into the IP address. 
    509  */ 
    510 PJ_DEF(pj_status_t) pj_sockaddr_in_init( pj_sockaddr_in *addr, 
    511                                          const pj_str_t *str_addr, 
    512                                          pj_uint16_t port) 
    513 { 
    514     PJ_ASSERT_RETURN(addr, (addr->sin_addr.s_addr=PJ_INADDR_NONE, PJ_EINVAL)); 
    515  
    516     addr->sin_family = PJ_AF_INET; 
    517     pj_memset(addr->sin_zero, 0, sizeof(addr->sin_zero)); 
    518     pj_sockaddr_in_set_port(addr, port); 
    519     return pj_sockaddr_in_set_str_addr(addr, str_addr); 
    520 } 
    521  
    522   
    523 /* 
    524445 * Get hostname. 
    525446 */ 
     
    532453 
    533454    if (hostname.ptr == NULL) { 
    534         RHostResolver & resv = PjSymbianOS::Instance()->GetResolver(); 
     455        RHostResolver &resv = PjSymbianOS::Instance()->GetResolver(PJ_AF_INET); 
    535456        TRequestStatus reqStatus; 
    536457        THostName tmpName; 
     
    545466    return &hostname; 
    546467} 
    547  
    548 /* 
    549  * Get first IP address associated with the hostname. 
    550  */ 
    551 PJ_DEF(pj_in_addr) pj_gethostaddr(void) 
    552 { 
    553     pj_sockaddr_in addr; 
    554     const pj_str_t *hostname = pj_gethostname(); 
    555  
    556     pj_sockaddr_in_set_str_addr(&addr, hostname); 
    557     return addr.sin_addr; 
    558 } 
    559  
    560468 
    561469/* 
     
    597505 
    598506    /* Wrap Symbian RSocket into PJLIB's CPjSocket, and return to caller */ 
    599     CPjSocket *pjSock = new CPjSocket(rSock); 
     507    CPjSocket *pjSock = new CPjSocket(af, rSock); 
    600508    *p_sock = (pj_sock_t)pjSock; 
    601509 
     
    611519                                  int len) 
    612520{ 
     521    pj_status_t status; 
    613522    TInt rc; 
    614523 
     
    616525 
    617526    PJ_ASSERT_RETURN(sock != 0, PJ_EINVAL); 
    618     PJ_ASSERT_RETURN(addr && len == sizeof(pj_sockaddr_in), PJ_EINVAL); 
    619  
    620     // Convert PJLIB's pj_sockaddr_in into Symbian's TInetAddr 
     527    PJ_ASSERT_RETURN(addr && len >= sizeof(pj_sockaddr_in), PJ_EINVAL); 
     528 
     529    // Convert PJLIB's pj_sockaddr into Symbian's TInetAddr 
    621530    TInetAddr inetAddr; 
    622     PjSymbianOS::pj2Addr(*(pj_sockaddr_in*)addr, inetAddr); 
     531    status = PjSymbianOS::pj2Addr(*(pj_sockaddr*)addr, len, inetAddr); 
     532    if (status != PJ_SUCCESS) 
     533        return status; 
    623534 
    624535    // Get the RSocket instance 
     
    690601    rSock.RemoteName(inetAddr); 
    691602 
    692     PjSymbianOS::Addr2pj(inetAddr, *(pj_sockaddr_in*)addr); 
    693     *namelen = sizeof(pj_sockaddr_in); 
    694  
    695     return PJ_SUCCESS; 
     603    return PjSymbianOS::Addr2pj(inetAddr, *(pj_sockaddr*)addr, namelen); 
    696604} 
    697605 
     
    714622    rSock.LocalName(inetAddr); 
    715623 
    716     PjSymbianOS::Addr2pj(inetAddr, *(pj_sockaddr_in*)addr); 
    717     *namelen = sizeof(pj_sockaddr_in); 
    718  
    719     return PJ_SUCCESS; 
     624    return PjSymbianOS::Addr2pj(inetAddr, *(pj_sockaddr*)addr, namelen); 
    720625} 
    721626 
     
    762667                                   int tolen) 
    763668{ 
     669    pj_status_t status; 
     670     
    764671    PJ_CHECK_STACK(); 
    765672    PJ_ASSERT_RETURN(sock && buf && len, PJ_EINVAL); 
     
    769676 
    770677    // Only supports AF_INET for now 
    771     PJ_ASSERT_RETURN(tolen==sizeof(pj_sockaddr_in) &&  
    772                      ((pj_sockaddr*)to)->addr.sa_family == PJ_AF_INET,  
    773                      PJ_EINVAL); 
     678    PJ_ASSERT_RETURN(tolen >= sizeof(pj_sockaddr_in), PJ_EINVAL); 
    774679 
    775680    TInetAddr inetAddr; 
    776     PjSymbianOS::pj2Addr(*(pj_sockaddr_in*)to, inetAddr); 
     681    status = PjSymbianOS::pj2Addr(*(pj_sockaddr*)to, tolen, inetAddr); 
     682    if (status != PJ_SUCCESS) 
     683        return status; 
    777684 
    778685    TPtrC8 data((const TUint8*)buf, (TInt)*len); 
     
    877784 
    878785            if (from && fromlen) { 
    879                 PjSymbianOS::Addr2pj(inetAddr, *(pj_sockaddr_in*)from); 
    880                 *fromlen = sizeof(pj_sockaddr_in); 
     786                return PjSymbianOS::Addr2pj(inetAddr, *(pj_sockaddr*)from,  
     787                                            fromlen); 
     788            } else { 
     789                return PJ_SUCCESS; 
    881790            } 
    882             return PJ_SUCCESS; 
    883791        } 
    884792    } 
     
    895803        //*len = (TInt)recvLen.Length(); 
    896804        *len = data.Length(); 
    897         *fromlen = sizeof(pj_sockaddr_in); 
    898         PjSymbianOS::Addr2pj(inetAddr, *(pj_sockaddr_in*)from); 
    899         return PJ_SUCCESS; 
     805        return PjSymbianOS::Addr2pj(inetAddr, *(pj_sockaddr*)from, fromlen); 
    900806    } else { 
    901807        *len = -1; 
     
    948854                                     int namelen) 
    949855{ 
     856    pj_status_t status; 
     857     
    950858    PJ_CHECK_STACK(); 
    951859 
     
    960868    TRequestStatus reqStatus; 
    961869 
    962     PjSymbianOS::pj2Addr(*(pj_sockaddr_in*)addr, inetAddr); 
     870    status = PjSymbianOS::pj2Addr(*(pj_sockaddr*)addr, namelen, inetAddr); 
     871    if (status != PJ_SUCCESS) 
     872        return status; 
    963873 
    964874    rSock.Connect(inetAddr, reqStatus); 
     
    1060970 
    1061971    // Create PJ socket 
    1062     CPjSocket *newPjSock = new CPjSocket(newSock); 
     972    CPjSocket *newPjSock = new CPjSocket(pjSock->GetAf(), newSock); 
    1063973    newPjSock->SetConnected(true); 
    1064974 
Note: See TracChangeset for help on using the changeset viewer.