Minor cleanup.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19174 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -210,6 +210,7 @@ TCPConnection::Free()
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Creates and sends a SYN packet to /a address
|
Creates and sends a SYN packet to /a address
|
||||||
*/
|
*/
|
||||||
@@ -356,6 +357,7 @@ TCPConnection::Listen(int count)
|
|||||||
BenaphoreLocker lock(&fLock);
|
BenaphoreLocker lock(&fLock);
|
||||||
if (fState != CLOSED)
|
if (fState != CLOSED)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
fState = LISTEN;
|
fState = LISTEN;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -370,25 +372,23 @@ TCPConnection::Shutdown(int direction)
|
|||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Puts data contained in \a buffer into send buffer
|
Puts data contained in \a buffer into send buffer
|
||||||
*/
|
*/
|
||||||
status_t
|
status_t
|
||||||
TCPConnection::SendData(net_buffer *buffer)
|
TCPConnection::SendData(net_buffer *buffer)
|
||||||
{
|
{
|
||||||
TRACE(("TCP:%p.SendData()\n", this));
|
TRACE(("TCP:%p.SendData()\n", this));
|
||||||
size_t bufSize = buffer->size;
|
size_t bufferSize = buffer->size;
|
||||||
BenaphoreLocker lock(&fLock);
|
BenaphoreLocker lock(&fLock);
|
||||||
if (fSendBuffer == NULL) {
|
if (fSendBuffer != NULL) {
|
||||||
fSendBuffer = buffer;
|
|
||||||
fNextByteToWrite += bufSize;
|
|
||||||
return SendQueuedData(TCP_FLG_ACK, false);
|
|
||||||
} else {
|
|
||||||
status_t status = sBufferModule->merge(fSendBuffer, buffer, true);
|
status_t status = sBufferModule->merge(fSendBuffer, buffer, true);
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
fNextByteToWrite += bufSize;
|
} else
|
||||||
return SendQueuedData(TCP_FLG_ACK, false);
|
fSendBuffer = buffer;
|
||||||
}
|
|
||||||
|
fNextByteToWrite += bufferSize;
|
||||||
|
return SendQueuedData(TCP_FLG_ACK, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -411,13 +411,13 @@ TCPConnection::SendAvailable()
|
|||||||
BenaphoreLocker lock(&fLock);
|
BenaphoreLocker lock(&fLock);
|
||||||
if (fSendBuffer != NULL)
|
if (fSendBuffer != NULL)
|
||||||
return TCP_MAX_SEND_BUF - fSendBuffer->size;
|
return TCP_MAX_SEND_BUF - fSendBuffer->size;
|
||||||
else
|
|
||||||
return TCP_MAX_SEND_BUF;
|
return TCP_MAX_SEND_BUF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
TCPConnection::ReadData(size_t numBytes, uint32 flags, net_buffer **buffer)
|
TCPConnection::ReadData(size_t numBytes, uint32 flags, net_buffer** _buffer)
|
||||||
{
|
{
|
||||||
TRACE(("TCP:%p.ReadData()\n", this));
|
TRACE(("TCP:%p.ReadData()\n", this));
|
||||||
|
|
||||||
@@ -426,19 +426,22 @@ TCPConnection::ReadData(size_t numBytes, uint32 flags, net_buffer **buffer)
|
|||||||
// must be in a synchronous state
|
// must be in a synchronous state
|
||||||
if (fState != ESTABLISHED || fState != FIN_WAIT1 || fState != FIN_WAIT2) {
|
if (fState != ESTABLISHED || fState != FIN_WAIT1 || fState != FIN_WAIT2) {
|
||||||
// is this correct semantics?
|
// is this correct semantics?
|
||||||
|
dprintf(" TCP state = %d\n", fState);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dprintf(" TCP error = %ld\n", fError);
|
||||||
if (fError != B_OK)
|
if (fError != B_OK)
|
||||||
return fError;
|
return fError;
|
||||||
|
|
||||||
if (fReceiveBuffer->size < numBytes)
|
if (fReceiveBuffer->size < numBytes)
|
||||||
numBytes = fReceiveBuffer->size;
|
numBytes = fReceiveBuffer->size;
|
||||||
*buffer = sBufferModule->split(fReceiveBuffer, numBytes);
|
|
||||||
if (*buffer != NULL)
|
*_buffer = sBufferModule->split(fReceiveBuffer, numBytes);
|
||||||
return B_OK;
|
if (*_buffer == NULL)
|
||||||
else
|
return B_NO_MEMORY;
|
||||||
return B_ERROR;
|
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -449,15 +452,15 @@ TCPConnection::ReadAvailable()
|
|||||||
BenaphoreLocker lock(&fLock);
|
BenaphoreLocker lock(&fLock);
|
||||||
if (fReceiveBuffer != NULL)
|
if (fReceiveBuffer != NULL)
|
||||||
return fReceiveBuffer->size;
|
return fReceiveBuffer->size;
|
||||||
else
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
TCPConnection::EnqueueReceivedData(net_buffer *buffer, uint32 sequenceNumber)
|
TCPConnection::EnqueueReceivedData(net_buffer *buffer, uint32 sequenceNumber)
|
||||||
{
|
{
|
||||||
TRACE(("TCP:%p.EnqueueReceivedData(%p, %u)\n", this, buffer, sequenceNumber));
|
TRACE(("TCP:%p.EnqueueReceivedData(%p, %lu)\n", this, buffer, sequenceNumber));
|
||||||
status_t status;
|
status_t status;
|
||||||
|
|
||||||
if (sequenceNumber == fNextByteExpected) {
|
if (sequenceNumber == fNextByteExpected) {
|
||||||
@@ -545,114 +548,120 @@ TCPConnection::ReceiveData(net_buffer *buffer)
|
|||||||
|
|
||||||
TRACE(("TCP: ReceiveData(): Connection in state %d received packet %p with flags %X!\n", fState, buffer, header.flags));
|
TRACE(("TCP: ReceiveData(): Connection in state %d received packet %p with flags %X!\n", fState, buffer, header.flags));
|
||||||
switch (fState) {
|
switch (fState) {
|
||||||
case CLOSED:
|
case CLOSED:
|
||||||
case TIME_WAIT:
|
case TIME_WAIT:
|
||||||
sBufferModule->free(buffer);
|
sBufferModule->free(buffer);
|
||||||
if (header.flags & TCP_FLG_ACK)
|
|
||||||
return Reset(byteAckd, 0);
|
|
||||||
else
|
|
||||||
return Reset(0, byteRcvd + payloadLength);
|
|
||||||
break;
|
|
||||||
case LISTEN:
|
|
||||||
// if packet is SYN, spawn new TCPConnection in SYN_RCVD state
|
|
||||||
// and add it to the Connection Queue. The new TCPConnection
|
|
||||||
// must continue the handshake by replying with SYN+ACK. Any
|
|
||||||
// data in the packet must go into the new TCPConnection's receive
|
|
||||||
// buffer.
|
|
||||||
// Otherwise, RST+ACK is sent.
|
|
||||||
// The current TCPConnection always remains in LISTEN state.
|
|
||||||
return B_ERROR;
|
|
||||||
break;
|
|
||||||
case SYN_SENT:
|
|
||||||
if (header.flags & TCP_FLG_RST) {
|
|
||||||
fError = ECONNREFUSED;
|
|
||||||
fState = CLOSED;
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
if (header.flags & TCP_FLG_ACK && !TCP_IS_GOOD_ACK(byteAckd))
|
|
||||||
return Reset(byteAckd, 0);
|
|
||||||
if (header.flags & TCP_FLG_SYN) {
|
|
||||||
fNextByteToRead = fNextByteExpected = ntohl(header.sequence_num) + 1;
|
|
||||||
flags |= TCP_FLG_ACK;
|
|
||||||
fLastByteAckd = byteAckd;
|
|
||||||
// cancel resend of this segment
|
|
||||||
if (header.flags & TCP_FLG_ACK)
|
if (header.flags & TCP_FLG_ACK)
|
||||||
nextState = ESTABLISHED;
|
return Reset(byteAckd, 0);
|
||||||
else {
|
|
||||||
nextState = SYN_RCVD;
|
return Reset(0, byteRcvd + payloadLength);
|
||||||
flags |= TCP_FLG_SYN;
|
|
||||||
}
|
case LISTEN:
|
||||||
}
|
// if packet is SYN, spawn new TCPConnection in SYN_RCVD state
|
||||||
break;
|
// and add it to the Connection Queue. The new TCPConnection
|
||||||
case SYN_RCVD:
|
// must continue the handshake by replying with SYN+ACK. Any
|
||||||
if (header.flags & TCP_FLG_ACK && TCP_IS_GOOD_ACK(byteAckd))
|
// data in the packet must go into the new TCPConnection's receive
|
||||||
fState = ESTABLISHED;
|
// buffer.
|
||||||
else
|
// Otherwise, RST+ACK is sent.
|
||||||
Reset(byteAckd, 0);
|
// The current TCPConnection always remains in LISTEN state.
|
||||||
break;
|
return B_ERROR;
|
||||||
default:
|
|
||||||
// In a synchronized state.
|
case SYN_SENT:
|
||||||
// first check that the received sequence number is good
|
|
||||||
if (TCP_IS_GOOD_SEQ(byteRcvd, payloadLength)) {
|
|
||||||
// If a valid RST was received, terminate the connection.
|
|
||||||
if (header.flags & TCP_FLG_RST) {
|
if (header.flags & TCP_FLG_RST) {
|
||||||
fError = ECONNREFUSED;
|
fError = ECONNREFUSED;
|
||||||
fState = CLOSED;
|
fState = CLOSED;
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
if (header.flags & TCP_FLG_ACK && TCP_IS_GOOD_ACK(byteAckd) ) {
|
|
||||||
|
if (header.flags & TCP_FLG_ACK && !TCP_IS_GOOD_ACK(byteAckd))
|
||||||
|
return Reset(byteAckd, 0);
|
||||||
|
|
||||||
|
if (header.flags & TCP_FLG_SYN) {
|
||||||
|
fNextByteToRead = fNextByteExpected = ntohl(header.sequence_num) + 1;
|
||||||
|
flags |= TCP_FLG_ACK;
|
||||||
fLastByteAckd = byteAckd;
|
fLastByteAckd = byteAckd;
|
||||||
if (fLastByteAckd == fNextByteToWrite) {
|
|
||||||
if (fState == LAST_ACK ) {
|
// cancel resend of this segment
|
||||||
nextState = CLOSED;
|
if (header.flags & TCP_FLG_ACK)
|
||||||
status = hash_remove(sTCPHash, this);
|
nextState = ESTABLISHED;
|
||||||
if (status != B_OK)
|
else {
|
||||||
return status;
|
nextState = SYN_RCVD;
|
||||||
}
|
flags |= TCP_FLG_SYN;
|
||||||
if (fState == CLOSING) {
|
|
||||||
nextState = TIME_WAIT;
|
|
||||||
status = hash_remove(sTCPHash, this);
|
|
||||||
if (status != B_OK)
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
if (fState == FIN_WAIT1) {
|
|
||||||
nextState = FIN_WAIT2;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (header.flags & TCP_FLG_FIN) {
|
break;
|
||||||
// other side is closing connection. change states
|
|
||||||
switch (fState) {
|
case SYN_RCVD:
|
||||||
case ESTABLISHED:
|
if (header.flags & TCP_FLG_ACK && TCP_IS_GOOD_ACK(byteAckd))
|
||||||
nextState = CLOSE_WAIT;
|
fState = ESTABLISHED;
|
||||||
fNextByteExpected++;
|
else
|
||||||
break;
|
Reset(byteAckd, 0);
|
||||||
case FIN_WAIT2:
|
break;
|
||||||
nextState = TIME_WAIT;
|
|
||||||
fNextByteExpected++;
|
default:
|
||||||
break;
|
// In a synchronized state.
|
||||||
case FIN_WAIT1:
|
// first check that the received sequence number is good
|
||||||
|
if (TCP_IS_GOOD_SEQ(byteRcvd, payloadLength)) {
|
||||||
|
// If a valid RST was received, terminate the connection.
|
||||||
|
if (header.flags & TCP_FLG_RST) {
|
||||||
|
fError = ECONNREFUSED;
|
||||||
|
fState = CLOSED;
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (header.flags & TCP_FLG_ACK && TCP_IS_GOOD_ACK(byteAckd) ) {
|
||||||
|
fLastByteAckd = byteAckd;
|
||||||
if (fLastByteAckd == fNextByteToWrite) {
|
if (fLastByteAckd == fNextByteToWrite) {
|
||||||
// our FIN has been ACKd: go to TIME_WAIT
|
if (fState == LAST_ACK ) {
|
||||||
nextState = TIME_WAIT;
|
nextState = CLOSED;
|
||||||
status = hash_remove(sTCPHash, this);
|
status = hash_remove(sTCPHash, this);
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
sStackModule->set_timer(&fTimer, TCP_MAX_SEGMENT_LIFETIME);
|
}
|
||||||
} else
|
if (fState == CLOSING) {
|
||||||
nextState = CLOSING;
|
nextState = TIME_WAIT;
|
||||||
fNextByteExpected++;
|
status = hash_remove(sTCPHash, this);
|
||||||
break;
|
if (status != B_OK)
|
||||||
default:
|
return status;
|
||||||
break;
|
}
|
||||||
|
if (fState == FIN_WAIT1) {
|
||||||
|
nextState = FIN_WAIT2;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (header.flags & TCP_FLG_FIN) {
|
||||||
|
// other side is closing connection. change states
|
||||||
|
switch (fState) {
|
||||||
|
case ESTABLISHED:
|
||||||
|
nextState = CLOSE_WAIT;
|
||||||
|
fNextByteExpected++;
|
||||||
|
break;
|
||||||
|
case FIN_WAIT2:
|
||||||
|
nextState = TIME_WAIT;
|
||||||
|
fNextByteExpected++;
|
||||||
|
break;
|
||||||
|
case FIN_WAIT1:
|
||||||
|
if (fLastByteAckd == fNextByteToWrite) {
|
||||||
|
// our FIN has been ACKd: go to TIME_WAIT
|
||||||
|
nextState = TIME_WAIT;
|
||||||
|
status = hash_remove(sTCPHash, this);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
sStackModule->set_timer(&fTimer, TCP_MAX_SEGMENT_LIFETIME);
|
||||||
|
} else
|
||||||
|
nextState = CLOSING;
|
||||||
|
fNextByteExpected++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
flags |= TCP_FLG_ACK;
|
||||||
|
} else {
|
||||||
|
// out-of-order packet received. remind the other side of where we are
|
||||||
|
return SendQueuedData(TCP_FLG_ACK, true);
|
||||||
}
|
}
|
||||||
flags |= TCP_FLG_ACK;
|
break;
|
||||||
} else {
|
|
||||||
// out-of-order packet received. remind the other side of where we are
|
|
||||||
return SendQueuedData(TCP_FLG_ACK, true);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
TRACE(("TCP %p.ReceiveData():Entering state %d\n", this, fState));
|
TRACE(("TCP %p.ReceiveData():Entering state %d\n", this, fState));
|
||||||
|
|
||||||
@@ -675,7 +684,6 @@ TCPConnection::ReceiveData(net_buffer *buffer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
fState = nextState;
|
fState = nextState;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -788,10 +796,10 @@ TCPConnection::Compare(void *_connection, const void *_key)
|
|||||||
const tcp_connection_key *key = (tcp_connection_key *)_key;
|
const tcp_connection_key *key = (tcp_connection_key *)_key;
|
||||||
TCPConnection *connection= ((TCPConnection *)_connection);
|
TCPConnection *connection= ((TCPConnection *)_connection);
|
||||||
|
|
||||||
if (sAddressModule->equal_addresses_and_ports(
|
if (sAddressModule->equal_addresses_and_ports(key->local,
|
||||||
key->local, (sockaddr *)&connection->socket->address)
|
(sockaddr *)&connection->socket->address)
|
||||||
&& sAddressModule->equal_addresses_and_ports(
|
&& sAddressModule->equal_addresses_and_ports(key->peer,
|
||||||
key->peer, (sockaddr *)&connection->socket->peer))
|
(sockaddr *)&connection->socket->peer))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user