svn merge -r108236:108243 svn+ssh://svn.lindenlab.com/svn/linden/branches/server/server-1.25

Still merging from server-1.25... one day I will catch up!

No conflicts
master
Robert Knop 2009-01-19 22:05:19 +00:00
parent f1380f2fc3
commit ce888706c5
8 changed files with 137 additions and 5 deletions

View File

@ -74,5 +74,6 @@ void LLPacketBuffer::init (S32 hSocket)
{
mSize = receive_packet(hSocket, mData);
mHost = ::get_sender();
mReceivingIF = ::get_receiving_interface();
}

View File

@ -44,15 +44,17 @@ public:
LLPacketBuffer(S32 hSocket); // receive a packet
~LLPacketBuffer();
S32 getSize() const { return mSize; }
const char *getData() const { return mData; }
LLHost getHost() const { return mHost; }
S32 getSize() const { return mSize; }
const char *getData() const { return mData; }
LLHost getHost() const { return mHost; }
LLHost getReceivingInterface() const { return mReceivingIF; }
void init(S32 hSocket);
protected:
char mData[NET_BUFFER_SIZE]; // packet data /* Flawfinder : ignore */
S32 mSize; // size of buffer in bytes
LLHost mHost; // source/dest IP and port
LLHost mReceivingIF; // source/dest IP and port
};
#endif

View File

@ -141,6 +141,7 @@ S32 LLPacketRing::receiveFromRing (S32 socket, char *datap)
}
// need to set sender IP/port!!
mLastSender = packetp->getHost();
mLastReceivingIF = packetp->getReceivingInterface();
delete packetp;
this->mInBufferLength -= packet_size;
@ -223,6 +224,7 @@ S32 LLPacketRing::receivePacket (S32 socket, char *datap)
// no delay, pull straight from net
packet_size = receive_packet(socket, datap);
mLastSender = ::get_sender();
mLastReceivingIF = ::get_receiving_interface();
if (packet_size) // did we actually get a packet?
{

View File

@ -62,6 +62,7 @@ public:
BOOL sendPacket(int h_socket, char * send_buffer, S32 buf_size, LLHost host);
inline LLHost getLastSender();
inline LLHost getLastReceivingInterface();
S32 getAndResetActualInBits() { S32 bits = mActualBitsIn; mActualBitsIn = 0; return bits;}
S32 getAndResetActualOutBits() { S32 bits = mActualBitsOut; mActualBitsOut = 0; return bits;}
@ -86,6 +87,7 @@ protected:
std::queue<LLPacketBuffer *> mSendQueue;
LLHost mLastSender;
LLHost mLastReceivingIF;
};
@ -94,4 +96,9 @@ inline LLHost LLPacketRing::getLastSender()
return mLastSender;
}
inline LLHost LLPacketRing::getLastReceivingInterface()
{
return mLastReceivingIF;
}
#endif

View File

@ -306,6 +306,9 @@ LLMessageSystem::LLMessageSystem(const std::string& filename, U32 port,
// default to not accepting packets from not alive circuits
mbProtected = TRUE;
// default to blocking trusted connections on a public interface if one is specified
mBlockUntrustedInterface = true;
mSendPacketFailureCount = 0;
mCircuitPrintFreq = 60.f; // seconds
@ -440,6 +443,7 @@ void LLMessageSystem::clearReceiveState()
mCurrentRecvPacketID = 0;
mIncomingCompressedSize = 0;
mLastSender.invalidate();
mLastReceivingIF.invalidate();
mMessageReader->clearMessage();
}
@ -589,6 +593,7 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )
receive_size = mTrueReceiveSize;
mLastSender = mPacketRing.getLastSender();
mLastReceivingIF = mPacketRing.getLastReceivingInterface();
if (receive_size < (S32) LL_MINIMUM_VALID_PACKET_SIZE)
{
@ -2355,6 +2360,23 @@ void process_create_trusted_circuit(LLMessageSystem *msg, void **)
return;
}
U32 untrusted_interface = msg->getUntrustedInterface().getAddress();
U32 last_interface = msg->getReceivingInterface().getAddress();
if ( ( untrusted_interface != INVALID_HOST_IP_ADDRESS ) && ( untrusted_interface == last_interface ) )
{
if( msg->getBlockUntrustedInterface() )
{
LL_WARNS("Messaging") << "Refusing trust on public interface from host: "
<< msg->getSender() << llendl;
return;
}
else
{
LL_WARNS("Messaging") << "Establishing trust on public interface from host: "
<< msg->getSender() << llendl;
}
}
char their_digest[MD5HEX_STR_SIZE]; /* Flawfinder: ignore */
S32 size = msg->getSizeFast(_PREHASH_DataBlock, _PREHASH_Digest);
if(size != MD5HEX_STR_BYTES)

View File

@ -212,6 +212,9 @@ class LLMessageSystem
U8 mSendBuffer[MAX_BUFFER_SIZE];
S32 mSendSize;
bool mBlockUntrustedInterface;
LLHost mUntrustedInterface;
public:
LLPacketRing mPacketRing;
LLReliablePacketParams mReliablePacketParams;
@ -352,6 +355,8 @@ public:
U32 getSenderIP() const; // getSender() is preferred
U32 getSenderPort() const; // getSender() is preferred
const LLHost& getReceivingInterface() const;
// This method returns the uuid associated with the sender. The
// UUID will be null if it is not yet known or is a server
// circuit.
@ -564,6 +569,12 @@ public:
/** Return false true if name is unknown or trusted */
bool isUntrustedMessage(const std::string& name) const;
// Mark an interface ineligible for trust
void setUntrustedInterface( const LLHost host ) { mUntrustedInterface = host; }
LLHost getUntrustedInterface() const { return mUntrustedInterface; }
void setBlockUntrustedInterface( bool block ) { mBlockUntrustedInterface = block; } // Throw a switch to allow, sending warnings only
bool getBlockUntrustedInterface() const { return mBlockUntrustedInterface; }
// Change this message to be UDP black listed.
void banUdpMessage(const std::string& name);
@ -747,6 +758,7 @@ private:
void init(); // ctor shared initialisation.
LLHost mLastSender;
LLHost mLastReceivingIF;
S32 mIncomingCompressedSize; // original size of compressed msg (0 if uncomp.)
TPACKETID mCurrentRecvPacketID; // packet ID of current receive packet (for reporting)
@ -966,6 +978,7 @@ inline void *ntohmemcpy(void *s, const void *ct, EMsgVariableType type, size_t n
inline const LLHost& LLMessageSystem::getSender() const {return mLastSender;}
inline const LLHost& LLMessageSystem::getReceivingInterface() const {return mLastReceivingIF;}
inline U32 LLMessageSystem::getSenderIP() const
{
@ -977,6 +990,7 @@ inline U32 LLMessageSystem::getSenderPort() const
return mLastSender.getPort();
}
//-----------------------------------------------------------------------------
// Transmission aliases
//-----------------------------------------------------------------------------

View File

@ -71,6 +71,7 @@ static WSADATA stWSAData;
struct sockaddr_in stDstAddr;
struct sockaddr_in stSrcAddr;
struct sockaddr_in stLclAddr;
static U32 gsnReceivingIFAddr = INVALID_HOST_IP_ADDRESS; // Address to which datagram was sent
#if LL_DARWIN
#ifndef _SOCKLEN_T
@ -110,6 +111,16 @@ U32 get_sender_port()
return ntohs(stSrcAddr.sin_port);
}
LLHost get_receiving_interface()
{
return LLHost(gsnReceivingIFAddr, INVALID_PORT);
}
U32 get_receiving_interface_ip(void)
{
return gsnReceivingIFAddr;
}
const char* u32_to_ip_string(U32 ip)
{
static char buffer[MAXADDRSTR]; /* Flawfinder: ignore */
@ -455,6 +466,21 @@ S32 start_net(S32& socket_out, int& nPort)
llinfos << "startNet - receive buffer size : " << rec_size << llendl;
llinfos << "startNet - send buffer size : " << snd_size << llendl;
#if LL_LINUX
// Turn on recipient address tracking
{
int use_pktinfo = 1;
if( setsockopt( hSocket, SOL_IP, IP_PKTINFO, &use_pktinfo, sizeof(use_pktinfo) ) == -1 )
{
llwarns << "No IP_PKTINFO available" << llendl;
}
else
{
llinfos << "IP_PKKTINFO enabled" << llendl;
}
}
#endif
// Setup a destination address
char achMCAddr[MAXADDRSTR] = "127.0.0.1"; /* Flawfinder: ignore */
stDstAddr.sin_family = AF_INET;
@ -473,6 +499,52 @@ void end_net(S32& socket_out)
}
}
#if LL_LINUX
static int recvfrom_destip( int socket, void *buf, int len, struct sockaddr *from, socklen_t *fromlen, U32 *dstip )
{
int size;
struct iovec iov[1];
char cmsg[CMSG_SPACE(sizeof(struct in_pktinfo))];
struct cmsghdr *cmsgptr;
struct msghdr msg = {0};
iov[0].iov_base = buf;
iov[0].iov_len = len;
memset( &msg, 0, sizeof msg );
msg.msg_name = from;
msg.msg_namelen = *fromlen;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
msg.msg_control = &cmsg;
msg.msg_controllen = sizeof(cmsg);
size = recvmsg( socket, &msg, 0 );
if( size == -1 )
{
return -1;
}
for( cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; cmsgptr = CMSG_NXTHDR( &msg, cmsgptr ) )
{
if( cmsgptr->cmsg_level == SOL_IP && cmsgptr->cmsg_type == IP_PKTINFO )
{
in_pktinfo *pktinfo = (in_pktinfo *)CMSG_DATA(cmsgptr);
if( pktinfo )
{
// Two choices. routed and specified. ipi_addr is routed, ipi_spec_dst is
// routed. We should stay with specified until we go to multiple
// interfaces
*dstip = pktinfo->ipi_spec_dst.s_addr;
}
}
}
return size;
}
#endif
int receive_packet(int hSocket, char * receiveBuffer)
{
// Receives data asynchronously from the socket set by initNet().
@ -482,7 +554,14 @@ int receive_packet(int hSocket, char * receiveBuffer)
int nRet;
socklen_t addr_size = sizeof(struct sockaddr_in);
nRet = recvfrom(hSocket, receiveBuffer, NET_BUFFER_SIZE, 0, (struct sockaddr*)&stSrcAddr, &addr_size);
gsnReceivingIFAddr = INVALID_HOST_IP_ADDRESS;
#if LL_LINUX
nRet = recvfrom_destip(hSocket, receiveBuffer, NET_BUFFER_SIZE, (struct sockaddr*)&stSrcAddr, &addr_size, &gsnReceivingIFAddr);
#else
int recv_flags = 0;
nRet = recvfrom(hSocket, receiveBuffer, NET_BUFFER_SIZE, recv_flags, (struct sockaddr*)&stSrcAddr, &addr_size);
#endif
if (nRet == -1)
{
@ -490,6 +569,9 @@ int receive_packet(int hSocket, char * receiveBuffer)
return 0;
}
// Uncomment for testing if/when implementing for Mac or Windows:
// llinfos << "Received datagram to in addr " << u32_to_ip_string(get_receiving_interface_ip()) << llendl;
return nRet;
}

View File

@ -55,6 +55,8 @@ BOOL send_packet(int hSocket, const char *sendBuffer, int size, U32 recipient, i
LLHost get_sender();
U32 get_sender_port();
U32 get_sender_ip(void);
LLHost get_receiving_interface();
U32 get_receiving_interface_ip(void);
const char* u32_to_ip_string(U32 ip); // Returns pointer to internal string buffer, "(bad IP addr)" on failure, cannot nest calls
char* u32_to_ip_string(U32 ip, char *ip_string); // NULL on failure, ip_string on success, you must allocate at least MAXADDRSTR chars