Changeset ee1c2d9 in mainline for uspace/srv/net/dnsrsrv/transport.c
- Timestamp:
- 2015-06-13T18:30:18Z (10 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- a157846
- Parents:
- 0453261 (diff), 2f9a8e8 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/dnsrsrv/transport.c
r0453261 ree1c2d9 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 … … 182 179 { 183 180 trans_req_t *treq = NULL; 184 struct sockaddr *saddr = NULL; 185 socklen_t saddrlen; 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 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 188 189 inet_ep_init(&ep); 190 ep.addr = dns_server_addr; 191 ep.port = DNS_SERVER_PORT; 192 200 193 size_t ntry = 0; 201 194 202 195 while (ntry < REQ_RETRY_MAX) { 203 rc = sendto(transport_fd, req_data, req_size, 0,204 saddr, saddrlen);196 rc = udp_assoc_send_msg(transport_assoc, &ep, req_data, 197 req_size); 205 198 if (rc != EOK) 206 199 goto error; 207 200 208 201 treq = treq_create(req); 209 202 if (treq == NULL) { … … 211 204 goto error; 212 205 } 213 206 214 207 fibril_mutex_lock(&treq->done_lock); 215 208 while (treq->done != true) { … … 221 214 } 222 215 } 223 216 224 217 fibril_mutex_unlock(&treq->done_lock); 225 218 226 219 if (rc != ETIMEOUT) 227 220 break; 228 221 } 229 222 230 223 if (ntry >= REQ_RETRY_MAX) { 231 224 rc = EIO; 232 225 goto error; 233 226 } 234 227 235 228 if (treq->status != EOK) { 236 229 rc = treq->status; 237 230 goto error; 238 231 } 239 232 240 233 *rresp = treq->resp; 241 234 treq_destroy(treq); 242 235 free(req_data); 243 free(saddr);244 236 return EOK; 245 237 246 238 error: 247 239 if (treq != NULL) 248 240 treq_destroy(treq); 249 241 250 242 free(req_data); 251 free(saddr);252 243 return rc; 253 244 } 254 245 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) 246 static void transport_recv_msg(udp_assoc_t *assoc, udp_rmsg_t *rmsg) 287 247 { 288 248 dns_message_t *resp = NULL; 289 249 trans_req_t *treq; 250 size_t size; 251 inet_ep_t remote_ep; 290 252 int rc; 291 253 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); 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) { 307 278 fibril_mutex_unlock(&treq_lock); 308 309 treq_complete(treq, resp); 310 } 311 312 return 0; 313 } 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 314 298 315 299 /** @}
Note:
See TracChangeset
for help on using the changeset viewer.