35#ifndef _UTILS_SOCKET_CLIENT_HXX_
36#define _UTILS_SOCKET_CLIENT_HXX_
81 ExecutorBase *mdns_executor, std::unique_ptr<SocketClientParams> params,
82 std::function<
void(
int,
Notifiable *)> connect_callback)
119 typedef std::unique_ptr<struct addrinfo, AddrInfoDeleter>
AddrinfoPtr;
155 "socketclient: sync shutdown isconn %d slp %d rqshut %d mdnsP %d"
156 "mdnsJ %d isShut %d",
192 "socketclient: start shutdown isconn %d slp %d rqshut %d mdnsP %d"
193 "mdnsJ %d isShut %d",
227 static int connect(
const char *host,
int port)
229 return connect(host, integer_to_string(port).c_str());
240 static int connect(
const char *host,
const char* port_str);
259 struct addrinfo *addr,
string *host,
int *port);
276 const char *host,
const char *port_str);
283 auto search =
params_->search_mode();
368 DIE(
"Unexpected action");
399 if (port <= 0 || host.empty())
405 v += integer_to_string(port);
429 params_->set_last(host.c_str(), port);
483 string srv =
params_->mdns_service_name();
484 string host =
params_->mdns_host_name();
506 memset(&hints, 0,
sizeof(hints));
514 ai_ret =
MDNS::lookup(mdns_service.c_str(), &hints, &addr);
516 if (ai_ret != 0 || addr ==
nullptr)
#define STATE(_fn)
Turns a function name into an argument to be supplied to functions expecting a state.
See OSMutexLock in os/OS.hxx.
Lightweight locking class for protecting small critical sections.
This class sends a notification in its destructor.
A BarrierNotifiable allows to create a number of child Notifiable and wait for all of them to finish.
BarrierNotifiable * reset(Notifiable *done)
Resets the barrier. Returns &*this. Asserts that is_done().
A notifiable class that calls a particular function object once when it is invoked,...
This class implements an execution of tasks pulled off an input queue.
virtual void add(Executable *action, unsigned priority=UINT_MAX)=0
Send a message to this Executor's queue.
static int lookup(const char *service, struct addrinfo *hints, struct addrinfo **addr)
Lookup an mDNS name.
An object that can schedule itself on an executor to run.
Collection of related state machines that pend on incoming messages.
@ AUTO_MANUAL
Try mDNS first, then (if it failed) try manual address.
@ MANUAL_ONLY
Try only manual address, never try mDNS lookups.
@ MANUAL_AUTO
Try manual address first, then (if it failed) try mDNS.
@ AUTO_ONLY
Try only mDNS, ignore manual address.
LogMessage
Enum for sending connection status updates to the caller.
@ MDNS_NOT_FOUND
mDNS lookup failed.
@ CONNECT_FAILED_SELF
Connection dropped because target is localhost.
@ MDNS_FOUND
mDNS lookup suceeded.
@ CONNECT_MDNS
Connecting to mDNS target. Arg is host:port.
@ CONNECT_MANUAL
Connecting to manual target. Arg is hostname:port.
@ MDNS_SEARCH
Starting mDNS lookup. Argument: mdns [hostname.]service_name.
@ CONNECT_FAILED_ONESHOT
Attempt to search & connect failed, given up. No arg.
@ CONNECT_RE
Attempting to reconnect. Arg is host:port.
ExecutorBase * mdnsExecutor_
Executor for synchronous (blocking) mDNS lookup calls.
uint8_t requestShutdown_
true if an external agent requested the flow to exit.
static bool local_test(struct addrinfo *addr)
Test if a given address is local.
void prepare_strategy()
Parses the params_ configuration and fills in strategyConfig_.
Attempt
This enum represents individual states of this state flow that we can branch to.
@ FAILED_EXIT
Failed and do not start again (for one-shot mode).
@ CONNECT_MDNS
Connect to mDNS lookup result.
@ RECONNECT
Connect to the reconnect slot.
@ CONNECT_STATIC
Connect to static target.
@ INITIATE_MDNS
Start mDNS lookup.
@ WAIT_RETRY
Attempt complete. Start again.
Action connected()
State that gets called when we have a completed connection in fd_.
ExecutorBase * connectExecutor_
Executor for synchronous (blocking) connect calls. Externally owned.
Action connect_mdns()
Takes the address from the mdns lookup and connects to it if it is valid.
long long startTime_
When the last connection attempt was started.
static AddrinfoPtr string_to_address(const char *host, const char *port_str)
Converts a hostname string (or null) and port number (or service name) to a struct addrinfo.
void reset_params(std::unique_ptr< SocketClientParams > params)
Updates the parameter structure for this socket client.
uint8_t strategyOffset_
What is the next step in the strategy.
Action start_connection()
Main entry point of the connection process.
std::function< void(int, Notifiable *)> callback_
callback to call on connection success
uint8_t mdnsJoin_
true if the main flow is waiting for the mdns lookup to complete.
SocketClient(Service *service, ExecutorBase *connect_executor, ExecutorBase *mdns_executor, std::unique_ptr< SocketClientParams > params, std::function< void(int, Notifiable *)> connect_callback)
Constructor.
void shutdown()
Shutdown the client so that it can be deleted.
static bool address_to_string(struct addrinfo *addr, string *host, int *port)
Converts a struct addrinfo to a dotted-decimal notation IP address.
uint8_t isConnected_
true if we are connected and waiting for a client notification to restart.
Action try_schedule_connect(SocketClientParams::LogMessage log, string host, int port)
Helper function to schedule asynchronous connect on a separate executor.
static int connect(const char *host, int port)
Connects a tcp socket to the specified remote host:port.
Action failed_oneshot()
Last state in the connection sequence, when everything failed, but the caller wanted one shot only.
AddrinfoPtr mdnsAddr_
Holds the results of the mdns lookup. null if failed (or never ran).
std::unique_ptr< struct addrinfo, AddrInfoDeleter > AddrinfoPtr
Custom unique pointer that knows how to delete a struct addrinfo.
std::array< Attempt, 5 > strategyConfig_
Stores the sequence of operations we need to try.
uint8_t mdnsPending_
true if there is a pending mdns lookup operation.
Action wait_and_connect_mdns()
Blocks the flow until mdns lookup is complete, then connects to the resulting address.
void mdns_lookup(string mdns_hostname, string mdns_service)
Synchronous function that runs on the mdns executor.
void start_shutdown()
Request that this client shutdown and exit the other thread.
std::unique_ptr< SocketClientParams > params_
Stores the parameter structure.
Action start_mdns()
State that initiates the mdns lookup asynchronously.
Action next_step()
Execute the next step of the strategy.
StateFlowTimer timer_
Helper for sleeping.
Action connect_complete()
State that gets invoked once the reconnect attempt is complete.
Action wait_retry()
Last state in the connection sequence, when everything failed: sleeps until the timeout specified in ...
void connect_blocking(const string &host, int port)
Called on the connect executor.
static AddrinfoPtr string_to_address(const char *host, int port)
Converts a hostname string and port number to a struct addrinfo.
uint8_t sleeping_
true while we are waiting for the timer.
string to_string(const char *p)
Turns a parameter to a string.
static int connect(const char *host, const char *port_str)
Connects a tcp socket to the specified remote host:port.
~SocketClient()
Destructor.
static int connect(struct addrinfo *addr)
Connects a tcp socket to the specified remote address.
Return type for a state flow callback.
Use this timer class to deliver the timeout notification to a stateflow.
Base class for state machines.
Service * service()
Return a pointer to the service I am bound to.
void notify() override
Wakeup call arrived.
Action exit()
Terminate current StateFlow activity.
void start_flow(Callback c)
Resets the flow to the specified state and starts it.
Action call_immediately(Callback c)
Imediately call the next state upon return.
Action wait_and_call(Callback c)
Wait for resource to become available before proceeding to next state.
void start_absolute(long long expiry_time_nsec)
Starts the timer with an absolute deadline.
void ensure_triggered()
Triggers the timer if it is not expired yet.
#define IPPROTO_TCP
TCP Raw Socket.
#define LOG(level, message...)
Conditionally write a message to the logging output.
static const int VERBOSE
Loglevel that is usually not printed, reporting debugging information.
#define HASSERT(x)
Checks that the value of expression x is true, else terminates the current process.
#define DIE(MSG)
Unconditionally terminates the current process with a message.
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Removes default copy-constructor and assignment added by C++.
void freeaddrinfo(struct addrinfo *ai)
see 'man freeaddrinfo'
long long os_get_time_monotonic(void)
Get the monotonic time since the system started.
#define SEC_TO_NSEC(_sec)
Convert a second value to a nanosecond value.
static void microsleep(uint32_t microseconds)
Sleep a given number of microseconds.
#define SOCK_STREAM
TCP Socket.
#define AF_INET
IPv4 Socket (UDP, TCP, etc...)
Helper structure for creating a unique_ptr for struct addrinfo pointers.
Structure to contain information about address of a service provider.
int ai_socktype
Socket type.
int ai_protocol
Protocol for socket.
int ai_family
Protocol family for socket.