added possibility to include manually some IP ranges

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@8315 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2015-05-29 18:03:14 +00:00
parent 86eb9a33d6
commit 4ebc87b9c2
7 changed files with 160 additions and 62 deletions

View File

@ -62,6 +62,8 @@ public:
virtual void enableIPFiltering(bool b) =0;
virtual bool ipFilteringEnabled() =0;
virtual void addIpRange(const struct sockaddr_storage& addr,int masked_bytes,const std::string& comment) =0;
virtual bool isAddressAccepted(const struct sockaddr_storage& addr) =0;
virtual void getListOfBannedIps(std::list<BanListPeer>& list) =0;

View File

@ -124,12 +124,12 @@ BanListPeer::BanListPeer()
masked_bytes=0;
reason=RSBANLIST_REASON_UNKNOWN ;
level=RSBANLIST_ORIGIN_UNKNOWN ;
state = false ;
state = true ;
connect_attempts=0;
mTs=0;
}
static sockaddr_storage make24BitsRange(const sockaddr_storage& addr)
static sockaddr_storage makeBitsRange(const sockaddr_storage& addr,int masked_bytes)
{
sockaddr_storage s ;
sockaddr_storage_clear(s) ;
@ -137,7 +137,12 @@ static sockaddr_storage make24BitsRange(const sockaddr_storage& addr)
sockaddr_in *ad = (sockaddr_in*)(&s) ;
ad->sin_addr.s_addr |= 0xff000000 ;
if(masked_bytes == 1)
ad->sin_addr.s_addr |= 0xff000000 ;
else if(masked_bytes == 2)
ad->sin_addr.s_addr |= 0xffff0000 ;
else if(masked_bytes != 0)
std::cerr << "Warning: unhandled mask size for IP range: " << masked_bytes << std::endl;
return s ;
}
@ -146,7 +151,18 @@ void p3BanList::autoFigureOutBanRanges()
{
RS_STACK_MUTEX(mBanMtx) ;
mBanRanges.clear() ;
// clear automatic ban ranges
for(std::map<sockaddr_storage,BanListPeer>::iterator it(mBanRanges.begin());it!=mBanRanges.end();)
if(it->second.reason == RSBANLIST_REASON_AUTO_RANGE)
{
std::map<sockaddr_storage,BanListPeer>::iterator it2=it ;
++it2 ;
mBanRanges.erase(it) ;
it=it2 ;
}
else
++it;
if(!mAutoRangeIps)
return ;
@ -156,7 +172,7 @@ void p3BanList::autoFigureOutBanRanges()
std::map<sockaddr_storage,ZeroedInt> range_map ;
for(std::map<sockaddr_storage,BanListPeer>::iterator it(mBanSet.begin());it!=mBanSet.end();++it)
++range_map[make24BitsRange(it->first)].n ;
++range_map[makeBitsRange(it->first,1)].n ;
time_t now = time(NULL) ;
@ -169,6 +185,9 @@ void p3BanList::autoFigureOutBanRanges()
std::cerr << " --> creating new ban range." << std::endl;
BanListPeer& peer(mBanRanges[it->first]) ;
if(peer.reason == RSBANLIST_REASON_USER)
continue ;
peer.addr = it->first ;
peer.masked_bytes = 1 ;
peer.reason = RSBANLIST_REASON_AUTO_RANGE ;
@ -190,12 +209,20 @@ bool p3BanList::isAddressAccepted(const sockaddr_storage &addr)
// we should normally work this including entire ranges of IPs. For now, just check the exact IPs.
sockaddr_storage addr_24 = make24BitsRange(addr) ;
sockaddr_storage addr_24 = makeBitsRange(addr,1) ;
sockaddr_storage addr_16 = makeBitsRange(addr,2) ;
std::cerr << "p3BanList::isAddressAccepted() testing " << sockaddr_storage_iptostring(addr) << " and range " << sockaddr_storage_iptostring(addr_24) ;
std::map<sockaddr_storage,BanListPeer>::iterator it ;
if((it=mBanRanges.find(addr_16)) != mBanRanges.end())
{
++it->second.connect_attempts;
std::cerr << " returning false. attempts=" << it->second.connect_attempts << std::endl;
return false ;
}
if((it=mBanRanges.find(addr_24)) != mBanRanges.end())
{
++it->second.connect_attempts;
@ -219,13 +246,38 @@ void p3BanList::getListOfBannedIps(std::list<BanListPeer> &lst)
RS_STACK_MUTEX(mBanMtx) ;
for(std::map<sockaddr_storage,BanListPeer>::const_iterator it(mBanSet.begin());it!=mBanSet.end();++it)
if(mBanRanges.find(make24BitsRange(it->first)) == mBanRanges.end())
if(mBanRanges.find(makeBitsRange(it->first,1)) == mBanRanges.end()
&& mBanRanges.find(makeBitsRange(it->first,2)) == mBanRanges.end())
lst.push_back(it->second) ;
for(std::map<sockaddr_storage,BanListPeer>::const_iterator it(mBanRanges.begin());it!=mBanRanges.end();++it)
lst.push_back(it->second) ;
}
void p3BanList::addIpRange(const sockaddr_storage &addr, int masked_bytes,const std::string& comment)
{
RS_STACK_MUTEX(mBanMtx) ;
BanListPeer blp ;
blp.level = RSBANLIST_ORIGIN_SELF ;
blp.connect_attempts = 0 ;
blp.addr = addr ;
blp.masked_bytes = masked_bytes ;
blp.mTs = time(NULL) ;
blp.reason = RSBANLIST_REASON_USER;
blp.comment = comment ;
if(masked_bytes != 0 && masked_bytes != 1 && masked_bytes != 2)
{
std::cerr << "Unhandled masked byte size " << masked_bytes << ". Should be 0,1 or 2" << std::endl;
return ;
}
sockaddr_storage addrrange = makeBitsRange(addr,masked_bytes) ;
mBanRanges[addrrange] = blp ;
}
int p3BanList::tick()
{
processIncoming();
@ -237,6 +289,7 @@ int p3BanList::tick()
{
if(mIPDHTGatheringEnabled)
getDhtInfo() ;
mLastDhtInfoRequest = now;
if(mAutoRangeIps)
@ -332,7 +385,6 @@ bool p3BanList::recvBanItem(RsBanListItem *item)
{
bool updated = false;
std::cerr << "(EE) should not receive a Ban item yet. Not implemented!" << std::endl;
time_t now = time(NULL) ;
std::list<RsTlvBanListEntry>::const_iterator it;
//for(it = item->peerList.entries.begin(); it != item->peerList.entries.end(); ++it)

View File

@ -64,6 +64,8 @@ public:
virtual bool isAddressAccepted(const struct sockaddr_storage& addr) ;
virtual void getListOfBannedIps(std::list<BanListPeer>& list) ;
virtual void addIpRange(const struct sockaddr_storage& addr,int masked_bytes,const std::string& comment) ;
virtual void enableIPFiltering(bool b) ;
virtual bool ipFilteringEnabled() ;
@ -85,13 +87,13 @@ public:
/***** overloaded from p3Service *****/
/*!
* This retrieves all chat msg items and also (important!)
* processes chat-status items that are in service item queue. chat msg item requests are also processed and not returned
* (important! also) notifications sent to notify base on receipt avatar, immediate status and custom status
* : notifyCustomState, notifyChatStatus, notifyPeerHasNewAvatar
* @see NotifyBase
* This retrieves all chat msg items and also (important!)
* processes chat-status items that are in service item queue. chat msg item requests are also processed and not returned
* (important! also) notifications sent to notify base on receipt avatar, immediate status and custom status
* : notifyCustomState, notifyChatStatus, notifyPeerHasNewAvatar
* @see NotifyBase
*/
*/
virtual int tick();
virtual int status();
@ -105,8 +107,8 @@ public:
/*!
* Interface stuff.
*/
* Interface stuff.
*/
/*************** pqiMonitor callback ***********************/
//virtual void statusChange(const std::list<pqipeer> &plist);

View File

@ -77,12 +77,13 @@ ServerPage::ServerPage(QWidget * parent, Qt::WindowFlags flags)
QObject::connect(ui.includeFromFriends_CB,SIGNAL(toggled(bool)),this,SLOT(toggleAutoIncludeFriends(bool)));
QObject::connect(ui.groupIPRanges_CB,SIGNAL(toggled(bool)),this,SLOT(toggleGroupIps(bool)));
QObject::connect(ui.groupIPRanges_SB,SIGNAL(valueChanged(int)),this,SLOT(setGroupIpLimit(int)));
QObject::connect(ui.ipInputAdd_PB,SIGNAL(clicked()),this,SLOT(addIpRange()));
QObject::connect(ui.ipInput_LE,SIGNAL(textChanged(const QString&)),this,SLOT(checkIpRange(const QString&)));
QTimer *timer = new QTimer(this);
timer->connect(timer, SIGNAL(timeout()), this, SLOT(updateStatus()));
timer->start(1000);
//load();
updateStatus();
@ -108,6 +109,81 @@ ServerPage::ServerPage(QWidget * parent, Qt::WindowFlags flags)
std::cerr << std::endl;
#endif
}
static bool parseAddrFromQString(const QString& s,struct sockaddr_storage& addr,int& bytes )
{
QStringList lst = s.split(".") ;
QStringList::const_iterator it = lst.begin();
bool ok ;
uint32_t s1 = (*it).toInt(&ok) ; ++it ; if(!ok) return false ; if(it ==lst.end()) return false ;
uint32_t s2 = (*it).toInt(&ok) ; ++it ; if(!ok) return false ; if(it ==lst.end()) return false ;
uint32_t s3 = (*it).toInt(&ok) ; ++it ; if(!ok) return false ; if(it ==lst.end()) return false ;
QStringList lst2 = (*it).split("/") ;
it = lst2.begin();
uint32_t s4 ;
s4 = (*it).toInt(&ok) ; ++it ; if(!ok) return false ;
if(it != lst2.end())
{
uint32_t x = (*it).toInt(&ok) ; if(!ok) return false ;
if(x%8 != 0)
return false ;
if(x != 16 && x != 24)
return false ;
bytes = 4 - x/8 ;
}
const sockaddr_in *in = (const sockaddr_in*)&addr ;
((uint8_t*)&in->sin_addr.s_addr)[0] = s1 ;
((uint8_t*)&in->sin_addr.s_addr)[1] = s2 ;
((uint8_t*)&in->sin_addr.s_addr)[2] = s3 ;
((uint8_t*)&in->sin_addr.s_addr)[3] = s4 ;
return ok;
}
void ServerPage::checkIpRange(const QString& ipstr)
{
QColor color;
struct sockaddr_storage addr;
int bytes ;
if(!parseAddrFromQString(ipstr,addr,bytes) || bytes != 0)
{
std::cout << "setting palette 1" << std::endl ;
color = QApplication::palette().color(QPalette::Disabled, QPalette::Base);
}
else
{
std::cout << "setting palette 2" << std::endl ;
color = QApplication::palette().color(QPalette::Active, QPalette::Base);
}
/* unpolish widget to clear the stylesheet's palette cache */
ui.ipInput_LE->style()->unpolish(ui.ipInput_LE);
QPalette palette = ui.ipInput_LE->palette();
palette.setColor(ui.ipInput_LE->backgroundRole(), color);
ui.ipInput_LE->setPalette(palette);
}
void ServerPage::addIpRange()
{
QString ipstr = ui.ipInput_LE->text() ;
sockaddr_storage addr ;
int bytes = 0 ;
if(!parseAddrFromQString(ipstr,addr,bytes) || bytes != 0)
return ;
bytes = 4 - ui.ipInputRange_SB->value()/8;
rsBanList->addIpRange(addr,bytes,ui.ipInputComment_LE->text().toStdString());
}
void ServerPage::clearKnownAddressList()
{
@ -315,10 +391,10 @@ void ServerPage::loadFilteredIps()
ui.filteredIpsTable->setEnabled(true) ;
ui.includeFromFriends_CB->setEnabled(true) ;
ui.includeFromDHT_CB->setEnabled(true) ;
ui.ipInput_LE->setEnabled(false) ;
ui.ipInputRange_SB->setEnabled(false) ;
ui.ipInputComment_LE->setEnabled(false) ;
ui.ipInputAdd_PB->setEnabled(false) ;
ui.ipInput_LE->setEnabled(true) ;
ui.ipInputRange_SB->setEnabled(true) ;
ui.ipInputComment_LE->setEnabled(true) ;
ui.ipInputAdd_PB->setEnabled(true) ;
ui.groupIPRanges_CB->setEnabled(true) ;
ui.groupIPRanges_SB->setEnabled(true) ;
}
@ -383,7 +459,7 @@ void ServerPage::loadFilteredIps()
case RSBANLIST_REASON_USER: ui.filteredIpsTable->setItem(row,COLUMN_REASON,new QTableWidgetItem(QString("Home-made rule"))) ;
break ;
case RSBANLIST_REASON_AUTO_RANGE: ui.filteredIpsTable->setItem(row,COLUMN_REASON,new QTableWidgetItem(QString("Auto-generated range"))) ;
ui.filteredIpsTable->item(row,COLUMN_REASON)->setToolTip(tr("Range made from %1 collected addresses").arg(QString::number((*it).connect_attempts))) ;
ui.filteredIpsTable->setItem(row,COLUMN_COMMENT,new QTableWidgetItem(tr("Range made from %1 collected addresses").arg(QString::number((*it).connect_attempts)))) ;
break ;
default:
case RSBANLIST_REASON_UNKNOWN: ui.filteredIpsTable->setItem(row,COLUMN_REASON,new QTableWidgetItem(QString("Unknown"))) ;
@ -394,44 +470,7 @@ void ServerPage::loadFilteredIps()
}
}
static bool parseAddrFromQString(const QString& s,struct sockaddr_storage& addr,int& bytes )
{
QStringList lst = s.split(".") ;
QStringList::const_iterator it = lst.begin();
bool ok ;
uint32_t s1 = (*it).toInt(&ok) ; ++it ; if(!ok) return false ;
uint32_t s2 = (*it).toInt(&ok) ; ++it ; if(!ok) return false ;
uint32_t s3 = (*it).toInt(&ok) ; ++it ; if(!ok) return false ;
QStringList lst2 = (*it).split("/") ;
it = lst2.begin();
uint32_t s4 ;
s4 = (*it).toInt(&ok) ; ++it ; if(!ok) return false ;
if(it != lst2.end())
{
uint32_t x = (*it).toInt(&ok) ; if(!ok) return false ;
if(x%8 != 0)
return false ;
if(x != 16 && x != 24)
return false ;
bytes = 4 - x/8 ;
}
const sockaddr_in *in = (const sockaddr_in*)&addr ;
((uint8_t*)&in->sin_addr.s_addr)[0] = s1 ;
((uint8_t*)&in->sin_addr.s_addr)[1] = s2 ;
((uint8_t*)&in->sin_addr.s_addr)[2] = s3 ;
((uint8_t*)&in->sin_addr.s_addr)[3] = s4 ;
return ok;
}
void ServerPage::toggleGroupIps(bool b) { rsBanList->enableAutoRange(b) ; }
void ServerPage::setGroupIpLimit(int n) { rsBanList->setAutoRangeLimit(n) ; }

View File

@ -50,6 +50,8 @@ public slots:
void updateStatus();
private slots:
void addIpRange();
void checkIpRange(const QString &);
void setGroupIpLimit(int n);
void toggleGroupIps(bool b);
void toggleAutoIncludeDHT(bool b);

View File

@ -17,7 +17,7 @@
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
<number>1</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
@ -626,13 +626,13 @@ behind a firewall or a VPN.</string>
<number>16</number>
</property>
<property name="maximum">
<number>32</number>
<number>24</number>
</property>
<property name="singleStep">
<number>8</number>
</property>
<property name="value">
<number>32</number>
<number>24</number>
</property>
</widget>
</item>

View File

@ -28,6 +28,7 @@
#include <QRgb>
#include <QSettings>
#include <stdint.h>
#include <gui/linetypes.h>
#include "rsettings.h"