Exemple #1
0
/* ares__gc
 *
 * __gc metamethod for the ares userdata.
 * cancels request if 
 *
 * Arguments:
 *	L	Lua State
 *
 * Lua Stack:
 *	1	aResolver userdata
 */
static int ares__gc(lua_State *L)
{
	aResolver *ares = (aResolver*) lua_touserdata(L, 1);
	void *dummy;
	gai_cancel(ares->rq);
	gai_finalize(ares->rq, (struct addrinfo **) &dummy);
	ares->rq = NULL;

	return 0;
}
Exemple #2
0
/* ares_cancel
 * 
 * cancels an asynchronous getaddrinfo request
 * 
 * Arguments:
 * 	L	Lua State
 * 
 * Lua Stack:
 * 	1	the aResolver userdata
 * 
 * Lua Returns:
 * 	+1	true, if the cancel request was sent, nil + error message if an
 *		error occurred.
 */
static int ares_cancel(lua_State *L)
{
	aResolver *ares = ares_checkaResolver(L, 1);
	if (!ares->rq)
		return ares_error(L, "invalid request object, has already been finalized.");
	int res = gai_cancel(ares->rq);
	if (res == 0)
		lua_pushboolean(L, 1);
	else
		return ares_error(L, strerror(errno));
	return 1;
}
Exemple #3
0
void runSuccess() {
    char buf[] = "hi";
    //@ assert \valid((char*)buf);
    struct addrinfo ai;
    struct gaicb g1 = {
            .ar_name = buf,
            .ar_service = buf,
            .ar_request = &ai,
    };
    struct gaicb *list[] = {NULL, &g1};
    if (!getaddrinfo_a(anyint(), list, 2, NULL)) {
        gai_cancel(&g1);
    }
}
Exemple #4
0
void testValues() {
    f = 2;
    
    char buf[] = "hi";
    //@ assert \valid((char*)buf);
    struct addrinfo ai;
    struct gaicb g1 = {
            .ar_name = buf,
            .ar_service = buf,
            .ar_request = &ai,
    };
    struct gaicb *list[] = {NULL, &g1};
    if (!getaddrinfo_a(anyint(), list, 2, NULL)) {
        gai_cancel(&g1);
    }

    //@ assert f == 2;
    //@ assert vacuous: \false;
}
Exemple #5
0
ipaddr ipremote(const char *name, int port, int mode, int64_t deadline) {
    ipaddr addr = mill_ipliteral(name, port, mode);
#if !defined __linux__
    return addr;
#else
    if(errno == 0)
       return addr;
    /* Let's do asynchronous DNS query here. */
    int efd = eventfd(0, 0);
    if(mill_slow(efd < 0))
        return addr;
    struct addrinfo request;
    memset(&request, 0, sizeof(request));
    request.ai_family = AF_UNSPEC;
    request.ai_socktype = SOCK_STREAM;
    struct gaicb gcb;
    memset(&gcb, 0, sizeof(gcb));
    gcb.ar_name = name;
    gcb.ar_service = NULL;
    gcb.ar_request = &request;
    gcb.ar_result = NULL;
    struct sigevent sev;
    memset(&sev, 0, sizeof(sev));
    /* The event will be delivered using a new thread rather than by a signal
       running of one of the coroutines' stack and possibly breaking it. */
    sev.sigev_notify = SIGEV_THREAD;
    sev.sigev_notify_function = mill_getaddrinfo_a_done;
    sev.sigev_value.sival_int = efd;
    struct gaicb *pgcb = &gcb;
    int rc = getaddrinfo_a(GAI_NOWAIT, &pgcb, 1, &sev);
    if(mill_slow(rc != 0)) {
        if(rc == EAI_AGAIN || rc == EAI_MEMORY) {
            close(efd);
            errno = ENOMEM;
            return addr;
        }
        mill_assert(0);
    }
    rc = fdwait(efd, FDW_IN, deadline);
    if(rc == 0) {
        gai_cancel(&gcb);
        rc = fdwait(efd, FDW_IN, -1);
    }
    mill_assert(rc == FDW_IN);
    close(efd);
    rc = gai_error(&gcb);
    if(rc != 0) {
        errno = EINVAL;
        return addr;
    }
    struct addrinfo *ipv4 = NULL;
    struct addrinfo *ipv6 = NULL;
    struct addrinfo *it = gcb.ar_result;
    while(it) {
        if(!ipv4 && it->ai_family == AF_INET)
            ipv4 = it;
        if(!ipv6 && it->ai_family == AF_INET6)
            ipv6 = it;
        if(ipv4 && ipv6)
            break;
        it = it->ai_next;
    }
    switch(mode) {
    case IPADDR_IPV4:
        ipv6 = NULL;
        break;
    case IPADDR_IPV6:
        ipv4 = NULL;
        break;
    case 0:
    case IPADDR_PREF_IPV4:
        if(ipv4)
           ipv6 = NULL;
        break;
    case IPADDR_PREF_IPV6:
        if(ipv6)
           ipv4 = NULL;
        break;
    default:
        mill_assert(0);
    }
    if(ipv4) {
        struct sockaddr_in *inaddr = (struct sockaddr_in*)&addr;
        memcpy(inaddr, ipv4->ai_addr, sizeof (struct sockaddr_in));
        inaddr->sin_port = htons(port);
    }
    if(ipv6) {
        struct sockaddr_in6 *inaddr = (struct sockaddr_in6*)&addr;
        memcpy(inaddr, ipv6->ai_addr, sizeof (struct sockaddr_in6));
        inaddr->sin6_port = htons(port);
    }
    freeaddrinfo(gcb.ar_result);
    errno = 0;
    return addr;
#endif
}
Exemple #6
0
//---------------------------------
int ResolverRequest::addRequest(const char *hostName)
{
    int i, emptyIndex = -1;

    DWORD   oldestTime  = 0x7fffffff;
    int     oldestIndex = -1;

    // find usable slot
    for(i=0; i<RESOLV_COUNT; i++) {
        if(requests[i].startTime == 0) {      // start time 0 means it's empty (not running)
            emptyIndex = i;
            break;
        }
                                            // if it's running and it's older than the currently found oldest, mark it
        if(oldestTime > requests[i].startTime) {
            oldestTime  = requests[i].startTime;
            oldestIndex = i;
        }
    }

    // get pointer to that slot
    Tresolv *r;
    int      usedIndex;

    if(emptyIndex != -1) {      // if found empty slot, use it
        r = &requests[emptyIndex];
        usedIndex = emptyIndex;
    } else {                    // if not found empty slot, cancel existing and use it
        gai_cancel(&requests[oldestIndex].req);       // try to cancel
        r = &requests[oldestIndex];
        usedIndex = oldestIndex;
    }

    r->startTime                = Utils::getCurrentMs();    // store start time
    r->getaddrinfoHasFinished   = 0;                        // mark that we did not finish yet
    r->count                    = 0;                        // no IPs stored yet
    r->processed                = 0;                        // not processed yet
    memset(r->canonName, 0, 256);                           // no canon name yet

    memset (r->hostName, 0, 256);
    strncpy(r->hostName, hostName, 255);                    // copy host name to our array
    r->req.ar_name      = r->hostName;                      // store pointer to that array

    //-------------------
    // check and possibly resolve dotted IP
    int a,b,c,d;
    int iRes = sscanf(hostName, "%d.%d.%d.%d", &a, &b, &c, &d);
    
    if(iRes == 4) {         // succeeded to get IP parts
        if(IS_VALID_IP_NUMBER(a) && IS_VALID_IP_NUMBER(b) && IS_VALID_IP_NUMBER(c) && IS_VALID_IP_NUMBER(d)) {

            BYTE *pIps = (BYTE *) r->data;
            pIps[0]     = a;    // store that IP
            pIps[1]     = b;
            pIps[2]     = c;
            pIps[3]     = d;
            
            r->count    = 1;    // store count
            
            strcpy(r->canonName, r->hostName);                          // pretend that the string is canonical name
            
            r->getaddrinfoHasFinished   = 1;                            // resolve finished
            r->processed                = 1;
            
            return usedIndex;
        }
    }
    //-------------------
    
    r->hints.ai_flags   = AI_CANONNAME;                     // get the official name of the host
    r->req.ar_request   = &r->hints;

    gaicb *pReq = &r->req;
    int ret = getaddrinfo_a(GAI_NOWAIT, &pReq, 1, NULL);

    if (ret) {
        Debug::out(LOG_DEBUG, "addRequest() failed");
        return -1;
    }

    Debug::out(LOG_DEBUG, "addRequest() - resolving %s under index %d", hostName, usedIndex);
    return usedIndex;           // return index under which this request runs
}