Switch to unified view

a/src/utils/netcon.h b/src/utils/netcon.h
...
...
16
 *   Free Software Foundation, Inc.,
16
 *   Free Software Foundation, Inc.,
17
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
 */
18
 */
19
#include <sys/time.h>
19
#include <sys/time.h>
20
#include <map>
20
#include <map>
21
#include <string>
22
21
#include "refcntr.h"
23
#include "refcntr.h"
22
23
using std::map;
24
24
25
/// A set of classes to manage client-server communication over a
25
/// A set of classes to manage client-server communication over a
26
/// connection-oriented network, or a pipe.
26
/// connection-oriented network, or a pipe.
27
///
27
///
28
/// The listening/connection-accepting code currently only uses
28
/// The listening/connection-accepting code currently only uses
...
...
43
class Netcon {
43
class Netcon {
44
public:
44
public:
45
    enum Event {NETCONPOLL_READ = 0x1, NETCONPOLL_WRITE=0x2};
45
    enum Event {NETCONPOLL_READ = 0x1, NETCONPOLL_WRITE=0x2};
46
    Netcon() 
46
    Netcon() 
47
    : m_peer(0), m_fd(-1), m_ownfd(true), m_didtimo(0), m_wantedEvents(0),
47
    : m_peer(0), m_fd(-1), m_ownfd(true), m_didtimo(0), m_wantedEvents(0),
48
      m_loop(0)
48
      m_loop(0) {
49
    {}
49
    }
50
    virtual ~Netcon();
50
    virtual ~Netcon();
51
    /// Remember whom we're talking to. We let external code do this because 
51
    /// Remember whom we're talking to. We let external code do this because 
52
    /// the application may have a non-dns method to find the peer name.
52
    /// the application may have a non-dns method to find the peer name.
53
    virtual void setpeer(const char *hostname);
53
    virtual void setpeer(const char *hostname);
54
    /// Retrieve the peer's hostname. Only works if it was set before !
54
    /// Retrieve the peer's hostname. Only works if it was set before !
...
...
56
    return m_peer ? (const char *)m_peer : "none";
56
    return m_peer ? (const char *)m_peer : "none";
57
    }
57
    }
58
    /// Set or reset the TCP_NODELAY option. 
58
    /// Set or reset the TCP_NODELAY option. 
59
    virtual int settcpnodelay(int on = 1); 
59
    virtual int settcpnodelay(int on = 1); 
60
    /// Did the last receive() call time out ? Resets the flag.
60
    /// Did the last receive() call time out ? Resets the flag.
61
    virtual int timedout() {int s = m_didtimo; m_didtimo = 0; return s;}
61
    virtual int timedout() {
62
        int s = m_didtimo; 
63
        m_didtimo = 0; 
64
        return s;
65
    }
62
    /// Return string version of last syscall error
66
    /// Return string version of last syscall error
63
    virtual char *sterror();
67
    virtual char *sterror();
64
    /// Return the socket descriptor
68
    /// Return the socket descriptor
65
    virtual int getfd() {return m_fd;}
69
    virtual int getfd() {
70
        return m_fd;
71
    }
66
    /// Close the current connection if it is open
72
    /// Close the current connection if it is open
67
    virtual void closeconn();
73
    virtual void closeconn();
68
    /// Set/reset the non-blocking flag on the underlying fd. Returns
74
    /// Set/reset the non-blocking flag on the underlying fd. Returns
69
    /// prev state The default is that sockets are blocking except
75
    /// prev state The default is that sockets are blocking except
70
    /// when added to the selectloop, or, transparently, to handle
76
    /// when added to the selectloop, or, transparently, to handle
71
    /// connection timeout issues.
77
    /// connection timeout issues.
72
    virtual int set_nonblock(int onoff);
78
    virtual int set_nonblock(int onoff);
73
79
74
    /// Decide what events the connection will be looking for
80
    /// Decide what events the connection will be looking for
75
    /// (NETCONPOLL_READ, NETCONPOLL_WRITE)
81
    /// (NETCONPOLL_READ, NETCONPOLL_WRITE)
76
    int setselevents(int evs) {return m_wantedEvents = evs;}
82
    int setselevents(int evs) {
83
        return m_wantedEvents = evs;
84
    }
77
    /// Retrieve the connection's currently monitored set of events
85
    /// Retrieve the connection's currently monitored set of events
78
    int getselevents() {return m_wantedEvents;}
86
    int getselevents() {
87
        return m_wantedEvents;
88
    }
79
    /// Add events to current set
89
    /// Add events to current set
80
    int addselevents(int evs) {return m_wantedEvents |= evs;}
90
    int addselevents(int evs) {
91
        return m_wantedEvents |= evs;
92
    }
81
    /// Clear events from current set
93
    /// Clear events from current set
82
    int clearselevents(int evs) {return m_wantedEvents &= ~evs;}
94
    int clearselevents(int evs) {
95
        return m_wantedEvents &= ~evs;
96
    }
83
97
84
    friend class SelectLoop;
98
    friend class SelectLoop;
85
    SelectLoop *getloop() {return m_loop;}
99
    SelectLoop *getloop() {
100
        return m_loop;
101
    }
86
102
87
    /// Utility function for a simplified select() interface: check one fd
103
    /// Utility function for a simplified select() interface: check one fd
88
    /// for reading or writing, for a specified maximum number of seconds.
104
    /// for reading or writing, for a specified maximum number of seconds.
89
    static int select1(int fd, int secs, int writing = 0);
105
    static int select1(int fd, int secs, int writing = 0);
90
106
...
...
97
    short m_wantedEvents;
113
    short m_wantedEvents;
98
    SelectLoop *m_loop;
114
    SelectLoop *m_loop;
99
    // Method called by the selectloop when something can be done with a netcon
115
    // Method called by the selectloop when something can be done with a netcon
100
    virtual int cando(Netcon::Event reason) = 0;
116
    virtual int cando(Netcon::Event reason) = 0;
101
    // Called when added to loop
117
    // Called when added to loop
102
    virtual void setloop(SelectLoop *loop) {m_loop = loop;}
118
    virtual void setloop(SelectLoop *loop) {
119
        m_loop = loop;
120
    }
103
};
121
};
104
122
105
123
106
/// The selectloop interface is used to implement parallel servers. 
124
/// The selectloop interface is used to implement parallel servers. 
107
// The select loop mechanism allows several netcons to be used for io
125
// The select loop mechanism allows several netcons to be used for io
...
...
112
class SelectLoop {
130
class SelectLoop {
113
public:
131
public:
114
    SelectLoop()
132
    SelectLoop()
115
    : m_selectloopDoReturn(false), m_selectloopReturnValue(0),
133
    : m_selectloopDoReturn(false), m_selectloopReturnValue(0),
116
      m_placetostart(0), 
134
      m_placetostart(0), 
117
      m_periodichandler(0), m_periodicparam(0), m_periodicmillis(0)
135
      m_periodichandler(0), m_periodicparam(0), m_periodicmillis(0) {
118
    {}
136
    }
119
137
120
    /// Loop waiting for events on the connections and call the
138
    /// Loop waiting for events on the connections and call the
121
    /// cando() method on the object when something happens (this will in 
139
    /// cando() method on the object when something happens (this will in 
122
    /// turn typically call the app callback set on the netcon). Possibly
140
    /// turn typically call the app callback set on the netcon). Possibly
123
    /// call the periodic handler (if set) at regular intervals.
141
    /// call the periodic handler (if set) at regular intervals.
124
    /// @return -1 for error. 0 if no descriptors left for i/o. 1 for periodic
142
    /// @return -1 for error. 0 if no descriptors left for i/o. 1 for periodic
125
    ///  timeout (should call back in after processing)
143
    ///  timeout (should call back in after processing)
126
    int doLoop();
144
    int doLoop();
127
145
128
    /// Call from data handler: make selectloop return the param value
146
    /// Call from data handler: make selectloop return the param value
129
    void loopReturn(int value) 
147
    void loopReturn(int value) {
130
    {
131
    m_selectloopDoReturn = true;
148
    m_selectloopDoReturn = true;
132
    m_selectloopReturnValue = value;
149
    m_selectloopReturnValue = value;
133
    }
150
    }
134
    /// Add a connection to be monitored (this will usually be called
151
    /// Add a connection to be monitored (this will usually be called
135
    /// from the server's listen connection's accept callback)
152
    /// from the server's listen connection's accept callback)
...
...
154
    bool m_selectloopDoReturn;
171
    bool m_selectloopDoReturn;
155
    int  m_selectloopReturnValue;
172
    int  m_selectloopReturnValue;
156
    int  m_placetostart;
173
    int  m_placetostart;
157
174
158
    // Map of NetconP indexed by fd
175
    // Map of NetconP indexed by fd
159
    map<int, NetconP> m_polldata;
176
    std::map<int, NetconP> m_polldata;
160
177
161
    // The last time we did the periodic thing. Initialized by setperiodic()
178
    // The last time we did the periodic thing. Initialized by setperiodic()
162
    struct timeval m_lasthdlcall;
179
    struct timeval m_lasthdlcall;
163
    // The call back function and its parameter
180
    // The call back function and its parameter
164
    int (*m_periodichandler)(void *);
181
    int (*m_periodichandler)(void *);
...
...
190
};
207
};
191
208
192
/// Base class for connections that actually transfer data. T
209
/// Base class for connections that actually transfer data. T
193
class NetconData : public Netcon {
210
class NetconData : public Netcon {
194
public:
211
public:
195
    NetconData() : m_buf(0), m_bufbase(0), m_bufbytes(0), m_bufsize(0)
212
    NetconData() : m_buf(0), m_bufbase(0), m_bufbytes(0), m_bufsize(0) {
196
    {}
213
    }
197
    virtual ~NetconData();
214
    virtual ~NetconData();
198
215
199
    /// Write data to the connection.
216
    /// Write data to the connection.
200
    /// @param buf the data buffer
217
    /// @param buf the data buffer
201
    /// @param cnt the number of bytes we should try to send
218
    /// @param cnt the number of bytes we should try to send
...
...
216
    virtual int doreceive(char *buf, int cnt, int timeo = -1);
233
    virtual int doreceive(char *buf, int cnt, int timeo = -1);
217
    /// Check for data being available for reading
234
    /// Check for data being available for reading
218
    virtual int readready();
235
    virtual int readready();
219
    /// Check for data being available for writing
236
    /// Check for data being available for writing
220
    virtual int writeready();
237
    virtual int writeready();
221
    /// Read a line of text on an ascii connection
238
    /// Read a line of text on an ascii connection. Returns -1 or byte count
239
    /// including final 0. \n is kept
222
    virtual int getline(char *buf, int cnt, int timeo = -1);
240
    virtual int getline(char *buf, int cnt, int timeo = -1);
223
    /// Set handler to be called when the connection is placed in the
241
    /// Set handler to be called when the connection is placed in the
224
    /// selectloop and an event occurs.
242
    /// selectloop and an event occurs.
225
    virtual void setcallback(RefCntr<NetconWorker> user) {m_user = user;}
243
    virtual void setcallback(RefCntr<NetconWorker> user) {
244
        m_user = user;
245
    }
226
246
227
private:
247
private:
228
    char *m_buf;    // Buffer. Only used when doing getline()s
248
    char *m_buf;    // Buffer. Only used when doing getline()s
229
    char *m_bufbase;    // Pointer to current 1st byte of useful data
249
    char *m_bufbase;    // Pointer to current 1st byte of useful data
230
    int m_bufbytes; // Bytes of data.
250
    int m_bufbytes; // Bytes of data.
...
...
234
};
254
};
235
255
236
/// Network endpoint, client side.
256
/// Network endpoint, client side.
237
class NetconCli : public NetconData {   
257
class NetconCli : public NetconData {   
238
public:
258
public:
239
    NetconCli(int silent = 0) {m_silentconnectfailure = silent;}
259
    NetconCli(int silent = 0) {
260
        m_silentconnectfailure = silent;
261
    }
240
262
241
    /// Open connection to specified host and named service. 
263
    /// Open connection to specified host and named service. Set host
264
    /// to an absolute path name for an AF_UNIX service. serv is
265
    /// ignored in this case.
242
    int openconn(const char *host, char *serv, int timeo = -1);
266
    int openconn(const char *host, const char *serv, int timeo = -1);
243
267
244
    /// Open connection to specified host and numeric port. port is in
268
    /// Open connection to specified host and numeric port. port is in
245
    /// HOST byte order
269
    /// HOST byte order. Set host to an absolute path name for an
270
    /// AF_UNIX service. serv is ignored in this case.
246
    int openconn(const char *host, unsigned int port, int timeo = -1);
271
    int openconn(const char *host, unsigned int port, int timeo = -1);
247
272
248
    /// Reuse existing fd. 
273
    /// Reuse existing fd. 
249
    /// We DONT take ownership of the fd, and do no closin' EVEN on an
274
    /// We DONT take ownership of the fd, and do no closin' EVEN on an
250
    /// explicit closeconn() or setconn() (use getfd(), close,
275
    /// explicit closeconn() or setconn() (use getfd(), close,
251
    /// setconn(-1) if you need to really close the fd and have no
276
    /// setconn(-1) if you need to really close the fd and have no
252
    /// other copy).
277
    /// other copy).
253
    int setconn(int fd);
278
    int setconn(int fd);
254
279
255
    /// Do not log message if openconn() fails.
280
    /// Do not log message if openconn() fails.
256
    void setSilentFail(int onoff) {m_silentconnectfailure = onoff;}
281
    void setSilentFail(int onoff) {
282
        m_silentconnectfailure = onoff;
283
    }
257
284
258
private:
285
private:
259
    int m_silentconnectfailure; // No logging of connection failures if set
286
    int m_silentconnectfailure; // No logging of connection failures if set
260
};
287
};
261
288
...
...
287
    okaddrs.len = okmasks.len = 0;
314
    okaddrs.len = okmasks.len = 0;
288
    okaddrs.intarray = okmasks.intarray = 0;
315
    okaddrs.intarray = okmasks.intarray = 0;
289
#endif /* NETCON_ACCESSCONTROL */
316
#endif /* NETCON_ACCESSCONTROL */
290
    }
317
    }
291
    ~NetconServLis();
318
    ~NetconServLis();
292
    /// Open named service.
319
    /// Open named service. Used absolute pathname to create an
320
    /// AF_UNIX path-based socket instead of an IP one.
293
    int openservice(char *serv, int backlog = 10);
321
    int openservice(const char *serv, int backlog = 10);
294
    /// Open service by port number.
322
    /// Open service by port number.
295
    int openservice(int port, int backlog = 10);
323
    int openservice(int port, int backlog = 10);
296
    /// Wait for incoming connection. Returned connected Netcon 
324
    /// Wait for incoming connection. Returned connected Netcon 
297
    NetconServCon *accept(int timeo = -1);
325
    NetconServCon *accept(int timeo = -1);
298
326
...
...
300
    /// This should be overriden in a derived class to handle incoming
328
    /// This should be overriden in a derived class to handle incoming
301
    /// connections. It will usually call NetconServLis::accept(), and
329
    /// connections. It will usually call NetconServLis::accept(), and
302
    /// insert the new connection in the selectloop.
330
    /// insert the new connection in the selectloop.
303
    virtual int cando(Netcon::Event reason);
331
    virtual int cando(Netcon::Event reason);
304
332
333
    // Empty if port was numeric, else service name or socket path
334
    std::string m_serv; 
335
305
private:
336
private:
306
#ifdef NETCON_ACCESSCONTROL
337
#ifdef NETCON_ACCESSCONTROL
307
    int permsinit;
338
    int permsinit;
308
    struct intarrayparam okaddrs;
339
    struct intarrayparam okaddrs;
309
    struct intarrayparam okmasks;
340
    struct intarrayparam okmasks;
310
    int initperms(char *servicename);
341
    int initperms(const char *servicename);
311
    int initperms(int port);
342
    int initperms(int port);
312
    int checkperms(void *cli, int clilen);
343
    int checkperms(void *cli, int clilen);
313
#endif /* NETCON_ACCESSCONTROL */
344
#endif /* NETCON_ACCESSCONTROL */
314
};
345
};
315
346
316
/// Server-side accepted client connection. The only specific code
347
/// Server-side accepted client connection. The only specific code
317
/// allows closing the listening endpoint in the child process (in the
348
/// allows closing the listening endpoint in the child process (in the
318
/// case of a forking server)
349
/// case of a forking server)
319
class NetconServCon : public NetconData {   
350
class NetconServCon : public NetconData {   
320
public:
351
public:
321
    NetconServCon(int newfd, Netcon* lis = 0) 
352
    NetconServCon(int newfd, Netcon* lis = 0) { 
322
    { 
323
    m_liscon = lis;
353
    m_liscon = lis;
324
    m_fd = newfd;
354
    m_fd = newfd;
325
    }
355
    }
326
    /// This is for forked servers that want to get rid of the main socket
356
    /// This is for forked servers that want to get rid of the main socket
327
    void closeLisCon() {
357
    void closeLisCon() {
328
    if (m_liscon)
358
    if (m_liscon) {
329
        m_liscon->closeconn();
359
        m_liscon->closeconn();
360
        }
330
    }
361
    }
331
private:
362
private:
332
    Netcon* m_liscon;
363
    Netcon* m_liscon;
333
};
364
};
334
365