blob: c51eed06411ba7f5687c6c142f1bddf721540bc4 [file] [log] [blame]
// Copyright 2017 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.
#ifndef STARBOARD_SHARED_WIN32_SOCKET_INTERNAL_H_
#define STARBOARD_SHARED_WIN32_SOCKET_INTERNAL_H_
#include <WS2tcpip.h>
#include <winsock2.h>
#include "starboard/common/atomic.h"
#include "starboard/common/socket.h"
#include "starboard/shared/internal_only.h"
#include "starboard/shared/win32/auto_event_handle.h"
#include "starboard/socket_waiter.h"
#include "starboard/types.h"
namespace sbwin32 = starboard::shared::win32;
struct SbSocketPrivate {
enum struct BindTarget {
kUnbound = 0,
kAny = 1,
kOther = 2,
kAccepted = 3,
};
SbSocketPrivate(SbSocketAddressType address_type,
SbSocketProtocol protocol,
SOCKET handle,
BindTarget bound_to)
: address_type(address_type),
protocol(protocol),
socket_handle(handle),
socket_event(WSA_INVALID_EVENT),
writable(0),
error(kSbSocketOk),
waiter(kSbSocketWaiterInvalid),
bound_to(bound_to) {}
~SbSocketPrivate() {}
// The address domain of this socket, IPv4 or IPv6.
SbSocketAddressType address_type;
// The protocol of this socket, UDP or TCP.
SbSocketProtocol protocol;
// The handle for this socket.
SOCKET socket_handle;
// The event related to the socket_handle. Used for SbSocketWaiter.
sbwin32::AutoEventHandle socket_event;
// Set to true between when socket is shown as writable via WSAEventSelect/
// WSAWaitForMultipleEvents and when writing to the socket returns
// fails with WSAEWOULDBLOCK.
//
// Used to work around the fact that WSAEventSelect for FD_WRITE is
// edge-triggered, unlike other events.
//
// See MSDN documentation for WSAEventSelect FD_WRITE for more info.
starboard::atomic_bool writable;
// The last error that occurred on this socket, or kSbSocketOk.
SbSocketError error;
// The waiter this socket is registered with, or kSbSocketWaiterInvalid.
SbSocketWaiter waiter;
BindTarget bound_to;
};
namespace starboard {
namespace shared {
namespace win32 {
const socklen_t kAddressLengthIpv4 = 4;
const socklen_t kAddressLengthIpv6 = 16;
// Translates an last_error from a socket call into an SbSocketError.
SbSocketError TranslateSocketErrorStatus(int error);
// Sets a boolean socket option, doing all appropriate checks.
bool SetBooleanSocketOption(SbSocket socket,
int level,
int option_code,
const char* option_name,
bool value);
// Sets an integer socket option, doing all appropriate checks.
bool SetIntegerSocketOption(SbSocket socket,
int level,
int option_code,
const char* option_name,
int value);
// A helper class for converting back and forth from sockaddrs, ugh.
class SockAddr {
public:
SockAddr() : length(sizeof(storage_)) {}
~SockAddr() {}
// Initializes this SockAddr with the given SbSocketAddress, overwriting
// anything any address previously held.
bool FromSbSocketAddress(const SbSocketAddress* address);
// Initializes the given SbSocketAddress with this SockAddr, which must have
// been previously initialized.
bool ToSbSocketAddress(SbSocketAddress* out_address) const;
// Initializes this SockAddr with |sock_addr|, assuming it is appropriately
// sized for its type.
bool FromSockaddr(const struct sockaddr* sock_addr);
// The sockaddr family. We only support INET and INET6.
u_short family() const { return sockaddr()->sa_family; }
struct sockaddr* sockaddr() {
return reinterpret_cast<struct sockaddr*>(&storage_);
}
const struct sockaddr* sockaddr() const {
return reinterpret_cast<const struct sockaddr*>(&storage_);
}
struct sockaddr_in* sockaddr_in() {
return reinterpret_cast<struct sockaddr_in*>(&storage_);
}
const struct sockaddr_in* sockaddr_in() const {
return reinterpret_cast<const struct sockaddr_in*>(&storage_);
}
struct sockaddr_in6* sockaddr_in6() {
return reinterpret_cast<struct sockaddr_in6*>(&storage_);
}
const struct sockaddr_in6* sockaddr_in6() const {
return reinterpret_cast<const struct sockaddr_in6*>(&storage_);
}
// Public on purpose, because it will be handy to be passed directly by
// reference into other functions.
socklen_t length;
private:
sockaddr_storage storage_;
};
} // namespace win32
} // namespace shared
} // namespace starboard
#endif // STARBOARD_SHARED_WIN32_SOCKET_INTERNAL_H_