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:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user