コード例 #1
0
/** ========================================================================
 * =========================================================================
 */
PslError
psl_inet_connect_sock(int         const s,
                      int         const addrFamily,
                      const char* const addrStr,
                      int         const port,
                      const char* const userLabel,
                      const void* const cookie)
{
    PslInetGenericSockAddr  server;

    PSL_LOG_DEBUG("%s (%s=%p): fd=%d, addrfamily=%d, addrStr=%s, port=%d",
                  __func__, userLabel, cookie, s, addrFamily,
                  PSL_LOG_OBFUSCATE_STR(addrStr), port);

    bool success = !psl_inet_make_sock_addr(addrFamily, addrStr,
                                            port, &server, userLabel, cookie);
    if (!success) {
        return PSL_ERR_BAD_SERV_ADDR;
    }

    int rc = connect(s, (struct sockaddr*)&server.sa, server.addrLength);
    PSL_ASSERT(rc <= 0);
    if (0 == rc) {
        PSL_LOG_DEBUG("%s (%s=%p): connect() succeeded immediately",
                      __func__, userLabel, cookie);
        return 0;
    }
    else if (rc < 0 && EINPROGRESS == errno) {
        PSL_LOG_DEBUG("%s (%s=%p): connect() returned EINPROGRESS",
                      __func__, userLabel, cookie);
        return 0;
    }
    /* @todo The implication of EINTR
             when connecting on a non-blocking socket is vague, at best.
             Should we retry connect(), assume that all is well, or give up
             on this connection?
    else if (rc < 0 && EINTR == errno) {
        PSL_LOG_DEBUG("%s (fsm=%p): connect() returned EINTR",
                      __func__, pFsm);
        return 0;
    }
    */
    else { /// (rc < 0)
        int const saverrno = errno;
        PSL_LOG_ERROR("%s (%s=%p): ERROR: connect() failed; errno=%d (%s)",
                      __func__, userLabel, cookie, saverrno, strerror(saverrno));

        return psl_err_pslerror_from_connect_errno(saverrno);
    }
}//psl_inet_connect_sock
コード例 #2
0
/** ========================================================================
 * =========================================================================
 */
bool
psl_inet_ipaddr_from_string(const char*         const hn,
                            PslInetIPAddress*   const pBuf,
                            const char*         const userLabel,
                            const void*         const cookie)
{
    PSL_ASSERT(pBuf);

    pBuf->family = AF_UNSPEC;

    if (!hn || !*hn) {
        PSL_LOG_ERROR("%s (%s=%p): ERROR: NULL or empty hostname string",
                      __func__, userLabel, cookie);
        return false;
    }

    int             rc;

    rc = inet_pton(AF_INET, hn, &pBuf->addr);
    if (rc > 0) {
        PSL_LOG_DEBUGLOW("%s (%s=%p): hostname looks like IPv4 address",
                         __func__, userLabel, cookie);
        pBuf->family = AF_INET;
        pBuf->len = sizeof(struct in_addr);
        return true;
    }
    else {
        rc = inet_pton(AF_INET6, hn, &pBuf->addr);
        if (rc > 0) {
            PSL_LOG_DEBUGLOW("%s (%s=%p): hostname looks like IPv6 address",
                             __func__, userLabel, cookie);
            pBuf->family = AF_INET6;
            pBuf->len = sizeof(struct in6_addr);
            return true;
        }
        else {
            PSL_LOG_DEBUGLOW("%s (%s=%p): hostname string '%s' doesn't look " \
                             "like an IP address'.",
                             __func__, userLabel, cookie, PSL_LOG_OBFUSCATE_STR(hn));
        }
    }

    return false;
}//psl_inet_ipaddr_from_string
コード例 #3
0
/** ========================================================================
 * =========================================================================
 */
int
psl_inet_make_sock_addr(int                       const reqFamily,
                        const char*               const addrStr,
                        int                       const port,
                        PslInetGenericSockAddr*   const res,
                        const char*               const userLabel,
                        const void*               const cookie)
{
    PSL_ASSERT(AF_INET == reqFamily || AF_INET6 == reqFamily ||
           AF_UNSPEC == reqFamily);
    PSL_ASSERT(AF_UNSPEC != reqFamily || (addrStr && addrStr[0]));
    PSL_ASSERT(res);

    memset(res, 0, sizeof(*res));

    res->family = AF_UNSPEC;


    PslInetIPAddress    pslinaddr;
    int                 inaddrlen = 0;

    int actualFamily = reqFamily;

    if (AF_UNSPEC == reqFamily) {
        PSL_LOG_DEBUGLOW("%s (%s=%p): resoloving addrfamily (was AF_UNSPEC)",
                         __func__, userLabel, cookie);
        PSL_ASSERT(addrStr);

        bool const gotAddr = psl_inet_ipaddr_from_string(addrStr, &pslinaddr,
                                                         userLabel, cookie);
        if (gotAddr) {
            actualFamily = pslinaddr.family;
            inaddrlen = pslinaddr.len;
        }
        else {
            PSL_LOG_ERROR("%s (%s=%p): ERROR: could not determine " \
                          "address family from address string '%s'.",
                          __func__, userLabel, cookie,
                          PSL_LOG_OBFUSCATE_STR(addrStr));
            return EINVAL;
        }
    }


    void*   addrDst = NULL;
    if (AF_INET == actualFamily) {
        res->addrLength = sizeof(res->sa);
        res->sa.sin_family = actualFamily;
        res->sa.sin_port = htons(port);
        res->sa.sin_addr.s_addr = INADDR_ANY;
        addrDst = &res->sa.sin_addr;
    }
    else {
        PSL_ASSERT(AF_INET6 == actualFamily);
        res->addrLength = sizeof(res->sa6);
        res->sa6.sin6_family = actualFamily;
        //res->sa6.sin6_flowinfo = 0; ///< what should we do with these?
        //res->sa6.sin6_scope_id = 0;
        res->sa6.sin6_port = htons(port);
        res->sa6.sin6_addr = in6addr_any;
        addrDst = &res->sa6.sin6_addr;
    }

    if (addrStr && inaddrlen) {
        memcpy(addrDst, &pslinaddr.addr, inaddrlen);
    }
    else if (addrStr) {
        PSL_ASSERT(addrDst);
        int const ptonRes = inet_pton(actualFamily, addrStr, addrDst);

        if (ptonRes < 0) {  /// unexpected address family - check errno
            int const saverrno = errno;
            PSL_LOG_ERROR("%s (%s=%p): ERROR: inet_pton() failed; " \
                          "family=%d, addrStr=%s, errno=%d (%s).",
                          __func__, userLabel, cookie, actualFamily,
                          PSL_LOG_OBFUSCATE_STR(addrStr), saverrno,
                          strerror(saverrno));
            PSL_ASSERT(saverrno);
            return saverrno;
        }
        else if (ptonRes == 0) {    /// addr does not match family
            /// @note This case does not set errno
            PSL_LOG_ERROR("%s (%s=%p): ERROR: inet_pton() failed; Address " \
                          "does not match family; family=%d, addrStr=%s.",
                          __func__, userLabel, cookie, actualFamily,
                          PSL_LOG_OBFUSCATE_STR(addrStr));
            return EINVAL;
        }
    }

    res->family = actualFamily;
    return 0;
}// psl_inet_make_sock_addr
コード例 #4
0
/** ========================================================================
 * =========================================================================
 */
static PslSmeEventStatus
chan_fsm_init_state_handler(PslChanFsmInitState*    const pState,
                            PslChanFsm*             const pFsm,
                            PslSmeEventId           const evtId,
                            const PslChanFsmEvtArg* const evtArg)
{   
    switch (evtId) 
    {
    case kFsmEventEnterScope:
    case kFsmEventExitScope:
    case kFsmEventBegin:
        return kPslSmeEventStatus_success;
        break;

    case PSL_CHAN_FSM_EVT_CONNECT:
        if (AF_UNSPEC == pFsm->userSettings.serverAddr.addrFamily && pFsm->fd < 0) {
            PSL_LOG_ERROR("%s (fsm=%p): ERROR: PSL_CHAN_FSM_EVT_CONNECT " \
                          "failed: connect address not set", __func__, pFsm);

            psl_chan_fsm_set_last_error(pFsm, kPslChanFsmErrorSource_psl,
                                        PSL_ERR_BAD_SERV_ADDR);
            return kPslSmeEventStatus_error;
        }


        if (pFsm->fd < 0) {
            psl_chan_fsm_goto_plain_lookup_state(pFsm, &evtArg->connect.data);
        }
        else {
            static const struct PslChanFsmEvtInetAddrText addrText = {
                .family = AF_UNSPEC
                };
            psl_chan_fsm_goto_plain_conn_state(pFsm, &evtArg->connect.data, &addrText);
        }
        return kPslSmeEventStatus_success;
        break;

    case PSL_CHAN_FSM_EVT_SET_CONN_FD:
        {
            const struct PslChanFsmEvtArgSetConnFD* const arg =
                &evtArg->setConnFD;

            PSL_ASSERT(arg->fd >= 0);

            if (AF_UNSPEC != pFsm->userSettings.serverAddr.addrFamily) {
                PSL_LOG_ERROR("%s (fsm=%p): SET_CONN_FD ERROR: " \
                              "not allowed when server address is set",
                              __func__, pFsm);
                return kPslSmeEventStatus_passToParent;
            }

            if (AF_UNSPEC != pFsm->userSettings.bindAddr.addrFamily) {
                PSL_LOG_ERROR("%s (fsm=%p): SET_CONN_FD ERROR: " \
                              "not allowed when bind address is set",
                              __func__, pFsm);
                return kPslSmeEventStatus_passToParent;
            }

            if (pFsm->fd >= 0) {
                PSL_LOG_ERROR("%s (fsm=%p): SET_CONN_FD ERROR: connected " \
                              "file descriptor was already set",
                              __func__, pFsm);
                return kPslSmeEventStatus_passToParent;
            }

            pFsm->fd = arg->fd;
            pFsm->userSettings.fdIsUserProvided = true;
            pFsm->userSettings.fdOpts = arg->opts;

            return kPslSmeEventStatus_success;
            break;
        }

    case PSL_CHAN_FSM_EVT_SET_SERVER:
        {
            const struct PslChanFsmEvtArgSetServer* const arg =
                &evtArg->setServer;

            if (pFsm->fd >= 0) {
                PSL_LOG_ERROR("%s (fsm=%p): SET_SERVER ADDR ERROR: not " \
                              "allowed when connected file descriptor is set",
                              __func__, pFsm);
                return kPslSmeEventStatus_passToParent;
            }

            if (AF_UNSPEC != pFsm->userSettings.serverAddr.addrFamily) {
                PSL_LOG_ERROR("%s (fsm=%p): SET_SERVER ADDR ERROR: " \
                              "server address was already set",
                              __func__, pFsm);
                return kPslSmeEventStatus_passToParent;
            }

            PSL_LOG_DEBUG("%s (fsm=%p): SET_SERVER ADDR: server: '%s:%d'/af=%d",
                          __func__, pFsm,
                          PSL_LOG_OBFUSCATE_STR(arg->hostStr),
                          (int)arg->port,
                          (int)arg->addrFamily);

            pFsm->userSettings.serverAddr.addrFamily = arg->addrFamily;
            pFsm->userSettings.serverAddr.port = arg->port;
            pFsm->userSettings.serverAddr.hostStr = g_strdup(arg->hostStr);
            PSL_ASSERT(pFsm->userSettings.serverAddr.hostStr);
        }
        return kPslSmeEventStatus_success;
        break;

    case PSL_CHAN_FSM_EVT_SET_SOCK_BIND:
        {
            const struct PslChanFsmEvtArgSetSockBind* const arg =
                &evtArg->setSockBind;

            if (pFsm->fd >= 0) {
                PSL_LOG_ERROR("%s (fsm=%p): SET_SOCK_BIND ERROR: not " \
                              "allowed when connected file descriptor is set",
                              __func__, pFsm);
                return kPslSmeEventStatus_passToParent;
            }

            if (AF_UNSPEC != pFsm->userSettings.bindAddr.addrFamily) {
                PSL_LOG_ERROR("%s (fsm=%p): SET_SOCK_BIND ERROR: " \
                              "socket bind address was already set",
                              __func__, pFsm);
                return kPslSmeEventStatus_passToParent;
            }

            PSL_LOG_DEBUG("%s (fsm=%p): SET_SOCK_BIND: local addr: '%s:%d'/af=%d",
                          __func__, pFsm,
                          PSL_LOG_MAKE_SAFE_STR(arg->ipAddrStr),
                          (int)arg->port,
                          (int)arg->addrFamily);

            pFsm->userSettings.bindAddr.addrFamily = arg->addrFamily;
            pFsm->userSettings.bindAddr.port = arg->port;
            pFsm->userSettings.bindAddr.hostStr = g_strdup(arg->ipAddrStr);
            PSL_ASSERT(!arg->ipAddrStr || pFsm->userSettings.bindAddr.hostStr);
        }
        return kPslSmeEventStatus_success;
        break;

    default:
        break; ///< allow default processing by parent
    }

    return kPslSmeEventStatus_passToParent;
}//chan_fsm_init_state_handler