Esempio n. 1
0
static err_t tcp_accept_callback(void *arg, struct tcp_pcb *newpcb, err_t err)
{
	struct socket * sock = (struct socket *) arg;

	debug_tcp_print("socket num %ld", get_sock_num(sock));

	assert(err == ERR_OK && newpcb);
	assert(sock->flags & SOCK_FLG_OP_LISTENING);

	if (sock->flags & SOCK_FLG_OP_PENDING) {
		int ret;

		ret = tcp_do_accept(sock, &sock->mess, newpcb);
		sock_revive(sock, ret);
		sock->flags &= ~SOCK_FLG_OP_PENDING;
		if (ret == OK) {
			return ERR_OK;
		}
		/* in case of an error fall through */
	}

	/* If we cannot accept rightaway we enqueue the connection for later */

	debug_tcp_print("Enqueue connection sock %ld pcb %p\n",
			get_sock_num(sock), newpcb);
	if (sock_enqueue_data(sock, newpcb, 1) != OK) {
		tcp_abort(newpcb);
		return ERR_ABRT;
	}
	if (sock_select_read_set(sock))
		sock_select_notify(sock);

	return ERR_OK;
}
Esempio n. 2
0
File: udp.c Progetto: Hooman3/minix
static void udp_recv_callback(void *arg,
			struct udp_pcb *pcb,
			struct pbuf *pbuf,
			ip_addr_t *addr,
			u16_t port)
{
	struct socket * sock = (struct socket *) arg;
	struct udp_recv_data * data;

	debug_udp_print("socket num : %ld addr : %x port : %d\n",
			get_sock_num(sock), (unsigned int) addr->addr, port);

	if (sock->flags & SOCK_FLG_OP_PENDING) {
		/* we are resuming a suspended operation */
		int ret;

		ret = udp_do_receive(sock, &sock->req, pcb, pbuf, addr, port);

		send_req_reply(&sock->req, ret);
		sock->flags &= ~SOCK_FLG_OP_PENDING;

		if (ret > 0) {
			pbuf_free(pbuf);
			return;
		}
	}

	/* Do not enqueue more data than allowed */
	if (sock->recv_data_size > UDP_BUF_SIZE) {
		pbuf_free(pbuf);
		return;
	}

	/*
	 * nobody is waiting for the data or an error occured above, we enqueue
	 * the packet
	 */
	if (!(data = udp_recv_alloc())) {
		pbuf_free(pbuf);
		return;
	}

	data->ip = *addr;
	data->port = port;
	data->pbuf = pbuf;

	if (sock_enqueue_data(sock, data, data->pbuf->tot_len) != OK) {
		udp_recv_free(data);
		return;
	}
	
	/*
	 * We don't need to notify when somebody is already waiting, reviving
	 * read operation will do the trick for us. But we must announce new
	 * data available here.
	 */
	if (sock_select_read_set(sock))
		sock_select_notify(sock);
}
Esempio n. 3
0
int raw_socket_input(struct pbuf * pbuf, struct nic * nic)
{
	struct socket * sock;
	struct pbuf * pbuf_new;

	if ((sock = nic->raw_socket) == NULL)
		return 0;

	debug_print("socket num : %ld", get_sock_num(sock));

	if (sock->flags & SOCK_FLG_OP_PENDING) {
		int ret;
		/* we are resuming a suspended operation */
		ret = raw_receive(&sock->mess, pbuf);

		if (ret > 0) {
			sock_reply(sock, ret);
			sock->flags &= ~SOCK_FLG_OP_PENDING;
			return 0;
		} else {
			sock_reply(sock, ret);
			sock->flags &= ~SOCK_FLG_OP_PENDING;
		}
	}

	/* Do not enqueue more data than allowed */
	if (sock->recv_data_size > RAW_BUF_SIZE) {
		return 0;
	}

	/*
	 * nobody is waiting for the data or an error occured above, we enqueue
	 * the packet. We store a copy of this packet
	 */
	pbuf_new = pbuf_alloc(PBUF_RAW, pbuf->tot_len, PBUF_RAM);
	if (pbuf_new == NULL) {
		debug_print("LWIP : cannot allocated new pbuf\n");
		return 0;
	}

	if (pbuf_copy(pbuf_new, pbuf) != ERR_OK) {
		debug_print("LWIP : cannot copy pbuf\n");
		return 0;
	}

	/*
	 * If we didn't managed to enqueue the packet we report it as not
	 * consumed
	 */
	if (sock_enqueue_data(sock, pbuf_new, pbuf_new->tot_len) != OK) {
		pbuf_free(pbuf_new);
	}

	return 0;
}
Esempio n. 4
0
static int enqueue_rcv_data(struct socket * sock, struct pbuf * pbuf)
{
	/* Do not enqueue more data than allowed */
	if (0 && sock->recv_data_size > 4 * TCP_BUF_SIZE)
		return ERR_MEM;

	if (sock_enqueue_data(sock, pbuf, pbuf->tot_len) != OK) {
		debug_tcp_print("data enqueueing failed");
		return ERR_MEM;
	}
	debug_tcp_print("enqueued %d bytes", pbuf->tot_len);
	//printf("enqueued %d bytes, queue %d\n", pbuf->tot_len, sock->recv_data_size);

	return ERR_OK;
}
Esempio n. 5
0
static u8_t raw_ip_op_receive(void *arg,
			__unused struct raw_pcb *pcb,
			struct pbuf *pbuf,
			ip_addr_t *addr)
{
	struct socket * sock = (struct socket *) arg;
	struct raw_ip_recv_data * data;
	int ret;

	debug_print("socket num : %ld addr : %x\n",
			get_sock_num(sock), (unsigned int) addr->addr);

	if (sock->flags & SOCK_FLG_OP_PENDING) {
		/* we are resuming a suspended operation */
		ret = raw_ip_do_receive(&sock->mess, pbuf);

		if (ret > 0) {
			sock_reply(sock, ret);
			sock->flags &= ~SOCK_FLG_OP_PENDING;
			if (sock->usr_flags & NWIO_EXCL) {
				pbuf_free(pbuf);
				return 1;
			} else
				return 0;
		} else {
			sock_reply(sock, ret);
			sock->flags &= ~SOCK_FLG_OP_PENDING;
		}
	}

	/* Do not enqueue more data than allowed */
	if (sock->recv_data_size > RAW_IP_BUF_SIZE)
		return 0;

	/*
	 * nobody is waiting for the data or an error occured above, we enqueue
	 * the packet
	 */
	if (!(data = raw_ip_recv_alloc())) {
		return 0;
	}

	data->ip = *addr;
	if (sock->usr_flags & NWIO_EXCL) {
		data->pbuf = pbuf;
		ret = 1;
	} else {
		/* we store a copy of this packet */
		data->pbuf = pbuf_alloc(PBUF_RAW, pbuf->tot_len, PBUF_RAM);
		if (data->pbuf == NULL) {
			debug_print("LWIP : cannot allocated new pbuf\n");
			raw_ip_recv_free(data);
			return 0;
		}

		if (pbuf_copy(data->pbuf, pbuf) != ERR_OK) {
			debug_print("LWIP : cannot copy pbuf\n");
			raw_ip_recv_free(data);
			return 0;
		}

		ret = 0;
	}

	/*
	 * If we didn't managed to enqueue the packet we report it as not
	 * consumed
	 */
	if (sock_enqueue_data(sock, data, data->pbuf->tot_len) != OK) {
		raw_ip_recv_free(data);
		ret = 0;
	}

	return ret;
}