Пример #1
0
void vio_link_state_change(struct vio_driver_state *vio, int event)
{
	if (event == LDC_EVENT_UP) {
		vio->hs_state = VIO_HS_INVALID;

		switch (vio->dev_class) {
		case VDEV_NETWORK:
		case VDEV_NETWORK_SWITCH:
			vio->dr_state = (VIO_DR_STATE_TXREQ |
					 VIO_DR_STATE_RXREQ);
			break;

		case VDEV_DISK:
			vio->dr_state = VIO_DR_STATE_TXREQ;
			break;
		case VDEV_DISK_SERVER:
			vio->dr_state = VIO_DR_STATE_RXREQ;
			break;
		}
		start_handshake(vio);
	} else if (event == LDC_EVENT_RESET) {
		vio->hs_state = VIO_HS_INVALID;

		if (vio->dr_state & VIO_DR_STATE_RXREG)
			flush_rx_dring(vio);

		vio->dr_state = 0x00;
		memset(&vio->ver, 0, sizeof(vio->ver));

		ldc_disconnect(vio->lp);
	}
}
Пример #2
0
/* Write some previously-buffered backend data upstream on the
 * secure socket using OpenSSL */
static void client_write(struct ev_loop *loop, ev_io *w, int revents) {
    (void) revents;
    int t;
    int sz;
    proxystate *ps = (proxystate *)w->data;
    assert(!ringbuffer_is_empty(&ps->ring_up));
    char * next = ringbuffer_read_next(&ps->ring_up, &sz);
    t = SSL_write(ps->ssl, next, sz);
    if (t > 0) {
        if (t == sz) {
            ringbuffer_read_pop(&ps->ring_up);
            safe_enable_io(ps, &ps->ev_r_down); // can be re-enabled b/c we've popped
            if (ringbuffer_is_empty(&ps->ring_up)) {
                if (ps->want_shutdown) {
                    shutdown_proxy(ps, SHUTDOWN_HARD);
                    return;
                }
                ev_io_stop(loop, &ps->ev_w_up);
            }
        }
        else {
            ringbuffer_read_skip(&ps->ring_up, t);
        }
    }
    else {
        int err = SSL_get_error(ps->ssl, t);
        if (err == SSL_ERROR_WANT_READ) {
            start_handshake(ps, err);
        }
        else if (err == SSL_ERROR_WANT_WRITE) {} /* incomplete SSL data */
        else
            handle_fatal_ssl_error(ps, err);
    }
}
Пример #3
0
/* Read some data from the upstream secure socket via OpenSSL,
 * and buffer anything we get for writing to the backend */
static void client_read(struct ev_loop *loop, ev_io *w, int revents) {
    (void) revents;
    int t;    
    proxystate *ps = (proxystate *)w->data;
    if (ps->want_shutdown) {
        ev_io_stop(loop, &ps->ev_r_up);
        return;
    }
    char * buf = ringbuffer_write_ptr(&ps->ring_down);
    t = SSL_read(ps->ssl, buf, RING_DATA_LEN);
    if (t > 0) {
        ringbuffer_write_append(&ps->ring_down, t);
        if (ringbuffer_is_full(&ps->ring_down))
            ev_io_stop(loop, &ps->ev_r_up);
        safe_enable_io(ps, &ps->ev_w_down);
    }
    else {
        int err = SSL_get_error(ps->ssl, t);
        if (err == SSL_ERROR_WANT_WRITE) {
            start_handshake(ps, err);
        }
        else if (err == SSL_ERROR_WANT_READ) { } /* incomplete SSL data */
        else
            handle_fatal_ssl_error(ps, err);
    }
}
Пример #4
0
Файл: stud.c Проект: djs55/stud
/* Continue/complete the asynchronous connect() before starting data transmission
 * between front/backend */
static void handle_connect(struct ev_loop *loop, ev_io *w, int revents) {
    (void) revents;
    int t;
    proxystate *ps = (proxystate *)w->data;
    t = connect(ps->fd_down, backaddr->ai_addr, backaddr->ai_addrlen);
    if (!t || errno == EISCONN || !errno) {
        /* INIT */
        ev_io_stop(loop, &ps->ev_w_down);
        ev_io_init(&ps->ev_r_down, back_read, ps->fd_down, EV_READ);
        ev_io_init(&ps->ev_w_down, back_write, ps->fd_down, EV_WRITE);
        start_handshake(ps, SSL_ERROR_WANT_READ); /* for client-first handshake */
        ev_io_start(loop, &ps->ev_r_down);
        if (OPTIONS.WRITE_IP_OCTET) {
            char *ring_pnt = ringbuffer_write_ptr(&ps->ring_down);
            assert(ps->remote_ip.ss_family == AF_INET ||
                   ps->remote_ip.ss_family == AF_INET6);
            *ring_pnt++ = (unsigned char) ps->remote_ip.ss_family;
            if (ps->remote_ip.ss_family == AF_INET6) {
                memcpy(ring_pnt, &((struct sockaddr_in6 *) &ps->remote_ip)
                       ->sin6_addr.s6_addr, 16U);
                ringbuffer_write_append(&ps->ring_down, 1U + 16U);
            } else {
                memcpy(ring_pnt, &((struct sockaddr_in *) &ps->remote_ip)
                       ->sin_addr.s_addr, 4U);
                ringbuffer_write_append(&ps->ring_down, 1U + 4U);
            }
            ev_io_start(loop, &ps->ev_w_down);
        }
    }
    else if (errno == EINPROGRESS || errno == EINTR || errno == EALREADY) {
        /* do nothing, we'll get phoned home again... */
    }
    else {
        perror("{backend-connect}");
        shutdown_proxy(ps, SHUTDOWN_HARD);
    }
}
Пример #5
0
/* Continue/complete the asynchronous connect() before starting data transmission
 * between front/backend */
static void handle_connect(struct ev_loop *loop, ev_io *w, int revents) {
    (void) revents;
    int t;
    proxystate *ps = (proxystate *)w->data;
    char tcp6_address_string[INET6_ADDRSTRLEN];
    size_t written = 0;
    t = connect(ps->fd_down, backaddr->ai_addr, backaddr->ai_addrlen);
    if (!t || errno == EISCONN || !errno) {
        /* INIT */
        ev_io_stop(loop, &ps->ev_w_down);
        ev_io_init(&ps->ev_r_down, back_read, ps->fd_down, EV_READ);
        ev_io_init(&ps->ev_w_down, back_write, ps->fd_down, EV_WRITE);
        start_handshake(ps, SSL_ERROR_WANT_READ); /* for client-first handshake */
        ev_io_start(loop, &ps->ev_r_down);
        if (OPTIONS.WRITE_PROXY_LINE) {
            char *ring_pnt = ringbuffer_write_ptr(&ps->ring_down);
            assert(ps->remote_ip.ss_family == AF_INET ||
		   ps->remote_ip.ss_family == AF_INET6);
	    if(ps->remote_ip.ss_family == AF_INET) {
	      struct sockaddr_in* addr = (struct sockaddr_in*)&ps->remote_ip;
	      written = snprintf(ring_pnt,
				 RING_DATA_LEN,
				 tcp_proxy_line,
				 "TCP4",
				 inet_ntoa(addr->sin_addr),
				 ntohs(addr->sin_port));
	    }
	    else if (ps->remote_ip.ss_family == AF_INET6) {
	      struct sockaddr_in6* addr = (struct sockaddr_in6*)&ps->remote_ip;
	      inet_ntop(AF_INET6,&(addr->sin6_addr),tcp6_address_string,INET6_ADDRSTRLEN);
	      written = snprintf(ring_pnt,
				 RING_DATA_LEN,
				 tcp_proxy_line,
				 "TCP6",
				 tcp6_address_string,
				 ntohs(addr->sin6_port));
	    }   
            ringbuffer_write_append(&ps->ring_down, written);
            ev_io_start(loop, &ps->ev_w_down);
        }
        else if (OPTIONS.WRITE_IP_OCTET) {
            char *ring_pnt = ringbuffer_write_ptr(&ps->ring_down);
            assert(ps->remote_ip.ss_family == AF_INET ||
                   ps->remote_ip.ss_family == AF_INET6);
            *ring_pnt++ = (unsigned char) ps->remote_ip.ss_family;
            if (ps->remote_ip.ss_family == AF_INET6) {
                memcpy(ring_pnt, &((struct sockaddr_in6 *) &ps->remote_ip)
                       ->sin6_addr.s6_addr, 16U);
                ringbuffer_write_append(&ps->ring_down, 1U + 16U);
            } else {
                memcpy(ring_pnt, &((struct sockaddr_in *) &ps->remote_ip)
                       ->sin_addr.s_addr, 4U);
                ringbuffer_write_append(&ps->ring_down, 1U + 4U);
            }
            ev_io_start(loop, &ps->ev_w_down);
        }
    }
    else if (errno == EINPROGRESS || errno == EINTR || errno == EALREADY) {
        /* do nothing, we'll get phoned home again... */
    }
    else {
        perror("{backend-connect}");
        shutdown_proxy(ps, SHUTDOWN_HARD);
    }
}
Пример #6
0
void audio_data_handler(struct sk_buff *skb)
{
	void *audio_data;
	struct atc_header *header;

	down(&handle_sem);
	header = (struct atc_header *)skb->data;
	audio_data = (u8 *) (skb->data + sizeof(struct atc_header));
	pr_debug_ratelimited("cmd_code:%u, sub_cmd:%u, cmd_type:%u, len:%u\n",
			     header->cmd_code, header->sub_cmd,
			     header->cmd_type, header->data_len);
	if (header->cmd_code != AUDIO_CMD_CODE) {
		pr_err("Invalid cmd code: %u\n", header->cmd_code);
		goto out;
	}

	if (header->cmd_type != CMD_TYPE_CONFIRM
	    && header->cmd_type != CMD_TYPE_INDICATION) {
		pr_err("Invalid cmd type: %u\n", header->cmd_type);
		goto out;
	}

	switch (header->sub_cmd) {
	case ATC_MSOCKET_LINKDOWN:
		pr_info("received MsocketLinkdown!\n");
		audiostub_inited = false;
		wake_up_interruptible(&pcm_rxwq);
		wake_up_interruptible(&pcm_txwq);
		stop_handshake();
		if (audio_fd) {
			filp_close(audio_fd, NULL);
			audio_fd = NULL;
		}
		break;
	case ATC_MSOCKET_LINKUP:
		pr_info("received MsocketLinkup!\n");
		start_handshake();
		break;
	case ATC_HANDSHAKE:
		{
			struct handshake_msg *msg =
			    (struct handshake_msg *)audio_data;
			pr_info("audio_data_handler,pcm=%u, wb=%u, ver=%u\n",
				msg->pcm_master, msg->is_wb, msg->ver);
			pcm_master = msg->pcm_master > 0;
			pcm_wb = msg->is_wb > 0;
			audiostub_inited = true;
			stop_handshake();
			break;
		}
	case ATC_VOLUMECTL:
	case ATC_MUTECTL:
	case ATC_PATHCTL:
	case ATC_EQCTL:
	case ATC_LOOPBACKCTL:
	case ATC_PCMRECCTL:
	case ATC_PCMPLAYBACKCTL:
		skb_queue_tail(&ctl_rxq, skb);
		complete(&ioctl_completion);
		skb = NULL;
		break;
	case ATC_PCMRECSTREAM:
		if (pcm_rx_opened) {
			pcm_rxcnt++;
			if (skb_queue_len(&pcm_rxq) >= MAX_AUDIO_PACKET_NUM) {
				pr_err_ratelimited("PCM recv overflow\n");
				/* discard old packet */
				kfree_skb(skb_dequeue(&pcm_rxq));
			}
			skb_queue_tail(&pcm_rxq, skb);
			wake_up_interruptible(&pcm_rxwq);
			skb = NULL;
		} else
			pr_err("pcm rx device not opened yet\n");
		break;
	case ATC_PCMPLAYSTREAM:
		if (pcm_tx_opened) {
			struct pcm_stream_ind *pcm_indication =
			    (struct pcm_stream_ind *)audio_data;
			struct sk_buff *pcm_skb;
			int ret;
			struct pcm_stream_data *pcm_data;

			pcm_txcnt++;
			while (pcm_underrun_cnt) {
				pcm_skb = skb_dequeue(&pcm_txq);
				if (pcm_skb) {
					/* discard packets */
					kfree_skb(pcm_skb);
					pcm_underrun_cnt--;
				} else
					break;
			}
			if (skb_queue_empty(&pcm_txq)) {
				pr_err_ratelimited("PCM send underrun\n");
				pcm_underrun_cnt++;
				pcm_skb = alloc_empty_data();
				if (!pcm_skb)
					break;
				header = (struct atc_header *)pcm_skb->data;
				header->cmd_code = AUDIO_CMD_CODE;
				header->sub_cmd = ATC_PCMPLAYSTREAM;
				header->cmd_type = CMD_TYPE_RESPONSE;
				header->data_len = sizeof(*pcm_data);
				pcm_data = (struct pcm_stream_data *)
				    (pcm_skb->data + sizeof(struct atc_header));
				pcm_data->msg_id = pcm_indication->msg_id;
				pcm_data->callback = pcm_indication->callback;
				pcm_data->len = pcm_pktsize;
				audio_tx_rawskb(pcm_skb);
			} else {
				pcm_skb = skb_dequeue(&pcm_txq);
				pcm_data = (struct pcm_stream_data *)
				    (pcm_skb->data + sizeof(struct atc_header));
				pcm_data->msg_id = pcm_indication->msg_id;
				pcm_data->callback = pcm_indication->callback;
				pcm_data->len = pcm_pktsize;
				ret = audio_tx_rawskb(pcm_skb);
				if (ret < 0)
					pr_err("PCM send error: %d\n", ret);
				wake_up_interruptible(&pcm_txwq);
			}
		} else
			pr_err("pcm tx device not opened yet\n");
		break;
	default:
		pr_err("audio_data_handler,unknown:sub_cmd=%d, cmd_type=%d\n",
		       header->sub_cmd, header->cmd_type);
		break;
	}
out:
	kfree_skb(skb);
	up(&handle_sem);
}