2013-01-09 09:17:07 +00:00
|
|
|
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
2011-10-05 05:20:07 +00:00
|
|
|
// 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_
|
|
|
|
|
2015-02-11 10:01:20 +00:00
|
|
|
#include <map>
|
|
|
|
|
2014-08-12 23:19:53 +00:00
|
|
|
#include "platform/globals.h"
|
|
|
|
|
2011-10-05 05:20:07 +00:00
|
|
|
#include "bin/builtin.h"
|
2013-09-25 15:03:24 +00:00
|
|
|
#include "bin/dartutils.h"
|
2012-04-10 23:29:02 +00:00
|
|
|
// Declare the OS-specific types ahead of defining the generic class.
|
2012-08-13 23:06:52 +00:00
|
|
|
#if defined(TARGET_OS_ANDROID)
|
|
|
|
#include "bin/socket_android.h"
|
|
|
|
#elif defined(TARGET_OS_LINUX)
|
2012-04-10 23:29:02 +00:00
|
|
|
#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
|
2014-08-12 23:19:53 +00:00
|
|
|
#include "bin/thread.h"
|
|
|
|
#include "bin/utils.h"
|
2011-10-05 05:20:07 +00:00
|
|
|
|
2013-04-25 14:22:30 +00:00
|
|
|
namespace dart {
|
|
|
|
namespace bin {
|
|
|
|
|
2013-04-24 09:26:58 +00:00
|
|
|
union RawAddr {
|
|
|
|
struct sockaddr_in in;
|
|
|
|
struct sockaddr_in6 in6;
|
2013-04-24 11:51:56 +00:00
|
|
|
struct sockaddr_storage ss;
|
2013-04-24 09:26:58 +00:00
|
|
|
struct sockaddr addr;
|
|
|
|
};
|
|
|
|
|
|
|
|
class SocketAddress {
|
|
|
|
public:
|
|
|
|
enum {
|
|
|
|
TYPE_ANY = -1,
|
|
|
|
TYPE_IPV4,
|
|
|
|
TYPE_IPV6,
|
|
|
|
};
|
|
|
|
|
2013-04-30 11:30:05 +00:00
|
|
|
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,
|
|
|
|
};
|
|
|
|
|
2013-10-01 11:27:46 +00:00
|
|
|
explicit SocketAddress(struct sockaddr* sa);
|
2013-06-21 07:58:48 +00:00
|
|
|
|
|
|
|
~SocketAddress() {}
|
2013-04-24 09:26:58 +00:00
|
|
|
|
|
|
|
int GetType() {
|
2016-03-16 17:01:00 +00:00
|
|
|
if (addr_.ss.ss_family == AF_INET6) {
|
|
|
|
return TYPE_IPV6;
|
|
|
|
}
|
2013-04-24 09:26:58 +00:00
|
|
|
return TYPE_IPV4;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char* as_string() const { return as_string_; }
|
|
|
|
const RawAddr& addr() const { return addr_; }
|
|
|
|
|
2015-02-12 11:39:20 +00:00
|
|
|
static intptr_t GetAddrLength(const RawAddr& addr) {
|
2016-03-16 17:01:00 +00:00
|
|
|
ASSERT((addr.ss.ss_family == AF_INET) || (addr.ss.ss_family == AF_INET6));
|
|
|
|
return (addr.ss.ss_family == AF_INET6) ?
|
2013-04-24 09:26:58 +00:00
|
|
|
sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
|
|
|
|
}
|
|
|
|
|
2015-02-12 11:39:20 +00:00
|
|
|
static intptr_t GetInAddrLength(const RawAddr& addr) {
|
2016-03-16 17:01:00 +00:00
|
|
|
ASSERT((addr.ss.ss_family == AF_INET) || (addr.ss.ss_family == AF_INET6));
|
|
|
|
return (addr.ss.ss_family == AF_INET6) ?
|
2013-12-17 15:35:11 +00:00
|
|
|
sizeof(struct in6_addr) : sizeof(struct in_addr);
|
|
|
|
}
|
|
|
|
|
2015-02-11 10:01:20 +00:00
|
|
|
static bool AreAddressesEqual(const RawAddr& a, const RawAddr& b) {
|
|
|
|
if (a.ss.ss_family == AF_INET) {
|
2016-03-16 17:01:00 +00:00
|
|
|
if (b.ss.ss_family != AF_INET) {
|
|
|
|
return false;
|
|
|
|
}
|
2015-02-11 10:01:20 +00:00
|
|
|
return memcmp(&a.in.sin_addr, &b.in.sin_addr, sizeof(a.in.sin_addr)) == 0;
|
|
|
|
} else if (a.ss.ss_family == AF_INET6) {
|
2016-03-16 17:01:00 +00:00
|
|
|
if (b.ss.ss_family != AF_INET6) {
|
|
|
|
return false;
|
|
|
|
}
|
2015-02-11 10:01:20 +00:00
|
|
|
return memcmp(&a.in6.sin6_addr,
|
|
|
|
&b.in6.sin6_addr,
|
|
|
|
sizeof(a.in6.sin6_addr)) == 0;
|
|
|
|
} else {
|
|
|
|
UNREACHABLE();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-17 15:35:11 +00:00
|
|
|
static void GetSockAddr(Dart_Handle obj, RawAddr* addr) {
|
|
|
|
Dart_TypedData_Type data_type;
|
|
|
|
uint8_t* data = NULL;
|
|
|
|
intptr_t len;
|
|
|
|
Dart_Handle result = Dart_TypedDataAcquireData(
|
|
|
|
obj, &data_type, reinterpret_cast<void**>(&data), &len);
|
2016-03-16 17:01:00 +00:00
|
|
|
if (Dart_IsError(result)) {
|
|
|
|
Dart_PropagateError(result);
|
|
|
|
}
|
|
|
|
if ((data_type != Dart_TypedData_kUint8) ||
|
|
|
|
((len != sizeof(in_addr)) && (len != sizeof(in6_addr)))) {
|
2013-12-17 15:35:11 +00:00
|
|
|
Dart_PropagateError(
|
|
|
|
Dart_NewApiError("Unexpected type for socket address"));
|
|
|
|
}
|
|
|
|
memset(reinterpret_cast<void*>(addr), 0, sizeof(RawAddr));
|
|
|
|
if (len == sizeof(in_addr)) {
|
|
|
|
addr->in.sin_family = AF_INET;
|
|
|
|
memmove(reinterpret_cast<void *>(&addr->in.sin_addr), data, len);
|
|
|
|
} else {
|
|
|
|
ASSERT(len == sizeof(in6_addr));
|
|
|
|
addr->in6.sin6_family = AF_INET6;
|
|
|
|
memmove(reinterpret_cast<void*>(&addr->in6.sin6_addr), data, len);
|
|
|
|
}
|
|
|
|
Dart_TypedDataReleaseData(obj);
|
|
|
|
}
|
|
|
|
|
2013-04-24 09:26:58 +00:00
|
|
|
static int16_t FromType(int type) {
|
2016-03-16 17:01:00 +00:00
|
|
|
if (type == TYPE_ANY) {
|
|
|
|
return AF_UNSPEC;
|
|
|
|
}
|
|
|
|
if (type == TYPE_IPV4) {
|
|
|
|
return AF_INET;
|
|
|
|
}
|
|
|
|
ASSERT((type == TYPE_IPV6) && "Invalid type");
|
2013-04-24 09:26:58 +00:00
|
|
|
return AF_INET6;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void SetAddrPort(RawAddr* addr, intptr_t port) {
|
2013-04-24 11:51:56 +00:00
|
|
|
if (addr->ss.ss_family == AF_INET) {
|
2013-04-24 09:26:58 +00:00
|
|
|
addr->in.sin_port = htons(port);
|
|
|
|
} else {
|
|
|
|
addr->in6.sin6_port = htons(port);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-12 11:39:20 +00:00
|
|
|
static intptr_t GetAddrPort(const RawAddr& addr) {
|
|
|
|
if (addr.ss.ss_family == AF_INET) {
|
|
|
|
return ntohs(addr.in.sin_port);
|
2013-04-24 09:26:58 +00:00
|
|
|
} else {
|
2015-02-12 11:39:20 +00:00
|
|
|
return ntohs(addr.in6.sin6_port);
|
2013-04-24 09:26:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-12 11:39:20 +00:00
|
|
|
static Dart_Handle ToTypedData(const RawAddr& addr) {
|
|
|
|
int len = GetInAddrLength(addr);
|
2013-11-20 10:01:22 +00:00
|
|
|
Dart_Handle result = Dart_NewTypedData(Dart_TypedData_kUint8, len);
|
2016-03-16 17:01:00 +00:00
|
|
|
if (Dart_IsError(result)) {
|
|
|
|
Dart_PropagateError(result);
|
|
|
|
}
|
2013-12-17 15:35:11 +00:00
|
|
|
Dart_Handle err;
|
2015-02-12 11:39:20 +00:00
|
|
|
if (addr.addr.sa_family == AF_INET6) {
|
2013-12-17 15:35:11 +00:00
|
|
|
err = Dart_ListSetAsBytes(
|
2015-12-15 18:24:40 +00:00
|
|
|
result, 0,
|
|
|
|
reinterpret_cast<const uint8_t*>(&addr.in6.sin6_addr), len);
|
2013-12-17 15:35:11 +00:00
|
|
|
} else {
|
|
|
|
err = Dart_ListSetAsBytes(
|
2015-12-15 18:24:40 +00:00
|
|
|
result, 0, reinterpret_cast<const uint8_t*>(&addr.in.sin_addr), len);
|
2013-12-17 15:35:11 +00:00
|
|
|
}
|
2016-03-16 17:01:00 +00:00
|
|
|
if (Dart_IsError(err)) {
|
|
|
|
Dart_PropagateError(err);
|
|
|
|
}
|
2013-11-20 10:01:22 +00:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2015-02-12 11:39:20 +00:00
|
|
|
static CObjectUint8Array* ToCObject(const RawAddr& addr) {
|
|
|
|
int in_addr_len = SocketAddress::GetInAddrLength(addr);
|
2015-12-15 18:24:40 +00:00
|
|
|
const void* in_addr;
|
2013-12-17 15:35:11 +00:00
|
|
|
CObjectUint8Array* data =
|
|
|
|
new CObjectUint8Array(CObject::NewUint8Array(in_addr_len));
|
2015-02-12 11:39:20 +00:00
|
|
|
if (addr.addr.sa_family == AF_INET6) {
|
2015-12-15 18:24:40 +00:00
|
|
|
in_addr = reinterpret_cast<const void*>(&addr.in6.sin6_addr);
|
2013-12-17 15:35:11 +00:00
|
|
|
} else {
|
2015-12-15 18:24:40 +00:00
|
|
|
in_addr = reinterpret_cast<const void*>(&addr.in.sin_addr);
|
2013-12-17 15:35:11 +00:00
|
|
|
}
|
|
|
|
memmove(data->Buffer(), in_addr, in_addr_len);
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
2013-04-24 09:26:58 +00:00
|
|
|
private:
|
|
|
|
char as_string_[INET6_ADDRSTRLEN];
|
|
|
|
RawAddr addr_;
|
|
|
|
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(SocketAddress);
|
|
|
|
};
|
|
|
|
|
2016-03-16 17:01:00 +00:00
|
|
|
|
2013-06-21 07:58:48 +00:00
|
|
|
class InterfaceSocketAddress {
|
2013-04-24 09:26:58 +00:00
|
|
|
public:
|
2016-03-16 17:01:00 +00:00
|
|
|
InterfaceSocketAddress(struct sockaddr* sa,
|
|
|
|
const char* interface_name,
|
|
|
|
intptr_t interface_index)
|
2013-10-01 11:27:46 +00:00
|
|
|
: socket_address_(new SocketAddress(sa)),
|
2013-11-29 11:18:30 +00:00
|
|
|
interface_name_(interface_name),
|
|
|
|
interface_index_(interface_index) {}
|
2013-06-21 07:58:48 +00:00
|
|
|
|
|
|
|
~InterfaceSocketAddress() {
|
|
|
|
delete socket_address_;
|
|
|
|
}
|
|
|
|
|
|
|
|
SocketAddress* socket_address() const { return socket_address_; }
|
|
|
|
const char* interface_name() const { return interface_name_; }
|
2013-11-29 11:18:30 +00:00
|
|
|
int interface_index() const { return interface_index_; }
|
2013-06-21 07:58:48 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
SocketAddress* socket_address_;
|
|
|
|
const char* interface_name_;
|
2013-11-29 11:18:30 +00:00
|
|
|
intptr_t interface_index_;
|
2013-06-21 07:58:48 +00:00
|
|
|
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(InterfaceSocketAddress);
|
|
|
|
};
|
|
|
|
|
2016-03-16 17:01:00 +00:00
|
|
|
|
2013-06-21 07:58:48 +00:00
|
|
|
template<typename T>
|
|
|
|
class AddressList {
|
|
|
|
public:
|
|
|
|
explicit AddressList(intptr_t count)
|
2013-04-24 09:26:58 +00:00
|
|
|
: count_(count),
|
2013-06-21 07:58:48 +00:00
|
|
|
addresses_(new T*[count_]) {}
|
2013-04-24 09:26:58 +00:00
|
|
|
|
2013-06-21 07:58:48 +00:00
|
|
|
~AddressList() {
|
2013-04-24 09:26:58 +00:00
|
|
|
for (intptr_t i = 0; i < count_; i++) {
|
|
|
|
delete addresses_[i];
|
|
|
|
}
|
|
|
|
delete[] addresses_;
|
|
|
|
}
|
|
|
|
|
|
|
|
intptr_t count() const { return count_; }
|
2013-06-21 07:58:48 +00:00
|
|
|
T* GetAt(intptr_t i) const { return addresses_[i]; }
|
|
|
|
void SetAt(intptr_t i, T* addr) { addresses_[i] = addr; }
|
2013-04-24 09:26:58 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
const intptr_t count_;
|
2013-06-21 07:58:48 +00:00
|
|
|
T** addresses_;
|
2013-04-24 09:26:58 +00:00
|
|
|
|
2013-06-21 07:58:48 +00:00
|
|
|
DISALLOW_COPY_AND_ASSIGN(AddressList);
|
2013-04-24 09:26:58 +00:00
|
|
|
};
|
|
|
|
|
2016-03-16 17:01:00 +00:00
|
|
|
|
2011-10-05 05:20:07 +00:00
|
|
|
class Socket {
|
|
|
|
public:
|
2012-03-19 11:26:41 +00:00
|
|
|
enum SocketRequest {
|
|
|
|
kLookupRequest = 0,
|
2013-06-21 07:58:48 +00:00
|
|
|
kListInterfacesRequest = 1,
|
2013-06-25 11:27:48 +00:00
|
|
|
kReverseLookupRequest = 2,
|
2012-03-19 11:26:41 +00:00
|
|
|
};
|
|
|
|
|
2011-10-05 05:20:07 +00:00
|
|
|
static bool Initialize();
|
|
|
|
static intptr_t Available(intptr_t fd);
|
2014-06-05 17:33:52 +00:00
|
|
|
static intptr_t Read(intptr_t fd, void* buffer, intptr_t num_bytes);
|
|
|
|
static intptr_t Write(intptr_t fd, const void* buffer, intptr_t num_bytes);
|
2015-02-12 11:39:20 +00:00
|
|
|
// Send data on a socket. The port to send to is specified in the port
|
|
|
|
// component of the passed RawAddr structure. The RawAddr structure is only
|
|
|
|
// used for datagram sockets.
|
2014-06-05 17:33:52 +00:00
|
|
|
static intptr_t SendTo(
|
2015-02-12 11:39:20 +00:00
|
|
|
intptr_t fd, const void* buffer, intptr_t num_bytes, const RawAddr& addr);
|
2014-06-05 17:33:52 +00:00
|
|
|
static intptr_t RecvFrom(
|
2013-12-12 15:45:25 +00:00
|
|
|
intptr_t fd, void* buffer, intptr_t num_bytes, RawAddr* addr);
|
2015-02-12 11:39:20 +00:00
|
|
|
// Creates a socket which is bound and connected. The port to connect to is
|
|
|
|
// specified as the port component of the passed RawAddr structure.
|
|
|
|
static intptr_t CreateConnect(const RawAddr& addr);
|
|
|
|
// Creates a socket which is bound and connected. The port to connect to is
|
|
|
|
// specified as the port component of the passed RawAddr structure.
|
2015-02-10 11:56:51 +00:00
|
|
|
static intptr_t CreateBindConnect(const RawAddr& addr,
|
|
|
|
const RawAddr& source_addr);
|
2015-02-12 11:39:20 +00:00
|
|
|
// Creates a datagram socket which is bound. The port to bind
|
|
|
|
// to is specified as the port component of the RawAddr structure.
|
|
|
|
static intptr_t CreateBindDatagram(const RawAddr& addr, bool reuseAddress);
|
2011-10-05 05:20:07 +00:00
|
|
|
static intptr_t GetPort(intptr_t fd);
|
2013-11-05 13:24:49 +00:00
|
|
|
static SocketAddress* GetRemotePeer(intptr_t fd, intptr_t* port);
|
2012-03-21 09:39:47 +00:00
|
|
|
static void GetError(intptr_t fd, OSError* os_error);
|
2013-01-09 09:17:07 +00:00
|
|
|
static int GetType(intptr_t fd);
|
2013-09-03 12:43:08 +00:00
|
|
|
static intptr_t GetStdioHandle(intptr_t num);
|
2013-02-07 00:44:55 +00:00
|
|
|
static void Close(intptr_t fd);
|
2013-12-12 15:45:25 +00:00
|
|
|
static bool GetNoDelay(intptr_t fd, bool* enabled);
|
2013-03-14 12:46:54 +00:00
|
|
|
static bool SetNoDelay(intptr_t fd, bool enabled);
|
2013-12-12 15:45:25 +00:00
|
|
|
static bool GetMulticastLoop(intptr_t fd, intptr_t protocol, bool* enabled);
|
|
|
|
static bool SetMulticastLoop(intptr_t fd, intptr_t protocol, bool enabled);
|
|
|
|
static bool GetMulticastHops(intptr_t fd, intptr_t protocol, int* value);
|
|
|
|
static bool SetMulticastHops(intptr_t fd, intptr_t protocol, int value);
|
|
|
|
static bool GetBroadcast(intptr_t fd, bool* value);
|
|
|
|
static bool SetBroadcast(intptr_t fd, bool value);
|
2015-02-12 11:39:20 +00:00
|
|
|
static bool JoinMulticast(intptr_t fd,
|
|
|
|
const RawAddr& addr,
|
|
|
|
const RawAddr& interface,
|
|
|
|
int interfaceIndex);
|
|
|
|
static bool LeaveMulticast(intptr_t fd,
|
|
|
|
const RawAddr& addr,
|
|
|
|
const RawAddr& interface,
|
|
|
|
int interfaceIndex);
|
2011-10-05 05:20:07 +00:00
|
|
|
|
2013-06-21 07:58:48 +00:00
|
|
|
// Perform a hostname lookup. Returns a AddressList of SocketAddress's.
|
|
|
|
static AddressList<SocketAddress>* LookupAddress(const char* host,
|
|
|
|
int type,
|
|
|
|
OSError** os_error);
|
2013-12-12 15:45:25 +00:00
|
|
|
|
2015-02-12 11:39:20 +00:00
|
|
|
static bool ReverseLookup(const RawAddr& addr,
|
2013-06-25 11:27:48 +00:00
|
|
|
char* host,
|
|
|
|
intptr_t host_len,
|
|
|
|
OSError** os_error);
|
2013-06-21 07:58:48 +00:00
|
|
|
|
2013-11-20 10:01:22 +00:00
|
|
|
static bool ParseAddress(int type, const char* address, RawAddr* addr);
|
2015-02-12 11:39:20 +00:00
|
|
|
static bool FormatNumericAddress(const RawAddr& addr, char* address, int len);
|
2013-11-20 10:01:22 +00:00
|
|
|
|
2013-06-21 07:58:48 +00:00
|
|
|
// List interfaces. Returns a AddressList of InterfaceSocketAddress's.
|
|
|
|
static AddressList<InterfaceSocketAddress>* ListInterfaces(
|
|
|
|
int type,
|
|
|
|
OSError** os_error);
|
2012-03-19 11:26:41 +00:00
|
|
|
|
2013-09-25 15:03:24 +00:00
|
|
|
static CObject* LookupRequest(const CObjectArray& request);
|
|
|
|
static CObject* ListInterfacesRequest(const CObjectArray& request);
|
|
|
|
static CObject* ReverseLookupRequest(const CObjectArray& request);
|
|
|
|
|
2012-03-19 11:26:41 +00:00
|
|
|
static Dart_Port GetServicePort();
|
|
|
|
|
2013-11-21 15:22:35 +00:00
|
|
|
static void SetSocketIdNativeField(Dart_Handle socket, intptr_t id);
|
|
|
|
static intptr_t GetSocketIdNativeField(Dart_Handle socket);
|
2012-09-21 08:19:01 +00:00
|
|
|
|
2012-03-19 11:26:41 +00:00
|
|
|
private:
|
2011-10-05 05:20:07 +00:00
|
|
|
DISALLOW_ALLOCATION();
|
|
|
|
DISALLOW_IMPLICIT_CONSTRUCTORS(Socket);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class ServerSocket {
|
|
|
|
public:
|
2012-03-23 22:39:27 +00:00
|
|
|
static const intptr_t kTemporaryFailure = -2;
|
|
|
|
|
2011-10-05 05:20:07 +00:00
|
|
|
static intptr_t Accept(intptr_t fd);
|
2012-09-03 14:39:47 +00:00
|
|
|
|
2015-02-12 11:39:20 +00:00
|
|
|
// Creates a socket which is bound and listens. The port to listen on is
|
|
|
|
// specified in the port component of the passed RawAddr structure.
|
|
|
|
//
|
2012-09-03 14:39:47 +00:00
|
|
|
// Returns a positive integer if the call is successful. In case of failure
|
|
|
|
// it returns:
|
|
|
|
//
|
|
|
|
// -1: system error (errno set)
|
|
|
|
// -5: invalid bindAddress
|
2015-02-12 11:39:20 +00:00
|
|
|
static intptr_t CreateBindListen(const RawAddr& addr,
|
2013-05-02 11:23:40 +00:00
|
|
|
intptr_t backlog,
|
|
|
|
bool v6_only = false);
|
2011-10-05 05:20:07 +00:00
|
|
|
|
2014-07-28 11:36:35 +00:00
|
|
|
// Start accepting on a newly created listening socket. If it was unable to
|
|
|
|
// start accepting incoming sockets, the fd is invalidated.
|
|
|
|
static bool StartAccept(intptr_t fd);
|
|
|
|
|
2013-06-21 07:58:48 +00:00
|
|
|
private:
|
2011-10-05 05:20:07 +00:00
|
|
|
DISALLOW_ALLOCATION();
|
|
|
|
DISALLOW_IMPLICIT_CONSTRUCTORS(ServerSocket);
|
|
|
|
};
|
|
|
|
|
2016-03-16 17:01:00 +00:00
|
|
|
|
2015-02-11 10:01:20 +00:00
|
|
|
class ListeningSocketRegistry {
|
|
|
|
private:
|
|
|
|
struct OSSocket {
|
|
|
|
RawAddr address;
|
|
|
|
int port;
|
|
|
|
bool v6_only;
|
|
|
|
bool shared;
|
|
|
|
int ref_count;
|
|
|
|
intptr_t socketfd;
|
|
|
|
|
|
|
|
// Singly linked lists of OSSocket instances which listen on the same port
|
|
|
|
// but on different addresses.
|
|
|
|
OSSocket *next;
|
|
|
|
|
|
|
|
OSSocket(RawAddr address, int port, bool v6_only, bool shared,
|
|
|
|
intptr_t socketfd)
|
|
|
|
: address(address), port(port), v6_only(v6_only), shared(shared),
|
|
|
|
ref_count(0), socketfd(socketfd), next(NULL) {}
|
|
|
|
};
|
|
|
|
|
|
|
|
public:
|
|
|
|
static void Initialize();
|
|
|
|
|
|
|
|
static ListeningSocketRegistry *Instance();
|
|
|
|
|
|
|
|
static void Cleanup();
|
|
|
|
|
|
|
|
|
|
|
|
ListeningSocketRegistry() : mutex_(new Mutex()) {}
|
|
|
|
|
|
|
|
~ListeningSocketRegistry() {
|
|
|
|
delete mutex_;
|
|
|
|
mutex_ = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
// This function should be called from a dart runtime call in order to create
|
|
|
|
// a new (potentially shared) socket.
|
|
|
|
Dart_Handle CreateBindListen(Dart_Handle socket_object,
|
|
|
|
RawAddr addr,
|
|
|
|
intptr_t backlog,
|
|
|
|
bool v6_only,
|
|
|
|
bool shared);
|
|
|
|
|
|
|
|
// This should be called from the event handler for every kCloseEvent it gets
|
|
|
|
// on listening sockets.
|
|
|
|
//
|
|
|
|
// Returns `true` if the last reference has been dropped and the underlying
|
|
|
|
// socket can be closed.
|
|
|
|
//
|
|
|
|
// The caller is responsible for obtaining the mutex first, before calling
|
|
|
|
// this function.
|
|
|
|
bool CloseSafe(intptr_t socketfd);
|
|
|
|
|
|
|
|
Mutex *mutex() { return mutex_; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
OSSocket *findOSSocketWithAddress(OSSocket *current, const RawAddr& addr) {
|
|
|
|
while (current != NULL) {
|
|
|
|
if (SocketAddress::AreAddressesEqual(current->address, addr)) {
|
|
|
|
return current;
|
|
|
|
}
|
|
|
|
current = current->next;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::map<intptr_t, OSSocket*> sockets_by_port_;
|
|
|
|
std::map<intptr_t, OSSocket*> sockets_by_fd_;
|
|
|
|
Mutex *mutex_;
|
|
|
|
|
|
|
|
typedef std::map<intptr_t, OSSocket*>::iterator SocketsIterator;
|
|
|
|
|
|
|
|
private:
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(ListeningSocketRegistry);
|
|
|
|
};
|
|
|
|
|
2013-04-25 14:22:30 +00:00
|
|
|
} // namespace bin
|
|
|
|
} // namespace dart
|
|
|
|
|
2011-10-05 05:20:07 +00:00
|
|
|
#endif // BIN_SOCKET_H_
|