33c74ee3d7
BUG=https://code.google.com/p/dart/issues/detail?id=13577 R=sgjesse@google.com Review URL: https://codereview.chromium.org//25411003 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@28090 260f80e4-7a28-3924-810f-c04153c831b5
234 lines
6.3 KiB
C++
234 lines
6.3 KiB
C++
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
#ifndef BIN_SOCKET_H_
|
|
#define BIN_SOCKET_H_
|
|
|
|
#include "bin/builtin.h"
|
|
#include "bin/utils.h"
|
|
#include "bin/dartutils.h"
|
|
|
|
#include "platform/globals.h"
|
|
#include "platform/thread.h"
|
|
// Declare the OS-specific types ahead of defining the generic class.
|
|
#if defined(TARGET_OS_ANDROID)
|
|
#include "bin/socket_android.h"
|
|
#elif defined(TARGET_OS_LINUX)
|
|
#include "bin/socket_linux.h"
|
|
#elif defined(TARGET_OS_MACOS)
|
|
#include "bin/socket_macos.h"
|
|
#elif defined(TARGET_OS_WINDOWS)
|
|
#include "bin/socket_win.h"
|
|
#else
|
|
#error Unknown target os.
|
|
#endif
|
|
|
|
|
|
namespace dart {
|
|
namespace bin {
|
|
|
|
union RawAddr {
|
|
struct sockaddr_in in;
|
|
struct sockaddr_in6 in6;
|
|
struct sockaddr_storage ss;
|
|
struct sockaddr addr;
|
|
};
|
|
|
|
class SocketAddress {
|
|
public:
|
|
enum {
|
|
TYPE_ANY = -1,
|
|
TYPE_IPV4,
|
|
TYPE_IPV6,
|
|
};
|
|
|
|
enum {
|
|
ADDRESS_LOOPBACK_IP_V4,
|
|
ADDRESS_LOOPBACK_IP_V6,
|
|
ADDRESS_ANY_IP_V4,
|
|
ADDRESS_ANY_IP_V6,
|
|
ADDRESS_FIRST = ADDRESS_LOOPBACK_IP_V4,
|
|
ADDRESS_LAST = ADDRESS_ANY_IP_V6,
|
|
};
|
|
|
|
explicit SocketAddress(struct sockaddr* sa);
|
|
|
|
~SocketAddress() {}
|
|
|
|
int GetType() {
|
|
if (addr_.ss.ss_family == AF_INET6) return TYPE_IPV6;
|
|
return TYPE_IPV4;
|
|
}
|
|
|
|
const char* as_string() const { return as_string_; }
|
|
const RawAddr& addr() const { return addr_; }
|
|
|
|
static intptr_t GetAddrLength(const RawAddr* addr) {
|
|
return addr->ss.ss_family == AF_INET6 ?
|
|
sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
|
|
}
|
|
|
|
static int16_t FromType(int type) {
|
|
if (type == TYPE_ANY) return AF_UNSPEC;
|
|
if (type == TYPE_IPV4) return AF_INET;
|
|
ASSERT(type == TYPE_IPV6 && "Invalid type");
|
|
return AF_INET6;
|
|
}
|
|
|
|
static void SetAddrPort(RawAddr* addr, intptr_t port) {
|
|
if (addr->ss.ss_family == AF_INET) {
|
|
addr->in.sin_port = htons(port);
|
|
} else {
|
|
addr->in6.sin6_port = htons(port);
|
|
}
|
|
}
|
|
|
|
static intptr_t GetAddrPort(RawAddr* addr) {
|
|
if (addr->ss.ss_family == AF_INET) {
|
|
return ntohs(addr->in.sin_port);
|
|
} else {
|
|
return ntohs(addr->in6.sin6_port);
|
|
}
|
|
}
|
|
|
|
private:
|
|
char as_string_[INET6_ADDRSTRLEN];
|
|
RawAddr addr_;
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(SocketAddress);
|
|
};
|
|
|
|
class InterfaceSocketAddress {
|
|
public:
|
|
explicit InterfaceSocketAddress(struct sockaddr* sa,
|
|
const char* interface_name)
|
|
: socket_address_(new SocketAddress(sa)),
|
|
interface_name_(interface_name) {}
|
|
|
|
~InterfaceSocketAddress() {
|
|
delete socket_address_;
|
|
free(const_cast<char*>(interface_name_));
|
|
}
|
|
|
|
SocketAddress* socket_address() const { return socket_address_; }
|
|
const char* interface_name() const { return interface_name_; }
|
|
|
|
private:
|
|
SocketAddress* socket_address_;
|
|
const char* interface_name_;
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(InterfaceSocketAddress);
|
|
};
|
|
|
|
template<typename T>
|
|
class AddressList {
|
|
public:
|
|
explicit AddressList(intptr_t count)
|
|
: count_(count),
|
|
addresses_(new T*[count_]) {}
|
|
|
|
~AddressList() {
|
|
for (intptr_t i = 0; i < count_; i++) {
|
|
delete addresses_[i];
|
|
}
|
|
delete[] addresses_;
|
|
}
|
|
|
|
intptr_t count() const { return count_; }
|
|
T* GetAt(intptr_t i) const { return addresses_[i]; }
|
|
void SetAt(intptr_t i, T* addr) { addresses_[i] = addr; }
|
|
|
|
private:
|
|
const intptr_t count_;
|
|
T** addresses_;
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(AddressList);
|
|
};
|
|
|
|
class Socket {
|
|
public:
|
|
enum SocketRequest {
|
|
kLookupRequest = 0,
|
|
kListInterfacesRequest = 1,
|
|
kReverseLookupRequest = 2,
|
|
};
|
|
|
|
static bool Initialize();
|
|
static intptr_t Available(intptr_t fd);
|
|
static int Read(intptr_t fd, void* buffer, intptr_t num_bytes);
|
|
static int Write(intptr_t fd, const void* buffer, intptr_t num_bytes);
|
|
static intptr_t Create(RawAddr addr);
|
|
static intptr_t Connect(intptr_t fd, RawAddr addr, const intptr_t port);
|
|
static intptr_t CreateConnect(RawAddr addr,
|
|
const intptr_t port);
|
|
static intptr_t GetPort(intptr_t fd);
|
|
static bool GetRemotePeer(intptr_t fd, char* host, intptr_t* port);
|
|
static void GetError(intptr_t fd, OSError* os_error);
|
|
static int GetType(intptr_t fd);
|
|
static intptr_t GetStdioHandle(intptr_t num);
|
|
static void Close(intptr_t fd);
|
|
static bool SetNonBlocking(intptr_t fd);
|
|
static bool SetBlocking(intptr_t fd);
|
|
static bool SetNoDelay(intptr_t fd, bool enabled);
|
|
|
|
// Perform a hostname lookup. Returns a AddressList of SocketAddress's.
|
|
static AddressList<SocketAddress>* LookupAddress(const char* host,
|
|
int type,
|
|
OSError** os_error);
|
|
static bool ReverseLookup(RawAddr addr,
|
|
char* host,
|
|
intptr_t host_len,
|
|
OSError** os_error);
|
|
|
|
// List interfaces. Returns a AddressList of InterfaceSocketAddress's.
|
|
static AddressList<InterfaceSocketAddress>* ListInterfaces(
|
|
int type,
|
|
OSError** os_error);
|
|
|
|
static CObject* LookupRequest(const CObjectArray& request);
|
|
static CObject* ListInterfacesRequest(const CObjectArray& request);
|
|
static CObject* ReverseLookupRequest(const CObjectArray& request);
|
|
|
|
static Dart_Port GetServicePort();
|
|
|
|
static Dart_Handle SetSocketIdNativeField(Dart_Handle socket, intptr_t id);
|
|
static Dart_Handle GetSocketIdNativeField(Dart_Handle socket, intptr_t* id);
|
|
|
|
private:
|
|
static dart::Mutex* mutex_;
|
|
static int service_ports_size_;
|
|
static Dart_Port* service_ports_;
|
|
static int service_ports_index_;
|
|
|
|
DISALLOW_ALLOCATION();
|
|
DISALLOW_IMPLICIT_CONSTRUCTORS(Socket);
|
|
};
|
|
|
|
|
|
class ServerSocket {
|
|
public:
|
|
static const intptr_t kTemporaryFailure = -2;
|
|
|
|
static intptr_t Accept(intptr_t fd);
|
|
|
|
// Returns a positive integer if the call is successful. In case of failure
|
|
// it returns:
|
|
//
|
|
// -1: system error (errno set)
|
|
// -5: invalid bindAddress
|
|
static intptr_t CreateBindListen(RawAddr addr,
|
|
intptr_t port,
|
|
intptr_t backlog,
|
|
bool v6_only = false);
|
|
|
|
private:
|
|
DISALLOW_ALLOCATION();
|
|
DISALLOW_IMPLICIT_CONSTRUCTORS(ServerSocket);
|
|
};
|
|
|
|
} // namespace bin
|
|
} // namespace dart
|
|
|
|
#endif // BIN_SOCKET_H_
|