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; Type fDataBuffer;
}; };
//! A class to add a header to a buffer //! A class to access a header safely across data node boundaries
template<typename Type, typename Module = NetBufferModuleGetter > class NetBufferPrepend { template<typename Type, typename Module = NetBufferModuleGetter>
class NetBufferSafeHeader {
public: public:
NetBufferPrepend(net_buffer *buffer, size_t size = 0) NetBufferSafeHeader(net_buffer *buffer)
: :
fBuffer(buffer), fBuffer(buffer)
fData(NULL)
{ {
if (size == 0) fStatus = Module::Get()->direct_access(fBuffer, 0,
size = sizeof(Type); sizeof(Type), (void **)&fData);
if (fStatus != B_OK) {
fStatus = Module::Get()->prepend_size(buffer, size, (void **)&fData); fData = NULL;
fStatus = Module::Get()->read(fBuffer, 0, &fDataBuffer,
sizeof(Type));
}
} }
~NetBufferPrepend() ~NetBufferSafeHeader()
{ {
if (fBuffer != NULL) if (fBuffer != NULL)
Detach(); Detach();
@@ -116,8 +119,6 @@ template<typename Type, typename Module = NetBufferModuleGetter > class NetBuffe
return fDataBuffer; 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 void
Detach() Detach()
{ {
@@ -126,11 +127,29 @@ template<typename Type, typename Module = NetBufferModuleGetter > class NetBuffe
fBuffer = NULL; fBuffer = NULL;
} }
private: protected:
NetBufferSafeHeader() {}
net_buffer *fBuffer; net_buffer *fBuffer;
status_t fStatus; status_t fStatus;
Type *fData; Type *fData;
Type fDataBuffer; 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 #endif // NET_BUFFER_UTILITIES_H
@@ -148,6 +148,10 @@ add_tcp_header(tcp_segment_header &segment, net_buffer *buffer)
header.urgent_offset = 0; header.urgent_offset = 0;
// TODO: urgent pointer not yet supported // 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) if (optionsLength > 0)
gBufferModule->write(buffer, sizeof(tcp_header), optionsBuffer, optionsLength); 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(IPPROTO_TCP)
<< (uint16)htons(buffer->size) << (uint16)htons(buffer->size)
<< Checksum::BufferHelper(buffer, gBufferModule); << 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; return B_OK;
} }