Fixed some more TCP issues.

- Properly flag sockets using non-blocking connects() when in SYN SENT.
 - and when in LISTEN, we should use the socket's connection queue size.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20631 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Hugo Santos
2007-04-10 05:28:56 +00:00
parent 1b52d54a31
commit 8107b19403
3 changed files with 39 additions and 4 deletions
+1
View File
@@ -65,6 +65,7 @@ struct net_socket_module_info {
status_t (*spawn_pending_socket)(net_socket *parent, net_socket **_socket);
void (*delete_socket)(net_socket *socket);
status_t (*dequeue_connected)(net_socket *parent, net_socket **_socket);
ssize_t (*count_connected)(net_socket *parent);
status_t (*set_max_backlog)(net_socket *socket, uint32 backlog);
status_t (*set_connected)(net_socket *socket);
@@ -52,7 +52,7 @@
// the space after 'this' is important in order for this to work with cpp 2.95
# define TRACE(format, args...) dprintf("TCP:%p:" format "\n", this , ##args)
#else
# define TRACE(args...)
# define TRACE(args...) do { } while (0)
#endif
// Initial estimate for packet round trip time (RTT)
@@ -62,6 +62,9 @@
enum {
FLAG_OPTION_WINDOW_SHIFT = 0x01,
FLAG_OPTION_TIMESTAMP = 0x02,
// TODO: Should FLAG_NO_RECEIVE apply as well to received connections?
// That is, what is excepected from accept() after a shutdown()
// is performed on a listen()ing socket.
FLAG_NO_RECEIVE = 0x04,
};
@@ -334,13 +337,16 @@ TCPEndpoint::Connect(const struct sockaddr *address)
// If we are running over Loopback, after _SendQueued() returns we
// may be in ESTABLISHED already.
if (fState == ESTABLISHED)
if (fState == ESTABLISHED) {
TRACE(" Connect() completed after _SendQueued()");
return B_OK;
}
// wait until 3-way handshake is complete (if needed)
bigtime_t timeout = min_c(socket->send.timeout, TCP_CONNECTION_TIMEOUT);
if (timeout == 0) {
// we're a non-blocking socket
TRACE(" Connect() delayed, return EINPROGRESS");
return EINPROGRESS;
}
@@ -368,6 +374,8 @@ TCPEndpoint::Accept(struct net_socket **_acceptedSocket)
return status;
status = gSocketModule->dequeue_connected(socket, _acceptedSocket);
if (status == B_OK)
TRACE(" Accept() returning %p", (*_acceptedSocket)->first_protocol);
} while (status < B_OK);
return status;
@@ -533,9 +541,8 @@ TCPEndpoint::SendData(net_buffer *buffer)
ssize_t
TCPEndpoint::SendAvailable()
{
TRACE("SendAvailable()");
RecursiveLocker locker(fLock);
TRACE("SendAvailable(): %li", fSendQueue.Free());
return fSendQueue.Free();
}
@@ -767,6 +774,8 @@ TCPEndpoint::ListenReceive(tcp_segment_header &segment, net_buffer *buffer)
}
}
TRACE(" ListenReceive() created new endpoint %p", endpoint);
// send SYN+ACK
status_t status = endpoint->_SendQueued();
@@ -1403,6 +1412,14 @@ TCPEndpoint::_ShutdownEgress(bool closing)
ssize_t
TCPEndpoint::_AvailableData() const
{
// TODO: Refer to the FLAG_NO_RECEIVE comment above regarding
// the application of FLAG_NO_RECEIVE in listen()ing
// sockets.
if (fState == LISTEN)
return gSocketModule->count_connected(socket);
else if (fState == SYNCHRONIZE_SENT)
return 0;
ssize_t availableData = fReceiveQueue.Available();
if (availableData == 0 && !_ShouldReceive())
@@ -372,6 +372,22 @@ socket_dequeue_connected(net_socket *_parent, net_socket **_socket)
}
ssize_t
socket_count_connected(net_socket *_parent)
{
net_socket_private *parent = (net_socket_private *)_parent;
BenaphoreLocker _(parent->lock);
int count = 0;
for (void *it = list_get_first_item(&parent->connected_children);
it != NULL; it = list_get_next_item(&parent->connected_children, it))
count++;
return count;
}
status_t
socket_set_max_backlog(net_socket *_socket, uint32 backlog)
{
@@ -1101,6 +1117,7 @@ net_socket_module_info gNetSocketModule = {
socket_spawn_pending,
socket_delete,
socket_dequeue_connected,
socket_count_connected,
socket_set_max_backlog,
socket_connected,