Changes in uspace/srv/net/dnsrsrv/transport.c [fab2746:b5f716b] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/dnsrsrv/transport.c
rfab2746 rb5f716b 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>42 39 #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 udp_t *transport_udp;75 static udp_assoc_t *transport_assoc;74 static fid_t recv_fid; 75 static int transport_fd = -1; 76 76 77 77 /** Outstanding requests */ … … 79 79 static FIBRIL_MUTEX_INITIALIZE(treq_lock); 80 80 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 }; 81 static int transport_recv_fibril(void *arg); 90 82 91 83 int transport_init(void) 92 84 { 93 inet_ep2_t epp; 85 struct sockaddr_in laddr; 86 int fd; 87 fid_t fid; 94 88 int rc; 95 89 96 inet_ep2_init(&epp); 97 98 rc = udp_create(&transport_udp); 99 if (rc != EOK) { 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) { 100 98 rc = EIO; 101 99 goto error; 102 100 } 103 101 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 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; 111 114 return EOK; 112 115 error: 113 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed initializing network .");114 udp_assoc_destroy(transport_assoc);115 udp_destroy(transport_udp);116 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed initializing network socket."); 117 if (fd >= 0) 118 closesocket(fd); 116 119 return rc; 117 120 } … … 119 122 void transport_fini(void) 120 123 { 121 udp_assoc_destroy(transport_assoc);122 udp_destroy(transport_udp);124 if (transport_fd >= 0) 125 closesocket(transport_fd); 123 126 } 124 127 … … 179 182 { 180 183 trans_req_t *treq = NULL; 181 inet_ep_t ep; 182 184 struct sockaddr *saddr = NULL; 185 socklen_t saddrlen; 186 183 187 void *req_data; 184 188 size_t req_size; … … 186 190 if (rc != EOK) 187 191 goto error; 188 189 inet_ep_init(&ep); 190 ep.addr = dns_server_addr; 191 ep.port = DNS_SERVER_PORT; 192 192 193 rc = inet_addr_sockaddr(&dns_server_addr, DNS_SERVER_PORT, 194 &saddr, &saddrlen); 195 if (rc != EOK) { 196 assert(rc == ENOMEM); 197 goto error; 198 } 199 193 200 size_t ntry = 0; 194 201 195 202 while (ntry < REQ_RETRY_MAX) { 196 rc = udp_assoc_send_msg(transport_assoc, &ep, req_data,197 req_size);203 rc = sendto(transport_fd, req_data, req_size, 0, 204 saddr, saddrlen); 198 205 if (rc != EOK) 199 206 goto error; 200 207 201 208 treq = treq_create(req); 202 209 if (treq == NULL) { … … 204 211 goto error; 205 212 } 206 213 207 214 fibril_mutex_lock(&treq->done_lock); 208 215 while (treq->done != true) { … … 214 221 } 215 222 } 216 223 217 224 fibril_mutex_unlock(&treq->done_lock); 218 225 219 226 if (rc != ETIMEOUT) 220 227 break; 221 228 } 222 229 223 230 if (ntry >= REQ_RETRY_MAX) { 224 231 rc = EIO; 225 232 goto error; 226 233 } 227 234 228 235 if (treq->status != EOK) { 229 236 rc = treq->status; 230 237 goto error; 231 238 } 232 239 233 240 *rresp = treq->resp; 234 241 treq_destroy(treq); 235 242 free(req_data); 243 free(saddr); 236 244 return EOK; 237 245 238 246 error: 239 247 if (treq != NULL) 240 248 treq_destroy(treq); 241 249 242 250 free(req_data); 251 free(saddr); 243 252 return rc; 244 253 } 245 254 246 static void transport_recv_msg(udp_assoc_t *assoc, udp_rmsg_t *rmsg) 255 static int transport_recv_msg(dns_message_t **rresp) 256 { 257 struct sockaddr_in src_addr; 258 socklen_t src_addr_size; 259 size_t recv_size; 260 dns_message_t *resp; 261 int rc; 262 263 src_addr_size = sizeof(src_addr); 264 rc = recvfrom(transport_fd, recv_buf, RECV_BUF_SIZE, 0, 265 (struct sockaddr *)&src_addr, &src_addr_size); 266 if (rc < 0) { 267 log_msg(LOG_DEFAULT, LVL_ERROR, "recvfrom returns error - %d", rc); 268 goto error; 269 } 270 271 recv_size = (size_t)rc; 272 273 rc = dns_message_decode(recv_buf, recv_size, &resp); 274 if (rc != EOK) { 275 rc = EIO; 276 goto error; 277 } 278 279 *rresp = resp; 280 return EOK; 281 282 error: 283 return rc; 284 } 285 286 static int transport_recv_fibril(void *arg) 247 287 { 248 288 dns_message_t *resp = NULL; 249 289 trans_req_t *treq; 250 size_t size;251 inet_ep_t remote_ep;252 290 int rc; 253 291 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); 259 if (rc != EOK) { 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) { 292 while (true) { 293 rc = transport_recv_msg(&resp); 294 if (rc != EOK) 295 continue; 296 297 assert(resp != NULL); 298 299 fibril_mutex_lock(&treq_lock); 300 treq = treq_match_resp(resp); 301 if (treq == NULL) { 302 fibril_mutex_unlock(&treq_lock); 303 continue; 304 } 305 306 list_remove(&treq->lreq); 278 307 fibril_mutex_unlock(&treq_lock); 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 308 309 treq_complete(treq, resp); 310 } 311 312 return 0; 313 } 298 314 299 315 /** @}
Note:
See TracChangeset
for help on using the changeset viewer.