Example #1
0
/**
 * See pcsl_network.h for definition.
 */
int pcsl_network_getremoteport(
	void *handle,
	int *pPortNumber)
{
    int status;
    int peerPort;
    struct sockaddr_in sa;
    socklen_t saLen = sizeof (sa);
    int fd = na_get_fd(handle);

    status = getpeername(fd, (struct sockaddr*)&sa, &saLen);
    lastError = errno;

    if (status < 0) {
        return PCSL_NET_IOERROR;
    }

    /*
     * DEBUG: 
     * printf("get ip number family=%x port=%d addr=%s\n",  
     *        sa.sin_family, sa.sin_port, inet_ntoa(sa.sin_addr) );
     */

    peerPort =  (int) ntohs(sa.sin_port);
    *pPortNumber = peerPort;

    return PCSL_NET_SUCCESS;
}
/**
 * See pcsl_socket.h for definition.
 */
int pcsl_socket_getremoteaddr(
    void *handle,
    char *pAddress)
{
    int status;
    struct sockaddr_in sa;
    socklen_t saLen = sizeof (sa);
    int fd = na_get_fd(handle);

    sa.sin_family = AF_INET;

    status = getpeername(fd, (struct sockaddr*)&sa, &saLen);
    lastError = errno;

    if (status < 0) {
        return PCSL_NET_IOERROR;
    }

    /*
     * DEBUG:
     * printf("get ip number port=%d addr=%s\n",
     *        sa.sin_port, inet_ntoa(sa.sin_addr) );
     */

    strcpy(pAddress, (char *)inet_ntoa(sa.sin_addr));

    return PCSL_NET_SUCCESS;
}
Example #3
0
/**
 * See pcsl_socket.h for definition.
 */
int pcsl_network_setsockopt(
	void *handle,
	int flag,
	int optval)
{
    int    level = SOL_SOCKET;
    int    optsize =  sizeof(optval);
    int    optname;
    struct linger lbuf ;
    void * opttarget = (void *) & optval ;

    int fd = na_get_fd(handle);

    switch (flag) { 
    case 0: /* DELAY */
        level = IPPROTO_TCP;
        optname = TCP_NODELAY;
        break;
    case 1: /* LINGER */
        opttarget = (void *) &lbuf ;
        optsize = sizeof (struct linger);
        optname = SO_LINGER;
        if (optval == 0) {
            lbuf.l_onoff = 0;
            lbuf.l_linger = 0;
        } else {
            lbuf.l_onoff = 1;
            lbuf.l_linger = optval;
        }           
        break;
    case 2: /* KEEPALIVE */
        optname = SO_KEEPALIVE;
        break;
    case 3: /* RCVBUF */
        optname = SO_RCVBUF;
        break;
    case 4: /* SNDBUF */
        optname = SO_SNDBUF;
        break;
    default:
        return PCSL_NET_INVALID;
    }

    /*
     * DEBUG: 
     * printf("setSockopt option=%d value=%d\n", optname, optval);
     */

    if (setsockopt(fd, level,  optname, opttarget, optsize) != 0) {
        lastError = errno;
        /*
         * DEBUG: 
         * printf("setsockopt errno=%d\n", errno);
         */
        return PCSL_NET_INVALID;
    }

    lastError = 0;
    return PCSL_NET_SUCCESS;
}
/**
 * See pcsl_socket.h for definition.
 */
int pcsl_socket_open_finish(
    void *handle,
    void *context)
{
    int err;
    socklen_t err_size = sizeof(err);

    int fd = na_get_fd(handle);

    int status = getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &err_size);
    /*
     * DEBUG:
     * printf( "pcsl_socket_open_finish::handle=%d err=%d\n", fd, err);
     */

    lastError = err;

    if (err == 0) {
        na_unregister_for_write(handle);
        /*
         * DEBUG:
         * printf("opened fd: %d\n", fd);
         */
        return PCSL_NET_SUCCESS;
    } else {
        na_destroy(handle);
        close(fd);
        return PCSL_NET_IOERROR;
    }
}
/**
 * See pcsl_socket.h for definition.
 *
 * Note that this function NEVER returns PCSL_NET_WOULDBLOCK. Therefore, the
 * finish() function should never be called and does nothing.
 */
int pcsl_socket_close_start(
    void *handle,
    void **pContext)
{
    int status;
    int fd = na_get_fd(handle);
    /*
     * DEBUG:
     * printf("closing fd: %d\n", fd);
     */

    status = close(fd);
    lastError = errno;

    /*
     * If PCSL_NET_WOULDBLOCk is detected, the notification adapter must not be
     * destroyed.
     */
    na_destroy(handle);

    if (status == 0) {
        return PCSL_NET_SUCCESS;
    }

    return PCSL_NET_IOERROR;
}
Example #6
0
/**
 * See pcsl_socket.h for definition.
 */
int pcsl_network_getsockopt(
	void *handle,
	int flag,
	int *pOptval)
{
    int level = SOL_SOCKET;
    int optname;
    socklen_t optsize = sizeof(optname);
    struct linger lbuf ;
    void * opttarget = (void *) pOptval ;

    int fd = na_get_fd(handle);

    switch (flag) { 
    case 0: /* DELAY */
        level = IPPROTO_TCP;
        optname = TCP_NODELAY;
        break;
    case 1: /* LINGER */
        opttarget = (void *) &lbuf ;
        optsize = sizeof (struct linger);
        optname = SO_LINGER;
        break;
    case 2: /* KEEPALIVE */
        optname = SO_KEEPALIVE;
        break;
    case 3: /* RCVBUF */
        optname = SO_RCVBUF;
        break;
    case 4: /* SNDBUF */
        optname = SO_SNDBUF;
        break;
    default:
        return PCSL_NET_INVALID;
    }

    if (getsockopt(fd, level,  optname, opttarget, &optsize) == 0 ) {
        lastError = 0;

        if (optname == SO_LINGER) {
            /* If linger is on return the number of seconds. */
            *pOptval = (lbuf.l_onoff == 0 ? 0 : lbuf.l_linger) ;
        }
        /*
         * DEBUG:
         * printf("getSockopt option=%d value=%d size=%d\n", 
         *	  optname, *pOptval, optsize);
         */
        return PCSL_NET_SUCCESS;
    } else {
        lastError = errno;
        /*
         * DEBUG: 
         * printf("getsockopt errno=%d option=%d level=%d\n", 
         *        errno, optname, level );
         */
        return PCSL_NET_IOERROR;
    }
}
/**
 * See pcsl_socket.h for definition.
 */
int pcsl_socket_shutdown_output(void *handle) {
    int fd = na_get_fd(handle);
    int status;

    status = shutdown(fd, 1);
    lastError = errno;

    /* Return value of shutdown() need not be checked */

    return PCSL_NET_SUCCESS;
}
/**
 * Common implementation between pcsl_socket_read_start()
 * and pcsl_socket_read_finish().
 */
static int pcsl_socket_read_common(
    void *handle,
    unsigned char *pData,
    int len,
    int *pBytesRead)
{
    int status;
    int fd;

    if (na_get_status(handle) == PCSL_NET_INTERRUPTED) {
        /*
         * VMSocket status need not be set to any value at this point
         * as the VMSocket is deleted and corresponding BSD socket is
         * also closed after emitting an interrupted IO exception
         */
        return PCSL_NET_INTERRUPTED;
    }

    fd = na_get_fd(handle);

    status = recv(fd, pData, len, 0);
    lastError = errno;


    if (SOCKET_ERROR == status) {
        if (EWOULDBLOCK == errno || EINPROGRESS == errno) {
            /*
             * DEBUG:
             * printf("read_start from : fd :%d\n", fd);
             */
            return PCSL_NET_WOULDBLOCK;
        } else if (EINTR == errno) {
            return PCSL_NET_INTERRUPTED;
        } else {
            return PCSL_NET_IOERROR;
        }
    }

    if (status == 0) {
        /*
         * DEBUG:
         * printf("Bytes read are 0\n");
         */
    }

    /*
     * DEBUG:
     * printf("read_finish from : fd :%d\n", fd);
     */
    *pBytesRead = status;
    return PCSL_NET_SUCCESS;
}
/**
 * See pcsl_socket.h for definition.
 */
int pcsl_socket_available(void *handle, int *pBytesAvailable)
{
    int fd = na_get_fd(handle);
    int status;

    status = ioctl(fd, FIONREAD, pBytesAvailable);
    lastError = errno;

    if (status < 0) {
        return PCSL_NET_IOERROR;
    } else {
        return PCSL_NET_SUCCESS;
    }
}
Example #10
0
/**
 * Common implementation between pcsl_datagram_read_start() 
 * and pcsl_datagram_read_finish().
 */
static int pcsl_datagram_read_common(
    void *handle, 
    unsigned char *pAddress,
    int *port, 
    char *buffer, 
    int length, 
    int *pBytesRead)
{
    struct sockaddr_in addr;
    int len = sizeof(struct sockaddr_in);
    int status;
    int fd;

    if (na_get_status(handle) == PCSL_NET_INTERRUPTED) {
        /*
         * VMSocket status need not be set to any value at this point
         * as the VMSocket is deleted and corresponding BSD socket is 
         * also closed
         */
        return PCSL_NET_INTERRUPTED;
    }

    fd = na_get_fd(handle);

    status = recvfrom(fd, buffer, length, 0, (struct sockaddr*)&addr, 
                   (socklen_t *)&len);
    lastError = errno;

    if (SOCKET_ERROR == status) {
        if (EWOULDBLOCK == errno || EINPROGRESS == errno) {
            /* printf("datagram read_start from : fd :%d\n", fd); */
            return PCSL_NET_WOULDBLOCK;
        } else if (EINTR == errno) {
            return PCSL_NET_INTERRUPTED;
        } else {
            return PCSL_NET_IOERROR;
        }
    }

    memcpy(pAddress, &addr.sin_addr.s_addr, sizeof(pAddress)); 
    //*ipnumber = (long)addr.sin_addr.s_addr;
    *port     = ntohs(addr.sin_port);
    *pBytesRead = status;

    return PCSL_NET_SUCCESS;
}
/**
 * Common implementation between pcsl_socket_write_start()
 * and pcsl_socket_write_finish().
 */
static int pcsl_socket_write_common(
    void *handle,
    char *pData,
    int len,
    int *pBytesWritten)
{
    int status;
    int fd;

    if (na_get_status(handle) == PCSL_NET_INTERRUPTED) {
        /*
         * VMSocket status need not be set to any value at this point
         * as the VMSocket is deleted and corresponding BSD socket is
         * also closed
         */
        return PCSL_NET_INTERRUPTED;
    }

    fd = na_get_fd(handle);

    status = send(fd, pData, len, 0);
    lastError = errno;

    if (SOCKET_ERROR == status) {
        if (EWOULDBLOCK == errno || EINPROGRESS == errno) {
            /*
             * DEBUG:
             * printf("write_start from : fd :%d\n", fd);
             */
            return PCSL_NET_WOULDBLOCK;
        } else if (EINTR == errno) {
            return PCSL_NET_INTERRUPTED;
        } else {
            return PCSL_NET_IOERROR;
        }
    }

    /*
     * DEBUG:
     * printf("writing : %s : to fd :%d\n", pData, fd);
     * printf("write_finish from : fd :%d\n", fd);
     */

    *pBytesWritten = status;
    return PCSL_NET_SUCCESS;
}
Example #12
0
/**
 * Common implementation between pcsl_datagram_write_start() 
 * and pcsl_datagram_write_finish().
 */
static int pcsl_datagram_write_common(
    void *handle,
    unsigned char *ipBytes,
    int port, 
    char *buffer, 
    int length, 
	int *pBytesWritten)
{
    struct sockaddr_in addr;
    int status;
    int fd;

    if (na_get_status(handle) == PCSL_NET_INTERRUPTED) {
        /*
         * VMSocket status need not be set to any value at this point
         * as the VMSocket is deleted and corresponding BSD socket is 
         * also closed
         */
        return PCSL_NET_INTERRUPTED;
    }

    fd = na_get_fd(handle);

    addr.sin_family      = AF_INET;
    addr.sin_port        = htons((short)port);
    memcpy(&addr.sin_addr.s_addr, ipBytes, sizeof(addr.sin_addr.s_addr));

    status = sendto(fd, buffer, length, 0, (struct sockaddr*)&addr,
                    sizeof(addr));
    lastError = errno;

    if (SOCKET_ERROR == status) {
        if (EWOULDBLOCK == errno || EINPROGRESS == errno) {
            /* printf("write_start from : fd :%d\n", fd); */
            return PCSL_NET_WOULDBLOCK;
        } else if (EINTR == errno) {
            return PCSL_NET_INTERRUPTED;
        } else {
            return PCSL_NET_IOERROR;
        }
    }

    *pBytesWritten = status;
    return PCSL_NET_SUCCESS;
}
Example #13
0
/**
 * See pcsl_datagram.h for definition.
 *
 * Note that this function NEVER returns PCSL_NET_WOULDBLOCK. Therefore, the 
 * finish() function should never be called and does nothing.
 */
int pcsl_datagram_close_start(
    void *handle,
    void **pContext)
{
    int status;
    int fd = na_get_fd(handle);
    /* printf("closing fd: %d\n", fd); */

    (void)pContext;
    na_destroy(handle);
    status = close(fd);
    lastError = errno;

    if (status == 0) {
        return PCSL_NET_SUCCESS;
    } 

    return PCSL_NET_IOERROR;
}
/**
 * Common functionality for accept start and finish
 */
static int pcsl_serversocket_accept_common(
    void *handle,
    void **pConnectionHandle,
    void **pContext)
{
    int connfd;
    int flags;
    struct sockaddr_in sa;
    int saLen = sizeof (sa);
    int listenfd = na_get_fd(handle);

    connfd = accept(listenfd, (struct sockaddr *)&sa, (socklen_t *)&saLen);

    if (connfd == SOCKET_ERROR) {
        if (errno == EWOULDBLOCK || errno == ECONNABORTED) {
            /*
             * The "listenfd" is marked as non-blocking and no connections 
             * are present to be accepted.
             */
            na_register_for_read((void *)handle);
            *pContext = NULL;
            return PCSL_NET_WOULDBLOCK;
        } else {
            na_unregister_for_read((void *)handle);
            return PCSL_NET_IOERROR;
        }
    } else {
        na_unregister_for_read((void *)handle);
        /*
         * Linux accept does _not_ inherit socket flags like O_NONBLOCK.
         * So, irrespective of the blocking or non-blockimg mode of listenfd,
         * connfd, must be set to non-blocking mode; otherwise VM will 
         * be blocked for any I/O operation on this new socket descriptor.
         */
        flags = fcntl(connfd, F_GETFL, 0);
        fcntl(connfd, F_SETFL, flags | O_NONBLOCK);

        *pConnectionHandle = na_create(connfd);

        return PCSL_NET_SUCCESS;
    }
}