| 140 | */ |
| 141 | |
| 142 | int _drcSetupNet (const char *ipAddress, const char *port, const char *password) |
| 143 | { |
| 144 | struct addrinfo hints; |
| 145 | struct addrinfo *result, *rp ; |
| 146 | struct in6_addr serveraddr ; |
| 147 | int remoteFd ; |
| 148 | |
| 149 | // Start by seeing if we've been given a (textual) numeric IP address |
| 150 | // which will save lookups in getaddrinfo() |
| 151 | |
| 152 | memset (&hints, 0, sizeof (hints)) ; |
| 153 | hints.ai_flags = AI_NUMERICSERV ; |
| 154 | hints.ai_family = AF_UNSPEC ; |
| 155 | hints.ai_socktype = SOCK_STREAM ; |
| 156 | hints.ai_protocol = 0 ; |
| 157 | |
| 158 | if (inet_pton (AF_INET, ipAddress, &serveraddr) == 1) // Valid IPv4 |
| 159 | { |
| 160 | hints.ai_family = AF_INET ; |
| 161 | hints.ai_flags |= AI_NUMERICHOST ; |
| 162 | } |
| 163 | else |
| 164 | { |
| 165 | if (inet_pton (AF_INET6, ipAddress, &serveraddr) == 1) // Valid IPv6 |
| 166 | { |
| 167 | hints.ai_family = AF_INET6 ; |
| 168 | hints.ai_flags |= AI_NUMERICHOST ; |
| 169 | } |
| 170 | } |
| 171 | |
| 172 | // Now use getaddrinfo() with the newly supplied hints |
| 173 | |
| 174 | if (getaddrinfo (ipAddress, port, &hints, &result) != 0) |
| 175 | return -1 ; |
| 176 | |
| 177 | // Now try each address in-turn until we get one that connects... |
| 178 | |
| 179 | for (rp = result; rp != NULL; rp = rp->ai_next) |
| 180 | { |
| 181 | if ((remoteFd = socket (rp->ai_family, rp->ai_socktype, rp->ai_protocol)) < 0) |
| 182 | continue ; |
| 183 | |
| 184 | if (connect (remoteFd, rp->ai_addr, rp->ai_addrlen) < 0) |
| 185 | continue ; |
| 186 | |
| 187 | if (authenticate (remoteFd, password) < 0) |
| 188 | { |
| 189 | close (remoteFd) ; |
| 190 | errno = EACCES ; // Permission denied |
| 191 | return -1 ; |
| 192 | } |
| 193 | else |
| 194 | return remoteFd ; |
| 195 | } |
| 196 | |
| 197 | errno = EHOSTUNREACH ; // Host unreachable - may not be right, but good enough |
| 198 | return -1 ; // Nothing connected |
| 199 | } |
no test coverage detected