blob: fdce6051310b86ed986f3530679ca3ca9499deec [file] [log] [blame]
// Copyright 2015 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "starboard/socket.h"
#include <errno.h>
#include <netdb.h>
#include <sys/socket.h>
#include "starboard/log.h"
#include "starboard/shared/posix/socket_internal.h"
namespace sbposix = starboard::shared::posix;
SbSocketResolution* SbSocketResolve(const char* hostname, int filters) {
struct addrinfo* ai = NULL;
struct addrinfo hints = {0};
if (filters & kSbSocketResolveFilterIpv4) {
if (filters & kSbSocketResolveFilterIpv6) {
hints.ai_family = AF_UNSPEC;
} else {
hints.ai_family = AF_INET;
}
} else if (filters & kSbSocketResolveFilterIpv6) {
hints.ai_family = AF_INET6;
} else {
hints.ai_family = AF_UNSPEC;
}
hints.ai_flags = AI_ADDRCONFIG;
hints.ai_socktype = SOCK_STREAM;
// Actually make the call to get the data.
int err = getaddrinfo(hostname, NULL, &hints, &ai);
if (err != 0 || ai == NULL) {
return NULL;
}
int address_count = 0;
for (const struct addrinfo* i = ai; i != NULL; i = i->ai_next) {
++address_count;
}
SbSocketResolution* result = new SbSocketResolution();
// Translate all the sockaddrs.
sbposix::SockAddr* sock_addrs = new sbposix::SockAddr[address_count];
bool* parsed = new bool[address_count];
int index = 0;
int skip = 0;
for (const struct addrinfo *i = ai; i != NULL; i = i->ai_next, ++index) {
// Skip over any addresses we can't parse.
parsed[index] = sock_addrs[index].FromSockaddr(i->ai_addr);
if (!parsed[index]) {
++skip;
}
}
result->address_count = address_count - skip;
result->addresses = new SbSocketAddress[result->address_count];
int result_index = 0;
for (int i = 0; i < address_count; ++i) {
if (parsed[i] &&
sock_addrs[i].ToSbSocketAddress(&result->addresses[result_index])) {
++result_index;
}
}
delete[] parsed;
delete[] sock_addrs;
freeaddrinfo(ai);
return result;
}