Ejemplo n.º 1
0
static void raw_ip_close(struct socket * sock)
{
	/* deque and free all enqueued data before closing */
	sock_dequeue_data_all(sock, raw_ip_recv_free);

	if (sock->pcb)
		raw_remove(sock->pcb);
	if (sock->buf)
		sock_free_buf(sock->buf);

	/* mark it as unused */
	sock->ops = NULL;
}
Ejemplo n.º 2
0
Archivo: tcp.c Proyecto: jkiiski/minix
static void tcp_op_close(struct socket * sock, __unused message * m)
{
	debug_tcp_print("socket num %ld", get_sock_num(sock));

	if (sock->flags & SOCK_FLG_OP_LISTENING)
		sock_dequeue_data_all(sock, tcp_backlog_free);
	else
		sock_dequeue_data_all(sock, tcp_recv_free);
	debug_tcp_print("dequed RX data");

	if (sock->pcb) {
		int err;

		/* we are not able to handle any callback anymore */
		if (((struct tcp_pcb *)sock->pcb)->state != LISTEN) {
			tcp_arg((struct tcp_pcb *)sock->pcb, NULL);
			tcp_err((struct tcp_pcb *)sock->pcb, NULL);
			tcp_sent((struct tcp_pcb *)sock->pcb, NULL);
			tcp_recv((struct tcp_pcb *)sock->pcb, NULL);
		}

		err = tcp_close(sock->pcb);
		assert(err == ERR_OK);
		sock->pcb = NULL;
	}
	debug_tcp_print("freed pcb");

	if (sock->buf) {
		free_wbuf_chain((struct wbuf_chain *) sock->buf);
		sock->buf = NULL;
	}
	debug_tcp_print("freed TX data");

	sock_reply_close(sock, OK);
	debug_tcp_print("socket unused");

	/* mark it as unused */
	sock->ops = NULL;
}
Ejemplo n.º 3
0
static void nic_op_close(struct socket * sock, __unused message * m)
{
	struct nic * nic = (struct nic *)sock->data;

	debug_drv_print("socket %d", get_sock_num(sock));
	
	sock_dequeue_data_all(sock, raw_recv_free);
	sock->ops = NULL;

	if (nic->raw_socket == sock) {
		nic->raw_socket = NULL;
		debug_drv_print("no active raw sock at %s", nic->name);
	}

	sock_reply_close(sock, OK);
}
Ejemplo n.º 4
0
static void udp_op_close(struct socket * sock, __unused message * m)
{
	debug_udp_print("socket num %ld", get_sock_num(sock));

	/* deque and free all enqueued data before closing */
	sock_dequeue_data_all(sock, udp_recv_free);

	if (sock->pcb)
		udp_remove(sock->pcb);
	assert(sock->buf == NULL);

	/* mark it as unused */
	sock->ops = NULL;

	sock_reply_close(sock, OK);
}
Ejemplo n.º 5
0
Archivo: udp.c Proyecto: Hooman3/minix
static int udp_op_close(struct socket * sock)
{
	debug_udp_print("socket num %ld", get_sock_num(sock));

	/* deque and free all enqueued data before closing */
	sock_dequeue_data_all(sock, udp_recv_free);

	if (sock->pcb)
		udp_remove(sock->pcb);
	assert(sock->buf == NULL);

	/* mark it as unused */
	sock->ops = NULL;

	return OK;
}
Ejemplo n.º 6
0
static err_t tcp_recv_callback(void *arg,
				struct tcp_pcb *tpcb,
				struct pbuf *pbuf,
				err_t err)
{
	int ret, enqueued = 0;
	struct socket * sock = (struct socket *) arg;

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

	if (sock->pcb == NULL) {
		if (sock_select_set(sock))
			sock_select_notify(sock);
		return ERR_OK;
	}

	assert((struct tcp_pcb *) sock->pcb == tpcb);

	if (err != ERR_OK)
		return ERR_OK;
	if (!pbuf) {
		debug_tcp_print("tcp stream closed on the remote side");
		// sock->flags |= SOCK_FLG_CLOSED;

		/* wake up the reader and report EOF */
		if (sock->flags & SOCK_FLG_OP_PENDING &&
				sock->flags & SOCK_FLG_OP_READING &&
				!(sock->flags & SOCK_FLG_OP_REVIVING)) {
			sock_revive(sock, 0);
			sock->flags &= ~(SOCK_FLG_OP_PENDING |
					SOCK_FLG_OP_READING);
		}
#if 0
		/* if there are any undelivered data, drop them */
		sock_dequeue_data_all(sock, tcp_recv_free);
		tcp_abandon(tpcb, 0);
		sock->pcb = NULL;
#endif

		return ERR_OK;
	}

	/*
	 * FIXME we always enqueue the data first. If the head is empty and read
	 * operation is pending we could try to deliver immeditaly without
	 * enqueueing
	 */
	if (enqueue_rcv_data(sock, pbuf) == ERR_OK)
		enqueued = 1;

	/*
	 * Deliver data if there is a pending read operation, otherwise notify
	 * select if the socket is being monitored
	 */
	if (sock->flags & SOCK_FLG_OP_PENDING) {
		if (sock->flags & SOCK_FLG_OP_READING) {
			ret = read_from_tcp(sock, &sock->mess);
			debug_tcp_print("read op finished");
			sock_revive(sock, ret);
			sock->flags &= ~(SOCK_FLG_OP_PENDING |
					SOCK_FLG_OP_READING);
		}
	} else if (!(sock->flags & SOCK_FLG_OP_WRITING) &&
			sock_select_rw_set(sock))
		sock_select_notify(sock);

	/* perhaps we have deliverd some data to user, try to enqueue again */
	if (!enqueued) {
		return enqueue_rcv_data(sock, pbuf);
	} else
		return ERR_OK;
}