88497faa4b2dead177bcb72f54dceee72713ee77
[libs/net.git] / source / net / resolve.cpp
1 #ifdef WIN32
2 #define _WIN32_WINNT 0x0501
3 #include <ws2tcpip.h>
4 #else
5 #include <netdb.h>
6 #endif
7 #include <msp/core/systemerror.h>
8 #include <msp/strings/format.h>
9 #include "sockaddr_private.h"
10 #include "socket.h"
11 #include "resolve.h"
12
13 using namespace std;
14
15 namespace Msp {
16 namespace Net {
17
18 SockAddr *resolve(const string &host, const string &serv, Family family)
19 {
20         const char *chost = (host.empty() ? 0 : host.c_str());
21         const char *cserv = (serv.empty() ? 0 : serv.c_str());
22         int flags = 0;
23         if(host=="*")
24         {
25                 flags = AI_PASSIVE;
26                 chost = 0;
27         }
28
29         addrinfo hints = { flags, family_to_sys(family), 0, 0, 0, 0, 0, 0 };
30         addrinfo *res;
31
32         int err = getaddrinfo(chost, cserv, &hints, &res);
33         if(err==0)
34         {
35                 SockAddr::SysAddr sa;
36                 sa.size = res->ai_addrlen;
37                 const char *sptr = reinterpret_cast<const char *>(res->ai_addr);
38                 char *dptr = reinterpret_cast<char *>(&sa.addr);
39                 copy(sptr, sptr+res->ai_addrlen, dptr);
40                 SockAddr *addr = SockAddr::new_from_sys(sa);
41                 freeaddrinfo(res);
42                 return addr;
43         }
44         else
45 #ifdef WIN32
46                 throw system_error("getaddrinfo", WSAGetLastError());
47 #else
48                 throw system_error("getaddrinfo", gai_strerror(err));
49 #endif
50 }
51
52 SockAddr *resolve(const string &str, Family family)
53 {
54         string host, serv;
55         if(str[0]=='[')
56         {
57                 string::size_type bracket = str.find(']');
58                 host = str.substr(1, bracket-1);
59                 string::size_type colon = str.find(':', bracket);
60                 if(colon!=string::npos)
61                         serv = str.substr(colon+1);
62         }
63         else
64         {
65                 string::size_type colon = str.find(':');
66                 if(colon!=string::npos)
67                 {
68                         host = str.substr(0, colon);
69                         serv = str.substr(colon+1);
70                 }
71                 else
72                         host = str;
73         }
74
75         return resolve(host, serv, family);
76 }
77
78                 /*sockaddr sa;
79                 unsigned size = fill_sockaddr(sa);
80                 char hst[128];
81                 char srv[128];
82                 int err = getnameinfo(&sa, size, hst, 128, srv, 128, 0);
83                 if(err==0)
84                 {
85                         host = hst;
86                         serv = srv;
87                 }*/
88
89 } // namespace Net
90 } // namespace Msp