Exemple #1
0
void connection::handshake_received(const boost::system::error_code& error, std::size_t bytes_transferred)
{
	if (error) {
		stillborn();
		return;
	}

	link_.received(bytes_transferred);

	bool handshake_valid;

	if (link_.socket.lowest_layer().remote_endpoint().address().is_v4())
		handshake_valid = do_parse_handshake<ip::address_v4>();
	else
		handshake_valid = do_parse_handshake<ip::address_v6>();

	if (!handshake_valid) {
		link_.socket.lowest_layer().close();
		DLOG(INFO) << "Error parsing handshake";
		return;
	}

	remote_identity_ = network_key(::SSL_get_peer_certificate(link_.socket.impl()->ssl));

	if (supported_protocols_.size() * 2 > link_.valid_received_bytes())
		boost::asio::async_read(link_.socket,
		                        mutable_buffers_1(link_.receive_buffer()),
		                        boost::asio::transfer_at_least(supported_protocols_.size() - link_.valid_received_bytes()),
		                        boost::bind(&connection::complete_connection,
		                                    shared_from_this(),
		                                    placeholders::error,
		                                    placeholders::bytes_transferred));
	else
		complete_connection(error, 0);
}
/*
 * ECONNRESET == RST in TCP world. Check what equivalent
 * events can happen in ATM world.
 *
 * Returns < 0 for error
 */
static int check_connection(int slot)
{
        char buff[MAX_PACKET_LENGTH];
        struct k_message *msg;
        struct pollfd *pfd;
        int bytes_read;

        dprintf("mpcd: io.c: check_connection() event in fd %d, type %d\n", fds[slot].fd, socket_type[slot]);
        if (socket_type[slot] & CONNECTING) { /* connect() completed (maybe) */
                complete_connection(slot);    /* ignore return value */
                return 0;
        }

        pfd = &fds[slot];
        bytes_read = read(pfd->fd, buff, sizeof(buff));
        if (bytes_read < 0) {
                if (errno == ECONNRESET || errno == EPIPE) { /* conn reset by the other end or kernel (EPIPE) */
                        if (socket_type[slot] & OUTGOING_SHORTCUT)
                                update_ingress_entry(NULL, pfd->fd, INGRESS_NOT_USED);

                        close(pfd->fd);
                        pfd->fd = -1;
                        socket_type[slot] = NOT_USED;
                        return 1;
                }
                printf("mpcd: io.c: check_connection() bytes_read=%d, errno='%s'\n", bytes_read, strerror(errno)); 
                return -1;
        }
        if (bytes_read == 0) {            /* conn closed by the other end */
                if (socket_type[slot] & OUTGOING_SHORTCUT)
                        update_ingress_entry(NULL, pfd->fd, INGRESS_NOT_USED);

                dprintf("mpcd: io.c: check_connection() fd %d type %d; connection closed'\n", pfd->fd, socket_type[slot]); 
                close(pfd->fd);
                pfd->fd = -1;
                socket_type[slot] = NOT_USED;
                return 1;
        }

        /* See if this is a MPOA control packet */
        if ( memcmp(buff, &llc_snap_mpoa_ctrl, sizeof(llc_snap_mpoa_ctrl)) == 0 )
                if ( recognize_packet(buff + sizeof(llc_snap_mpoa_ctrl)) >= 0)
		        return 1;

        dprintf("mpcd: io.c check_connection(): msg from kernel\n");
	msg = (struct k_message *)buff;
	if(msg->type == DATA_PLANE_PURGE){
	        send_purge_request(msg->content.eg_info.mps_ip,32,
				   get_own_ip_addr(mpc_control.INTERFACE_NUMBER),pfd->fd);
		return 1;
	}

	printf("mpcd: io.c check_connection(): unknown msg %d from kernel, ignoring",
	       msg->type);
	
        return 1;
}