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:
@@ -65,6 +65,7 @@ struct net_socket_module_info {
|
|||||||
status_t (*spawn_pending_socket)(net_socket *parent, net_socket **_socket);
|
status_t (*spawn_pending_socket)(net_socket *parent, net_socket **_socket);
|
||||||
void (*delete_socket)(net_socket *socket);
|
void (*delete_socket)(net_socket *socket);
|
||||||
status_t (*dequeue_connected)(net_socket *parent, 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_max_backlog)(net_socket *socket, uint32 backlog);
|
||||||
status_t (*set_connected)(net_socket *socket);
|
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
|
// 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)
|
# define TRACE(format, args...) dprintf("TCP:%p:" format "\n", this , ##args)
|
||||||
#else
|
#else
|
||||||
# define TRACE(args...)
|
# define TRACE(args...) do { } while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Initial estimate for packet round trip time (RTT)
|
// Initial estimate for packet round trip time (RTT)
|
||||||
@@ -62,6 +62,9 @@
|
|||||||
enum {
|
enum {
|
||||||
FLAG_OPTION_WINDOW_SHIFT = 0x01,
|
FLAG_OPTION_WINDOW_SHIFT = 0x01,
|
||||||
FLAG_OPTION_TIMESTAMP = 0x02,
|
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,
|
FLAG_NO_RECEIVE = 0x04,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -334,13 +337,16 @@ TCPEndpoint::Connect(const struct sockaddr *address)
|
|||||||
|
|
||||||
// If we are running over Loopback, after _SendQueued() returns we
|
// If we are running over Loopback, after _SendQueued() returns we
|
||||||
// may be in ESTABLISHED already.
|
// may be in ESTABLISHED already.
|
||||||
if (fState == ESTABLISHED)
|
if (fState == ESTABLISHED) {
|
||||||
|
TRACE(" Connect() completed after _SendQueued()");
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
// wait until 3-way handshake is complete (if needed)
|
// wait until 3-way handshake is complete (if needed)
|
||||||
bigtime_t timeout = min_c(socket->send.timeout, TCP_CONNECTION_TIMEOUT);
|
bigtime_t timeout = min_c(socket->send.timeout, TCP_CONNECTION_TIMEOUT);
|
||||||
if (timeout == 0) {
|
if (timeout == 0) {
|
||||||
// we're a non-blocking socket
|
// we're a non-blocking socket
|
||||||
|
TRACE(" Connect() delayed, return EINPROGRESS");
|
||||||
return EINPROGRESS;
|
return EINPROGRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -368,6 +374,8 @@ TCPEndpoint::Accept(struct net_socket **_acceptedSocket)
|
|||||||
return status;
|
return status;
|
||||||
|
|
||||||
status = gSocketModule->dequeue_connected(socket, _acceptedSocket);
|
status = gSocketModule->dequeue_connected(socket, _acceptedSocket);
|
||||||
|
if (status == B_OK)
|
||||||
|
TRACE(" Accept() returning %p", (*_acceptedSocket)->first_protocol);
|
||||||
} while (status < B_OK);
|
} while (status < B_OK);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
@@ -533,9 +541,8 @@ TCPEndpoint::SendData(net_buffer *buffer)
|
|||||||
ssize_t
|
ssize_t
|
||||||
TCPEndpoint::SendAvailable()
|
TCPEndpoint::SendAvailable()
|
||||||
{
|
{
|
||||||
TRACE("SendAvailable()");
|
|
||||||
|
|
||||||
RecursiveLocker locker(fLock);
|
RecursiveLocker locker(fLock);
|
||||||
|
TRACE("SendAvailable(): %li", fSendQueue.Free());
|
||||||
return 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
|
// send SYN+ACK
|
||||||
status_t status = endpoint->_SendQueued();
|
status_t status = endpoint->_SendQueued();
|
||||||
|
|
||||||
@@ -1403,6 +1412,14 @@ TCPEndpoint::_ShutdownEgress(bool closing)
|
|||||||
ssize_t
|
ssize_t
|
||||||
TCPEndpoint::_AvailableData() const
|
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();
|
ssize_t availableData = fReceiveQueue.Available();
|
||||||
|
|
||||||
if (availableData == 0 && !_ShouldReceive())
|
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
|
status_t
|
||||||
socket_set_max_backlog(net_socket *_socket, uint32 backlog)
|
socket_set_max_backlog(net_socket *_socket, uint32 backlog)
|
||||||
{
|
{
|
||||||
@@ -1101,6 +1117,7 @@ net_socket_module_info gNetSocketModule = {
|
|||||||
socket_spawn_pending,
|
socket_spawn_pending,
|
||||||
socket_delete,
|
socket_delete,
|
||||||
socket_dequeue_connected,
|
socket_dequeue_connected,
|
||||||
|
socket_count_connected,
|
||||||
socket_set_max_backlog,
|
socket_set_max_backlog,
|
||||||
socket_connected,
|
socket_connected,
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user