@@ -0,0 +1,185 @@
1+// C-Side of the Idris network library
2+// (C) Simon Fowler, 2014
3+// MIT Licensed. Have fun!
14+static int socket_inited = 0;
15+static WSADATA wsa_data;
17+void* idrnet_malloc(int size) {
21+void idrnet_free(void* ptr) {
25+static int check_init()
27+ if (!socket_inited) {
28+ int result = WSAStartup(MAKEWORD(2, 2), &wsa_data);
29+ if (result == NO_ERROR) {
33+ return socket_inited;
36+int idrnet_bind(int sockfd, int family, int socket_type, char* host, int port) {
37+ struct addrinfo hints;
38+ struct addrinfo* address_res;
39+ // Convert port into string
41+ sprintf(str_port, "%d", port);
46+ // Set up hints structure
47+ memset(&hints, 0, sizeof(hints)); // zero out hints
48+ hints.ai_family = family;
49+ hints.ai_socktype = socket_type;
51+ // If the length of the hostname is 0 (i.e, it was set to Nothing in Idris)
52+ // then we want to instruct the C library to fill in the IP automatically
53+ if (strlen(host) == 0) {
54+ hints.ai_flags = AI_PASSIVE; // fill in IP automatically
57+ int addr_res = getaddrinfo(host, str_port, &hints, &address_res);
58+ if (addr_res == -1) {
62+ int bind_res = bind(sockfd, address_res->ai_addr, address_res->ai_addrlen);
63+ if (bind_res == -1) {
70+int idrnet_connect(int sockfd, int family, int socket_type, char* host, int port) {
72+ sprintf(str_port, "%d", port);
73+ struct addrinfo hints;
74+ struct addrinfo* remote_host;
79+ // Set up hints structure for getaddrinfo
80+ memset(&hints, 0, sizeof(hints));
81+ hints.ai_family = family;
82+ hints.ai_socktype = socket_type;
84+ // Get info about the remote host (DNS lookup etc)
85+ int addr_res = getaddrinfo(host, str_port, &hints, &remote_host);
86+ if (addr_res == -1) {
90+ int connect_res = connect(sockfd, remote_host->ai_addr, remote_host->ai_addrlen);
91+ if (connect_res == -1) {
99+int idrnet_sockaddr_family(void* sockaddr) {
100+ struct sockaddr* addr = (struct sockaddr*) sockaddr;
101+ return (int) addr->sa_family;
104+char* idrnet_sockaddr_ipv4(void* sockaddr) {
105+ struct sockaddr_in* addr = (struct sockaddr_in*) sockaddr;
106+ char* ip_addr = (char*) malloc(sizeof(char) * INET_ADDRSTRLEN);
107+ inet_ntop(AF_INET, &(addr->sin_addr), ip_addr, INET_ADDRSTRLEN);
111+void* idrnet_create_sockaddr() {
112+ return malloc(sizeof(struct sockaddr_storage));
116+int idrnet_accept(int sockfd, void* sockaddr) {
117+ struct sockaddr* addr = (struct sockaddr*) sockaddr;
118+ socklen_t addr_size = 0;
119+ if (!check_init()) {
122+ return accept(sockfd, addr, &addr_size);
125+int idrnet_send(int sockfd, char* data) {
126+ int len = strlen(data); // For now.
127+ if (!check_init()) {
130+ return send(sockfd, (void*) data, len, 0);
133+int idrnet_send_buf(int sockfd, void* data, int len) {
134+ if (!check_init()) {
137+ return send(sockfd, data, len, 0);
140+void* idrnet_recv(int sockfd, int len) {
141+ if (!check_init()) {
144+ idrnet_recv_result* res_struct =
145+ (idrnet_recv_result*) malloc(sizeof(idrnet_recv_result));
147+ char* buf = malloc(len + 1);
148+ int recv_res = recv(sockfd, buf, len, 0);
149+ res_struct->result = recv_res;
151+ if (recv_res > 0) { // Data was received
152+ buf[recv_res + 1] = 0x00; // Null-term, so Idris can interpret it
154+ res_struct->payload = (void*) buf;
155+ return (void*) res_struct;
158+int idrnet_recv_buf(int sockfd, void* buf, int len) {
159+ if (!check_init()) {
162+ return recv(sockfd, buf, len, 0);
165+int idrnet_get_recv_res(void* res_struct) {
166+ return (((idrnet_recv_result*) res_struct)->result);
169+void* idrnet_get_recv_payload(void* res_struct) {
170+ return (((idrnet_recv_result*) res_struct)->payload);
173+void idrnet_free_recv_struct(void* res_struct) {
174+ idrnet_recv_result* i_res_struct =
175+ (idrnet_recv_result*) res_struct;
176+ if (i_res_struct->payload != NULL) {
177+ free(i_res_struct->payload);