Changes in uspace/srv/net/udp/sock.c [695b6ff:6b0b508] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/udp/sock.c
r695b6ff r6b0b508 1 1 /* 2 2 * Copyright (c) 2008 Lukas Mejdrech 3 * Copyright (c) 201 3Jiri Svoboda3 * Copyright (c) 2012 Jiri Svoboda 4 4 * All rights reserved. 5 5 * … … 159 159 static void udp_sock_bind(udp_client_t *client, ipc_callid_t callid, ipc_call_t call) 160 160 { 161 int rc; 162 struct sockaddr_in *addr; 163 size_t addr_size; 164 socket_core_t *sock_core; 165 udp_sockdata_t *socket; 166 udp_sock_t fsock; 167 udp_error_t urc; 168 161 169 log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_bind()"); 162 170 log_msg(LOG_DEFAULT, LVL_DEBUG, " - async_data_write_accept"); 163 164 struct sockaddr_in6 *addr6= NULL;165 size_t addr_len; 166 int rc = async_data_write_accept((void **) &addr6, false, 0, 0, 0, &addr_len);171 172 addr = NULL; 173 174 rc = async_data_write_accept((void **) &addr, false, 0, 0, 0, &addr_size); 167 175 if (rc != EOK) { 168 176 async_answer_0(callid, rc); 169 return; 170 } 171 172 if ((addr_len != sizeof(struct sockaddr_in)) && 173 (addr_len != sizeof(struct sockaddr_in6))) { 177 goto out; 178 } 179 180 if (addr_size != sizeof(struct sockaddr_in)) { 174 181 async_answer_0(callid, EINVAL); 175 182 goto out; 176 183 } 177 184 178 struct sockaddr_in *addr = (struct sockaddr_in *) addr6;179 180 185 log_msg(LOG_DEFAULT, LVL_DEBUG, " - call socket_bind"); 181 182 186 rc = socket_bind(&client->sockets, &gsock, SOCKET_GET_SOCKET_ID(call), 183 addr 6, addr_len, UDP_FREE_PORTS_START, UDP_FREE_PORTS_END,187 addr, addr_size, UDP_FREE_PORTS_START, UDP_FREE_PORTS_END, 184 188 last_used_port); 185 189 if (rc != EOK) { … … 189 193 190 194 log_msg(LOG_DEFAULT, LVL_DEBUG, " - call socket_cores_find"); 191 192 socket_core_t *sock_core = socket_cores_find(&client->sockets, 193 SOCKET_GET_SOCKET_ID(call)); 195 sock_core = socket_cores_find(&client->sockets, SOCKET_GET_SOCKET_ID(call)); 194 196 if (sock_core == NULL) { 195 197 async_answer_0(callid, ENOENT); 196 198 goto out; 197 199 } 198 199 udp_sockdata_t *socket = 200 (udp_sockdata_t *) sock_core->specific_data; 201 202 udp_sock_t fsocket; 203 204 fsocket.port = sock_core->port; 205 206 switch (addr->sin_family) { 207 case AF_INET: 208 inet_sockaddr_in_addr(addr, &fsocket.addr); 209 break; 210 case AF_INET6: 211 inet_sockaddr_in6_addr(addr6, &fsocket.addr); 212 break; 213 default: 214 async_answer_0(callid, EINVAL); 215 goto out; 216 } 217 218 udp_error_t urc = udp_uc_set_local(socket->assoc, &fsocket); 219 200 201 socket = (udp_sockdata_t *)sock_core->specific_data; 202 203 fsock.addr.ipv4 = uint32_t_be2host(addr->sin_addr.s_addr); 204 fsock.port = sock_core->port; 205 urc = udp_uc_set_local(socket->assoc, &fsock); 206 220 207 switch (urc) { 221 208 case UDP_EOK: … … 234 221 assert(false); 235 222 } 236 223 237 224 log_msg(LOG_DEFAULT, LVL_DEBUG, " - success"); 238 225 async_answer_0(callid, rc); 239 240 226 out: 241 if (addr 6!= NULL)242 free(addr 6);227 if (addr != NULL) 228 free(addr); 243 229 } 244 230 … … 265 251 log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_send()"); 266 252 267 uint8_t *buffer = calloc(UDP_FRAGMENT_SIZE, 1); 268 if (buffer == NULL) { 269 async_answer_0(callid, ENOMEM); 270 return; 271 } 272 273 struct sockaddr_in6 *addr6 = NULL; 274 struct sockaddr_in *addr; 275 udp_sock_t fsocket; 276 udp_sock_t *fsocket_ptr; 253 struct sockaddr_in *addr = NULL; 254 udp_sock_t fsock; 255 udp_sock_t *fsock_ptr; 277 256 278 257 if (IPC_GET_IMETHOD(call) == NET_SOCKET_SENDTO) { 279 size_t addr_ len;280 int rc = async_data_write_accept((void **) &addr 6, false,281 0, 0, 0, &addr_ len);258 size_t addr_size; 259 int rc = async_data_write_accept((void **) &addr, false, 260 0, 0, 0, &addr_size); 282 261 if (rc != EOK) { 283 262 async_answer_0(callid, rc); … … 285 264 } 286 265 287 if ((addr_len != sizeof(struct sockaddr_in)) && 288 (addr_len != sizeof(struct sockaddr_in6))) { 266 if (addr_size != sizeof(struct sockaddr_in)) { 289 267 async_answer_0(callid, EINVAL); 290 268 goto out; 291 269 } 292 270 293 addr = (struct sockaddr_in *) addr6; 294 295 switch (addr->sin_family) { 296 case AF_INET: 297 inet_sockaddr_in_addr(addr, &fsocket.addr); 298 break; 299 case AF_INET6: 300 inet_sockaddr_in6_addr(addr6, &fsocket.addr); 301 break; 302 default: 303 async_answer_0(callid, EINVAL); 304 goto out; 305 } 306 307 fsocket.port = uint16_t_be2host(addr->sin_port); 308 fsocket_ptr = &fsocket; 271 fsock.addr.ipv4 = uint32_t_be2host(addr->sin_addr.s_addr); 272 fsock.port = uint16_t_be2host(addr->sin_port); 273 fsock_ptr = &fsock; 309 274 } else 310 fsock et_ptr = NULL;275 fsock_ptr = NULL; 311 276 312 277 int socket_id = SOCKET_GET_SOCKET_ID(call); … … 349 314 fibril_mutex_lock(&socket->lock); 350 315 351 if (inet_addr_is_any(&socket->assoc->ident.local.addr) && 352 socket->assoc->ident.iplink == 0) { 316 if (socket->assoc->ident.local.addr.ipv4 == UDP_IPV4_ANY) { 353 317 /* Determine local IP address */ 354 inet_addr_t loc_addr; 355 inet_addr_t rem_addr; 356 357 rem_addr = fsocket_ptr ? fsocket.addr : 358 socket->assoc->ident.foreign.addr; 318 inet_addr_t loc_addr, rem_addr; 319 320 rem_addr.ipv4 = fsock_ptr ? fsock.addr.ipv4 : 321 socket->assoc->ident.foreign.addr.ipv4; 359 322 360 323 int rc = inet_get_srcaddr(&rem_addr, 0, &loc_addr); … … 364 327 log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_sendto: Failed to " 365 328 "determine local address."); 366 goto out; 367 } 368 369 socket->assoc->ident.local.addr = loc_addr; 329 return; 330 } 331 332 socket->assoc->ident.local.addr.ipv4 = loc_addr.ipv4; 333 log_msg(LOG_DEFAULT, LVL_DEBUG, "Local IP address is %x", 334 socket->assoc->ident.local.addr.ipv4); 370 335 } 371 336 … … 386 351 length = UDP_FRAGMENT_SIZE; 387 352 353 uint8_t buffer[UDP_FRAGMENT_SIZE]; 388 354 int rc = async_data_write_finalize(wcallid, buffer, length); 389 355 if (rc != EOK) { … … 394 360 395 361 udp_error_t urc = 396 udp_uc_send(socket->assoc, fsock et_ptr, buffer, length, 0);362 udp_uc_send(socket->assoc, fsock_ptr, buffer, length, 0); 397 363 398 364 switch (urc) { … … 429 395 430 396 out: 431 if (addr6 != NULL) 432 free(addr6); 433 434 free(buffer); 397 if (addr != NULL) 398 free(addr); 435 399 } 436 400 437 401 static void udp_sock_recvfrom(udp_client_t *client, ipc_callid_t callid, ipc_call_t call) 438 402 { 403 int socket_id; 404 int flags; 405 size_t addr_length, length; 406 socket_core_t *sock_core; 407 udp_sockdata_t *socket; 408 ipc_call_t answer; 409 ipc_callid_t rcallid; 410 size_t data_len; 411 udp_error_t urc; 412 udp_sock_t rsock; 413 struct sockaddr_in addr; 414 int rc; 415 439 416 log_msg(LOG_DEFAULT, LVL_DEBUG, "%p: udp_sock_recv[from]()", client); 440 441 intsocket_id = SOCKET_GET_SOCKET_ID(call);442 443 socket_core_t *sock_core = 444 417 418 socket_id = SOCKET_GET_SOCKET_ID(call); 419 flags = SOCKET_GET_FLAGS(call); 420 421 sock_core = socket_cores_find(&client->sockets, socket_id); 445 422 if (sock_core == NULL) { 446 423 async_answer_0(callid, ENOTSOCK); 447 424 return; 448 425 } 449 450 udp_sockdata_t *socket = 451 (udp_sockdata_t *) sock_core->specific_data; 452 426 427 socket = (udp_sockdata_t *)sock_core->specific_data; 453 428 fibril_mutex_lock(&socket->lock); 454 429 455 430 if (socket->assoc == NULL) { 456 431 fibril_mutex_unlock(&socket->lock); … … 458 433 return; 459 434 } 460 435 436 (void)flags; 437 461 438 log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_recvfrom(): lock recv_buffer lock"); 462 463 439 fibril_mutex_lock(&socket->recv_buffer_lock); 464 465 while ((socket->recv_buffer_used == 0) && 466 (socket->recv_error == UDP_EOK)) { 440 while (socket->recv_buffer_used == 0 && socket->recv_error == UDP_EOK) { 467 441 log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_recvfrom(): wait for cv"); 468 442 fibril_condvar_wait(&socket->recv_buffer_cv, 469 443 &socket->recv_buffer_lock); 470 444 } 471 445 472 446 log_msg(LOG_DEFAULT, LVL_DEBUG, "Got data in sock recv_buffer"); 473 474 size_t data_len = socket->recv_buffer_used; 475 udp_error_t urc = socket->recv_error; 476 447 448 rsock = socket->recv_fsock; 449 data_len = socket->recv_buffer_used; 450 urc = socket->recv_error; 451 477 452 log_msg(LOG_DEFAULT, LVL_DEBUG, "**** recv data_len=%zu", data_len); 478 479 int rc; 480 453 481 454 switch (urc) { 482 455 case UDP_EOK: … … 493 466 assert(false); 494 467 } 495 468 496 469 log_msg(LOG_DEFAULT, LVL_DEBUG, "**** udp_uc_receive -> %d", rc); 497 498 470 if (rc != EOK) { 499 471 fibril_mutex_unlock(&socket->recv_buffer_lock); … … 502 474 return; 503 475 } 504 505 ipc_callid_t rcallid; 506 size_t addr_size = 0; 507 476 508 477 if (IPC_GET_IMETHOD(call) == NET_SOCKET_RECVFROM) { 509 /* Fill address */ 510 udp_sock_t *rsock = &socket->recv_fsock; 511 struct sockaddr_in addr; 512 struct sockaddr_in6 addr6; 513 size_t addr_length; 514 515 uint16_t addr_af = inet_addr_sockaddr_in(&rsock->addr, &addr, 516 &addr6); 517 518 switch (addr_af) { 519 case AF_INET: 520 addr.sin_port = host2uint16_t_be(rsock->port); 521 522 log_msg(LOG_DEFAULT, LVL_DEBUG, "addr read receive"); 523 if (!async_data_read_receive(&rcallid, &addr_length)) { 524 fibril_mutex_unlock(&socket->recv_buffer_lock); 525 fibril_mutex_unlock(&socket->lock); 526 async_answer_0(callid, EINVAL); 527 return; 528 } 529 530 if (addr_length > sizeof(addr)) 531 addr_length = sizeof(addr); 532 533 addr_size = sizeof(addr); 534 535 log_msg(LOG_DEFAULT, LVL_DEBUG, "addr read finalize"); 536 rc = async_data_read_finalize(rcallid, &addr, addr_length); 537 if (rc != EOK) { 538 fibril_mutex_unlock(&socket->recv_buffer_lock); 539 fibril_mutex_unlock(&socket->lock); 540 async_answer_0(callid, EINVAL); 541 return; 542 } 543 544 break; 545 case AF_INET6: 546 addr6.sin6_port = host2uint16_t_be(rsock->port); 547 548 log_msg(LOG_DEFAULT, LVL_DEBUG, "addr6 read receive"); 549 if (!async_data_read_receive(&rcallid, &addr_length)) { 550 fibril_mutex_unlock(&socket->recv_buffer_lock); 551 fibril_mutex_unlock(&socket->lock); 552 async_answer_0(callid, EINVAL); 553 return; 554 } 555 556 if (addr_length > sizeof(addr6)) 557 addr_length = sizeof(addr6); 558 559 addr_size = sizeof(addr6); 560 561 log_msg(LOG_DEFAULT, LVL_DEBUG, "addr6 read finalize"); 562 rc = async_data_read_finalize(rcallid, &addr6, addr_length); 563 if (rc != EOK) { 564 fibril_mutex_unlock(&socket->recv_buffer_lock); 565 fibril_mutex_unlock(&socket->lock); 566 async_answer_0(callid, EINVAL); 567 return; 568 } 569 570 break; 571 default: 478 /* Fill addr */ 479 addr.sin_family = AF_INET; 480 addr.sin_addr.s_addr = host2uint32_t_be(rsock.addr.ipv4); 481 addr.sin_port = host2uint16_t_be(rsock.port); 482 483 log_msg(LOG_DEFAULT, LVL_DEBUG, "addr read receive"); 484 if (!async_data_read_receive(&rcallid, &addr_length)) { 572 485 fibril_mutex_unlock(&socket->recv_buffer_lock); 573 486 fibril_mutex_unlock(&socket->lock); … … 575 488 return; 576 489 } 577 } 578 490 491 if (addr_length > sizeof(addr)) 492 addr_length = sizeof(addr); 493 494 log_msg(LOG_DEFAULT, LVL_DEBUG, "addr read finalize"); 495 rc = async_data_read_finalize(rcallid, &addr, addr_length); 496 if (rc != EOK) { 497 fibril_mutex_unlock(&socket->recv_buffer_lock); 498 fibril_mutex_unlock(&socket->lock); 499 async_answer_0(callid, EINVAL); 500 return; 501 } 502 } 503 579 504 log_msg(LOG_DEFAULT, LVL_DEBUG, "data read receive"); 580 581 size_t length;582 505 if (!async_data_read_receive(&rcallid, &length)) { 583 506 fibril_mutex_unlock(&socket->recv_buffer_lock); … … 586 509 return; 587 510 } 588 511 589 512 if (length > data_len) 590 513 length = data_len; 591 514 592 515 log_msg(LOG_DEFAULT, LVL_DEBUG, "data read finalize"); 593 594 516 rc = async_data_read_finalize(rcallid, socket->recv_buffer, length); 595 596 if ( (length < data_len) && (rc == EOK))517 518 if (length < data_len && rc == EOK) 597 519 rc = EOVERFLOW; 598 520 599 521 log_msg(LOG_DEFAULT, LVL_DEBUG, "read_data_length <- %zu", length); 600 601 ipc_call_t answer;602 603 522 IPC_SET_ARG2(answer, 0); 604 523 SOCKET_SET_READ_DATA_LENGTH(answer, length); 605 SOCKET_SET_ADDRESS_LENGTH(answer, addr_size);524 SOCKET_SET_ADDRESS_LENGTH(answer, sizeof(addr)); 606 525 async_answer_3(callid, EOK, IPC_GET_ARG1(answer), 607 526 IPC_GET_ARG2(answer), IPC_GET_ARG3(answer)); 608 527 609 528 socket->recv_buffer_used = 0; 610 529 611 530 fibril_condvar_broadcast(&socket->recv_buffer_cv); 612 531 fibril_mutex_unlock(&socket->recv_buffer_lock); … … 618 537 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_close()"); 619 538 int socket_id = SOCKET_GET_SOCKET_ID(call); 620 621 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_close() - find core"); 539 622 540 socket_core_t *sock_core = 623 541 socket_cores_find(&client->sockets, socket_id); 624 542 if (sock_core == NULL) { 625 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_close() - core not found");626 543 async_answer_0(callid, ENOTSOCK); 627 544 return; 628 545 } 629 630 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_close() - spec data"); 546 631 547 udp_sockdata_t *socket = 632 548 (udp_sockdata_t *) sock_core->specific_data; 633 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_close() - lock socket");634 549 fibril_mutex_lock(&socket->lock); 635 636 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_close() - lock socket buffer"); 637 fibril_mutex_lock(&socket->recv_buffer_lock); 638 log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_close - set socket->sock_core = NULL"); 639 socket->sock_core = NULL; 640 fibril_mutex_unlock(&socket->recv_buffer_lock); 641 642 udp_uc_reset(socket->assoc); 643 550 644 551 int rc = socket_destroy(NULL, socket_id, &client->sockets, &gsock, 645 552 udp_free_sock_data); 646 553 if (rc != EOK) { 647 log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_close - socket_destroy failed");648 554 fibril_mutex_unlock(&socket->lock); 649 555 async_answer_0(callid, rc); 650 556 return; 651 557 } 652 653 log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_close - broadcast recv_buffer_cv"); 654 fibril_condvar_broadcast(&socket->recv_buffer_cv); 655 558 656 559 fibril_mutex_unlock(&socket->lock); 657 560 async_answer_0(callid, EOK); … … 666 569 static void udp_sock_setsockopt(udp_client_t *client, ipc_callid_t callid, ipc_call_t call) 667 570 { 668 log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_setsockopt)"); 669 log_msg(LOG_DEFAULT, LVL_DEBUG, " - async_data_write_accept"); 670 671 void *data = NULL; 672 size_t data_len; 673 int rc = async_data_write_accept(&data, false, 0, 0, 0, &data_len); 674 if (rc != EOK) { 675 log_msg(LOG_DEFAULT, LVL_DEBUG, " - failed accepting data"); 676 async_answer_0(callid, rc); 677 return; 678 } 679 680 sysarg_t opt_level = SOL_SOCKET; 681 sysarg_t opt_name = SOCKET_GET_OPT_NAME(call); 682 683 if (opt_level != SOL_SOCKET || opt_name != SO_IPLINK || 684 data_len != sizeof(service_id_t)) { 685 log_msg(LOG_DEFAULT, LVL_DEBUG, " - failed opt_level/name/len"); 686 log_msg(LOG_DEFAULT, LVL_DEBUG, " - failed opt_level=%d, " 687 "opt_name=%d, data_len=%zu", (int)opt_level, (int)opt_name, 688 data_len); 689 async_answer_0(callid, EINVAL); 690 return; 691 } 692 693 log_msg(LOG_DEFAULT, LVL_DEBUG, " - call socket_cores_find"); 694 695 socket_core_t *sock_core = socket_cores_find(&client->sockets, 696 SOCKET_GET_SOCKET_ID(call)); 697 if (sock_core == NULL) { 698 log_msg(LOG_DEFAULT, LVL_DEBUG, " - failed getting sock_core"); 699 async_answer_0(callid, ENOENT); 700 return; 701 } 702 703 udp_sockdata_t *socket = 704 (udp_sockdata_t *) sock_core->specific_data; 705 706 service_id_t iplink = *(service_id_t *)data; 707 udp_uc_set_iplink(socket->assoc, iplink); 708 709 log_msg(LOG_DEFAULT, LVL_DEBUG, " - success"); 710 async_answer_0(callid, EOK); 711 } 712 571 log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_setsockopt()"); 572 async_answer_0(callid, ENOTSUP); 573 } 713 574 714 575 static int udp_sock_recv_fibril(void *arg) … … 721 582 log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_recv_fibril()"); 722 583 723 fibril_mutex_lock(&sock->recv_buffer_lock);724 725 584 while (true) { 726 585 log_msg(LOG_DEFAULT, LVL_DEBUG, "[] wait for rcv buffer empty()"); 727 while ((sock->recv_buffer_used != 0) && (sock->sock_core != NULL)) { 586 fibril_mutex_lock(&sock->recv_buffer_lock); 587 while (sock->recv_buffer_used != 0) { 728 588 fibril_condvar_wait(&sock->recv_buffer_cv, 729 589 &sock->recv_buffer_lock); 730 590 } 731 732 fibril_mutex_unlock(&sock->recv_buffer_lock); 733 591 734 592 log_msg(LOG_DEFAULT, LVL_DEBUG, "[] call udp_uc_receive()"); 735 593 urc = udp_uc_receive(sock->assoc, sock->recv_buffer, 736 594 UDP_FRAGMENT_SIZE, &rcvd, &xflags, &sock->recv_fsock); 737 fibril_mutex_lock(&sock->recv_buffer_lock);738 595 sock->recv_error = urc; 739 740 log_msg(LOG_DEFAULT, LVL_DEBUG, "[] udp_uc_receive -> %d", urc); 741 742 if (sock->sock_core != NULL) 743 udp_sock_notify_data(sock->sock_core); 744 596 597 udp_sock_notify_data(sock->sock_core); 598 745 599 if (urc != UDP_EOK) { 746 log_msg(LOG_DEFAULT, LVL_DEBUG, "[] urc != UDP_EOK, break");747 600 fibril_condvar_broadcast(&sock->recv_buffer_cv); 748 601 fibril_mutex_unlock(&sock->recv_buffer_lock); 749 602 break; 750 603 } 751 604 752 605 log_msg(LOG_DEFAULT, LVL_DEBUG, "[] got data - broadcast recv_buffer_cv"); 753 606 754 607 sock->recv_buffer_used = rcvd; 608 fibril_mutex_unlock(&sock->recv_buffer_lock); 755 609 fibril_condvar_broadcast(&sock->recv_buffer_cv); 756 610 } 757 611 758 log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_recv_fibril() exited loop");759 612 udp_uc_destroy(sock->assoc); 760 761 log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_recv_fibril() terminated");762 613 763 614 return 0; … … 772 623 /* Accept the connection */ 773 624 async_answer_0(iid, EOK); 774 775 log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_connection: begin");776 625 777 626 client.sess = async_callback_receive(EXCHANGE_SERIALIZE);
Note:
See TracChangeset
for help on using the changeset viewer.