* net/tipc/socket.c: TIPC socket API
*
* Copyright (c) 2001-2006, Ericsson AB
- * Copyright (c) 2004-2005, Wind River Systems
+ * Copyright (c) 2004-2006, Wind River Systems
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
if (unlikely(!dest))
return -EDESTADDRREQ;
- if (unlikely(dest->family != AF_TIPC))
+ if (unlikely((m->msg_namelen < sizeof(*dest)) ||
+ (dest->family != AF_TIPC)))
return -EINVAL;
needs_conn = (sock->state != SS_READY);
return -ENOTCONN;
}
+ if (unlikely(m->msg_name))
+ return -EISCONN;
+
/*
* Send each iovec entry using one or more messages
*
curr_iovlen = m->msg_iovlen;
my_msg.msg_iov = &my_iov;
my_msg.msg_iovlen = 1;
+ my_msg.msg_flags = m->msg_flags;
+ my_msg.msg_name = NULL;
bytes_sent = 0;
while (curr_iovlen--) {
int sz_to_copy;
int sz_copied = 0;
int needed;
- char *crs = m->msg_iov->iov_base;
+ char __user *crs = m->msg_iov->iov_base;
unsigned char *buf_crs;
u32 err;
int res;
restart:
if (unlikely((skb_queue_len(&sock->sk->sk_receive_queue) == 0) &&
(flags & MSG_DONTWAIT))) {
- res = (sz_copied == 0) ? -EWOULDBLOCK : 0;
+ res = -EWOULDBLOCK;
goto exit;
}
exit:
up(&tsock->sem);
- return res ? res : sz_copied;
+ return sz_copied ? sz_copied : res;
}
/**
atomic_inc(&tipc_queue_size);
skb_queue_tail(&sock->sk->sk_receive_queue, buf);
- wake_up_interruptible(sock->sk->sk_sleep);
+ if (waitqueue_active(sock->sk->sk_sleep))
+ wake_up_interruptible(sock->sk->sk_sleep);
return TIPC_OK;
}
{
struct tipc_sock *tsock = (struct tipc_sock *)tport->usr_handle;
- wake_up_interruptible(tsock->sk.sk_sleep);
+ if (waitqueue_active(tsock->sk.sk_sleep))
+ wake_up_interruptible(tsock->sk.sk_sleep);
}
/**
if (sock->state == SS_READY)
return -EOPNOTSUPP;
- /* MOVE THE REST OF THIS ERROR CHECKING TO send_msg()? */
+ /* Issue Posix-compliant error code if socket is in the wrong state */
+
if (sock->state == SS_LISTENING)
return -EOPNOTSUPP;
if (sock->state == SS_CONNECTING)
if (sock->state != SS_UNCONNECTED)
return -EISCONN;
- if ((destlen < sizeof(*dst)) || (dst->family != AF_TIPC) ||
- ((dst->addrtype != TIPC_ADDR_NAME) && (dst->addrtype != TIPC_ADDR_ID)))
+ /*
+ * Reject connection attempt using multicast address
+ *
+ * Note: send_msg() validates the rest of the address fields,
+ * so there's no need to do it here
+ */
+
+ if (dst->addrtype == TIPC_ADDR_MCAST)
return -EINVAL;
/* Send a 'SYN-' to destination */
m.msg_name = dest;
+ m.msg_namelen = destlen;
if ((res = send_msg(NULL, sock, &m, 0)) < 0) {
sock->state = SS_DISCONNECTING;
return res;
return -ENOPROTOOPT;
if (ol < sizeof(value))
return -EINVAL;
- if ((res = get_user(value, (u32 *)ov)))
+ if ((res = get_user(value, (u32 __user *)ov)))
return res;
if (down_interruptible(&tsock->sem))
*/
static int getsockopt(struct socket *sock,
- int lvl, int opt, char __user *ov, int *ol)
+ int lvl, int opt, char __user *ov, int __user *ol)
{
struct tipc_sock *tsock = tipc_sk(sock->sk);
int len;