Sunshine latest
Self-hosted game stream host for Moonlight.
publish.cpp File Reference

Definitions for publishing services on Linux. More...

#include <thread>
#include "misc.h"
#include "src/logging.h"
#include "src/network.h"
#include "src/nvhttp.h"
#include "src/platform/common.h"
#include "src/utility.h"
Include dependency graph for publish.cpp:

Classes

class  platf::publish::deinit_t
 

Typedefs

typedef char *(* avahi::alternative_service_name_fn) (char *)
 
typedef int(* avahi::client_errno_fn) (Client *)
 
typedef void(* avahi::client_free_fn) (Client *)
 
typedef Client *(* avahi::client_new_fn) (const Poll *poll_api, ClientFlags flags, ClientCallback callback, void *userdata, int *error)
 
using platf::publish::client_t = util::dyn_safe_ptr<avahi::Client, &avahi::client_free>
 
typedef void(* avahi::ClientCallback) (Client *, ClientState, void *userdata)
 
typedef int(* avahi::entry_group_add_service_fn) (EntryGroup *group, IfIndex interface, Protocol protocol, PublishFlags flags, const char *name, const char *type, const char *domain, const char *host, uint16_t port,...)
 
typedef int(* avahi::entry_group_commit_fn) (EntryGroup *)
 
typedef Client *(* avahi::entry_group_get_client_fn) (EntryGroup *)
 
typedef int(* avahi::entry_group_is_empty_fn) (EntryGroup *)
 
typedef EntryGroup *(* avahi::entry_group_new_fn) (Client *, EntryGroupCallback, void *userdata)
 
typedef int(* avahi::entry_group_reset_fn) (EntryGroup *)
 
typedef void(* avahi::EntryGroupCallback) (EntryGroup *g, EntryGroupState state, void *userdata)
 
typedef void(* avahi::free_fn) (void *)
 
using avahi::IfIndex = int
 
using platf::publish::poll_t = util::dyn_safe_ptr<avahi::SimplePoll, &avahi::simple_poll_free>
 
using avahi::Protocol = int
 
template<class T >
using platf::publish::ptr_t = util::safe_ptr<T, free<T>>
 
typedef void(* avahi::simple_poll_free_fn) (SimplePoll *)
 
typedef Poll *(* avahi::simple_poll_get_fn) (SimplePoll *)
 
typedef int(* avahi::simple_poll_loop_fn) (SimplePoll *)
 
typedef SimplePoll *(* avahi::simple_poll_new_fn) ()
 
typedef void(* avahi::simple_poll_quit_fn) (SimplePoll *)
 
typedef char *(* avahi::strdup_fn) (const char *)
 
typedef char *(* avahi::strerror_fn) (int)
 

Enumerations

enum  avahi::ClientFlags { avahi::CLIENT_IGNORE_USER_CONFIG = 1 , avahi::CLIENT_NO_FAIL = 2 }
 
enum  avahi::ClientState {
  avahi::CLIENT_S_REGISTERING = SERVER_REGISTERING , avahi::CLIENT_S_RUNNING = SERVER_RUNNING , avahi::CLIENT_S_COLLISION = SERVER_COLLISION , avahi::CLIENT_FAILURE = 100 ,
  avahi::CLIENT_CONNECTING = 101
}
 
enum  avahi::EntryGroupState {
  avahi::ENTRY_GROUP_UNCOMMITED , avahi::ENTRY_GROUP_REGISTERING , avahi::ENTRY_GROUP_ESTABLISHED , avahi::ENTRY_GROUP_COLLISION ,
  avahi::ENTRY_GROUP_FAILURE
}
 
enum  avahi::err_e {
  avahi::OK = 0 , avahi::ERR_FAILURE = -1 , avahi::ERR_BAD_STATE = -2 , avahi::ERR_INVALID_HOST_NAME = -3 ,
  avahi::ERR_INVALID_DOMAIN_NAME = -4 , avahi::ERR_NO_NETWORK = -5 , avahi::ERR_INVALID_TTL = -6 , avahi::ERR_IS_PATTERN = -7 ,
  avahi::ERR_COLLISION = -8 , avahi::ERR_INVALID_RECORD = -9 , avahi::ERR_INVALID_SERVICE_NAME = -10 , avahi::ERR_INVALID_SERVICE_TYPE = -11 ,
  avahi::ERR_INVALID_PORT = -12 , avahi::ERR_INVALID_KEY = -13 , avahi::ERR_INVALID_ADDRESS = -14 , avahi::ERR_TIMEOUT = -15 ,
  avahi::ERR_TOO_MANY_CLIENTS = -16 , avahi::ERR_TOO_MANY_OBJECTS = -17 , avahi::ERR_TOO_MANY_ENTRIES = -18 , avahi::ERR_OS = -19 ,
  avahi::ERR_ACCESS_DENIED = -20 , avahi::ERR_INVALID_OPERATION = -21 , avahi::ERR_DBUS_ERROR = -22 , avahi::ERR_DISCONNECTED = -23 ,
  avahi::ERR_NO_MEMORY = -24 , avahi::ERR_INVALID_OBJECT = -25 , avahi::ERR_NO_DAEMON = -26 , avahi::ERR_INVALID_INTERFACE = -27 ,
  avahi::ERR_INVALID_PROTOCOL = -28 , avahi::ERR_INVALID_FLAGS = -29 , avahi::ERR_NOT_FOUND = -30 , avahi::ERR_INVALID_CONFIG = -31 ,
  avahi::ERR_VERSION_MISMATCH = -32 , avahi::ERR_INVALID_SERVICE_SUBTYPE = -33 , avahi::ERR_INVALID_PACKET = -34 , avahi::ERR_INVALID_DNS_ERROR = -35 ,
  avahi::ERR_DNS_FORMERR = -36 , avahi::ERR_DNS_SERVFAIL = -37 , avahi::ERR_DNS_NXDOMAIN = -38 , avahi::ERR_DNS_NOTIMP = -39 ,
  avahi::ERR_DNS_REFUSED = -40 , avahi::ERR_DNS_YXDOMAIN = -41 , avahi::ERR_DNS_YXRRSET = -42 , avahi::ERR_DNS_NXRRSET = -43 ,
  avahi::ERR_DNS_NOTAUTH = -44 , avahi::ERR_DNS_NOTZONE = -45 , avahi::ERR_INVALID_RDATA = -46 , avahi::ERR_INVALID_DNS_CLASS = -47 ,
  avahi::ERR_INVALID_DNS_TYPE = -48 , avahi::ERR_NOT_SUPPORTED = -49 , avahi::ERR_NOT_PERMITTED = -50 , avahi::ERR_INVALID_ARGUMENT = -51 ,
  avahi::ERR_IS_EMPTY = -52 , avahi::ERR_NO_CHANGE = -53 , avahi::ERR_MAX = -54
}
 Error codes used by avahi. More...
 
enum  avahi::proto { avahi::PROTO_INET = 0 , avahi::PROTO_INET6 = 1 , avahi::PROTO_UNSPEC = -1 }
 
enum  avahi::PublishFlags {
  avahi::PUBLISH_UNIQUE = 1 , avahi::PUBLISH_NO_PROBE = 2 , avahi::PUBLISH_NO_ANNOUNCE = 4 , avahi::PUBLISH_ALLOW_MULTIPLE = 8 ,
  avahi::PUBLISH_NO_REVERSE = 16 , avahi::PUBLISH_NO_COOKIE = 32 , avahi::PUBLISH_UPDATE = 64 , avahi::PUBLISH_USE_WIDE_AREA = 128 ,
  avahi::PUBLISH_USE_MULTICAST = 256
}
 Flags for publishing functions. More...
 
enum  avahi::ServerState {
  avahi::SERVER_INVALID , avahi::SERVER_REGISTERING , avahi::SERVER_RUNNING , avahi::SERVER_COLLISION ,
  avahi::SERVER_FAILURE
}
 

Functions

void platf::publish::client_callback (avahi::Client *c, avahi::ClientState state, void *)
 
void platf::publish::create_services (avahi::Client *c)
 
void platf::publish::entry_group_callback (avahi::EntryGroup *g, avahi::EntryGroupState state, void *)
 
template<class T >
void platf::publish::free (T *p)
 
int avahi::init_client ()
 
int avahi::init_common ()
 
std::unique_ptr< deinit_tplatf::publish::start ()
 Main entry point for publication of our service on macOS.
 

Variables

alternative_service_name_fn avahi::alternative_service_name
 
client_t platf::publish::client
 
client_errno_fn avahi::client_errno
 
client_free_fn avahi::client_free
 
client_new_fn avahi::client_new
 
entry_group_add_service_fn avahi::entry_group_add_service
 
entry_group_commit_fn avahi::entry_group_commit
 
entry_group_get_client_fn avahi::entry_group_get_client
 
entry_group_is_empty_fn avahi::entry_group_is_empty
 
entry_group_new_fn avahi::entry_group_new
 
entry_group_reset_fn avahi::entry_group_reset
 
free_fn avahi::free
 
avahi::EntryGroup * platf::publish::group = nullptr
 
constexpr auto avahi::IF_UNSPEC = -1
 
ptr_t< char > platf::publish::name
 
poll_t platf::publish::poll
 
simple_poll_free_fn avahi::simple_poll_free
 
simple_poll_get_fn avahi::simple_poll_get
 
simple_poll_loop_fn avahi::simple_poll_loop
 
simple_poll_new_fn avahi::simple_poll_new
 
simple_poll_quit_fn avahi::simple_poll_quit
 
strdup_fn avahi::strdup
 
strerror_fn avahi::strerror
 

Detailed Description

Definitions for publishing services on Linux.

Note
Adapted from https://www.avahi.org/doxygen/html/client-publish-service_8c-example.html

Enumeration Type Documentation

◆ ClientFlags

Enumerator
CLIENT_IGNORE_USER_CONFIG 

Don't read user configuration.

CLIENT_NO_FAIL 

Don't fail if the daemon is not available when avahi_client_new() is called, instead enter CLIENT_CONNECTING state and wait for the daemon to appear.

◆ ClientState

Enumerator
CLIENT_S_REGISTERING 

Server state: REGISTERING.

CLIENT_S_RUNNING 

Server state: RUNNING.

CLIENT_S_COLLISION 

Server state: COLLISION.

CLIENT_FAILURE 

Some kind of error happened on the client side.

CLIENT_CONNECTING 

We're still connecting. This state is only entered when AVAHI_CLIENT_NO_FAIL has been passed to avahi_client_new() and the daemon is not yet available.

◆ EntryGroupState

Enumerator
ENTRY_GROUP_UNCOMMITED 

The group has not yet been committed, the user must still call avahi_entry_group_commit()

ENTRY_GROUP_REGISTERING 

The entries of the group are currently being registered.

ENTRY_GROUP_ESTABLISHED 

The entries have successfully been established.

ENTRY_GROUP_COLLISION 

A name collision for one of the entries in the group has been detected, the entries have been withdrawn.

ENTRY_GROUP_FAILURE 

Some kind of failure happened, the entries have been withdrawn.

◆ err_e

Error codes used by avahi.

Enumerator
OK 

OK.

ERR_FAILURE 

Generic error code.

ERR_BAD_STATE 

Object was in a bad state.

ERR_INVALID_HOST_NAME 

Invalid host name.

ERR_INVALID_DOMAIN_NAME 

Invalid domain name.

ERR_NO_NETWORK 

No suitable network protocol available.

ERR_INVALID_TTL 

Invalid DNS TTL.

ERR_IS_PATTERN 

RR key is pattern.

ERR_COLLISION 

Name collision.

ERR_INVALID_RECORD 

Invalid RR.

ERR_INVALID_SERVICE_NAME 

Invalid service name.

ERR_INVALID_SERVICE_TYPE 

Invalid service type.

ERR_INVALID_PORT 

Invalid port number.

ERR_INVALID_KEY 

Invalid key.

ERR_INVALID_ADDRESS 

Invalid address.

ERR_TIMEOUT 

Timeout reached.

ERR_TOO_MANY_CLIENTS 

Too many clients.

ERR_TOO_MANY_OBJECTS 

Too many objects.

ERR_TOO_MANY_ENTRIES 

Too many entries.

ERR_OS 

OS error.

ERR_ACCESS_DENIED 

Access denied.

ERR_INVALID_OPERATION 

Invalid operation.

ERR_DBUS_ERROR 

An unexpected D-Bus error occurred.

ERR_DISCONNECTED 

Daemon connection failed.

ERR_NO_MEMORY 

Memory exhausted.

ERR_INVALID_OBJECT 

The object passed to this function was invalid.

ERR_NO_DAEMON 

Daemon not running.

ERR_INVALID_INTERFACE 

Invalid interface.

ERR_INVALID_PROTOCOL 

Invalid protocol.

ERR_INVALID_FLAGS 

Invalid flags.

ERR_NOT_FOUND 

Not found.

ERR_INVALID_CONFIG 

Configuration error.

ERR_VERSION_MISMATCH 

Version mismatch.

ERR_INVALID_SERVICE_SUBTYPE 

Invalid service subtype.

ERR_INVALID_PACKET 

Invalid packet.

ERR_INVALID_DNS_ERROR 

Invalid DNS return code.

ERR_DNS_FORMERR 

DNS Error: Form error.

ERR_DNS_SERVFAIL 

DNS Error: Server Failure.

ERR_DNS_NXDOMAIN 

DNS Error: No such domain.

ERR_DNS_NOTIMP 

DNS Error: Not implemented.

ERR_DNS_REFUSED 

DNS Error: Operation refused.

ERR_DNS_YXDOMAIN 

TODO.

ERR_DNS_YXRRSET 

TODO.

ERR_DNS_NXRRSET 

TODO.

ERR_DNS_NOTAUTH 

DNS Error: Not authorized.

ERR_DNS_NOTZONE 

TODO.

ERR_INVALID_RDATA 

Invalid RDATA.

ERR_INVALID_DNS_CLASS 

Invalid DNS class.

ERR_INVALID_DNS_TYPE 

Invalid DNS type.

ERR_NOT_SUPPORTED 

Not supported.

ERR_NOT_PERMITTED 

Operation not permitted.

ERR_INVALID_ARGUMENT 

Invalid argument.

ERR_IS_EMPTY 

Is empty.

ERR_NO_CHANGE 

The requested operation is invalid because it is redundant.

ERR_MAX 

TODO.

◆ proto

Enumerator
PROTO_INET 

IPv4.

PROTO_INET6 

IPv6.

PROTO_UNSPEC 

Unspecified/all protocol(s)

◆ PublishFlags

Flags for publishing functions.

Enumerator
PUBLISH_UNIQUE 

For raw records: The RRset is intended to be unique.

PUBLISH_NO_PROBE 

For raw records: Though the RRset is intended to be unique no probes shall be sent.

PUBLISH_NO_ANNOUNCE 

For raw records: Do not announce this RR to other hosts.

PUBLISH_ALLOW_MULTIPLE 

For raw records: Allow multiple local records of this type, even if they are intended to be unique.

PUBLISH_NO_REVERSE 

For address records: don't create a reverse (PTR) entry.

PUBLISH_NO_COOKIE 

For service records: do not implicitly add the local service cookie to TXT data.

PUBLISH_UPDATE 

Update existing records instead of adding new ones.

PUBLISH_USE_WIDE_AREA 

Register the record using wide area DNS (i.e. unicast DNS update)

PUBLISH_USE_MULTICAST 

Register the record using multicast DNS.

◆ ServerState

Enumerator
SERVER_INVALID 

Invalid state (initial)

SERVER_REGISTERING 

Host RRs are being registered.

SERVER_RUNNING 

All host RRs have been established.

SERVER_COLLISION 

There is a collision with a host RR. All host RRs have been withdrawn, the user should set a new host name via avahi_server_set_host_name()

SERVER_FAILURE 

Some fatal failure happened, the server is unable to proceed.

Function Documentation

◆ start()

std::unique_ptr<::platf::deinit_t > platf::publish::start ( )

Main entry point for publication of our service on macOS.

This function initiates a connection to the macOS mDNS service and requests to register our Sunshine service. Registration will occur asynchronously (unless it fails immediately, which is probably only possible if the host machine is misconfigured).

Returns
Either nullptr (if the registration fails immediately) or a uniqur_ptr<deinit_t>, which will manage polling for a response from the mDNS service, and then, when deconstructed, will deregister the service.