|
@@ -3939,7 +3939,6 @@ SCTP_STATIC int sctp_do_peeloff(struct sctp_association *asoc,
|
|
|
{
|
|
|
struct sock *sk = asoc->base.sk;
|
|
|
struct socket *sock;
|
|
|
- struct inet_sock *inetsk;
|
|
|
struct sctp_af *af;
|
|
|
int err = 0;
|
|
|
|
|
@@ -3954,18 +3953,18 @@ SCTP_STATIC int sctp_do_peeloff(struct sctp_association *asoc,
|
|
|
if (err < 0)
|
|
|
return err;
|
|
|
|
|
|
- /* Populate the fields of the newsk from the oldsk and migrate the
|
|
|
- * asoc to the newsk.
|
|
|
- */
|
|
|
- sctp_sock_migrate(sk, sock->sk, asoc, SCTP_SOCKET_UDP_HIGH_BANDWIDTH);
|
|
|
+ sctp_copy_sock(sock->sk, sk, asoc);
|
|
|
|
|
|
/* Make peeled-off sockets more like 1-1 accepted sockets.
|
|
|
* Set the daddr and initialize id to something more random
|
|
|
*/
|
|
|
af = sctp_get_af_specific(asoc->peer.primary_addr.sa.sa_family);
|
|
|
af->to_sk_daddr(&asoc->peer.primary_addr, sk);
|
|
|
- inetsk = inet_sk(sock->sk);
|
|
|
- inetsk->id = asoc->next_tsn ^ jiffies;
|
|
|
+
|
|
|
+ /* Populate the fields of the newsk from the oldsk and migrate the
|
|
|
+ * asoc to the newsk.
|
|
|
+ */
|
|
|
+ sctp_sock_migrate(sk, sock->sk, asoc, SCTP_SOCKET_UDP_HIGH_BANDWIDTH);
|
|
|
|
|
|
*sockp = sock;
|
|
|
|
|
@@ -6700,6 +6699,48 @@ done:
|
|
|
sctp_skb_set_owner_r(skb, sk);
|
|
|
}
|
|
|
|
|
|
+void sctp_copy_sock(struct sock *newsk, struct sock *sk,
|
|
|
+ struct sctp_association *asoc)
|
|
|
+{
|
|
|
+ struct inet_sock *inet = inet_sk(sk);
|
|
|
+ struct inet_sock *newinet = inet_sk(newsk);
|
|
|
+
|
|
|
+ newsk->sk_type = sk->sk_type;
|
|
|
+ newsk->sk_bound_dev_if = sk->sk_bound_dev_if;
|
|
|
+ newsk->sk_flags = sk->sk_flags;
|
|
|
+ newsk->sk_no_check = sk->sk_no_check;
|
|
|
+ newsk->sk_reuse = sk->sk_reuse;
|
|
|
+
|
|
|
+ newsk->sk_shutdown = sk->sk_shutdown;
|
|
|
+ newsk->sk_destruct = inet_sock_destruct;
|
|
|
+ newsk->sk_family = sk->sk_family;
|
|
|
+ newsk->sk_protocol = IPPROTO_SCTP;
|
|
|
+ newsk->sk_backlog_rcv = sk->sk_prot->backlog_rcv;
|
|
|
+ newsk->sk_sndbuf = sk->sk_sndbuf;
|
|
|
+ newsk->sk_rcvbuf = sk->sk_rcvbuf;
|
|
|
+ newsk->sk_lingertime = sk->sk_lingertime;
|
|
|
+ newsk->sk_rcvtimeo = sk->sk_rcvtimeo;
|
|
|
+ newsk->sk_sndtimeo = sk->sk_sndtimeo;
|
|
|
+
|
|
|
+ newinet = inet_sk(newsk);
|
|
|
+
|
|
|
+ /* Initialize sk's sport, dport, rcv_saddr and daddr for
|
|
|
+ * getsockname() and getpeername()
|
|
|
+ */
|
|
|
+ newinet->sport = inet->sport;
|
|
|
+ newinet->saddr = inet->saddr;
|
|
|
+ newinet->rcv_saddr = inet->rcv_saddr;
|
|
|
+ newinet->dport = htons(asoc->peer.port);
|
|
|
+ newinet->pmtudisc = inet->pmtudisc;
|
|
|
+ newinet->id = asoc->next_tsn ^ jiffies;
|
|
|
+
|
|
|
+ newinet->uc_ttl = inet->uc_ttl;
|
|
|
+ newinet->mc_loop = 1;
|
|
|
+ newinet->mc_ttl = 1;
|
|
|
+ newinet->mc_index = 0;
|
|
|
+ newinet->mc_list = NULL;
|
|
|
+}
|
|
|
+
|
|
|
/* Populate the fields of the newsk from the oldsk and migrate the assoc
|
|
|
* and its messages to the newsk.
|
|
|
*/
|