int aeron_driver_receiver_add_pending_setup( aeron_driver_receiver_t *receiver, aeron_receive_channel_endpoint_t *endpoint, int32_t session_id, int32_t stream_id, struct sockaddr_storage *control_addr) { int ensure_capacity_result = 0; AERON_ARRAY_ENSURE_CAPACITY( ensure_capacity_result, receiver->pending_setups, aeron_driver_receiver_pending_setup_entry_t); if (ensure_capacity_result < 0) { int errcode = errno; aeron_set_err(errcode, "receiver add_pending_setup: %s", strerror(errcode)); return ensure_capacity_result; } aeron_driver_receiver_pending_setup_entry_t *entry = &receiver->pending_setups.array[receiver->pending_setups.length++]; entry->endpoint = endpoint; entry->session_id = session_id; entry->stream_id = stream_id; entry->time_of_status_message_ns = receiver->context->nano_clock(); entry->is_periodic = false; if (NULL != control_addr) { memcpy(&entry->control_addr, control_addr, sizeof(entry->control_addr)); entry->is_periodic = true; } return ensure_capacity_result; }
int aeron_distinct_error_log_init( aeron_distinct_error_log_t *log, uint8_t *buffer, size_t buffer_size, aeron_clock_func_t clock, aeron_resource_linger_func_t linger, void *clientd) { if (NULL == log || NULL == clock || NULL == linger) { aeron_set_err(EINVAL, "%s", "invalid argument"); return -1; } if (aeron_alloc((void **)&log->observations_pimpl, sizeof(aeron_distinct_error_log_observations_pimpl_t)) < 0) { return -1; } log->buffer = buffer; log->buffer_capacity = buffer_size; log->clock = clock; log->linger_resource = linger; log->linger_resource_clientd = clientd; log->next_offset = 0; atomic_store(&log->observations_pimpl->num_observations, 0); atomic_store(&log->observations_pimpl->observations, NULL); pthread_mutex_init(&log->mutex, NULL); return 0; }
int aeron_counters_manager_init( volatile aeron_counters_manager_t *manager, uint8_t *metadata_buffer, size_t metadata_length, uint8_t *values_buffer, size_t values_length, aeron_counters_manager_clock_func_t clock_func, int64_t free_to_reuse_timeout_ms) { int result = -1; if (AERON_COUNTERS_MANAGER_IS_VALID_BUFFER_SIZES(metadata_length, values_length)) { manager->metadata = metadata_buffer; manager->metadata_length = metadata_length; manager->values = values_buffer; manager->values_length = values_length; manager->id_high_water_mark = -1; manager->free_list_index = -1; manager->free_list_length = 2; manager->clock_func = clock_func; manager->free_to_reuse_timeout_ms = free_to_reuse_timeout_ms; result = aeron_alloc((void **)&manager->free_list, sizeof(int32_t) * manager->free_list_length); } else { aeron_set_err(EINVAL, "%s:%d: %s", __FILE__, __LINE__, strerror(EINVAL)); } return result; }
int aeron_udp_transport_poller_add(aeron_udp_transport_poller_t *poller, aeron_udp_channel_transport_t *transport) { int ensure_capacity_result = 0; size_t old_capacity = poller->transports.capacity, index = poller->transports.length; AERON_ARRAY_ENSURE_CAPACITY(ensure_capacity_result, poller->transports, aeron_udp_channel_transport_entry_t); if (ensure_capacity_result < 0) { return -1; } poller->transports.array[index].transport = transport; #if defined(HAVE_EPOLL) size_t new_capacity = poller->transports.capacity; if (new_capacity > old_capacity) { if (aeron_array_ensure_capacity((uint8_t **)&poller->epoll_events, sizeof(struct epoll_event), old_capacity, new_capacity) < 0) { return -1; } } struct epoll_event event; event.data.fd = transport->fd; event.data.ptr = transport; event.events = EPOLLIN; int result = epoll_ctl(poller->epoll_fd, EPOLL_CTL_ADD, transport->fd, &event); if (result < 0) { aeron_set_err(errno, "epoll_ctl(EPOLL_CTL_ADD): %s", strerror(errno)); return -1; } #elif defined(HAVE_POLL) size_t new_capacity = poller->transports.capacity; if (new_capacity > old_capacity) { if (aeron_array_ensure_capacity((uint8_t **)&poller->pollfds, sizeof(struct pollfd), old_capacity, new_capacity) < 0) { return -1; } } poller->pollfds[index].fd = transport->fd; poller->pollfds[index].events = POLLIN; poller->pollfds[index].revents = 0; #endif poller->transports.length++; return 0; }
int aeron_driver_receiver_init( aeron_driver_receiver_t *receiver, aeron_driver_context_t *context, aeron_system_counters_t *system_counters, aeron_distinct_error_log_t *error_log) { if (aeron_udp_transport_poller_init(&receiver->poller) < 0) { return -1; } for (size_t i = 0; i < AERON_DRIVER_RECEIVER_NUM_RECV_BUFFERS; i++) { size_t offset = 0; if (aeron_alloc_aligned( (void **)&receiver->recv_buffers.buffers[i], &offset, AERON_DRIVER_RECEIVER_MAX_UDP_PACKET_LENGTH, AERON_CACHE_LINE_LENGTH * 2) < 0) { int errcode = errno; aeron_set_err(errcode, "%s:%d: %s", __FILE__, __LINE__, strerror(errcode)); return -1; } receiver->recv_buffers.iov[i].iov_base = receiver->recv_buffers.buffers[i] + offset; receiver->recv_buffers.iov[i].iov_len = AERON_DRIVER_RECEIVER_MAX_UDP_PACKET_LENGTH; } receiver->images.array = NULL; receiver->images.length = 0; receiver->images.capacity = 0; receiver->pending_setups.array = NULL; receiver->pending_setups.length = 0; receiver->pending_setups.capacity = 0; receiver->context = context; receiver->error_log = error_log; receiver->receiver_proxy.command_queue = &context->receiver_command_queue; receiver->receiver_proxy.fail_counter = aeron_system_counter_addr( system_counters, AERON_SYSTEM_COUNTER_RECEIVER_PROXY_FAILS); receiver->receiver_proxy.threading_mode = context->threading_mode; receiver->receiver_proxy.receiver = receiver; receiver->errors_counter = aeron_system_counter_addr(system_counters, AERON_SYSTEM_COUNTER_ERRORS); receiver->invalid_frames_counter = aeron_system_counter_addr(system_counters, AERON_SYSTEM_COUNTER_INVALID_PACKETS); receiver->total_bytes_received_counter = aeron_system_counter_addr( system_counters, AERON_SYSTEM_COUNTER_BYTES_RECEIVED); return 0; }
int aeron_udp_transport_poller_remove(aeron_udp_transport_poller_t *poller, aeron_udp_channel_transport_t *transport) { int index = -1, last_index = (int)poller->transports.length - 1; for (int i = last_index; i >= 0; i--) { if (poller->transports.array[i].transport == transport) { index = i; break; } } if (index >= 0) { aeron_array_fast_unordered_remove( (uint8_t *)poller->transports.array, sizeof(aeron_udp_channel_transport_entry_t), (size_t)index, (size_t)last_index); #if defined(HAVE_EPOLL) aeron_array_fast_unordered_remove( (uint8_t *)poller->epoll_events, sizeof(struct epoll_event), (size_t)index, (size_t)last_index); struct epoll_event event; event.data.fd = transport->fd; event.data.ptr = transport; event.events = EPOLLIN; int result = epoll_ctl(poller->epoll_fd, EPOLL_CTL_DEL, transport->fd, &event); if (result < 0) { aeron_set_err(errno, "epoll_ctl(EPOLL_CTL_DEL): %s", strerror(errno)); return -1; } #elif defined(HAVE_POLL) aeron_array_fast_unordered_remove( (uint8_t *)poller->pollfds, sizeof(struct pollfd), (size_t)index, (size_t)last_index); #endif poller->transports.length--; } return 0; }
int aeron_udp_channel_transport_sendmsg( aeron_udp_channel_transport_t *transport, struct msghdr *message) { ssize_t sendmsg_result = sendmsg(transport->fd, message, 0); if (sendmsg_result < 0) { aeron_set_err(errno, "sendmsg: %s", strerror(errno)); return -1; } return (int)sendmsg_result; }
int32_t aeron_counters_manager_allocate( volatile aeron_counters_manager_t *manager, int32_t type_id, const uint8_t *key, size_t key_length, const char *label, size_t label_length) { const int32_t counter_id = aeron_counters_manager_next_counter_id(manager); if ((counter_id * AERON_COUNTERS_MANAGER_VALUE_LENGTH) + AERON_COUNTERS_MANAGER_VALUE_LENGTH > manager->values_length) { aeron_set_err(EINVAL, "%s:%d: %s", __FILE__, __LINE__, strerror(EINVAL)); return -1; } if ((counter_id * AERON_COUNTERS_MANAGER_METADATA_LENGTH) + AERON_COUNTERS_MANAGER_METADATA_LENGTH > manager->metadata_length) { aeron_set_err(EINVAL, "%s:%d: %s", __FILE__, __LINE__, strerror(EINVAL)); return -1; } aeron_counter_metadata_descriptor_t *metadata = (aeron_counter_metadata_descriptor_t *)(manager->metadata + (counter_id * AERON_COUNTERS_MANAGER_METADATA_LENGTH)); metadata->type_id = type_id; metadata->free_to_reuse_deadline = AERON_COUNTER_NOT_FREE_TO_REUSE; if (NULL != key && key_length > 0) { memcpy(metadata->key, key, fmin(sizeof(metadata->key), key_length)); } memcpy(metadata->label, label, fmin(sizeof(metadata->label), label_length)); metadata->label_length = (int32_t)label_length; AERON_PUT_ORDERED(metadata->state, AERON_COUNTER_RECORD_ALLOCATED); return counter_id; }
aeron_congestion_control_strategy_supplier_func_t aeron_congestion_control_strategy_supplier_load( const char *strategy_name) { aeron_congestion_control_strategy_supplier_func_t func = NULL; if ((func = (aeron_congestion_control_strategy_supplier_func_t)dlsym(RTLD_DEFAULT, strategy_name)) == NULL) { aeron_set_err(EINVAL, "could not find congestion control strategy %s: dlsym - %s", strategy_name, dlerror()); return NULL; } return func; }
int aeron_udp_channel_transport_get_so_rcvbuf(aeron_udp_channel_transport_t *transport, size_t *so_rcvbuf) { socklen_t len = sizeof(size_t); if (getsockopt(transport->fd, SOL_SOCKET, SO_RCVBUF, so_rcvbuf, &len) < 0) { int errcode = errno; aeron_set_err(errcode, "getsockopt(SO_RCVBUF) %s:%d: %s", __FILE__, __LINE__, strerror(errcode)); return -1; } return 0; }
aeron_flow_control_strategy_supplier_func_t aeron_flow_control_strategy_supplier_load(const char *strategy_name) { aeron_flow_control_strategy_supplier_func_t func = NULL; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpedantic" if ((func = (aeron_flow_control_strategy_supplier_func_t)aeron_dlsym(RTLD_DEFAULT, strategy_name)) == NULL) { aeron_set_err(EINVAL, "could not find flow control strategy %s: dlsym - %s", strategy_name, aeron_dlerror()); return NULL; } #pragma GCC diagnostic pop return func; }
int aeron_multicast_control_address(struct sockaddr_storage *data_addr, struct sockaddr_storage *control_addr) { if (AF_INET6 == data_addr->ss_family) { return aeron_ipv6_multicast_control_address( (struct sockaddr_in6 *)data_addr, (struct sockaddr_in6 *)control_addr); } else if (AF_INET == data_addr->ss_family) { return aeron_ipv4_multicast_control_address( (struct sockaddr_in *)data_addr, (struct sockaddr_in *)control_addr); } aeron_set_err(EINVAL, "unknown address family: %d", data_addr->ss_family); return -1; }
int aeron_distinct_error_log_record( aeron_distinct_error_log_t *log, int error_code, const char *description, const char *message) { int64_t timestamp = 0; aeron_distinct_observation_t *observation = NULL; if (NULL == log) { aeron_set_err(EINVAL, "%s", "invalid argument"); return -1; } timestamp = log->clock(); size_t num_observations = atomic_load(&log->observations_pimpl->num_observations); aeron_distinct_observation_t *observations = atomic_load(&log->observations_pimpl->observations); if ((observation = aeron_distinct_error_log_find_observation( observations, num_observations, error_code, description)) == NULL) { pthread_mutex_lock(&log->mutex); observation = aeron_distinct_error_log_new_observation( log, num_observations, timestamp, error_code, description, message); pthread_mutex_unlock(&log->mutex); if (NULL == observation) { char buffer[AERON_MAX_PATH]; aeron_format_date(buffer, sizeof(buffer), timestamp); fprintf(stderr, "%s - unrecordable error %d: %s %s\n", buffer, error_code, description, message); errno = ENOMEM; return -1; } } aeron_error_log_entry_t *entry = (aeron_error_log_entry_t *)(log->buffer + observation->offset); int32_t dest; AERON_GET_AND_ADD_INT32(dest, entry->observation_count, 1); AERON_PUT_ORDERED(entry->last_observation_timestamp, timestamp); return 0; }
int aeron_uri_linger_timeout_param(aeron_uri_params_t *uri_params, aeron_uri_publication_params_t *params) { const char *value_str; if ((value_str = aeron_uri_find_param_value(uri_params, AERON_URI_LINGER_TIMEOUT_KEY)) != NULL) { uint64_t value; if (-1 == aeron_parse_duration_ns(value_str, &value)) { aeron_set_err(EINVAL, "could not parse %s in URI", AERON_URI_LINGER_TIMEOUT_KEY); return -1; } params->linger_timeout_ns = value; } return 0; }
int aeron_uri_parse(size_t uri_length, const char *uri, aeron_uri_t *params) { size_t copy_length = sizeof(params->mutable_uri) - 1; copy_length = uri_length < copy_length ? uri_length : copy_length; memcpy(params->mutable_uri, uri, copy_length); params->mutable_uri[copy_length] = '\0'; char *ptr = params->mutable_uri; params->type = AERON_URI_UNKNOWN; if (strncmp(ptr, AERON_URI_SCHEME, strlen(AERON_URI_SCHEME)) == 0) { ptr += strlen(AERON_URI_SCHEME); if (strncmp(ptr, AERON_URI_UDP_TRANSPORT, strlen(AERON_URI_UDP_TRANSPORT)) == 0) { ptr += strlen(AERON_URI_UDP_TRANSPORT); if (*ptr++ == '?') { params->type = AERON_URI_UDP; return aeron_udp_uri_parse(ptr, ¶ms->params.udp); } } else if (strncmp(ptr, AERON_URI_IPC_TRANSPORT, strlen(AERON_URI_IPC_TRANSPORT)) == 0) { ptr += strlen(AERON_URI_IPC_TRANSPORT); if (*ptr == '?') { ptr++; } params->type = AERON_URI_IPC; return aeron_ipc_uri_parse(ptr, ¶ms->params.ipc); } } aeron_set_err(EINVAL, "invalid URI scheme or transport: %s", uri); return -1; }
int aeron_udp_transport_poller_init(aeron_udp_transport_poller_t *poller) { poller->transports.array = NULL; poller->transports.length = 0; poller->transports.capacity = 0; #if defined(HAVE_EPOLL) if ((poller->epoll_fd = epoll_create1(0)) < 0) { aeron_set_err(errno, "epoll_create1: %s", strerror(errno)); return -1; } poller->epoll_events = NULL; #elif defined(HAVE_POLL) poller->pollfds = NULL; #endif return 0; }
int aeron_ipv6_multicast_control_address(struct sockaddr_in6 *data_addr, struct sockaddr_in6 *control_addr) { uint8_t bytes[sizeof(struct in6_addr)]; size_t addr_len = sizeof(struct in6_addr); size_t last_byte_index = addr_len - 1; memcpy(bytes, &(data_addr->sin6_addr), addr_len); if ((bytes[last_byte_index] & 0x1) == 0) { aeron_set_err(EINVAL, "%s", "Multicast data address must be odd"); return -1; } bytes[last_byte_index]++; control_addr->sin6_family = data_addr->sin6_family; memcpy(&(control_addr->sin6_addr), bytes, addr_len); control_addr->sin6_port = data_addr->sin6_port; return 0; }
int aeron_parse_get_line(char *str, size_t max_length, const char *buffer) { size_t i; for (i = 0; i < max_length - 1; i++) { str[i] = buffer[i]; if ('\0' == buffer[i]) { return 0; } if ('\n' == buffer[i]) { str[i + 1] = '\0'; return i + 1; } } aeron_set_err(EINVAL, "line too long: %" PRIu64 "/%" PRIu64, (uint64_t)i, (uint64_t)max_length); return -1; }
int aeron_uri_get_mtu_length_param(aeron_uri_params_t *uri_params, aeron_uri_publication_params_t *params) { const char *value_str; if ((value_str = aeron_uri_find_param_value(uri_params, AERON_URI_MTU_LENGTH_KEY)) != NULL) { uint64_t value; if (-1 == aeron_parse_size64(value_str, &value)) { aeron_set_err(EINVAL, "could not parse %s in URI", AERON_URI_MTU_LENGTH_KEY); return -1; } if (aeron_driver_context_validate_mtu_length(value) < 0) { return -1; } params->mtu_length = value; } return 0; }
aeron_driver_termination_validator_func_t aeron_driver_termination_validator_load(const char *validator_name) { aeron_driver_termination_validator_func_t func = NULL; if (strncmp(validator_name, "allow", sizeof("allow")) == 0) { return aeron_driver_termination_validator_load("aeron_driver_termination_validator_default_allow"); } else if (strncmp(validator_name, "deny", sizeof("deny")) == 0) { return aeron_driver_termination_validator_load("aeron_driver_termination_validator_default_deny"); } else { if ((func = (aeron_driver_termination_validator_func_t) aeron_dlsym(RTLD_DEFAULT, validator_name)) == NULL) { aeron_set_err( EINVAL, "could not find termination validator %s: dlsym - %s", validator_name, aeron_dlerror()); return NULL; } } return func; }
int aeron_uri_get_term_length_param(aeron_uri_params_t *uri_params, aeron_uri_publication_params_t *params) { const char *value_str; if ((value_str = aeron_uri_find_param_value(uri_params, AERON_URI_TERM_LENGTH_KEY)) != NULL) { uint64_t value; if (-1 == aeron_parse_size64(value_str, &value)) { aeron_set_err(EINVAL, "could not parse %s in URI", AERON_URI_TERM_LENGTH_KEY); return -1; } if (aeron_logbuffer_check_term_length(value) < 0) { return -1; } params->term_length = value; } return 0; }
int aeron_publication_image_create( aeron_publication_image_t **image, aeron_receive_channel_endpoint_t *endpoint, aeron_driver_context_t *context, int64_t correlation_id, int32_t session_id, int32_t stream_id, int32_t initial_term_id, int32_t active_term_id, int32_t initial_term_offset, aeron_position_t *rcv_hwm_position, aeron_position_t *rcv_pos_position, aeron_congestion_control_strategy_t *congestion_control, struct sockaddr_storage *control_address, struct sockaddr_storage *source_address, int32_t term_buffer_length, int32_t sender_mtu_length, aeron_loss_reporter_t *loss_reporter, bool is_reliable, bool is_sparse, aeron_system_counters_t *system_counters) { char path[AERON_MAX_PATH]; int path_length = aeron_publication_image_location( path, sizeof(path), context->aeron_dir, endpoint->conductor_fields.udp_channel->canonical_form, session_id, stream_id, correlation_id); aeron_publication_image_t *_image = NULL; const uint64_t usable_fs_space = context->usable_fs_space_func(context->aeron_dir); const uint64_t log_length = aeron_logbuffer_compute_log_length((uint64_t)term_buffer_length, context->file_page_size); bool is_multicast = endpoint->conductor_fields.udp_channel->multicast; int64_t now_ns = context->nano_clock(); *image = NULL; if (usable_fs_space < log_length) { aeron_set_err( ENOSPC, "Insufficient usable storage for new log of length=%" PRId64 " in %s", log_length, context->aeron_dir); return -1; } if (aeron_alloc((void **)&_image, sizeof(aeron_publication_image_t)) < 0) { aeron_set_err(ENOMEM, "%s", "Could not allocate publication image"); return -1; } _image->log_file_name = NULL; if (aeron_alloc((void **)(&_image->log_file_name), (size_t)path_length + 1) < 0) { aeron_free(_image); aeron_set_err(ENOMEM, "%s", "Could not allocate publication image log_file_name"); return -1; } if (aeron_loss_detector_init( &_image->loss_detector, is_multicast, is_multicast ? aeron_loss_detector_nak_multicast_delay_generator : aeron_loss_detector_nak_unicast_delay_generator, aeron_publication_image_on_gap_detected, _image) < 0) { aeron_free(_image); aeron_set_err(ENOMEM, "%s", "Could not init publication image loss detector"); return -1; } if (context->map_raw_log_func( &_image->mapped_raw_log, path, is_sparse, (uint64_t)term_buffer_length, context->file_page_size) < 0) { aeron_free(_image->log_file_name); aeron_free(_image); aeron_set_err(aeron_errcode(), "error mapping network raw log %s: %s", path, aeron_errmsg()); return -1; } _image->map_raw_log_close_func = context->map_raw_log_close_func; strncpy(_image->log_file_name, path, (size_t)path_length); _image->log_file_name[path_length] = '\0'; _image->log_file_name_length = (size_t)path_length; _image->log_meta_data = (aeron_logbuffer_metadata_t *)(_image->mapped_raw_log.log_meta_data.addr); _image->log_meta_data->initial_term_id = initial_term_id; _image->log_meta_data->mtu_length = sender_mtu_length; _image->log_meta_data->term_length = term_buffer_length; _image->log_meta_data->page_size = (int32_t)context->file_page_size; _image->log_meta_data->correlation_id = correlation_id; _image->log_meta_data->is_connected = 0; _image->log_meta_data->end_of_stream_position = INT64_MAX; aeron_logbuffer_fill_default_header( _image->mapped_raw_log.log_meta_data.addr, session_id, stream_id, initial_term_id); _image->endpoint = endpoint; _image->congestion_control = congestion_control; _image->loss_reporter = loss_reporter; _image->loss_reporter_offset = -1; _image->nano_clock = context->nano_clock; _image->epoch_clock = context->epoch_clock; _image->conductor_fields.subscribable.array = NULL; _image->conductor_fields.subscribable.length = 0; _image->conductor_fields.subscribable.capacity = 0; _image->conductor_fields.subscribable.add_position_hook_func = aeron_driver_subscribable_null_hook; _image->conductor_fields.subscribable.remove_position_hook_func = aeron_driver_subscribable_null_hook; _image->conductor_fields.subscribable.clientd = NULL; _image->conductor_fields.managed_resource.registration_id = correlation_id; _image->conductor_fields.managed_resource.clientd = _image; _image->conductor_fields.managed_resource.incref = NULL; _image->conductor_fields.managed_resource.decref = NULL; _image->conductor_fields.is_reliable = is_reliable; _image->conductor_fields.status = AERON_PUBLICATION_IMAGE_STATUS_ACTIVE; _image->conductor_fields.liveness_timeout_ns = context->image_liveness_timeout_ns; _image->session_id = session_id; _image->stream_id = stream_id; _image->rcv_hwm_position.counter_id = rcv_hwm_position->counter_id; _image->rcv_hwm_position.value_addr = rcv_hwm_position->value_addr; _image->rcv_pos_position.counter_id = rcv_pos_position->counter_id; _image->rcv_pos_position.value_addr = rcv_pos_position->value_addr; _image->initial_term_id = initial_term_id; _image->term_length_mask = (int32_t)term_buffer_length - 1; _image->position_bits_to_shift = (size_t)aeron_number_of_trailing_zeroes((int32_t)term_buffer_length); _image->mtu_length = sender_mtu_length; _image->last_sm_change_number = -1; _image->last_loss_change_number = -1; _image->is_end_of_stream = false; memcpy(&_image->control_address, control_address, sizeof(_image->control_address)); memcpy(&_image->source_address, source_address, sizeof(_image->source_address)); _image->heartbeats_received_counter = aeron_system_counter_addr( system_counters, AERON_SYSTEM_COUNTER_HEARTBEATS_RECEIVED); _image->flow_control_under_runs_counter = aeron_system_counter_addr( system_counters, AERON_SYSTEM_COUNTER_FLOW_CONTROL_UNDER_RUNS); _image->flow_control_over_runs_counter = aeron_system_counter_addr( system_counters, AERON_SYSTEM_COUNTER_FLOW_CONTROL_OVER_RUNS); _image->status_messages_sent_counter = aeron_system_counter_addr( system_counters, AERON_SYSTEM_COUNTER_STATUS_MESSAGES_SENT); _image->nak_messages_sent_counter = aeron_system_counter_addr( system_counters, AERON_SYSTEM_COUNTER_NAK_MESSAGES_SENT); _image->loss_gap_fills_counter = aeron_system_counter_addr( system_counters, AERON_SYSTEM_COUNTER_LOSS_GAP_FILLS); const int64_t initial_position = aeron_logbuffer_compute_position( active_term_id, initial_term_offset, _image->position_bits_to_shift, initial_term_id); _image->begin_loss_change = -1; _image->end_loss_change = -1; _image->loss_term_id = active_term_id; _image->loss_term_offset = initial_term_offset; _image->loss_length = 0; _image->begin_sm_change = -1; _image->end_sm_change = -1; _image->next_sm_position = initial_position; _image->next_sm_receiver_window_length = _image->congestion_control->initial_window_length( _image->congestion_control->state); _image->last_sm_position = initial_position; _image->last_sm_position_window_limit = initial_position + _image->next_sm_receiver_window_length; _image->last_packet_timestamp_ns = now_ns; _image->last_status_message_timestamp = 0; _image->conductor_fields.clean_position = initial_position; _image->conductor_fields.time_of_last_status_change_ns = now_ns; aeron_counter_set_ordered(_image->rcv_hwm_position.value_addr, initial_position); aeron_counter_set_ordered(_image->rcv_pos_position.value_addr, initial_position); *image = _image; return 0; }
int aeron_udp_transport_poller_poll( aeron_udp_transport_poller_t *poller, struct mmsghdr *msgvec, size_t vlen, aeron_udp_transport_recv_func_t recv_func, void *clientd) { int work_count = 0; if (poller->transports.length <= AERON_UDP_TRANSPORT_POLLER_ITERATION_THRESHOLD) { for (size_t i = 0, length = poller->transports.length; i < length; i++) { int recv_result = aeron_udp_channel_transport_recvmmsg( poller->transports.array[i].transport, msgvec, vlen, recv_func, clientd); if (recv_result < 0) { return recv_result; } work_count += recv_result; } } else { #if defined(HAVE_EPOLL) int result = epoll_wait(poller->epoll_fd, poller->epoll_events, (int)poller->transports.length, 0); if (result < 0) { int err = errno; if (EINTR == err || EAGAIN == err) { return 0; } aeron_set_err(err, "epoll_wait: %s", strerror(err)); return -1; } else if (0 == result) { return 0; } else { for (size_t i = 0, length = result; i < length; i++) { if (poller->epoll_events[i].events & EPOLLIN) { int recv_result = aeron_udp_channel_transport_recvmmsg( poller->epoll_events[i].data.ptr, msgvec, vlen, recv_func, clientd); if (recv_result < 0) { return recv_result; } work_count += recv_result; } poller->epoll_events[i].events = 0; } } #elif defined(HAVE_POLL) int result = poll(poller->pollfds, (nfds_t)poller->transports.length, 0); if (result < 0) { int err = errno; if (EINTR == err || EAGAIN == err) { return 0; } aeron_set_err(err, "poll: %s", strerror(err)); return -1; } else if (0 == result) { return 0; } else { for (size_t i = 0, length = poller->transports.length; i < length; i++) { if (poller->pollfds[i].revents & POLLIN) { int recv_result = aeron_udp_channel_transport_recvmmsg( poller->transports.array[i].transport, msgvec, vlen, recv_func, clientd); if (recv_result < 0) { return recv_result; } work_count += recv_result; } poller->pollfds[i].revents = 0; } } #endif } return work_count; }
int aeron_interface_split(const char *interface_str, aeron_parsed_interface_t *parsed_interface) { if (NULL == interface_str || '\0' == *interface_str) { aeron_set_err(EINVAL, "no interface value"); return -1; } int percent_index = -1; int colon_index = -1; int l_brace_index = -1; int r_brace_index = -1; int slash_index = -1; int i = 0; char c = *interface_str; while ('\0' != c) { if (':' == c) { colon_index = i; } else if ('[' == c) { l_brace_index = i; } else if (']' == c) { r_brace_index = i; } else if ('/' == c) { slash_index = i; } else if ('%' == c) { percent_index = i; } ++i; c = *(interface_str + i); } bool is_ipv6 = false; if (l_brace_index > 0 || r_brace_index > 0) { if (l_brace_index < 0 || r_brace_index < 0 || r_brace_index < l_brace_index) { aeron_set_err(EINVAL, "host address invalid: %s", interface_str); return -1; } is_ipv6 = true; parsed_interface->ip_version_hint = 6; } else { parsed_interface->ip_version_hint = 4; } *parsed_interface->prefix = '\0'; if (slash_index >= 0) { int length = i - slash_index; if (length <= 0) { aeron_set_err(EINVAL, "subnet prefix invalid: %s", interface_str); return -1; } if (length >= AERON_MAX_PREFIX_LENGTH) { aeron_set_err(EINVAL, "subnet prefix invalid: %s", interface_str); return -1; } strncpy(parsed_interface->prefix, interface_str + slash_index + 1, (size_t)length); *(parsed_interface->prefix + length) = '\0'; } *parsed_interface->port = '\0'; if (colon_index >= 0 && r_brace_index < colon_index) { if (i - 1 == colon_index) { aeron_set_err(EINVAL, "port invalid: %s", interface_str); return -1; } int port_begin = colon_index + 1; int length = slash_index > 0 ? slash_index - port_begin : i - port_begin; if (length >= AERON_MAX_PORT_LENGTH) { aeron_set_err(EINVAL, "port invalid: %s", interface_str); return -1; } strncpy(parsed_interface->port, interface_str + port_begin, (size_t)length); *(parsed_interface->port + length) = '\0'; } int length = i; if (slash_index >= 0) { length = slash_index; } if (colon_index >= 0 && colon_index > r_brace_index) { length = colon_index; } bool is_scoped = false; if (percent_index >= 0 && percent_index < r_brace_index) { length = percent_index; is_scoped = true; } const char *host = is_ipv6 ? interface_str + 1 : interface_str; if (is_ipv6) { length = is_scoped ? length -1 : length - 2; } if (length >= AERON_MAX_HOST_LENGTH) { aeron_set_err(EINVAL, "host address invalid: %s", interface_str); return -1; } strncpy(parsed_interface->host, host, (size_t)length); *(parsed_interface->host + length) = '\0'; return 0; }
int aeron_address_split(const char *address_str, aeron_parsed_address_t *parsed_address) { if (NULL == address_str || '\0' == *address_str) { aeron_set_err(EINVAL, "no address value"); return -1; } int percent_index = -1; int colon_index = -1; int l_brace_index = -1; int r_brace_index = -1; int i = 0; char c = *address_str; while ('\0' != c) { if (':' == c) { colon_index = i; } else if ('[' == c) { l_brace_index = i; } else if (']' == c) { r_brace_index = i; } else if ('%' == c) { percent_index = i; } ++i; c = *(address_str + i); } bool is_ipv6 = false; if (l_brace_index > 0 || r_brace_index > 0) { if (l_brace_index < 0 || r_brace_index < 0 || r_brace_index < l_brace_index) { aeron_set_err(EINVAL, "host address invalid: %s", address_str); return -1; } is_ipv6 = true; parsed_address->ip_version_hint = 6; } else { parsed_address->ip_version_hint = 4; } *parsed_address->port = '\0'; if (colon_index >= 0 && r_brace_index < colon_index) { if (i - 1 == colon_index) { aeron_set_err(EINVAL, "port invalid: %s", address_str); return -1; } int port_begin = colon_index + 1; int length = i - port_begin; if (length >= AERON_MAX_PORT_LENGTH) { aeron_set_err(EINVAL, "port invalid: %s", address_str); return -1; } strncpy(parsed_address->port, address_str + port_begin, (size_t)length); *(parsed_address->port + length) = '\0'; } int length = i; if (colon_index >= 0 && colon_index > r_brace_index) { length = colon_index; } bool is_scoped = false; if (percent_index >= 0 && percent_index < r_brace_index) { is_scoped = true; length = percent_index; } const char *host = is_ipv6 ? address_str + 1 : address_str; if (is_ipv6) { length = is_scoped ? length -1 : length - 2; } if (length >= AERON_MAX_HOST_LENGTH) { aeron_set_err(EINVAL, "host address invalid: %s", address_str); return -1; } strncpy(parsed_address->host, host, (size_t)length); *(parsed_address->host + length) = '\0'; return 0; }
int aeron_uri_publication_params( aeron_uri_t *uri, aeron_uri_publication_params_t *params, aeron_driver_context_t *context, bool is_exclusive) { params->linger_timeout_ns = context->publication_linger_timeout_ns; params->term_length = AERON_URI_IPC == uri->type ? context->ipc_term_buffer_length : context->term_buffer_length; params->mtu_length = AERON_URI_IPC == uri->type ? context->ipc_mtu_length : context->mtu_length; params->initial_term_id = 0; params->term_offset = 0; params->term_id = 0; params->is_replay = false; params->is_sparse = context->term_buffer_sparse_file; aeron_uri_params_t *uri_params = AERON_URI_IPC == uri->type ? &uri->params.ipc.additional_params : &uri->params.udp.additional_params; if (aeron_uri_linger_timeout_param(uri_params, params) < 0) { return -1; } if (aeron_uri_get_term_length_param(uri_params, params) < 0) { return -1; } if (aeron_uri_get_mtu_length_param(uri_params, params) < 0) { return -1; } if (is_exclusive) { const char *initial_term_id_str = NULL; const char *term_id_str = NULL; const char *term_offset_str = NULL; int count = 0; initial_term_id_str = aeron_uri_find_param_value(uri_params, AERON_URI_INITIAL_TERM_ID_KEY); count += initial_term_id_str ? 1 : 0; term_id_str = aeron_uri_find_param_value(uri_params, AERON_URI_TERM_ID_KEY); count += term_id_str ? 1 : 0; term_offset_str = aeron_uri_find_param_value(uri_params, AERON_URI_TERM_OFFSET_KEY); count += term_offset_str ? 1 : 0; if (count > 0) { char *end_ptr = NULL; if (count < 3) { aeron_set_err(EINVAL, "params must be used as a complete set: %s %s %s", AERON_URI_INITIAL_TERM_ID_KEY, AERON_URI_TERM_ID_KEY, AERON_URI_TERM_OFFSET_KEY); return -1; } errno = 0; end_ptr = NULL; if (((params->initial_term_id = strtoll(initial_term_id_str, &end_ptr, 0)) == 0 && 0 != errno) || end_ptr == initial_term_id_str) { aeron_set_err(EINVAL, "could not parse %s in URI", AERON_URI_INITIAL_TERM_ID_KEY); return -1; } errno = 0; end_ptr = NULL; if (((params->term_id = strtoll(term_id_str, &end_ptr, 0)) == 0 && 0 != errno) || end_ptr == term_id_str) { aeron_set_err(EINVAL, "could not parse %s in URI", AERON_URI_TERM_ID_KEY); return -1; } errno = 0; end_ptr = NULL; if (((params->term_offset = strtoull(term_offset_str, &end_ptr, 0)) == 0 && 0 != errno) || end_ptr == term_offset_str) { aeron_set_err(EINVAL, "could not parse %s in URI", AERON_URI_TERM_OFFSET_KEY); return -1; } if (params->initial_term_id < INT32_MIN || params->initial_term_id > INT32_MAX) { aeron_set_err( EINVAL, "Params %s=%" PRId64 " out of range", AERON_URI_INITIAL_TERM_ID_KEY, params->initial_term_id); return -1; } if (params->term_id < INT32_MIN || params->term_id > INT32_MAX) { aeron_set_err(EINVAL, "Params %s=%" PRId64 " out of range", AERON_URI_TERM_ID_KEY, params->term_id); return -1; } if (((int32_t)params->term_id - (int32_t)params->initial_term_id) < 0) { aeron_set_err( EINVAL, "Param difference greater than 2^31 - 1: %s=%" PRId64 " %s=%" PRId64, AERON_URI_INITIAL_TERM_ID_KEY, params->initial_term_id, AERON_URI_TERM_OFFSET_KEY, params->term_id); return -1; } if (params->term_offset > params->term_length) { aeron_set_err( EINVAL, "Param %s=%" PRIu64 " > %s=%" PRIu64, AERON_URI_TERM_OFFSET_KEY, params->term_offset, AERON_URI_TERM_LENGTH_KEY, params->term_length); return -1; } if ((params->term_offset & (AERON_LOGBUFFER_FRAME_ALIGNMENT - 1)) != 0) { aeron_set_err( EINVAL, "Param %s=%" PRIu64 " must be multiple of FRAME_ALIGNMENT", AERON_URI_TERM_OFFSET_KEY, params->term_offset); return -1; } params->is_replay = true; } } const char *value_str; if ((value_str = aeron_uri_find_param_value(uri_params, AERON_URI_SPARSE_TERM_KEY)) != NULL) { if (strncmp("true", value_str, strlen("true")) == 0) { params->is_sparse = true; } } return 0; }
int aeron_udp_channel_parse(const char *uri, size_t uri_length, aeron_udp_channel_t **channel) { aeron_udp_channel_t *_channel = NULL; struct sockaddr_storage endpoint_addr, explicit_control_addr, interface_addr; unsigned int interface_index = 0; memset(&endpoint_addr, 0, sizeof(endpoint_addr)); memset(&explicit_control_addr, 0, sizeof(explicit_control_addr)); memset(&interface_addr, 0, sizeof(interface_addr)); if (aeron_alloc((void **)&_channel, sizeof(aeron_udp_channel_t)) < 0) { aeron_set_err(ENOMEM, "%s", "could not allocate UDP channel"); return -1; } if (aeron_uri_parse(uri, &_channel->uri) < 0) { goto error_cleanup; } size_t copy_length = sizeof(_channel->original_uri) - 1; copy_length = uri_length < copy_length ? uri_length : copy_length; strncpy(_channel->original_uri, uri, copy_length); _channel->original_uri[copy_length] = '\0'; _channel->uri_length = copy_length; _channel->explicit_control = false; _channel->multicast = false; if (_channel->uri.type != AERON_URI_UDP) { aeron_set_err(EINVAL, "%s", "UDP channels must use UDP URIs"); goto error_cleanup; } if (NULL == _channel->uri.params.udp.endpoint_key && NULL == _channel->uri.params.udp.control_key) { aeron_set_err(EINVAL, "%s", "Aeron URIs for UDP must specify an endpoint address and/or a control address"); goto error_cleanup; } if (NULL != _channel->uri.params.udp.endpoint_key) { if (aeron_host_and_port_parse_and_resolve(_channel->uri.params.udp.endpoint_key, &endpoint_addr) < 0) { aeron_set_err( aeron_errcode(), "could not resolve endpoint address=(%s): %s", _channel->uri.params.udp.endpoint_key, aeron_errmsg()); goto error_cleanup; } } else { aeron_set_ipv4_wildcard_host_and_port(&endpoint_addr); } if (NULL != _channel->uri.params.udp.control_key) { if (aeron_host_and_port_parse_and_resolve(_channel->uri.params.udp.control_key, &explicit_control_addr) < 0) { aeron_set_err( aeron_errcode(), "could not resolve control address=(%s): %s", _channel->uri.params.udp.control_key, aeron_errmsg()); goto error_cleanup; } } if (aeron_is_addr_multicast(&endpoint_addr)) { memcpy(&_channel->remote_data, &endpoint_addr, AERON_ADDR_LEN(&endpoint_addr)); if (aeron_multicast_control_address(&endpoint_addr, &_channel->remote_control) < 0) { goto error_cleanup; } if (aeron_find_multicast_interface( endpoint_addr.ss_family, _channel->uri.params.udp.interface_key, &interface_addr, &interface_index) < 0) { aeron_set_err( aeron_errcode(), "could not find interface=(%s): %s", _channel->uri.params.udp.interface_key, aeron_errmsg()); goto error_cleanup; } _channel->interface_index = interface_index; _channel->multicast_ttl = aeron_uri_multicast_ttl(&_channel->uri); memcpy(&_channel->local_data, &interface_addr, AERON_ADDR_LEN(&interface_addr)); memcpy(&_channel->local_control, &interface_addr, AERON_ADDR_LEN(&interface_addr)); aeron_uri_udp_canonicalise( _channel->canonical_form, sizeof(_channel->canonical_form), &interface_addr, &endpoint_addr); _channel->canonical_length = strlen(_channel->canonical_form); _channel->multicast = true; } else if (NULL != _channel->uri.params.udp.control_key) { _channel->interface_index = 0; _channel->multicast_ttl = 0; memcpy(&_channel->remote_data, &endpoint_addr, AERON_ADDR_LEN(&endpoint_addr)); memcpy(&_channel->remote_control, &endpoint_addr, AERON_ADDR_LEN(&endpoint_addr)); memcpy(&_channel->local_data, &explicit_control_addr, AERON_ADDR_LEN(&explicit_control_addr)); memcpy(&_channel->local_control, &explicit_control_addr, AERON_ADDR_LEN(&explicit_control_addr)); aeron_uri_udp_canonicalise( _channel->canonical_form, sizeof(_channel->canonical_form), &explicit_control_addr, &endpoint_addr); _channel->canonical_length = strlen(_channel->canonical_form); _channel->explicit_control = true; } else { if (aeron_find_unicast_interface( endpoint_addr.ss_family, _channel->uri.params.udp.interface_key, &interface_addr, &interface_index) < 0) { goto error_cleanup; } _channel->interface_index = interface_index; _channel->multicast_ttl = 0; memcpy(&_channel->remote_data, &endpoint_addr, AERON_ADDR_LEN(&endpoint_addr)); memcpy(&_channel->remote_control, &endpoint_addr, AERON_ADDR_LEN(&endpoint_addr)); memcpy(&_channel->local_data, &interface_addr, AERON_ADDR_LEN(&interface_addr)); memcpy(&_channel->local_control, &interface_addr, AERON_ADDR_LEN(&interface_addr)); aeron_uri_udp_canonicalise( _channel->canonical_form, sizeof(_channel->canonical_form), &interface_addr, &endpoint_addr); _channel->canonical_length = strlen(_channel->canonical_form); } *channel = _channel; return 0; error_cleanup: *channel = NULL; if (NULL != _channel) { aeron_udp_channel_delete(_channel); } return -1; }
int aeron_udp_channel_transport_recvmmsg( aeron_udp_channel_transport_t *transport, struct mmsghdr *msgvec, size_t vlen, aeron_udp_transport_recv_func_t recv_func, void *clientd) { #if defined(HAVE_RECVMMSG) struct timespec tv = {.tv_nsec = 0, .tv_sec = 0}; int result = recvmmsg(transport->fd, msgvec, vlen, 0, &tv); if (result < 0) { int err = errno; if (EINTR == err || EAGAIN == err) { return 0; } aeron_set_err(err, "recvmmsg: %s", strerror(err)); return -1; } else if (0 == result) { return 0; } else { for (size_t i = 0, length = result; i < length; i++) { recv_func( clientd, transport->dispatch_clientd, msgvec[i].msg_hdr.msg_iov[0].iov_base, msgvec[i].msg_len, msgvec[i].msg_hdr.msg_name); } return result; } #else int work_count = 0; for (size_t i = 0, length = vlen; i < length; i++) { ssize_t result = recvmsg(transport->fd, &msgvec[i].msg_hdr, 0); if (result < 0) { int err = errno; if (EINTR == err || EAGAIN == err) { break; } aeron_set_err(err, "recvmsg: %s", strerror(err)); return -1; } if (0 == result) { break; } msgvec[i].msg_len = (unsigned int)result; recv_func( clientd, transport->dispatch_clientd, msgvec[i].msg_hdr.msg_iov[0].iov_base, msgvec[i].msg_len, msgvec[i].msg_hdr.msg_name); work_count++; } return work_count; #endif } int aeron_udp_channel_transport_sendmmsg( aeron_udp_channel_transport_t *transport, struct mmsghdr *msgvec, size_t vlen) { #if defined(HAVE_RECVMMSG) int sendmmsg_result = sendmmsg(transport->fd, msgvec, vlen, 0); if (sendmmsg_result < 0) { aeron_set_err(errno, "sendmmsg: %s", strerror(errno)); return -1; } return sendmmsg_result; #else int result = 0; for (size_t i = 0, length = vlen; i < length; i++) { ssize_t sendmsg_result = sendmsg(transport->fd, &msgvec[i].msg_hdr, 0); if (sendmsg_result < 0) { aeron_set_err(errno, "sendmsg: %s", strerror(errno)); return -1; } msgvec[i].msg_len = (unsigned int)sendmsg_result; if (0 == sendmsg_result) { break; } result++; } return result; #endif }
int aeron_udp_channel_transport_init( aeron_udp_channel_transport_t *transport, struct sockaddr_storage *bind_addr, struct sockaddr_storage *multicast_if_addr, unsigned int multicast_if_index, uint8_t ttl, size_t socket_rcvbuf, size_t socket_sndbuf) { bool is_ipv6, is_multicast; struct sockaddr_in *in4 = (struct sockaddr_in *)bind_addr; struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)bind_addr; transport->fd = -1; if ((transport->fd = socket(bind_addr->ss_family, SOCK_DGRAM, 0)) < 0) { goto error; } is_ipv6 = (AF_INET6 == bind_addr->ss_family); is_multicast = aeron_is_addr_multicast(bind_addr); socklen_t bind_addr_len = is_ipv6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in); if (!is_multicast) { if (bind(transport->fd, (struct sockaddr *)bind_addr, bind_addr_len) < 0) { int errcode = errno; aeron_set_err(errcode, "unicast bind: %s", strerror(errcode)); goto error; } } else { int reuse = 1; #if defined(SO_REUSEADDR) if (setsockopt(transport->fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0) { int errcode = errno; aeron_set_err(errcode, "setsockopt(SO_REUSEADDR): %s", strerror(errcode)); goto error; } #endif #if defined(SO_REUSEPORT) if (setsockopt(transport->fd, SOL_SOCKET, SO_REUSEPORT, &reuse, sizeof(reuse)) < 0) { int errcode = errno; aeron_set_err(errcode, "setsockopt(SO_REUSEPORT): %s", strerror(errcode)); goto error; } #endif if (bind(transport->fd, (struct sockaddr *) bind_addr, bind_addr_len) < 0) { int errcode = errno; aeron_set_err(errcode, "multicast bind: %s", strerror(errcode)); goto error; } if (is_ipv6) { struct ipv6_mreq mreq; memcpy(&mreq.ipv6mr_multiaddr, &in6->sin6_addr, sizeof(in6->sin6_addr)); mreq.ipv6mr_interface = multicast_if_index; if (setsockopt(transport->fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) < 0) { int errcode = errno; aeron_set_err(errcode, "setsockopt(IPV6_JOIN_GROUP): %s", strerror(errcode)); goto error; } if (setsockopt( transport->fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &multicast_if_index, sizeof(multicast_if_index)) < 0) { int errcode = errno; aeron_set_err(errcode, "setsockopt(IPV6_MULTICAST_IF): %s", strerror(errcode)); goto error; } if (ttl > 0) { if (setsockopt(transport->fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &ttl, sizeof(ttl)) < 0) { int errcode = errno; aeron_set_err(errcode, "setsockopt(IPV6_MULTICAST_HOPS): %s", strerror(errcode)); goto error; } } } else { struct ip_mreq mreq; struct sockaddr_in *interface_addr = (struct sockaddr_in *) &multicast_if_addr; mreq.imr_multiaddr.s_addr = in4->sin_addr.s_addr; mreq.imr_interface.s_addr = interface_addr->sin_addr.s_addr; if (setsockopt(transport->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) { int errcode = errno; aeron_set_err(errcode, "setsockopt(IP_ADD_MEMBERSHIP): %s", strerror(errcode)); goto error; } if (setsockopt(transport->fd, IPPROTO_IP, IP_MULTICAST_IF, interface_addr, sizeof(struct in_addr)) < 0) { int errcode = errno; aeron_set_err(errcode, "setsockopt(IP_MULTICAST_IF): %s", strerror(errcode)); goto error; } if (ttl > 0) { if (setsockopt(transport->fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) < 0) { int errcode = errno; aeron_set_err(errcode, "setsockopt(IP_MULTICAST_TTL): %s", strerror(errcode)); goto error; } } } } if (socket_rcvbuf > 0) { if (setsockopt(transport->fd, SOL_SOCKET, SO_RCVBUF, &socket_rcvbuf, sizeof(socket_rcvbuf)) < 0) { int errcode = errno; aeron_set_err(errcode, "setsockopt(SO_RCVBUF): %s", strerror(errcode)); goto error; } } if (socket_sndbuf > 0) { if (setsockopt(transport->fd, SOL_SOCKET, SO_SNDBUF, &socket_sndbuf, sizeof(socket_sndbuf)) < 0) { int errcode = errno; aeron_set_err(errcode, "setsockopt(SO_SNDBUF): %s", strerror(errcode)); goto error; } } int flags; if ((flags = fcntl(transport->fd, F_GETFL, 0)) < 0) { int errcode = errno; aeron_set_err(errcode, "fcntl(F_GETFL): %s", strerror(errcode)); goto error; } flags |= O_NONBLOCK; if (fcntl(transport->fd, F_SETFL, flags) < 0) { int errcode = errno; aeron_set_err(errcode, "fcntl(F_SETFL): %s", strerror(errcode)); goto error; } return 0; error: close(transport->fd); transport->fd = -1; return -1; }