コード例 #1
0
SIZE_TYPE CSocketAPI::StringToHostPort(const string&   str,
                                       unsigned int*   host,
                                       unsigned short* port)
{
    const char* s = str.c_str();
    const char* e = SOCK_StringToHostPort(s, host, port);
    return e ? (SIZE_TYPE)(e - s) : NPOS;
}
コード例 #2
0
ファイル: ncbi_dblb.c プロジェクト: swuecho/igblast
const char* DBLB_GetServer(const char*             lb_name,
                           TDBLB_Flags             flags,
                           const SDBLB_Preference* preference,
                           const char* const       skip_servers[],
                           SDBLB_ConnPoint*        conn_point,
                           char*                   server_name_buf,
                           size_t                  server_name_buflen,
                           EDBLB_Status*           result)
{
    static const char kPrefix[] = "DB_IP__";
    size_t          len, n, a_skip, n_skip;
    SConnNetInfo*   net_info;
    int/*bool*/     failed;
    unsigned int    x_host;
    unsigned short  x_port;
    double          x_pref;
    SSERV_InfoCPtr* skip;
    SSERV_Info*     info;
    SDBLB_ConnPoint cp;
    EDBLB_Status    x;
    const char*     c;

    if (!result)
        result = &x;
    if (server_name_buf) {
        assert(server_name_buflen);
        server_name_buf[0] = '\0';
    }
    if (!conn_point)
        conn_point = &cp;
    memset(conn_point, 0, sizeof(*conn_point));
    if (!lb_name  ||  !*lb_name) {
        *result = eDBLB_BadName;
        return 0/*failure*/;
    }
    *result = eDBLB_Success;

    if (strchr(lb_name, '.')) {
        cp.host = SOCK_gethostbyname(lb_name);
        if (cp.host == SOCK_GetLoopbackAddress())
            cp.host = /*FIXME?*/SERV_LOCALHOST;
    } else
        cp.host = 0;

    skip = 0;
    n_skip = 0;
    a_skip = 0;
    net_info = 0;
    failed = 0/*false*/;
    if (skip_servers) {
        for (n = 0;  !failed  &&  skip_servers[n];  n++) {
            const char* server = skip_servers[n];
            SSERV_Info* info;
            if (!(len = strlen(server))) {
                continue;
            }
            if (strncasecmp(server, kPrefix, sizeof(kPrefix)-1) == 0
                &&  isdigit((unsigned char) server[sizeof(kPrefix)-1])) {
                c = strstr(server + sizeof(kPrefix)-1, "__");
                if (c) {
                    size_t i = (size_t)(c - server) - (sizeof(kPrefix)-1);
                    char* temp = strdup(server + sizeof(kPrefix)-1);
                    if (temp) {
                        char* s = temp + i;
                        *s++ = ':';
                        memmove(s, s + 1, strlen(s + 1) + 1);
                        server = temp;
                        while (++temp < s) {
                            if (*temp == '_')
                                *temp =  '.';
                        }
                        len -= sizeof(kPrefix);
                    }
                }
            }
            if (SOCK_StringToHostPort(server, &x_host, &x_port)
                != server + len) {
                int/*bool*/ resolved = 0/*false*/;
                const SSERV_Info* temp;
                SERV_ITER iter;

                if (!net_info)
                    net_info = ConnNetInfo_Create(lb_name);
                iter = SERV_Open(skip_servers[n],
                                 fSERV_Standalone | fSERV_Dns
                                 | fSERV_Promiscuous,
                                 0, net_info);
                do {
                    SSERV_Info* dns;
                    temp = SERV_GetNextInfo(iter);
                    if (temp) {
                        x_host = temp->host;
                        if (x_host  &&  s_IsSkipHost(x_host, cp.host)) {
                            failed = 1/*true*/;
                            break;
                        }
                        x_port = temp->port;
                    } else if (!resolved) {
                        x_host = 0;
                        x_port = 0;
                    } else
                        break;
                    if ((dns = SERV_CreateDnsInfo(x_host)) != 0) {
                        dns->port = x_port;
                        s_AddSkip(&skip, &a_skip, &n_skip, x_host
                                  ? dns
                                  : SERV_CopyInfoEx(dns, skip_servers[n]));
                        if (!x_host)
                            free(dns);
                    }
                    resolved = 1/*true*/;
                } while (temp);
                SERV_Close(iter);
                info = 0;
            } else if (s_IsSkipHost(x_host, cp.host)) {
                failed = 1/*true*/;
                info = 0;
            } else if (server != skip_servers[n]) {
                info = SERV_CreateStandaloneInfo(x_host, x_port);
            } else if ((info = SERV_CreateDnsInfo(x_host)) != 0)
                info->port = x_port;
            if (server != skip_servers[n])
                free((void*) server);
            if (info)
                s_AddSkip(&skip, &a_skip, &n_skip, info);
        }
    }

    if (!failed  &&  !cp.host) {
        if (preference) {
            x_host = preference->host;
            x_port = preference->port;
            if ((x_pref = preference->pref) < 0.0)
                x_pref  =  0.0;
            else if (x_pref >= 100.0)
                x_pref  = -1.0;
        } else {
            x_host = 0;
            x_port = 0;
            x_pref = 0.0;
        }

        if (!net_info)
            net_info = ConnNetInfo_Create(lb_name);
        info = SERV_GetInfoP(lb_name, fSERV_ReverseDns | fSERV_Standalone,
                             x_host, x_port, x_pref, net_info,
                             skip, n_skip, 0/*not external*/,
                             0, 0, 0); /* NCBI_FAKE_WARNING: GCC */
        if (!info  &&  (flags & fDBLB_AllowFallbackToStandby)) {
            /*FIXME: eliminate second pass by fix in ordering in ncbi_lbsmd.c*/
            info = SERV_GetInfoP(lb_name, fSERV_ReverseDns | fSERV_Standalone
                                 | fSERV_IncludeSuppressed,
                                 x_host, x_port, x_pref, net_info,
                                 skip, n_skip, 0/*not external*/,
                                 0, 0, 0); /* NCBI_FAKE_WARNING: GCC */
        }
    } else
        info = 0;

    if (!info) {
        if (!failed) {
            if (!cp.host) {
                if (n_skip  &&  (x_host = SOCK_gethostbyname(lb_name)) != 0) {
                    for (n = 0;  n < n_skip;  n++) {
                        if (x_host == skip[n]->host) {
                            failed = 1/*true*/;
                            break;
                        }
                    }
                }
                if (!failed  &&  skip_servers) {
                    for (n = 0;  (c = skip_servers[n]) != 0;  n++) {
                        if (strcasecmp(c, lb_name) == 0) {
                            failed = 1/*true*/;
                            break;
                        }
                    }
                }
            } else if (conn_point != &cp) {
                conn_point->host = cp.host;
                conn_point->time = NCBI_TIME_INFINITE;
            }
        }
        if (!failed  &&  server_name_buf)
            strncpy0(server_name_buf, lb_name, server_name_buflen - 1);
        *result = eDBLB_NotFound;
    } else {
        if (info->type != fSERV_Dns) {
            char* s, buf[80];
            strncpy0(buf, kPrefix, sizeof(buf) - 1);
            SOCK_HostPortToString(info->host, info->port,
                                  buf + sizeof(kPrefix) - 1,
                                  sizeof(buf) - sizeof(kPrefix));
            len = strlen(buf);
            if ((s = strchr(buf, ':')) != 0)
                memmove(s + 1, s, strlen(s) + 1);
            for (n = 0;  n < len;  n++) {
                if (buf[n] == '.'  ||  buf[n] == ':')
                    buf[n] = '_';
            }
            if (server_name_buf)
                strncpy0(server_name_buf, buf, server_name_buflen - 1);
            *result = eDBLB_NoDNSEntry;
        } else if (info->host) {
            c = SERV_NameOfInfo(info);
            assert(c);
            if (server_name_buf)
                strncpy0(server_name_buf, c, server_name_buflen - 1);
        } else {
            failed = 1/*true*/;
            *result = eDBLB_ServiceDown;
        }
        if (!failed) {
            conn_point->host = info->host;
            conn_point->port = info->port;
            conn_point->time = info->time;
        }
        free(info);
    }

    for (n = 0;  n < n_skip;  n++)
        free((void*) skip[n]);
    if (skip)
        free((void*) skip);

    if (net_info)
        ConnNetInfo_Destroy(net_info);

    return failed ? 0 : (server_name_buf ? server_name_buf : lb_name);
}
コード例 #3
0
ファイル: ncbi_server_info.c プロジェクト: fbtestrepo/hw
SSERV_Info* SERV_ReadInfoEx(const char* info_str, const char* name)
{
    /* detect server type */
    ESERV_Type     type;
    const char*    str = SERV_ReadType(info_str, &type);
    int/*bool*/    coef, mime, locl, priv, quorum, rate, sful, time;
    unsigned int   host;                /* network byte order       */
    unsigned short port;                /* host (native) byte order */
    SSERV_Info*    info;

    if (!str || (*str && !isspace((unsigned char)(*str))))
        return 0;
    /* NB: "str" guarantees there is non-NULL attr */
    while (*str && isspace((unsigned char)(*str)))
        str++;
    if (!ispunct((unsigned char)(*str)) || *str == ':') {
        if (!(str = SOCK_StringToHostPort(str, &host, &port)))
            return 0;
        while (*str && isspace((unsigned char)(*str)))
            str++;
    } else {
        host = 0;
        port = 0;
    }
    /* read server-specific info according to the detected type */
    info = s_GetAttrByType(type)->vtable.Read(&str, name ? strlen(name)+1 : 0);
    if (!info)
        return 0;
    info->host = host;
    if (port)
        info->port = port;
    coef = mime = locl = priv = quorum = rate = sful = time = 0;/*unassigned*/
    /* continue reading server info: optional parts: ... */
    while (*str && isspace((unsigned char)(*str)))
        str++;
    while (*str) {
        if (*(str + 1) == '=') {
            int            n;
            double         d;
            unsigned short h;
            unsigned long  t;
            char           s[4];
            EMIME_Type     mime_t;
            EMIME_SubType  mime_s;
            EMIME_Encoding mime_e;
            
            switch (toupper((unsigned char)(*str++))) {
            case 'B':
                if (!coef && sscanf(str, "=%lf%n", &d, &n) >= 1) {
                    if (d < -100.0)
                        d = -100.0;
                    else if (d < 0.0)
                        d = (d < -0.1 ? d : -0.1);
                    else if (d < 0.01)
                        d = 0.0;
                    else if (d > 1000.0)
                        d = 1000.0;
                    info->coef = d;
                    str += n;
                    coef = 1;
                }
                break;
            case 'C':
                if (type == fSERV_Dns)
                    break;
                if (!mime && MIME_ParseContentTypeEx(str + 1, &mime_t,
                                                     &mime_s, &mime_e)) {
                    info->mime_t = mime_t;
                    info->mime_s = mime_s;
                    info->mime_e = mime_e;
                    mime = 1;
                    while (*str && !isspace((unsigned char)(*str)))
                        str++;
                }
                break;
            case 'L':
                if (!locl && sscanf(str, "=%3s%n", s, &n) >= 1) {
                    if (strcasecmp(s, "YES") == 0) {
                        info->locl |=  0x01/*true in low nibble*/;
                        str += n;
                        locl = 1;
                    } else if (strcasecmp(s, "NO") == 0) {
                        info->locl &= ~0x0F/*false in low nibble*/;
                        str += n;
                        locl = 1;
                    }
                }
                break;
            case 'P':
                if (type == fSERV_Dns)
                    break;
                if (!priv && sscanf(str, "=%3s%n", s, &n) >= 1) {
                    if (strcasecmp(s, "YES") == 0) {
                        info->locl |=  0x10;/*true in high nibble*/
                        str += n;
                        priv = 1;
                    } else if (strcasecmp(s, "NO") == 0) {
                        info->locl &= ~0xF0;/*false in high nibble*/
                        str += n;
                        priv = 1;
                    }
                }
                break;
            case 'Q':
                if (type == fSERV_Firewall || !info->host || quorum)
                    break;
                if (sscanf(str,"=%3s%n",s,&n) >= 1 && strcasecmp(s, "YES")==0){
                    info->quorum = (unsigned short)(-1);
                    str += n;
                    quorum = 1;
                } else if (sscanf(str, "=%hu%n", &h, &n) >= 1) {
                    info->quorum = h;
                    str += n;
                    quorum = 1;
                }
                break;
            case 'R':
                if (!rate && sscanf(str, "=%lf%n", &d, &n) >= 1) {
                    if (fabs(d) < 0.001)
                        d = 0.0;
                    else if (fabs(d) > 100000.0)
                        d = d < 0.0 ? -100000.0 : 100000.0;
                    info->rate = d;
                    str += n;
                    rate = 1;
                }
                break;
            case 'S':
                if ((type & fSERV_Http) != 0)
                    break;
                if (!sful && sscanf(str, "=%3s%n", s, &n) >= 1) {
                    if (strcasecmp(s, "YES") == 0) {
                        if (type == fSERV_Dns)
                            break; /*check only here for compatibility*/
                        info->sful = 1/*true */;
                        str += n;
                        sful = 1;
                    } else if (strcasecmp(s, "NO") == 0) {
                        info->sful = 0/* false */;
                        str += n;
                        sful = 1;
                    }
                }
                break;
            case 'T':
                if (!time && sscanf(str, "=%lu%n", &t, &n) >= 1) {
                    info->time = (TNCBI_Time) t;
                    str += n;
                    time = 1;
                }
                break;
            }
        } else {
            size_t i;
            for (i = 0; i < sizeof(k_FlagTag)/sizeof(k_FlagTag[0]); i++) {
                size_t n = strlen(k_FlagTag[i]);
                if (strncasecmp(str, k_FlagTag[i], n) == 0) {
                    info->flag = (ESERV_Flag) i;
                    str += n;
                    break;
                }
            }
        }
        if (*str && !isspace((unsigned char)(*str)))
            break;
        while (*str && isspace((unsigned char)(*str)))
            str++;
    }
    if (*str) {
        free(info);
        info = 0;
    } else if (name) {
        strcpy((char*) info + SERV_SizeOfInfo(info), name);
        if (info->type == fSERV_Dns)
            info->u.dns.name = 1/*true*/;
    } else if (info->type == fSERV_Dns) {
        info->u.dns.name = 0/*false*/;
    }
    return info;
}