#include <string.h>
#define BSOCK_GET_ADDR_MAX_HOSTNAME_SZ (256+1)
typedef enum
{
MODULE_STATE_INIT,
MODULE_STATE_WAIT,
MODULE_STATE_END,
MODULE_STATE_ERROR,
} MODULE_STATE;
typedef struct
{
sa_family_t sin_family;
char hostName[BSOCK_GET_ADDR_MAX_HOSTNAME_SZ];
} BSOCK_GET_ADDR_INIT_TYPE;
static MODULE_STATE state;
static BSOCK_GET_ADDR_INIT_TYPE initData = {0};
static struct addrinfo *pAddrInfo;
static struct addrinfo *pHints, hints;
void bsock_get_addr_init(void *pInitData)
{
if (NULL != pInitData)
{
memcpy(&initData, pInitData, sizeof(BSOCK_GET_ADDR_INIT_TYPE));
}
state = MODULE_STATE_INIT;
}
void bsock_get_addr_run(void)
{
switch (state)
{
case MODULE_STATE_INIT:
{
int result;
if (AF_INET == initData.sin_family)
{
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
pHints = &hints;
}
else if (AF_INET6 == initData.sin_family)
{
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET6;
pHints = &hints;
}
else if (AF_UNSPEC == initData.sin_family)
{
pHints = NULL;
}
else
{
printf("invalid address family %d\n", initData.sin_family);
state = MODULE_STATE_ERROR;
}
pAddrInfo = NULL;
errno = 0;
result = getaddrinfo(initData.hostName, NULL, pHints, &pAddrInfo);
printf("getaddrinfo = %d (%d)\n", result, errno);
if (0 == result)
{
printf("result found\n");
state = MODULE_STATE_END;
}
else if (EAI_AGAIN == result)
{
printf("result pending\n");
state = MODULE_STATE_WAIT;
}
else
{
printf("result error\n");
state = MODULE_STATE_ERROR;
}
break;
}
case MODULE_STATE_WAIT:
{
int result;
pAddrInfo = NULL;
errno = 0;
result = getaddrinfo(initData.hostName, NULL, pHints, &pAddrInfo);
printf("getaddrinfo = %d (%d)\n", result, errno);
if (0 == result)
{
printf("result found\n");
state = MODULE_STATE_END;
}
else if (EAI_AGAIN != result)
{
printf("result error\n");
state = MODULE_STATE_ERROR;
}
break;
}
case MODULE_STATE_END:
{
if (NULL != pAddrInfo)
{
struct addrinfo *pRes = pAddrInfo;
while (NULL != pRes)
{
if (NULL != pRes->ai_addr)
{
char ipStr[64];
union sockaddr_union *pAddr = (union sockaddr_union*)pRes->ai_addr;
if (AF_INET == pAddr->sin_family)
{
inet_ntop(pAddr->sin_family, &pAddr->in4.sin_addr, ipStr, sizeof(ipStr));
}
else if (AF_INET6 == pAddr->sin_family)
{
inet_ntop(pAddr->sin_family, &pAddr->in6.sin6_addr, ipStr, sizeof(ipStr));
}
printf("result is %s\n", ipStr);
}
pRes = pRes->ai_next;
}
freeaddrinfo(pAddrInfo);
pAddrInfo = NULL;
}
break;
}
case MODULE_STATE_ERROR:
{
break;
}
default:
{
break;
}
}
}