void web_connection_base::get_specific_peer_info(peer_info& p) const
	{
		if (is_interesting()) p.flags |= peer_info::interesting;
		if (is_choked()) p.flags |= peer_info::choked;
		if (!is_connecting() && m_server_string.empty())
			p.flags |= peer_info::handshake;
		if (is_connecting()) p.flags |= peer_info::connecting;

		p.client = m_server_string;
	}
Beispiel #2
0
void connman_peer_set_as_master(struct connman_peer *peer, bool master)
{
	if (!peer || !is_connecting(peer))
		return;

	peer->connection_master = master;
}
Beispiel #3
0
static void deselect_service(struct session_info *info)
{
	struct service_entry *entry;
	connman_bool_t disconnect, connected;

	DBG("");

	if (info->entry == NULL)
		return;

	disconnect = explicit_disconnect(info);

	connected = is_connecting(info->entry->state) == TRUE ||
			is_connected(info->entry->state) == TRUE;

	info->state = CONNMAN_SESSION_STATE_DISCONNECTED;
	info->entry->reason = CONNMAN_SESSION_REASON_UNKNOWN;

	entry = info->entry;
	info->entry = NULL;

	DBG("disconnect %d connected %d", disconnect, connected);

	if (disconnect == TRUE && connected == TRUE)
		pending_timeout_add(0, call_disconnect, entry);
}
        // client
        hpc_rpc_session::hpc_rpc_session(
            socket_t sock,
            std::shared_ptr<dsn::message_parser>& parser,
            connection_oriented_network& net,
            const ::dsn::rpc_address& remote_addr,
            rpc_client_matcher_ptr& matcher
            )
            : rpc_session(net, remote_addr, matcher, parser),
             _socket(sock)
        {
            dassert(sock != -1, "invalid given socket handle");
            _sending_msg = nullptr;
            _sending_buffer_start_index = 0;
            _looper = nullptr;

            memset((void*)&_peer_addr, 0, sizeof(_peer_addr));
            _peer_addr.sin_family = AF_INET;
            _peer_addr.sin_addr.s_addr = INADDR_ANY;
            _peer_addr.sin_port = 0;

            _ready_event = [this](int err, uint32_t length, uintptr_t lolp_or_events)
            {
                if (is_connecting())
                    this->on_connect_events_ready(lolp_or_events);
                else
                    this->on_send_recv_events_ready(lolp_or_events);
            };
        }
        void hpc_rpc_session::on_connect_events_ready(uintptr_t lolp_or_events)
        {
            dassert(is_connecting(), "session must be connecting at this time");

            struct kevent& e = *((struct kevent*)lolp_or_events);
            dinfo("(s = %d) epoll for connect to %s:%hu, events = %x",
                _socket,
                _remote_addr.name(),
                _remote_addr.port(),
                e.filter
                );

            if ((e.filter == EVFILT_WRITE)
                && ((e.flags & EV_ERROR) == 0)
                && ((e.flags & EV_EOF) == 0)
                )
            {
                socklen_t addr_len = (socklen_t)sizeof(_peer_addr);
                if (getpeername(_socket, (struct sockaddr*)&_peer_addr, &addr_len) == -1)
                {
                    dassert(false, "(s = %d) (client) getpeername failed, err = %s",
                        _socket, strerror(errno));
                }

                dinfo("(s = %d) client session %s:%hu connected",
                    _socket,
                    _remote_addr.name(),
                    _remote_addr.port()
                    );

                set_connected();
                
                if (_looper->bind_io_handle(
                    (dsn_handle_t)(intptr_t)_socket,
                    &_ready_event,
                    EVFILT_READ_WRITE
                    ) != ERR_OK)
                {
                    on_failure();
                    return;
                }

                // start first round send
                do_safe_write(nullptr);
            }
            else
            {
                int err = 0;
                socklen_t err_len = (socklen_t)sizeof(err);

                if (getsockopt(_socket, SOL_SOCKET, SO_ERROR, (void*)&err, &err_len) < 0)
                {
                    dassert(false, "getsockopt for SO_ERROR failed, err = %s", strerror(errno));
                }

                derror("(s = %d) connect failed (in epoll), err = %s", _socket, strerror(err));
                on_failure();
            }
        }
Beispiel #6
0
int connman_peer_set_state(struct connman_peer *peer,
					enum connman_peer_state new_state)
{
	enum connman_peer_state old_state = peer->state;
	int err;

	DBG("peer (%s) old state %d new state %d", peer->name,
				old_state, new_state);

	if (old_state == new_state)
		return -EALREADY;

	switch (new_state) {
	case CONNMAN_PEER_STATE_UNKNOWN:
		return -EINVAL;
	case CONNMAN_PEER_STATE_IDLE:
		if (is_connecting(peer) || is_connected(peer))
			return peer_disconnect(peer);
		peer->sub_device = NULL;
		break;
	case CONNMAN_PEER_STATE_ASSOCIATION:
		break;
	case CONNMAN_PEER_STATE_CONFIGURATION:
		if (peer->connection_master)
			err = start_dhcp_server(peer);
		else
			err = start_dhcp_client(peer);
		if (err < 0)
			return connman_peer_set_state(peer,
						CONNMAN_PEER_STATE_FAILURE);
		break;
	case CONNMAN_PEER_STATE_READY:
		reply_pending(peer, 0);
		break;
	case CONNMAN_PEER_STATE_DISCONNECT:
		if (peer->connection_master)
			stop_dhcp_server(peer);
		peer->connection_master = false;
		peer->sub_device = NULL;

		break;
	case CONNMAN_PEER_STATE_FAILURE:
		if (manage_peer_error(peer) == 0)
			return 0;
		break;
	};

	peer->state = new_state;
	state_changed(peer);

	return 0;
}
Beispiel #7
0
static DBusMessage *connect_peer(DBusConnection *conn,
					DBusMessage *msg, void *user_data)
{
	struct connman_peer *peer = user_data;
	GList *list, *start;
	int err;

	DBG("peer %p", peer);

	if (peer->pending)
		return __connman_error_in_progress(msg);

	list = g_hash_table_get_values(peers_table);
	start = list;
	for (; list; list = list->next) {
		struct connman_peer *temp = list->data;

		if (temp == peer || temp->device != peer->device)
			continue;

		if (is_connecting(temp) || is_connected(temp)) {
			if (peer_disconnect(temp) == -EINPROGRESS) {
				g_list_free(start);
				return __connman_error_in_progress(msg);
			}
		}
	}

	g_list_free(start);

	peer->pending = dbus_message_ref(msg);

	err = peer_connect(peer);
	if (err == -EINPROGRESS)
		return NULL;

	if (err < 0) {
		dbus_message_unref(peer->pending);
		peer->pending = NULL;

		return __connman_error_failed(msg, -err);
	}

	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
Beispiel #8
0
static void session_changed(struct connman_session *session,
				enum connman_session_trigger trigger)
{
	struct session_info *info = session->info;
	struct session_info *info_last = session->info_last;
	GSequenceIter *service_iter = NULL, *service_iter_last = NULL;
	GSequence *service_list_last;
	GHashTable *service_hash_last;

	/*
	 * TODO: This only a placeholder for the 'real' algorithm to
	 * play a bit around. So we are going to improve it step by step.
	 */

	DBG("session %p trigger %s reason %s", session, trigger2string(trigger),
						reason2string(info->reason));

	if (info->entry != NULL) {
		enum connman_session_state state;

		state = service_to_session_state(info->entry->state);

		if (is_type_matching_state(&state, info->config.type) == TRUE)
			info->state = state;
	}

	switch (trigger) {
	case CONNMAN_SESSION_TRIGGER_UNKNOWN:
		DBG("ignore session changed event");
		return;
	case CONNMAN_SESSION_TRIGGER_SETTING:
		if (info->config.allowed_bearers != info_last->config.allowed_bearers) {

			service_hash_last = session->service_hash;
			service_list_last = session->service_list;

			populate_service_list(session);

			if (info->entry != NULL) {
				service_iter_last = g_hash_table_lookup(
							service_hash_last,
							info->entry->service);
				service_iter = g_hash_table_lookup(
							session->service_hash,
							info->entry->service);
			}

			if (service_iter == NULL && service_iter_last != NULL) {
				/*
				 * The currently selected service is
				 * not part of this session anymore.
				 */
				deselect_and_disconnect(session);
			}

			g_hash_table_remove_all(service_hash_last);
			g_sequence_free(service_list_last);
		}

		if (info->config.type != info_last->config.type) {
			if (info->state >= CONNMAN_SESSION_STATE_CONNECTED &&
					is_type_matching_state(&info->state,
							info->config.type) == FALSE)
				deselect_and_disconnect(session);
		}

		if (info->state == CONNMAN_SESSION_STATE_DISCONNECTED) {
			select_and_connect(session,
					CONNMAN_SESSION_REASON_FREE_RIDE);
		}

		break;
	case CONNMAN_SESSION_TRIGGER_ECALL:
		/*
		 * For the time beeing we fallback to normal connect
		 * strategy.
		 */
	case CONNMAN_SESSION_TRIGGER_CONNECT:
		if (info->state >= CONNMAN_SESSION_STATE_CONNECTED) {
			if (info->entry->reason == CONNMAN_SESSION_REASON_CONNECT)
				break;
			info->entry->reason = CONNMAN_SESSION_REASON_CONNECT;
			__connman_service_session_inc(info->entry->service);
			break;
		}

		if (info->entry != NULL &&
				is_connecting(info->entry->state) == TRUE) {
			break;
		}

		select_and_connect(session,
				CONNMAN_SESSION_REASON_CONNECT);

		break;
	case CONNMAN_SESSION_TRIGGER_DISCONNECT:
		deselect_and_disconnect(session);

		break;
	case CONNMAN_SESSION_TRIGGER_SERVICE:
		if (info->entry != NULL &&
			(is_connecting(info->entry->state) == TRUE ||
				is_connected(info->entry->state) == TRUE)) {
			break;
		}

		deselect_and_disconnect(session);

		if (info->reason == CONNMAN_SESSION_REASON_FREE_RIDE) {
			select_and_connect(session, info->reason);
		}

		break;
	}

	session_notify(session);
}