* j1939: bind() and connect() @ 2017-08-14 17:37 Marc Kleine-Budde 2017-08-15 8:14 ` Marc Kleine-Budde 2017-08-16 9:34 ` Kurt Van Dijck 0 siblings, 2 replies; 14+ messages in thread From: Marc Kleine-Budde @ 2017-08-14 17:37 UTC (permalink / raw) To: Kurt Van Dijck, linux-can; +Cc: David Jander [-- Attachment #1.1: Type: text/plain, Size: 973 bytes --] Hello Kurt, I've a few questions about the j1939 socket model: - Should bind() be allowed to any interface, i.e. with can_ifindex == 0? I don't think so, but it's never checked for this. - Should a connect() without a previous bind() be allowed? It's not checked for, but the error handling in sk_connect doesn't take that into account. - Should a second bind() be allowed on a previously bind() socket? As far as I understand the code, there's some support, but when the interface is switched, j1939_ifindex_stop() is not called. - Should a second conect() be allowed on a previously connect() socket? Again some code, but AFAICS no real support. regards, Marc -- Pengutronix e.K. | Marc Kleine-Budde | Industrial Linux Solutions | Phone: +49-231-2826-924 | Vertretung West/Dortmund | Fax: +49-5121-206917-5555 | Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de | [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 488 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: j1939: bind() and connect() 2017-08-14 17:37 j1939: bind() and connect() Marc Kleine-Budde @ 2017-08-15 8:14 ` Marc Kleine-Budde 2017-08-15 9:01 ` David Jander 2017-08-16 9:34 ` Kurt Van Dijck 1 sibling, 1 reply; 14+ messages in thread From: Marc Kleine-Budde @ 2017-08-15 8:14 UTC (permalink / raw) To: Kurt Van Dijck, linux-can; +Cc: David Jander [-- Attachment #1.1: Type: text/plain, Size: 670 bytes --] On 08/14/2017 07:37 PM, Marc Kleine-Budde wrote: > - Should a second bind() be allowed on a previously bind() socket? > > As far as I understand the code, there's some support, but when the > interface is switched, j1939_ifindex_stop() is not called. Ah, there's a check, that you cannot re-bind() to another interface: > if (bound_dev_if != addr->can_ifindex) regards, Marc -- Pengutronix e.K. | Marc Kleine-Budde | Industrial Linux Solutions | Phone: +49-231-2826-924 | Vertretung West/Dortmund | Fax: +49-5121-206917-5555 | Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de | [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 488 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: j1939: bind() and connect() 2017-08-15 8:14 ` Marc Kleine-Budde @ 2017-08-15 9:01 ` David Jander 2017-08-15 9:16 ` Marc Kleine-Budde 0 siblings, 1 reply; 14+ messages in thread From: David Jander @ 2017-08-15 9:01 UTC (permalink / raw) To: Marc Kleine-Budde; +Cc: Kurt Van Dijck, linux-can On Tue, 15 Aug 2017 10:14:18 +0200 Marc Kleine-Budde <mkl@pengutronix.de> wrote: > On 08/14/2017 07:37 PM, Marc Kleine-Budde wrote: > > - Should a second bind() be allowed on a previously bind() socket? > > > > As far as I understand the code, there's some support, but when the > > interface is switched, j1939_ifindex_stop() is not called. > > Ah, there's a check, that you cannot re-bind() to another interface: > > > if (bound_dev_if != addr->can_ifindex) This makes sense. re-bind() to another interface only would make sense if bind() to any interface is also permitted, but that would imply separate address-claims on all different interfaces with potentially different source-address being claimed on each one.... don't think the stack should take care of such complex scenarios, at least not at first IMHO. Best regards, -- David Jander Protonic Holland. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: j1939: bind() and connect() 2017-08-15 9:01 ` David Jander @ 2017-08-15 9:16 ` Marc Kleine-Budde 2017-08-15 10:24 ` David Jander 0 siblings, 1 reply; 14+ messages in thread From: Marc Kleine-Budde @ 2017-08-15 9:16 UTC (permalink / raw) To: David Jander; +Cc: Kurt Van Dijck, linux-can [-- Attachment #1.1: Type: text/plain, Size: 1849 bytes --] On 08/15/2017 11:01 AM, David Jander wrote: > On Tue, 15 Aug 2017 10:14:18 +0200 > Marc Kleine-Budde <mkl@pengutronix.de> wrote: > >> On 08/14/2017 07:37 PM, Marc Kleine-Budde wrote: >>> - Should a second bind() be allowed on a previously bind() socket? >>> >>> As far as I understand the code, there's some support, but when the >>> interface is switched, j1939_ifindex_stop() is not called. >> >> Ah, there's a check, that you cannot re-bind() to another interface: >> >>> if (bound_dev_if != addr->can_ifindex) > > This makes sense. re-bind() to another interface only would make sense if > bind() to any interface is also permitted, but that would imply separate > address-claims on all different interfaces with potentially different > source-address being claimed on each one.... don't think the stack should take > care of such complex scenarios, at least not at first IMHO. Bind to any interface doesn't work, you cannot send anything: > static int j1939sk_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) > { [...] > ifindex = jsk->ifindex_started; > if (!ifindex) > return -EBADFD; And you will probably not receive anything, as the rx-register, which takes place in j1939_ifindex_start() is not done if you try to bind to any device (bound_dev_if == 0). > if (bound_dev_if && bound_dev_if != jsk->ifindex_started) { [...] > > ret = j1939_ifindex_start(bound_dev_if); Then I'll add proper test, that you have to bind to a specific interface. That will make the code much simpler. Marc -- Pengutronix e.K. | Marc Kleine-Budde | Industrial Linux Solutions | Phone: +49-231-2826-924 | Vertretung West/Dortmund | Fax: +49-5121-206917-5555 | Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de | [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 488 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: j1939: bind() and connect() 2017-08-15 9:16 ` Marc Kleine-Budde @ 2017-08-15 10:24 ` David Jander 2017-08-16 21:08 ` Kurt Van Dijck 0 siblings, 1 reply; 14+ messages in thread From: David Jander @ 2017-08-15 10:24 UTC (permalink / raw) To: Marc Kleine-Budde; +Cc: Kurt Van Dijck, linux-can On Tue, 15 Aug 2017 11:16:44 +0200 Marc Kleine-Budde <mkl@pengutronix.de> wrote: > On 08/15/2017 11:01 AM, David Jander wrote: > > On Tue, 15 Aug 2017 10:14:18 +0200 > > Marc Kleine-Budde <mkl@pengutronix.de> wrote: > > > >> On 08/14/2017 07:37 PM, Marc Kleine-Budde wrote: > >>> - Should a second bind() be allowed on a previously bind() socket? > >>> > >>> As far as I understand the code, there's some support, but when the > >>> interface is switched, j1939_ifindex_stop() is not called. > >> > >> Ah, there's a check, that you cannot re-bind() to another interface: > >> > >>> if (bound_dev_if != addr->can_ifindex) > > > > This makes sense. re-bind() to another interface only would make sense if > > bind() to any interface is also permitted, but that would imply separate > > address-claims on all different interfaces with potentially different > > source-address being claimed on each one.... don't think the stack should take > > care of such complex scenarios, at least not at first IMHO. > > Bind to any interface doesn't work, you cannot send anything: > > > static int j1939sk_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) > > { > [...] > > ifindex = jsk->ifindex_started; > > if (!ifindex) > > return -EBADFD; > > And you will probably not receive anything, as the rx-register, which > takes place in j1939_ifindex_start() is not done if you try to bind to > any device (bound_dev_if == 0). > > > if (bound_dev_if && bound_dev_if != jsk->ifindex_started) { > [...] > > > > ret = j1939_ifindex_start(bound_dev_if); > > Then I'll add proper test, that you have to bind to a specific > interface. That will make the code much simpler. I agree. Don't know if the case for bind-any will ever be necessary in the context of J1939, but we certainly should keep things simple for now. I've had cases myself where an ECU would talk J1939 on two interfaces at the same time, but not yet something like a Group-Function server exporting the same functions on more than one interface. I could think of that use-case happening though, but it can also be solved easily in user-space opening more than one socket... Best regards, -- David Jander Protonic Holland. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: j1939: bind() and connect() 2017-08-15 10:24 ` David Jander @ 2017-08-16 21:08 ` Kurt Van Dijck 2017-08-17 7:35 ` Marc Kleine-Budde 0 siblings, 1 reply; 14+ messages in thread From: Kurt Van Dijck @ 2017-08-16 21:08 UTC (permalink / raw) To: David Jander; +Cc: Marc Kleine-Budde, linux-can > On Tue, 15 Aug 2017 11:16:44 +0200 > Marc Kleine-Budde <mkl@pengutronix.de> wrote: > > > On 08/15/2017 11:01 AM, David Jander wrote: > > > On Tue, 15 Aug 2017 10:14:18 +0200 > > > Marc Kleine-Budde <mkl@pengutronix.de> wrote: > > > > > >> On 08/14/2017 07:37 PM, Marc Kleine-Budde wrote: > > >>> - Should a second bind() be allowed on a previously bind() socket? > > >>> > > >>> As far as I understand the code, there's some support, but when the > > >>> interface is switched, j1939_ifindex_stop() is not called. > > >> > > >> Ah, there's a check, that you cannot re-bind() to another interface: > > >> > > >>> if (bound_dev_if != addr->can_ifindex) > > > > > > This makes sense. re-bind() to another interface only would make sense if > > > bind() to any interface is also permitted, but that would imply separate > > > address-claims on all different interfaces with potentially different > > > source-address being claimed on each one.... don't think the stack should take > > > care of such complex scenarios, at least not at first IMHO. > > > > Bind to any interface doesn't work, you cannot send anything: > > > > > static int j1939sk_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) > > > { > > [...] > > > ifindex = jsk->ifindex_started; > > > if (!ifindex) > > > return -EBADFD; > > > > And you will probably not receive anything, as the rx-register, which > > takes place in j1939_ifindex_start() is not done if you try to bind to > > any device (bound_dev_if == 0). which is like calling tcpdump when the interface is down, yep. That's a stupid thing to do, but not necessarily a bad API. > > > > > if (bound_dev_if && bound_dev_if != jsk->ifindex_started) { > > [...] > > > > > > ret = j1939_ifindex_start(bound_dev_if); > > > > Then I'll add proper test, that you have to bind to a specific > > interface. That will make the code much simpler. I agree that in contrast to my initial goal, binding to any interface complicates things. Since j1939 is not a routed protocol, you should be aware of at least which interface you're running on. Userspace programs can still default to can0 :-) And it probably simplifies the socket code quite much. That's a good thing too. > > I agree. Don't know if the case for bind-any will ever be necessary in the > context of J1939, but we certainly should keep things simple for now. > I've had cases myself where an ECU would talk J1939 on two interfaces at the > same time, but not yet something like a Group-Function server exporting the > same functions on more than one interface. I could think of that use-case > happening though, but it can also be solved easily in user-space opening more > than one socket... Indeed, logical ECU's connected to 2+ j1939 busses cannot take any advantage by combining multiple interfaces. the 2+ busses will always be addressed independantly, like David suggests by opening more sockets. Kind regards, Kurt ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: j1939: bind() and connect() 2017-08-16 21:08 ` Kurt Van Dijck @ 2017-08-17 7:35 ` Marc Kleine-Budde 2017-08-17 8:28 ` Kurt Van Dijck 0 siblings, 1 reply; 14+ messages in thread From: Marc Kleine-Budde @ 2017-08-17 7:35 UTC (permalink / raw) To: David Jander, linux-can [-- Attachment #1.1: Type: text/plain, Size: 2905 bytes --] On 08/16/2017 11:08 PM, Kurt Van Dijck wrote: >>> Bind to any interface doesn't work, you cannot send anything: >>> >>>> static int j1939sk_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) >>>> { >>> [...] >>>> ifindex = jsk->ifindex_started; >>>> if (!ifindex) >>>> return -EBADFD; >>> >>> And you will probably not receive anything, as the rx-register, which >>> takes place in j1939_ifindex_start() is not done if you try to bind to >>> any device (bound_dev_if == 0). > > which is like calling tcpdump when the interface is down, yep. > That's a stupid thing to do, but not necessarily a bad API. From my point of view, you either want to do diagnostics, then you'd use tcpdump/wireshark. Or you have a legitimate application scenario, but then you don't want other applications to interfere with the packages you receive. First I want to keep it simple and allow only binds to exactly one interface. If it later turns out, that bind to any is a requirement, we can still add it. >>>> if (bound_dev_if && bound_dev_if != jsk->ifindex_started) { >>> [...] >>>> >>>> ret = j1939_ifindex_start(bound_dev_if); >>> >>> Then I'll add proper test, that you have to bind to a specific >>> interface. That will make the code much simpler. > > I agree that in contrast to my initial goal, binding to any interface > complicates things. Since j1939 is not a routed protocol, you should be > aware of at least which interface you're running on. > Userspace programs can still default to can0 :-) > > And it probably simplifies the socket code quite much. That's a good > thing too. ACK. >> I agree. Don't know if the case for bind-any will ever be necessary in the >> context of J1939, but we certainly should keep things simple for now. >> I've had cases myself where an ECU would talk J1939 on two interfaces at the >> same time, but not yet something like a Group-Function server exporting the >> same functions on more than one interface. I could think of that use-case >> happening though, but it can also be solved easily in user-space opening more >> than one socket... > > Indeed, logical ECU's connected to 2+ j1939 busses cannot take any > advantage by combining multiple interfaces. the 2+ busses will always be > addressed independantly, like David suggests by opening more sockets. Let's conclude: - bind() to any not allowed - bind() to a single interface needed before {send,rcv}_msg() - re-bind() to same interface allowed - bind() before connect() mandatory - re-connect() allowed Is this correct? regards. Marc -- Pengutronix e.K. | Marc Kleine-Budde | Industrial Linux Solutions | Phone: +49-231-2826-924 | Vertretung West/Dortmund | Fax: +49-5121-206917-5555 | Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de | [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 488 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: j1939: bind() and connect() 2017-08-17 7:35 ` Marc Kleine-Budde @ 2017-08-17 8:28 ` Kurt Van Dijck 2017-08-17 8:32 ` Marc Kleine-Budde 0 siblings, 1 reply; 14+ messages in thread From: Kurt Van Dijck @ 2017-08-17 8:28 UTC (permalink / raw) To: Marc Kleine-Budde; +Cc: David Jander, linux-can > Let's conclude: > - bind() to any not allowed > - bind() to a single interface needed before {send,rcv}_msg() > - re-bind() to same interface allowed > - bind() before connect() mandatory 4x ack > - re-connect() allowed As David pointed out, re-connect() is not necessary. If it makes things much simpler, then drop it for now. right? > > Is this correct? > > regards. > Marc ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: j1939: bind() and connect() 2017-08-17 8:28 ` Kurt Van Dijck @ 2017-08-17 8:32 ` Marc Kleine-Budde 0 siblings, 0 replies; 14+ messages in thread From: Marc Kleine-Budde @ 2017-08-17 8:32 UTC (permalink / raw) To: David Jander, linux-can [-- Attachment #1.1: Type: text/plain, Size: 719 bytes --] On 08/17/2017 10:28 AM, Kurt Van Dijck wrote: > >> Let's conclude: >> - bind() to any not allowed >> - bind() to a single interface needed before {send,rcv}_msg() >> - re-bind() to same interface allowed >> - bind() before connect() mandatory > 4x ack > >> - re-connect() allowed > > As David pointed out, re-connect() is not necessary. If it makes things > much simpler, then drop it for now. right? Fine with me. Marc -- Pengutronix e.K. | Marc Kleine-Budde | Industrial Linux Solutions | Phone: +49-231-2826-924 | Vertretung West/Dortmund | Fax: +49-5121-206917-5555 | Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de | [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 488 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: j1939: bind() and connect() 2017-08-14 17:37 j1939: bind() and connect() Marc Kleine-Budde 2017-08-15 8:14 ` Marc Kleine-Budde @ 2017-08-16 9:34 ` Kurt Van Dijck 2017-08-16 10:06 ` Marc Kleine-Budde 1 sibling, 1 reply; 14+ messages in thread From: Kurt Van Dijck @ 2017-08-16 9:34 UTC (permalink / raw) To: Marc Kleine-Budde; +Cc: linux-can, David Jander > Hello Kurt, > > I've a few questions about the j1939 socket model: > > - Should bind() be allowed to any interface, i.e. with can_ifindex == 0? > > I don't think so, but it's never checked for this. I'll explain a bit what I tried to accomplish: * allow bind to any interface, for receive packets only (obviously) * for rx/tx, only bind to 1 interface. > > - Should a connect() without a previous bind() be allowed? > > It's not checked for, but the error handling in sk_connect doesn't take > that into account. Like UDP will auto-bind to the first known local address ... Then an application would not need to know the local address to use. > > - Should a second bind() be allowed on a previously bind() socket? Yes, definitely. This is required to support dynamic addressing without possible losing relevant messages. > > As far as I understand the code, there's some support, but when the > interface is switched, j1939_ifindex_stop() is not called. > > - Should a second conect() be allowed on a previously connect() socket? Never thought on that. This would equally be necessary when the remote changes SA, but I consider this not a core requirement, since changing SA implies possible glitches in the upper applications anyway. closing socket and reopening a new one is allowed in that case. > > Again some code, but AFAICS no real support. > > regards, > Marc Kurt ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: j1939: bind() and connect() 2017-08-16 9:34 ` Kurt Van Dijck @ 2017-08-16 10:06 ` Marc Kleine-Budde 2017-08-16 10:29 ` David Jander 2017-08-16 10:47 ` Marc Kleine-Budde 0 siblings, 2 replies; 14+ messages in thread From: Marc Kleine-Budde @ 2017-08-16 10:06 UTC (permalink / raw) To: linux-can, David Jander [-- Attachment #1.1: Type: text/plain, Size: 2777 bytes --] On 08/16/2017 11:34 AM, Kurt Van Dijck wrote: >> Hello Kurt, >> >> I've a few questions about the j1939 socket model: >> >> - Should bind() be allowed to any interface, i.e. with can_ifindex == 0? >> >> I don't think so, but it's never checked for this. > > I'll explain a bit what I tried to accomplish: > * allow bind to any interface, for receive packets only (obviously) > * for rx/tx, only bind to 1 interface. Have you tested this? If I understand the code correctly j1939_ifindex_start() will not be called. So you will only receive packages from interfaces someone has other socket has bind() to, thus called j1939_ifindex_start(). And you'll stop receiving packages once the last socket on that interfaces is closed. >> - Should a connect() without a previous bind() be allowed? >> >> It's not checked for, but the error handling in sk_connect doesn't take >> that into account. > > Like UDP will auto-bind to the first known local address ... > Then an application would not need to know the local address to use. Which will be: > static int j1939sk_init(struct sock *sk) > { [...] > jsk->addr.sa = J1939_NO_ADDR; > jsk->addr.da = J1939_NO_ADDR; > jsk->addr.pgn = J1939_NO_PGN; [...] > } > static int j1939sk_connect(struct socket *sock, struct sockaddr *uaddr, > int len, int flags) [...] > j1939_name_local_get(priv, jsk->addr.src); > j1939_addr_local_get(priv, jsk->addr.sa); right? Does this work, as sendmsg tests: > static int j1939sk_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) > { [...] > if (jsk->addr.sa == J1939_NO_ADDR && !jsk->addr.src) > /* no address assigned yet */ > return -EBADFD; > >> - Should a second bind() be allowed on a previously bind() socket? > > Yes, definitely. > This is required to support dynamic addressing without possible losing > relevant messages. With changing the interface or not? >> As far as I understand the code, there's some support, but when the >> interface is switched, j1939_ifindex_stop() is not called. >> >> - Should a second conect() be allowed on a previously connect() socket? > > Never thought on that. This would equally be necessary when the remote > changes SA, but I consider this not a core requirement, since changing > SA implies possible glitches in the upper applications anyway. > closing socket and reopening a new one is allowed in that case. So I'll add a check against a re-connect(). Marc -- Pengutronix e.K. | Marc Kleine-Budde | Industrial Linux Solutions | Phone: +49-231-2826-924 | Vertretung West/Dortmund | Fax: +49-5121-206917-5555 | Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de | [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 488 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: j1939: bind() and connect() 2017-08-16 10:06 ` Marc Kleine-Budde @ 2017-08-16 10:29 ` David Jander 2017-08-16 21:18 ` Kurt Van Dijck 2017-08-16 10:47 ` Marc Kleine-Budde 1 sibling, 1 reply; 14+ messages in thread From: David Jander @ 2017-08-16 10:29 UTC (permalink / raw) To: Marc Kleine-Budde; +Cc: linux-can, Kurt Van Dijck On Wed, 16 Aug 2017 12:06:50 +0200 Marc Kleine-Budde <mkl@pengutronix.de> wrote: > On 08/16/2017 11:34 AM, Kurt Van Dijck wrote: > >> Hello Kurt, > >> > >> I've a few questions about the j1939 socket model: > >> > >> - Should bind() be allowed to any interface, i.e. with can_ifindex == 0? > >> > >> I don't think so, but it's never checked for this. > > > > I'll explain a bit what I tried to accomplish: > > * allow bind to any interface, for receive packets only (obviously) > > * for rx/tx, only bind to 1 interface. > > Have you tested this? If I understand the code correctly > j1939_ifindex_start() will not be called. So you will only receive > packages from interfaces someone has other socket has bind() to, thus > called j1939_ifindex_start(). And you'll stop receiving packages once > the last socket on that interfaces is closed. > > >> - Should a connect() without a previous bind() be allowed? > >> > >> It's not checked for, but the error handling in sk_connect doesn't take > >> that into account. > > > > Like UDP will auto-bind to the first known local address ... > > Then an application would not need to know the local address to use. > > Which will be: > > > static int j1939sk_init(struct sock *sk) > > { > [...] > > jsk->addr.sa = J1939_NO_ADDR; > > jsk->addr.da = J1939_NO_ADDR; > > jsk->addr.pgn = J1939_NO_PGN; > [...] > > } > > > static int j1939sk_connect(struct socket *sock, struct sockaddr *uaddr, > > int len, int flags) > [...] > > j1939_name_local_get(priv, jsk->addr.src); > > j1939_addr_local_get(priv, jsk->addr.sa); > > right? Does this work, as sendmsg tests: > > > static int j1939sk_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) > > { > [...] > > if (jsk->addr.sa == J1939_NO_ADDR && !jsk->addr.src) > > /* no address assigned yet */ > > return -EBADFD; > > > > >> - Should a second bind() be allowed on a previously bind() socket? > > > > Yes, definitely. > > This is required to support dynamic addressing without possible losing > > relevant messages. > > With changing the interface or not? > > >> As far as I understand the code, there's some support, but when the > >> interface is switched, j1939_ifindex_stop() is not called. > >> > >> - Should a second conect() be allowed on a previously connect() socket? > > > > Never thought on that. This would equally be necessary when the remote > > changes SA, but I consider this not a core requirement, since changing > > SA implies possible glitches in the upper applications anyway. > > closing socket and reopening a new one is allowed in that case. > > So I'll add a check against a re-connect(). Hmmm... in theory, any node can change SA at any time due to a re-claim. I always try to make this as transparent as possible to applications. The worst that I would deem acceptable to happen is that a transport session times-out and is transparently re-started, or a single message gets lost due to the inherent race of switching address. Why is a re-connect necessary if one connects to the NAME instead of the SA? Best regards, -- David Jander Protonic Holland. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: j1939: bind() and connect() 2017-08-16 10:29 ` David Jander @ 2017-08-16 21:18 ` Kurt Van Dijck 0 siblings, 0 replies; 14+ messages in thread From: Kurt Van Dijck @ 2017-08-16 21:18 UTC (permalink / raw) To: David Jander; +Cc: Marc Kleine-Budde, linux-can > > On Wed, 16 Aug 2017 12:06:50 +0200 > Marc Kleine-Budde <mkl@pengutronix.de> wrote: > > > On 08/16/2017 11:34 AM, Kurt Van Dijck wrote: > > >> Hello Kurt, > > >> > > >> I've a few questions about the j1939 socket model: > > >> > > >> - Should bind() be allowed to any interface, i.e. with can_ifindex == 0? > > >> > > >> I don't think so, but it's never checked for this. > > > > > > I'll explain a bit what I tried to accomplish: > > > * allow bind to any interface, for receive packets only (obviously) > > > * for rx/tx, only bind to 1 interface. > > > > Have you tested this? If I understand the code correctly > > j1939_ifindex_start() will not be called. So you will only receive > > packages from interfaces someone has other socket has bind() to, thus > > called j1939_ifindex_start(). And you'll stop receiving packages once > > the last socket on that interfaces is closed. Well, I'm well aware of the requirement to start j1939 processing on an interface. I tested this, with that requirement in mind. As already suggested in another mail in this thread, I don't thread this like a core requirement. Drop it if it solves things. > > > > >> - Should a connect() without a previous bind() be allowed? > > >> > > >> It's not checked for, but the error handling in sk_connect doesn't take > > >> that into account. > > > > > > Like UDP will auto-bind to the first known local address ... > > > Then an application would not need to know the local address to use. > > > > Which will be: > > > > > static int j1939sk_init(struct sock *sk) > > > { > > [...] > > > jsk->addr.sa = J1939_NO_ADDR; > > > jsk->addr.da = J1939_NO_ADDR; > > > jsk->addr.pgn = J1939_NO_PGN; > > [...] > > > } > > > > > static int j1939sk_connect(struct socket *sock, struct sockaddr *uaddr, > > > int len, int flags) > > [...] > > > j1939_name_local_get(priv, jsk->addr.src); > > > j1939_addr_local_get(priv, jsk->addr.sa); > > > > right? Does this work, as sendmsg tests: > > > > > static int j1939sk_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) > > > { > > [...] > > > if (jsk->addr.sa == J1939_NO_ADDR && !jsk->addr.src) > > > /* no address assigned yet */ > > > return -EBADFD; > > > Good point! Consider connect without bind as disfunctional for now. Maybe, if things clear up, we can try to add it then. > > > > >> - Should a second bind() be allowed on a previously bind() socket? > > > > > > Yes, definitely. > > > This is required to support dynamic addressing without possible losing > > > relevant messages. > > > > With changing the interface or not? > > > > >> As far as I understand the code, there's some support, but when the > > >> interface is switched, j1939_ifindex_stop() is not called. A re-bind should not change interface! A re-bind is necessary for changing SA or PGN only. > > >> > > >> - Should a second conect() be allowed on a previously connect() socket? > > > > > > Never thought on that. This would equally be necessary when the remote > > > changes SA, but I consider this not a core requirement, since changing > > > SA implies possible glitches in the upper applications anyway. > > > closing socket and reopening a new one is allowed in that case. > > > > So I'll add a check against a re-connect(). > > Hmmm... in theory, any node can change SA at any time due to a re-claim. I > always try to make this as transparent as possible to applications. The worst > that I would deem acceptable to happen is that a transport session times-out > and is transparently re-started, or a single message gets lost due to the > inherent race of switching address. Why is a re-connect necessary if one > connects to the NAME instead of the SA? That's true. A connect to a NAME is SA agnostic (should be), and so remote address changes are followed transparently. This is the core reason to put NAME's in kernel. So a re-connect should not be necessary. Kind regards, Kurt ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: j1939: bind() and connect() 2017-08-16 10:06 ` Marc Kleine-Budde 2017-08-16 10:29 ` David Jander @ 2017-08-16 10:47 ` Marc Kleine-Budde 1 sibling, 0 replies; 14+ messages in thread From: Marc Kleine-Budde @ 2017-08-16 10:47 UTC (permalink / raw) To: linux-can, David Jander [-- Attachment #1.1: Type: text/plain, Size: 1899 bytes --] On 08/16/2017 12:06 PM, Marc Kleine-Budde wrote: >>> - Should a connect() without a previous bind() be allowed? >>> >>> It's not checked for, but the error handling in sk_connect doesn't take >>> that into account. >> >> Like UDP will auto-bind to the first known local address ... >> Then an application would not need to know the local address to use. > > Which will be: > >> static int j1939sk_init(struct sock *sk) >> { > [...] >> jsk->addr.sa = J1939_NO_ADDR; >> jsk->addr.da = J1939_NO_ADDR; >> jsk->addr.pgn = J1939_NO_PGN; > [...] >> } > >> static int j1939sk_connect(struct socket *sock, struct sockaddr *uaddr, >> int len, int flags) > [...] >> j1939_name_local_get(priv, jsk->addr.src); >> j1939_addr_local_get(priv, jsk->addr.sa); > > right? Does this work, as sendmsg tests: > >> static int j1939sk_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) >> { > [...] >> if (jsk->addr.sa == J1939_NO_ADDR && !jsk->addr.src) >> /* no address assigned yet */ >> return -EBADFD; >> sendmsg() will fail, as it checks if the socket is in bound state. > static int j1939sk_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) > { > struct sock *sk = sock->sk; > struct j1939_sock *jsk = j1939_sk(sk); > struct sockaddr_can *addr = msg->msg_name; > struct j1939_sk_buff_cb *skcb; > struct sk_buff *skb; > struct net_device *dev; > int ifindex; > int ret; > > /* various socket state tests */ > if (!(jsk->state & J1939_SOCK_BOUND)) > return -EBADFD; > Receiving doesn't work, but I don't know why. Marc -- Pengutronix e.K. | Marc Kleine-Budde | Industrial Linux Solutions | Phone: +49-231-2826-924 | Vertretung West/Dortmund | Fax: +49-5121-206917-5555 | Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de | [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 488 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2017-08-17 8:32 UTC | newest] Thread overview: 14+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2017-08-14 17:37 j1939: bind() and connect() Marc Kleine-Budde 2017-08-15 8:14 ` Marc Kleine-Budde 2017-08-15 9:01 ` David Jander 2017-08-15 9:16 ` Marc Kleine-Budde 2017-08-15 10:24 ` David Jander 2017-08-16 21:08 ` Kurt Van Dijck 2017-08-17 7:35 ` Marc Kleine-Budde 2017-08-17 8:28 ` Kurt Van Dijck 2017-08-17 8:32 ` Marc Kleine-Budde 2017-08-16 9:34 ` Kurt Van Dijck 2017-08-16 10:06 ` Marc Kleine-Budde 2017-08-16 10:29 ` David Jander 2017-08-16 21:18 ` Kurt Van Dijck 2017-08-16 10:47 ` Marc Kleine-Budde
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.