Changeset 1601 for pjproject/trunk/pjlib/src/pj/addr_resolv_symbian.cpp
- Timestamp:
- Dec 1, 2007 8:52:57 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjlib/src/pj/addr_resolv_symbian.cpp
r1599 r1601 28 28 29 29 30 30 31 // PJLIB API: resolve hostname 31 32 PJ_DEF(pj_status_t) pj_gethostbyname(const pj_str_t *name, pj_hostent *he) 32 33 { 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 } 34 59 35 RHostResolver &resv = PjSymbianOS::Instance()->GetResolver(); 60 61 // Resolve for specific address family 62 static 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); 36 72 37 73 // Convert name to Unicode … … 47 83 User::WaitForRequest(reqStatus); 48 84 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; 51 92 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)); 57 104 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 } 68 116 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; 85 118 return PJ_SUCCESS; 86 119 } 87 120 88 89 /* Get the default IP interface */ 90 PJ_DEF(pj_status_t) pj_getdefaultipinterface(pj_in_addr *addr) 121 /* Resolve IPv4/IPv6 address */ 122 PJ_DEF(pj_status_t) pj_getaddrinfo(int af, const pj_str_t *nodename, 123 unsigned *count, pj_addrinfo ai[]) 91 124 { 92 pj_sock_t fd; 93 pj_str_t cp; 94 pj_sockaddr_in a; 95 int len; 125 unsigned start; 96 126 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 } 101 142 } 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 } 110 152 } 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; 117 160 } 118 119 pj_sock_close(fd);120 121 *addr = a.sin_addr;122 123 /* Success */124 return PJ_SUCCESS;125 161 } 126 162 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 default144 * 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
Note: See TracChangeset
for help on using the changeset viewer.