/* include test_udp */ void test_udp(void) { volatile int nsent = 0, timeout = 3; struct udpiphdr *ui; Signal(SIGALRM, sig_alrm); if (sigsetjmp(jmpbuf, 1)) { if (nsent >= 3) err_quit("no response"); printf("timeout\n"); timeout *= 2; /* exponential backoff: 3, 6, 12 */ } canjump = 1; /* siglongjmp is now OK */ send_dns_query(); nsent++; alarm(timeout); ui = udp_read(); canjump = 0; alarm(0); if (ui->ui_sum == 0) printf("UDP checksums off\n"); else printf("UDP checksums on\n"); if (verbose) printf("received UDP checksum = %x\n", ntohs(ui->ui_sum)); }
int main() { struct sockaddr_in dest; int skt = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); int flags = fcntl(skt, F_GETFL, 0); fcntl(skt, F_SETFL, flags | O_NONBLOCK); dest.sin_family = AF_INET; dest.sin_port = htons(53); dest.sin_addr.s_addr = inet_addr("8.8.8.8"); send_dns_query(skt, (struct sockaddr*)&dest, "pubsub.pubnub.com"); fd_set read_set, write_set; int rslt; struct timeval timev = { 0, 300000 }; FD_ZERO(&read_set); FD_SET(skt, &read_set); rslt = select(skt + 1, &read_set, NULL, NULL, &timev); if (-1 == rslt) { puts("select() Error!\n"); return -1; } else if (rslt > 0) { struct sockaddr_in resolved_addr; printf("skt=%d, rslt=%d, timev.tv_sec=%ld, timev.tv_usec=%ld\n", skt, rslt, timev.tv_sec, timev.tv_usec); read_dns_response(skt, (struct sockaddr*)&dest, &resolved_addr); } else { puts("no select() event"); } return 0; }
enum pbpal_resolv_n_connect_result pbpal_resolv_and_connect(pubnub_t *pb) { int error; uint16_t port = HTTP_PORT; char const* origin; #ifdef PUBNUB_CALLBACK_API struct sockaddr_in dest; prepare_port_and_hostname(pb, &port, &origin); #if PUBNUB_PROXY_API if (0 != pb->proxy_ip_address.ipv4[0]) { struct pubnub_ipv4_address* p_dest_addr = (struct pubnub_ipv4_address*)&(dest.sin_addr.s_addr); memset(&dest, '\0', sizeof dest); memcpy(p_dest_addr->ipv4, pb->proxy_ip_address.ipv4, sizeof p_dest_addr->ipv4); dest.sin_family = AF_INET; return connect_TCP_socket(pb, dest, port); } #endif if (SOCKET_INVALID == pb->pal.socket) { pb->pal.socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); } if (SOCKET_INVALID == pb->pal.socket) { return pbpal_resolv_resource_failure; } pb->options.use_blocking_io = false; pbpal_set_blocking_io(pb); dest.sin_family = AF_INET; dest.sin_port = htons(DNS_PORT); get_dns_ip(&dest); error = send_dns_query(pb->pal.socket, (struct sockaddr*)&dest, origin); if (error < 0) { return pbpal_resolv_failed_send; } else if (error > 0) { return pbpal_resolv_send_wouldblock; } return pbpal_resolv_sent; #else char port_string[20]; struct addrinfo *result; struct addrinfo *it; struct addrinfo hint; hint.ai_socktype = SOCK_STREAM; hint.ai_family = AF_UNSPEC; hint.ai_protocol = hint.ai_flags = hint.ai_addrlen = 0; hint.ai_addr = NULL; hint.ai_canonname = NULL; hint.ai_next = NULL; prepare_port_and_hostname(pb, &port, &origin); snprintf(port_string, sizeof port_string, "%hu", port); error = getaddrinfo(origin, port_string, &hint, &result); if (error != 0) { return pbpal_resolv_failed_processing; } for (it = result; it != NULL; it = it->ai_next) { pb->pal.socket = socket(it->ai_family, it->ai_socktype, it->ai_protocol); if (pb->pal.socket == SOCKET_INVALID) { continue; } pbpal_set_blocking_io(pb); if (connect(pb->pal.socket, it->ai_addr, it->ai_addrlen) == SOCKET_ERROR) { if (socket_would_block()) { error = 1; break; } else { PUBNUB_LOG_WARNING("socket connect() failed, will try another IP address, if available\n"); socket_close(pb->pal.socket); pb->pal.socket = SOCKET_INVALID; continue; } } break; } freeaddrinfo(result); if (NULL == it) { return pbpal_connect_failed; } socket_set_rcv_timeout(pb->pal.socket, pb->transaction_timeout_ms); socket_disable_SIGPIPE(pb->pal.socket); return error ? pbpal_connect_wouldblock : pbpal_connect_success; #endif /* PUBNUB_CALLBACK_API */ }
enum pbpal_resolv_n_connect_result pbpal_resolv_and_connect(pubnub_t *pb) { int error; char const* origin = PUBNUB_ORIGIN_SETTABLE ? pb->origin : PUBNUB_ORIGIN; PUBNUB_ASSERT(pb_valid_ctx_ptr(pb)); PUBNUB_ASSERT_OPT((pb->state == PBS_READY) || (pb->state == PBS_WAIT_DNS_SEND) || (pb->state == PBS_WAIT_DNS_RCV)); if (PUBNUB_USE_ADNS) { struct sockaddr_in dest; int skt = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (SOCKET_INVALID == skt) { return pbpal_resolv_resource_failure; } pb->options.use_blocking_io = false; pbpal_set_blocking_io(pb); dest.sin_family = AF_INET; dest.sin_port = htons(DNS_PORT); inet_pton(AF_INET, "8.8.8.8", &dest.sin_addr.s_addr); error = send_dns_query(skt, (struct sockaddr*)&dest, (unsigned char*)origin); if (error < 0) { socket_close(skt); return pbpal_resolv_failed_send; } else if (error > 0) { return pbpal_resolv_send_wouldblock; } pb->pal.socket = skt; return pbpal_resolv_sent; } else { struct addrinfo *result; struct addrinfo *it; struct addrinfo hint; hint.ai_socktype = SOCK_STREAM; hint.ai_family = AF_UNSPEC; hint.ai_protocol = hint.ai_flags = hint.ai_addrlen = 0; hint.ai_addr = NULL; hint.ai_canonname = NULL; hint.ai_next = NULL; error = getaddrinfo(origin, HTTP_PORT_STRING, &hint, &result); if (error != 0) { return pbpal_resolv_failed_processing; } for (it = result; it != NULL; it = it->ai_next) { pb->pal.socket = socket(it->ai_family, it->ai_socktype, it->ai_protocol); if (pb->pal.socket == SOCKET_INVALID) { continue; } pbpal_set_blocking_io(pb); if (connect(pb->pal.socket, it->ai_addr, it->ai_addrlen) == SOCKET_ERROR) { if (socket_would_block()) { error = 1; break; } else { PUBNUB_LOG_WARNING("socket connect() failed, will try another IP address, if available\n"); socket_close(pb->pal.socket); pb->pal.socket = SOCKET_INVALID; continue; } } break; } freeaddrinfo(result); if (NULL == it) { return pbpal_connect_failed; } socket_set_rcv_timeout(pb->pal.socket, pb->transaction_timeout_ms); return error ? pbpal_connect_wouldblock : pbpal_connect_success; } }