Usermode/libc - Fix strchr and strrchr behavior
[tpg/acess2.git] / Usermode / Libraries / libnet.so_src / dns.c
1 /*
2  * Acess2 Networking Toolkit
3  * By John Hodge (thePowersGang)
4  * 
5  * dns.c
6  * - Hostname<->Address resolution
7  */
8 #include <stddef.h>     // size_t / NULL
9 #include <stdint.h>     // uint*_t
10 #include <string.h>     // memcpy, strchr
11 #include <assert.h>
12 #include <acess/sys.h>  // for _SysSelect
13 #include <acess/fd_set.h>       // FD_SET
14 #include <net.h>
15 #include "include/dns.h"
16 #include "include/dns_int.h"
17
18 // === PROTOTYPES ===
19 //int DNS_Query(int ServerAType, const void *ServerAddr, const char *name, enum eTypes type, enum eClass class, handle_record_t* handle_record, void *info);
20
21 // === CODE ===
22 int DNS_Query(int ServerAType, const void *ServerAddr, const char *name, enum eTypes type, enum eClass class, handle_record_t* handle_record, void *info)
23 {
24         char    packet[512];
25         size_t packlen = DNS_int_EncodeQuery(packet, sizeof(packet), name, type, class);
26         if( packlen == 0 ) {
27                 _SysDebug("DNS_Query - Serialising packet failed");
28                 return 2;
29         }
30         
31         // Send and wait for reply
32         // - Lock
33         //  > TODO: Lock DNS queries
34         // - Send
35         int sock = Net_OpenSocket_UDP(ServerAType, ServerAddr, 53, 0);
36         if( sock < 0 ) {
37                 // Connection failed
38                 _SysDebug("DNS_Query - UDP open failed");
39                 // TODO: Correctly report this failure with a useful error code
40                 return 1;
41         }
42         int rv = Net_UDP_SendTo(sock, 53, ServerAType, ServerAddr, packlen, packet);
43         if( rv != packlen ) {
44                 _SysDebug("DNS_Query - Write failed");
45                 // TODO: Error reporting
46                 _SysClose(sock);
47                 return 1;
48         }
49         // - Wait
50         {
51                  int    nfd = sock + 1;
52                 fd_set  fds;
53                 FD_ZERO(&fds);
54                 FD_SET(sock, &fds);
55                 int64_t timeout = 2000; // Give it two seconds, should be long enough
56                 rv = _SysSelect(nfd, &fds, NULL, NULL, &timeout, 0);
57                 if( rv == 0 ) {
58                         // Timeout with no reply, give up
59                         _SysDebug("DNS_Query - Timeout");
60                         _SysClose(sock);
61                         return 1;
62                 }
63                 if( rv < 0 ) {
64                         // Oops, select failed
65                         _SysDebug("DNS_Query - Select failure");
66                         _SysClose(sock);
67                         return 1;
68                 }
69         }
70         int return_len = Net_UDP_RecvFrom(sock, NULL, NULL, NULL, sizeof(packet), packet);
71         if( return_len <= 0 ) {
72                 // TODO: Error reporting
73                 _SysDebug("DNS_Query - Read failure");
74                 _SysClose(sock);
75                 return 1;
76         }
77         _SysClose(sock);
78         // - Release
79         //  > TODO: Lock DNS queries
80         
81         // For each response in the answer (and additional) sections, call the passed callback
82         return DNS_int_ParseResponse(packet, return_len, info, handle_record);
83 }
84

UCC git Repository :: git.ucc.asn.au