Subject: connect() on UDP-style sockets

From: Sridhar Samudrala <[email-masked]>
Date: Tue, 5 Nov 2002 10:25:19 -0800 (PST)

I have a couple of questions on the behavior of connect() for udp-style sockets.

1. What should be the default behavior of a connect() on a udp-style sctp 
socket. Should it block until the association is established or return after
sending an INIT with EINPROGRESS similar to a non-blocking socket?

2. What is the default behavior of an initial sendmsg() on a udp-style socket 
that was called without a prior connect() call causing an association to be
setup implicitly. Should it block or return immediately? 

3. Also i noticed that the sctp sockets api draft doesn't explicitly call for
autobind on connect() for udp-style sockets if bind() was not called prior to 
connect(). Autobind is explicitly mentioned for sendmsg() on udp-style and
connect() on tcp-style sockets. But there is no mention of autobind for 
connect() on udp-style sockets.

Thanks
Sridhar

---

From: Nivedita Singhvi <[email-masked]>
Date: Tue, 05 Nov 2002 13:28:58 -0800

> connect() on udp-style sockets.

For defining testcases for SCTP, I assumed that a connect on a udp socket
that wasnt bound would autobind to an ephemeral port and wildcard address,
similar to sendmsg() and other such situations, even though it wasnt
mentioned in the SCTP API draft.  If thats not the case, I'd also be 
interested in what error should be returned. 

thanks,
Nivedita

---

From: "Randall Stewart (cisco)" <[email-masked]>
Date: Tue, 05 Nov 2002 17:40:19 -0600

>>sending an INIT with EINPROGRESS similar to a non-blocking socket?
I don't see why it would have to... but I would like to hear what others 
would say..

>>setup implicitly. Should it block or return immediately?

Since udp style.. 1 to many if you will .. represent many assoc's it 
might be best
not to block and start the setup with the data in queue... Same thing 
that would
happen when you write to a socket() and there is space in the socket 
buffer.. you return
with a number of bytes written.. even though it does not necessarily 
complete the write
until after the data that may be ahead gets across..

>interested in what error should be returned. 
Yes.. we missed adding the text on autobind.. this is what should happen..

-- 
Randall R. Stewart
ITD
Cisco Systems Inc.
[email-masked] 815-342-5222(cell) or 815-477-2127(office)

---

From: Jon Grimm <[email-masked]>
Date: Tue, 05 Nov 2002 18:08:52 -0600

> I don't see why it would have to... but I would like to hear what others

Per discussions of late, I'd expect non-blocking, but with no
EINPROGRESS for UDP-style connect().  Events already provide association
change information that is needed anyway.   For this choice, one should
also suppress EALREADY/EISCONN too   

As a second choice, I'd go with a blocking connect(), as I can see some
application requirement towards blocking on connect.   With this second
choice, I guess its stil possible to convert into a non-blocking socket
that returns EINPROGRESS/EALREADY/EISCONN or whatever flavor your OS of
choice propogates up as an error code.  OTOH, if you want this behavior,
its likely that the TCP-style would have likely been a better choice of
model anyway.  

Best Regards,
Jon Grimm

---

From: Sridhar Samudrala <[email-masked]>
Date: Tue, 5 Nov 2002 17:20:30 -0800 (PST)

> also suppress EALREADY/EISCONN too   

Going by Randy's argument that a udp-style socket may represent multiple 
association's and it is best not to block, i too feel that non-blocking 
may be better. But i don't see why we need to supress EINPROGRESS/EALREADY/
EISCONN return values. These are not really error values in this situation,
but do provide the application some information about the current status of
the socket/association. For example, this information will be useful for an
application that disables notifications.

Regards
Sridhar

---

From: Jon Grimm <[email-masked]>
Date: Tue, 05 Nov 2002 19:06:35 -0600

> application that disables notifications.

Hi Sridhar,

Well, I considered them for suppression since I could look at UDP-style
on my typically strange reasoning process:  
1) If I look at UDP-style as its the closest thing to my SOCK_DGRAM
application.   Consequently, I wouldn't expect any of those error codes
nor blocking behavior  
2) Instead, if I instead look at UDP-style as being an entirely new
model, events are the real way of getting this type of association
change information.    If you are using UDP-style you really should (I'm
using 'should' but in reality tell app writers 'must') use
events/notifications.
3) Otherwise, just plain go use TCP-style.  If you are doing connect(),
its not likely you have multiple associations anyway.   

I don't consider it that hideous to have such behavior (non-block
EINPROGRESS, etc..). I just couldn't figure out why one should need it
on the above, and it didn't fit in with the feel of the rest ofthe
UDP-style changes). 

Best Regards,
jon

---

From: Nivedita Singhvi <[email-masked]>
Date: Tue, 05 Nov 2002 17:39:21 -0800

> application that disables notifications.

This may be a dumb question, but...

If the connect() system call is going to fail [ return a -1 ], then 
I believe we must return the proper error value. i.e. tell the application
EINPROGRESS or whatever. However, we dont want the application to attempt the 
connect() system call again or consider it a failure, isnt that correct?

If we return success [0] (even if the connect hasnt completed), then 
how does the application learn the status of the connect?

thanks,
Nivedita

---

From: Jon Grimm <[email-masked]>
Date: Tue, 05 Nov 2002 20:05:33 -0600

> connect() system call again or consider it a failure, isnt that correct?

Depends.  UDP-style sockets already have a way to get this information..
connect() as an API was relatively recent add to the I-D.   This
information is already part of  API. 

> how does the application learn the status of the connect?

UDP-style sockets have an alternative mechanism for reporting such
information.  ASSOC_CHANGE notifications report this an much more up
through recvmsg().  So if I put on my UDP-style hat, which says its a
new model, this is what I come up with.. 

Now... the connect() status may very well be interesting to app, but if
so.. its also likely that a blocking connect was interesting too.  Or
that TCP-style is more appropriate anyway.  However, I'm not fond of a
blocking connect() anyway, since this defeat the ability to bundle data
with the last part of the association setup, so you lose that as an SCTP
feature.  :-(   

Best Regards,
jon

---

From: Chuck Winters <[email-masked]>
Date: Wed, 6 Nov 2002 07:42:55 -0500

> > application that disables notifications.
Stupid question, but is the default for the UDP style socket to be non-blocking,
or do you have to set it to non-blocking after creation?  

I think you can preserve the semantics of connect() which I believe is that only
when the socket is in non-blocking mode are these errors are returned.
> application.   Consequently, I wouldn't expect any of those error codes
Now, if SCTP were not a connection oriented protocol, I would agree with the
above statement.
> using 'should' but in reality tell app writers 'must') use
If the errors are not suppressed, then they give some information to the app.
If you wanted more info, use the events produced by the stack.

> > > its likely that the TCP-style would have likely been a better choice of
Later,
Chuck

-- 
Chuck Winters                            | Email:  [email-masked]
Distributed Processing Laboratory        | Phone:  856-338-3987
Lockheed Martin Advanced Technology Labs |
1 Federal St - A&E-3W                    |
Camden, NJ 08102                         |

---

From: Jon Grimm <[email-masked]>
Date: Wed, 06 Nov 2002 08:36:06 -0600

Hi Chuck,
	I'm clipping a bit since the response trail is getting a little long.  
I'll summarize by saying that I don't feel very strongly on this issue
at all, though I do want the application writer to know what to expect
by reading the I-D.  As a secondary goal, the application writer should
have a good chance of assuming semantics based on their previous
experience with BSD Sockets.  

Chuck Winters wrote:

> or do you have to set it to non-blocking after creation?

I believe the are blocking.   See section 3.3 of the I-D:  

excerpt:
"Once all bind() calls are complete on a UDP-style socket, the
application must set the non-blocking option by a fcntl() (such as
O_NONBLOCK)."

This at least implies blocking by default.  

> when the socket is in non-blocking mode are these errors are returned.

Ah... well this is more akin to my choice #2.   Preserve the semantics
of connect() entirely.  

> Now, if SCTP were not a connection oriented protocol, I would agree with the

Which is why I move on... ;-)  Well, its probably also fair for me to
respond that the whole "auto-connect" behavior of sendmsg hides the
connection-oriented nature of the underlying protocol.  IIRC, 'connect'
has only been in the tsvwg sockets I-D since draft 3 or 4??? for
UDP-style.  I don't remember if it was in the sigtran drafts.  

> If you wanted more info, use the events produced by the stack.

Yes, I think I'm convinced that this doesn't take away anything, though
it is redundant information.  You can get this same redundant
information on TCP-style by enabling events.. so its there anyway.   

> > its not likely you have multiple associations anyway.

Hmmm... no one responses to this point.  Thats no fun.  

Thats enough for me...  I don't feel very strongly on any of these,
except to have in the end rationale choice documented in the I-D.   

Best Regards and thanks,
Jon Grimm
|

---

From: Sridhar Samudrala <[email-masked]>
Date: Wed, 6 Nov 2002 10:22:38 -0800 (PST)

> experience with BSD Sockets.  

Jon,

I agree entirely with your summary. We need to clearly define the behavior of
udp-style connect() as either non-blocking or blocking. If we define the
behavior as non-blocking, i feel that we should go with the semantics of
a BSD socket that is explicitly set to non-blocking. But if we want to
deviate from this semantics, we need to make that clear in the draft.

> Hmmm... no one responses to this point.  Thats no fun.  

OK. Let me respond. I don't think it is that unlikely to have multiple
associations on a socket that does connect. For example, Richard Stevens Unix 
network programming Vol 1, in sec 15.5 talks of a web browser that can use 
multiple non-blocking connects to multiple web servers that are referenced on 
the same web page. In this scenario, SCTP can be used with a single socket 
having multiple shortlived associations that are initiated using connect().
If the default behavior of udp-style connect() is defined as non-blocking,
the user need not even explicitly set the socket as non-blocking. 

Regards
Sridhar

---

From: Jon Grimm <[email-masked]>
Date: Wed, 06 Nov 2002 12:49:10 -0600

---

From: Jon Grimm <[email-masked]>
Date: Wed, 06 Nov 2002 13:18:14 -0600

Hi Sridhar,

	Sorry for the previous accidental send.

> having multiple shortlived associations that are initiated using connect().

Good point! (though if I were 'exploiting' the UDP-style API I'd 
probably rewrite the example without connect at all using auto-connect.)

> the user need not even explicitly set the socket as non-blocking. 

Agreed.. but if so, I'd like to see the entirety of the socket be in 
this state, as there is not a method to independantly change the state 
of connect vs I/O blocking behavior.   If one is non-blocking the other 
should be too.

The I-D today implies that the UDP-style socket is blocking by default. 
      See section 3.3. of the I-D.   IMO, if we change connect to 
non-blocking, this too should change.

Thanks,
jon

---

From: "Randall Stewart (cisco)" <[email-masked]>
Date: Wed, 06 Nov 2002 17:54:06 -0600

Jon:

I wonder if it would not be better to change the udp default
to be NON-BLOCKING. And then leave the connect
symantics to be strictly BSD like... This way you get
a non-blocking connect (and everything else  too) by default.

Then if you really want a blocking connect you can do the fctl() thing 
(or whatever
sets the flag in your socket) and change it to blocking and get the wonderus
blocking behaviour...

R

---

From: Jon Grimm <[email-masked]>
Date: Thu, 07 Nov 2002 08:08:29 -0600

Works for me.   Sridhar, how is that for you?  I think we agreed that 
the below solution is what we'd implement in lksctp in the face of 
silence, anyway.  ;-)   Its easy enough for us to switch to a different 
default socket behavior.

Best Regards,
jon

---

From: Sridhar Samudrala <[email-masked]>
Date: Thu, 7 Nov 2002 09:53:31 -0800 (PST)

> silence, anyway.  ;-)   Its easy enough for us to switch to a different 

I think there is going to be an issue with implementation. By default, all the
operations on a file/socket are supposed to be blocking. Using fcntl()
we can change this behavior to be non-blocking by setting O_NONBLOCK.
But i am not sure if there is a mechanism to change the behavior to
blocking when by default we are doing non-blocking. 
If O_NONBLOCK is not set, we don't know if the user wants default behavior or 
blocking behavior?

Do we really need to support blocking connect for udp-style sockets? If not,
may be Jon's suggestion of returning success on connect() by default should
work out.

Default:
-------
connect() return success after initiating the connection.

Non-blocking enabled:
--------------------
connect() returns -1 with EINPROGRESS after initiating the connection.

I think we either need to go with the above behavior or by default do blocking
connect.
 
Thanks
Sridhar

---

From: Jon Grimm <[email-masked]>
Date: Thu, 07 Nov 2002 15:55:59 -0600

Well this is certainly going around in circles.  Yes, I see the layering 
issue that is there.  We can't even get to those file flags at socket 
initialization to go whack them to NONBLOCK.  :-(

Yes, I could go for either of these.   Though I think just sticking to 
blocking semantics throughout will cause the least application or 
implementation issues for all.   'connect' on a connection-oriented 
protocol has always had blocking semantics.

Best Regards,
Jon

---

From: "K. Poon" <[email-masked]>
Date: Sun, 10 Nov 2002 01:52:37 -0800 (PST)

> application.   Consequently, I wouldn't expect any of those error

I don't think people should treat SCTP UDP-style socket mapping
as modeling after real UDP socket.  It is more like a new style
of socket programming.  But it has its root in real UDP socket.
I believe this has been brought up before.  So I think it is OK 
to return an error if the socket is set to non-blocking, as it
should be blocking by default.

> using 'should' but in reality tell app writers 'must') use

If I remember correctly, the reason why connect() was added to
the UDP-style socket mapping was simply that it works for real
UDP socket, so it should also work for SCTP UDP-style socket.

There is actually a very interesting consequence if an app
chooses to use this with SCTP UDP-style socket.  For real UDP
socket, the semantics of connect() is to set the remote
address (IP addr + port) so that send() will work.  It is used
to simplify app programming if the app knows that the UDP socket
will only be used to talk to a fixed peer for a period of time.

Now when this semantics is applied to SCTP UDP-style socket,
it means that ALL accociations controlled by this socket will
go to the same remote address (IP addr + port).  This effectively
changes the UDP-style socket to a TCP-style socket, as it does
not make sense to have more than one association going to the
same remote address, from the same local address.  So the effect
of connect() is more than just initiating an association.  But
from a porting (real UDP socket to SCTP UDP-style socket) point
of view, this makes sense as this is how app uses connect() on
a real UDP socket.  I believe this should be clarified in the 
draft.  And the behavior on subsequent connect() should be
specified.  It should be somethinkg like shutting down the previous
association and initiating a new association to a different
remote address.

I think the authors should discuss this and update the draft
accordingly.

> its not likely you have multiple associations anyway.   

Yes.
 
> on the above, and it didn't fit in with the feel of the rest ofthe

I believe connect() on UDP-style socket should be blocking by
default.  And it should probably be used only for "straight" 
porting of apps.

=====
K. Poon.				[email-masked]

__________________________________________________
Do you Yahoo!?
U2 on LAUNCH - Exclusive greatest hits videos
http://launch.yahoo.com/u2

---

From: "K. Poon" <[email-masked]>
Date: Sun, 10 Nov 2002 02:01:54 -0800 (PST)

> the user need not even explicitly set the socket as non-blocking. 

I don't have that book handy, so I am inferring the following
here...  I believe the "correct" porting of the book's example
using both UDP-style socket and connect() is to setup one
association with several streams, instead of setting up
multiple associations.  And this will work with the connect()
behavior I mentioned in an earlier mail.

=====

---

From: Sridhar Samudrala <[email-masked]>
Date: Mon, 11 Nov 2002 09:43:11 -0800 (PST)

> behavior I mentioned in an earlier mail.

Maybe the above description was not clear. The example in the book refers to a 
webpage containing links to multiple webservers(for ex. the images on the same
page may be located at different websites). So i guess a single association
with several streams will not work out. There needs to be multiple associations 
for this case. 

Although if we are using udp-style sockets in this scenario, as Jon mentioned,
using sendmsg() with auto connect behavior may be a better choice.

Thanks
Sridhar

---

From: venkat venkatsubra <[email-masked]>
Date: Mon, 11 Nov 2002 12:03:17 -0600

> default.  And it should probably be used only for "straight"

I also feel the default should be blocking.
It was much simpler to code a typical client
application not having to handle connect() error return
codes (since the protocol is connection oriented).

> K. Poon.                                [email-masked]

Venkat