Skip to content

Commit

Permalink
[ROSE]: Socket locking is a great invention.
Browse files Browse the repository at this point in the history
Especially if you actually try to do it ;-)

Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Ralf Baechle authored and David S. Miller committed Mar 12, 2007
1 parent 6cee77d commit 2536b94
Showing 1 changed file with 50 additions and 28 deletions.
78 changes: 50 additions & 28 deletions net/rose/af_rose.c
Original file line number Diff line number Diff line change
Expand Up @@ -700,23 +700,7 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
unsigned char cause, diagnostic;
struct net_device *dev;
ax25_uid_assoc *user;
int n;

if (sk->sk_state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) {
sock->state = SS_CONNECTED;
return 0; /* Connect completed during a ERESTARTSYS event */
}

if (sk->sk_state == TCP_CLOSE && sock->state == SS_CONNECTING) {
sock->state = SS_UNCONNECTED;
return -ECONNREFUSED;
}

if (sk->sk_state == TCP_ESTABLISHED)
return -EISCONN; /* No reconnect on a seqpacket socket */

sk->sk_state = TCP_CLOSE;
sock->state = SS_UNCONNECTED;
int n, err = 0;

if (addr_len != sizeof(struct sockaddr_rose) && addr_len != sizeof(struct full_sockaddr_rose))
return -EINVAL;
Expand All @@ -734,24 +718,53 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
if ((rose->source_ndigis + addr->srose_ndigis) > ROSE_MAX_DIGIS)
return -EINVAL;

lock_sock(sk);

if (sk->sk_state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) {
/* Connect completed during a ERESTARTSYS event */
sock->state = SS_CONNECTED;
goto out_release;
}

if (sk->sk_state == TCP_CLOSE && sock->state == SS_CONNECTING) {
sock->state = SS_UNCONNECTED;
err = -ECONNREFUSED;
goto out_release;
}

if (sk->sk_state == TCP_ESTABLISHED) {
/* No reconnect on a seqpacket socket */
err = -EISCONN;
goto out_release;
}

sk->sk_state = TCP_CLOSE;
sock->state = SS_UNCONNECTED;

rose->neighbour = rose_get_neigh(&addr->srose_addr, &cause,
&diagnostic);
if (!rose->neighbour)
return -ENETUNREACH;

rose->lci = rose_new_lci(rose->neighbour);
if (!rose->lci)
return -ENETUNREACH;
if (!rose->lci) {
err = -ENETUNREACH;
goto out_release;
}

if (sock_flag(sk, SOCK_ZAPPED)) { /* Must bind first - autobinding in this may or may not work */
sock_reset_flag(sk, SOCK_ZAPPED);

if ((dev = rose_dev_first()) == NULL)
return -ENETUNREACH;
if ((dev = rose_dev_first()) == NULL) {
err = -ENETUNREACH;
goto out_release;
}

user = ax25_findbyuid(current->euid);
if (!user)
return -EINVAL;
if (!user) {
err = -EINVAL;
goto out_release;
}

memcpy(&rose->source_addr, dev->dev_addr, ROSE_ADDR_LEN);
rose->source_call = user->call;
Expand Down Expand Up @@ -789,8 +802,10 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
rose_start_t1timer(sk);

/* Now the loop */
if (sk->sk_state != TCP_ESTABLISHED && (flags & O_NONBLOCK))
return -EINPROGRESS;
if (sk->sk_state != TCP_ESTABLISHED && (flags & O_NONBLOCK)) {
err = -EINPROGRESS;
goto out_release;
}

/*
* A Connect Ack with Choke or timeout or failed routing will go to
Expand All @@ -805,8 +820,10 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
set_current_state(TASK_INTERRUPTIBLE);
if (sk->sk_state != TCP_SYN_SENT)
break;
release_sock(sk);
if (!signal_pending(tsk)) {
schedule();
lock_sock(sk);
continue;
}
current->state = TASK_RUNNING;
Expand All @@ -822,14 +839,19 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
rose->neighbour = rose_get_neigh(&addr->srose_addr, &cause, &diagnostic);
if (rose->neighbour)
goto rose_try_next_neigh;
/* No more neighbour */

/* No more neighbours */
sock->state = SS_UNCONNECTED;
return sock_error(sk); /* Always set at this point */
err = sock_error(sk); /* Always set at this point */
goto out_release;
}

sock->state = SS_CONNECTED;

return 0;
out_release:
release_sock(sk);

return err;
}

static int rose_accept(struct socket *sock, struct socket *newsock, int flags)
Expand Down

0 comments on commit 2536b94

Please sign in to comment.