vmm: refactor cpuid vmexit handling (XCC)
[akaros.git] / tools / syscall_server / udp.c
1 #include <fcntl.h>
2 #include <stdio.h>
3
4 #include <stdlib.h>
5 #include <string.h>
6 #include <netdb.h>
7 #include <sys/socket.h>
8 #include <netinet/in.h>
9
10 #define UDP_ARR_SIZE 4096
11
12 int port = 44444;
13 char udp_arr[UDP_ARR_SIZE];
14 int udp_buf_len = 0;
15 int udp_cur_pos = 0;
16 struct sockaddr_in ret_addr;
17
18
19 int init_syscall_server(int* fd_read, int* fd_write) {
20
21         int listen_socket;
22
23         // Address structures
24         struct sockaddr_in server_addr;
25
26         // Size of our address structure
27         unsigned int addr_len = sizeof(struct sockaddr_in);
28
29         if ((listen_socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
30         {
31                 printf("Error: PORT: %i. Could not create socket.\n", port);
32                 exit(1);
33         }
34
35         // Setup sockaddr_in
36         server_addr.sin_family = AF_INET;
37         server_addr.sin_port = htons(port);
38         server_addr.sin_addr.s_addr=INADDR_ANY;
39         bzero(&(server_addr.sin_zero), 8);      // This is apparently a source of bugs? Who knew.
40
41         // Bind to the given port.
42         if (bind(listen_socket, (struct sockaddr *) &server_addr, sizeof(struct sockaddr)))
43         {
44                 printf("Error: Spawned Process, PORT: %i. Could not bind to port.\n", port);
45                 exit(1);
46         }
47
48         struct hostent *hp;
49         hp = gethostbyname("192.168.0.10");
50         memset(&ret_addr, 0, sizeof(ret_addr));
51         ret_addr.sin_family = AF_INET;
52         memcpy(&ret_addr.sin_addr, hp->h_addr, hp->h_length);
53         ret_addr.sin_port = htons(44443);
54
55         *fd_read = listen_socket;
56         *fd_write = listen_socket;
57         
58         return listen_socket + listen_socket;
59
60 }
61
62 int read_syscall_server(int fd, char* buf, int len) {
63
64         if (udp_buf_len == 0) {
65                 udp_buf_len = recvfrom(fd, udp_arr, UDP_ARR_SIZE, 0, 0, 0);
66
67                 if (udp_buf_len== 0)
68                         return -1;
69         }
70
71         if ((udp_cur_pos + len) > udp_buf_len)
72                 return -1;
73
74         memcpy(buf, udp_arr + udp_cur_pos, len);
75
76         udp_cur_pos = udp_cur_pos + len;
77
78         if (udp_cur_pos == udp_buf_len) {
79                 udp_cur_pos = 0;
80                 udp_buf_len = 0;
81         }
82
83         return len;
84
85 }
86
87 int write_syscall_server(int fd, char* buf, int len, int bytes_to_follow) {
88
89         static int bytes_buffered = 0;
90         static char* internal_buffer = NULL;
91         static int buffer_size = 0;
92         
93         if (bytes_to_follow != 0) {
94
95                 if (internal_buffer != NULL) {
96                         printf("Called buffered write after a buffered write. Illegal.\n");
97                         exit(1);
98                 }
99
100                 internal_buffer = malloc(len + bytes_to_follow);
101
102                 if (internal_buffer == NULL) {
103                         printf("Could not malloc send buffer.\n");
104                         exit(1);
105                 }
106
107                 buffer_size = len + bytes_to_follow;
108
109                 memcpy(internal_buffer, buf, len);
110
111                 bytes_buffered = len;
112
113                 return bytes_buffered;
114
115         } else if (bytes_buffered == 0) {
116                 return sendto(fd, buf, len, 0, (struct sockaddr *)&ret_addr, sizeof(ret_addr));
117         } else {
118
119                 if ((len + bytes_buffered) != buffer_size) {
120                         printf("Buffered size does not match actual size\n");
121                         exit(1);
122                 }
123
124                 if (internal_buffer == NULL) {
125                         printf("Bytes bufferd out of sync with buffer\n");
126                         exit(1);
127                 }
128
129                 memcpy(internal_buffer + bytes_buffered, buf, len);
130
131                 int ret_val = sendto(fd, internal_buffer, len + bytes_buffered, 0, 
132                                      (struct sockaddr *)&ret_addr, sizeof(ret_addr));
133                 
134                 free(internal_buffer);
135                 internal_buffer = NULL;
136                 bytes_buffered = 0;
137                 buffer_size = 0;
138
139                 return ret_val;
140
141         }
142 }