Exemplo n.º 1
0
arg_t _connect(void)
{
	uint8_t flag;
	struct socket *s = sock_get(fd, &flag);
	struct sockaddr_in sin;
	if (s == NULL)
		return -1;
	if (s->s_state == SS_CONNECTING) {
		udata.u_error = EALREADY;
		return -1;
	}
	if (s->s_state == SS_UNCONNECTED && sock_autobind(s))
		return -1;
	
	if (s->s_state == SS_BOUND) {
		if (sa_getremote(uaddr, &sin) == -1)
			return -1;
		s->s_addr[SADDR_DST].addr = sin.sin_addr.s_addr;
		s->s_addr[SADDR_DST].port = sin.sin_port;
		if (net_connect(s))
			return -1;
		if (sock_wait_leave(s, 0, SS_CONNECTING)) {
			/* API oddity, thanks Berkeley */
			if (udata.u_error == EAGAIN)
				udata.u_error = EINPROGRESS;
			return -1;
		}
		return sock_error(s);
	}
	udata.u_error = EINVAL;
	return -1;
}
Exemplo n.º 2
0
arg_t _connect(void)
{
	uint8_t flag;
	struct socket *s = sock_get(fd, &flag);
	struct sockaddr_in sin;
	if (s == NULL)
		return -1;
	if (s->s_state == SS_CONNECTING) {
		udata.u_error = EALREADY;
		return -1;
	}
	if (s->s_state == SS_UNCONNECTED && sock_autobind(s))
		return -1;
	
	if (s->s_state == SS_BOUND) {
		if (sa_getremote(uaddr, &sin) == -1)
			return -1;
		s->s_addr[SADDR_DST].addr = sin.sin_addr.s_addr;
		s->s_addr[SADDR_DST].port = sin.sin_port;
		s->s_state = SS_CONNECTING;
		/* Protocol op to kick off */
	}

	do {
		/* FIXME: return EINPROGRESS not EINTR for SS_CONNECTING */
		if (psleep_flags(s, flag))
			return -1;
		/* Protocol state check */
	} while (s->s_state == SS_CONNECTING);
	return sock_error(s);
}
Exemplo n.º 3
0
static int udp_send_buf(struct sock *sk, void *buf, int size,
				struct sock_addr *skaddr)
{
	struct sock_addr sk_addr;
	struct pkbuf *pkb;

	/* destination address check */
	if (size <= 0 || size > UDP_MAX_BUFSZ)
		return -1;
	if (skaddr) {
		sk_addr.dst_addr = skaddr->dst_addr;
		sk_addr.dst_port = skaddr->dst_port;
	} else if (sk->sk_dport) {
		sk_addr.dst_addr = sk->sk_daddr;
		sk_addr.dst_port = sk->sk_dport;
	}
	if (!sk_addr.dst_addr || !sk_addr.dst_port)
		return -1;
	if (!sk->sk_sport && sock_autobind(sk) < 0)
		return -1;
	/* udp packet send */
	pkb = alloc_pkb(ETH_HRD_SZ + IP_HRD_SZ + UDP_HRD_SZ + size);
	if (udp_init_pkb(sk, pkb, buf, size, &sk_addr) < 0) {
		free_pkb(pkb);
		return -1;
	}
	if (sk->ops->send_pkb)
		return sk->ops->send_pkb(sk, pkb);
	else
		return udp_send_pkb(sk, pkb);
}
Exemplo n.º 4
0
arg_t _sendto(void)
{
	struct socket *s = sock_get(fd, NULL);
	struct sockaddr_in sin;
	uint16_t flags;
	uint16_t alen;
	uint16_t err;

	if (s == NULL)
		return -1;

	if (s->s_state == SS_UNCONNECTED) {
		err = sock_autobind(s);
		if (err)
			return err;
	}
	if (s->s_state < SS_BOUND) {
		udata.u_error = EINVAL;
		return -1;
	}
	if (s->s_state != SS_BOUND && s->s_state < SS_CONNECTED) {
		udata.u_error = ENOTCONN;
		return -1;
	}
	flags = ugetw(&uaddr->sio_flags);
	if (flags) {
		udata.u_error = EINVAL;
		return -1;
	}
	alen = ugetw(&uaddr->sio_flags);
	/* Save the address and then just do a 'write' */
	if (s->s_type != SOCKTYPE_TCP && alen) {
		if (s->s_state >= SS_CONNECTING) {
			udata.u_error = EISCONN;
			return -1;
		}
		/* Use the address in atmp */
		s->s_flag |= SFLAG_ATMP;
		if (sa_getremote(&uaddr->sio_addr, &sin) == -1)
			return -1;
		s->s_addr[SADDR_TMP].addr = sin.sin_addr.s_addr;
		s->s_addr[SADDR_TMP].port = sin.sin_port;
	} else {
		s->s_flag &= ~SFLAG_ATMP;
		if (s->s_state < SS_CONNECTED) {
			udata.u_error = EDESTADDRREQ;
			return -1;
		}
	}
	return _write();
}
Exemplo n.º 5
0
arg_t _listen(void)
{
	struct socket *s = sock_get(fd, NULL);
	if (s == NULL)
		return -1;
	if (s->s_state == SS_UNCONNECTED && sock_autobind(s))
		return -1;
	if (s->s_type != SOCKTYPE_TCP || s->s_state != SS_BOUND) {
		udata.u_error = EINVAL;
		return -1;	
	}
	/* Call the protocol services */
	return net_listen(s);
}