TCP Socket creation and destruction implemented, as well as the beginning of the TCP state-machine
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18558 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -6,12 +6,16 @@
|
|||||||
* Andrew Galante, [email protected]
|
* Andrew Galante, [email protected]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Initial estimate for packet round trip time (RTT)
|
||||||
|
#define TCP_INITIAL_RTT 120000000LL
|
||||||
|
|
||||||
|
// keep maximum buffer sizes < max net_buffer size for now
|
||||||
|
#define TCP_MAX_SEND_BUF 1024
|
||||||
|
#define TCP_MAX_RECV_BUF TCP_MAX_SEND_BUF
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
in_addr_t source;
|
const sockaddr *local;
|
||||||
in_addr_t destination;
|
const sockaddr *peer;
|
||||||
uint16 source_port;
|
|
||||||
uint16 destination_port;
|
|
||||||
} tcp_connection_key;
|
} tcp_connection_key;
|
||||||
|
|
||||||
|
|
||||||
@@ -35,20 +39,71 @@ public:
|
|||||||
status_t ReadData(size_t numBytes, uint32 flags, net_buffer **_buffer);
|
status_t ReadData(size_t numBytes, uint32 flags, net_buffer **_buffer);
|
||||||
status_t ReadAvailable();
|
status_t ReadAvailable();
|
||||||
|
|
||||||
|
status_t ReceiveData(net_buffer *buffer);
|
||||||
|
|
||||||
|
static void ResendSegment(struct net_timer *timer, void *data);
|
||||||
static int Compare(void *_packet, const void *_key);
|
static int Compare(void *_packet, const void *_key);
|
||||||
static uint32 Hash(void *_packet, const void *_key, uint32 range);
|
static uint32 Hash(void *_packet, const void *_key, uint32 range);
|
||||||
static int32 HashOffset() { return offsetof(TCPConnection, fHashLink); }
|
static int32 HashOffset() { return offsetof(TCPConnection, fHashLink); }
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
class TCPSegment {
|
||||||
|
public:
|
||||||
|
TCPSegment(net_buffer *_buffer, uint32 _sequenceNumber, bigtime_t timeout);
|
||||||
|
~TCPSegment();
|
||||||
|
|
||||||
|
net_buffer *fBuffer;
|
||||||
|
bigtime_t fTime;
|
||||||
|
uint32 fSequenceNumber;
|
||||||
|
uint32 fAcknowledgementNumber;
|
||||||
|
net_timer fTimeout;
|
||||||
|
};
|
||||||
|
|
||||||
|
status_t Send(uint8 flags);
|
||||||
|
|
||||||
|
uint32 fLastByteSent;
|
||||||
|
uint32 fLastByteAckd;
|
||||||
|
uint32 fLastByteWritten;
|
||||||
|
|
||||||
|
uint32 fLastByteRead;
|
||||||
|
uint32 fNextByteExpected;
|
||||||
|
uint32 fLastByteReceived;
|
||||||
|
|
||||||
|
uint32 fEffectiveWindow;
|
||||||
|
|
||||||
|
bigtime_t fAvgRTT;
|
||||||
|
|
||||||
|
TCPSegment *fSent;
|
||||||
|
TCPSegment *fReceived;
|
||||||
|
|
||||||
TCPConnection *fHashLink;
|
TCPConnection *fHashLink;
|
||||||
tcp_state fState;
|
tcp_state fState;
|
||||||
benaphore fLock;
|
benaphore fLock;
|
||||||
public:
|
|
||||||
tcp_connection_key fKey;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
TCPConnection::TCPSegment::TCPSegment(net_buffer *_buffer, uint32 _sequenceNumber, bigtime_t timeout)
|
||||||
|
:
|
||||||
|
fBuffer(_buffer),
|
||||||
|
fSequenceNumber(_sequenceNumber)
|
||||||
|
{
|
||||||
|
sStackModule->init_timer(&fTimeout, &TCPConnection::ResendSegment, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TCPConnection::TCPSegment::~TCPSegment()
|
||||||
|
{
|
||||||
|
sStackModule->set_timer(&fTimeout, -1);
|
||||||
|
sBufferModule->free(fBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
TCPConnection::TCPConnection(net_socket *socket)
|
TCPConnection::TCPConnection(net_socket *socket)
|
||||||
:
|
:
|
||||||
|
fLastByteSent(0),//system_time()),
|
||||||
|
fLastByteAckd(0),//fLastByteSent),
|
||||||
|
fLastByteWritten(0),//fLastByteSent),
|
||||||
|
fAvgRTT(TCP_INITIAL_RTT),
|
||||||
fState(CLOSED)
|
fState(CLOSED)
|
||||||
{
|
{
|
||||||
benaphore_init(&fLock, "TCPConnection");
|
benaphore_init(&fLock, "TCPConnection");
|
||||||
@@ -64,6 +119,16 @@ TCPConnection::~TCPConnection()
|
|||||||
status_t
|
status_t
|
||||||
TCPConnection::Open()
|
TCPConnection::Open()
|
||||||
{
|
{
|
||||||
|
TRACE(("%p.Open()\n", this));
|
||||||
|
if (sAddressModule == NULL)
|
||||||
|
return B_ERROR;
|
||||||
|
TRACE(("Using Address Module %p\n", sAddressModule));
|
||||||
|
|
||||||
|
BenaphoreLocker lock(&fLock);
|
||||||
|
sAddressModule->set_to_empty_address((sockaddr *)&socket->address);
|
||||||
|
sAddressModule->set_port((sockaddr *)&socket->address, 0);
|
||||||
|
sAddressModule->set_to_empty_address((sockaddr *)&socket->peer);
|
||||||
|
sAddressModule->set_port((sockaddr *)&socket->peer, 0);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,6 +136,16 @@ TCPConnection::Open()
|
|||||||
status_t
|
status_t
|
||||||
TCPConnection::Close()
|
TCPConnection::Close()
|
||||||
{
|
{
|
||||||
|
TRACE(("%p.Close()\n", this));
|
||||||
|
|
||||||
|
BenaphoreLocker hashLock(&sTCPLock);
|
||||||
|
BenaphoreLocker lock(&fLock);
|
||||||
|
tcp_connection_key key;
|
||||||
|
key.local = (sockaddr *)&socket->address;
|
||||||
|
key.peer = (sockaddr *)&socket->peer;
|
||||||
|
if (hash_lookup(sTCPHash, &key) != NULL) {
|
||||||
|
return hash_remove(sTCPHash, (void *)this);
|
||||||
|
}
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,13 +153,75 @@ TCPConnection::Close()
|
|||||||
status_t
|
status_t
|
||||||
TCPConnection::Free()
|
TCPConnection::Free()
|
||||||
{
|
{
|
||||||
|
TRACE(("%p.Free()\n", this));
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Creates and sends a SYN packet to /a address
|
||||||
|
*/
|
||||||
status_t
|
status_t
|
||||||
TCPConnection::Connect(const struct sockaddr *address)
|
TCPConnection::Connect(const struct sockaddr *address)
|
||||||
{
|
{
|
||||||
|
TRACE(("TCP:%p.Connect() on address %s\n", this,
|
||||||
|
AddressString(sDomain, address, true).Data()));
|
||||||
|
|
||||||
|
if (address->sa_family != AF_INET)
|
||||||
|
return EAFNOSUPPORT;
|
||||||
|
|
||||||
|
benaphore_lock(&sTCPLock); // want to release lock later, so no autolock
|
||||||
|
BenaphoreLocker lock(&fLock);
|
||||||
|
|
||||||
|
// Can only call Connect from CLOSED or LISTEN states
|
||||||
|
// otherwise connection is considered already connected
|
||||||
|
if (fState != CLOSED && fState != LISTEN) {
|
||||||
|
benaphore_unlock(&sTCPLock);
|
||||||
|
return EISCONN;
|
||||||
|
}
|
||||||
|
TRACE(("TCP: Connect(): in state %d\n", fState));
|
||||||
|
|
||||||
|
// make sure connection does not already exist
|
||||||
|
tcp_connection_key key;
|
||||||
|
key.local = (sockaddr *)&socket->address;
|
||||||
|
key.peer = address;
|
||||||
|
if (hash_lookup(sTCPHash, &key) != NULL) {
|
||||||
|
benaphore_unlock(&sTCPLock);
|
||||||
|
return EADDRINUSE;
|
||||||
|
}
|
||||||
|
TRACE(("TCP: Connect(): connecting...\n"));
|
||||||
|
|
||||||
|
status_t status;
|
||||||
|
// update the hash with the new key values
|
||||||
|
key.peer = (sockaddr *)&socket->peer;
|
||||||
|
if (hash_lookup(sTCPHash, &key) != NULL) {
|
||||||
|
status = hash_remove(sTCPHash, (void *)this);
|
||||||
|
if (status != B_OK) {
|
||||||
|
TRACE(("TCP: Hash Error: %s\n", strerror(status)));
|
||||||
|
benaphore_unlock(&sTCPLock);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
TRACE(("TCP: Connect(): Connection not in hash yet!\n"));
|
||||||
|
sAddressModule->set_to((sockaddr *)&socket->peer, address);
|
||||||
|
status = hash_insert(sTCPHash, (void *)this);
|
||||||
|
if (status != B_OK) {
|
||||||
|
TRACE(("TCP: Connect(): Error inserting connection into hash!\n"));
|
||||||
|
benaphore_unlock(&sTCPLock);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// done manipulating the hash, release the lock
|
||||||
|
benaphore_unlock(&sTCPLock);
|
||||||
|
|
||||||
|
TRACE(("TCP: Connect(): starting 3-way handshake...\n"));
|
||||||
|
// send SYN
|
||||||
|
status = Send(TCP_FLG_SYN);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
fState=SYN_SENT;
|
||||||
|
|
||||||
|
// TODO: Should Connect() not return until 3-way handshake is complete?
|
||||||
|
TRACE(("TCP: Connect(): Connection complete\n"));
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,16 +229,21 @@ TCPConnection::Connect(const struct sockaddr *address)
|
|||||||
status_t
|
status_t
|
||||||
TCPConnection::Accept(struct net_socket **_acceptedSocket)
|
TCPConnection::Accept(struct net_socket **_acceptedSocket)
|
||||||
{
|
{
|
||||||
return B_OK;
|
TRACE(("%p.Accept()\n", this));
|
||||||
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
TCPConnection::Bind(sockaddr *address)
|
TCPConnection::Bind(sockaddr *address)
|
||||||
{
|
{
|
||||||
|
TRACE(("TCP:%p.Bind() on address %s\n", this,
|
||||||
|
AddressString(sDomain, address, true).Data()));
|
||||||
|
|
||||||
if (address->sa_family != AF_INET)
|
if (address->sa_family != AF_INET)
|
||||||
return EAFNOSUPPORT;
|
return EAFNOSUPPORT;
|
||||||
|
|
||||||
|
BenaphoreLocker hashLock(&sTCPLock);
|
||||||
BenaphoreLocker lock(&fLock);
|
BenaphoreLocker lock(&fLock);
|
||||||
|
|
||||||
// let IP check whether there is an interface that supports the given address:
|
// let IP check whether there is an interface that supports the given address:
|
||||||
@@ -109,11 +251,20 @@ TCPConnection::Bind(sockaddr *address)
|
|||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
//TODO: clean this up
|
sAddressModule->set_to((sockaddr *)&socket->address, address);
|
||||||
/* fKey.source = ((struct sockaddr_in *)address)->sin_addr;
|
// for now, leave port=0. TCP should still work 1 connection at a time
|
||||||
fKey.source_port = sAddressModule->get_port(address);
|
if (0) { //sAddressModule->get_port((sockaddr *)&socket->address) == 0) {
|
||||||
fKey.destination = INADDR_ANY;
|
//assign ephemeral port
|
||||||
fKey.destination_port = 0;*/
|
} else {
|
||||||
|
//TODO:Check for Socket flags
|
||||||
|
tcp_connection_key key;
|
||||||
|
key.peer = (sockaddr *)&socket->peer;
|
||||||
|
key.local = (sockaddr *)&socket->address;
|
||||||
|
if (hash_lookup(sTCPHash, &key) == NULL) {
|
||||||
|
hash_insert(sTCPHash, (void *)this);
|
||||||
|
} else
|
||||||
|
return EADDRINUSE;
|
||||||
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -122,6 +273,17 @@ TCPConnection::Bind(sockaddr *address)
|
|||||||
status_t
|
status_t
|
||||||
TCPConnection::Unbind(struct sockaddr *address)
|
TCPConnection::Unbind(struct sockaddr *address)
|
||||||
{
|
{
|
||||||
|
TRACE(("TCP:%p.Unbind()\n", this ));
|
||||||
|
|
||||||
|
BenaphoreLocker hashLock(&sTCPLock);
|
||||||
|
BenaphoreLocker lock(&fLock);
|
||||||
|
|
||||||
|
status_t status = hash_remove(sTCPHash, (void *)this);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
sAddressModule->set_to_empty_address((sockaddr *)&socket->address);
|
||||||
|
sAddressModule->set_port((sockaddr *)&socket->address, 0);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,20 +291,23 @@ TCPConnection::Unbind(struct sockaddr *address)
|
|||||||
status_t
|
status_t
|
||||||
TCPConnection::Listen(int count)
|
TCPConnection::Listen(int count)
|
||||||
{
|
{
|
||||||
return B_OK;
|
TRACE(("%p.Listen()\n", this));
|
||||||
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
TCPConnection::Shutdown(int direction)
|
TCPConnection::Shutdown(int direction)
|
||||||
{
|
{
|
||||||
return B_OK;
|
TRACE(("%p.Shutdown()\n", this));
|
||||||
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
TCPConnection::SendData(net_buffer *buffer)
|
TCPConnection::SendData(net_buffer *buffer)
|
||||||
{
|
{
|
||||||
|
TRACE(("%p.SendData()\n", this));
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,6 +315,7 @@ TCPConnection::SendData(net_buffer *buffer)
|
|||||||
status_t
|
status_t
|
||||||
TCPConnection::SendRoutedData(net_route *route, net_buffer *buffer)
|
TCPConnection::SendRoutedData(net_route *route, net_buffer *buffer)
|
||||||
{
|
{
|
||||||
|
TRACE(("%p.SendRoutedData()\n", this));
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,6 +323,7 @@ TCPConnection::SendRoutedData(net_route *route, net_buffer *buffer)
|
|||||||
status_t
|
status_t
|
||||||
TCPConnection::SendAvailable()
|
TCPConnection::SendAvailable()
|
||||||
{
|
{
|
||||||
|
TRACE(("%p.SendAvailable()\n", this));
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,6 +331,7 @@ TCPConnection::SendAvailable()
|
|||||||
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(("%p.ReadData()\n", this));
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,20 +339,54 @@ TCPConnection::ReadData(size_t numBytes, uint32 flags, net_buffer **_buffer)
|
|||||||
status_t
|
status_t
|
||||||
TCPConnection::ReadAvailable()
|
TCPConnection::ReadAvailable()
|
||||||
{
|
{
|
||||||
|
TRACE(("%p.ReadAvailable()\n", this));
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
TCPConnection::ReceiveData(net_buffer *buffer)
|
||||||
|
{
|
||||||
|
TRACE(("%p.ReceiveData()\n", this));
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Resends a sent segment (\a data) if the segment's ACK wasn't received
|
||||||
|
before the timeout (eg \a timer expired)
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
TCPConnection::ResendSegment(struct net_timer *timer, void *data)
|
||||||
|
{
|
||||||
|
TRACE(("ResendSegment(%p)\n", data));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Sends a TCP packet with the specified \a flags. If there is any data in
|
||||||
|
the send buffer, fEffectiveWindow bytes or less of it are sent as well.
|
||||||
|
Sequence and Acknowledgement numbers are filled in accordingly.
|
||||||
|
The fLock benaphore must be held before calling.
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
TCPConnection::Send(uint8 flags)
|
||||||
|
{
|
||||||
|
TRACE(("%p.Send()\n", this));
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
TCPConnection::Compare(void *_packet, const void *_key)
|
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;
|
||||||
tcp_connection_key *packetKey = &((TCPConnection *)_packet)->fKey;
|
TCPConnection *connection= ((TCPConnection *)_connection);
|
||||||
|
|
||||||
if (key->source == packetKey->source
|
if (sAddressModule->equal_addresses_and_ports(
|
||||||
&& key->destination == packetKey->destination
|
key->local, (sockaddr *)&connection->socket->address)
|
||||||
&& key->source_port == packetKey->source_port
|
&& sAddressModule->equal_addresses_and_ports(
|
||||||
&& key->destination_port == packetKey->destination_port)
|
key->peer, (sockaddr *)&connection->socket->peer))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@@ -192,12 +394,15 @@ TCPConnection::Compare(void *_packet, const void *_key)
|
|||||||
|
|
||||||
|
|
||||||
uint32
|
uint32
|
||||||
TCPConnection::Hash(void *_packet, const void *_key, uint32 range)
|
TCPConnection::Hash(void *_connection, const void *_key, uint32 range)
|
||||||
{
|
{
|
||||||
const tcp_connection_key *key = (tcp_connection_key *)_key;
|
if (_connection != NULL) {
|
||||||
if (_packet != NULL)
|
TCPConnection *connection = (TCPConnection *)_connection;
|
||||||
key = &((TCPConnection *)_packet)->fKey;
|
return sAddressModule->hash_address_pair(
|
||||||
|
(sockaddr *)&connection->socket->address, (sockaddr *)&connection->socket->peer) % range;
|
||||||
|
}
|
||||||
|
|
||||||
return ((uint32)key->source_port << 16 ^ (uint32)key->destination_port
|
const tcp_connection_key *key = (tcp_connection_key *)_key;
|
||||||
^ key->source ^ key->destination) % range;
|
return sAddressModule->hash_address_pair(
|
||||||
|
key->local, key->peer) % range;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,19 +48,45 @@ static net_stack_module_info *sStackModule;
|
|||||||
static hash_table *sTCPHash;
|
static hash_table *sTCPHash;
|
||||||
static benaphore sTCPLock;
|
static benaphore sTCPLock;
|
||||||
|
|
||||||
|
|
||||||
#include "tcp.h"
|
#include "tcp.h"
|
||||||
#include "TCPConnection.h"
|
#include "TCPConnection.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef TRACE_TCP
|
||||||
|
# define DUMP_HASH tcp_dump_hash()
|
||||||
|
// Dumps the TCP Connection hash. sTCPLock must NOT be held when calling
|
||||||
|
void
|
||||||
|
tcp_dump_hash(){
|
||||||
|
BenaphoreLocker lock(&sTCPLock);
|
||||||
|
if (sDomain == NULL) {
|
||||||
|
TRACE(("Unable to dump TCP Connections!\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
struct hash_iterator iterator;
|
||||||
|
hash_open(sTCPHash, &iterator);
|
||||||
|
TCPConnection *connection;
|
||||||
|
hash_rewind(sTCPHash, &iterator);
|
||||||
|
TRACE(("Active TCP Connections:\n"));
|
||||||
|
while ((connection = (TCPConnection *)hash_next(sTCPHash, &iterator)) != NULL) {
|
||||||
|
TRACE((" TCPConnection %p: %s, %s\n", connection,
|
||||||
|
AddressString(sDomain, (sockaddr *)&connection->socket->address, true).Data(),
|
||||||
|
AddressString(sDomain, (sockaddr *)&connection->socket->peer, true).Data()));
|
||||||
|
}
|
||||||
|
hash_close(sTCPHash, &iterator, false);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
# define DUMP_HASH
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
net_protocol *
|
net_protocol *
|
||||||
tcp_init_protocol(net_socket *socket)
|
tcp_init_protocol(net_socket *socket)
|
||||||
{
|
{
|
||||||
|
DUMP_HASH;
|
||||||
socket->protocol = IPPROTO_TCP;
|
socket->protocol = IPPROTO_TCP;
|
||||||
TCPConnection *protocol = new (std::nothrow) TCPConnection(socket);
|
TCPConnection *protocol = new (std::nothrow) TCPConnection(socket);
|
||||||
if (protocol == NULL)
|
TRACE(("Creating new TCPConnection: %p\n", protocol));
|
||||||
return NULL;
|
|
||||||
|
|
||||||
TRACE(("Created new TCPConnection %p\n", protocol));
|
|
||||||
return protocol;
|
return protocol;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,6 +94,8 @@ tcp_init_protocol(net_socket *socket)
|
|||||||
status_t
|
status_t
|
||||||
tcp_uninit_protocol(net_protocol *protocol)
|
tcp_uninit_protocol(net_protocol *protocol)
|
||||||
{
|
{
|
||||||
|
DUMP_HASH;
|
||||||
|
TRACE(("Deleting TCPConnection: %p\n", protocol));
|
||||||
delete (TCPConnection *)protocol;
|
delete (TCPConnection *)protocol;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -76,6 +104,12 @@ tcp_uninit_protocol(net_protocol *protocol)
|
|||||||
status_t
|
status_t
|
||||||
tcp_open(net_protocol *protocol)
|
tcp_open(net_protocol *protocol)
|
||||||
{
|
{
|
||||||
|
if (!sDomain)
|
||||||
|
sDomain = sStackModule->get_domain(AF_INET);
|
||||||
|
if (!sAddressModule)
|
||||||
|
sAddressModule = sDomain->address_module;
|
||||||
|
DUMP_HASH;
|
||||||
|
|
||||||
return ((TCPConnection *)protocol)->Open();
|
return ((TCPConnection *)protocol)->Open();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,6 +117,7 @@ tcp_open(net_protocol *protocol)
|
|||||||
status_t
|
status_t
|
||||||
tcp_close(net_protocol *protocol)
|
tcp_close(net_protocol *protocol)
|
||||||
{
|
{
|
||||||
|
DUMP_HASH;
|
||||||
return ((TCPConnection *)protocol)->Close();
|
return ((TCPConnection *)protocol)->Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,6 +125,7 @@ tcp_close(net_protocol *protocol)
|
|||||||
status_t
|
status_t
|
||||||
tcp_free(net_protocol *protocol)
|
tcp_free(net_protocol *protocol)
|
||||||
{
|
{
|
||||||
|
DUMP_HASH;
|
||||||
return ((TCPConnection *)protocol)->Free();
|
return ((TCPConnection *)protocol)->Free();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,6 +133,7 @@ tcp_free(net_protocol *protocol)
|
|||||||
status_t
|
status_t
|
||||||
tcp_connect(net_protocol *protocol, const struct sockaddr *address)
|
tcp_connect(net_protocol *protocol, const struct sockaddr *address)
|
||||||
{
|
{
|
||||||
|
DUMP_HASH;
|
||||||
return ((TCPConnection *)protocol)->Connect(address);
|
return ((TCPConnection *)protocol)->Connect(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,16 +157,15 @@ tcp_control(net_protocol *protocol, int level, int option, void *value,
|
|||||||
status_t
|
status_t
|
||||||
tcp_bind(net_protocol *protocol, struct sockaddr *address)
|
tcp_bind(net_protocol *protocol, struct sockaddr *address)
|
||||||
{
|
{
|
||||||
TRACE(("tcp_bind(%p) on address %s\n", protocol,
|
DUMP_HASH;
|
||||||
AddressString(sDomain, address, true).Data()));
|
return ((TCPConnection *)protocol)->Bind(address);
|
||||||
TCPConnection *connection = (TCPConnection *)protocol;
|
|
||||||
return connection->Bind(address);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
tcp_unbind(net_protocol *protocol, struct sockaddr *address)
|
tcp_unbind(net_protocol *protocol, struct sockaddr *address)
|
||||||
{
|
{
|
||||||
|
DUMP_HASH;
|
||||||
return ((TCPConnection *)protocol)->Unbind(address);
|
return ((TCPConnection *)protocol)->Unbind(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,6 +235,17 @@ tcp_get_mtu(net_protocol *protocol, const struct sockaddr *address)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Constructs a TCP header on \a buffer with the specified values
|
||||||
|
for \a flags, \a seq and \a ack. The packet is then sent on \a route
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
tcp_send_segment(net_buffer *buffer, net_route *route, uint16 flags, uint32 seq, uint32 ack)
|
||||||
|
{
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
tcp_receive_data(net_buffer *buffer)
|
tcp_receive_data(net_buffer *buffer)
|
||||||
{
|
{
|
||||||
@@ -229,10 +276,8 @@ tcp_init()
|
|||||||
{
|
{
|
||||||
status_t status;
|
status_t status;
|
||||||
|
|
||||||
#if 0
|
sDomain = NULL;
|
||||||
sDomain = sStackModule->get_domain(AF_INET);
|
sAddressModule = NULL;
|
||||||
sAddressModule = sDomain->address_module;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
status = get_module(NET_STACK_MODULE_NAME, (module_info **)&sStackModule);
|
status = get_module(NET_STACK_MODULE_NAME, (module_info **)&sStackModule);
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
|
|||||||
Reference in New Issue
Block a user