You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
92 lines
3.2 KiB
92 lines
3.2 KiB
// Copyright 2018 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#ifndef PLATFORM_IMPL_UDP_SOCKET_POSIX_H_
|
|
#define PLATFORM_IMPL_UDP_SOCKET_POSIX_H_
|
|
|
|
#include "absl/types/optional.h"
|
|
#include "platform/api/udp_socket.h"
|
|
#include "platform/base/macros.h"
|
|
#include "platform/impl/platform_client_posix.h"
|
|
#include "platform/impl/socket_handle_posix.h"
|
|
#include "util/weak_ptr.h"
|
|
|
|
namespace openscreen {
|
|
|
|
class UdpSocketReaderPosix;
|
|
|
|
// Threading: All public methods must be called on the same thread--the one
|
|
// executing the TaskRunner. All non-public methods, except ReceiveMessage(),
|
|
// are also assumed to be called on that thread.
|
|
class UdpSocketPosix : public UdpSocket {
|
|
public:
|
|
// Creates a new UdpSocketPosix. The provided client and task_runner must
|
|
// exist for the duration of this socket's lifetime.
|
|
UdpSocketPosix(TaskRunner* task_runner,
|
|
Client* client,
|
|
SocketHandle handle,
|
|
const IPEndpoint& local_endpoint,
|
|
PlatformClientPosix* platform_client =
|
|
PlatformClientPosix::GetInstance());
|
|
|
|
~UdpSocketPosix() override;
|
|
|
|
// Implementations of UdpSocket methods.
|
|
bool IsIPv4() const override;
|
|
bool IsIPv6() const override;
|
|
IPEndpoint GetLocalEndpoint() const override;
|
|
void Bind() override;
|
|
void SetMulticastOutboundInterface(NetworkInterfaceIndex ifindex) override;
|
|
void JoinMulticastGroup(const IPAddress& address,
|
|
NetworkInterfaceIndex ifindex) override;
|
|
void SendMessage(const void* data,
|
|
size_t length,
|
|
const IPEndpoint& dest) override;
|
|
void SetDscp(DscpMode state) override;
|
|
|
|
const SocketHandle& GetHandle() const;
|
|
|
|
protected:
|
|
friend class UdpSocketReaderPosix;
|
|
|
|
// Called by UdpSocketReaderPosix to perform a non-blocking read on the socket
|
|
// and then dispatch the packet to this socket's Client. This method is the
|
|
// only one in this class possibly being called from another thread.
|
|
void ReceiveMessage();
|
|
|
|
private:
|
|
// Helper to close the socket if |error| is fatal, in addition to dispatching
|
|
// an Error to the |client_|.
|
|
void OnError(Error::Code error);
|
|
|
|
bool is_closed() const { return handle_.fd < 0; }
|
|
void Close();
|
|
|
|
// Task runner to use for queuing |client_| callbacks.
|
|
TaskRunner* const task_runner_;
|
|
|
|
// Client to use for callbacks. This can be nullptr if the user does not want
|
|
// any callbacks (for example, in the send-only case).
|
|
Client* const client_;
|
|
|
|
// Holds the POSIX file descriptor, or -1 if the socket is closed.
|
|
SocketHandle handle_;
|
|
|
|
// Cached value of current local endpoint. This can change (e.g., when the
|
|
// operating system auto-assigns a free local port when Bind() is called). If
|
|
// the port is zero, getsockname() is called to try to resolve it. Once the
|
|
// port is non-zero, it is assumed never to change again.
|
|
mutable IPEndpoint local_endpoint_;
|
|
|
|
WeakPtrFactory<UdpSocketPosix> weak_factory_{this};
|
|
|
|
PlatformClientPosix* const platform_client_;
|
|
|
|
OSP_DISALLOW_COPY_AND_ASSIGN(UdpSocketPosix);
|
|
};
|
|
|
|
} // namespace openscreen
|
|
|
|
#endif // PLATFORM_IMPL_UDP_SOCKET_POSIX_H_
|