37#define LOG(kind, ...) GNUNET_log_from (kind, "util-client", __VA_ARGS__)
45#define CONNECT_RETRY_TIMEOUT GNUNET_TIME_relative_multiply ( \
46 GNUNET_TIME_UNIT_SECONDS, 5)
74 const struct sockaddr *
addr;
233 "Failed to establish connection to `%s', no further addresses to try, will try again in %s.\n",
256 int notify_in_flight;
261 pos = (
const char *) cstate->
msg;
262 len = ntohs (cstate->
msg->
size);
265 "message of type %u and size %u trying to send with socket %p (MQ: %p\n",
276 ( (EAGAIN == errno) ||
285 "Error during sending message of type %u: %s\n",
291 "Retrying message of type %u\n",
299 notify_in_flight = (0 == cstate->
msg_off);
304 "rescheduling message of type %u\n",
311 if (notify_in_flight)
316 "sending message of type %u and size %u successful\n",
343 "Received message of type %u and size %u from %s\n",
419 if (NULL != cstate->
sock)
422 "destroying socket: %p\n",
453 if (NULL != cstate->
mq)
491 if (NULL != cstate->
msg)
517 struct sockaddr_un s_un;
525 (0 < strlen (unixpath)))
528 if (strlen (unixpath) >=
sizeof(s_un.sun_path))
531 _ (
"UNIXPATH `%s' too long, maximum length is %llu\n"),
533 (
unsigned long long)
sizeof(s_un.sun_path));
536 _ (
"Using `%s' instead\n"),
538 if (NULL == unixpath)
544 s_un.sun_family = AF_UNIX;
547 sizeof(s_un.sun_path));
548#if HAVE_SOCKADDR_UN_SUN_LEN
549 s_un.sun_len = (u_char)
sizeof(
struct sockaddr_un);
554 if ((NULL != sock) &&
557 (
struct sockaddr *) &s_un,
559 (EINPROGRESS == errno)))
562 "Successfully connected to unixpath `%s'!\n",
611 if ((NULL == cstate->
ap_head) &&
618 "Connection to `%s' succeeded!\n",
639 const struct sockaddr *addr,
658 "Trying to connect using address `%s:%u'\n",
663 ap->
addr = (
const struct sockaddr *) &ap[1];
670 switch (ap->
addr->sa_family)
673 ((
struct sockaddr_in *) ap->
addr)->sin_port = htons (cstate->
port);
677 ((
struct sockaddr_in6 *) ap->
addr)->sin6_port = htons (cstate->
port);
688 if (NULL == ap->
sock)
697 (EINPROGRESS != errno))
730 char *hostname = NULL;
731 unsigned long long port;
734 char *unixpath = NULL;
741 (0 < strlen (unixpath)))
751 _ (
"not a valid filename"));
774 (0 != strlen (hostname)))
798 socks_connect (cstate);
803 if ((0 == (cstate->
attempts++ % 2)) ||
804 (0 == cstate->
port) ||
811 if (NULL != cstate->
sock)
853 if (NULL == cstate->
sock)
856 "message of type %u waiting for socket\n",
907 unsigned long long port;
912 char *unixpath = NULL;
920 if (0 == strlen (unixpath))
925 if (0 == access (unixpath,
942 _ (
"not a valid filename"));
982 struct sockaddr_in v4;
983 struct sockaddr_in6 v6;
986 memset (&v4, 0,
sizeof (v4));
987 memset (&v6, 0,
sizeof (v6));
988 v4.sin_family = AF_INET;
989 v4.sin_port = htons ((uint16_t)
port);
990#if HAVE_SOCKADDR_IN_SUN_LEN
991 v4.sin_len = (u_char)
sizeof(
struct sockaddr_in);
997 sock = socket (AF_INET,
1002 if (0 != bind (sock,
1003 (
struct sockaddr *) &v4,
1009 (void) close (sock);
1018 v6.sin6_family = AF_INET6;
1019 v6.sin6_port = htons ((uint16_t)
port);
1020#if HAVE_SOCKADDR_IN_SUN_LEN
1021 v6.sin6_len = (u_char)
sizeof(
struct sockaddr_in6);
1023 inet_pton (AF_INET6,
1026 sock = socket (AF_INET6,
1031 if (0 != bind (sock,
1032 (
struct sockaddr *) &v6,
1038 (void) close (sock);
1089 (cstate->
port > 65535) ||
1100 _ (
"Need a non-empty hostname for service `%s'.\n"),
struct GNUNET_MQ_MessageHandlers handlers[]
struct GNUNET_MQ_Handle * mq
struct GNUNET_MessageHeader * msg
static void error_handler(void *cls, enum GNUNET_MQ_Error error)
Function called on connection trouble.
static void try_connect_using_address(void *cls, const struct sockaddr *addr, socklen_t addrlen)
Try to establish a connection given the specified address.
static void connect_success_continuation(struct ClientState *cstate)
We've succeeded in establishing a connection.
static void connection_client_cancel_impl(struct GNUNET_MQ_Handle *mq, void *impl_state)
Cancel the currently sent message.
static void connection_client_send_impl(struct GNUNET_MQ_Handle *mq, const struct GNUNET_MessageHeader *msg, void *impl_state)
Implements the transmission functionality of a message queue.
static void start_connect(void *cls)
Try to connect to the service.
static void transmit_ready(void *cls)
We are ready to send a message to the service.
static void connect_probe_continuation(void *cls)
Scheduler let us know that we're either ready to write on the socket OR connect timed out.
static enum GNUNET_GenericReturnValue recv_message(void *cls, const struct GNUNET_MessageHeader *msg)
We have received a full message, pass to the MQ dispatcher.
static void receive_ready(void *cls)
This function is called once we have data ready to read.
static void connection_client_destroy_impl(struct GNUNET_MQ_Handle *mq, void *impl_state)
Implement the destruction of a message queue.
static void cancel_aps(struct ClientState *cstate)
Cancel all remaining connect attempts.
static void connect_fail_continuation(struct ClientState *cstate)
We've failed for good to establish a connection (timeout or no more addresses to try).
static int test_service_configuration(const char *service_name, const struct GNUNET_CONFIGURATION_Handle *cfg)
Test whether the configuration has proper values for connection (UNIXPATH || (PORT && HOSTNAME)).
static struct GNUNET_NETWORK_Handle * try_unixpath(const char *service_name, const struct GNUNET_CONFIGURATION_Handle *cfg)
Try connecting to the server using UNIX domain sockets.
#define CONNECT_RETRY_TIMEOUT
Timeout we use on TCP connect before trying another result from the DNS resolver.
static int ret
Final status code.
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
static uint16_t port
Port number.
static char * service_name
Option -s: service name (hash to get service descriptor)
Constants for network protocols.
Functions related to doing DNS lookups.
SOCKS proxy for connections.
struct GNUNET_MQ_Handle * GNUNET_CLIENT_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *service_name, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *error_handler_cls)
Create a message queue to connect to a GNUnet service.
enum GNUNET_GenericReturnValue GNUNET_CLIENT_test(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *service_name)
Test if the port or UNIXPATH of the given service_name is in use and thus (most likely) the respectiv...
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_have_value(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Test if we have a value for a particular option.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_GenericReturnValue
Named constants for return values.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
const char * GNUNET_a2s(const struct sockaddr *addr, socklen_t addrlen)
Convert a "struct sockaddr*" (IPv4 or IPv6 address) to a string (for printing debug messages).
void GNUNET_log_config_invalid(enum GNUNET_ErrorType kind, const char *section, const char *option, const char *required)
Log error message about invalid configuration option value.
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_MQ_inject_error(struct GNUNET_MQ_Handle *mq, enum GNUNET_MQ_Error error)
Call the error handler of a message queue with the given error code.
struct GNUNET_MQ_Handle * GNUNET_MQ_queue_for_callbacks(GNUNET_MQ_SendImpl send, GNUNET_MQ_DestroyImpl destroy, GNUNET_MQ_CancelImpl cancel, void *impl_state, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *cls)
Create a message queue for the specified handlers.
void(* GNUNET_MQ_ErrorHandler)(void *cls, enum GNUNET_MQ_Error error)
Generic error handler, called with the appropriate error code and the same closure specified at the c...
void GNUNET_MQ_impl_send_continue(struct GNUNET_MQ_Handle *mq)
Call the send implementation for the next queued message, if any.
void GNUNET_MQ_inject_message(struct GNUNET_MQ_Handle *mq, const struct GNUNET_MessageHeader *mh)
Call the message message handler that was registered for the type of the given message in the given m...
void GNUNET_MQ_impl_send_in_flight(struct GNUNET_MQ_Handle *mq)
Call the send notification for the current message, but do not try to send the next message until #gn...
@ GNUNET_MQ_ERROR_READ
Failed to read message from the network.
@ GNUNET_MQ_ERROR_WRITE
FIXME: document!
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_getsockopt(const struct GNUNET_NETWORK_Handle *desc, int level, int optname, void *optval, socklen_t *optlen)
Get socket options.
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
char * GNUNET_NETWORK_shorten_unixpath(char *unixpath)
Given a unixpath that is too long (larger than UNIX_PATH_MAX), shorten it to an acceptable length whi...
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_connect(const struct GNUNET_NETWORK_Handle *desc, const struct sockaddr *address, socklen_t address_len)
Connect a socket to some remote address.
ssize_t GNUNET_NETWORK_socket_send(const struct GNUNET_NETWORK_Handle *desc, const void *buffer, size_t length)
Send data (always non-blocking).
struct GNUNET_RESOLVER_RequestHandle * GNUNET_RESOLVER_ip_get(const char *hostname, int af, struct GNUNET_TIME_Relative timeout, GNUNET_RESOLVER_AddressCallback callback, void *callback_cls)
Convert a string to one or more IP addresses.
void GNUNET_RESOLVER_request_cancel(struct GNUNET_RESOLVER_RequestHandle *rh)
Cancel a request that is still pending with the resolver.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_read_net(struct GNUNET_TIME_Relative delay, struct GNUNET_NETWORK_Handle *rfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when the specified file descriptor is ready f...
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_write_net(struct GNUNET_TIME_Relative delay, struct GNUNET_NETWORK_Handle *wfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when the specified file descriptor is ready f...
const struct GNUNET_SCHEDULER_TaskContext * GNUNET_SCHEDULER_get_task_context(void)
Obtain the reasoning why the current task was started.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
@ GNUNET_SCHEDULER_REASON_WRITE_READY
The writing socket is ready.
struct GNUNET_MessageStreamTokenizer * GNUNET_MST_create(GNUNET_MessageTokenizerCallback cb, void *cb_cls)
Create a message stream tokenizer.
void GNUNET_MST_destroy(struct GNUNET_MessageStreamTokenizer *mst)
Destroys a tokenizer.
enum GNUNET_GenericReturnValue GNUNET_MST_read(struct GNUNET_MessageStreamTokenizer *mst, struct GNUNET_NETWORK_Handle *sock, int purge, int one_shot)
Add incoming data to the receive buffer and call the callback for all complete messages.
int GNUNET_SOCKS_check_service(const char *service_name, const struct GNUNET_CONFIGURATION_Handle *cfg)
Check if a SOCKS proxy is required by a service.
size_t GNUNET_strlcpy(char *dst, const char *src, size_t n)
Like strlcpy but portable.
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
static struct GNUNET_SCHEDULER_TaskContext tc
Task context of the current task.
During connect, we try multiple possible IP addresses to find out which one might work.
const struct sockaddr * addr
The address; do not free (allocated at the end of this struct).
socklen_t addrlen
Length of addr.
struct GNUNET_SCHEDULER_Task * task
Task waiting for the connection to finish connecting.
struct AddressProbe * next
This is a linked list.
struct ClientState * cstate
Connection for which we are probing.
struct AddressProbe * prev
This is a doubly-linked list.
struct GNUNET_NETWORK_Handle * sock
Underlying OS's socket.
State we keep per client.
struct GNUNET_MQ_Handle * mq
MQ to talk to client.
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
struct GNUNET_MessageStreamTokenizer * mst
Tokenizer for inbound messages.
int in_destroy
Are we supposed to die? GNUNET_SYSERR if destruction must be deferred, GNUNET_NO by default,...
unsigned int attempts
How often have we tried to connect?
const struct GNUNET_MessageHeader * msg
Next message to transmit to the service.
size_t msg_off
Offset in the message where we are for transmission.
struct GNUNET_SCHEDULER_Task * retry_task
Task for trying to connect to the service.
struct GNUNET_TIME_Relative back_off
Current value for our incremental back-off (for connect re-tries).
struct GNUNET_SCHEDULER_Task * send_task
Task for sending messages to the service.
char * hostname
Hostname, if any.
struct GNUNET_RESOLVER_RequestHandle * dns_active
Handle to a pending DNS lookup request, NULL if DNS is finished.
unsigned long long port
TCP port (0 for disabled).
struct GNUNET_TIME_Absolute receive_timeout
Timeout for receiving a response (absolute time).
struct GNUNET_SCHEDULER_Task * recv_task
Task for sending messages to the service.
struct GNUNET_NETWORK_Handle * sock
The connection handle, NULL if not live.
char * service_name
Name of the service we interact with.
struct AddressProbe * ap_tail
Linked list of sockets we are currently trying out (during connect).
struct AddressProbe * ap_head
Linked list of sockets we are currently trying out (during connect).
Handle to a message queue.
void * error_handler_cls
Closure for the error handler.
Message handler for a specific message type.
Handle to a message stream tokenizer.
Handle to a request given to the resolver.
Context information passed to each scheduler task.
enum GNUNET_SCHEDULER_Reason reason
Reason why the task is run now.
Entry in list of pending tasks.
Time for absolute times used by GNUnet, in microseconds.
Time for relative time used by GNUnet, in microseconds.