本文整理汇总了C++中release_sock函数的典型用法代码示例。如果您正苦于以下问题:C++ release_sock函数的具体用法?C++ release_sock怎么用?C++ release_sock使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了release_sock函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: connect
static int connect(struct socket *sock, struct sockaddr *dest, int destlen,
int flags)
{
struct sock *sk = sock->sk;
struct sockaddr_tipc *dst = (struct sockaddr_tipc *)dest;
struct msghdr m = {NULL,};
struct sk_buff *buf;
struct tipc_msg *msg;
unsigned int timeout;
int res;
lock_sock(sk);
/* For now, TIPC does not allow use of connect() with DGRAM/RDM types */
if (sock->state == SS_READY) {
res = -EOPNOTSUPP;
goto exit;
}
/* For now, TIPC does not support the non-blocking form of connect() */
if (flags & O_NONBLOCK) {
res = -EOPNOTSUPP;
goto exit;
}
/* Issue Posix-compliant error code if socket is in the wrong state */
if (sock->state == SS_LISTENING) {
res = -EOPNOTSUPP;
goto exit;
}
if (sock->state == SS_CONNECTING) {
res = -EALREADY;
goto exit;
}
if (sock->state != SS_UNCONNECTED) {
res = -EISCONN;
goto exit;
}
/*
* 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) {
res = -EINVAL;
goto exit;
}
/* Reject any messages already in receive queue (very unlikely) */
reject_rx_queue(sk);
/* Send a 'SYN-' to destination */
m.msg_name = dest;
m.msg_namelen = destlen;
res = send_msg(NULL, sock, &m, 0);
if (res < 0)
goto exit;
/* Wait until an 'ACK' or 'RST' arrives, or a timeout occurs */
timeout = tipc_sk(sk)->conn_timeout;
release_sock(sk);
res = wait_event_interruptible_timeout(*sk_sleep(sk),
(!skb_queue_empty(&sk->sk_receive_queue) ||
(sock->state != SS_CONNECTING)),
timeout ? (long)msecs_to_jiffies(timeout)
: MAX_SCHEDULE_TIMEOUT);
lock_sock(sk);
if (res > 0) {
buf = skb_peek(&sk->sk_receive_queue);
if (buf != NULL) {
msg = buf_msg(buf);
res = auto_connect(sock, msg);
if (!res) {
if (!msg_data_sz(msg))
advance_rx_queue(sk);
}
} else {
if (sock->state == SS_CONNECTED)
res = -EISCONN;
else
res = -ECONNREFUSED;
}
} else {
if (res == 0)
res = -ETIMEDOUT;
else
; /* leave "res" unchanged */
sock->state = SS_DISCONNECTING;
}
//.........这里部分代码省略.........
示例2: l2cap_sock_setsockopt
//.........这里部分代码省略.........
if (get_user(opt, (u32 __user *) optval)) {
err = -EFAULT;
break;
}
bt_sk(sk)->defer_setup = opt;
break;
case BT_POWER:
if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
&& sk->sk_type != SOCK_RAW) {
err = -EINVAL;
break;
}
pwr.force_active = 1;
len = min_t(unsigned int, sizeof(pwr), optlen);
if (copy_from_user((char *) &pwr, optval, len)) {
err = -EFAULT;
break;
}
l2cap_pi(sk)->force_active = pwr.force_active;
break;
case BT_AMP_POLICY:
if (get_user(opt, (u32 __user *) optval)) {
err = -EFAULT;
break;
}
if ((opt > BT_AMP_POLICY_PREFER_AMP) ||
((l2cap_pi(sk)->mode != L2CAP_MODE_ERTM) &&
(l2cap_pi(sk)->mode != L2CAP_MODE_STREAMING))) {
err = -EINVAL;
break;
}
l2cap_pi(sk)->amp_pref = (u8) opt;
BT_DBG("BT_AMP_POLICY now %d", opt);
if ((sk->sk_state == BT_CONNECTED) &&
(l2cap_pi(sk)->amp_move_role == L2CAP_AMP_MOVE_NONE))
l2cap_amp_move_init(sk);
break;
case BT_FLUSHABLE:
if (get_user(opt, (u32 __user *) optval)) {
err = -EFAULT;
break;
}
l2cap_pi(sk)->flushable = opt;
break;
case BT_LE_PARAMS:
if (l2cap_pi(sk)->scid != L2CAP_CID_LE_DATA) {
err = -EINVAL;
break;
}
if (copy_from_user((char *) &le_params, optval,
sizeof(struct bt_le_params))) {
err = -EFAULT;
break;
}
conn = l2cap_pi(sk)->conn;
if (!conn || !conn->hcon ||
l2cap_pi(sk)->scid != L2CAP_CID_LE_DATA) {
memcpy(&bt_sk(sk)->le_params, &le_params,
sizeof(le_params));
break;
}
if (!conn->hcon->out ||
!l2cap_sock_le_conn_update_params_valid(
&le_params)) {
err = -EINVAL;
break;
}
memcpy(&bt_sk(sk)->le_params, &le_params, sizeof(le_params));
hci_le_conn_update(conn->hcon,
le_params.interval_min,
le_params.interval_max,
le_params.latency,
le_params.supervision_timeout);
break;
default:
err = -ENOPROTOOPT;
break;
}
release_sock(sk);
return err;
}
示例3: raw_bind
static int raw_bind(struct socket *sock, struct sockaddr *uaddr, int len)
{
struct sockaddr_can *addr = (struct sockaddr_can *)uaddr;
struct sock *sk = sock->sk;
struct raw_sock *ro = raw_sk(sk);
int ifindex;
int err = 0;
int notify_enetdown = 0;
if (len < sizeof(*addr))
return -EINVAL;
lock_sock(sk);
if (ro->bound && addr->can_ifindex == ro->ifindex)
goto out;
if (addr->can_ifindex) {
struct net_device *dev;
dev = dev_get_by_index(&init_net, addr->can_ifindex);
if (!dev) {
err = -ENODEV;
goto out;
}
if (dev->type != ARPHRD_CAN) {
dev_put(dev);
err = -ENODEV;
goto out;
}
if (!(dev->flags & IFF_UP))
notify_enetdown = 1;
ifindex = dev->ifindex;
/* filters set by default/setsockopt */
err = raw_enable_allfilters(dev, sk);
dev_put(dev);
} else {
ifindex = 0;
/* filters set by default/setsockopt */
err = raw_enable_allfilters(NULL, sk);
}
if (!err) {
if (ro->bound) {
/* unregister old filters */
if (ro->ifindex) {
struct net_device *dev;
dev = dev_get_by_index(&init_net, ro->ifindex);
if (dev) {
raw_disable_allfilters(dev, sk);
dev_put(dev);
}
} else
raw_disable_allfilters(NULL, sk);
}
ro->ifindex = ifindex;
ro->bound = 1;
}
out:
release_sock(sk);
if (notify_enetdown) {
sk->sk_err = ENETDOWN;
if (!sock_flag(sk, SOCK_DEAD))
sk->sk_error_report(sk);
}
return err;
}
示例4: l2cap_sock_connect
static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
{
struct sock *sk = sock->sk;
struct sockaddr_l2 la;
int len, err = 0;
BT_DBG("sk %p type %d mode %d state %d", sk, sk->sk_type,
l2cap_pi(sk)->mode, sk->sk_state);
if (!addr || alen < sizeof(addr->sa_family) ||
addr->sa_family != AF_BLUETOOTH)
return -EINVAL;
memset(&la, 0, sizeof(la));
len = min_t(unsigned int, sizeof(la), alen);
memcpy(&la, addr, len);
if (la.l2_cid && la.l2_psm)
return -EINVAL;
lock_sock(sk);
if ((sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM)
&& !(la.l2_psm || la.l2_cid || l2cap_pi(sk)->fixed_channel)) {
err = -EINVAL;
goto done;
}
switch (l2cap_pi(sk)->mode) {
case L2CAP_MODE_BASIC:
break;
case L2CAP_MODE_ERTM:
case L2CAP_MODE_STREAMING:
if (!disable_ertm)
break;
/* fall through */
default:
err = -ENOTSUPP;
goto done;
}
switch (sk->sk_state) {
case BT_CONNECT:
case BT_CONNECT2:
case BT_CONFIG:
/* Already connecting */
goto wait;
case BT_CONNECTED:
/* Already connected */
err = -EISCONN;
goto done;
case BT_OPEN:
case BT_BOUND:
/* Can connect */
break;
default:
err = -EBADFD;
goto done;
}
/* PSM must be odd and lsb of upper byte must be 0 */
if ((__le16_to_cpu(la.l2_psm) & 0x0101) != 0x0001 &&
!l2cap_pi(sk)->fixed_channel &&
sk->sk_type != SOCK_RAW && !la.l2_cid) {
BT_DBG("Bad PSM 0x%x", (int)__le16_to_cpu(la.l2_psm));
err = -EINVAL;
goto done;
}
/* Set destination address and psm */
bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr);
l2cap_pi(sk)->psm = la.l2_psm;
l2cap_pi(sk)->dcid = la.l2_cid;
err = l2cap_do_connect(sk);
if (err)
goto done;
wait:
err = bt_sock_wait_state(sk, BT_CONNECTED,
sock_sndtimeo(sk, flags & O_NONBLOCK));
done:
if (err)
BT_ERR("failed %d", err);
release_sock(sk);
return err;
}
示例5: l2cap_sock_getsockopt
static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
{
struct sock *sk = sock->sk;
struct bt_security sec;
struct bt_power pwr;
int len, err = 0;
BT_DBG("sk %p", sk);
if (level == SOL_L2CAP)
return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);
if (level != SOL_BLUETOOTH)
return -ENOPROTOOPT;
if (get_user(len, optlen))
return -EFAULT;
lock_sock(sk);
switch (optname) {
case BT_SECURITY:
if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
&& sk->sk_type != SOCK_RAW) {
err = -EINVAL;
break;
}
memset(&sec, 0, sizeof(sec));
sec.level = l2cap_pi(sk)->sec_level;
if (sk->sk_state == BT_CONNECTED) {
sec.key_size = l2cap_pi(sk)->conn->hcon->enc_key_size;
sec.level = l2cap_pi(sk)->conn->hcon->sec_level;
}
len = min_t(unsigned int, len, sizeof(sec));
if (copy_to_user(optval, (char *) &sec, len))
err = -EFAULT;
break;
case BT_DEFER_SETUP:
if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
err = -EINVAL;
break;
}
if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval))
err = -EFAULT;
break;
case BT_POWER:
if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
&& sk->sk_type != SOCK_RAW) {
err = -EINVAL;
break;
}
pwr.force_active = l2cap_pi(sk)->force_active;
len = min_t(unsigned int, len, sizeof(pwr));
if (copy_to_user(optval, (char *) &pwr, len))
err = -EFAULT;
break;
case BT_AMP_POLICY:
if (put_user(l2cap_pi(sk)->amp_pref, (u32 __user *) optval))
err = -EFAULT;
break;
case BT_LE_PARAMS:
if (l2cap_pi(sk)->scid != L2CAP_CID_LE_DATA) {
err = -EINVAL;
break;
}
if (copy_to_user(optval, (char *) &bt_sk(sk)->le_params,
sizeof(bt_sk(sk)->le_params)))
err = -EFAULT;
break;
default:
err = -ENOPROTOOPT;
break;
}
release_sock(sk);
return err;
}
示例6: dccp_close
void dccp_close(struct sock *sk, long timeout)
{
struct dccp_sock *dp = dccp_sk(sk);
struct sk_buff *skb;
u32 data_was_unread = 0;
int state;
lock_sock(sk);
sk->sk_shutdown = SHUTDOWN_MASK;
if (sk->sk_state == DCCP_LISTEN) {
dccp_set_state(sk, DCCP_CLOSED);
/* Special case. */
inet_csk_listen_stop(sk);
goto adjudge_to_death;
}
sk_stop_timer(sk, &dp->dccps_xmit_timer);
/*
* We need to flush the recv. buffs. We do this only on the
* descriptor close, not protocol-sourced closes, because the
*reader process may not have drained the data yet!
*/
while ((skb = __skb_dequeue(&sk->sk_receive_queue)) != NULL) {
data_was_unread += skb->len;
__kfree_skb(skb);
}
if (data_was_unread) {
/* Unread data was tossed, send an appropriate Reset Code */
DCCP_WARN("DCCP: ABORT -- %u bytes unread\n", data_was_unread);
dccp_send_reset(sk, DCCP_RESET_CODE_ABORTED);
dccp_set_state(sk, DCCP_CLOSED);
} else if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) {
/* Check zero linger _after_ checking for unread data. */
sk->sk_prot->disconnect(sk, 0);
} else if (sk->sk_state != DCCP_CLOSED) {
dccp_terminate_connection(sk);
}
sk_stream_wait_close(sk, timeout);
adjudge_to_death:
state = sk->sk_state;
sock_hold(sk);
sock_orphan(sk);
/*
* It is the last release_sock in its life. It will remove backlog.
*/
release_sock(sk);
/*
* Now socket is owned by kernel and we acquire BH lock
* to finish close. No need to check for user refs.
*/
local_bh_disable();
bh_lock_sock(sk);
WARN_ON(sock_owned_by_user(sk));
percpu_counter_inc(sk->sk_prot->orphan_count);
/* Have we already been destroyed by a softirq or backlog? */
if (state != DCCP_CLOSED && sk->sk_state == DCCP_CLOSED)
goto out;
if (sk->sk_state == DCCP_CLOSED)
inet_csk_destroy_sock(sk);
/* Otherwise, socket is reprieved until protocol close. */
out:
bh_unlock_sock(sk);
local_bh_enable();
sock_put(sk);
}
示例7: raw_getsockopt
static int raw_getsockopt(struct socket *sock, int level, int optname,
char __user *optval, int __user *optlen)
{
struct sock *sk = sock->sk;
struct raw_sock *ro = raw_sk(sk);
int len;
void *val;
int err = 0;
if (level != SOL_CAN_RAW)
return -EINVAL;
if (get_user(len, optlen))
return -EFAULT;
if (len < 0)
return -EINVAL;
switch (optname) {
case CAN_RAW_FILTER:
lock_sock(sk);
if (ro->count > 0) {
int fsize = ro->count * sizeof(struct can_filter);
if (len > fsize)
len = fsize;
if (copy_to_user(optval, ro->filter, len))
err = -EFAULT;
} else
len = 0;
release_sock(sk);
if (!err)
err = put_user(len, optlen);
return err;
case CAN_RAW_ERR_FILTER:
if (len > sizeof(can_err_mask_t))
len = sizeof(can_err_mask_t);
val = &ro->err_mask;
break;
case CAN_RAW_LOOPBACK:
if (len > sizeof(int))
len = sizeof(int);
val = &ro->loopback;
break;
case CAN_RAW_RECV_OWN_MSGS:
if (len > sizeof(int))
len = sizeof(int);
val = &ro->recv_own_msgs;
break;
default:
return -ENOPROTOOPT;
}
if (put_user(len, optlen))
return -EFAULT;
if (copy_to_user(optval, val, len))
return -EFAULT;
return 0;
}
示例8: send_stream
static int send_stream(struct kiocb *iocb, struct socket *sock,
struct msghdr *m, size_t total_len)
{
struct sock *sk = sock->sk;
struct tipc_port *tport = tipc_sk_port(sk);
struct msghdr my_msg;
struct iovec my_iov;
struct iovec *curr_iov;
int curr_iovlen;
char __user *curr_start;
u32 hdr_size;
int curr_left;
int bytes_to_send;
int bytes_sent;
int res;
lock_sock(sk);
/* Handle special cases where there is no connection */
if (unlikely(sock->state != SS_CONNECTED)) {
if (sock->state == SS_UNCONNECTED) {
res = send_packet(NULL, sock, m, total_len);
goto exit;
} else if (sock->state == SS_DISCONNECTING) {
res = -EPIPE;
goto exit;
} else {
res = -ENOTCONN;
goto exit;
}
}
if (unlikely(m->msg_name)) {
res = -EISCONN;
goto exit;
}
if ((total_len > (unsigned)INT_MAX) ||
(m->msg_iovlen > (unsigned)INT_MAX)) {
res = -EMSGSIZE;
goto exit;
}
/*
* Send each iovec entry using one or more messages
*
* Note: This algorithm is good for the most likely case
* (i.e. one large iovec entry), but could be improved to pass sets
* of small iovec entries into send_packet().
*/
curr_iov = m->msg_iov;
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;
hdr_size = msg_hdr_sz(&tport->phdr);
while (curr_iovlen--) {
curr_start = curr_iov->iov_base;
curr_left = curr_iov->iov_len;
while (curr_left) {
bytes_to_send = tport->max_pkt - hdr_size;
if (bytes_to_send > TIPC_MAX_USER_MSG_SIZE)
bytes_to_send = TIPC_MAX_USER_MSG_SIZE;
if (curr_left < bytes_to_send)
bytes_to_send = curr_left;
my_iov.iov_base = curr_start;
my_iov.iov_len = bytes_to_send;
res = send_packet(NULL, sock, &my_msg, bytes_to_send);
if (res < 0) {
if (bytes_sent)
res = bytes_sent;
goto exit;
}
curr_left -= bytes_to_send;
curr_start += bytes_to_send;
bytes_sent += bytes_to_send;
}
curr_iov++;
}
res = bytes_sent;
exit:
release_sock(sk);
return res;
}
示例9: recv_msg
static int recv_msg(struct kiocb *iocb, struct socket *sock,
struct msghdr *m, size_t buf_len, int flags)
{
struct sock *sk = sock->sk;
struct tipc_port *tport = tipc_sk_port(sk);
struct sk_buff *buf;
struct tipc_msg *msg;
long timeout;
unsigned int sz;
u32 err;
int res;
/* Catch invalid receive requests */
if (unlikely(!buf_len))
return -EINVAL;
lock_sock(sk);
if (unlikely(sock->state == SS_UNCONNECTED)) {
res = -ENOTCONN;
goto exit;
}
timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
restart:
/* Look for a message in receive queue; wait if necessary */
while (skb_queue_empty(&sk->sk_receive_queue)) {
if (sock->state == SS_DISCONNECTING) {
res = -ENOTCONN;
goto exit;
}
if (timeout <= 0L) {
res = timeout ? timeout : -EWOULDBLOCK;
goto exit;
}
release_sock(sk);
timeout = wait_event_interruptible_timeout(*sk_sleep(sk),
tipc_rx_ready(sock),
timeout);
lock_sock(sk);
}
/* Look at first message in receive queue */
buf = skb_peek(&sk->sk_receive_queue);
msg = buf_msg(buf);
sz = msg_data_sz(msg);
err = msg_errcode(msg);
/* Complete connection setup for an implied connect */
if (unlikely(sock->state == SS_CONNECTING)) {
res = auto_connect(sock, msg);
if (res)
goto exit;
}
/* Discard an empty non-errored message & try again */
if ((!sz) && (!err)) {
advance_rx_queue(sk);
goto restart;
}
/* Capture sender's address (optional) */
set_orig_addr(m, msg);
/* Capture ancillary data (optional) */
res = anc_data_recv(m, msg, tport);
if (res)
goto exit;
/* Capture message data (if valid) & compute return value (always) */
if (!err) {
if (unlikely(buf_len < sz)) {
sz = buf_len;
m->msg_flags |= MSG_TRUNC;
}
res = skb_copy_datagram_iovec(buf, msg_hdr_sz(msg),
m->msg_iov, sz);
if (res)
goto exit;
res = sz;
} else {
if ((sock->state == SS_READY) ||
((err == TIPC_CONN_SHUTDOWN) || m->msg_control))
res = 0;
else
res = -ECONNRESET;
}
/* Consume received message (optional) */
if (likely(!(flags & MSG_PEEK))) {
//.........这里部分代码省略.........
示例10: send_msg
static int send_msg(struct kiocb *iocb, struct socket *sock,
struct msghdr *m, size_t total_len)
{
struct sock *sk = sock->sk;
struct tipc_port *tport = tipc_sk_port(sk);
struct sockaddr_tipc *dest = (struct sockaddr_tipc *)m->msg_name;
int needs_conn;
long timeout_val;
int res = -EINVAL;
if (unlikely(!dest))
return -EDESTADDRREQ;
if (unlikely((m->msg_namelen < sizeof(*dest)) ||
(dest->family != AF_TIPC)))
return -EINVAL;
if ((total_len > TIPC_MAX_USER_MSG_SIZE) ||
(m->msg_iovlen > (unsigned)INT_MAX))
return -EMSGSIZE;
if (iocb)
lock_sock(sk);
needs_conn = (sock->state != SS_READY);
if (unlikely(needs_conn)) {
if (sock->state == SS_LISTENING) {
res = -EPIPE;
goto exit;
}
if (sock->state != SS_UNCONNECTED) {
res = -EISCONN;
goto exit;
}
if ((tport->published) ||
((sock->type == SOCK_STREAM) && (total_len != 0))) {
res = -EOPNOTSUPP;
goto exit;
}
if (dest->addrtype == TIPC_ADDR_NAME) {
tport->conn_type = dest->addr.name.name.type;
tport->conn_instance = dest->addr.name.name.instance;
}
/* Abort any pending connection attempts (very unlikely) */
reject_rx_queue(sk);
}
timeout_val = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT);
do {
if (dest->addrtype == TIPC_ADDR_NAME) {
res = dest_name_check(dest, m);
if (res)
break;
res = tipc_send2name(tport->ref,
&dest->addr.name.name,
dest->addr.name.domain,
m->msg_iovlen,
m->msg_iov,
total_len);
} else if (dest->addrtype == TIPC_ADDR_ID) {
res = tipc_send2port(tport->ref,
&dest->addr.id,
m->msg_iovlen,
m->msg_iov,
total_len);
} else if (dest->addrtype == TIPC_ADDR_MCAST) {
if (needs_conn) {
res = -EOPNOTSUPP;
break;
}
res = dest_name_check(dest, m);
if (res)
break;
res = tipc_multicast(tport->ref,
&dest->addr.nameseq,
m->msg_iovlen,
m->msg_iov,
total_len);
}
if (likely(res != -ELINKCONG)) {
if (needs_conn && (res >= 0))
sock->state = SS_CONNECTING;
break;
}
if (timeout_val <= 0L) {
res = timeout_val ? timeout_val : -EWOULDBLOCK;
break;
}
release_sock(sk);
timeout_val = wait_event_interruptible_timeout(*sk_sleep(sk),
!tport->congested, timeout_val);
lock_sock(sk);
} while (1);
exit:
if (iocb)
release_sock(sk);
return res;
}
示例11: release
static int release(struct socket *sock)
{
struct sock *sk = sock->sk;
struct tipc_port *tport;
struct sk_buff *buf;
int res;
/*
* Exit if socket isn't fully initialized (occurs when a failed accept()
* releases a pre-allocated child socket that was never used)
*/
if (sk == NULL)
return 0;
tport = tipc_sk_port(sk);
lock_sock(sk);
/*
* Reject all unreceived messages, except on an active connection
* (which disconnects locally & sends a 'FIN+' to peer)
*/
while (sock->state != SS_DISCONNECTING) {
buf = __skb_dequeue(&sk->sk_receive_queue);
if (buf == NULL)
break;
atomic_dec(&tipc_queue_size);
if (TIPC_SKB_CB(buf)->handle != 0)
kfree_skb(buf);
else {
if ((sock->state == SS_CONNECTING) ||
(sock->state == SS_CONNECTED)) {
sock->state = SS_DISCONNECTING;
tipc_disconnect(tport->ref);
}
tipc_reject_msg(buf, TIPC_ERR_NO_PORT);
}
}
/*
* Delete TIPC port; this ensures no more messages are queued
* (also disconnects an active connection & sends a 'FIN-' to peer)
*/
res = tipc_deleteport(tport->ref);
/* Discard any remaining (connection-based) messages in receive queue */
discard_rx_queue(sk);
/* Reject any messages that accumulated in backlog queue */
sock->state = SS_DISCONNECTING;
release_sock(sk);
sock_put(sk);
sock->sk = NULL;
return res;
}
示例12: accept
static int accept(struct socket *sock, struct socket *new_sock, int flags)
{
struct sock *sk = sock->sk;
struct sk_buff *buf;
int res;
lock_sock(sk);
if (sock->state != SS_LISTENING) {
res = -EINVAL;
goto exit;
}
while (skb_queue_empty(&sk->sk_receive_queue)) {
if (flags & O_NONBLOCK) {
res = -EWOULDBLOCK;
goto exit;
}
release_sock(sk);
res = wait_event_interruptible(*sk_sleep(sk),
(!skb_queue_empty(&sk->sk_receive_queue)));
lock_sock(sk);
if (res)
goto exit;
}
buf = skb_peek(&sk->sk_receive_queue);
res = tipc_create(sock_net(sock->sk), new_sock, 0, 0);
if (!res) {
struct sock *new_sk = new_sock->sk;
struct tipc_sock *new_tsock = tipc_sk(new_sk);
struct tipc_port *new_tport = new_tsock->p;
u32 new_ref = new_tport->ref;
struct tipc_msg *msg = buf_msg(buf);
lock_sock(new_sk);
/*
* Reject any stray messages received by new socket
* before the socket lock was taken (very, very unlikely)
*/
reject_rx_queue(new_sk);
/* Connect new socket to it's peer */
new_tsock->peer_name.ref = msg_origport(msg);
new_tsock->peer_name.node = msg_orignode(msg);
tipc_connect2port(new_ref, &new_tsock->peer_name);
new_sock->state = SS_CONNECTED;
tipc_set_portimportance(new_ref, msg_importance(msg));
if (msg_named(msg)) {
new_tport->conn_type = msg_nametype(msg);
new_tport->conn_instance = msg_nameinst(msg);
}
/*
* Respond to 'SYN-' by discarding it & returning 'ACK'-.
* Respond to 'SYN+' by queuing it on new socket.
*/
if (!msg_data_sz(msg)) {
struct msghdr m = {NULL,};
advance_rx_queue(sk);
send_packet(NULL, new_sock, &m, 0);
} else {
__skb_dequeue(&sk->sk_receive_queue);
__skb_queue_head(&new_sk->sk_receive_queue, buf);
}
release_sock(new_sk);
}
exit:
release_sock(sk);
return res;
}
示例13: sock_setsockopt
//.........这里部分代码省略.........
case SO_TIMESTAMP:
sk->sk_rcvtstamp = valbool;
break;
case SO_RCVLOWAT:
if (val < 0)
val = INT_MAX;
sk->sk_rcvlowat = val ? : 1;
break;
case SO_RCVTIMEO:
ret = sock_set_timeout(&sk->sk_rcvtimeo, optval, optlen);
break;
case SO_SNDTIMEO:
ret = sock_set_timeout(&sk->sk_sndtimeo, optval, optlen);
break;
#ifdef CONFIG_NETDEVICES
case SO_BINDTODEVICE:
{
char devname[IFNAMSIZ];
/* Sorry... */
if (!capable(CAP_NET_RAW)) {
ret = -EPERM;
break;
}
/* Bind this socket to a particular device like "eth0",
* as specified in the passed interface name. If the
* name is "" or the option length is zero the socket
* is not bound.
*/
if (!valbool) {
sk->sk_bound_dev_if = 0;
} else {
if (optlen > IFNAMSIZ)
optlen = IFNAMSIZ;
if (copy_from_user(devname, optval, optlen)) {
ret = -EFAULT;
break;
}
/* Remove any cached route for this socket. */
sk_dst_reset(sk);
if (devname[0] == '\0') {
sk->sk_bound_dev_if = 0;
} else {
struct net_device *dev = dev_get_by_name(devname);
if (!dev) {
ret = -ENODEV;
break;
}
sk->sk_bound_dev_if = dev->ifindex;
dev_put(dev);
}
}
break;
}
#endif
case SO_ATTACH_FILTER:
ret = -EINVAL;
if (optlen == sizeof(struct sock_fprog)) {
struct sock_fprog fprog;
ret = -EFAULT;
if (copy_from_user(&fprog, optval, sizeof(fprog)))
break;
ret = sk_attach_filter(&fprog, sk);
}
break;
case SO_DETACH_FILTER:
spin_lock_bh(&sk->sk_lock.slock);
filter = sk->sk_filter;
if (filter) {
sk->sk_filter = NULL;
spin_unlock_bh(&sk->sk_lock.slock);
sk_filter_release(sk, filter);
break;
}
spin_unlock_bh(&sk->sk_lock.slock);
ret = -ENONET;
break;
/* We implement the SO_SNDLOWAT etc to
not be settable (1003.1g 5.3) */
default:
ret = -ENOPROTOOPT;
break;
}
release_sock(sk);
return ret;
}
示例14: ipv6_setsockopt
//.........这里部分代码省略.........
if (retv)
break;
omode = MCAST_INCLUDE;
add = 1;
} else /*IP_DROP_SOURCE_MEMBERSHIP */ {
omode = MCAST_INCLUDE;
add = 0;
}
retv = ip6_mc_source(add, omode, sk, &greqs);
break;
}
case MCAST_MSFILTER:
{
extern int sysctl_optmem_max;
extern int sysctl_mld_max_msf;
struct group_filter *gsf;
if (optlen < GROUP_FILTER_SIZE(0))
goto e_inval;
if (optlen > sysctl_optmem_max) {
retv = -ENOBUFS;
break;
}
gsf = (struct group_filter *)kmalloc(optlen,GFP_KERNEL);
if (gsf == 0) {
retv = -ENOBUFS;
break;
}
retv = -EFAULT;
if (copy_from_user(gsf, optval, optlen)) {
kfree(gsf);
break;
}
/* numsrc >= (4G-140)/128 overflow in 32 bits */
if (gsf->gf_numsrc >= 0x1ffffffU ||
gsf->gf_numsrc > sysctl_mld_max_msf) {
kfree(gsf);
retv = -ENOBUFS;
break;
}
if (GROUP_FILTER_SIZE(gsf->gf_numsrc) > optlen) {
kfree(gsf);
retv = -EINVAL;
break;
}
retv = ip6_mc_msfilter(sk, gsf);
kfree(gsf);
break;
}
case IPV6_ROUTER_ALERT:
retv = ip6_ra_control(sk, val, NULL);
break;
case IPV6_MTU_DISCOVER:
if (val<0 || val>2)
goto e_inval;
np->pmtudisc = val;
retv = 0;
break;
case IPV6_MTU:
if (val && val < IPV6_MIN_MTU)
goto e_inval;
np->frag_size = val;
retv = 0;
break;
case IPV6_RECVERR:
np->recverr = valbool;
if (!val)
skb_queue_purge(&sk->sk_error_queue);
retv = 0;
break;
case IPV6_FLOWINFO_SEND:
np->sndflow = valbool;
retv = 0;
break;
case IPV6_FLOWLABEL_MGR:
retv = ipv6_flowlabel_opt(sk, optval, optlen);
break;
case IPV6_IPSEC_POLICY:
case IPV6_XFRM_POLICY:
retv = xfrm_user_policy(sk, optname, optval, optlen);
break;
#ifdef CONFIG_NETFILTER
default:
retv = nf_setsockopt(sk, PF_INET6, optname, optval,
optlen);
break;
#endif
}
release_sock(sk);
out:
return retv;
e_inval:
release_sock(sk);
return -EINVAL;
}
示例15: dccp_recvmsg
//.........这里部分代码省略.........
lock_sock(sk);
if (sk->sk_state == DCCP_LISTEN) {
len = -ENOTCONN;
goto out;
}
timeo = sock_rcvtimeo(sk, nonblock);
do {
struct sk_buff *skb = skb_peek(&sk->sk_receive_queue);
if (skb == NULL)
goto verify_sock_status;
dh = dccp_hdr(skb);
switch (dh->dccph_type) {
case DCCP_PKT_DATA:
case DCCP_PKT_DATAACK:
goto found_ok_skb;
case DCCP_PKT_CLOSE:
case DCCP_PKT_CLOSEREQ:
if (!(flags & MSG_PEEK))
dccp_finish_passive_close(sk);
/* fall through */
case DCCP_PKT_RESET:
dccp_pr_debug("found fin (%s) ok!\n",
dccp_packet_name(dh->dccph_type));
len = 0;
goto found_fin_ok;
default:
dccp_pr_debug("packet_type=%s\n",
dccp_packet_name(dh->dccph_type));
sk_eat_skb(sk, skb, 0);
}
verify_sock_status:
if (sock_flag(sk, SOCK_DONE)) {
len = 0;
break;
}
if (sk->sk_err) {
len = sock_error(sk);
break;
}
if (sk->sk_shutdown & RCV_SHUTDOWN) {
len = 0;
break;
}
if (sk->sk_state == DCCP_CLOSED) {
if (!sock_flag(sk, SOCK_DONE)) {
/* This occurs when user tries to read
* from never connected socket.
*/
len = -ENOTCONN;
break;
}
len = 0;
break;
}
if (!timeo) {
len = -EAGAIN;
break;
}
if (signal_pending(current)) {
len = sock_intr_errno(timeo);
break;
}
sk_wait_data(sk, &timeo);
continue;
found_ok_skb:
if (len > skb->len)
len = skb->len;
else if (len < skb->len)
msg->msg_flags |= MSG_TRUNC;
if (skb_copy_datagram_iovec(skb, 0, msg->msg_iov, len)) {
/* Exception. Bailout! */
len = -EFAULT;
break;
}
if (flags & MSG_TRUNC)
len = skb->len;
found_fin_ok:
if (!(flags & MSG_PEEK))
sk_eat_skb(sk, skb, 0);
break;
} while (1);
out:
release_sock(sk);
return len;
}