Switch to unified view

a/src/netcon.cpp b/src/netcon.cpp
...
...
29
#endif // _AIX
29
#endif // _AIX
30
30
31
#include <unistd.h>
31
#include <unistd.h>
32
#include <fcntl.h>
32
#include <fcntl.h>
33
#include <sys/time.h>
33
#include <sys/time.h>
34
35
#include <sys/socket.h>
34
#include <sys/socket.h>
35
#include <sys/un.h>
36
#include <netinet/in.h>
36
#include <netinet/in.h>
37
#include <netinet/tcp.h>
37
#include <netinet/tcp.h>
38
#include <arpa/inet.h>
38
#include <arpa/inet.h>
39
#include <netdb.h>
39
#include <netdb.h>
40
40
...
...
59
59
60
#include "netcon.h"
60
#include "netcon.h"
61
61
62
#ifndef SOCKLEN_T
62
#ifndef SOCKLEN_T
63
#define SOCKLEN_T socklen_t
63
#define SOCKLEN_T socklen_t
64
#endif
65
66
// Size of path buffer in sockaddr_un (AF_UNIX socket
67
// addr). Mysteriously it's 108 (explicit value) under linux, no
68
// define accessible. Let's take a little margin as it appears that
69
// some systems use 92. I believe we could also malloc a variable size
70
// struct but why bother.
71
#ifndef UNIX_PATH_MAX
72
#define UNIX_PATH_MAX 90
64
#endif
73
#endif
65
74
66
// Need &one, &zero for setsockopt...
75
// Need &one, &zero for setsockopt...
67
static const int one = 1;
76
static const int one = 1;
68
static const int zero = 0;
77
static const int zero = 0;
...
...
613
    int ret = -1;
622
    int ret = -1;
614
    LOGDEB2(("Netconcli::openconn: host %s, port %d\n", host, port));
623
    LOGDEB2(("Netconcli::openconn: host %s, port %d\n", host, port));
615
624
616
    closeconn();
625
    closeconn();
617
626
627
    struct sockaddr *saddr;
628
    socklen_t addrsize;
629
618
    struct sockaddr_in saddr;
630
    struct sockaddr_in ip_addr;
631
    struct sockaddr_un unix_addr;
632
    if (host[0] != '/') {
619
    memset(&saddr, 0, sizeof(saddr));
633
        memset(&ip_addr, 0, sizeof(ip_addr));
620
    saddr.sin_family = AF_INET;
634
        ip_addr.sin_family = AF_INET;
621
    saddr.sin_port = htons(port);
635
        ip_addr.sin_port = htons(port);
622
636
623
    // Server name may be host name or IP address
637
        // Server name may be host name or IP address
624
    int addr;
638
        int addr;
625
    if ((addr = inet_addr(host)) != -1) {
639
        if ((addr = inet_addr(host)) != -1) {
626
        memcpy(&saddr.sin_addr, &addr, sizeof(addr));
640
            memcpy(&ip_addr.sin_addr, &addr, sizeof(addr));
641
        } else {
642
            struct hostent *hp;
643
            if ((hp = gethostbyname(host)) == 0) {
644
                LOGERR(("NetconCli::openconn: gethostbyname(%s) failed\n", 
645
                        host));
646
                return -1;
647
            }
648
            memcpy(&ip_addr.sin_addr, hp->h_addr, hp->h_length);
649
        }
650
651
        if ((m_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
652
            LOGSYSERR("NetconCli::openconn", "socket", "");
653
            return -1;
654
        }
655
        addrsize = sizeof(ip_addr);
656
        saddr = (sockaddr*)&ip_addr;
627
    } else {
657
    } else {
628
        struct hostent *hp;
658
        memset(&unix_addr, 0, sizeof(unix_addr));
629
        if ((hp = gethostbyname(host)) == 0) {
659
        unix_addr.sun_family = AF_UNIX;
660
        if (strlen(host) > UNIX_PATH_MAX - 1) {
630
            LOGERR(("NetconCli::openconn: gethostbyname(%s) failed\n", host));
661
            LOGERR(("NetconCli::openconn: name too long: %s\n", host));
631
            return -1;
662
            return -1;
632
        }
633
        memcpy(&saddr.sin_addr, hp->h_addr, hp->h_length);
634
    }
663
        }
664
        strcpy(unix_addr.sun_path, host);
635
665
636
    if ((m_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
666
        if ((m_fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
637
        LOGSYSERR("NetconCli::openconn", "socket", "");
667
            LOGSYSERR("NetconCli::openconn", "socket", "");
638
        return -1;
668
            return -1;
669
        }
670
        addrsize = sizeof(unix_addr);
671
        saddr = (sockaddr*)&unix_addr;
639
    }
672
    }
640
    if (timeo > 0) {
673
    if (timeo > 0) {
641
        set_nonblock(1);
674
        set_nonblock(1);
642
    }
675
    }
643
676
644
    if (connect(m_fd, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) {
677
    if (connect(m_fd, saddr, addrsize) < 0) {
645
        if (timeo > 0) {
678
        if (timeo > 0) {
646
            if (errno != EINPROGRESS) {
679
            if (errno != EINPROGRESS) {
647
                goto out;
680
                goto out;
648
            }
681
            }
649
            if (select1(m_fd, timeo, 1) == 1) {
682
            if (select1(m_fd, timeo, 1) == 1) {
...
...
674
    }
707
    }
675
    return ret;
708
    return ret;
676
}
709
}
677
710
678
// Same as previous, but get the port number from services
711
// Same as previous, but get the port number from services
679
int NetconCli::openconn(const char *host, char *serv, int timeo)
712
int NetconCli::openconn(const char *host, const char *serv, int timeo)
680
{
713
{
681
    LOGDEB2(("Netconcli::openconn: host %s, serv %s\n", host, serv));
714
    LOGDEB2(("Netconcli::openconn: host %s, serv %s\n", host, serv));
682
715
716
    if (host[0]  != '/') {
683
    struct servent *sp;
717
        struct servent *sp;
684
    if ((sp = getservbyname(serv, "tcp")) == 0) {
718
        if ((sp = getservbyname(serv, "tcp")) == 0) {
685
        LOGERR(("NetconCli::openconn: getservbyname failed for %s\n", serv));
719
            LOGERR(("NetconCli::openconn: getservbyname failed for %s\n",serv));
686
        return -1;
720
            return -1;
687
    }
721
        }
688
    // Callee expects the port number in host byte order
722
        // Callee expects the port number in host byte order
689
    return openconn(host, ntohs(sp->s_port), timeo);
723
        return openconn(host, ntohs(sp->s_port), timeo);
724
    } else {
725
        return openconn(host, (unsigned int)0, timeo);
726
    }
690
}
727
}
691
728
692
729
693
int NetconCli::setconn(int fd)
730
int NetconCli::setconn(int fd)
694
{
731
{
...
...
725
    fprintf(stderr, "Proto %s\n", servp->s_proto);
762
    fprintf(stderr, "Proto %s\n", servp->s_proto);
726
}
763
}
727
#endif
764
#endif
728
765
729
// Set up service.
766
// Set up service.
730
int NetconServLis::openservice(char *serv, int backlog)
767
int NetconServLis::openservice(const char *serv, int backlog)
731
{
768
{
732
    int port;
769
    int port;
733
    struct servent  *servp;
770
    struct servent  *servp;
771
    if (!serv) {
772
        LOGERR(("NetconServLis::openservice: null serv??\n"));
773
        return -1;
774
    }
734
    LOGDEB1(("NetconServLis::openservice: serv %s\n", serv));
775
    LOGDEB1(("NetconServLis::openservice: serv %s\n", serv));
735
#ifdef NETCON_ACCESSCONTROL
776
#ifdef NETCON_ACCESSCONTROL
736
    if (initperms(serv) < 0) {
777
    if (initperms(serv) < 0) {
737
        return -1;
778
        return -1;
738
    }
779
    }
739
#endif
780
#endif
781
782
    m_serv = serv;
783
    if (serv[0] != '/') {
740
    if ((servp = getservbyname(serv, "tcp")) == 0) {
784
        if ((servp = getservbyname(serv, "tcp")) == 0) {
741
        LOGERR(("NetconServLis::openservice: getservbyname failed for %s\n", serv));
785
            LOGERR(("NetconServLis::openservice: getservbyname failed for %s\n",
786
                    serv));
742
        return -1;
787
            return -1;
743
    }
788
        }
744
    port = (int)ntohs((short)servp->s_port);
789
        port = (int)ntohs((short)servp->s_port);
745
    return openservice(port, backlog);
790
        return openservice(port, backlog);
791
    } else {
792
        if (strlen(serv) > UNIX_PATH_MAX - 1) {
793
            LOGERR(("NetconServLis::openservice: too long for AF_UNIX: %s\n",
794
                    serv));
795
            return -1;
796
        }
797
        int ret = -1;
798
        struct sockaddr_un  addr;
799
        if ((m_fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
800
            LOGSYSERR("NetconServLis", "socket", "");
801
            return -1;
802
        }
803
        memset(&addr, 0, sizeof(addr));
804
        addr.sun_family = AF_UNIX;
805
        strcpy(addr.sun_path, serv);
806
807
        if (::bind(m_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
808
            LOGSYSERR("NetconServLis", "bind", "");
809
            goto out;
810
        }
811
        if (listen(m_fd, backlog) < 0) {
812
            LOGSYSERR("NetconServLis", "listen", "");
813
            goto out;
814
        }
815
816
        LOGDEB1(("NetconServLis::openservice: service opened ok\n"));
817
        ret = 0;
818
    out:
819
        if (ret < 0 && m_fd >= 0) {
820
            close(m_fd);
821
            m_fd = -1;
822
        }
823
        return ret;
824
    }
746
}
825
}
747
826
748
// Port is a natural host integer value
827
// Port is a natural host integer value
749
int NetconServLis::openservice(int port, int backlog)
828
int NetconServLis::openservice(int port, int backlog)
750
{
829
{
...
...
798
    sprintf(sport, "%d", port);
877
    sprintf(sport, "%d", port);
799
    return initperms(sport);
878
    return initperms(sport);
800
}
879
}
801
880
802
// Get authorized address lists from parameter file. This is disabled for now
881
// Get authorized address lists from parameter file. This is disabled for now
803
int NetconServLis::initperms(char *serv)
882
int NetconServLis::initperms(const char *serv)
804
{
883
{
805
    if (permsinit) {
884
    if (permsinit) {
806
        return 0;
885
        return 0;
807
    }
886
    }
808
887
...
...
866
    m_didtimo = 0;
945
    m_didtimo = 0;
867
946
868
    NetconServCon *con = 0;
947
    NetconServCon *con = 0;
869
    int newfd = -1;
948
    int newfd = -1;
870
    struct sockaddr_in who;
949
    struct sockaddr_in who;
950
    struct sockaddr_un uwho;
951
    if (m_serv.empty() || m_serv[0] != '/') {
871
    SOCKLEN_T clilen = (SOCKLEN_T)sizeof(who);
952
        SOCKLEN_T clilen = (SOCKLEN_T)sizeof(who);
872
    if ((newfd = ::accept(m_fd, (struct sockaddr *)&who, &clilen)) < 0) {
953
        if ((newfd = ::accept(m_fd, (struct sockaddr *)&who, &clilen)) < 0) {
873
        LOGSYSERR("NetconServCon::accept", "accept", "");
954
            LOGSYSERR("NetconServCon::accept", "accept", "");
874
        goto out;
955
            goto out;
875
    }
956
        }
876
#ifdef NETCON_ACCESSCONTROL
957
#ifdef NETCON_ACCESSCONTROL
877
    if (checkperms(&who, clilen) < 0) {
958
        if (checkperms(&who, clilen) < 0) {
878
        goto out;
959
            goto out;
879
    }
960
        }
880
#endif
961
#endif
962
    } else {
963
        SOCKLEN_T clilen = (SOCKLEN_T)sizeof(uwho);
964
        if ((newfd = ::accept(m_fd, (struct sockaddr *)&uwho, &clilen)) < 0) {
965
            LOGSYSERR("NetconServCon::accept", "accept", "");
966
            goto out;
967
        }
968
    }
969
881
    con = new NetconServCon(newfd);
970
    con = new NetconServCon(newfd);
882
    if (con == 0) {
971
    if (con == 0) {
883
        LOGERR(("NetconServLis::accept: new NetconServCon failed\n"));
972
        LOGERR(("NetconServLis::accept: new NetconServCon failed\n"));
884
        goto out;
973
        goto out;
885
    }
974
    }
975
886
    // Retrieve peer's host name. Errors are non fatal
976
    // Retrieve peer's host name. Errors are non fatal
977
    if (m_serv.empty() || m_serv[0] != '/') {
887
    struct hostent *hp;
978
        struct hostent *hp;
888
    if ((hp = gethostbyaddr((char *) & (who.sin_addr), sizeof(struct in_addr),
979
        if ((hp = gethostbyaddr((char *) & (who.sin_addr), 
889
                            AF_INET)) == 0) {
980
                                sizeof(struct in_addr), AF_INET)) == 0) {
890
        LOGERR(("NetconServLis::accept: gethostbyaddr failed for addr 0x%lx\n",
981
            LOGERR(("NetconServLis::accept: gethostbyaddr failed for addr 0x%lx\n",
891
                who.sin_addr.s_addr));
982
                who.sin_addr.s_addr));
892
        con->setpeer(inet_ntoa(who.sin_addr));
983
            con->setpeer(inet_ntoa(who.sin_addr));
984
        } else {
985
            con->setpeer(hp->h_name);
986
        }
893
    } else {
987
    } else {
894
        con->setpeer(hp->h_name);
988
        con->setpeer(m_serv.c_str());
895
    }
989
    }
990
896
    LOGDEB2(("NetconServLis::accept: setting keepalive\n"));
991
    LOGDEB2(("NetconServLis::accept: setting keepalive\n"));
897
    if (setsockopt(newfd, SOL_SOCKET, SO_KEEPALIVE,
992
    if (setsockopt(newfd, SOL_SOCKET, SO_KEEPALIVE,
898
                   (char *)&one, sizeof(one)) < 0) {
993
                   (char *)&one, sizeof(one)) < 0) {
899
        LOGSYSERR("NetconServLis::accept", "setsockopt", "KEEPALIVE");
994
        LOGSYSERR("NetconServLis::accept", "setsockopt", "KEEPALIVE");
900
    }
995
    }
...
...
1104
    NetconP con(clicon);
1199
    NetconP con(clicon);
1105
    if (!con) {
1200
    if (!con) {
1106
        fprintf(stderr, "new NetconCli failed\n");
1201
        fprintf(stderr, "new NetconCli failed\n");
1107
        return 1;
1202
        return 1;
1108
    }
1203
    }
1109
    if (clicon->openconn(host, serv) < 0) {
1204
    int port = atoi(serv);
1205
    int ret = port > 0 ? 
1206
        clicon->openconn(host, port) : clicon->openconn(host, serv);
1207
    if (ret < 0) {
1110
        fprintf(stderr, "openconn(%s, %s) failed\n", host, serv);
1208
        fprintf(stderr, "openconn(%s, %s) failed\n", host, serv);
1111
        return 1;
1209
        return 1;
1112
    }
1210
    }
1113
    fprintf(stderr, "openconn(%s, %s) ok\n", host, serv);
1211
    fprintf(stderr, "openconn(%s, %s) ok\n", host, serv);
1114
#ifdef NOSELLOOP
1212
#ifdef NOSELLOOP
...
...
1133
    shared_ptr<CliNetconWorker> worker = make_shared<CliNetconWorker>();
1231
    shared_ptr<CliNetconWorker> worker = make_shared<CliNetconWorker>();
1134
    clicon->setcallback(worker);
1232
    clicon->setcallback(worker);
1135
    SelectLoop myloop;
1233
    SelectLoop myloop;
1136
    myloop.addselcon(con, Netcon::NETCONPOLL_WRITE);
1234
    myloop.addselcon(con, Netcon::NETCONPOLL_WRITE);
1137
    fprintf(stderr, "client ready\n");
1235
    fprintf(stderr, "client ready\n");
1138
    int ret = myloop.doLoop();
1236
    ret = myloop.doLoop();
1139
    if (ret < 0) {
1237
    if (ret < 0) {
1140
        fprintf(stderr, "selectloop failed\n");
1238
        fprintf(stderr, "selectloop failed\n");
1141
        exit(1);
1239
        exit(1);
1142
    }
1240
    }
1143
    fprintf(stderr, "selectloop returned %d\n", ret);
1241
    fprintf(stderr, "selectloop returned %d\n", ret);
...
...
1235
    sigemptyset(&sa.sa_mask);
1333
    sigemptyset(&sa.sa_mask);
1236
    sigaction(SIGINT, &sa, 0);
1334
    sigaction(SIGINT, &sa, 0);
1237
    sigaction(SIGQUIT, &sa, 0);
1335
    sigaction(SIGQUIT, &sa, 0);
1238
    sigaction(SIGTERM, &sa, 0);
1336
    sigaction(SIGTERM, &sa, 0);
1239
1337
1240
    if (servlis->openservice(serv) < 0) {
1338
    int port = atoi(serv);
1339
    int ret = port > 0 ? 
1340
        servlis->openservice(port) : servlis->openservice(serv);
1341
    if (ret < 0) {
1241
        fprintf(stderr, "openservice(%s) failed\n", serv);
1342
        fprintf(stderr, "openservice(%s) failed\n", serv);
1242
        return 1;
1343
        return 1;
1243
    }
1344
    }
1244
    myloop.addselcon(lis, Netcon::NETCONPOLL_READ);
1345
    myloop.addselcon(lis, Netcon::NETCONPOLL_READ);
1245
    fprintf(stderr, "openservice(%s) Ok\n", serv);
1346
    fprintf(stderr, "openservice(%s) Ok\n", serv);