Changes in uspace/srv/net/udp/sock.c [02a09ed:69a93df7] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/udp/sock.c
r02a09ed r69a93df7 43 43 #include <ipc/services.h> 44 44 #include <ipc/socket.h> 45 #include <net/modules.h> 45 46 #include <net/socket.h> 46 47 #include <ns.h> … … 51 52 #include "ucall.h" 52 53 54 #define FRAGMENT_SIZE 1024 55 53 56 /** Free ports pool start. */ 54 57 #define UDP_FREE_PORTS_START 1025 … … 61 64 62 65 static void udp_sock_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg); 63 static int udp_sock_recv_fibril(void *arg);64 66 65 67 int udp_sock_init(void) 66 68 { 69 int rc; 70 67 71 socket_ports_initialize(&gsock); 68 72 69 73 async_set_client_connection(udp_sock_connection); 70 71 intrc = service_register(SERVICE_UDP);74 75 rc = service_register(SERVICE_UDP); 72 76 if (rc != EOK) 73 77 return EEXIST; 74 78 75 79 return EOK; 76 80 } … … 82 86 socket = (udp_sockdata_t *)sock_core->specific_data; 83 87 (void)socket; 84 85 /* XXX We need to force the receive fibril to quit */86 88 } 87 89 88 90 static void udp_sock_notify_data(socket_core_t *sock_core) 89 91 { 90 log_msg(L OG_DEFAULT, LVL_DEBUG, "udp_sock_notify_data(%d)", sock_core->socket_id);92 log_msg(LVL_DEBUG, "udp_sock_notify_data(%d)", sock_core->socket_id); 91 93 async_exch_t *exch = async_exchange_begin(sock_core->sess); 92 async_msg_5(exch, NET_SOCKET_RECEIVED, (sysarg_t) 93 UDP_FRAGMENT_SIZE, 0, 0, 1);94 async_msg_5(exch, NET_SOCKET_RECEIVED, (sysarg_t)sock_core->socket_id, 95 FRAGMENT_SIZE, 0, 0, 1); 94 96 async_exchange_end(exch); 95 97 } … … 103 105 ipc_call_t answer; 104 106 105 log_msg(L OG_DEFAULT, LVL_DEBUG, "udp_sock_socket()");106 sock = calloc( 1, sizeof(udp_sockdata_t));107 log_msg(LVL_DEBUG, "udp_sock_socket()"); 108 sock = calloc(sizeof(udp_sockdata_t), 1); 107 109 if (sock == NULL) { 108 110 async_answer_0(callid, ENOMEM); … … 113 115 sock->client = client; 114 116 115 sock->recv_buffer_used = 0;116 sock->recv_error = UDP_EOK;117 fibril_mutex_initialize(&sock->recv_buffer_lock);118 fibril_condvar_initialize(&sock->recv_buffer_cv);119 120 117 rc = udp_uc_create(&sock->assoc); 121 118 if (rc != EOK) { 119 udp_uc_destroy(sock->assoc); 122 120 free(sock); 123 121 async_answer_0(callid, rc); 124 return;125 }126 127 sock->recv_fibril = fibril_create(udp_sock_recv_fibril, sock);128 if (sock->recv_fibril == 0) {129 udp_uc_destroy(sock->assoc);130 free(sock);131 async_answer_0(callid, ENOMEM);132 122 return; 133 123 } … … 136 126 rc = socket_create(&client->sockets, client->sess, sock, &sock_id); 137 127 if (rc != EOK) { 138 fibril_destroy(sock->recv_fibril);139 udp_uc_destroy(sock->assoc);140 free(sock);141 128 async_answer_0(callid, rc); 142 129 return; 143 130 } 144 145 fibril_add_ready(sock->recv_fibril);146 131 147 132 sock_core = socket_cores_find(&client->sockets, sock_id); 148 133 assert(sock_core != NULL); 149 134 sock->sock_core = sock_core; 150 135 136 137 refresh_answer(&answer, NULL); 151 138 SOCKET_SET_SOCKET_ID(answer, sock_id); 152 139 153 SOCKET_SET_DATA_FRAGMENT_SIZE(answer, UDP_FRAGMENT_SIZE);140 SOCKET_SET_DATA_FRAGMENT_SIZE(answer, FRAGMENT_SIZE); 154 141 SOCKET_SET_HEADER_SIZE(answer, sizeof(udp_header_t)); 155 async_answer_3(callid, EOK, IPC_GET_ARG1(answer), 156 IPC_GET_ARG2(answer), IPC_GET_ARG3(answer)); 142 answer_call(callid, EOK, &answer, 3); 157 143 } 158 144 159 145 static void udp_sock_bind(udp_client_t *client, ipc_callid_t callid, ipc_call_t call) 160 146 { 161 log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_bind()"); 162 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); 147 int rc; 148 struct sockaddr_in *addr; 149 size_t addr_size; 150 socket_core_t *sock_core; 151 udp_sockdata_t *socket; 152 udp_sock_t fsock; 153 udp_error_t urc; 154 155 log_msg(LVL_DEBUG, "udp_sock_bind()"); 156 log_msg(LVL_DEBUG, " - async_data_write_accept"); 157 158 addr = NULL; 159 160 rc = async_data_write_accept((void **) &addr, false, 0, 0, 0, &addr_size); 167 161 if (rc != EOK) { 168 162 async_answer_0(callid, rc); 169 return;170 }171 172 if ((addr_len != sizeof(struct sockaddr_in)) &&173 (addr_len != sizeof(struct sockaddr_in6))) {174 async_answer_0(callid, EINVAL);175 163 goto out; 176 164 } 177 178 struct sockaddr_in *addr = (struct sockaddr_in *) addr6; 179 180 log_msg(LOG_DEFAULT, LVL_DEBUG, " - call socket_bind"); 181 165 166 log_msg(LVL_DEBUG, " - call socket_bind"); 182 167 rc = socket_bind(&client->sockets, &gsock, SOCKET_GET_SOCKET_ID(call), 183 addr 6, addr_len, UDP_FREE_PORTS_START, UDP_FREE_PORTS_END,168 addr, addr_size, UDP_FREE_PORTS_START, UDP_FREE_PORTS_END, 184 169 last_used_port); 185 170 if (rc != EOK) { … … 187 172 goto out; 188 173 } 189 190 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)); 174 175 if (addr_size != sizeof(struct sockaddr_in)) { 176 async_answer_0(callid, EINVAL); 177 goto out; 178 } 179 180 log_msg(LVL_DEBUG, " - call socket_cores_find"); 181 sock_core = socket_cores_find(&client->sockets, SOCKET_GET_SOCKET_ID(call)); 194 182 if (sock_core == NULL) { 195 183 async_answer_0(callid, ENOENT); 196 184 goto out; 197 185 } 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 186 187 socket = (udp_sockdata_t *)sock_core->specific_data; 188 189 fsock.addr.ipv4 = uint32_t_be2host(addr->sin_addr.s_addr); 190 fsock.port = sock_core->port; 191 urc = udp_uc_set_local(socket->assoc, &fsock); 192 220 193 switch (urc) { 221 194 case UDP_EOK: … … 234 207 assert(false); 235 208 } 236 237 log_msg(LOG_DEFAULT, LVL_DEBUG, " - success"); 209 210 udp_sock_notify_data(sock_core); 211 212 log_msg(LVL_DEBUG, " - success"); 238 213 async_answer_0(callid, rc); 239 240 214 out: 241 if (addr 6!= NULL)242 free(addr 6);215 if (addr != NULL) 216 free(addr); 243 217 } 244 218 245 219 static void udp_sock_listen(udp_client_t *client, ipc_callid_t callid, ipc_call_t call) 246 220 { 247 log_msg(L OG_DEFAULT, LVL_DEBUG, "udp_sock_listen()");221 log_msg(LVL_DEBUG, "udp_sock_listen()"); 248 222 async_answer_0(callid, ENOTSUP); 249 223 } … … 251 225 static void udp_sock_connect(udp_client_t *client, ipc_callid_t callid, ipc_call_t call) 252 226 { 253 log_msg(L OG_DEFAULT, LVL_DEBUG, "udp_sock_connect()");227 log_msg(LVL_DEBUG, "udp_sock_connect()"); 254 228 async_answer_0(callid, ENOTSUP); 255 229 } … … 257 231 static void udp_sock_accept(udp_client_t *client, ipc_callid_t callid, ipc_call_t call) 258 232 { 259 log_msg(L OG_DEFAULT, LVL_DEBUG, "udp_sock_accept()");233 log_msg(LVL_DEBUG, "udp_sock_accept()"); 260 234 async_answer_0(callid, ENOTSUP); 261 235 } … … 263 237 static void udp_sock_sendto(udp_client_t *client, ipc_callid_t callid, ipc_call_t call) 264 238 { 265 log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_send()");266 267 struct sockaddr_in6 *addr6 = NULL;239 int socket_id; 240 int fragments; 241 int index; 268 242 struct sockaddr_in *addr; 269 udp_sock_t fsocket; 270 udp_sock_t *fsocket_ptr; 271 243 size_t addr_size; 244 socket_core_t *sock_core; 245 udp_sockdata_t *socket; 246 udp_sock_t fsock, *fsockp; 247 ipc_call_t answer; 248 ipc_callid_t wcallid; 249 size_t length; 250 uint8_t buffer[FRAGMENT_SIZE]; 251 udp_error_t urc; 252 int rc; 253 254 log_msg(LVL_DEBUG, "udp_sock_send()"); 255 256 addr = NULL; 257 272 258 if (IPC_GET_IMETHOD(call) == NET_SOCKET_SENDTO) { 273 size_t addr_len; 274 int rc = async_data_write_accept((void **) &addr6, false, 275 0, 0, 0, &addr_len); 259 rc = async_data_write_accept((void **) &addr, false, 260 0, 0, 0, &addr_size); 276 261 if (rc != EOK) { 277 262 async_answer_0(callid, rc); 278 return; 279 } 280 281 if ((addr_len != sizeof(struct sockaddr_in)) && 282 (addr_len != sizeof(struct sockaddr_in6))) { 263 goto out; 264 } 265 266 if (addr_size != sizeof(struct sockaddr_in)) { 283 267 async_answer_0(callid, EINVAL); 284 268 goto out; 285 269 } 286 287 addr = (struct sockaddr_in *) addr6; 288 289 switch (addr->sin_family) { 290 case AF_INET: 291 inet_sockaddr_in_addr(addr, &fsocket.addr); 292 break; 293 case AF_INET6: 294 inet_sockaddr_in6_addr(addr6, &fsocket.addr); 295 break; 296 default: 297 async_answer_0(callid, EINVAL); 298 goto out; 299 } 300 301 fsocket.port = uint16_t_be2host(addr->sin_port); 302 fsocket_ptr = &fsocket; 303 } else 304 fsocket_ptr = NULL; 305 306 int socket_id = SOCKET_GET_SOCKET_ID(call); 307 270 271 fsock.addr.ipv4 = uint32_t_be2host(addr->sin_addr.s_addr); 272 fsock.port = uint16_t_be2host(addr->sin_port); 273 fsockp = &fsock; 274 } else { 275 fsockp = NULL; 276 } 277 278 socket_id = SOCKET_GET_SOCKET_ID(call); 279 fragments = SOCKET_GET_DATA_FRAGMENTS(call); 308 280 SOCKET_GET_FLAGS(call); 309 310 socket_core_t *sock_core = 311 socket_cores_find(&client->sockets, socket_id); 281 282 sock_core = socket_cores_find(&client->sockets, socket_id); 312 283 if (sock_core == NULL) { 313 284 async_answer_0(callid, ENOTSOCK); 314 285 goto out; 315 286 } 316 317 udp_sockdata_t *socket = 318 (udp_sockdata_t *) sock_core->specific_data; 319 320 if (sock_core->port <= 0) { 287 288 if (sock_core->port == 0) { 321 289 /* Implicitly bind socket to port */ 322 int rc = socket_bind_free_port(&gsock, sock_core, 323 UDP_FREE_PORTS_START, UDP_FREE_PORTS_END, last_used_port); 290 rc = socket_bind(&client->sockets, &gsock, SOCKET_GET_SOCKET_ID(call), 291 addr, addr_size, UDP_FREE_PORTS_START, UDP_FREE_PORTS_END, 292 last_used_port); 324 293 if (rc != EOK) { 325 294 async_answer_0(callid, rc); 326 295 goto out; 327 296 } 328 329 assert(sock_core->port > 0); 330 331 udp_error_t urc = udp_uc_set_local_port(socket->assoc, 332 sock_core->port); 333 334 if (urc != UDP_EOK) { 335 // TODO: better error handling 336 async_answer_0(callid, EINTR); 337 goto out; 338 } 339 340 last_used_port = sock_core->port; 341 } 342 297 298 udp_sock_notify_data(sock_core); 299 } 300 301 socket = (udp_sockdata_t *)sock_core->specific_data; 343 302 fibril_mutex_lock(&socket->lock); 344 345 if ( inet_addr_is_any(&socket->assoc->ident.local.addr)) {303 304 if (socket->assoc->ident.local.addr.ipv4 == UDP_IPV4_ANY) { 346 305 /* Determine local IP address */ 347 inet_addr_t loc_addr; 348 inet_addr_t rem_addr; 349 350 rem_addr = fsocket_ptr ? fsocket.addr : 351 socket->assoc->ident.foreign.addr; 352 353 int rc = inet_get_srcaddr(&rem_addr, 0, &loc_addr); 306 inet_addr_t loc_addr, rem_addr; 307 308 rem_addr.ipv4 = fsockp ? fsock.addr.ipv4 : 309 socket->assoc->ident.foreign.addr.ipv4; 310 311 rc = inet_get_srcaddr(&rem_addr, 0, &loc_addr); 354 312 if (rc != EOK) { 355 313 fibril_mutex_unlock(&socket->lock); 356 314 async_answer_0(callid, rc); 357 log_msg(L OG_DEFAULT, LVL_DEBUG, "udp_sock_sendto: Failed to "315 log_msg(LVL_DEBUG, "udp_sock_sendto: Failed to " 358 316 "determine local address."); 359 317 return; 360 318 } 361 362 socket->assoc->ident.local.addr = loc_addr; 363 } 364 319 320 socket->assoc->ident.local.addr.ipv4 = loc_addr.ipv4; 321 log_msg(LVL_DEBUG, "Local IP address is %x", 322 socket->assoc->ident.local.addr.ipv4); 323 } 324 325 365 326 assert(socket->assoc != NULL); 366 367 int fragments = SOCKET_GET_DATA_FRAGMENTS(call); 368 for (int index = 0; index < fragments; index++) { 369 ipc_callid_t wcallid; 370 size_t length; 371 327 328 for (index = 0; index < fragments; index++) { 372 329 if (!async_data_write_receive(&wcallid, &length)) { 373 330 fibril_mutex_unlock(&socket->lock); … … 375 332 goto out; 376 333 } 377 378 if (length > UDP_FRAGMENT_SIZE) 379 length = UDP_FRAGMENT_SIZE; 380 381 uint8_t buffer[UDP_FRAGMENT_SIZE]; 382 int rc = async_data_write_finalize(wcallid, buffer, length); 334 335 if (length > FRAGMENT_SIZE) 336 length = FRAGMENT_SIZE; 337 338 rc = async_data_write_finalize(wcallid, buffer, length); 383 339 if (rc != EOK) { 384 340 fibril_mutex_unlock(&socket->lock); … … 386 342 goto out; 387 343 } 388 389 udp_error_t urc = 390 udp_uc_send(socket->assoc, fsocket_ptr, buffer, length, 0); 391 344 345 urc = udp_uc_send(socket->assoc, fsockp, buffer, length, 0); 346 392 347 switch (urc) { 393 348 case UDP_EOK: 394 349 rc = EOK; 395 350 break; 396 case UDP_ENORES:397 rc = ENO MEM;398 break; 399 case UDP_EUNSPEC:400 rc = E INVAL;401 break; 402 case UDP_ENOROUTE:403 rc = E IO;404 break; 351 /* case TCP_ENOTEXIST: 352 rc = ENOTCONN; 353 break; 354 case TCP_ECLOSING: 355 rc = ENOTCONN; 356 break; 357 case TCP_ERESET: 358 rc = ECONNABORTED; 359 break;*/ 405 360 default: 406 361 assert(false); 407 362 } 408 363 409 364 if (rc != EOK) { 410 365 fibril_mutex_unlock(&socket->lock); … … 413 368 } 414 369 } 415 370 371 refresh_answer(&answer, NULL); 372 SOCKET_SET_DATA_FRAGMENT_SIZE(answer, FRAGMENT_SIZE); 373 answer_call(callid, EOK, &answer, 2); 374 fibril_mutex_unlock(&socket->lock); 375 out: 376 if (addr != NULL) 377 free(addr); 378 } 379 380 static void udp_sock_recvfrom(udp_client_t *client, ipc_callid_t callid, ipc_call_t call) 381 { 382 int socket_id; 383 int flags; 384 size_t addr_length, length; 385 socket_core_t *sock_core; 386 udp_sockdata_t *socket; 416 387 ipc_call_t answer; 417 418 IPC_SET_ARG1(answer, 0); 419 SOCKET_SET_DATA_FRAGMENT_SIZE(answer, UDP_FRAGMENT_SIZE); 420 async_answer_2(callid, EOK, IPC_GET_ARG1(answer), 421 IPC_GET_ARG2(answer)); 422 fibril_mutex_unlock(&socket->lock); 423 424 out: 425 if (addr6 != NULL) 426 free(addr6); 427 } 428 429 static void udp_sock_recvfrom(udp_client_t *client, ipc_callid_t callid, ipc_call_t call) 430 { 431 log_msg(LOG_DEFAULT, LVL_DEBUG, "%p: udp_sock_recv[from]()", client); 432 433 int socket_id = SOCKET_GET_SOCKET_ID(call); 434 435 socket_core_t *sock_core = 436 socket_cores_find(&client->sockets, socket_id); 388 ipc_callid_t rcallid; 389 uint8_t buffer[FRAGMENT_SIZE]; 390 size_t data_len; 391 xflags_t xflags; 392 udp_error_t urc; 393 struct sockaddr_in addr; 394 udp_sock_t rsock; 395 int rc; 396 397 log_msg(LVL_DEBUG, "%p: udp_sock_recv[from]()", client); 398 399 socket_id = SOCKET_GET_SOCKET_ID(call); 400 flags = SOCKET_GET_FLAGS(call); 401 402 sock_core = socket_cores_find(&client->sockets, socket_id); 437 403 if (sock_core == NULL) { 438 404 async_answer_0(callid, ENOTSOCK); 439 405 return; 440 406 } 441 442 udp_sockdata_t *socket = 443 (udp_sockdata_t *) sock_core->specific_data; 444 407 408 socket = (udp_sockdata_t *)sock_core->specific_data; 445 409 fibril_mutex_lock(&socket->lock); 446 410 447 411 if (socket->assoc == NULL) { 448 412 fibril_mutex_unlock(&socket->lock); … … 450 414 return; 451 415 } 452 453 log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_recvfrom(): lock recv_buffer lock"); 454 455 fibril_mutex_lock(&socket->recv_buffer_lock); 456 457 while ((socket->recv_buffer_used == 0) && 458 (socket->recv_error == UDP_EOK)) { 459 log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_recvfrom(): wait for cv"); 460 fibril_condvar_wait(&socket->recv_buffer_cv, 461 &socket->recv_buffer_lock); 462 } 463 464 log_msg(LOG_DEFAULT, LVL_DEBUG, "Got data in sock recv_buffer"); 465 466 size_t data_len = socket->recv_buffer_used; 467 udp_error_t urc = socket->recv_error; 468 469 log_msg(LOG_DEFAULT, LVL_DEBUG, "**** recv data_len=%zu", data_len); 470 471 int rc; 472 416 417 (void)flags; 418 419 urc = udp_uc_receive(socket->assoc, buffer, FRAGMENT_SIZE, &data_len, 420 &xflags, &rsock); 421 log_msg(LVL_DEBUG, "**** udp_uc_receive done, data_len=%zu", data_len); 422 473 423 switch (urc) { 474 424 case UDP_EOK: … … 485 435 assert(false); 486 436 } 487 488 log_msg(LOG_DEFAULT, LVL_DEBUG, "**** udp_uc_receive -> %d", rc); 489 437 438 log_msg(LVL_DEBUG, "**** udp_uc_receive -> %d", rc); 490 439 if (rc != EOK) { 491 fibril_mutex_unlock(&socket->recv_buffer_lock);492 440 fibril_mutex_unlock(&socket->lock); 493 441 async_answer_0(callid, rc); 494 442 return; 495 443 } 496 497 ipc_callid_t rcallid; 498 size_t addr_size = 0; 499 444 500 445 if (IPC_GET_IMETHOD(call) == NET_SOCKET_RECVFROM) { 501 /* Fill address */ 502 udp_sock_t *rsock = &socket->recv_fsock; 503 struct sockaddr_in addr; 504 struct sockaddr_in6 addr6; 505 size_t addr_length; 506 507 uint16_t addr_af = inet_addr_sockaddr_in(&rsock->addr, &addr, 508 &addr6); 509 510 switch (addr_af) { 511 case AF_INET: 512 addr.sin_port = host2uint16_t_be(rsock->port); 513 514 log_msg(LOG_DEFAULT, LVL_DEBUG, "addr read receive"); 515 if (!async_data_read_receive(&rcallid, &addr_length)) { 516 fibril_mutex_unlock(&socket->recv_buffer_lock); 517 fibril_mutex_unlock(&socket->lock); 518 async_answer_0(callid, EINVAL); 519 return; 520 } 521 522 if (addr_length > sizeof(addr)) 523 addr_length = sizeof(addr); 524 525 addr_size = sizeof(addr); 526 527 log_msg(LOG_DEFAULT, LVL_DEBUG, "addr read finalize"); 528 rc = async_data_read_finalize(rcallid, &addr, addr_length); 529 if (rc != EOK) { 530 fibril_mutex_unlock(&socket->recv_buffer_lock); 531 fibril_mutex_unlock(&socket->lock); 532 async_answer_0(callid, EINVAL); 533 return; 534 } 535 536 break; 537 case AF_INET6: 538 addr6.sin6_port = host2uint16_t_be(rsock->port); 539 540 log_msg(LOG_DEFAULT, LVL_DEBUG, "addr6 read receive"); 541 if (!async_data_read_receive(&rcallid, &addr_length)) { 542 fibril_mutex_unlock(&socket->recv_buffer_lock); 543 fibril_mutex_unlock(&socket->lock); 544 async_answer_0(callid, EINVAL); 545 return; 546 } 547 548 if (addr_length > sizeof(addr6)) 549 addr_length = sizeof(addr6); 550 551 addr_size = sizeof(addr6); 552 553 log_msg(LOG_DEFAULT, LVL_DEBUG, "addr6 read finalize"); 554 rc = async_data_read_finalize(rcallid, &addr6, addr_length); 555 if (rc != EOK) { 556 fibril_mutex_unlock(&socket->recv_buffer_lock); 557 fibril_mutex_unlock(&socket->lock); 558 async_answer_0(callid, EINVAL); 559 return; 560 } 561 562 break; 563 default: 564 fibril_mutex_unlock(&socket->recv_buffer_lock); 446 /* Fill addr */ 447 addr.sin_family = AF_INET; 448 addr.sin_addr.s_addr = host2uint32_t_be(rsock.addr.ipv4); 449 addr.sin_port = host2uint16_t_be(rsock.port); 450 451 log_msg(LVL_DEBUG, "addr read receive"); 452 if (!async_data_read_receive(&rcallid, &addr_length)) { 565 453 fibril_mutex_unlock(&socket->lock); 566 454 async_answer_0(callid, EINVAL); 567 455 return; 568 456 } 569 } 570 571 log_msg(LOG_DEFAULT, LVL_DEBUG, "data read receive"); 572 573 size_t length; 457 458 if (addr_length > sizeof(addr)) 459 addr_length = sizeof(addr); 460 461 log_msg(LVL_DEBUG, "addr read finalize"); 462 rc = async_data_read_finalize(rcallid, &addr, addr_length); 463 if (rc != EOK) { 464 fibril_mutex_unlock(&socket->lock); 465 async_answer_0(callid, EINVAL); 466 return; 467 } 468 } 469 470 log_msg(LVL_DEBUG, "data read receive"); 574 471 if (!async_data_read_receive(&rcallid, &length)) { 575 fibril_mutex_unlock(&socket->recv_buffer_lock);576 472 fibril_mutex_unlock(&socket->lock); 577 473 async_answer_0(callid, EINVAL); 578 474 return; 579 475 } 580 476 581 477 if (length > data_len) 582 478 length = data_len; 583 584 log_msg(LOG_DEFAULT, LVL_DEBUG, "data read finalize"); 585 586 rc = async_data_read_finalize(rcallid, socket->recv_buffer, length); 587 588 if ((length < data_len) && (rc == EOK)) 479 480 log_msg(LVL_DEBUG, "data read finalize"); 481 rc = async_data_read_finalize(rcallid, buffer, length); 482 483 if (length < data_len && rc == EOK) 589 484 rc = EOVERFLOW; 590 591 log_msg(LOG_DEFAULT, LVL_DEBUG, "read_data_length <- %zu", length); 592 593 ipc_call_t answer; 594 595 IPC_SET_ARG2(answer, 0); 485 486 log_msg(LVL_DEBUG, "read_data_length <- %zu", length); 596 487 SOCKET_SET_READ_DATA_LENGTH(answer, length); 597 SOCKET_SET_ADDRESS_LENGTH(answer, addr_size); 598 async_answer_3(callid, EOK, IPC_GET_ARG1(answer), 599 IPC_GET_ARG2(answer), IPC_GET_ARG3(answer)); 600 601 socket->recv_buffer_used = 0; 602 603 fibril_condvar_broadcast(&socket->recv_buffer_cv); 604 fibril_mutex_unlock(&socket->recv_buffer_lock); 488 SOCKET_SET_ADDRESS_LENGTH(answer, sizeof(addr)); 489 answer_call(callid, EOK, &answer, 3); 490 491 /* Push one fragment notification to client's queue */ 492 udp_sock_notify_data(sock_core); 605 493 fibril_mutex_unlock(&socket->lock); 606 494 } … … 608 496 static void udp_sock_close(udp_client_t *client, ipc_callid_t callid, ipc_call_t call) 609 497 { 610 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_close()"); 611 int socket_id = SOCKET_GET_SOCKET_ID(call); 612 613 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_close() - find core"); 614 socket_core_t *sock_core = 615 socket_cores_find(&client->sockets, socket_id); 498 int socket_id; 499 socket_core_t *sock_core; 500 udp_sockdata_t *socket; 501 int rc; 502 503 log_msg(LVL_DEBUG, "tcp_sock_close()"); 504 socket_id = SOCKET_GET_SOCKET_ID(call); 505 506 sock_core = socket_cores_find(&client->sockets, socket_id); 616 507 if (sock_core == NULL) { 617 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_close() - core not found");618 508 async_answer_0(callid, ENOTSOCK); 619 509 return; 620 510 } 621 511 622 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_close() - spec data"); 623 udp_sockdata_t *socket = 624 (udp_sockdata_t *) sock_core->specific_data; 625 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_close() - lock socket"); 512 socket = (udp_sockdata_t *)sock_core->specific_data; 626 513 fibril_mutex_lock(&socket->lock); 627 514 628 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_close() - lock socket buffer"); 629 fibril_mutex_lock(&socket->recv_buffer_lock); 630 log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_close - set socket->sock_core = NULL"); 631 socket->sock_core = NULL; 632 fibril_mutex_unlock(&socket->recv_buffer_lock); 633 634 udp_uc_reset(socket->assoc); 635 636 int rc = socket_destroy(NULL, socket_id, &client->sockets, &gsock, 515 assert(socket->assoc != NULL); 516 udp_uc_destroy(socket->assoc); 517 518 rc = socket_destroy(NULL, socket_id, &client->sockets, &gsock, 637 519 udp_free_sock_data); 638 520 if (rc != EOK) { 639 log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_close - socket_destroy failed");640 521 fibril_mutex_unlock(&socket->lock); 641 522 async_answer_0(callid, rc); … … 643 524 } 644 525 645 log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_close - broadcast recv_buffer_cv");646 fibril_condvar_broadcast(&socket->recv_buffer_cv);647 648 526 fibril_mutex_unlock(&socket->lock); 649 527 async_answer_0(callid, EOK); … … 652 530 static void udp_sock_getsockopt(udp_client_t *client, ipc_callid_t callid, ipc_call_t call) 653 531 { 654 log_msg(L OG_DEFAULT, LVL_DEBUG, "udp_sock_getsockopt()");532 log_msg(LVL_DEBUG, "udp_sock_getsockopt()"); 655 533 async_answer_0(callid, ENOTSUP); 656 534 } … … 658 536 static void udp_sock_setsockopt(udp_client_t *client, ipc_callid_t callid, ipc_call_t call) 659 537 { 660 log_msg(L OG_DEFAULT, LVL_DEBUG, "udp_sock_setsockopt()");538 log_msg(LVL_DEBUG, "udp_sock_setsockopt()"); 661 539 async_answer_0(callid, ENOTSUP); 662 }663 664 static int udp_sock_recv_fibril(void *arg)665 {666 udp_sockdata_t *sock = (udp_sockdata_t *)arg;667 udp_error_t urc;668 xflags_t xflags;669 size_t rcvd;670 671 log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_recv_fibril()");672 673 fibril_mutex_lock(&sock->recv_buffer_lock);674 675 while (true) {676 log_msg(LOG_DEFAULT, LVL_DEBUG, "[] wait for rcv buffer empty()");677 while ((sock->recv_buffer_used != 0) && (sock->sock_core != NULL)) {678 fibril_condvar_wait(&sock->recv_buffer_cv,679 &sock->recv_buffer_lock);680 }681 682 fibril_mutex_unlock(&sock->recv_buffer_lock);683 684 log_msg(LOG_DEFAULT, LVL_DEBUG, "[] call udp_uc_receive()");685 urc = udp_uc_receive(sock->assoc, sock->recv_buffer,686 UDP_FRAGMENT_SIZE, &rcvd, &xflags, &sock->recv_fsock);687 fibril_mutex_lock(&sock->recv_buffer_lock);688 sock->recv_error = urc;689 690 log_msg(LOG_DEFAULT, LVL_DEBUG, "[] udp_uc_receive -> %d", urc);691 692 if (sock->sock_core != NULL)693 udp_sock_notify_data(sock->sock_core);694 695 if (urc != UDP_EOK) {696 log_msg(LOG_DEFAULT, LVL_DEBUG, "[] urc != UDP_EOK, break");697 fibril_condvar_broadcast(&sock->recv_buffer_cv);698 fibril_mutex_unlock(&sock->recv_buffer_lock);699 break;700 }701 702 log_msg(LOG_DEFAULT, LVL_DEBUG, "[] got data - broadcast recv_buffer_cv");703 704 sock->recv_buffer_used = rcvd;705 fibril_condvar_broadcast(&sock->recv_buffer_cv);706 }707 708 log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_recv_fibril() exited loop");709 fibril_mutex_unlock(&sock->recv_buffer_lock);710 udp_uc_destroy(sock->assoc);711 712 log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_recv_fibril() terminated");713 714 return 0;715 540 } 716 541 … … 728 553 729 554 while (true) { 730 log_msg(L OG_DEFAULT, LVL_DEBUG, "udp_sock_connection: wait");555 log_msg(LVL_DEBUG, "udp_sock_connection: wait"); 731 556 callid = async_get_call(&call); 732 557 if (!IPC_GET_IMETHOD(call)) 733 558 break; 734 559 735 log_msg(L OG_DEFAULT, LVL_DEBUG, "udp_sock_connection: METHOD=%d",560 log_msg(LVL_DEBUG, "udp_sock_connection: METHOD=%d", 736 561 (int)IPC_GET_IMETHOD(call)); 737 562 … … 774 599 } 775 600 } 776 777 /* Clean up */778 log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_connection: Clean up");779 async_hangup(client.sess);780 socket_cores_release(NULL, &client.sockets, &gsock, udp_free_sock_data);781 601 } 782 602
Note:
See TracChangeset
for help on using the changeset viewer.