summaryrefslogtreecommitdiff
path: root/src/anytun.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/anytun.cpp')
-rw-r--r--src/anytun.cpp539
1 files changed, 284 insertions, 255 deletions
diff --git a/src/anytun.cpp b/src/anytun.cpp
index 7b03785..e3b3ce3 100644
--- a/src/anytun.cpp
+++ b/src/anytun.cpp
@@ -116,80 +116,88 @@ bool checkPacketSeqNr(EncryptedPacket& pack,ConnectionParam& conn)
void* sender(void* p)
{
- ThreadParam* param = reinterpret_cast<ThreadParam*>(p);
-
- std::auto_ptr<Cipher> c(CipherFactory::create(gOpt.getCipher()));
- std::auto_ptr<AuthAlgo> a(AuthAlgoFactory::create(gOpt.getAuthAlgo()) );
-
- PlainPacket plain_packet(MAX_PACKET_LENGTH);
- EncryptedPacket encrypted_packet(MAX_PACKET_LENGTH);
-
- Buffer session_key(u_int32_t(SESSION_KEYLEN_ENCR)); // TODO: hardcoded size
- Buffer session_salt(u_int32_t(SESSION_KEYLEN_SALT)); // TODO: hardcoded size
- Buffer session_auth_key(u_int32_t(SESSION_KEYLEN_AUTH)); // TODO: hardcoded size
+ try
+ {
+ ThreadParam* param = reinterpret_cast<ThreadParam*>(p);
- //TODO replace mux
- u_int16_t mux = gOpt.getMux();
- while(1)
+ std::auto_ptr<Cipher> c(CipherFactory::create(gOpt.getCipher()));
+ std::auto_ptr<AuthAlgo> a(AuthAlgoFactory::create(gOpt.getAuthAlgo()) );
+
+ PlainPacket plain_packet(MAX_PACKET_LENGTH);
+ EncryptedPacket encrypted_packet(MAX_PACKET_LENGTH);
+
+ Buffer session_key(u_int32_t(SESSION_KEYLEN_ENCR)); // TODO: hardcoded size
+ Buffer session_salt(u_int32_t(SESSION_KEYLEN_SALT)); // TODO: hardcoded size
+ Buffer session_auth_key(u_int32_t(SESSION_KEYLEN_AUTH)); // TODO: hardcoded size
+
+ //TODO replace mux
+ u_int16_t mux = gOpt.getMux();
+ while(1)
+ {
+ plain_packet.setLength(MAX_PACKET_LENGTH);
+ encrypted_packet.withAuthTag(false);
+ encrypted_packet.setLength(MAX_PACKET_LENGTH);
+
+ // read packet from device
+ u_int32_t len = param->dev.read(plain_packet.getPayload(), plain_packet.getPayloadLength());
+ plain_packet.setPayloadLength(len);
+ // set payload type
+ if(param->dev.getType() == TYPE_TUN)
+ plain_packet.setPayloadType(PAYLOAD_TYPE_TUN);
+ else if(param->dev.getType() == TYPE_TAP)
+ plain_packet.setPayloadType(PAYLOAD_TYPE_TAP);
+ else
+ plain_packet.setPayloadType(0);
+
+ if(param->cl.empty())
+ continue;
+ //std::cout << "got Packet for plain "<<plain_packet.getDstAddr().toString();
+ mux = gRoutingTable.getRoute(plain_packet.getDstAddr());
+ //std::cout << " -> "<<mux << std::endl;
+ ConnectionMap::iterator cit = param->cl.getConnection(mux);
+ if(cit==param->cl.getEnd())
+ continue;
+ ConnectionParam & conn = cit->second;
+
+ if(conn.remote_host_==""||!conn.remote_port_)
+ continue;
+ // generate packet-key TODO: do this only when needed
+ conn.kd_.generate(LABEL_SATP_ENCRYPTION, conn.seq_nr_, session_key);
+ conn.kd_.generate(LABEL_SATP_SALT, conn.seq_nr_, session_salt);
+
+ c->setKey(session_key);
+ c->setSalt(session_salt);
+
+ // encrypt packet
+ c->encrypt(plain_packet, encrypted_packet, conn.seq_nr_, gOpt.getSenderId(), mux);
+
+ encrypted_packet.setHeader(conn.seq_nr_, gOpt.getSenderId(), mux);
+ conn.seq_nr_++;
+
+ // add authentication tag
+ if(a->getMaxLength()) {
+ encrypted_packet.addAuthTag();
+ conn.kd_.generate(LABEL_SATP_MSG_AUTH, encrypted_packet.getSeqNr(), session_auth_key);
+ a->setKey(session_auth_key);
+ a->generate(encrypted_packet);
+ }
+ try
+ {
+ param->src.send(encrypted_packet.getBuf(), encrypted_packet.getLength(), conn.remote_host_, conn.remote_port_);
+ }
+ catch (std::exception e)
+ {
+ // ignoring icmp port unreachable :) and other socket errors :(
+ }
+ }
+ }
+ catch(std::exception e)
{
- plain_packet.setLength(MAX_PACKET_LENGTH);
- encrypted_packet.withAuthTag(false);
- encrypted_packet.setLength(MAX_PACKET_LENGTH);
-
- // read packet from device
- u_int32_t len = param->dev.read(plain_packet.getPayload(), plain_packet.getPayloadLength());
- plain_packet.setPayloadLength(len);
- // set payload type
- if(param->dev.getType() == TYPE_TUN)
- plain_packet.setPayloadType(PAYLOAD_TYPE_TUN);
- else if(param->dev.getType() == TYPE_TAP)
- plain_packet.setPayloadType(PAYLOAD_TYPE_TAP);
- else
- plain_packet.setPayloadType(0);
-
- if(param->cl.empty())
- continue;
- //std::cout << "got Packet for plain "<<plain_packet.getDstAddr().toString();
- mux = gRoutingTable.getRoute(plain_packet.getDstAddr());
- //std::cout << " -> "<<mux << std::endl;
- ConnectionMap::iterator cit = param->cl.getConnection(mux);
- if(cit==param->cl.getEnd())
- continue;
- ConnectionParam & conn = cit->second;
-
- if(conn.remote_host_==""||!conn.remote_port_)
- continue;
- // generate packet-key TODO: do this only when needed
- conn.kd_.generate(LABEL_SATP_ENCRYPTION, conn.seq_nr_, session_key);
- conn.kd_.generate(LABEL_SATP_SALT, conn.seq_nr_, session_salt);
-
- c->setKey(session_key);
- c->setSalt(session_salt);
-
- // encrypt packet
- c->encrypt(plain_packet, encrypted_packet, conn.seq_nr_, gOpt.getSenderId(), mux);
-
- encrypted_packet.setHeader(conn.seq_nr_, gOpt.getSenderId(), mux);
- conn.seq_nr_++;
-
- // add authentication tag
- if(a->getMaxLength()) {
- encrypted_packet.addAuthTag();
- conn.kd_.generate(LABEL_SATP_MSG_AUTH, encrypted_packet.getSeqNr(), session_auth_key);
- a->setKey(session_auth_key);
- a->generate(encrypted_packet);
- }
- try
- {
- param->src.send(encrypted_packet.getBuf(), encrypted_packet.getLength(), conn.remote_host_, conn.remote_port_);
- }
- catch (std::exception e)
- {
- }
+ cLog.msg(Log::PRIO_ERR) << "sender thread died due to an uncaught exception: " << e.what();
}
pthread_exit(NULL);
}
-
+
#ifndef ANYTUN_NOSYNC
void* syncConnector(void* p )
{
@@ -228,88 +236,96 @@ void* syncListener(void* p )
void* receiver(void* p)
{
- ThreadParam* param = reinterpret_cast<ThreadParam*>(p);
-
- std::auto_ptr<Cipher> c( CipherFactory::create(gOpt.getCipher()) );
- std::auto_ptr<AuthAlgo> a( AuthAlgoFactory::create(gOpt.getAuthAlgo()) );
-
- EncryptedPacket encrypted_packet(MAX_PACKET_LENGTH);
- PlainPacket plain_packet(MAX_PACKET_LENGTH);
-
- Buffer session_key(u_int32_t(SESSION_KEYLEN_ENCR)); // TODO: hardcoded size
- Buffer session_salt(u_int32_t(SESSION_KEYLEN_SALT)); // TODO: hardcoded size
- Buffer session_auth_key(u_int32_t(SESSION_KEYLEN_AUTH)); // TODO: hardcoded size
-
- while(1)
+ try
{
- string remote_host;
- u_int16_t remote_port;
-
- plain_packet.setLength(MAX_PACKET_LENGTH);
- encrypted_packet.withAuthTag(false);
- encrypted_packet.setLength(MAX_PACKET_LENGTH);
-
- // read packet from socket
- u_int32_t len = param->src.recv(encrypted_packet.getBuf(), encrypted_packet.getLength(), remote_host, remote_port);
- encrypted_packet.setLength(len);
+ ThreadParam* param = reinterpret_cast<ThreadParam*>(p);
- mux_t mux = encrypted_packet.getMux();
- // autodetect peer
- if(gOpt.getRemoteAddr() == "" && param->cl.empty())
- {
- cLog.msg(Log::PRIO_NOTICE) << "autodetected remote host " << remote_host << ":" << remote_port;
- createConnection(remote_host, remote_port, param->cl, gOpt.getSeqWindowSize(),param->queue,mux);
- }
-
- ConnectionMap::iterator cit = param->cl.getConnection(mux);
- if (cit == param->cl.getEnd())
- continue;
- ConnectionParam & conn = cit->second;
-
- // check whether auth tag is ok or not
- if(a->getMaxLength()) {
- encrypted_packet.withAuthTag(true);
- conn.kd_.generate(LABEL_SATP_MSG_AUTH, encrypted_packet.getSeqNr(), session_auth_key);
- a->setKey(session_auth_key);
- if(!a->checkTag(encrypted_packet)) {
- cLog.msg(Log::PRIO_NOTICE) << "wrong Authentication Tag!" << std::endl;
- continue;
- }
- encrypted_packet.removeAuthTag();
- }
-
- //Allow dynamic IP changes
- //TODO: add command line option to turn this off
- if (remote_host != conn.remote_host_ || remote_port != conn.remote_port_)
- {
- cLog.msg(Log::PRIO_NOTICE) << "connection "<< mux << " autodetected remote host ip changed " << remote_host << ":" << remote_port;
- conn.remote_host_=remote_host;
- conn.remote_port_=remote_port;
- SyncCommand sc (param->cl,mux);
- param->queue.push(sc);
- }
-
- // Replay Protection
- if (!checkPacketSeqNr(encrypted_packet, conn))
- continue;
+ std::auto_ptr<Cipher> c( CipherFactory::create(gOpt.getCipher()) );
+ std::auto_ptr<AuthAlgo> a( AuthAlgoFactory::create(gOpt.getAuthAlgo()) );
+
+ EncryptedPacket encrypted_packet(MAX_PACKET_LENGTH);
+ PlainPacket plain_packet(MAX_PACKET_LENGTH);
- // generate packet-key
- conn.kd_.generate(LABEL_SATP_ENCRYPTION, encrypted_packet.getSeqNr(), session_key);
- conn.kd_.generate(LABEL_SATP_SALT, encrypted_packet.getSeqNr(), session_salt);
- c->setKey(session_key);
- c->setSalt(session_salt);
-
- // decrypt packet
- c->decrypt(encrypted_packet, plain_packet);
+ Buffer session_key(u_int32_t(SESSION_KEYLEN_ENCR)); // TODO: hardcoded size
+ Buffer session_salt(u_int32_t(SESSION_KEYLEN_SALT)); // TODO: hardcoded size
+ Buffer session_auth_key(u_int32_t(SESSION_KEYLEN_AUTH)); // TODO: hardcoded size
- // check payload_type
- if((param->dev.getType() == TYPE_TUN && plain_packet.getPayloadType() != PAYLOAD_TYPE_TUN4 &&
- plain_packet.getPayloadType() != PAYLOAD_TYPE_TUN6) ||
- (param->dev.getType() == TYPE_TAP && plain_packet.getPayloadType() != PAYLOAD_TYPE_TAP))
- continue;
-
- // write it on the device
- param->dev.write(plain_packet.getPayload(), plain_packet.getLength());
+ while(1)
+ {
+ string remote_host;
+ u_int16_t remote_port;
+
+ plain_packet.setLength(MAX_PACKET_LENGTH);
+ encrypted_packet.withAuthTag(false);
+ encrypted_packet.setLength(MAX_PACKET_LENGTH);
+
+ // read packet from socket
+ u_int32_t len = param->src.recv(encrypted_packet.getBuf(), encrypted_packet.getLength(), remote_host, remote_port);
+ encrypted_packet.setLength(len);
+
+ mux_t mux = encrypted_packet.getMux();
+ // autodetect peer
+ if(gOpt.getRemoteAddr() == "" && param->cl.empty())
+ {
+ cLog.msg(Log::PRIO_NOTICE) << "autodetected remote host " << remote_host << ":" << remote_port;
+ createConnection(remote_host, remote_port, param->cl, gOpt.getSeqWindowSize(),param->queue,mux);
+ }
+
+ ConnectionMap::iterator cit = param->cl.getConnection(mux);
+ if (cit == param->cl.getEnd())
+ continue;
+ ConnectionParam & conn = cit->second;
+
+ // check whether auth tag is ok or not
+ if(a->getMaxLength()) {
+ encrypted_packet.withAuthTag(true);
+ conn.kd_.generate(LABEL_SATP_MSG_AUTH, encrypted_packet.getSeqNr(), session_auth_key);
+ a->setKey(session_auth_key);
+ if(!a->checkTag(encrypted_packet)) {
+ cLog.msg(Log::PRIO_NOTICE) << "wrong Authentication Tag!" << std::endl;
+ continue;
+ }
+ encrypted_packet.removeAuthTag();
+ }
+
+ //Allow dynamic IP changes
+ //TODO: add command line option to turn this off
+ if (remote_host != conn.remote_host_ || remote_port != conn.remote_port_)
+ {
+ cLog.msg(Log::PRIO_NOTICE) << "connection "<< mux << " autodetected remote host ip changed "
+ << remote_host << ":" << remote_port;
+ conn.remote_host_=remote_host;
+ conn.remote_port_=remote_port;
+ SyncCommand sc (param->cl,mux);
+ param->queue.push(sc);
+ }
+
+ // Replay Protection
+ if (!checkPacketSeqNr(encrypted_packet, conn))
+ continue;
+
+ // generate packet-key
+ conn.kd_.generate(LABEL_SATP_ENCRYPTION, encrypted_packet.getSeqNr(), session_key);
+ conn.kd_.generate(LABEL_SATP_SALT, encrypted_packet.getSeqNr(), session_salt);
+ c->setKey(session_key);
+ c->setSalt(session_salt);
+
+ // decrypt packet
+ c->decrypt(encrypted_packet, plain_packet);
+
+ // check payload_type
+ if((param->dev.getType() == TYPE_TUN && plain_packet.getPayloadType() != PAYLOAD_TYPE_TUN4 &&
+ plain_packet.getPayloadType() != PAYLOAD_TYPE_TUN6) ||
+ (param->dev.getType() == TYPE_TAP && plain_packet.getPayloadType() != PAYLOAD_TYPE_TAP))
+ continue;
+
+ // write it on the device
+ param->dev.write(plain_packet.getPayload(), plain_packet.getLength());
+ }
+ }
+ catch(std::exception e)
+ {
+ cLog.msg(Log::PRIO_ERR) << "receiver thread died due to an uncaught exception: " << e.what();
}
pthread_exit(NULL);
}
@@ -427,122 +443,135 @@ int execScript(string const& script, string const& ifname)
int main(int argc, char* argv[])
{
-// std::cout << "anytun - secure anycast tunneling protocol" << std::endl;
- if(!gOpt.parse(argc, argv)) {
- gOpt.printUsage();
- exit(-1);
- }
-
- cLog.msg(Log::PRIO_NOTICE) << "anytun started...";
+ bool daemonized=false;
+ try
+ {
- std::ofstream pidFile;
- if(gOpt.getPidFile() != "") {
- pidFile.open(gOpt.getPidFile().c_str());
- if(!pidFile.is_open()) {
- std::cout << "can't open pid file" << std::endl;
+// std::cout << "anytun - secure anycast tunneling protocol" << std::endl;
+ if(!gOpt.parse(argc, argv)) {
+ gOpt.printUsage();
+ exit(-1);
}
- }
-
- TunDevice dev(gOpt.getDevName() =="" ? NULL : gOpt.getDevName().c_str(),
- gOpt.getDevType() =="" ? NULL : gOpt.getDevType().c_str(),
- gOpt.getIfconfigParamLocal() =="" ? NULL : gOpt.getIfconfigParamLocal().c_str(),
- gOpt.getIfconfigParamRemoteNetmask() =="" ? NULL : gOpt.getIfconfigParamRemoteNetmask().c_str());
- cLog.msg(Log::PRIO_NOTICE) << "dev created (opened)";
- cLog.msg(Log::PRIO_NOTICE) << "dev opened - actual name is '" << dev.getActualName() << "'";
- cLog.msg(Log::PRIO_NOTICE) << "dev type is '" << dev.getTypeString() << "'";
- if(gOpt.getPostUpScript() != "") {
- int postup_ret = execScript(gOpt.getPostUpScript(), dev.getActualName());
- cLog.msg(Log::PRIO_NOTICE) << "post up script '" << gOpt.getPostUpScript() << "' returned " << postup_ret;
- }
-
-
-// Buffer buff(u_int32_t(1600));
-// int len;
-// while(1)
-// {
-// len = dev.read(buff.getBuf(), buff.getLength());
-// std::cout << "read " << len << " bytes form interface " << dev.getActualName() << std::endl;
-// dev.write(buff.getBuf(), len);
-// }
-
-// exit(0);
-
-
-
-
- if(gOpt.getChroot())
- chrootAndDrop(gOpt.getChrootDir(), gOpt.getUsername());
- if(gOpt.getDaemonize())
- daemonize();
-
- if(pidFile.is_open()) {
- pid_t pid = getpid();
- pidFile << pid;
- pidFile.close();
- }
-
- SignalController sig;
- sig.init();
-
- PacketSource* src;
- if(gOpt.getLocalAddr() == "")
- src = new UDPPacketSource(gOpt.getLocalPort());
- else
- src = new UDPPacketSource(gOpt.getLocalAddr(), gOpt.getLocalPort());
-
- ConnectionList cl;
- ConnectToList connect_to = gOpt.getConnectTo();
- SyncQueue queue;
-
- if(gOpt.getRemoteAddr() != "")
- createConnection(gOpt.getRemoteAddr(),gOpt.getRemotePort(),cl,gOpt.getSeqWindowSize(), queue, gOpt.getMux());
-
- ThreadParam p(dev, *src, cl, queue,*(new OptionConnectTo()));
- // this must be called before any other libgcrypt call
- if(!initLibGCrypt())
- return -1;
-
- pthread_t senderThread;
- pthread_create(&senderThread, NULL, sender, &p);
- pthread_t receiverThread;
- pthread_create(&receiverThread, NULL, receiver, &p);
+ cLog.msg(Log::PRIO_NOTICE) << "anytun started...";
+
+ std::ofstream pidFile;
+ if(gOpt.getPidFile() != "") {
+ pidFile.open(gOpt.getPidFile().c_str());
+ if(!pidFile.is_open()) {
+ std::cout << "can't open pid file" << std::endl;
+ }
+ }
+
+ TunDevice dev(gOpt.getDevName() =="" ? NULL : gOpt.getDevName().c_str(),
+ gOpt.getDevType() =="" ? NULL : gOpt.getDevType().c_str(),
+ gOpt.getIfconfigParamLocal() =="" ? NULL : gOpt.getIfconfigParamLocal().c_str(),
+ gOpt.getIfconfigParamRemoteNetmask() =="" ? NULL : gOpt.getIfconfigParamRemoteNetmask().c_str());
+ cLog.msg(Log::PRIO_NOTICE) << "dev created (opened)";
+ cLog.msg(Log::PRIO_NOTICE) << "dev opened - actual name is '" << dev.getActualName() << "'";
+ cLog.msg(Log::PRIO_NOTICE) << "dev type is '" << dev.getTypeString() << "'";
+ if(gOpt.getPostUpScript() != "") {
+ int postup_ret = execScript(gOpt.getPostUpScript(), dev.getActualName());
+ cLog.msg(Log::PRIO_NOTICE) << "post up script '" << gOpt.getPostUpScript() << "' returned " << postup_ret;
+ }
+
+
+// Buffer buff(u_int32_t(1600));
+// int len;
+// while(1)
+// {
+// len = dev.read(buff.getBuf(), buff.getLength());
+// std::cout << "read " << len << " bytes form interface " << dev.getActualName() << std::endl;
+// dev.write(buff.getBuf(), len);
+// }
+
+// return 0;
+
+
+
+ if(gOpt.getChroot())
+ chrootAndDrop(gOpt.getChrootDir(), gOpt.getUsername());
+ if(gOpt.getDaemonize())
+ daemonize();
+ daemonized = true;
+
+ if(pidFile.is_open()) {
+ pid_t pid = getpid();
+ pidFile << pid;
+ pidFile.close();
+ }
+
+ SignalController sig;
+ sig.init();
+
+ PacketSource* src;
+ if(gOpt.getLocalAddr() == "")
+ src = new UDPPacketSource(gOpt.getLocalPort());
+ else
+ src = new UDPPacketSource(gOpt.getLocalAddr(), gOpt.getLocalPort());
+
+ ConnectionList cl;
+ ConnectToList connect_to = gOpt.getConnectTo();
+ SyncQueue queue;
+
+ if(gOpt.getRemoteAddr() != "")
+ createConnection(gOpt.getRemoteAddr(),gOpt.getRemotePort(),cl,gOpt.getSeqWindowSize(), queue, gOpt.getMux());
+
+ ThreadParam p(dev, *src, cl, queue,*(new OptionConnectTo()));
+
+ // this must be called before any other libgcrypt call
+ if(!initLibGCrypt())
+ return -1;
+
+ pthread_t senderThread;
+ pthread_create(&senderThread, NULL, sender, &p);
+ pthread_t receiverThread;
+ pthread_create(&receiverThread, NULL, receiver, &p);
#ifndef ANYTUN_NOSYNC
- pthread_t syncListenerThread;
- if ( gOpt.getLocalSyncPort())
- pthread_create(&syncListenerThread, NULL, syncListener, &p);
-
- std::list<pthread_t> connectThreads;
- for(ConnectToList::iterator it = connect_to.begin() ;it != connect_to.end(); ++it) {
- connectThreads.push_back(pthread_t());
- ThreadParam * point = new ThreadParam(dev, *src, cl, queue,*it);
- pthread_create(& connectThreads.back(), NULL, syncConnector, point);
- }
+ pthread_t syncListenerThread;
+ if ( gOpt.getLocalSyncPort())
+ pthread_create(&syncListenerThread, NULL, syncListener, &p);
+
+ std::list<pthread_t> connectThreads;
+ for(ConnectToList::iterator it = connect_to.begin() ;it != connect_to.end(); ++it) {
+ connectThreads.push_back(pthread_t());
+ ThreadParam * point = new ThreadParam(dev, *src, cl, queue,*it);
+ pthread_create(& connectThreads.back(), NULL, syncConnector, point);
+ }
#endif
-
- int ret = sig.run();
-
- pthread_cancel(senderThread);
- pthread_cancel(receiverThread);
+
+ int ret = sig.run();
+
+ pthread_cancel(senderThread);
+ pthread_cancel(receiverThread);
#ifndef ANYTUN_NOSYNC
- if ( gOpt.getLocalSyncPort())
- pthread_cancel(syncListenerThread);
- for( std::list<pthread_t>::iterator it = connectThreads.begin() ;it != connectThreads.end(); ++it)
- pthread_cancel(*it);
+ if ( gOpt.getLocalSyncPort())
+ pthread_cancel(syncListenerThread);
+ for( std::list<pthread_t>::iterator it = connectThreads.begin() ;it != connectThreads.end(); ++it)
+ pthread_cancel(*it);
#endif
-
- pthread_join(senderThread, NULL);
- pthread_join(receiverThread, NULL);
+
+ pthread_join(senderThread, NULL);
+ pthread_join(receiverThread, NULL);
#ifndef ANYTUN_NOSYNC
- if ( gOpt.getLocalSyncPort())
- pthread_join(syncListenerThread, NULL);
-
- for( std::list<pthread_t>::iterator it = connectThreads.begin() ;it != connectThreads.end(); ++it)
- pthread_join(*it, NULL);
+ if ( gOpt.getLocalSyncPort())
+ pthread_join(syncListenerThread, NULL);
+
+ for( std::list<pthread_t>::iterator it = connectThreads.begin() ;it != connectThreads.end(); ++it)
+ pthread_join(*it, NULL);
#endif
- delete src;
- delete &p.connto;
+ delete src;
+ delete &p.connto;
- return ret;
+ return ret;
+ }
+ catch(std::exception e)
+ {
+ if(daemonized)
+ cLog.msg(Log::PRIO_ERR) << "uncaught exception, exiting: " << e.what();
+ else
+ std::cout << "uncaught exception, exiting: " << e.what() << std::endl;
+ }
}
-
+
+