Changes in uspace/srv/net/dnsrsrv/transport.c [02a09ed:fab2746] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/dnsrsrv/transport.c
r02a09ed rfab2746 37 37 #include <errno.h> 38 38 #include <fibril_synch.h> 39 #include <inet/addr.h> 40 #include <inet/endpoint.h> 41 #include <inet/udp.h> 39 42 #include <io/log.h> 40 #include <net/in.h>41 #include <net/inet.h>42 #include <net/socket.h>43 43 #include <stdbool.h> 44 44 #include <stdlib.h> … … 72 72 73 73 static uint8_t recv_buf[RECV_BUF_SIZE]; 74 static fid_t recv_fid;75 static int transport_fd = -1;74 static udp_t *transport_udp; 75 static udp_assoc_t *transport_assoc; 76 76 77 77 /** Outstanding requests */ … … 79 79 static FIBRIL_MUTEX_INITIALIZE(treq_lock); 80 80 81 static int transport_recv_fibril(void *arg); 81 static void transport_recv_msg(udp_assoc_t *, udp_rmsg_t *); 82 static void transport_recv_err(udp_assoc_t *, udp_rerr_t *); 83 static void transport_link_state(udp_assoc_t *, udp_link_state_t); 84 85 static udp_cb_t transport_cb = { 86 .recv_msg = transport_recv_msg, 87 .recv_err = transport_recv_err, 88 .link_state = transport_link_state 89 }; 82 90 83 91 int transport_init(void) 84 92 { 85 struct sockaddr_in laddr; 86 int fd; 87 fid_t fid; 93 inet_ep2_t epp; 88 94 int rc; 89 95 90 laddr.sin_family = AF_INET; 91 laddr.sin_port = htons(12345); 92 laddr.sin_addr.s_addr = INADDR_ANY; 93 94 fd = -1; 95 96 fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); 97 if (fd < 0) { 96 inet_ep2_init(&epp); 97 98 rc = udp_create(&transport_udp); 99 if (rc != EOK) { 98 100 rc = EIO; 99 101 goto error; 100 102 } 101 103 102 rc = bind(fd, (struct sockaddr *)&laddr, sizeof(laddr)); 103 if (rc != EOK) 104 goto error; 105 106 transport_fd = fd; 107 108 fid = fibril_create(transport_recv_fibril, NULL); 109 if (fid == 0) 110 goto error; 111 112 fibril_add_ready(fid); 113 recv_fid = fid; 104 rc = udp_assoc_create(transport_udp, &epp, &transport_cb, NULL, 105 &transport_assoc); 106 if (rc != EOK) { 107 rc = EIO; 108 goto error; 109 } 110 114 111 return EOK; 115 112 error: 116 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed initializing network socket.");117 if (fd >= 0)118 closesocket(fd);113 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed initializing network."); 114 udp_assoc_destroy(transport_assoc); 115 udp_destroy(transport_udp); 119 116 return rc; 120 117 } … … 122 119 void transport_fini(void) 123 120 { 124 if (transport_fd >= 0)125 closesocket(transport_fd);121 udp_assoc_destroy(transport_assoc); 122 udp_destroy(transport_udp); 126 123 } 127 124 … … 158 155 assert(fibril_mutex_is_locked(&treq_lock)); 159 156 160 list_foreach(treq_list, link) { 161 trans_req_t *treq = list_get_instance(link, trans_req_t, lreq); 162 157 list_foreach(treq_list, lreq, trans_req_t, treq) { 163 158 if (treq->req->id == resp->id) { 164 159 /* Match */ … … 184 179 { 185 180 trans_req_t *treq = NULL; 186 181 inet_ep_t ep; 182 187 183 void *req_data; 188 184 size_t req_size; … … 190 186 if (rc != EOK) 191 187 goto error; 192 193 struct sockaddr_in addr; 194 struct sockaddr_in6 addr6; 195 uint16_t af = 196 inet_addr_sockaddr_in(&dns_server_addr, &addr, &addr6); 197 198 struct sockaddr *address; 199 socklen_t addrlen; 200 201 switch (af) { 202 case AF_INET: 203 addr.sin_port = htons(DNS_SERVER_PORT); 204 address = (struct sockaddr *) &addr; 205 addrlen = sizeof(addr); 206 break; 207 case AF_INET6: 208 addr6.sin6_port = htons(DNS_SERVER_PORT); 209 address = (struct sockaddr *) &addr6; 210 addrlen = sizeof(addr6); 211 break; 212 default: 213 rc = EAFNOSUPPORT; 214 goto error; 215 } 216 188 189 inet_ep_init(&ep); 190 ep.addr = dns_server_addr; 191 ep.port = DNS_SERVER_PORT; 192 217 193 size_t ntry = 0; 218 194 219 195 while (ntry < REQ_RETRY_MAX) { 220 rc = sendto(transport_fd, req_data, req_size, 0,221 (struct sockaddr *) address, addrlen);196 rc = udp_assoc_send_msg(transport_assoc, &ep, req_data, 197 req_size); 222 198 if (rc != EOK) 223 199 goto error; 224 200 225 201 treq = treq_create(req); 226 202 if (treq == NULL) { … … 228 204 goto error; 229 205 } 230 206 231 207 fibril_mutex_lock(&treq->done_lock); 232 208 while (treq->done != true) { … … 238 214 } 239 215 } 240 216 241 217 fibril_mutex_unlock(&treq->done_lock); 242 218 243 219 if (rc != ETIMEOUT) 244 220 break; 245 221 } 246 222 247 223 if (ntry >= REQ_RETRY_MAX) { 248 224 rc = EIO; 249 225 goto error; 250 226 } 251 227 252 228 if (treq->status != EOK) { 253 229 rc = treq->status; 254 230 goto error; 255 231 } 256 232 257 233 *rresp = treq->resp; 258 234 treq_destroy(treq); 259 235 free(req_data); 260 236 return EOK; 261 237 262 238 error: 263 239 if (treq != NULL) 264 240 treq_destroy(treq); 265 241 266 242 free(req_data); 267 243 return rc; 268 244 } 269 245 270 static int transport_recv_msg(dns_message_t **rresp)271 { 272 struct sockaddr_in src_addr;273 socklen_t src_addr_size;274 size_t recv_size;275 dns_message_t *resp;246 static void transport_recv_msg(udp_assoc_t *assoc, udp_rmsg_t *rmsg) 247 { 248 dns_message_t *resp = NULL; 249 trans_req_t *treq; 250 size_t size; 251 inet_ep_t remote_ep; 276 252 int rc; 277 253 278 src_addr_size = sizeof(src_addr); 279 rc = recvfrom(transport_fd, recv_buf, RECV_BUF_SIZE, 0, 280 (struct sockaddr *)&src_addr, &src_addr_size); 281 if (rc < 0) { 282 log_msg(LOG_DEFAULT, LVL_ERROR, "recvfrom returns error - %d", rc); 283 goto error; 284 } 285 286 recv_size = (size_t)rc; 287 288 rc = dns_message_decode(recv_buf, recv_size, &resp); 254 size = udp_rmsg_size(rmsg); 255 if (size > RECV_BUF_SIZE) 256 size = RECV_BUF_SIZE; /* XXX */ 257 258 rc = udp_rmsg_read(rmsg, 0, recv_buf, size); 289 259 if (rc != EOK) { 290 rc = EIO; 291 goto error; 292 } 293 294 *rresp = resp; 295 return EOK; 296 297 error: 298 return rc; 299 } 300 301 static int transport_recv_fibril(void *arg) 302 { 303 dns_message_t *resp; 304 trans_req_t *treq; 305 int rc; 306 307 while (true) { 308 rc = transport_recv_msg(&resp); 309 if (rc != EOK) 310 continue; 311 312 fibril_mutex_lock(&treq_lock); 313 treq = treq_match_resp(resp); 314 if (treq == NULL) { 315 fibril_mutex_unlock(&treq_lock); 316 continue; 317 } 318 319 list_remove(&treq->lreq); 260 log_msg(LOG_DEFAULT, LVL_ERROR, "Error reading message."); 261 return; 262 } 263 264 udp_rmsg_remote_ep(rmsg, &remote_ep); 265 /* XXX */ 266 267 rc = dns_message_decode(recv_buf, size, &resp); 268 if (rc != EOK) { 269 log_msg(LOG_DEFAULT, LVL_ERROR, "Error decoding message."); 270 return; 271 } 272 273 assert(resp != NULL); 274 275 fibril_mutex_lock(&treq_lock); 276 treq = treq_match_resp(resp); 277 if (treq == NULL) { 320 278 fibril_mutex_unlock(&treq_lock); 321 322 treq_complete(treq, resp); 323 } 324 325 return 0; 326 } 279 return; 280 } 281 282 list_remove(&treq->lreq); 283 fibril_mutex_unlock(&treq_lock); 284 285 treq_complete(treq, resp); 286 } 287 288 static void transport_recv_err(udp_assoc_t *assoc, udp_rerr_t *rerr) 289 { 290 log_msg(LOG_DEFAULT, LVL_WARN, "Ignoring ICMP error"); 291 } 292 293 static void transport_link_state(udp_assoc_t *assoc, udp_link_state_t ls) 294 { 295 log_msg(LOG_DEFAULT, LVL_NOTE, "Link state change"); 296 } 297 327 298 328 299 /** @}
Note:
See TracChangeset
for help on using the changeset viewer.