fixed add_tcp_header() as it wasn't considering the possibility that prepending data would not result in a contiguous buffer. This would result in wrong checksums for apparent no reason.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20643 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Hugo Santos
2007-04-10 19:04:13 +00:00
parent 1c96882baa
commit af56b5b233
2 changed files with 40 additions and 14 deletions
+32 -13
View File
@@ -81,21 +81,24 @@ template<typename Type, typename Module = NetBufferModuleGetter > class NetBuffe
Type fDataBuffer;
};
//! A class to add a header to a buffer
template<typename Type, typename Module = NetBufferModuleGetter > class NetBufferPrepend {
//! A class to access a header safely across data node boundaries
template<typename Type, typename Module = NetBufferModuleGetter>
class NetBufferSafeHeader {
public:
NetBufferPrepend(net_buffer *buffer, size_t size = 0)
NetBufferSafeHeader(net_buffer *buffer)
:
fBuffer(buffer),
fData(NULL)
fBuffer(buffer)
{
if (size == 0)
size = sizeof(Type);
fStatus = Module::Get()->prepend_size(buffer, size, (void **)&fData);
fStatus = Module::Get()->direct_access(fBuffer, 0,
sizeof(Type), (void **)&fData);
if (fStatus != B_OK) {
fData = NULL;
fStatus = Module::Get()->read(fBuffer, 0, &fDataBuffer,
sizeof(Type));
}
}
~NetBufferPrepend()
~NetBufferSafeHeader()
{
if (fBuffer != NULL)
Detach();
@@ -116,8 +119,6 @@ template<typename Type, typename Module = NetBufferModuleGetter > class NetBuffe
return fDataBuffer;
}
// TODO: I'm not sure it's a good idea to have Detach() routines
// in NetBufferHeader and here with such a different outcome...
void
Detach()
{
@@ -126,11 +127,29 @@ template<typename Type, typename Module = NetBufferModuleGetter > class NetBuffe
fBuffer = NULL;
}
private:
protected:
NetBufferSafeHeader() {}
net_buffer *fBuffer;
status_t fStatus;
Type *fData;
Type fDataBuffer;
};
//! A class to add a header to a buffer
template<typename Type, typename Module = NetBufferModuleGetter>
class NetBufferPrepend : public NetBufferSafeHeader<Type, Module> {
public:
NetBufferPrepend(net_buffer *buffer, size_t size = 0)
{
fBuffer = buffer;
fData = NULL;
if (size == 0)
size = sizeof(Type);
fStatus = Module::Get()->prepend_size(buffer, size, (void **)&fData);
}
};
#endif // NET_BUFFER_UTILITIES_H
@@ -148,6 +148,10 @@ add_tcp_header(tcp_segment_header &segment, net_buffer *buffer)
header.urgent_offset = 0;
// TODO: urgent pointer not yet supported
// we must detach before calculating the checksum as we may
// not have a contiguous buffer.
bufferHeader.Detach();
if (optionsLength > 0)
gBufferModule->write(buffer, sizeof(tcp_header), optionsBuffer, optionsLength);
@@ -162,7 +166,10 @@ add_tcp_header(tcp_segment_header &segment, net_buffer *buffer)
<< (uint16)htons(IPPROTO_TCP)
<< (uint16)htons(buffer->size)
<< Checksum::BufferHelper(buffer, gBufferModule);
header.checksum = checksum;
// we are pretty sure the header is there.
NetBufferSafeHeader<tcp_header> headerRef(buffer);
headerRef.Data().checksum = checksum;
return B_OK;
}