示例#1
0
		int handle() {
			nlSystemUseChangeLock.startReadAccess();
			int ret = -1;
			if(bNetworkInited) { // only do that if we have the network system still up
				// this should already close the socket but not lock other parts in HawkNL
				nlPrepareClose(sock);
				// hopefully this does not block anymore
				ret = (nlClose(sock) != NL_FALSE) ? 0 : -1;
			}
			nlSystemUseChangeLock.endReadAccess();
			return ret;
		}
示例#2
0
文件: test.c 项目: tsky1971/hawknl
int main(int argc, char **argv)
{
    NLboolean   isserver = NL_FALSE;
    NLsocket    serversock;
    NLsocket    clientsock;
    NLaddress   addr;
    NLbyte      server[] = "127.0.0.1:25000";
    NLenum      type = NL_UNRELIABLE; /* Change this to NL_RELIABLE for reliable connection */
    NLbyte      string[NL_MAX_STRING_LENGTH];

    if(!nlInit())
        printErrorExit();

    printf("nlGetString(NL_VERSION) = %s\n\n", nlGetString(NL_VERSION));
    printf("nlGetString(NL_NETWORK_TYPES) = %s\n\n", nlGetString(NL_NETWORK_TYPES));

    if(!nlSelectNetwork(NL_IP))
        printErrorExit();

    if(argc > 1)
    {
        if(!strcmp(argv[1], "-s")) /* server mode */
            isserver = NL_TRUE;
    }

    if(isserver)
    {
        /* create a server socket */
        serversock = nlOpen(25000, type); /* just a random port number ;) */

        if(serversock == NL_INVALID)
            printErrorExit();

        if(!nlListen(serversock))       /* let's listen on this socket */
        {
            nlClose(serversock);
            printErrorExit();
        }
        nlGetLocalAddr(serversock, &addr);
        printf("Server address is %s\n", nlAddrToString(&addr, string));
        mainServerLoop(serversock);
    }
    else
    {
        /* create a client socket */
        clientsock = nlOpen(0, type); /* let the system assign the port number */
        nlGetLocalAddr(clientsock, &addr);
        printf("our address is %s\n", nlAddrToString(&addr, string));

        if(clientsock == NL_INVALID)
            printErrorExit();
        /* create the NLaddress */
        nlStringToAddr(server, &addr);
        printf("Address is %s\n", nlAddrToString(&addr, string));
        /* now connect */
        if(!nlConnect(clientsock, &addr))
        {
            nlClose(clientsock);
            printErrorExit();
        }
        mainClientLoop(clientsock);
    }

    nlShutdown();
    return 0;
}
示例#3
0
/**
 * nlComm:
 * @nlmsg: pointer to netlink message
 * @respbuf: pointer to pointer where response buffer will be allocated
 * @respbuflen: pointer to integer holding the size of the response buffer
 *      on return of the function.
 * @nl_pid: the pid of the process to talk to, i.e., pid = 0 for kernel
 *
 * Send the given message to the netlink layer and receive response.
 * Returns 0 on success, -1 on error. In case of error, no response
 * buffer will be returned.
 */
static
int nlComm(struct nlmsghdr *nlmsg,
           char **respbuf, unsigned int *respbuflen,
           int nl_pid)
{
    int rc = 0;
    struct sockaddr_nl nladdr = {
            .nl_family = AF_NETLINK,
            .nl_pid    = nl_pid,
            .nl_groups = 0,
    };
    int rcvChunkSize = 1024; // expecting less than that
    int rcvoffset = 0;
    ssize_t nbytes;
    struct timeval tv = {
        .tv_sec = NETLINK_ACK_TIMEOUT_S,
    };
    fd_set readfds;
    int fd = nlOpen();
    int n;

    if (fd < 0)
        return -1;

    nlmsg->nlmsg_pid = getpid();
    nlmsg->nlmsg_flags |= NLM_F_ACK;

    nbytes = sendto(fd, (void *)nlmsg, nlmsg->nlmsg_len, 0,
                    (struct sockaddr *)&nladdr, sizeof(nladdr));
    if (nbytes < 0) {
        virReportSystemError(errno,
                             "%s", _("cannot send to netlink socket"));
        rc = -1;
        goto err_exit;
    }

    FD_ZERO(&readfds);
    FD_SET(fd, &readfds);

    n = select(fd + 1, &readfds, NULL, NULL, &tv);
    if (n <= 0) {
        if (n < 0)
            virReportSystemError(errno, "%s",
                                 _("error in select call"));
        if (n == 0)
            virReportSystemError(ETIMEDOUT, "%s",
                                 _("no valid netlink response was received"));
        rc = -1;
        goto err_exit;
    }

    while (1) {
        if (VIR_REALLOC_N(*respbuf, rcvoffset+rcvChunkSize) < 0) {
            virReportOOMError();
            rc = -1;
            goto err_exit;
        }

        socklen_t addrlen = sizeof(nladdr);
        nbytes = recvfrom(fd, &((*respbuf)[rcvoffset]), rcvChunkSize, 0,
                          (struct sockaddr *)&nladdr, &addrlen);
        if (nbytes < 0) {
            if (errno == EAGAIN || errno == EINTR)
                continue;
            virReportSystemError(errno, "%s",
                                 _("error receiving from netlink socket"));
            rc = -1;
            goto err_exit;
        }
        rcvoffset += nbytes;
        break;
    }
    *respbuflen = rcvoffset;

err_exit:
    if (rc == -1) {
        VIR_FREE(*respbuf);
        *respbuf = NULL;
        *respbuflen = 0;
    }

    nlClose(fd);
    return rc;
}


static struct rtattr *
rtattrCreate(char *buffer, int bufsize, int type,
             const void *data, int datalen)
{
    struct rtattr *r = (struct rtattr *)buffer;
    r->rta_type = type;
    r->rta_len  = RTA_LENGTH(datalen);
    if (r->rta_len > bufsize)
        return NULL;
    memcpy(RTA_DATA(r), data, datalen);
    return r;
}


static void
nlInit(struct nlmsghdr *nlm, int flags, int type)
{
    nlm->nlmsg_len = NLMSG_LENGTH(0);
    nlm->nlmsg_flags = flags;
    nlm->nlmsg_type = type;
}