Switch to unified view

a/src/netcon.cpp b/src/netcon.cpp
...
...
102
        ret = select(fd + 1, 0, &rd, 0, &tv);
102
        ret = select(fd + 1, 0, &rd, 0, &tv);
103
    } else {
103
    } else {
104
        ret = select(fd + 1, &rd, 0, 0, &tv);
104
        ret = select(fd + 1, &rd, 0, 0, &tv);
105
    }
105
    }
106
    if (!FD_ISSET(fd, &rd)) {
106
    if (!FD_ISSET(fd, &rd)) {
107
        LOGDEB2("Netcon::select1: fd "  << (fd) << " timeout\n" );
107
        LOGDEB2("Netcon::select1: fd " << fd << " timeout\n");
108
    }
108
    }
109
    return ret;
109
    return ret;
110
}
110
}
111
111
112
void SelectLoop::setperiodichandler(int (*handler)(void *), void *p, int ms)
112
void SelectLoop::setperiodichandler(int (*handler)(void *), void *p, int ms)
...
...
133
    }
133
    }
134
134
135
    struct timeval mtv;
135
    struct timeval mtv;
136
    gettimeofday(&mtv, 0);
136
    gettimeofday(&mtv, 0);
137
    int millis = m_periodicmillis - MILLIS(m_lasthdlcall, mtv);
137
    int millis = m_periodicmillis - MILLIS(m_lasthdlcall, mtv);
138
138
    
139
    // millis <= 0 means we should have already done the thing. *dont* set the
139
    // millis <= 0 means we should have already done the thing. *dont* set the
140
    // tv to 0, which means no timeout at all !
140
    // tv to 0, which means no timeout at all !
141
    if (millis <= 0) {
141
    if (millis <= 0) {
142
        millis = 1;
142
        millis = 1;
143
    }
143
    }
...
...
169
int SelectLoop::doLoop()
169
int SelectLoop::doLoop()
170
{
170
{
171
    for (;;) {
171
    for (;;) {
172
        if (m_selectloopDoReturn) {
172
        if (m_selectloopDoReturn) {
173
            m_selectloopDoReturn = false;
173
            m_selectloopDoReturn = false;
174
            LOGDEB("Netcon::selectloop: returning on request\n" );
174
            LOGDEB("Netcon::selectloop: returning on request\n");
175
            return m_selectloopReturnValue;
175
            return m_selectloopReturnValue;
176
        }
176
        }
177
        int nfds;
177
        int nfds;
178
        fd_set rd, wd;
178
        fd_set rd, wd;
179
        FD_ZERO(&rd);
179
        FD_ZERO(&rd);
...
...
205
            // condition.
205
            // condition.
206
206
207
            // Just in case there would still be open fds in there
207
            // Just in case there would still be open fds in there
208
            // (with no r/w flags set). Should not be needed, but safer
208
            // (with no r/w flags set). Should not be needed, but safer
209
            m_polldata.clear();
209
            m_polldata.clear();
210
            LOGDEB1("Netcon::selectloop: no fds\n" );
210
            LOGDEB1("Netcon::selectloop: no fds\n");
211
            return 0;
211
            return 0;
212
        }
212
        }
213
213
214
        LOGDEB2("Netcon::selectloop: selecting, nfds = " << nfds << "\n");
214
        LOGDEB2("Netcon::selectloop: selecting, nfds = " << nfds << "\n");
215
215
...
...
217
        // done apart from waiting for data
217
        // done apart from waiting for data
218
        struct timeval tv;
218
        struct timeval tv;
219
        periodictimeout(&tv);
219
        periodictimeout(&tv);
220
        // Wait for something to happen
220
        // Wait for something to happen
221
        int ret = select(nfds, &rd, &wd, 0, &tv);
221
        int ret = select(nfds, &rd, &wd, 0, &tv);
222
        LOGDEB2("Netcon::selectloop: select returns "  << (ret) << "\n" );
222
        LOGDEB2("Netcon::selectloop: nfds " << nfds <<
223
                " select returns " << ret << "\n");
223
        if (ret < 0) {
224
        if (ret < 0) {
224
            LOGSYSERR("Netcon::selectloop", "select", "");
225
            LOGSYSERR("Netcon::selectloop", "select", "");
225
            return -1;
226
            return -1;
226
        }
227
        }
227
        if (m_periodicmillis > 0)
228
        if (m_periodicmillis > 0 && maybecallperiodic() <= 0) {
228
            if (maybecallperiodic() <= 0) {
229
                return 1;
229
            return 1;
230
            }
230
        }
231
231
232
        // Timeout, do it again.
232
        // Timeout, do it again.
233
        if (ret == 0) {
233
        if (ret == 0) {
234
            continue;
234
            continue;
235
        }
235
        }
236
236
237
        // Select returned > 0: at least one fd must be ready. Sweep the fd
238
        // table and act on the ready ones.
237
        // We don't start the fd sweep at 0, else some fds would be advantaged.
239
        // We don't start the fd sweep at 0, else some fds would be advantaged.
238
        // Note that we do an fd sweep, not a map sweep. This is
240
        // Note that we do an fd sweep, not a map sweep. This is
239
        // inefficient because the fd array may be very sparse. Otoh, the
241
        // inefficient because the fd array may be very sparse. Otoh, the
240
        // map may change between 2 sweeps, so that we'd have to be smart
242
        // map may change between 2 sweeps, so that we'd have to be smart
241
        // with the iterator. As the cost per unused fd is low (just 2 bit
243
        // with the iterator. As the cost per unused fd is low (just 2 bit
242
        // flag tests), we keep it like this for now
244
        // flag tests), we keep it like this for now
243
        if (m_placetostart >= nfds) {
245
        if (m_placetostart >= nfds) {
244
            m_placetostart = 0;
246
            m_placetostart = 0;
245
        }
247
        }
246
        int i, fd;
248
        int i, fd;
249
        int activefds = 0;
247
        for (i = 0, fd = m_placetostart; i < nfds; i++, fd++) {
250
        for (i = 0, fd = m_placetostart; i < nfds; i++, fd++) {
248
            if (fd >= nfds) {
251
            if (fd >= nfds) {
249
                fd = 0;
252
                fd = 0;
250
            }
253
            }
251
254
252
            int canread = FD_ISSET(fd, &rd);
255
            int canread = FD_ISSET(fd, &rd);
253
            int canwrite = FD_ISSET(fd, &wd);
256
            int canwrite = FD_ISSET(fd, &wd);
254
            bool none = !canread && !canwrite;
257
            bool none = !canread && !canwrite;
255
            LOGDEB2("Netcon::selectloop: fd "  << (fd) << " "  << (none ? "blocked" : "can") << " "  << (canread ? "read" : "") << " "  << (canwrite ? "write" : "") << "\n" );
258
            LOGDEB2("Netcon::selectloop: fd " << fd << " "  << 
259
                    (none ? "blocked" : "can") << " "  << 
260
                    (canread ? "read" : "") << " "  << 
261
                    (canwrite ? "write" : "") << "\n");
256
            if (none) {
262
            if (none) {
257
                continue;
263
                continue;
258
            }
264
            }
259
265
260
            map<int, NetconP>::iterator it = m_polldata.find(fd);
266
            map<int, NetconP>::iterator it = m_polldata.find(fd);
261
            if (it == m_polldata.end()) {
267
            if (it == m_polldata.end()) {
262
                /// This should not happen actually
268
                // This should never happen, because we only set our
269
                // own fds in the mask !
263
                LOGDEB2("Netcon::selectloop: fd "  << (fd) << " not found\n" );
270
                LOGERR("Netcon::selectloop: fd "  << fd << " not found\n");
264
                continue;
271
                continue;
265
            }
272
            }
266
273
            activefds++;
267
            // Next start will be one beyond last serviced (modulo nfds)
274
            // Next start will be one beyond last serviced (modulo nfds)
268
            m_placetostart = fd + 1;
275
            m_placetostart = fd + 1;
276
269
            NetconP& pll = it->second;
277
            NetconP& pll = it->second;
270
            if (canread && pll->cando(Netcon::NETCONPOLL_READ) <= 0) {
278
            if (canread && pll->cando(Netcon::NETCONPOLL_READ) <= 0) {
271
                pll->m_wantedEvents &= ~Netcon::NETCONPOLL_READ;
279
                pll->m_wantedEvents &= ~Netcon::NETCONPOLL_READ;
272
            }
280
            }
273
            if (canwrite && pll->cando(Netcon::NETCONPOLL_WRITE) <= 0) {
281
            if (canwrite && pll->cando(Netcon::NETCONPOLL_WRITE) <= 0) {
274
                pll->m_wantedEvents &= ~Netcon::NETCONPOLL_WRITE;
282
                pll->m_wantedEvents &= ~Netcon::NETCONPOLL_WRITE;
275
            }
283
            }
284
            if (!(pll->m_wantedEvents &
276
            if (!(pll->m_wantedEvents & (Netcon::NETCONPOLL_WRITE | Netcon::NETCONPOLL_READ))) {
285
                  (Netcon::NETCONPOLL_WRITE | Netcon::NETCONPOLL_READ))) {
277
                LOGDEB0("Netcon::selectloop: fd "  << (it->first) << " has 0x"  << (it->second->m_wantedEvents) << " mask, erasing\n" );
286
                LOGDEB0("Netcon::selectloop: fd " << it->first << " has 0x"
287
                        << it->second->m_wantedEvents << " mask, erasing\n");
278
                m_polldata.erase(it);
288
                m_polldata.erase(it);
279
            }
289
            }
280
        } // fd sweep
290
        } // fd sweep
281
291
292
        if (ret > 0 && activefds != ret) {
293
            LOGERR("Select returned " << ret << " not equal to " <<
294
                   activefds << " active fd found\n");
295
            return -1;
296
        }
282
    } // forever loop
297
    } // forever loop
283
    LOGERR("SelectLoop::doLoop: got out of loop !\n" );
298
    LOGERR("SelectLoop::doLoop: got out of loop !\n");
284
    return -1;
299
    return -1;
285
}
300
}
286
301
287
// Add a connection to the monitored set.
302
// Add a connection to the monitored set.
288
int SelectLoop::addselcon(NetconP con, int events)
303
int SelectLoop::addselcon(NetconP con, int events)
289
{
304
{
290
    if (!con) {
305
    if (!con) {
291
        return -1;
306
        return -1;
292
    }
307
    }
293
    LOGDEB1("Netcon::addselcon: fd "  << (con->m_fd) << "\n" );
308
    LOGDEB1("Netcon::addselcon: fd " << con->m_fd << "\n");
294
    con->set_nonblock(1);
309
    con->set_nonblock(1);
295
    con->setselevents(events);
310
    con->setselevents(events);
296
    m_polldata[con->m_fd] = con;
311
    m_polldata[con->m_fd] = con;
297
    con->setloop(this);
312
    con->setloop(this);
298
    return 0;
313
    return 0;
...
...
302
int SelectLoop::remselcon(NetconP con)
317
int SelectLoop::remselcon(NetconP con)
303
{
318
{
304
    if (!con) {
319
    if (!con) {
305
        return -1;
320
        return -1;
306
    }
321
    }
307
    LOGDEB1("Netcon::remselcon: fd "  << (con->m_fd) << "\n" );
322
    LOGDEB1("Netcon::remselcon: fd " << con->m_fd << "\n");
308
    map<int, NetconP>::iterator it = m_polldata.find(con->m_fd);
323
    map<int, NetconP>::iterator it = m_polldata.find(con->m_fd);
309
    if (it == m_polldata.end()) {
324
    if (it == m_polldata.end()) {
310
        LOGDEB1("Netcon::remselcon: con not found for fd "  << (con->m_fd) << "\n" );
325
        LOGDEB1("Netcon::remselcon: con not found for fd " << 
326
                con->m_fd << "\n");
311
        return -1;
327
        return -1;
312
    }
328
    }
313
    con->setloop(0);
329
    con->setloop(0);
314
    m_polldata.erase(it);
330
    m_polldata.erase(it);
315
    return 0;
331
    return 0;
...
...
348
    m_peer = strdup(hostname);
364
    m_peer = strdup(hostname);
349
}
365
}
350
366
351
int Netcon::settcpnodelay(int on)
367
int Netcon::settcpnodelay(int on)
352
{
368
{
353
    LOGDEB2("Netcon::settcpnodelay\n" );
369
    LOGDEB2("Netcon::settcpnodelay\n");
354
    if (m_fd < 0) {
370
    if (m_fd < 0) {
355
        LOGERR("Netcon::settcpnodelay: connection not opened\n" );
371
        LOGERR("Netcon::settcpnodelay: connection not opened\n");
356
        return -1;
372
        return -1;
357
    }
373
    }
358
    char *cp = on ? (char *)&one : (char *)&zero;
374
    char *cp = on ? (char *)&one : (char *)&zero;
359
    if (setsockopt(m_fd, IPPROTO_TCP, TCP_NODELAY, cp, sizeof(one)) < 0) {
375
    if (setsockopt(m_fd, IPPROTO_TCP, TCP_NODELAY, cp, sizeof(one)) < 0) {
360
        LOGSYSERR("NetconCli::settcpnodelay", "setsockopt", "TCP_NODELAY");
376
        LOGSYSERR("NetconCli::settcpnodelay", "setsockopt", "TCP_NODELAY");
...
...
414
{
430
{
415
    LOGDEB2("NetconData::send: fd " << m_fd << " cnt " << cnt <<
431
    LOGDEB2("NetconData::send: fd " << m_fd << " cnt " << cnt <<
416
            " expe " << expedited << "\n");
432
            " expe " << expedited << "\n");
417
    int flag = 0;
433
    int flag = 0;
418
    if (m_fd < 0) {
434
    if (m_fd < 0) {
419
        LOGERR("NetconData::send: connection not opened\n" );
435
        LOGERR("NetconData::send: connection not opened\n");
420
        return -1;
436
        return -1;
421
    }
437
    }
422
    if (expedited) {
438
    if (expedited) {
423
        LOGDEB2("NetconData::send: expedited data, count " <<cnt << " bytes\n");
439
        LOGDEB2("NetconData::send: expedited data, count " <<cnt << " bytes\n");
424
        flag = MSG_OOB;
440
        flag = MSG_OOB;
...
...
454
{
470
{
455
    LOGDEB2("NetconData::receive: cnt " << cnt << " timeo "  << timeo <<
471
    LOGDEB2("NetconData::receive: cnt " << cnt << " timeo "  << timeo <<
456
            " m_buf 0x" << m_buf << " m_bufbytes " << m_bufbytes << "\n");
472
            " m_buf 0x" << m_buf << " m_bufbytes " << m_bufbytes << "\n");
457
473
458
    if (m_fd < 0) {
474
    if (m_fd < 0) {
459
        LOGERR("NetconData::receive: connection not opened\n" );
475
        LOGERR("NetconData::receive: connection not opened\n");
460
        return -1;
476
        return -1;
461
    }
477
    }
462
478
463
    int fromibuf = 0;
479
    int fromibuf = 0;
464
    // Get whatever might have been left in the buffer by a previous
480
    // Get whatever might have been left in the buffer by a previous
...
...
526
    int got, cur;
542
    int got, cur;
527
    LOGDEB2("Netcon::doreceive: cnt " << cnt << ", timeo " << timeo << "\n");
543
    LOGDEB2("Netcon::doreceive: cnt " << cnt << ", timeo " << timeo << "\n");
528
    cur = 0;
544
    cur = 0;
529
    while (cnt > cur) {
545
    while (cnt > cur) {
530
        got = receive(buf, cnt - cur, timeo);
546
        got = receive(buf, cnt - cur, timeo);
531
        LOGDEB2("Netcon::doreceive: got "  << (got) << "\n" );
547
        LOGDEB2("Netcon::doreceive: got " << got << "\n");
532
        if (got < 0) {
548
        if (got < 0) {
533
            return got;
549
            return got;
534
        }
550
        }
535
        if (got == 0) {
551
        if (got == 0) {
536
            return cur;
552
            return cur;
...
...
550
//  0: EOF reached, no chars transferred
566
//  0: EOF reached, no chars transferred
551
// -1: error
567
// -1: error
552
static const int defbufsize = 200;
568
static const int defbufsize = 200;
553
int NetconData::getline(char *buf, int cnt, int timeo)
569
int NetconData::getline(char *buf, int cnt, int timeo)
554
{
570
{
555
    LOGDEB2("NetconData::getline: cnt "  << (cnt) << ", timeo "  << (timeo) << "\n" );
571
    LOGDEB2("NetconData::getline: cnt " << cnt << ", timeo " << 
572
            timeo << "\n");
556
    if (m_buf == 0) {
573
    if (m_buf == 0) {
557
        if ((m_buf = (char *)malloc(defbufsize)) == 0) {
574
        if ((m_buf = (char *)malloc(defbufsize)) == 0) {
558
            LOGSYSERR("NetconData::getline: Out of mem", "malloc", "");
575
            LOGSYSERR("NetconData::getline: Out of mem", "malloc", "");
559
            return -1;
576
            return -1;
560
        }
577
        }
...
...
567
    for (;;) {
584
    for (;;) {
568
        // Transfer from buffer. Have to take a lot of care to keep counts and
585
        // Transfer from buffer. Have to take a lot of care to keep counts and
569
        // pointers consistant in all end cases
586
        // pointers consistant in all end cases
570
        int maxtransf = MIN(m_bufbytes, cnt - 1);
587
        int maxtransf = MIN(m_bufbytes, cnt - 1);
571
        int nn = maxtransf;
588
        int nn = maxtransf;
572
        LOGDEB2("Before loop, bufbytes "  << (m_bufbytes) << ", maxtransf "  << (maxtransf) << ", nn: "  << (nn) << "\n" );
589
        LOGDEB2("Before loop, bufbytes " << m_bufbytes << ", maxtransf " <<
590
                maxtransf << ", nn: " << nn << "\n");
573
        for (nn = maxtransf; nn > 0;) {
591
        for (nn = maxtransf; nn > 0;) {
574
            // This is not pretty but we want nn to be decremented for
592
            // This is not pretty but we want nn to be decremented for
575
            // each byte copied (even newline), and not become -1 if
593
            // each byte copied (even newline), and not become -1 if
576
            // we go to the end. Better ways welcome!
594
            // we go to the end. Better ways welcome!
577
            nn--;
595
            nn--;
...
...
581
        }
599
        }
582
        // Update counts
600
        // Update counts
583
        maxtransf -= nn; // Actual count transferred
601
        maxtransf -= nn; // Actual count transferred
584
        m_bufbytes -= maxtransf;
602
        m_bufbytes -= maxtransf;
585
        cnt -= maxtransf;
603
        cnt -= maxtransf;
586
        LOGDEB2("After transfer: actual transf "  << (maxtransf) << " cnt "  << (cnt) << ", m_bufbytes "  << (m_bufbytes) << "\n" );
604
        LOGDEB2("After transfer: actual transf " << maxtransf << " cnt " << 
605
                cnt << ", m_bufbytes " << m_bufbytes << "\n");
587
606
588
        // Finished ?
607
        // Finished ?
589
        if (cnt <= 1 || (cp > buf && cp[-1] == '\n')) {
608
        if (cnt <= 1 || (cp > buf && cp[-1] == '\n')) {
590
            *cp = 0;
609
            *cp = 0;
591
            return cp - buf;
610
            return cp - buf;
...
...
611
// the connection. The user callback would normally have been set
630
// the connection. The user callback would normally have been set
612
// up. If it is, call it and return. Else, perform housecleaning: read
631
// up. If it is, call it and return. Else, perform housecleaning: read
613
// and discard.
632
// and discard.
614
int NetconData::cando(Netcon::Event reason)
633
int NetconData::cando(Netcon::Event reason)
615
{
634
{
616
    LOGDEB2("NetconData::cando\n" );
635
    LOGDEB2("NetconData::cando\n");
617
    if (m_user) {
636
    if (m_user) {
618
        return m_user->data(this, reason);
637
        return m_user->data(this, reason);
619
    }
638
    }
620
639
621
    // No user callback. Clean up by ourselves
640
    // No user callback. Clean up by ourselves
...
...
639
///////////////////////////////////////////////////////////////////////
658
///////////////////////////////////////////////////////////////////////
640
// Methods for a client connection (NetconCli)
659
// Methods for a client connection (NetconCli)
641
int NetconCli::openconn(const char *host, unsigned int port, int timeo)
660
int NetconCli::openconn(const char *host, unsigned int port, int timeo)
642
{
661
{
643
    int ret = -1;
662
    int ret = -1;
644
    LOGDEB2("Netconcli::openconn: host "  << (host) << ", port "  << (port) << "\n" );
663
    LOGDEB2("Netconcli::openconn: host " << host << ", port "  << port << "\n");
645
664
646
    closeconn();
665
    closeconn();
647
666
648
    struct sockaddr *saddr;
667
    struct sockaddr *saddr;
649
    socklen_t addrsize;
668
    socklen_t addrsize;
...
...
660
        if ((addr = inet_addr(host)) != -1) {
679
        if ((addr = inet_addr(host)) != -1) {
661
            memcpy(&ip_addr.sin_addr, &addr, sizeof(addr));
680
            memcpy(&ip_addr.sin_addr, &addr, sizeof(addr));
662
        } else {
681
        } else {
663
            struct hostent *hp;
682
            struct hostent *hp;
664
            if ((hp = gethostbyname(host)) == 0) {
683
            if ((hp = gethostbyname(host)) == 0) {
665
                LOGERR("NetconCli::openconn: gethostbyname("  << (host) << ") failed\n" );
684
                LOGERR("NetconCli::openconn: gethostbyname(" << host << 
685
                       ") failed\n");
666
                return -1;
686
                return -1;
667
            }
687
            }
668
            memcpy(&ip_addr.sin_addr, hp->h_addr, hp->h_length);
688
            memcpy(&ip_addr.sin_addr, hp->h_addr, hp->h_length);
669
        }
689
        }
670
690
...
...
676
        saddr = (sockaddr*)&ip_addr;
696
        saddr = (sockaddr*)&ip_addr;
677
    } else {
697
    } else {
678
        memset(&unix_addr, 0, sizeof(unix_addr));
698
        memset(&unix_addr, 0, sizeof(unix_addr));
679
        unix_addr.sun_family = AF_UNIX;
699
        unix_addr.sun_family = AF_UNIX;
680
        if (strlen(host) > UNIX_PATH_MAX - 1) {
700
        if (strlen(host) > UNIX_PATH_MAX - 1) {
681
            LOGERR("NetconCli::openconn: name too long: "  << (host) << "\n" );
701
            LOGERR("NetconCli::openconn: name too long: " << host << "\n");
682
            return -1;
702
            return -1;
683
        }
703
        }
684
        strcpy(unix_addr.sun_path, host);
704
        strcpy(unix_addr.sun_path, host);
685
705
686
        if ((m_fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
706
        if ((m_fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
...
...
711
connectok:
731
connectok:
712
    if (timeo > 0) {
732
    if (timeo > 0) {
713
        set_nonblock(0);
733
        set_nonblock(0);
714
    }
734
    }
715
735
716
    LOGDEB2("NetconCli::connect: setting keepalive\n" );
736
    LOGDEB2("NetconCli::connect: setting keepalive\n");
717
    if (setsockopt(m_fd, SOL_SOCKET, SO_KEEPALIVE,
737
    if (setsockopt(m_fd, SOL_SOCKET, SO_KEEPALIVE,
718
                   (char *)&one, sizeof(one)) < 0) {
738
                   (char *)&one, sizeof(one)) < 0) {
719
        LOGSYSERR("NetconCli::connect", "setsockopt", "KEEPALIVE");
739
        LOGSYSERR("NetconCli::connect", "setsockopt", "KEEPALIVE");
720
    }
740
    }
721
    setpeer(host);
741
    setpeer(host);
722
    LOGDEB2("NetconCli::openconn: connection opened ok\n" );
742
    LOGDEB2("NetconCli::openconn: connection opened ok\n");
723
    ret = 0;
743
    ret = 0;
724
out:
744
out:
725
    if (ret < 0) {
745
    if (ret < 0) {
726
        closeconn();
746
        closeconn();
727
    }
747
    }
...
...
729
}
749
}
730
750
731
// Same as previous, but get the port number from services
751
// Same as previous, but get the port number from services
732
int NetconCli::openconn(const char *host, const char *serv, int timeo)
752
int NetconCli::openconn(const char *host, const char *serv, int timeo)
733
{
753
{
734
    LOGDEB2("Netconcli::openconn: host "  << (host) << ", serv "  << (serv) << "\n" );
754
    LOGDEB2("Netconcli::openconn: host " << host << ", serv " << serv << "\n");
735
755
736
    if (host[0]  != '/') {
756
    if (host[0]  != '/') {
737
        struct servent *sp;
757
        struct servent *sp;
738
        if ((sp = getservbyname(serv, "tcp")) == 0) {
758
        if ((sp = getservbyname(serv, "tcp")) == 0) {
739
            LOGERR("NetconCli::openconn: getservbyname failed for "  << (serv) << "\n" );
759
            LOGERR("NetconCli::openconn: getservbyname failed for " << serv 
760
                   << "\n");
740
            return -1;
761
            return -1;
741
        }
762
        }
742
        // Callee expects the port number in host byte order
763
        // Callee expects the port number in host byte order
743
        return openconn(host, ntohs(sp->s_port), timeo);
764
        return openconn(host, ntohs(sp->s_port), timeo);
744
    } else {
765
    } else {
...
...
747
}
768
}
748
769
749
770
750
int NetconCli::setconn(int fd)
771
int NetconCli::setconn(int fd)
751
{
772
{
752
    LOGDEB2("Netconcli::setconn: fd "  << (fd) << "\n" );
773
    LOGDEB2("Netconcli::setconn: fd " << fd << "\n");
753
    closeconn();
774
    closeconn();
754
775
755
    m_fd = fd;
776
    m_fd = fd;
756
    m_ownfd = false;
777
    m_ownfd = false;
757
    setpeer("");
778
    setpeer("");
...
...
787
int NetconServLis::openservice(const char *serv, int backlog)
808
int NetconServLis::openservice(const char *serv, int backlog)
788
{
809
{
789
    int port;
810
    int port;
790
    struct servent  *servp;
811
    struct servent  *servp;
791
    if (!serv) {
812
    if (!serv) {
792
        LOGERR("NetconServLis::openservice: null serv??\n" );
813
        LOGERR("NetconServLis::openservice: null serv??\n");
793
        return -1;
814
        return -1;
794
    }
815
    }
795
    LOGDEB1("NetconServLis::openservice: serv "  << (serv) << "\n" );
816
    LOGDEB1("NetconServLis::openservice: serv " << serv << "\n");
796
#ifdef NETCON_ACCESSCONTROL
817
#ifdef NETCON_ACCESSCONTROL
797
    if (initperms(serv) < 0) {
818
    if (initperms(serv) < 0) {
798
        return -1;
819
        return -1;
799
    }
820
    }
800
#endif
821
#endif
801
822
802
    m_serv = serv;
823
    m_serv = serv;
803
    if (serv[0] != '/') {
824
    if (serv[0] != '/') {
804
        if ((servp = getservbyname(serv, "tcp")) == 0) {
825
        if ((servp = getservbyname(serv, "tcp")) == 0) {
805
            LOGERR("NetconServLis::openservice: getservbyname failed for "  << (serv) << "\n" );
826
            LOGERR("NetconServLis::openservice: getservbyname failed for " << 
827
                   serv << "\n");
806
            return -1;
828
            return -1;
807
        }
829
        }
808
        port = (int)ntohs((short)servp->s_port);
830
        port = (int)ntohs((short)servp->s_port);
809
        return openservice(port, backlog);
831
        return openservice(port, backlog);
810
    } else {
832
    } else {
811
        if (strlen(serv) > UNIX_PATH_MAX - 1) {
833
        if (strlen(serv) > UNIX_PATH_MAX - 1) {
812
            LOGERR("NetconServLis::openservice: too long for AF_UNIX: "  << (serv) << "\n" );
834
            LOGERR("NetconServLis::openservice: too long for AF_UNIX: " << 
835
                   serv << "\n");
813
            return -1;
836
            return -1;
814
        }
837
        }
815
        int ret = -1;
838
        int ret = -1;
816
        struct sockaddr_un  addr;
839
        struct sockaddr_un  addr;
817
        if ((m_fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
840
        if ((m_fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
...
...
829
        if (listen(m_fd, backlog) < 0) {
852
        if (listen(m_fd, backlog) < 0) {
830
            LOGSYSERR("NetconServLis", "listen", "");
853
            LOGSYSERR("NetconServLis", "listen", "");
831
            goto out;
854
            goto out;
832
        }
855
        }
833
856
834
        LOGDEB1("NetconServLis::openservice: service opened ok\n" );
857
        LOGDEB1("NetconServLis::openservice: service opened ok\n");
835
        ret = 0;
858
        ret = 0;
836
out:
859
out:
837
        if (ret < 0 && m_fd >= 0) {
860
        if (ret < 0 && m_fd >= 0) {
838
            close(m_fd);
861
            close(m_fd);
839
            m_fd = -1;
862
            m_fd = -1;
...
...
843
}
866
}
844
867
845
// Port is a natural host integer value
868
// Port is a natural host integer value
846
int NetconServLis::openservice(int port, int backlog)
869
int NetconServLis::openservice(int port, int backlog)
847
{
870
{
848
    LOGDEB1("NetconServLis::openservice: port "  << (port) << "\n" );
871
    LOGDEB1("NetconServLis::openservice: port " << port << "\n");
849
#ifdef NETCON_ACCESSCONTROL
872
#ifdef NETCON_ACCESSCONTROL
850
    if (initperms(port) < 0) {
873
    if (initperms(port) < 0) {
851
        return -1;
874
        return -1;
852
    }
875
    }
853
#endif
876
#endif
...
...
872
    if (listen(m_fd, backlog) < 0) {
895
    if (listen(m_fd, backlog) < 0) {
873
        LOGSYSERR("NetconServLis", "listen", "");
896
        LOGSYSERR("NetconServLis", "listen", "");
874
        goto out;
897
        goto out;
875
    }
898
    }
876
899
877
    LOGDEB1("NetconServLis::openservice: service opened ok\n" );
900
    LOGDEB1("NetconServLis::openservice: service opened ok\n");
878
    ret = 0;
901
    ret = 0;
879
out:
902
out:
880
    if (ret < 0 && m_fd >= 0) {
903
    if (ret < 0 && m_fd >= 0) {
881
        close(m_fd);
904
        close(m_fd);
882
        m_fd = -1;
905
        m_fd = -1;
...
...
902
    if (permsinit) {
925
    if (permsinit) {
903
        return 0;
926
        return 0;
904
    }
927
    }
905
928
906
    if (serv == 0 || *serv == 0 || strlen(serv) > 80) {
929
    if (serv == 0 || *serv == 0 || strlen(serv) > 80) {
907
        LOGERR("NetconServLis::initperms: bad service name "  << (serv) << "\n" );
930
        LOGERR("NetconServLis::initperms: bad service name " << serv << "\n");
908
        return -1;
931
        return -1;
909
    }
932
    }
910
933
911
    char keyname[100];
934
    char keyname[100];
912
    sprintf(keyname, "%s_okaddrs", serv);
935
    sprintf(keyname, "%s_okaddrs", serv);
913
    if (genparams->getparam(keyname, &okaddrs, 1) < 0) {
936
    if (genparams->getparam(keyname, &okaddrs, 1) < 0) {
914
        serv = "default";
937
        serv = "default";
915
        sprintf(keyname, "%s_okaddrs", serv);
938
        sprintf(keyname, "%s_okaddrs", serv);
916
        if (genparams->getparam(keyname, &okaddrs) < 0) {
939
        if (genparams->getparam(keyname, &okaddrs) < 0) {
917
            LOGERR("NetconServLis::initperms: no okaddrs found in config file\n" );
940
            LOGERR("NetconServLis::initperms: no okaddrs found in config file\n");
918
            return -1;
941
            return -1;
919
        }
942
        }
920
    }
943
    }
921
    sprintf(keyname, "%s_okmasks", serv);
944
    sprintf(keyname, "%s_okmasks", serv);
922
    if (genparams->getparam(keyname, &okmasks)) {
945
    if (genparams->getparam(keyname, &okmasks)) {
923
        LOGERR("NetconServLis::initperms: okmasks not found\n" );
946
        LOGERR("NetconServLis::initperms: okmasks not found\n");
924
        return -1;
947
        return -1;
925
    }
948
    }
926
    if (okaddrs.len == 0 || okmasks.len == 0) {
949
    if (okaddrs.len == 0 || okmasks.len == 0) {
927
        LOGERR("NetconServLis::initperms: len 0 for okmasks or okaddrs\n" );
950
        LOGERR("NetconServLis::initperms: len 0 for okmasks or okaddrs\n");
928
        return -1;
951
        return -1;
929
    }
952
    }
930
953
931
    permsinit = 1;
954
    permsinit = 1;
932
    return 0;
955
    return 0;
...
...
944
}
967
}
945
968
946
NetconServCon *
969
NetconServCon *
947
NetconServLis::accept(int timeo)
970
NetconServLis::accept(int timeo)
948
{
971
{
949
    LOGDEB("NetconServLis::accept\n" );
972
    LOGDEB("NetconServLis::accept\n");
950
973
951
    if (timeo > 0) {
974
    if (timeo > 0) {
952
        int ret = select1(m_fd, timeo);
975
        int ret = select1(m_fd, timeo);
953
        if (ret == 0) {
976
        if (ret == 0) {
954
            LOGDEB2("NetconServLis::accept timed out\n" );
977
            LOGDEB2("NetconServLis::accept timed out\n");
955
            m_didtimo = 1;
978
            m_didtimo = 1;
956
            return 0;
979
            return 0;
957
        }
980
        }
958
        if (ret < 0) {
981
        if (ret < 0) {
959
            LOGSYSERR("NetconServLis::accept", "select", "");
982
            LOGSYSERR("NetconServLis::accept", "select", "");
...
...
985
        }
1008
        }
986
    }
1009
    }
987
1010
988
    con = new NetconServCon(newfd);
1011
    con = new NetconServCon(newfd);
989
    if (con == 0) {
1012
    if (con == 0) {
990
        LOGERR("NetconServLis::accept: new NetconServCon failed\n" );
1013
        LOGERR("NetconServLis::accept: new NetconServCon failed\n");
991
        goto out;
1014
        goto out;
992
    }
1015
    }
993
1016
994
    // Retrieve peer's host name. Errors are non fatal
1017
    // Retrieve peer's host name. Errors are non fatal
995
    if (m_serv.empty() || m_serv[0] != '/') {
1018
    if (m_serv.empty() || m_serv[0] != '/') {
996
        struct hostent *hp;
1019
        struct hostent *hp;
997
        if ((hp = gethostbyaddr((char *) & (who.sin_addr),
1020
        if ((hp = gethostbyaddr((char *) & (who.sin_addr),
998
                                sizeof(struct in_addr), AF_INET)) == 0) {
1021
                                sizeof(struct in_addr), AF_INET)) == 0) {
999
            LOGERR("NetconServLis::accept: gethostbyaddr failed for addr 0x"  << (who.sin_addr.s_addr) << "\n" );
1022
            LOGERR("NetconServLis::accept: gethostbyaddr failed for addr 0x" <<
1023
                   who.sin_addr.s_addr << "\n");
1000
            con->setpeer(inet_ntoa(who.sin_addr));
1024
            con->setpeer(inet_ntoa(who.sin_addr));
1001
        } else {
1025
        } else {
1002
            con->setpeer(hp->h_name);
1026
            con->setpeer(hp->h_name);
1003
        }
1027
        }
1004
    } else {
1028
    } else {
1005
        con->setpeer(m_serv.c_str());
1029
        con->setpeer(m_serv.c_str());
1006
    }
1030
    }
1007
1031
1008
    LOGDEB2("NetconServLis::accept: setting keepalive\n" );
1032
    LOGDEB2("NetconServLis::accept: setting keepalive\n");
1009
    if (setsockopt(newfd, SOL_SOCKET, SO_KEEPALIVE,
1033
    if (setsockopt(newfd, SOL_SOCKET, SO_KEEPALIVE,
1010
                   (char *)&one, sizeof(one)) < 0) {
1034
                   (char *)&one, sizeof(one)) < 0) {
1011
        LOGSYSERR("NetconServLis::accept", "setsockopt", "KEEPALIVE");
1035
        LOGSYSERR("NetconServLis::accept", "setsockopt", "KEEPALIVE");
1012
    }
1036
    }
1013
    LOGDEB2("NetconServLis::accept: got connect from "  << (con->getpeer()) << "\n" );
1037
    LOGDEB2("NetconServLis::accept: got connect from " << con->getpeer() << 
1038
            "\n");
1014
1039
1015
out:
1040
out:
1016
    if (con == 0 && newfd >= 0) {
1041
    if (con == 0 && newfd >= 0) {
1017
        close(newfd);
1042
        close(newfd);
1018
    }
1043
    }
...
...
1030
1055
1031
    struct sockaddr *addr = (struct sockaddr *)cl;
1056
    struct sockaddr *addr = (struct sockaddr *)cl;
1032
    unsigned long ip_addr;
1057
    unsigned long ip_addr;
1033
1058
1034
    if (addr->sa_family != AF_INET) {
1059
    if (addr->sa_family != AF_INET) {
1035
        LOGERR("NetconServLis::checkperms: connection from non-INET addr !\n" );
1060
        LOGERR("NetconServLis::checkperms: connection from non-INET addr !\n");
1036
        return -1;
1061
        return -1;
1037
    }
1062
    }
1038
1063
1039
    ip_addr = ntohl(((struct sockaddr_in *)addr)->sin_addr.s_addr);
1064
    ip_addr = ntohl(((struct sockaddr_in *)addr)->sin_addr.s_addr);
1040
    LOGDEB2("checkperms: ip_addr: 0x"  << (ip_addr) << "\n" );
1065
    LOGDEB2("checkperms: ip_addr: 0x" << ip_addr << "\n");
1041
    for (int i = 0; i < okaddrs.len; i++) {
1066
    for (int i = 0; i < okaddrs.len; i++) {
1042
        unsigned int mask;
1067
        unsigned int mask;
1043
        if (i < okmasks.len) {
1068
        if (i < okmasks.len) {
1044
            mask = okmasks.intarray[i];
1069
            mask = okmasks.intarray[i];
1045
        } else {
1070
        } else {
1046
            mask = okmasks.intarray[okmasks.len - 1];
1071
            mask = okmasks.intarray[okmasks.len - 1];
1047
        }
1072
        }
1048
        LOGDEB2("checkperms: trying okaddr 0x"  << (okaddrs.intarray[i]) << ", mask 0x"  << (mask) << "\n" );
1073
        LOGDEB2("checkperms: trying okaddr 0x" << okaddrs.intarray[i] <<
1074
                ", mask 0x" << mask << "\n");
1049
        if ((ip_addr & mask) == (okaddrs.intarray[i] & mask)) {
1075
        if ((ip_addr & mask) == (okaddrs.intarray[i] & mask)) {
1050
            return (0);
1076
            return (0);
1051
        }
1077
        }
1052
    }
1078
    }
1053
    LOGERR("NetconServLis::checkperm: connection from bad address 0x"  << (ip_addr) << "\n" );
1079
    LOGERR("NetconServLis::checkperm: connection from bad address 0x" <<
1080
           ip_addr << "\n");
1054
    return -1;
1081
    return -1;
1055
}
1082
}
1056
#endif /* NETCON_ACCESSCONTROL */
1083
#endif /* NETCON_ACCESSCONTROL */