cosmetics+prepare change to shared_ptr+import unix socket support
This commit is contained in:
parent
45f37cfffb
commit
efa5882a79
1
src/common/config.h
Symbolic link
1
src/common/config.h
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
autoconfig.h
|
||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user