serve.c (3027B)
1 2 #include <sys/types.h> 3 #include <sys/socket.h> 4 #include <netinet/in.h> 5 #include <arpa/inet.h> 6 #include <stdio.h> 7 #include <string.h> 8 #include <errno.h> 9 #include <assert.h> 10 #include <stdlib.h> 11 12 #include "serve.h" 13 #include "entity.h" 14 #include "net.h" 15 #include "io.h" 16 17 #define MAX_CACHED_FILES 12 18 19 int inet_aton(const char *cp, struct in_addr *inp); 20 21 struct file_cache { 22 const char *path; 23 int data_len; 24 unsigned char *dat; 25 }; 26 27 static int load_data(struct cursor *buf, const char *path, 28 int *data_len, unsigned char **data) 29 { 30 int ok; 31 32 ok = read_file(path, buf->p, buf->end - buf->p, data_len); 33 if (!ok) return 0; 34 35 assert(*data_len <= buf->end - buf->p); 36 37 *data = buf->p; 38 39 buf->p += *data_len; 40 41 return 1; 42 } 43 44 static int make_fetch_response(struct cursor *buf, 45 struct packet *response, 46 const char *path) 47 { 48 int data_len, ok; 49 data_len = 0; 50 51 ok = load_data(buf, path, &data_len, 52 &response->data.fetch_response.data); 53 54 /* printf("load_data %d ok %d\n", data_len, ok); */ 55 56 if (!ok) return 0; 57 58 response->type = PKT_FETCH_DATA_RESPONSE; 59 response->data.fetch_response.path = path; 60 response->data.fetch_response.data_len = data_len; 61 62 return 1; 63 } 64 65 static int handle_packet(int sockfd, 66 struct env *env, 67 struct cursor *buf, 68 struct sockaddr_in *from, 69 struct packet *packet) 70 { 71 struct packet response; 72 int ok; 73 74 print_packet(env, packet); 75 switch (packet->type) { 76 case PKT_MESSAGE: 77 return send_packet(sockfd, from, packet); 78 case PKT_FETCH_DATA: 79 ok = make_fetch_response(buf, &response, 80 packet->data.fetch.path); 81 if (!ok) return 0; 82 return send_packet(sockfd, from, &response); 83 case PKT_FETCH_DATA_RESPONSE: 84 printf("todo: handle fetch response\n"); 85 return 0; 86 case PKT_NUM_TYPES: 87 return 0; 88 } 89 90 return 0; 91 } 92 93 94 int protoverse_serve(struct protoverse_server *server) 95 { 96 #define FILEBUF_SIZE 31457280 97 static unsigned char *buf_; 98 99 struct in_addr my_addr; 100 struct sockaddr_in bind_addr; 101 struct sockaddr_in from; 102 struct packet packet; 103 struct cursor buf; 104 /* socklen_t from_addr_len; */ 105 106 int err, ok, fd; 107 108 buf_ = malloc(FILEBUF_SIZE); 109 make_cursor(buf_, buf_ + FILEBUF_SIZE, &buf); 110 111 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { 112 printf("socket creation failed: %s\n", strerror(errno)); 113 return 0; 114 } 115 116 if (inet_aton(server->bind, &my_addr) == 0) { 117 printf("inet_aton failed: %s\n", strerror(errno)); 118 return 0; 119 } 120 121 bind_addr.sin_family = AF_INET; 122 bind_addr.sin_port = server->port == 0 || server->port == -1 ? 1988 : server->port; 123 bind_addr.sin_addr = my_addr; 124 125 err = bind(fd, (struct sockaddr*)&bind_addr, sizeof(bind_addr)) == -1; 126 127 if (err) { 128 printf("bind failed: %s\n", strerror(errno)); 129 return 0; 130 } 131 132 while (1) { 133 ok = recv_packet(fd, &buf, &from, &packet); 134 if (!ok) { 135 printf("malformed packet\n"); 136 continue; 137 } 138 139 ok = handle_packet(fd, &server->env, &buf, &from, &packet); 140 if (!ok) { 141 printf("handle packet failed for "); 142 print_packet(&server->env, &packet); 143 } 144 145 buf.p = buf.start; 146 } 147 148 free(buf_); 149 }