cosmetics+prepare change to shared_ptr+import unix socket support

This commit is contained in:
Jean-Francois Dockes 2015-05-21 18:02:27 +02:00
parent 45f37cfffb
commit efa5882a79
3 changed files with 781 additions and 571 deletions

1
src/common/config.h Symbolic link
View File

@ -0,0 +1 @@
autoconfig.h

View File

@ -1,4 +1,19 @@
/* Copyright (C) 2002 Jean-Francois Dockes */ /* Copyright (C) 2002 J.F. Dockes
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Wrapper classes for the socket interface // Wrapper classes for the socket interface
@ -16,8 +31,8 @@
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <arpa/inet.h> #include <arpa/inet.h>
@ -25,17 +40,40 @@
#include <map> #include <map>
#ifndef NO_NAMESPACES
using namespace std; #ifdef RECOLL_DATADIR
#include "debuglog.h"
#else
#define LOGFATAL(X)
#define LOGERR(X)
#define LOGINFO(X)
#define LOGDEB(X)
#define LOGDEB0(X)
#define LOGDEB1(X)
#define LOGDEB2(X)
#define LOGDEB3(X)
#define LOGDEB4(X)
#endif #endif
#include "debuglog.h"
#include "netcon.h" #include "netcon.h"
using namespace std;
#ifndef SOCKLEN_T #ifndef SOCKLEN_T
#define SOCKLEN_T socklen_t #define SOCKLEN_T socklen_t
#endif #endif
// Size of path buffer in sockaddr_un (AF_UNIX socket
// addr). Mysteriously it's 108 (explicit value) under linux, no
// define accessible. Let's take a little margin as it appears that
// some systems use 92. I believe we could also malloc a variable size
// struct but why bother.
#ifndef UNIX_PATH_MAX
#define UNIX_PATH_MAX 90
#endif
// Need &one, &zero for setsockopt... // Need &one, &zero for setsockopt...
static const int one = 1; static const int one = 1;
static const int zero = 0; static const int zero = 0;
@ -88,8 +126,9 @@ void SelectLoop::setperiodichandler(int (*handler)(void *), void *p, int ms)
m_periodichandler = handler; m_periodichandler = handler;
m_periodicparam = p; m_periodicparam = p;
m_periodicmillis = ms; m_periodicmillis = ms;
if (m_periodicmillis > 0) if (m_periodicmillis > 0) {
gettimeofday(&m_lasthdlcall, 0); gettimeofday(&m_lasthdlcall, 0);
}
} }
// Compute the appropriate timeout so that the select call returns in // Compute the appropriate timeout so that the select call returns in
@ -111,8 +150,9 @@ void SelectLoop::periodictimeout(struct timeval *tv)
// millis <= 0 means we should have already done the thing. *dont* set the // millis <= 0 means we should have already done the thing. *dont* set the
// tv to 0, which means no timeout at all ! // tv to 0, which means no timeout at all !
if (millis <= 0) if (millis <= 0) {
millis = 1; millis = 1;
}
tv->tv_sec = millis / 1000; tv->tv_sec = millis / 1000;
tv->tv_usec = (millis % 1000) * 1000; tv->tv_usec = (millis % 1000) * 1000;
} }
@ -121,18 +161,20 @@ void SelectLoop::periodictimeout(struct timeval *tv)
// caller if it or we return 0 // caller if it or we return 0
int SelectLoop::maybecallperiodic() int SelectLoop::maybecallperiodic()
{ {
if (m_periodicmillis <= 0) if (m_periodicmillis <= 0) {
return 1; return 1;
}
struct timeval mtv; struct timeval mtv;
gettimeofday(&mtv, 0); gettimeofday(&mtv, 0);
int millis = m_periodicmillis - MILLIS(m_lasthdlcall, mtv); int millis = m_periodicmillis - MILLIS(m_lasthdlcall, mtv);
if (millis <= 0) { if (millis <= 0) {
gettimeofday(&m_lasthdlcall, 0); gettimeofday(&m_lasthdlcall, 0);
if (m_periodichandler) if (m_periodichandler) {
return m_periodichandler(m_periodicparam); return m_periodichandler(m_periodicparam);
else } else {
return 0; return 0;
} }
}
return 1; return 1;
} }
@ -194,12 +236,14 @@ int SelectLoop::doLoop()
return -1; return -1;
} }
if (m_periodicmillis > 0) if (m_periodicmillis > 0)
if (maybecallperiodic() <= 0) if (maybecallperiodic() <= 0) {
return 1; return 1;
}
// Timeout, do it again. // Timeout, do it again.
if (ret == 0) if (ret == 0) {
continue; continue;
}
// We don't start the fd sweep at 0, else some fds would be advantaged. // We don't start the fd sweep at 0, else some fds would be advantaged.
// Note that we do an fd sweep, not a map sweep. This is // Note that we do an fd sweep, not a map sweep. This is
@ -207,12 +251,14 @@ int SelectLoop::doLoop()
// map may change between 2 sweeps, so that we'd have to be smart // map may change between 2 sweeps, so that we'd have to be smart
// with the iterator. As the cost per unused fd is low (just 2 bit // with the iterator. As the cost per unused fd is low (just 2 bit
// flag tests), we keep it like this for now // flag tests), we keep it like this for now
if (m_placetostart >= nfds) if (m_placetostart >= nfds) {
m_placetostart = 0; m_placetostart = 0;
}
int i, fd; int i, fd;
for (i = 0, fd = m_placetostart; i < nfds;i++, fd++) { for (i = 0, fd = m_placetostart; i < nfds; i++, fd++) {
if (fd >= nfds) if (fd >= nfds) {
fd = 0; fd = 0;
}
int canread = FD_ISSET(fd, &rd); int canread = FD_ISSET(fd, &rd);
int canwrite = FD_ISSET(fd, &wd); int canwrite = FD_ISSET(fd, &wd);
@ -220,8 +266,9 @@ int SelectLoop::doLoop()
LOGDEB2(("Netcon::selectloop: fd %d %s %s %s\n", fd, LOGDEB2(("Netcon::selectloop: fd %d %s %s %s\n", fd,
none ? "blocked" : "can" , canread ? "read" : "", none ? "blocked" : "can" , canread ? "read" : "",
canwrite ? "write" : "")); canwrite ? "write" : ""));
if (none) if (none) {
continue; continue;
}
map<int,NetconP>::iterator it = m_polldata.find(fd); map<int,NetconP>::iterator it = m_polldata.find(fd);
if (it == m_polldata.end()) { if (it == m_polldata.end()) {
@ -233,10 +280,12 @@ int SelectLoop::doLoop()
// Next start will be one beyond last serviced (modulo nfds) // Next start will be one beyond last serviced (modulo nfds)
m_placetostart = fd + 1; m_placetostart = fd + 1;
NetconP &pll = it->second; NetconP &pll = it->second;
if (canread && pll->cando(Netcon::NETCONPOLL_READ) <= 0) if (canread && pll->cando(Netcon::NETCONPOLL_READ) <= 0) {
pll->m_wantedEvents &= ~Netcon::NETCONPOLL_READ; pll->m_wantedEvents &= ~Netcon::NETCONPOLL_READ;
if (canwrite && pll->cando(Netcon::NETCONPOLL_WRITE) <= 0) }
if (canwrite && pll->cando(Netcon::NETCONPOLL_WRITE) <= 0) {
pll->m_wantedEvents &= ~Netcon::NETCONPOLL_WRITE; pll->m_wantedEvents &= ~Netcon::NETCONPOLL_WRITE;
}
if (!(pll->m_wantedEvents & (Netcon::NETCONPOLL_WRITE|Netcon::NETCONPOLL_READ))) { if (!(pll->m_wantedEvents & (Netcon::NETCONPOLL_WRITE|Netcon::NETCONPOLL_READ))) {
LOGDEB0(("Netcon::selectloop: fd %d has 0x%x mask, erasing\n", LOGDEB0(("Netcon::selectloop: fd %d has 0x%x mask, erasing\n",
it->first, it->second->m_wantedEvents)); it->first, it->second->m_wantedEvents));
@ -252,7 +301,9 @@ int SelectLoop::doLoop()
// Add a connection to the monitored set. // Add a connection to the monitored set.
int SelectLoop::addselcon(NetconP con, int events) int SelectLoop::addselcon(NetconP con, int events)
{ {
if (con.isNull()) return -1; if (!con) {
return -1;
}
LOGDEB1(("Netcon::addselcon: fd %d\n", con->m_fd)); LOGDEB1(("Netcon::addselcon: fd %d\n", con->m_fd));
con->set_nonblock(1); con->set_nonblock(1);
con->setselevents(events); con->setselevents(events);
@ -264,7 +315,9 @@ int SelectLoop::addselcon(NetconP con, int events)
// Remove a connection from the monitored set. // Remove a connection from the monitored set.
int SelectLoop::remselcon(NetconP con) int SelectLoop::remselcon(NetconP con)
{ {
if (con.isNull()) return -1; if (!con) {
return -1;
}
LOGDEB1(("Netcon::remselcon: fd %d\n", con->m_fd)); LOGDEB1(("Netcon::remselcon: fd %d\n", con->m_fd));
map<int,NetconP>::iterator it = m_polldata.find(con->m_fd); map<int,NetconP>::iterator it = m_polldata.find(con->m_fd);
if (it == m_polldata.end()) { if (it == m_polldata.end()) {
@ -278,7 +331,8 @@ int SelectLoop::remselcon(NetconP con)
////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////
// Base class (Netcon) methods // Base class (Netcon) methods
Netcon::~Netcon() { Netcon::~Netcon()
{
closeconn(); closeconn();
if (m_peer) { if (m_peer) {
free(m_peer); free(m_peer);
@ -302,8 +356,9 @@ char *Netcon::sterror()
void Netcon::setpeer(const char *hostname) void Netcon::setpeer(const char *hostname)
{ {
if (m_peer) if (m_peer) {
free(m_peer); free(m_peer);
}
m_peer = strdup(hostname); m_peer = strdup(hostname);
} }
@ -329,16 +384,18 @@ int Netcon::set_nonblock(int onoff)
if (flags != -1 ) { if (flags != -1 ) {
int newflags = onoff ? flags | O_NONBLOCK : flags & ~O_NONBLOCK; int newflags = onoff ? flags | O_NONBLOCK : flags & ~O_NONBLOCK;
if (newflags != flags) if (newflags != flags)
if (fcntl(m_fd, F_SETFL, newflags)< 0) if (fcntl(m_fd, F_SETFL, newflags) < 0) {
return -1; return -1;
} }
}
return flags; return flags;
} }
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
// Data socket (NetconData) methods // Data socket (NetconData) methods
NetconData::~NetconData() { NetconData::~NetconData()
{
freeZ(m_buf); freeZ(m_buf);
m_bufbase = 0; m_bufbase = 0;
m_bufbytes = m_bufsize = 0; m_bufbytes = m_bufsize = 0;
@ -359,14 +416,16 @@ int NetconData::send(const char *buf, int cnt, int expedited)
int ret; int ret;
// There is a bug in the uthread version of sendto() in FreeBSD at // There is a bug in the uthread version of sendto() in FreeBSD at
// least up to 2.2.7, so avoid using it when possible // least up to 2.2.7, so avoid using it when possible
if (flag) if (flag) {
ret = ::send(m_fd, buf, cnt, flag); ret = ::send(m_fd, buf, cnt, flag);
else } else {
ret = ::write(m_fd, buf, cnt); ret = ::write(m_fd, buf, cnt);
}
// Note: byte count may be different from cnt if fd is non-blocking // Note: byte count may be different from cnt if fd is non-blocking
if (ret < 0) { if (ret < 0) {
char fdcbuf[20];sprintf(fdcbuf, "%d", m_fd); char fdcbuf[20];
sprintf(fdcbuf, "%d", m_fd);
LOGSYSERR("NetconData::send", "send", fdcbuf); LOGSYSERR("NetconData::send", "send", fdcbuf);
} }
return ret; return ret;
@ -413,9 +472,10 @@ int NetconData::receive(char *buf, int cnt, int timeo)
m_bufbase += fromibuf; m_bufbase += fromibuf;
cnt -= fromibuf; cnt -= fromibuf;
LOGDEB2(("NetconData::receive: transferred %d from mbuf\n", fromibuf)); LOGDEB2(("NetconData::receive: transferred %d from mbuf\n", fromibuf));
if (cnt <= 0) if (cnt <= 0) {
return fromibuf; return fromibuf;
} }
}
if (timeo > 0) { if (timeo > 0) {
int ret = select1(m_fd, timeo); int ret = select1(m_fd, timeo);
if (ret == 0) { if (ret == 0) {
@ -430,7 +490,8 @@ int NetconData::receive(char *buf, int cnt, int timeo)
} }
m_didtimo = 0; m_didtimo = 0;
if ((cnt = read(m_fd, buf + fromibuf, cnt)) < 0) { if ((cnt = read(m_fd, buf + fromibuf, cnt)) < 0) {
char fdcbuf[20];sprintf(fdcbuf, "%d", m_fd); char fdcbuf[20];
sprintf(fdcbuf, "%d", m_fd);
LOGSYSERR("NetconData::receive", "read", fdcbuf); LOGSYSERR("NetconData::receive", "read", fdcbuf);
return -1; return -1;
} }
@ -494,9 +555,10 @@ int NetconData::getline(char *buf, int cnt, int timeo)
// each byte copied (even newline), and not become -1 if // each byte copied (even newline), and not become -1 if
// we go to the end. Better ways welcome! // we go to the end. Better ways welcome!
nn--; nn--;
if ((*cp++ = *m_bufbase++) == '\n') if ((*cp++ = *m_bufbase++) == '\n') {
break; break;
} }
}
// Update counts // Update counts
maxtransf -= nn; // Actual count transferred maxtransf -= nn; // Actual count transferred
m_bufbytes -= maxtransf; m_bufbytes -= maxtransf;
@ -533,7 +595,7 @@ int NetconData::getline(char *buf, int cnt, int timeo)
int NetconData::cando(Netcon::Event reason) int NetconData::cando(Netcon::Event reason)
{ {
LOGDEB2(("NetconData::cando\n")); LOGDEB2(("NetconData::cando\n"));
if (!m_user.isNull()) { if (m_user) {
return m_user->data(this, reason); return m_user->data(this, reason);
} }
@ -564,46 +626,74 @@ int NetconCli::openconn(const char *host, unsigned int port, int timeo)
closeconn(); closeconn();
struct sockaddr_in saddr; struct sockaddr *saddr;
memset(&saddr, 0, sizeof(saddr)); socklen_t addrsize;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(port); struct sockaddr_in ip_addr;
struct sockaddr_un unix_addr;
if (host[0] != '/') {
memset(&ip_addr, 0, sizeof(ip_addr));
ip_addr.sin_family = AF_INET;
ip_addr.sin_port = htons(port);
// Server name may be host name or IP address // Server name may be host name or IP address
int addr; int addr;
if ((addr = inet_addr(host)) != -1) { if ((addr = inet_addr(host)) != -1) {
memcpy(&saddr.sin_addr, &addr, sizeof(addr)); memcpy(&ip_addr.sin_addr, &addr, sizeof(addr));
} else { } else {
struct hostent *hp; struct hostent *hp;
if ((hp = gethostbyname(host)) == 0) { if ((hp = gethostbyname(host)) == 0) {
LOGERR(("NetconCli::openconn: gethostbyname(%s) failed\n", host)); LOGERR(("NetconCli::openconn: gethostbyname(%s) failed\n",
host));
return -1; return -1;
} }
memcpy(&saddr.sin_addr, hp->h_addr, hp->h_length); memcpy(&ip_addr.sin_addr, hp->h_addr, hp->h_length);
} }
if ((m_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { if ((m_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
LOGSYSERR("NetconCli::openconn", "socket", ""); LOGSYSERR("NetconCli::openconn", "socket", "");
return -1; return -1;
} }
if (timeo > 0) addrsize = sizeof(ip_addr);
set_nonblock(1); saddr = (sockaddr*)&ip_addr;
} else {
memset(&unix_addr, 0, sizeof(unix_addr));
unix_addr.sun_family = AF_UNIX;
if (strlen(host) > UNIX_PATH_MAX - 1) {
LOGERR(("NetconCli::openconn: name too long: %s\n", host));
return -1;
}
strcpy(unix_addr.sun_path, host);
if(connect(m_fd,(struct sockaddr *) &saddr, sizeof(saddr)) < 0) { if ((m_fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
LOGSYSERR("NetconCli::openconn", "socket", "");
return -1;
}
addrsize = sizeof(unix_addr);
saddr = (sockaddr*)&unix_addr;
}
if (timeo > 0) { if (timeo > 0) {
if (errno != EINPROGRESS) set_nonblock(1);
}
if (connect(m_fd, saddr, addrsize) < 0) {
if (timeo > 0) {
if (errno != EINPROGRESS) {
goto out; goto out;
if (select1(m_fd, timeo, 1) == 1) }
if (select1(m_fd, timeo, 1) == 1) {
goto connectok; goto connectok;
} }
}
if (m_silentconnectfailure == 0) { if (m_silentconnectfailure == 0) {
LOGSYSERR("NetconCli", "connect", ""); LOGSYSERR("NetconCli", "connect", "");
} }
goto out; goto out;
} }
connectok: connectok:
if (timeo > 0) if (timeo > 0) {
set_nonblock(0); set_nonblock(0);
}
LOGDEB2(("NetconCli::connect: setting keepalive\n")); LOGDEB2(("NetconCli::connect: setting keepalive\n"));
if (setsockopt(m_fd, SOL_SOCKET, SO_KEEPALIVE, if (setsockopt(m_fd, SOL_SOCKET, SO_KEEPALIVE,
@ -613,24 +703,29 @@ int NetconCli::openconn(const char *host, unsigned int port, int timeo)
setpeer(host); setpeer(host);
LOGDEB2(("NetconCli::openconn: connection opened ok\n")); LOGDEB2(("NetconCli::openconn: connection opened ok\n"));
ret = 0; ret = 0;
out: out:
if (ret < 0) if (ret < 0) {
closeconn(); closeconn();
}
return ret; return ret;
} }
// Same as previous, but get the port number from services // Same as previous, but get the port number from services
int NetconCli::openconn(const char *host, char *serv, int timeo) int NetconCli::openconn(const char *host, const char *serv, int timeo)
{ {
LOGDEB2(("Netconcli::openconn: host %s, serv %s\n", host, serv)); LOGDEB2(("Netconcli::openconn: host %s, serv %s\n", host, serv));
if (host[0] != '/') {
struct servent *sp; struct servent *sp;
if ((sp = getservbyname(serv, "tcp")) == 0) { if ((sp = getservbyname(serv, "tcp")) == 0) {
LOGERR(("NetconCli::openconn: getservbyname failed for %s\n", serv)); LOGERR(("NetconCli::openconn: getservbyname failed for %s\n",serv));
return -1; return -1;
} }
// Callee expects the port number in host byte order // Callee expects the port number in host byte order
return openconn(host, ntohs(sp->s_port), timeo); return openconn(host, ntohs(sp->s_port), timeo);
} else {
return openconn(host, (unsigned int)0, timeo);
}
} }
@ -649,7 +744,8 @@ int NetconCli::setconn(int fd)
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
// Methods for the main (listening) server connection // Methods for the main (listening) server connection
NetconServLis::~NetconServLis() { NetconServLis::~NetconServLis()
{
#ifdef NETCON_ACCESSCONTROL #ifdef NETCON_ACCESSCONTROL
freeZ(okaddrs.intarray); freeZ(okaddrs.intarray);
freeZ(okmasks.intarray); freeZ(okmasks.intarray);
@ -658,56 +754,59 @@ NetconServLis::~NetconServLis() {
#if 0 #if 0
// code for dumping a struct servent // code for dumping a struct servent
static void dump_servent(struct servent *servp) { static void dump_servent(struct servent *servp)
{
fprintf(stderr, "Official name %s\n", servp->s_name); fprintf(stderr, "Official name %s\n", servp->s_name);
for (char **cpp = servp->s_aliases;*cpp;cpp++) for (char **cpp = servp->s_aliases; *cpp; cpp++) {
fprintf(stderr, "Nickname %s\n", *cpp); fprintf(stderr, "Nickname %s\n", *cpp);
}
fprintf(stderr, "Port %d\n", (int)ntohs((short)servp->s_port)); fprintf(stderr, "Port %d\n", (int)ntohs((short)servp->s_port));
fprintf(stderr, "Proto %s\n", servp->s_proto); fprintf(stderr, "Proto %s\n", servp->s_proto);
} }
#endif #endif
// Set up service. // Set up service.
int NetconServLis::openservice(char *serv, int backlog) int NetconServLis::openservice(const char *serv, int backlog)
{ {
int port; int port;
struct servent *servp; struct servent *servp;
if (!serv) {
LOGERR(("NetconServLis::openservice: null serv??\n"));
return -1;
}
LOGDEB1(("NetconServLis::openservice: serv %s\n", serv)); LOGDEB1(("NetconServLis::openservice: serv %s\n", serv));
#ifdef NETCON_ACCESSCONTROL #ifdef NETCON_ACCESSCONTROL
if (initperms(serv) < 0) if (initperms(serv) < 0) {
return -1; return -1;
}
#endif #endif
m_serv = serv;
if (serv[0] != '/') {
if ((servp = getservbyname(serv, "tcp")) == 0) { if ((servp = getservbyname(serv, "tcp")) == 0) {
LOGERR(("NetconServLis::openservice: getservbyname failed for %s\n",serv)); LOGERR(("NetconServLis::openservice: getservbyname failed for %s\n",
serv));
return -1; return -1;
} }
port = (int)ntohs((short)servp->s_port); port = (int)ntohs((short)servp->s_port);
return openservice(port, backlog); return openservice(port, backlog);
} } else {
if (strlen(serv) > UNIX_PATH_MAX - 1) {
// Port is a natural host integer value LOGERR(("NetconServLis::openservice: too long for AF_UNIX: %s\n",
int NetconServLis::openservice(int port, int backlog) serv));
{
LOGDEB1(("NetconServLis::openservice: port %d\n", port));
#ifdef NETCON_ACCESSCONTROL
if (initperms(port) < 0)
return -1; return -1;
#endif }
int ret = -1; int ret = -1;
struct sockaddr_in ipaddr; struct sockaddr_un addr;
if ((m_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { if ((m_fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
LOGSYSERR("NetconServLis", "socket", ""); LOGSYSERR("NetconServLis", "socket", "");
return -1; return -1;
} }
(void) setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR,(char *)&one, sizeof(one)); memset(&addr, 0, sizeof(addr));
#ifdef SO_REUSEPORT addr.sun_family = AF_UNIX;
(void) setsockopt(m_fd, SOL_SOCKET, SO_REUSEPORT,(char *)&one, sizeof(one)); strcpy(addr.sun_path, serv);
#endif /*SO_REUSEPORT*/
memset(&ipaddr, 0, sizeof(ipaddr)); if (::bind(m_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
ipaddr.sin_family = AF_INET;
ipaddr.sin_addr.s_addr = htonl(INADDR_ANY);
ipaddr.sin_port = htons((short)port);
if (bind(m_fd, (struct sockaddr *)&ipaddr, sizeof(ipaddr)) < 0){
LOGSYSERR("NetconServLis", "bind", ""); LOGSYSERR("NetconServLis", "bind", "");
goto out; goto out;
} }
@ -724,13 +823,57 @@ int NetconServLis::openservice(int port, int backlog)
m_fd = -1; m_fd = -1;
} }
return ret; return ret;
}
}
// Port is a natural host integer value
int NetconServLis::openservice(int port, int backlog)
{
LOGDEB1(("NetconServLis::openservice: port %d\n", port));
#ifdef NETCON_ACCESSCONTROL
if (initperms(port) < 0) {
return -1;
}
#endif
int ret = -1;
struct sockaddr_in ipaddr;
if ((m_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
LOGSYSERR("NetconServLis", "socket", "");
return -1;
}
(void) setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR,(char *)&one, sizeof(one));
#ifdef SO_REUSEPORT
(void) setsockopt(m_fd, SOL_SOCKET, SO_REUSEPORT,(char *)&one, sizeof(one));
#endif /*SO_REUSEPORT*/
memset(&ipaddr, 0, sizeof(ipaddr));
ipaddr.sin_family = AF_INET;
ipaddr.sin_addr.s_addr = htonl(INADDR_ANY);
ipaddr.sin_port = htons((short)port);
if (::bind(m_fd, (struct sockaddr *)&ipaddr, sizeof(ipaddr)) < 0) {
LOGSYSERR("NetconServLis", "bind", "");
goto out;
}
if (listen(m_fd, backlog) < 0) {
LOGSYSERR("NetconServLis", "listen", "");
goto out;
}
LOGDEB1(("NetconServLis::openservice: service opened ok\n"));
ret = 0;
out:
if (ret < 0 && m_fd >= 0) {
close(m_fd);
m_fd = -1;
}
return ret;
} }
#ifdef NETCON_ACCESSCONTROL #ifdef NETCON_ACCESSCONTROL
int NetconServLis::initperms(int port) int NetconServLis::initperms(int port)
{ {
if (permsinit) if (permsinit) {
return 0; return 0;
}
char sport[30]; char sport[30];
sprintf(sport, "%d", port); sprintf(sport, "%d", port);
@ -738,10 +881,11 @@ int NetconServLis::initperms(int port)
} }
// Get authorized address lists from parameter file. This is disabled for now // Get authorized address lists from parameter file. This is disabled for now
int NetconServLis::initperms(char *serv) int NetconServLis::initperms(const char *serv)
{ {
if (permsinit) if (permsinit) {
return 0; return 0;
}
if (serv == 0 || *serv == 0 || strlen(serv) > 80) { if (serv == 0 || *serv == 0 || strlen(serv) > 80) {
LOGERR(("NetconServLis::initperms: bad service name %s\n", serv)); LOGERR(("NetconServLis::initperms: bad service name %s\n", serv));
@ -805,6 +949,8 @@ NetconServLis::accept(int timeo)
NetconServCon *con = 0; NetconServCon *con = 0;
int newfd = -1; int newfd = -1;
struct sockaddr_in who; struct sockaddr_in who;
struct sockaddr_un uwho;
if (m_serv.empty() || m_serv[0] != '/') {
SOCKLEN_T clilen = (SOCKLEN_T)sizeof(who); SOCKLEN_T clilen = (SOCKLEN_T)sizeof(who);
if ((newfd = ::accept(m_fd, (struct sockaddr *)&who, &clilen)) < 0) { if ((newfd = ::accept(m_fd, (struct sockaddr *)&who, &clilen)) < 0) {
LOGSYSERR("NetconServCon::accept", "accept", ""); LOGSYSERR("NetconServCon::accept", "accept", "");
@ -815,21 +961,35 @@ NetconServLis::accept(int timeo)
goto out; goto out;
} }
#endif #endif
} else {
SOCKLEN_T clilen = (SOCKLEN_T)sizeof(uwho);
if ((newfd = ::accept(m_fd, (struct sockaddr *)&uwho, &clilen)) < 0) {
LOGSYSERR("NetconServCon::accept", "accept", "");
goto out;
}
}
con = new NetconServCon(newfd); con = new NetconServCon(newfd);
if (con == 0) { if (con == 0) {
LOGERR(("NetconServLis::accept: new NetconServCon failed\n")); LOGERR(("NetconServLis::accept: new NetconServCon failed\n"));
goto out; goto out;
} }
// Retrieve peer's host name. Errors are non fatal // Retrieve peer's host name. Errors are non fatal
if (m_serv.empty() || m_serv[0] != '/') {
struct hostent *hp; struct hostent *hp;
if ((hp = gethostbyaddr((char *)&(who.sin_addr), sizeof(struct in_addr), if ((hp = gethostbyaddr((char *) & (who.sin_addr),
AF_INET)) == 0) { sizeof(struct in_addr), AF_INET)) == 0) {
LOGERR(("NetconServLis::accept: gethostbyaddr failed for addr 0x%lx\n", LOGERR(("NetconServLis::accept: gethostbyaddr failed for addr 0x%lx\n",
who.sin_addr.s_addr)); who.sin_addr.s_addr));
con->setpeer(inet_ntoa(who.sin_addr)); con->setpeer(inet_ntoa(who.sin_addr));
} else { } else {
con->setpeer(hp->h_name); con->setpeer(hp->h_name);
} }
} else {
con->setpeer(m_serv.c_str());
}
LOGDEB2(("NetconServLis::accept: setting keepalive\n")); LOGDEB2(("NetconServLis::accept: setting keepalive\n"));
if (setsockopt(newfd, SOL_SOCKET, SO_KEEPALIVE, if (setsockopt(newfd, SOL_SOCKET, SO_KEEPALIVE,
(char *)&one, sizeof(one)) < 0) { (char *)&one, sizeof(one)) < 0) {
@ -837,9 +997,10 @@ NetconServLis::accept(int timeo)
} }
LOGDEB2(("NetconServLis::accept: got connect from %s\n", con->getpeer())); LOGDEB2(("NetconServLis::accept: got connect from %s\n", con->getpeer()));
out: out:
if (con == 0 && newfd >= 0) if (con == 0 && newfd >= 0) {
close(newfd); close(newfd);
}
return con; return con;
} }
@ -848,8 +1009,9 @@ int
NetconServLis::checkperms(void *cl, int) NetconServLis::checkperms(void *cl, int)
{ {
// If okmasks and addrs were not initialized, the default is allow to all // If okmasks and addrs were not initialized, the default is allow to all
if (okmasks.len <= 0 || okaddrs.len <= 0) if (okmasks.len <= 0 || okaddrs.len <= 0) {
return 0; return 0;
}
struct sockaddr *addr = (struct sockaddr *)cl; struct sockaddr *addr = (struct sockaddr *)cl;
unsigned long ip_addr; unsigned long ip_addr;
@ -863,15 +1025,17 @@ NetconServLis::checkperms(void *cl, int)
LOGDEB2(("checkperms: ip_addr: 0x%x\n", ip_addr)); LOGDEB2(("checkperms: ip_addr: 0x%x\n", ip_addr));
for (int i = 0; i < okaddrs.len; i++) { for (int i = 0; i < okaddrs.len; i++) {
unsigned int mask; unsigned int mask;
if (i < okmasks.len) if (i < okmasks.len) {
mask = okmasks.intarray[i]; mask = okmasks.intarray[i];
else } else {
mask = okmasks.intarray[okmasks.len-1]; mask = okmasks.intarray[okmasks.len-1];
}
LOGDEB2(("checkperms: trying okaddr 0x%x, mask 0x%x\n", LOGDEB2(("checkperms: trying okaddr 0x%x, mask 0x%x\n",
okaddrs.intarray[i], mask)); okaddrs.intarray[i], mask));
if ((ip_addr & mask) == (okaddrs.intarray[i] & mask)) if ((ip_addr & mask) == (okaddrs.intarray[i] & mask)) {
return (0); return (0);
} }
}
LOGERR(("NetconServLis::checkperm: connection from bad address 0x%x\n", LOGERR(("NetconServLis::checkperm: connection from bad address 0x%x\n",
ip_addr)); ip_addr));
return -1; return -1;
@ -893,6 +1057,8 @@ NetconServLis::checkperms(void *cl, int)
#include "debuglog.h" #include "debuglog.h"
#include "netcon.h" #include "netcon.h"
using namespace std;
static char *thisprog; static char *thisprog;
static char usage[] = static char usage[] =
"-c <host> <service>: Connects to trnetcon server, exchange message, then\n" "-c <host> <service>: Connects to trnetcon server, exchange message, then\n"
@ -923,13 +1089,16 @@ int main(int argc, char **argv)
char *host, *serv; char *host, *serv;
thisprog = argv[0]; thisprog = argv[0];
argc--; argv++; argc--;
argv++;
while (argc > 0 && **argv == '-') { while (argc > 0 && **argv == '-') {
(*argv)++; (*argv)++;
if (!(**argv)) if (!(**argv))
/* Cas du "adb - core" */ /* Cas du "adb - core" */
{
Usage(); Usage();
}
while (**argv) while (**argv)
switch (*(*argv)++) { switch (*(*argv)++) {
case 's': case 's':
@ -955,14 +1124,17 @@ int main(int argc, char **argv)
if (argc != 2) { if (argc != 2) {
Usage(); Usage();
} }
host = *argv++;argc--; host = *argv++;
serv = *argv++;argc--; argc--;
serv = *argv++;
argc--;
exit(trycli(host, serv)); exit(trycli(host, serv));
} else if (op_flags & OPT_s) { } else if (op_flags & OPT_s) {
if (argc != 1) { if (argc != 1) {
Usage(); Usage();
} }
serv = *argv++;argc--; serv = *argv++;
argc--;
exit(tryserv(serv)); exit(tryserv(serv));
} else { } else {
Usage(); Usage();
@ -977,8 +1149,7 @@ static char fromcli[200];
class CliNetconWorker : public NetconWorker { class CliNetconWorker : public NetconWorker {
public: public:
CliNetconWorker() : m_count(0) {} CliNetconWorker() : m_count(0) {}
int data(NetconData *con, Netcon::Event reason) int data(NetconData *con, Netcon::Event reason) {
{
LOGDEB(("clientdata\n")); LOGDEB(("clientdata\n"));
if (reason & Netcon::NETCONPOLL_WRITE) { if (reason & Netcon::NETCONPOLL_WRITE) {
sprintf(fromcli, "Bonjour Bonjour client %d, count %d", sprintf(fromcli, "Bonjour Bonjour client %d, count %d",
@ -1012,9 +1183,10 @@ public:
} }
if (m_count >= 10) { if (m_count >= 10) {
fprintf(stderr, "Did 10, enough\n"); fprintf(stderr, "Did 10, enough\n");
if (con->getloop()) if (con->getloop()) {
con->getloop()->loopReturn(0); con->getloop()->loopReturn(0);
} }
}
return 0; return 0;
} }
private: private:
@ -1027,17 +1199,20 @@ int trycli(char *host, char *serv)
NetconCli *clicon = new NetconCli(); NetconCli *clicon = new NetconCli();
NetconP con(clicon); NetconP con(clicon);
if (con.isNull()) { if (!con) {
fprintf(stderr, "new NetconCli failed\n"); fprintf(stderr, "new NetconCli failed\n");
return 1; return 1;
} }
if (clicon->openconn(host, serv) < 0) { int port = atoi(serv);
int ret = port > 0 ?
clicon->openconn(host, port) : clicon->openconn(host, serv);
if (ret < 0) {
fprintf(stderr, "openconn(%s, %s) failed\n", host, serv); fprintf(stderr, "openconn(%s, %s) failed\n", host, serv);
return 1; return 1;
} }
fprintf(stderr, "openconn(%s, %s) ok\n", host, serv); fprintf(stderr, "openconn(%s, %s) ok\n", host, serv);
#ifdef NOSELLOOP #ifdef NOSELLOOP
for (int i = 0;i < nloop;i++) { for (int i = 0; i < nloop; i++) {
if (con->send(fromcli, strlen(fromcli) + 1) < 0) { if (con->send(fromcli, strlen(fromcli) + 1) < 0) {
fprintf(stderr, "%d: Send failed\n", getpid()); fprintf(stderr, "%d: Send failed\n", getpid());
return 1; return 1;
@ -1061,7 +1236,7 @@ int trycli(char *host, char *serv)
SelectLoop myloop; SelectLoop myloop;
myloop.addselcon(con, Netcon::NETCONPOLL_WRITE); myloop.addselcon(con, Netcon::NETCONPOLL_WRITE);
fprintf(stderr, "client ready\n"); fprintf(stderr, "client ready\n");
int ret = myloop.doLoop(); ret = myloop.doLoop();
if (ret < 0) { if (ret < 0) {
fprintf(stderr, "selectloop failed\n"); fprintf(stderr, "selectloop failed\n");
exit(1); exit(1);
@ -1076,8 +1251,7 @@ int trycli(char *host, char *serv)
class ServNetconWorker : public NetconWorker { class ServNetconWorker : public NetconWorker {
public: public:
ServNetconWorker() : m_count(0) {} ServNetconWorker() : m_count(0) {}
int data(NetconData *con, Netcon::Event reason) int data(NetconData *con, Netcon::Event reason) {
{
LOGDEB(("serverdata\n")); LOGDEB(("serverdata\n"));
if (reason & Netcon::NETCONPOLL_WRITE) { if (reason & Netcon::NETCONPOLL_WRITE) {
con->setselevents(Netcon::NETCONPOLL_READ); con->setselevents(Netcon::NETCONPOLL_READ);
@ -1114,14 +1288,14 @@ private:
class MyNetconServLis : public NetconServLis { class MyNetconServLis : public NetconServLis {
public: public:
MyNetconServLis(SelectLoop &loop) MyNetconServLis(SelectLoop &loop)
: NetconServLis(), m_loop(loop) : NetconServLis(), m_loop(loop) {
{
} }
protected: protected:
int cando(Netcon::Event reason) { int cando(Netcon::Event reason) {
NetconServCon *con = accept(); NetconServCon *con = accept();
if (con == 0) if (con == 0) {
return -1; return -1;
}
RefCntr<NetconWorker> worker = RefCntr<NetconWorker> worker =
RefCntr<NetconWorker>(new ServNetconWorker()); RefCntr<NetconWorker>(new ServNetconWorker());
con->setcallback(worker); con->setcallback(worker);
@ -1137,8 +1311,9 @@ void
onexit(int sig) onexit(int sig)
{ {
fprintf(stderr, "Onexit: "); fprintf(stderr, "Onexit: ");
if (sig == SIGQUIT) if (sig == SIGQUIT) {
kill(getpid(), SIGKILL); kill(getpid(), SIGKILL);
}
fprintf(stderr, "Exiting\n"); fprintf(stderr, "Exiting\n");
exit(0); exit(0);
} }
@ -1149,7 +1324,7 @@ int tryserv(char *serv)
SelectLoop myloop; SelectLoop myloop;
MyNetconServLis *servlis = new MyNetconServLis(myloop); MyNetconServLis *servlis = new MyNetconServLis(myloop);
lis = NetconP(servlis); lis = NetconP(servlis);
if (lis.isNull()) { if (!lis) {
fprintf(stderr, "new NetconServLis failed\n"); fprintf(stderr, "new NetconServLis failed\n");
return 1; return 1;
} }
@ -1163,7 +1338,10 @@ int tryserv(char *serv)
sigaction(SIGQUIT, &sa, 0); sigaction(SIGQUIT, &sa, 0);
sigaction(SIGTERM, &sa, 0); sigaction(SIGTERM, &sa, 0);
if (servlis->openservice(serv) < 0) { int port = atoi(serv);
int ret = port > 0 ?
servlis->openservice(port) : servlis->openservice(serv);
if (ret < 0) {
fprintf(stderr, "openservice(%s) failed\n", serv); fprintf(stderr, "openservice(%s) failed\n", serv);
return 1; return 1;
} }

View File

@ -18,9 +18,9 @@
*/ */
#include <sys/time.h> #include <sys/time.h>
#include <map> #include <map>
#include "refcntr.h" #include <string>
using std::map; #include "refcntr.h"
/// A set of classes to manage client-server communication over a /// A set of classes to manage client-server communication over a
/// connection-oriented network, or a pipe. /// connection-oriented network, or a pipe.
@ -45,8 +45,8 @@ public:
enum Event {NETCONPOLL_READ = 0x1, NETCONPOLL_WRITE=0x2}; enum Event {NETCONPOLL_READ = 0x1, NETCONPOLL_WRITE=0x2};
Netcon() Netcon()
: m_peer(0), m_fd(-1), m_ownfd(true), m_didtimo(0), m_wantedEvents(0), : m_peer(0), m_fd(-1), m_ownfd(true), m_didtimo(0), m_wantedEvents(0),
m_loop(0) m_loop(0) {
{} }
virtual ~Netcon(); virtual ~Netcon();
/// Remember whom we're talking to. We let external code do this because /// Remember whom we're talking to. We let external code do this because
/// the application may have a non-dns method to find the peer name. /// the application may have a non-dns method to find the peer name.
@ -58,11 +58,17 @@ public:
/// Set or reset the TCP_NODELAY option. /// Set or reset the TCP_NODELAY option.
virtual int settcpnodelay(int on = 1); virtual int settcpnodelay(int on = 1);
/// Did the last receive() call time out ? Resets the flag. /// Did the last receive() call time out ? Resets the flag.
virtual int timedout() {int s = m_didtimo; m_didtimo = 0; return s;} virtual int timedout() {
int s = m_didtimo;
m_didtimo = 0;
return s;
}
/// Return string version of last syscall error /// Return string version of last syscall error
virtual char *sterror(); virtual char *sterror();
/// Return the socket descriptor /// Return the socket descriptor
virtual int getfd() {return m_fd;} virtual int getfd() {
return m_fd;
}
/// Close the current connection if it is open /// Close the current connection if it is open
virtual void closeconn(); virtual void closeconn();
/// Set/reset the non-blocking flag on the underlying fd. Returns /// Set/reset the non-blocking flag on the underlying fd. Returns
@ -73,16 +79,26 @@ public:
/// Decide what events the connection will be looking for /// Decide what events the connection will be looking for
/// (NETCONPOLL_READ, NETCONPOLL_WRITE) /// (NETCONPOLL_READ, NETCONPOLL_WRITE)
int setselevents(int evs) {return m_wantedEvents = evs;} int setselevents(int evs) {
return m_wantedEvents = evs;
}
/// Retrieve the connection's currently monitored set of events /// Retrieve the connection's currently monitored set of events
int getselevents() {return m_wantedEvents;} int getselevents() {
return m_wantedEvents;
}
/// Add events to current set /// Add events to current set
int addselevents(int evs) {return m_wantedEvents |= evs;} int addselevents(int evs) {
return m_wantedEvents |= evs;
}
/// Clear events from current set /// Clear events from current set
int clearselevents(int evs) {return m_wantedEvents &= ~evs;} int clearselevents(int evs) {
return m_wantedEvents &= ~evs;
}
friend class SelectLoop; friend class SelectLoop;
SelectLoop *getloop() {return m_loop;} SelectLoop *getloop() {
return m_loop;
}
/// Utility function for a simplified select() interface: check one fd /// Utility function for a simplified select() interface: check one fd
/// for reading or writing, for a specified maximum number of seconds. /// for reading or writing, for a specified maximum number of seconds.
@ -99,7 +115,9 @@ protected:
// Method called by the selectloop when something can be done with a netcon // Method called by the selectloop when something can be done with a netcon
virtual int cando(Netcon::Event reason) = 0; virtual int cando(Netcon::Event reason) = 0;
// Called when added to loop // Called when added to loop
virtual void setloop(SelectLoop *loop) {m_loop = loop;} virtual void setloop(SelectLoop *loop) {
m_loop = loop;
}
}; };
@ -114,8 +132,8 @@ public:
SelectLoop() SelectLoop()
: m_selectloopDoReturn(false), m_selectloopReturnValue(0), : m_selectloopDoReturn(false), m_selectloopReturnValue(0),
m_placetostart(0), m_placetostart(0),
m_periodichandler(0), m_periodicparam(0), m_periodicmillis(0) m_periodichandler(0), m_periodicparam(0), m_periodicmillis(0) {
{} }
/// Loop waiting for events on the connections and call the /// Loop waiting for events on the connections and call the
/// cando() method on the object when something happens (this will in /// cando() method on the object when something happens (this will in
@ -126,8 +144,7 @@ public:
int doLoop(); int doLoop();
/// Call from data handler: make selectloop return the param value /// Call from data handler: make selectloop return the param value
void loopReturn(int value) void loopReturn(int value) {
{
m_selectloopDoReturn = true; m_selectloopDoReturn = true;
m_selectloopReturnValue = value; m_selectloopReturnValue = value;
} }
@ -156,7 +173,7 @@ private:
int m_placetostart; int m_placetostart;
// Map of NetconP indexed by fd // Map of NetconP indexed by fd
map<int, NetconP> m_polldata; std::map<int, NetconP> m_polldata;
// The last time we did the periodic thing. Initialized by setperiodic() // The last time we did the periodic thing. Initialized by setperiodic()
struct timeval m_lasthdlcall; struct timeval m_lasthdlcall;
@ -192,8 +209,8 @@ public:
/// Base class for connections that actually transfer data. T /// Base class for connections that actually transfer data. T
class NetconData : public Netcon { class NetconData : public Netcon {
public: public:
NetconData() : m_buf(0), m_bufbase(0), m_bufbytes(0), m_bufsize(0) NetconData() : m_buf(0), m_bufbase(0), m_bufbytes(0), m_bufsize(0) {
{} }
virtual ~NetconData(); virtual ~NetconData();
/// Write data to the connection. /// Write data to the connection.
@ -218,11 +235,14 @@ public:
virtual int readready(); virtual int readready();
/// Check for data being available for writing /// Check for data being available for writing
virtual int writeready(); virtual int writeready();
/// Read a line of text on an ascii connection /// Read a line of text on an ascii connection. Returns -1 or byte count
/// including final 0. \n is kept
virtual int getline(char *buf, int cnt, int timeo = -1); virtual int getline(char *buf, int cnt, int timeo = -1);
/// Set handler to be called when the connection is placed in the /// Set handler to be called when the connection is placed in the
/// selectloop and an event occurs. /// selectloop and an event occurs.
virtual void setcallback(RefCntr<NetconWorker> user) {m_user = user;} virtual void setcallback(RefCntr<NetconWorker> user) {
m_user = user;
}
private: private:
char *m_buf; // Buffer. Only used when doing getline()s char *m_buf; // Buffer. Only used when doing getline()s
@ -236,13 +256,18 @@ private:
/// Network endpoint, client side. /// Network endpoint, client side.
class NetconCli : public NetconData { class NetconCli : public NetconData {
public: public:
NetconCli(int silent = 0) {m_silentconnectfailure = silent;} NetconCli(int silent = 0) {
m_silentconnectfailure = silent;
}
/// Open connection to specified host and named service. /// Open connection to specified host and named service. Set host
int openconn(const char *host, char *serv, int timeo = -1); /// to an absolute path name for an AF_UNIX service. serv is
/// ignored in this case.
int openconn(const char *host, const char *serv, int timeo = -1);
/// Open connection to specified host and numeric port. port is in /// Open connection to specified host and numeric port. port is in
/// HOST byte order /// HOST byte order. Set host to an absolute path name for an
/// AF_UNIX service. serv is ignored in this case.
int openconn(const char *host, unsigned int port, int timeo = -1); int openconn(const char *host, unsigned int port, int timeo = -1);
/// Reuse existing fd. /// Reuse existing fd.
@ -253,7 +278,9 @@ public:
int setconn(int fd); int setconn(int fd);
/// Do not log message if openconn() fails. /// Do not log message if openconn() fails.
void setSilentFail(int onoff) {m_silentconnectfailure = onoff;} void setSilentFail(int onoff) {
m_silentconnectfailure = onoff;
}
private: private:
int m_silentconnectfailure; // No logging of connection failures if set int m_silentconnectfailure; // No logging of connection failures if set
@ -289,8 +316,9 @@ public:
#endif /* NETCON_ACCESSCONTROL */ #endif /* NETCON_ACCESSCONTROL */
} }
~NetconServLis(); ~NetconServLis();
/// Open named service. /// Open named service. Used absolute pathname to create an
int openservice(char *serv, int backlog = 10); /// AF_UNIX path-based socket instead of an IP one.
int openservice(const char *serv, int backlog = 10);
/// Open service by port number. /// Open service by port number.
int openservice(int port, int backlog = 10); int openservice(int port, int backlog = 10);
/// Wait for incoming connection. Returned connected Netcon /// Wait for incoming connection. Returned connected Netcon
@ -302,12 +330,15 @@ protected:
/// insert the new connection in the selectloop. /// insert the new connection in the selectloop.
virtual int cando(Netcon::Event reason); virtual int cando(Netcon::Event reason);
// Empty if port was numeric, else service name or socket path
std::string m_serv;
private: private:
#ifdef NETCON_ACCESSCONTROL #ifdef NETCON_ACCESSCONTROL
int permsinit; int permsinit;
struct intarrayparam okaddrs; struct intarrayparam okaddrs;
struct intarrayparam okmasks; struct intarrayparam okmasks;
int initperms(char *servicename); int initperms(const char *servicename);
int initperms(int port); int initperms(int port);
int checkperms(void *cli, int clilen); int checkperms(void *cli, int clilen);
#endif /* NETCON_ACCESSCONTROL */ #endif /* NETCON_ACCESSCONTROL */
@ -318,16 +349,16 @@ private:
/// case of a forking server) /// case of a forking server)
class NetconServCon : public NetconData { class NetconServCon : public NetconData {
public: public:
NetconServCon(int newfd, Netcon* lis = 0) NetconServCon(int newfd, Netcon* lis = 0) {
{
m_liscon = lis; m_liscon = lis;
m_fd = newfd; m_fd = newfd;
} }
/// This is for forked servers that want to get rid of the main socket /// This is for forked servers that want to get rid of the main socket
void closeLisCon() { void closeLisCon() {
if (m_liscon) if (m_liscon) {
m_liscon->closeconn(); m_liscon->closeconn();
} }
}
private: private:
Netcon* m_liscon; Netcon* m_liscon;
}; };