* [PATCH net] sctp: return a one-to-one type socket when doing peeloff
@ 2020-03-02 6:57 Xin Long
2020-03-03 18:38 ` Leppanen, Jere (Nokia - FI/Espoo)
2020-03-10 1:09 ` David Miller
0 siblings, 2 replies; 10+ messages in thread
From: Xin Long @ 2020-03-02 6:57 UTC (permalink / raw)
To: network dev, linux-sctp
Cc: davem, Marcelo Ricardo Leitner, Neil Horman, jere.leppanen,
michael.tuexen
As it says in rfc6458#section-9.2:
The application uses the sctp_peeloff() call to branch off an
association into a separate socket. (Note that the semantics are
somewhat changed from the traditional one-to-one style accept()
call.) Note also that the new socket is a one-to-one style socket.
Thus, it will be confined to operations allowed for a one-to-one
style socket.
Prior to this patch, sctp_peeloff() returned a one-to-many type socket,
on which some operations are not allowed, like shutdown, as Jere
reported.
This patch is to change it to return a one-to-one type socket instead.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reported-by: Leppanen, Jere (Nokia - FI/Espoo) <jere.leppanen@nokia.com>
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
net/sctp/socket.c | 15 ++++++---------
1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 1b56fc4..2b55beb 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -88,8 +88,7 @@ static int sctp_send_asconf(struct sctp_association *asoc,
static int sctp_do_bind(struct sock *, union sctp_addr *, int);
static int sctp_autobind(struct sock *sk);
static int sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
- struct sctp_association *assoc,
- enum sctp_socket_type type);
+ struct sctp_association *assoc);
static unsigned long sctp_memory_pressure;
static atomic_long_t sctp_memory_allocated;
@@ -4965,7 +4964,7 @@ static struct sock *sctp_accept(struct sock *sk, int flags, int *err, bool kern)
/* Populate the fields of the newsk from the oldsk and migrate the
* asoc to the newsk.
*/
- error = sctp_sock_migrate(sk, newsk, asoc, SCTP_SOCKET_TCP);
+ error = sctp_sock_migrate(sk, newsk, asoc);
if (error) {
sk_common_release(newsk);
newsk = NULL;
@@ -5711,7 +5710,7 @@ int sctp_do_peeloff(struct sock *sk, sctp_assoc_t id, struct socket **sockp)
return -EINVAL;
/* Create a new socket. */
- err = sock_create(sk->sk_family, SOCK_SEQPACKET, IPPROTO_SCTP, &sock);
+ err = sock_create(sk->sk_family, SOCK_STREAM, IPPROTO_SCTP, &sock);
if (err < 0)
return err;
@@ -5727,8 +5726,7 @@ int sctp_do_peeloff(struct sock *sk, sctp_assoc_t id, struct socket **sockp)
/* Populate the fields of the newsk from the oldsk and migrate the
* asoc to the newsk.
*/
- err = sctp_sock_migrate(sk, sock->sk, asoc,
- SCTP_SOCKET_UDP_HIGH_BANDWIDTH);
+ err = sctp_sock_migrate(sk, sock->sk, asoc);
if (err) {
sock_release(sock);
sock = NULL;
@@ -9453,8 +9451,7 @@ static inline void sctp_copy_descendant(struct sock *sk_to,
* and its messages to the newsk.
*/
static int sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
- struct sctp_association *assoc,
- enum sctp_socket_type type)
+ struct sctp_association *assoc)
{
struct sctp_sock *oldsp = sctp_sk(oldsk);
struct sctp_sock *newsp = sctp_sk(newsk);
@@ -9562,7 +9559,7 @@ static int sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
* original UDP-style socket or created with the accept() call on a
* TCP-style socket..
*/
- newsp->type = type;
+ newsp->type = SCTP_SOCKET_TCP;
/* Mark the new socket "in-use" by the user so that any packets
* that may arrive on the association after we've moved it are
--
2.1.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* RE: [PATCH net] sctp: return a one-to-one type socket when doing peeloff
2020-03-02 6:57 [PATCH net] sctp: return a one-to-one type socket when doing peeloff Xin Long
@ 2020-03-03 18:38 ` Leppanen, Jere (Nokia - FI/Espoo)
2020-03-04 9:38 ` Xin Long
2020-03-10 1:09 ` David Miller
1 sibling, 1 reply; 10+ messages in thread
From: Leppanen, Jere (Nokia - FI/Espoo) @ 2020-03-03 18:38 UTC (permalink / raw)
To: Xin Long, network dev, linux-sctp
Cc: davem, Marcelo Ricardo Leitner, Neil Horman, michael.tuexen
On Mon, 2 Mar 2020, Xin Long wrote:
> As it says in rfc6458#section-9.2:
>
> The application uses the sctp_peeloff() call to branch off an
> association into a separate socket. (Note that the semantics are
> somewhat changed from the traditional one-to-one style accept()
> call.) Note also that the new socket is a one-to-one style socket.
> Thus, it will be confined to operations allowed for a one-to-one
> style socket.
>
> Prior to this patch, sctp_peeloff() returned a one-to-many type socket,
> on which some operations are not allowed, like shutdown, as Jere
> reported.
>
> This patch is to change it to return a one-to-one type socket instead.
Thanks for looking into this. I like the patch, and it fixes my simple
test case.
But with this patch, peeled-off sockets are created by copying from a
one-to-many socket to a one-to-one socket. Are you sure that that's
not going to cause any problems? Is it possible that there was a
reason why peeloff wasn't implemented this way in the first place?
With this patch there's no way to create UDP_HIGH_BANDWIDTH style
sockets anymore, so the remaining references should probably be
cleaned up:
./net/sctp/socket.c:1886: if (!sctp_style(sk, UDP_HIGH_BANDWIDTH) && msg->msg_name) {
./net/sctp/socket.c:8522: if (sctp_style(sk, UDP_HIGH_BANDWIDTH))
./include/net/sctp/structs.h:144: SCTP_SOCKET_UDP_HIGH_BANDWIDTH,
This patch disables those checks. The first one ignores a destination
address given to sendmsg() with a peeled-off socket - I don't know
why. The second one prevents listen() on a peeled-off socket.
>
> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> Reported-by: Leppanen, Jere (Nokia - FI/Espoo) <jere.leppanen@nokia.com>
Reported-by: Jere Leppanen <jere.leppanen@nokia.com>
> Signed-off-by: Xin Long <lucien.xin@gmail.com>
> ---
> net/sctp/socket.c | 15 ++++++---------
> 1 file changed, 6 insertions(+), 9 deletions(-)
>
> diff --git a/net/sctp/socket.c b/net/sctp/socket.c
> index 1b56fc4..2b55beb 100644
> --- a/net/sctp/socket.c
> +++ b/net/sctp/socket.c
> @@ -88,8 +88,7 @@ static int sctp_send_asconf(struct sctp_association *asoc,
> static int sctp_do_bind(struct sock *, union sctp_addr *, int);
> static int sctp_autobind(struct sock *sk);
> static int sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
> - struct sctp_association *assoc,
> - enum sctp_socket_type type);
> + struct sctp_association *assoc);
>
> static unsigned long sctp_memory_pressure;
> static atomic_long_t sctp_memory_allocated;
> @@ -4965,7 +4964,7 @@ static struct sock *sctp_accept(struct sock *sk, int flags, int *err, bool kern)
> /* Populate the fields of the newsk from the oldsk and migrate the
> * asoc to the newsk.
> */
> - error = sctp_sock_migrate(sk, newsk, asoc, SCTP_SOCKET_TCP);
> + error = sctp_sock_migrate(sk, newsk, asoc);
> if (error) {
> sk_common_release(newsk);
> newsk = NULL;
> @@ -5711,7 +5710,7 @@ int sctp_do_peeloff(struct sock *sk, sctp_assoc_t id, struct socket **sockp)
> return -EINVAL;
>
> /* Create a new socket. */
> - err = sock_create(sk->sk_family, SOCK_SEQPACKET, IPPROTO_SCTP, &sock);
> + err = sock_create(sk->sk_family, SOCK_STREAM, IPPROTO_SCTP, &sock);
> if (err < 0)
> return err;
>
> @@ -5727,8 +5726,7 @@ int sctp_do_peeloff(struct sock *sk, sctp_assoc_t id, struct socket **sockp)
> /* Populate the fields of the newsk from the oldsk and migrate the
> * asoc to the newsk.
> */
> - err = sctp_sock_migrate(sk, sock->sk, asoc,
> - SCTP_SOCKET_UDP_HIGH_BANDWIDTH);
> + err = sctp_sock_migrate(sk, sock->sk, asoc);
> if (err) {
> sock_release(sock);
> sock = NULL;
> @@ -9453,8 +9451,7 @@ static inline void sctp_copy_descendant(struct sock *sk_to,
> * and its messages to the newsk.
> */
> static int sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
> - struct sctp_association *assoc,
> - enum sctp_socket_type type)
> + struct sctp_association *assoc)
> {
> struct sctp_sock *oldsp = sctp_sk(oldsk);
> struct sctp_sock *newsp = sctp_sk(newsk);
> @@ -9562,7 +9559,7 @@ static int sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
> * original UDP-style socket or created with the accept() call on a
> * TCP-style socket..
> */
> - newsp->type = type;
> + newsp->type = SCTP_SOCKET_TCP;
>
> /* Mark the new socket "in-use" by the user so that any packets
> * that may arrive on the association after we've moved it are
> --
> 2.1.0
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH net] sctp: return a one-to-one type socket when doing peeloff
2020-03-03 18:38 ` Leppanen, Jere (Nokia - FI/Espoo)
@ 2020-03-04 9:38 ` Xin Long
2020-03-04 17:13 ` Jere Leppanen
0 siblings, 1 reply; 10+ messages in thread
From: Xin Long @ 2020-03-04 9:38 UTC (permalink / raw)
To: Leppanen, Jere (Nokia - FI/Espoo)
Cc: network dev, linux-sctp, davem, Marcelo Ricardo Leitner,
Neil Horman, michael.tuexen
On Wed, Mar 4, 2020 at 2:38 AM Leppanen, Jere (Nokia - FI/Espoo)
<jere.leppanen@nokia.com> wrote:
>
> On Mon, 2 Mar 2020, Xin Long wrote:
>
> > As it says in rfc6458#section-9.2:
> >
> > The application uses the sctp_peeloff() call to branch off an
> > association into a separate socket. (Note that the semantics are
> > somewhat changed from the traditional one-to-one style accept()
> > call.) Note also that the new socket is a one-to-one style socket.
> > Thus, it will be confined to operations allowed for a one-to-one
> > style socket.
> >
> > Prior to this patch, sctp_peeloff() returned a one-to-many type socket,
> > on which some operations are not allowed, like shutdown, as Jere
> > reported.
> >
> > This patch is to change it to return a one-to-one type socket instead.
>
> Thanks for looking into this. I like the patch, and it fixes my simple
> test case.
>
> But with this patch, peeled-off sockets are created by copying from a
> one-to-many socket to a one-to-one socket. Are you sure that that's
> not going to cause any problems? Is it possible that there was a
> reason why peeloff wasn't implemented this way in the first place?
I'm not sure, it's been there since very beginning, and I couldn't find
any changelog about it.
I guess it was trying to differentiate peeled-off socket from TCP style
sockets.
>
> With this patch there's no way to create UDP_HIGH_BANDWIDTH style
> sockets anymore, so the remaining references should probably be
> cleaned up:
>
> ./net/sctp/socket.c:1886: if (!sctp_style(sk, UDP_HIGH_BANDWIDTH) && msg->msg_name) {
> ./net/sctp/socket.c:8522: if (sctp_style(sk, UDP_HIGH_BANDWIDTH))
> ./include/net/sctp/structs.h:144: SCTP_SOCKET_UDP_HIGH_BANDWIDTH,
>
> This patch disables those checks. The first one ignores a destination
> address given to sendmsg() with a peeled-off socket - I don't know
> why. The second one prevents listen() on a peeled-off socket.
My understanding is:
UDP_HIGH_BANDWIDTH is another kind of one-to-one socket, like TCP style.
it can get asoc by its socket when sending msg, doesn't need daddr.
Now I thinking to fix your issue in sctp_shutdown():
@@ -5163,7 +5163,7 @@ static void sctp_shutdown(struct sock *sk, int how)
struct net *net = sock_net(sk);
struct sctp_endpoint *ep;
- if (!sctp_style(sk, TCP))
+ if (sctp_style(sk, UDP))
return;
in this way, we actually think:
one-to-many socket: UDP style socket
one-to-one socket includes: UDP_HIGH_BANDWIDTH and TCP style sockets.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH net] sctp: return a one-to-one type socket when doing peeloff
2020-03-04 9:38 ` Xin Long
@ 2020-03-04 17:13 ` Jere Leppanen
2020-03-05 14:01 ` David Laight
2020-03-11 3:34 ` Marcelo Ricardo Leitner
0 siblings, 2 replies; 10+ messages in thread
From: Jere Leppanen @ 2020-03-04 17:13 UTC (permalink / raw)
To: Xin Long
Cc: network dev, linux-sctp, davem, Marcelo Ricardo Leitner,
Neil Horman, michael.tuexen
On Wed, 4 Mar 2020, Xin Long wrote:
> On Wed, Mar 4, 2020 at 2:38 AM Leppanen, Jere (Nokia - FI/Espoo)
> <jere.leppanen@nokia.com> wrote:
>>
>> On Mon, 2 Mar 2020, Xin Long wrote:
>>
>>> As it says in rfc6458#section-9.2:
>>>
>>> The application uses the sctp_peeloff() call to branch off an
>>> association into a separate socket. (Note that the semantics are
>>> somewhat changed from the traditional one-to-one style accept()
>>> call.) Note also that the new socket is a one-to-one style socket.
>>> Thus, it will be confined to operations allowed for a one-to-one
>>> style socket.
>>>
>>> Prior to this patch, sctp_peeloff() returned a one-to-many type socket,
>>> on which some operations are not allowed, like shutdown, as Jere
>>> reported.
>>>
>>> This patch is to change it to return a one-to-one type socket instead.
>>
>> Thanks for looking into this. I like the patch, and it fixes my simple
>> test case.
>>
>> But with this patch, peeled-off sockets are created by copying from a
>> one-to-many socket to a one-to-one socket. Are you sure that that's
>> not going to cause any problems? Is it possible that there was a
>> reason why peeloff wasn't implemented this way in the first place?
> I'm not sure, it's been there since very beginning, and I couldn't find
> any changelog about it.
>
> I guess it was trying to differentiate peeled-off socket from TCP style
> sockets.
Well, that's probably the reason for UDP_HIGH_BANDWIDTH style. And maybe
there is legitimate need for that differentiation in some cases, but I
think inventing a special socket style is not the best way to handle it.
But actually I meant why is a peeled-off socket created as SOCK_SEQPACKET
instead of SOCK_STREAM. It could be to avoid copying from SOCK_SEQPACKET
to SOCK_STREAM, but why would we need to avoid that?
Mark Butler commented in 2006
(https://sourceforge.net/p/lksctp/mailman/message/10122693/):
In short, SOCK_SEQPACKET could/should be replaced with SOCK_STREAM
right there, but there might be a minor dependency or two that would
need to be fixed.
>
>>
>> With this patch there's no way to create UDP_HIGH_BANDWIDTH style
>> sockets anymore, so the remaining references should probably be
>> cleaned up:
>>
>> ./net/sctp/socket.c:1886: if (!sctp_style(sk, UDP_HIGH_BANDWIDTH) && msg->msg_name) {
>> ./net/sctp/socket.c:8522: if (sctp_style(sk, UDP_HIGH_BANDWIDTH))
>> ./include/net/sctp/structs.h:144: SCTP_SOCKET_UDP_HIGH_BANDWIDTH,
>>
>> This patch disables those checks. The first one ignores a destination
>> address given to sendmsg() with a peeled-off socket - I don't know
>> why. The second one prevents listen() on a peeled-off socket.
> My understanding is:
> UDP_HIGH_BANDWIDTH is another kind of one-to-one socket, like TCP style.
> it can get asoc by its socket when sending msg, doesn't need daddr.
But on that association, the peer may have multiple addresses. The RFC
says (https://tools.ietf.org/html/rfc6458#section-4.1.8):
When sending, the msg_name field [...] is used to indicate a preferred
peer address if the sender wishes to discourage the stack from sending
the message to the primary address of the receiver.
>
> Now I thinking to fix your issue in sctp_shutdown():
>
> @@ -5163,7 +5163,7 @@ static void sctp_shutdown(struct sock *sk, int how)
> struct net *net = sock_net(sk);
> struct sctp_endpoint *ep;
>
> - if (!sctp_style(sk, TCP))
> + if (sctp_style(sk, UDP))
> return;
>
> in this way, we actually think:
> one-to-many socket: UDP style socket
> one-to-one socket includes: UDP_HIGH_BANDWIDTH and TCP style sockets.
>
That would probably fix shutdown(), but there are other problems as well.
sctp_style() is called in nearly a hundred different places, I wonder if
anyone systematically went through all of them back when
UDP_HIGH_BANDWIDTH was added.
I think getting rid of UDP_HIGH_BANDWIDTH altogether is a much cleaner
solution. That's what your patch does, which is why I like it. But such a
change could easily break something.
^ permalink raw reply [flat|nested] 10+ messages in thread
* RE: [PATCH net] sctp: return a one-to-one type socket when doing peeloff
2020-03-04 17:13 ` Jere Leppanen
@ 2020-03-05 14:01 ` David Laight
2020-03-05 17:31 ` Jere Leppanen
2020-03-11 3:34 ` Marcelo Ricardo Leitner
1 sibling, 1 reply; 10+ messages in thread
From: David Laight @ 2020-03-05 14:01 UTC (permalink / raw)
To: 'Jere Leppanen', Xin Long
Cc: network dev, linux-sctp, davem, Marcelo Ricardo Leitner,
Neil Horman, michael.tuexen
From: Jere Leppanen
> Sent: 04 March 2020 17:13
> On Wed, 4 Mar 2020, Xin Long wrote:
>
> > On Wed, Mar 4, 2020 at 2:38 AM Leppanen, Jere (Nokia - FI/Espoo)
> > <jere.leppanen@nokia.com> wrote:
> >>
> >> On Mon, 2 Mar 2020, Xin Long wrote:
> >>
> >>> As it says in rfc6458#section-9.2:
> >>>
> >>> The application uses the sctp_peeloff() call to branch off an
> >>> association into a separate socket. (Note that the semantics are
> >>> somewhat changed from the traditional one-to-one style accept()
> >>> call.) Note also that the new socket is a one-to-one style socket.
> >>> Thus, it will be confined to operations allowed for a one-to-one
> >>> style socket.
> >>>
> >>> Prior to this patch, sctp_peeloff() returned a one-to-many type socket,
> >>> on which some operations are not allowed, like shutdown, as Jere
> >>> reported.
> >>>
> >>> This patch is to change it to return a one-to-one type socket instead.
> >>
> >> Thanks for looking into this. I like the patch, and it fixes my simple
> >> test case.
> >>
> >> But with this patch, peeled-off sockets are created by copying from a
> >> one-to-many socket to a one-to-one socket. Are you sure that that's
> >> not going to cause any problems? Is it possible that there was a
> >> reason why peeloff wasn't implemented this way in the first place?
> > I'm not sure, it's been there since very beginning, and I couldn't find
> > any changelog about it.
> >
> > I guess it was trying to differentiate peeled-off socket from TCP style
> > sockets.
>
> Well, that's probably the reason for UDP_HIGH_BANDWIDTH style. And maybe
> there is legitimate need for that differentiation in some cases, but I
> think inventing a special socket style is not the best way to handle it.
>
> But actually I meant why is a peeled-off socket created as SOCK_SEQPACKET
> instead of SOCK_STREAM. It could be to avoid copying from SOCK_SEQPACKET
> to SOCK_STREAM, but why would we need to avoid that?
Because you don't want all the acks and retransmissions??
David
-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)
^ permalink raw reply [flat|nested] 10+ messages in thread
* RE: [PATCH net] sctp: return a one-to-one type socket when doing peeloff
2020-03-05 14:01 ` David Laight
@ 2020-03-05 17:31 ` Jere Leppanen
0 siblings, 0 replies; 10+ messages in thread
From: Jere Leppanen @ 2020-03-05 17:31 UTC (permalink / raw)
To: David Laight
Cc: Xin Long, network dev, linux-sctp, davem,
Marcelo Ricardo Leitner, Neil Horman, michael.tuexen
On Thu, 5 Mar 2020, David Laight wrote:
> From: Jere Leppanen
> > Sent: 04 March 2020 17:13
> > On Wed, 4 Mar 2020, Xin Long wrote:
> >
> > > On Wed, Mar 4, 2020 at 2:38 AM Leppanen, Jere (Nokia - FI/Espoo)
> > > <jere.leppanen@nokia.com> wrote:
> > >>
> > >> On Mon, 2 Mar 2020, Xin Long wrote:
> > >>
> > >>> As it says in rfc6458#section-9.2:
> > >>>
> > >>> The application uses the sctp_peeloff() call to branch off an
> > >>> association into a separate socket. (Note that the semantics are
> > >>> somewhat changed from the traditional one-to-one style accept()
> > >>> call.) Note also that the new socket is a one-to-one style socket.
> > >>> Thus, it will be confined to operations allowed for a one-to-one
> > >>> style socket.
> > >>>
> > >>> Prior to this patch, sctp_peeloff() returned a one-to-many type socket,
> > >>> on which some operations are not allowed, like shutdown, as Jere
> > >>> reported.
> > >>>
> > >>> This patch is to change it to return a one-to-one type socket instead.
> > >>
> > >> Thanks for looking into this. I like the patch, and it fixes my simple
> > >> test case.
> > >>
> > >> But with this patch, peeled-off sockets are created by copying from a
> > >> one-to-many socket to a one-to-one socket. Are you sure that that's
> > >> not going to cause any problems? Is it possible that there was a
> > >> reason why peeloff wasn't implemented this way in the first place?
> > > I'm not sure, it's been there since very beginning, and I couldn't find
> > > any changelog about it.
> > >
> > > I guess it was trying to differentiate peeled-off socket from TCP style
> > > sockets.
> >
> > Well, that's probably the reason for UDP_HIGH_BANDWIDTH style. And maybe
> > there is legitimate need for that differentiation in some cases, but I
> > think inventing a special socket style is not the best way to handle it.
> >
> > But actually I meant why is a peeled-off socket created as SOCK_SEQPACKET
> > instead of SOCK_STREAM. It could be to avoid copying from SOCK_SEQPACKET
> > to SOCK_STREAM, but why would we need to avoid that?
>
> Because you don't want all the acks and retransmissions??
I don't follow. The socket type and style have virtually no effect on the
protocol side of things, I think.
>
> David
>
> -
> Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
> Registration No: 1397386 (Wales)
>
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH net] sctp: return a one-to-one type socket when doing peeloff
2020-03-02 6:57 [PATCH net] sctp: return a one-to-one type socket when doing peeloff Xin Long
2020-03-03 18:38 ` Leppanen, Jere (Nokia - FI/Espoo)
@ 2020-03-10 1:09 ` David Miller
2020-03-11 3:35 ` Marcelo Ricardo Leitner
1 sibling, 1 reply; 10+ messages in thread
From: David Miller @ 2020-03-10 1:09 UTC (permalink / raw)
To: lucien.xin
Cc: netdev, linux-sctp, marcelo.leitner, nhorman, jere.leppanen,
michael.tuexen
From: Xin Long <lucien.xin@gmail.com>
Date: Mon, 2 Mar 2020 14:57:15 +0800
> As it says in rfc6458#section-9.2:
>
> The application uses the sctp_peeloff() call to branch off an
> association into a separate socket. (Note that the semantics are
> somewhat changed from the traditional one-to-one style accept()
> call.) Note also that the new socket is a one-to-one style socket.
> Thus, it will be confined to operations allowed for a one-to-one
> style socket.
>
> Prior to this patch, sctp_peeloff() returned a one-to-many type socket,
> on which some operations are not allowed, like shutdown, as Jere
> reported.
>
> This patch is to change it to return a one-to-one type socket instead.
>
> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> Reported-by: Leppanen, Jere (Nokia - FI/Espoo) <jere.leppanen@nokia.com>
> Signed-off-by: Xin Long <lucien.xin@gmail.com>
I don't know what to do with this patch.
There seems to be some discussion about a potential alternative approach
to the fix, but there were problems with that suggestion.
Please advise, thank you.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH net] sctp: return a one-to-one type socket when doing peeloff
2020-03-04 17:13 ` Jere Leppanen
2020-03-05 14:01 ` David Laight
@ 2020-03-11 3:34 ` Marcelo Ricardo Leitner
2020-03-11 18:41 ` Jere Leppanen
1 sibling, 1 reply; 10+ messages in thread
From: Marcelo Ricardo Leitner @ 2020-03-11 3:34 UTC (permalink / raw)
To: Jere Leppanen
Cc: Xin Long, network dev, linux-sctp, davem, Neil Horman, michael.tuexen
On Wed, Mar 04, 2020 at 07:13:14PM +0200, Jere Leppanen wrote:
> On Wed, 4 Mar 2020, Xin Long wrote:
>
> > On Wed, Mar 4, 2020 at 2:38 AM Leppanen, Jere (Nokia - FI/Espoo)
> > <jere.leppanen@nokia.com> wrote:
> > >
> > > On Mon, 2 Mar 2020, Xin Long wrote:
> > >
> > > > As it says in rfc6458#section-9.2:
> > > >
> > > > The application uses the sctp_peeloff() call to branch off an
> > > > association into a separate socket. (Note that the semantics are
> > > > somewhat changed from the traditional one-to-one style accept()
> > > > call.) Note also that the new socket is a one-to-one style socket.
> > > > Thus, it will be confined to operations allowed for a one-to-one
> > > > style socket.
> > > >
> > > > Prior to this patch, sctp_peeloff() returned a one-to-many type socket,
> > > > on which some operations are not allowed, like shutdown, as Jere
> > > > reported.
> > > >
> > > > This patch is to change it to return a one-to-one type socket instead.
> > >
> > > Thanks for looking into this. I like the patch, and it fixes my simple
> > > test case.
> > >
> > > But with this patch, peeled-off sockets are created by copying from a
> > > one-to-many socket to a one-to-one socket. Are you sure that that's
> > > not going to cause any problems? Is it possible that there was a
> > > reason why peeloff wasn't implemented this way in the first place?
> > I'm not sure, it's been there since very beginning, and I couldn't find
> > any changelog about it.
> >
> > I guess it was trying to differentiate peeled-off socket from TCP style
> > sockets.
Me too.
>
> Well, that's probably the reason for UDP_HIGH_BANDWIDTH style. And maybe
> there is legitimate need for that differentiation in some cases, but I think
> inventing a special socket style is not the best way to handle it.
I agree, but.. (in the end of the email)
>
> But actually I meant why is a peeled-off socket created as SOCK_SEQPACKET
> instead of SOCK_STREAM. It could be to avoid copying from SOCK_SEQPACKET to
> SOCK_STREAM, but why would we need to avoid that?
>
> Mark Butler commented in 2006
> (https://sourceforge.net/p/lksctp/mailman/message/10122693/):
>
> In short, SOCK_SEQPACKET could/should be replaced with SOCK_STREAM
> right there, but there might be a minor dependency or two that would
> need to be fixed.
>
> >
> > >
> > > With this patch there's no way to create UDP_HIGH_BANDWIDTH style
> > > sockets anymore, so the remaining references should probably be
> > > cleaned up:
> > >
> > > ./net/sctp/socket.c:1886: if (!sctp_style(sk, UDP_HIGH_BANDWIDTH) && msg->msg_name) {
> > > ./net/sctp/socket.c:8522: if (sctp_style(sk, UDP_HIGH_BANDWIDTH))
> > > ./include/net/sctp/structs.h:144: SCTP_SOCKET_UDP_HIGH_BANDWIDTH,
> > >
> > > This patch disables those checks. The first one ignores a destination
> > > address given to sendmsg() with a peeled-off socket - I don't know
> > > why. The second one prevents listen() on a peeled-off socket.
> > My understanding is:
> > UDP_HIGH_BANDWIDTH is another kind of one-to-one socket, like TCP style.
> > it can get asoc by its socket when sending msg, doesn't need daddr.
>
> But on that association, the peer may have multiple addresses. The RFC says
> (https://tools.ietf.org/html/rfc6458#section-4.1.8):
>
> When sending, the msg_name field [...] is used to indicate a preferred
> peer address if the sender wishes to discourage the stack from sending
> the message to the primary address of the receiver.
Which means the currect check in 1886 is wrong and should be fixed regardless.
>
> >
> > Now I thinking to fix your issue in sctp_shutdown():
> >
> > @@ -5163,7 +5163,7 @@ static void sctp_shutdown(struct sock *sk, int how)
> > struct net *net = sock_net(sk);
> > struct sctp_endpoint *ep;
> >
> > - if (!sctp_style(sk, TCP))
> > + if (sctp_style(sk, UDP))
> > return;
> >
> > in this way, we actually think:
> > one-to-many socket: UDP style socket
> > one-to-one socket includes: UDP_HIGH_BANDWIDTH and TCP style sockets.
> >
>
> That would probably fix shutdown(), but there are other problems as well.
> sctp_style() is called in nearly a hundred different places, I wonder if
> anyone systematically went through all of them back when UDP_HIGH_BANDWIDTH
> was added.
I suppose, and with no grounds, just random thoughts, that
UDP_HIGH_BANDWIDTH is a left-over from an early draft/implementation.
>
> I think getting rid of UDP_HIGH_BANDWIDTH altogether is a much cleaner
> solution. That's what your patch does, which is why I like it. But such a
> change could easily break something.
Xin's initial patch here or this without backward compatibility, will
create some user-noticeable differences, yes. For example, in
sctp_recvmsg():
if (sctp_style(sk, TCP) && !sctp_sstate(sk, ESTABLISHED) &&
!sctp_sstate(sk, CLOSING) && !sctp_sstate(sk, CLOSED)) {
err = -ENOTCONN;
goto out;
And in sctp_setsockopt_autoclose():
" * This socket option is applicable to the UDP-style socket only. When"
/* Applicable to UDP-style socket only */
if (sctp_style(sk, TCP))
return -EOPNOTSUPP;
Although on RFC it was updated to:
8.1.8. Automatic Close of Associations (SCTP_AUTOCLOSE)
This socket option is applicable to the one-to-many style socket
only.
These would start to be checked with such change. The first is a
minor, because that return code is already possible from within
sctp_wait_for_packet(), it's mostly just enforced later. But the
second.. Yes, we're violating the RFC in there, but OTOH, I'm afraid
it may be too late to fix it.
Removing UDP_HIGH_BANDWIDTH would thus require some weird checks, like
in the autoclose example above, something like:
/* Applicable to one-to-many sockets only */
if (sctp_style(sk, TCP) && !sctp_peeledoff(sk))
return -EOPNOTSUPP;
Which doesn't help much by now. Yet, maybe there is only a few cases
like this around?
Marcelo
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH net] sctp: return a one-to-one type socket when doing peeloff
2020-03-10 1:09 ` David Miller
@ 2020-03-11 3:35 ` Marcelo Ricardo Leitner
0 siblings, 0 replies; 10+ messages in thread
From: Marcelo Ricardo Leitner @ 2020-03-11 3:35 UTC (permalink / raw)
To: David Miller
Cc: lucien.xin, netdev, linux-sctp, nhorman, jere.leppanen, michael.tuexen
On Mon, Mar 09, 2020 at 06:09:49PM -0700, David Miller wrote:
> From: Xin Long <lucien.xin@gmail.com>
> Date: Mon, 2 Mar 2020 14:57:15 +0800
>
> > As it says in rfc6458#section-9.2:
> >
> > The application uses the sctp_peeloff() call to branch off an
> > association into a separate socket. (Note that the semantics are
> > somewhat changed from the traditional one-to-one style accept()
> > call.) Note also that the new socket is a one-to-one style socket.
> > Thus, it will be confined to operations allowed for a one-to-one
> > style socket.
> >
> > Prior to this patch, sctp_peeloff() returned a one-to-many type socket,
> > on which some operations are not allowed, like shutdown, as Jere
> > reported.
> >
> > This patch is to change it to return a one-to-one type socket instead.
> >
> > Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> > Reported-by: Leppanen, Jere (Nokia - FI/Espoo) <jere.leppanen@nokia.com>
> > Signed-off-by: Xin Long <lucien.xin@gmail.com>
>
> I don't know what to do with this patch.
>
> There seems to be some discussion about a potential alternative approach
> to the fix, but there were problems with that suggestion.
>
> Please advise, thank you.
Please drop it. As you noticed, we do need more discussions around
it. Thanks.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH net] sctp: return a one-to-one type socket when doing peeloff
2020-03-11 3:34 ` Marcelo Ricardo Leitner
@ 2020-03-11 18:41 ` Jere Leppanen
0 siblings, 0 replies; 10+ messages in thread
From: Jere Leppanen @ 2020-03-11 18:41 UTC (permalink / raw)
To: Marcelo Ricardo Leitner
Cc: Xin Long, network dev, linux-sctp, davem, Neil Horman, michael.tuexen
On Wed, 11 Mar 2020, Marcelo Ricardo Leitner wrote:
> On Wed, Mar 04, 2020 at 07:13:14PM +0200, Jere Leppanen wrote:
> > On Wed, 4 Mar 2020, Xin Long wrote:
> >
> > > On Wed, Mar 4, 2020 at 2:38 AM Leppanen, Jere (Nokia - FI/Espoo)
> > > <jere.leppanen@nokia.com> wrote:
> > > >
> > > > On Mon, 2 Mar 2020, Xin Long wrote:
> > > >
> > > > > As it says in rfc6458#section-9.2:
> > > > >
> > > > > The application uses the sctp_peeloff() call to branch off an
> > > > > association into a separate socket. (Note that the semantics are
> > > > > somewhat changed from the traditional one-to-one style accept()
> > > > > call.) Note also that the new socket is a one-to-one style socket.
> > > > > Thus, it will be confined to operations allowed for a one-to-one
> > > > > style socket.
> > > > >
> > > > > Prior to this patch, sctp_peeloff() returned a one-to-many type socket,
> > > > > on which some operations are not allowed, like shutdown, as Jere
> > > > > reported.
> > > > >
> > > > > This patch is to change it to return a one-to-one type socket instead.
> > > >
> > > > Thanks for looking into this. I like the patch, and it fixes my simple
> > > > test case.
> > > >
> > > > But with this patch, peeled-off sockets are created by copying from a
> > > > one-to-many socket to a one-to-one socket. Are you sure that that's
> > > > not going to cause any problems? Is it possible that there was a
> > > > reason why peeloff wasn't implemented this way in the first place?
> > > I'm not sure, it's been there since very beginning, and I couldn't find
> > > any changelog about it.
> > >
> > > I guess it was trying to differentiate peeled-off socket from TCP style
> > > sockets.
>
> Me too.
>
> >
> > Well, that's probably the reason for UDP_HIGH_BANDWIDTH style. And maybe
> > there is legitimate need for that differentiation in some cases, but I think
> > inventing a special socket style is not the best way to handle it.
>
> I agree, but.. (in the end of the email)
>
> >
> > But actually I meant why is a peeled-off socket created as SOCK_SEQPACKET
> > instead of SOCK_STREAM. It could be to avoid copying from SOCK_SEQPACKET to
> > SOCK_STREAM, but why would we need to avoid that?
> >
> > Mark Butler commented in 2006
> > (https://sourceforge.net/p/lksctp/mailman/message/10122693/):
> >
> > In short, SOCK_SEQPACKET could/should be replaced with SOCK_STREAM
> > right there, but there might be a minor dependency or two that would
> > need to be fixed.
> >
> > >
> > > >
> > > > With this patch there's no way to create UDP_HIGH_BANDWIDTH style
> > > > sockets anymore, so the remaining references should probably be
> > > > cleaned up:
> > > >
> > > > ./net/sctp/socket.c:1886: if (!sctp_style(sk, UDP_HIGH_BANDWIDTH) && msg->msg_name) {
> > > > ./net/sctp/socket.c:8522: if (sctp_style(sk, UDP_HIGH_BANDWIDTH))
> > > > ./include/net/sctp/structs.h:144: SCTP_SOCKET_UDP_HIGH_BANDWIDTH,
> > > >
> > > > This patch disables those checks. The first one ignores a destination
> > > > address given to sendmsg() with a peeled-off socket - I don't know
> > > > why. The second one prevents listen() on a peeled-off socket.
> > > My understanding is:
> > > UDP_HIGH_BANDWIDTH is another kind of one-to-one socket, like TCP style.
> > > it can get asoc by its socket when sending msg, doesn't need daddr.
> >
> > But on that association, the peer may have multiple addresses. The RFC says
> > (https://tools.ietf.org/html/rfc6458#section-4.1.8):
> >
> > When sending, the msg_name field [...] is used to indicate a preferred
> > peer address if the sender wishes to discourage the stack from sending
> > the message to the primary address of the receiver.
>
> Which means the currect check in 1886 is wrong and should be fixed regardless.
>
> >
> > >
> > > Now I thinking to fix your issue in sctp_shutdown():
> > >
> > > @@ -5163,7 +5163,7 @@ static void sctp_shutdown(struct sock *sk, int how)
> > > struct net *net = sock_net(sk);
> > > struct sctp_endpoint *ep;
> > >
> > > - if (!sctp_style(sk, TCP))
> > > + if (sctp_style(sk, UDP))
> > > return;
> > >
> > > in this way, we actually think:
> > > one-to-many socket: UDP style socket
> > > one-to-one socket includes: UDP_HIGH_BANDWIDTH and TCP style sockets.
> > >
> >
> > That would probably fix shutdown(), but there are other problems as well.
> > sctp_style() is called in nearly a hundred different places, I wonder if
> > anyone systematically went through all of them back when UDP_HIGH_BANDWIDTH
> > was added.
>
> I suppose, and with no grounds, just random thoughts, that
> UDP_HIGH_BANDWIDTH is a left-over from an early draft/implementation.
>
> >
> > I think getting rid of UDP_HIGH_BANDWIDTH altogether is a much cleaner
> > solution. That's what your patch does, which is why I like it. But such a
> > change could easily break something.
>
> Xin's initial patch here or this without backward compatibility, will
> create some user-noticeable differences, yes. For example, in
> sctp_recvmsg():
> if (sctp_style(sk, TCP) && !sctp_sstate(sk, ESTABLISHED) &&
> !sctp_sstate(sk, CLOSING) && !sctp_sstate(sk, CLOSED)) {
> err = -ENOTCONN;
> goto out;
>
> And in sctp_setsockopt_autoclose():
> " * This socket option is applicable to the UDP-style socket only. When"
> /* Applicable to UDP-style socket only */
> if (sctp_style(sk, TCP))
> return -EOPNOTSUPP;
>
> Although on RFC it was updated to:
> 8.1.8. Automatic Close of Associations (SCTP_AUTOCLOSE)
> This socket option is applicable to the one-to-many style socket
> only.
>
> These would start to be checked with such change. The first is a
> minor, because that return code is already possible from within
> sctp_wait_for_packet(), it's mostly just enforced later. But the
> second.. Yes, we're violating the RFC in there, but OTOH, I'm afraid
> it may be too late to fix it.
>
> Removing UDP_HIGH_BANDWIDTH would thus require some weird checks, like
> in the autoclose example above, something like:
> /* Applicable to one-to-many sockets only */
> if (sctp_style(sk, TCP) && !sctp_peeledoff(sk))
> return -EOPNOTSUPP;
>
> Which doesn't help much by now. Yet, maybe there is only a few cases
> like this around?
>
> Marcelo
>
Right, I agree on every point, Marcelo.
Weird checks are required regardless of whether UDP_HIGH_BANDWIDTH is
removed or not. Either way, it's probably wise to explicitly point out bug
compatibility in the code.
Removing UDP_HIGH_BANDWIDTH is in some sense cleaner, but on the other
hand, not removing it allows for smaller incremental changes. Maybe
keeping UDP_HIGH_BANDWIDTH is fine, after all. Less risk.
So due to this issue, there are probably multiple unfixable RFC violations
in place. I suppose the known problems should at least be documented
somewhere.
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2020-03-11 18:41 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-02 6:57 [PATCH net] sctp: return a one-to-one type socket when doing peeloff Xin Long
2020-03-03 18:38 ` Leppanen, Jere (Nokia - FI/Espoo)
2020-03-04 9:38 ` Xin Long
2020-03-04 17:13 ` Jere Leppanen
2020-03-05 14:01 ` David Laight
2020-03-05 17:31 ` Jere Leppanen
2020-03-11 3:34 ` Marcelo Ricardo Leitner
2020-03-11 18:41 ` Jere Leppanen
2020-03-10 1:09 ` David Miller
2020-03-11 3:35 ` Marcelo Ricardo Leitner
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).