📄 sockethandler.cpp.svn-base
字号:
}
m_trigger_src.erase(m_trigger_src.find(id));
m_trigger_dst.erase(m_trigger_dst.find(id));
again = true;
break;
}
}
} while (again);
#endif
delete p;
}
}
return n;
}
#ifdef ENABLE_RESOLVER
bool SocketHandler::Resolving(Socket *p0)
{
std::map<Socket *, bool>::iterator it = m_resolve_q.find(p0);
return it != m_resolve_q.end();
}
#endif
bool SocketHandler::Valid(Socket *p0)
{
for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end(); it++)
{
Socket *p = it -> second;
if (p0 == p)
return true;
}
return false;
}
bool SocketHandler::OkToAccept(Socket *)
{
return true;
}
size_t SocketHandler::GetCount()
{
/*
printf(" m_sockets : %d\n", m_sockets.size());
printf(" m_add : %d\n", m_add.size());
printf(" m_delete : %d\n", m_delete.size());
*/
return m_sockets.size() + m_add.size() + m_delete.size();
}
#ifdef ENABLE_SOCKS4
void SocketHandler::SetSocks4Host(ipaddr_t a)
{
m_socks4_host = a;
}
void SocketHandler::SetSocks4Host(const std::string& host)
{
Utility::u2ip(host, m_socks4_host);
}
void SocketHandler::SetSocks4Port(port_t port)
{
m_socks4_port = port;
}
void SocketHandler::SetSocks4Userid(const std::string& id)
{
m_socks4_userid = id;
}
#endif
#ifdef ENABLE_RESOLVER
int SocketHandler::Resolve(Socket *p,const std::string& host,port_t port)
{
// check cache
ResolvSocket *resolv = new ResolvSocket(*this, p, host, port);
resolv -> SetId(++m_resolv_id);
resolv -> SetDeleteByHandler();
ipaddr_t local;
Utility::u2ip("127.0.0.1", local);
if (!resolv -> Open(local, m_resolver_port))
{
LogError(resolv, "Resolve", -1, "Can't connect to local resolve server", LOG_LEVEL_FATAL);
}
Add(resolv);
m_resolve_q[p] = true;
DEB( fprintf(stderr, " *** Resolve '%s:%d' id#%d m_resolve_q size: %d p: %p\n", host.c_str(), port, resolv -> GetId(), m_resolve_q.size(), p);)
return resolv -> GetId();
}
#ifdef ENABLE_IPV6
int SocketHandler::Resolve6(Socket *p,const std::string& host,port_t port)
{
// check cache
ResolvSocket *resolv = new ResolvSocket(*this, p, host, port, true);
resolv -> SetId(++m_resolv_id);
resolv -> SetDeleteByHandler();
ipaddr_t local;
Utility::u2ip("127.0.0.1", local);
if (!resolv -> Open(local, m_resolver_port))
{
LogError(resolv, "Resolve", -1, "Can't connect to local resolve server", LOG_LEVEL_FATAL);
}
Add(resolv);
m_resolve_q[p] = true;
return resolv -> GetId();
}
#endif
int SocketHandler::Resolve(Socket *p,ipaddr_t a)
{
// check cache
ResolvSocket *resolv = new ResolvSocket(*this, p, a);
resolv -> SetId(++m_resolv_id);
resolv -> SetDeleteByHandler();
ipaddr_t local;
Utility::u2ip("127.0.0.1", local);
if (!resolv -> Open(local, m_resolver_port))
{
LogError(resolv, "Resolve", -1, "Can't connect to local resolve server", LOG_LEVEL_FATAL);
}
Add(resolv);
m_resolve_q[p] = true;
return resolv -> GetId();
}
#ifdef ENABLE_IPV6
int SocketHandler::Resolve(Socket *p,in6_addr& a)
{
// check cache
ResolvSocket *resolv = new ResolvSocket(*this, p, a);
resolv -> SetId(++m_resolv_id);
resolv -> SetDeleteByHandler();
ipaddr_t local;
Utility::u2ip("127.0.0.1", local);
if (!resolv -> Open(local, m_resolver_port))
{
LogError(resolv, "Resolve", -1, "Can't connect to local resolve server", LOG_LEVEL_FATAL);
}
Add(resolv);
m_resolve_q[p] = true;
return resolv -> GetId();
}
#endif
void SocketHandler::EnableResolver(port_t port)
{
if (!m_resolver)
{
m_resolver_port = port;
m_resolver = new ResolvServer(port);
}
}
bool SocketHandler::ResolverReady()
{
return m_resolver ? m_resolver -> Ready() : false;
}
#endif // ENABLE_RESOLVER
#ifdef ENABLE_SOCKS4
void SocketHandler::SetSocks4TryDirect(bool x)
{
m_bTryDirect = x;
}
ipaddr_t SocketHandler::GetSocks4Host()
{
return m_socks4_host;
}
port_t SocketHandler::GetSocks4Port()
{
return m_socks4_port;
}
const std::string& SocketHandler::GetSocks4Userid()
{
return m_socks4_userid;
}
bool SocketHandler::Socks4TryDirect()
{
return m_bTryDirect;
}
#endif
#ifdef ENABLE_RESOLVER
bool SocketHandler::ResolverEnabled()
{
return m_resolver ? true : false;
}
port_t SocketHandler::GetResolverPort()
{
return m_resolver_port;
}
#endif // ENABLE_RESOLVER
#ifdef ENABLE_POOL
ISocketHandler::PoolSocket *SocketHandler::FindConnection(int type,const std::string& protocol,SocketAddress& ad)
{
for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end() && !m_sockets.empty(); it++)
{
PoolSocket *pools = dynamic_cast<PoolSocket *>(it -> second);
if (pools)
{
if (pools -> GetSocketType() == type &&
pools -> GetSocketProtocol() == protocol &&
// %! pools -> GetClientRemoteAddress() &&
*pools -> GetClientRemoteAddress() == ad)
{
m_sockets.erase(it);
pools -> SetRetain(); // avoid Close in Socket destructor
return pools; // Caller is responsible that this socket is deleted
}
}
}
return NULL;
}
void SocketHandler::EnablePool(bool x)
{
m_b_enable_pool = x;
}
bool SocketHandler::PoolEnabled()
{
return m_b_enable_pool;
}
#endif
void SocketHandler::Remove(Socket *p)
{
#ifdef ENABLE_RESOLVER
std::map<Socket *, bool>::iterator it4 = m_resolve_q.find(p);
if (it4 != m_resolve_q.end())
m_resolve_q.erase(it4);
#endif
if (p -> ErasedByHandler())
{
return;
}
for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end(); it++)
{
if (it -> second == p)
{
LogError(p, "Remove", -1, "Socket destructor called while still in use", LOG_LEVEL_WARNING);
m_sockets.erase(it);
return;
}
}
for (socket_m::iterator it2 = m_add.begin(); it2 != m_add.end(); it2++)
{
if ((*it2).second == p)
{
LogError(p, "Remove", -2, "Socket destructor called while still in use", LOG_LEVEL_WARNING);
m_add.erase(it2);
return;
}
}
for (std::list<Socket *>::iterator it3 = m_delete.begin(); it3 != m_delete.end(); it3++)
{
if (*it3 == p)
{
LogError(p, "Remove", -3, "Socket destructor called while still in use", LOG_LEVEL_WARNING);
m_delete.erase(it3);
return;
}
}
}
void SocketHandler::CheckSanity()
{
CheckList(m_fds, "active sockets"); // active sockets
CheckList(m_fds_erase, "sockets to be erased"); // should always be empty anyway
CheckList(m_fds_callonconnect, "checklist CallOnConnect");
#ifdef ENABLE_DETACH
CheckList(m_fds_detach, "checklist Detach");
#endif
CheckList(m_fds_timeout, "checklist Timeout");
CheckList(m_fds_retry, "checklist retry client connect");
CheckList(m_fds_close, "checklist close and delete");
}
void SocketHandler::CheckList(socket_v& ref,const std::string& listname)
{
for (socket_v::iterator it = ref.begin(); it != ref.end(); it++)
{
SOCKET s = *it;
if (m_sockets.find(s) != m_sockets.end())
continue;
if (m_add.find(s) != m_add.end())
continue;
bool found = false;
for (std::list<Socket *>::iterator it = m_delete.begin(); it != m_delete.end(); it++)
{
Socket *p = *it;
if (p -> GetSocket() == s)
{
found = true;
break;
}
}
if (!found)
{
fprintf(stderr, "CheckList failed for \"%s\": fd %d\n", listname.c_str(), s);
}
}
}
void SocketHandler::AddList(SOCKET s,list_t which_one,bool add)
{
if (s == INVALID_SOCKET)
{
DEB( fprintf(stderr, "AddList: invalid_socket\n");)
return;
}
socket_v& ref =
(which_one == LIST_CALLONCONNECT) ? m_fds_callonconnect :
#ifdef ENABLE_DETACH
(which_one == LIST_DETACH) ? m_fds_detach :
#endif
(which_one == LIST_TIMEOUT) ? m_fds_timeout :
(which_one == LIST_RETRY) ? m_fds_retry :
(which_one == LIST_CLOSE) ? m_fds_close : m_fds_close;
if (add)
{
#ifdef ENABLE_DETACH
DEB( fprintf(stderr, "AddList; %5d: %s: %s\n", s, (which_one == LIST_CALLONCONNECT) ? "CallOnConnect" :
(which_one == LIST_DETACH) ? "Detach" :
(which_one == LIST_TIMEOUT) ? "Timeout" :
(which_one == LIST_RETRY) ? "Retry" :
(which_one == LIST_CLOSE) ? "Close" : "<undef>",
add ? "Add" : "Remove");)
#else
DEB( fprintf(stderr, "AddList; %5d: %s: %s\n", s, (which_one == LIST_CALLONCONNECT) ? "CallOnConnect" :
(which_one == LIST_TIMEOUT) ? "Timeout" :
(which_one == LIST_RETRY) ? "Retry" :
(which_one == LIST_CLOSE) ? "Close" : "<undef>",
add ? "Add" : "Remove");)
#endif
}
if (add)
{
for (socket_v::iterator it = ref.begin(); it != ref.end(); it++)
{
if (*it == s) // already there
{
return;
}
}
ref.push_back(s);
return;
}
// remove
for (socket_v::iterator it = ref.begin(); it != ref.end(); it++)
{
if (*it == s)
{
ref.erase(it);
break;
}
}
//DEB( fprintf(stderr, "/AddList\n");)
}
#ifdef ENABLE_TRIGGERS
int SocketHandler::TriggerID(Socket *src)
{
int id = m_next_trigger_id++;
m_trigger_src[id] = src;
return id;
}
bool SocketHandler::Subscribe(int id, Socket *dst)
{
if (m_trigger_src.find(id) != m_trigger_src.end())
{
std::map<Socket *, bool>::iterator it = m_trigger_dst[id].find(dst);
if (it != m_trigger_dst[id].end())
{
m_trigger_dst[id][dst] = true;
return true;
}
LogError(dst, "Subscribe", id, "Already subscribed", LOG_LEVEL_INFO);
return false;
}
LogError(dst, "Subscribe", id, "Trigger id not found", LOG_LEVEL_INFO);
return false;
}
bool SocketHandler::Unsubscribe(int id, Socket *dst)
{
if (m_trigger_src.find(id) != m_trigger_src.end())
{
std::map<Socket *, bool>::iterator it = m_trigger_dst[id].find(dst);
if (it != m_trigger_dst[id].end())
{
m_trigger_dst[id].erase(it);
return true;
}
LogError(dst, "Unsubscribe", id, "Not subscribed", LOG_LEVEL_INFO);
return false;
}
LogError(dst, "Unsubscribe", id, "Trigger id not found", LOG_LEVEL_INFO);
return false;
}
void SocketHandler::Trigger(int id, Socket::TriggerData& data, bool erase)
{
if (m_trigger_src.find(id) != m_trigger_src.end())
{
data.SetSource( m_trigger_src[id] );
for (std::map<Socket *, bool>::iterator it = m_trigger_dst[id].begin(); it != m_trigger_dst[id].end(); it++)
{
Socket *dst = it -> first;
if (Valid(dst))
{
dst -> OnTrigger(id, data);
}
}
if (erase)
{
m_trigger_src.erase(m_trigger_src.find(id));
m_trigger_dst.erase(m_trigger_dst.find(id));
}
}
else
{
LogError(NULL, "Trigger", id, "Trigger id not found", LOG_LEVEL_INFO);
}
}
#endif // ENABLE_TRIGGERS
#ifdef SOCKETS_NAMESPACE
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -