sbuf.c revision 4303a4a8fc3ab5903d4a0d12a4bbbd5d187960aa
/* $Id$ */
/** @file
* NAT - sbuf implemenation.
*/
/*
* Copyright (C) 2006-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
/*
* This code is based on:
*
* Copyright (c) 1995 Danny Gasparovski.
*
* Please read the file COPYRIGHT for the
* terms and conditions of the copyright.
*/
#include <slirp.h>
#ifndef VBOX_WITH_SLIRP_BSD_SBUF
/* Done as a macro in socket.h */
/* int
* sbspace(struct sockbuff *sb)
* {
* return SB_DATALEN - sb->sb_cc;
* }
*/
void
{
/*
* Catch double frees. Actually tcp_close() already filters out listening sockets
* passing NULL.
*/
/*
* Don't call RTMemFree() for an already freed buffer, the EFence could complain
*/
{
}
}
void
{
/*
* We can only drop how much we have
* This should never succeed
*/
}
void
{
{
/* Already alloced, realloc if necessary */
{
else
sb->sb_datalen = 0;
}
}
else
{
else
sb->sb_datalen = 0;
}
}
/*
* Try and write() to the socket, whatever doesn't get written
* append to the buffer... for a host with a fast net connection,
* this prevents an unnecessary copy of the data
* (the socket is non-blocking, so we won't hang)
*/
void
{
int ret = 0;
int mlen = 0;
/* Shouldn't happen, but... e.g. foreign host closes connection */
if (mlen <= 0)
{
goto done;
}
/*
* If there is urgent data, call sosendoob
* if not all was sent, sowrite will take care of the rest
* (The rest of this function is just an optimisation)
*/
{
return;
}
/*
* We only write if there's nothing in the buffer,
* otherwise it'll arrive out of order, and hence corrupt
*/
{
if (m->m_next)
{
{
ret = 0;
goto no_sent;
}
}
else
if (m->m_next)
}
if (ret <= 0)
{
/*
* Nothing was written
* It's possible that the socket has closed, but
* we don't need to check because if it has closed,
* it will be detected in the normal way by soread()
*/
goto done;
}
{
/*
* Something was written, but not everything..
* sbappendsb the rest
*/
goto done;
} /* else */
/* Whatever happened, we free the mbuf */
done:
}
/*
* Copy the data from m into sb
* The caller is responsible to make sure there's enough room
*/
void
{
#ifndef VBOX_WITH_STATISTICS
#endif
{
if (n > len)
n = len;
}
else
{
/* Do the right edge first */
if (n > len)
n = len;
len -= n;
if (len)
{
/* Now the left edge */
n += nn;
}
}
{
}
}
/*
* Copy data from sbuf to a normal, straight buffer
* Don't update the sbuf rptr, this will be
* done in sbdrop when the data is acked
*/
void
{
char *from;
{
}
else
{
/* re-use off */
if (len)
}
}
#else /* VBOX_WITH_SLIRP_BSD_SBUF */
void
{
int ret = 0;
int mlen = 0;
if (mlen <= 0)
{
goto done;
}
/*
* We only write if there's nothing in the buffer,
* ottherwise it'll arrive out of order, and hence corrupt
*/
{
ret = 0;
goto no_sent;
}
/*
* If there is urgent data, call sosendoob
* if not all was sent, sowrite will take care of the rest
* (The rest of this function is just an optimisation)
*/
{
return;
}
if (ret <= 0)
{
/*
* Nothing was written
* It's possible that the socket has closed, but
* we don't need to check because if it has closed,
* it will be detected in the normal way by soread()
*/
goto done;
}
{
/*
* Something was written, but not everything..
* sbappendsb the rest
*/
goto done;
} /* else */
/* Whatever happened, we free the mbuf */
done:
}
#endif