Changes in uspace/srv/net/tcp/sock.c [02a09ed:69a93df7] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/tcp/sock.c
r02a09ed r69a93df7 42 42 #include <ipc/services.h> 43 43 #include <ipc/socket.h> 44 #include <net/modules.h> 44 45 #include <net/socket.h> 45 46 #include <ns.h> … … 51 52 #include "ucall.h" 52 53 54 #define FRAGMENT_SIZE 1024 55 53 56 #define MAX_BACKLOG 128 54 57 … … 64 67 static void tcp_sock_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg); 65 68 static void tcp_sock_cstate_cb(tcp_conn_t *conn, void *arg); 66 static int tcp_sock_recv_fibril(void *arg);67 69 68 70 int tcp_sock_init(void) 69 71 { 72 int rc; 73 70 74 socket_ports_initialize(&gsock); 71 75 72 76 async_set_client_connection(tcp_sock_connection); 73 74 intrc = service_register(SERVICE_TCP);77 78 rc = service_register(SERVICE_TCP); 75 79 if (rc != EOK) 76 80 return EEXIST; 77 81 78 82 return EOK; 79 83 } … … 85 89 socket = (tcp_sockdata_t *)sock_core->specific_data; 86 90 (void)socket; 87 88 /* XXX We need to initiate connection cleanup here */89 91 } 90 92 91 93 static void tcp_sock_notify_data(socket_core_t *sock_core) 92 94 { 93 log_msg(L OG_DEFAULT, LVL_DEBUG, "tcp_sock_notify_data(%d)", sock_core->socket_id);95 log_msg(LVL_DEBUG, "tcp_sock_notify_data(%d)", sock_core->socket_id); 94 96 async_exch_t *exch = async_exchange_begin(sock_core->sess); 95 97 async_msg_5(exch, NET_SOCKET_RECEIVED, (sysarg_t)sock_core->socket_id, 96 TCP_SOCK_FRAGMENT_SIZE, 0, 0, 1);98 FRAGMENT_SIZE, 0, 0, 1); 97 99 async_exchange_end(exch); 98 100 } … … 100 102 static void tcp_sock_notify_aconn(socket_core_t *lsock_core) 101 103 { 102 log_msg(L OG_DEFAULT, LVL_DEBUG, "tcp_sock_notify_aconn(%d)", lsock_core->socket_id);104 log_msg(LVL_DEBUG, "tcp_sock_notify_aconn(%d)", lsock_core->socket_id); 103 105 async_exch_t *exch = async_exchange_begin(lsock_core->sess); 104 106 async_msg_5(exch, NET_SOCKET_ACCEPTED, (sysarg_t)lsock_core->socket_id, 105 TCP_SOCK_FRAGMENT_SIZE, 0, 0, 0);107 FRAGMENT_SIZE, 0, 0, 0); 106 108 async_exchange_end(exch); 107 109 } 108 110 109 static int tcp_sock_create(tcp_client_t *client, tcp_sockdata_t **rsock)111 static void tcp_sock_socket(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call) 110 112 { 111 113 tcp_sockdata_t *sock; 112 113 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_create()");114 *rsock = NULL;115 116 sock = calloc(1, sizeof(tcp_sockdata_t));117 if (sock == NULL)118 return ENOMEM;119 120 fibril_mutex_initialize(&sock->lock);121 sock->client = client;122 123 sock->recv_buffer_used = 0;124 sock->recv_error = TCP_EOK;125 fibril_mutex_initialize(&sock->recv_buffer_lock);126 fibril_condvar_initialize(&sock->recv_buffer_cv);127 list_initialize(&sock->ready);128 129 *rsock = sock;130 return EOK;131 }132 133 static void tcp_sock_uncreate(tcp_sockdata_t *sock)134 {135 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_uncreate()");136 free(sock);137 }138 139 static int tcp_sock_finish_setup(tcp_sockdata_t *sock, int *sock_id)140 {141 114 socket_core_t *sock_core; 142 int rc;143 144 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_finish_setup()");145 146 sock->recv_fibril = fibril_create(tcp_sock_recv_fibril, sock);147 if (sock->recv_fibril == 0)148 return ENOMEM;149 150 rc = socket_create(&sock->client->sockets, sock->client->sess,151 sock, sock_id);152 153 if (rc != EOK) {154 fibril_destroy(sock->recv_fibril);155 sock->recv_fibril = 0;156 return rc;157 }158 159 sock_core = socket_cores_find(&sock->client->sockets, *sock_id);160 assert(sock_core != NULL);161 sock->sock_core = sock_core;162 163 return EOK;164 }165 166 static void tcp_sock_socket(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call)167 {168 tcp_sockdata_t *sock;169 115 int sock_id; 170 116 int rc; 171 117 ipc_call_t answer; 172 118 173 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_socket()"); 174 175 rc = tcp_sock_create(client, &sock); 119 log_msg(LVL_DEBUG, "tcp_sock_socket()"); 120 sock = calloc(sizeof(tcp_sockdata_t), 1); 121 if (sock == NULL) { 122 async_answer_0(callid, ENOMEM); 123 return; 124 } 125 126 fibril_mutex_initialize(&sock->lock); 127 sock->client = client; 128 sock->laddr.ipv4 = TCP_IPV4_ANY; 129 sock->lconn = NULL; 130 sock->backlog = 0; 131 list_initialize(&sock->ready); 132 133 sock_id = SOCKET_GET_SOCKET_ID(call); 134 rc = socket_create(&client->sockets, client->sess, sock, &sock_id); 176 135 if (rc != EOK) { 177 136 async_answer_0(callid, rc); … … 179 138 } 180 139 181 inet_addr_any(&sock->laddr); 182 sock->lconn = NULL; 183 sock->backlog = 0; 184 185 sock_id = SOCKET_GET_SOCKET_ID(call); 186 rc = tcp_sock_finish_setup(sock, &sock_id); 187 if (rc != EOK) { 188 tcp_sock_uncreate(sock); 189 async_answer_0(callid, rc); 190 return; 191 } 192 140 sock_core = socket_cores_find(&client->sockets, sock_id); 141 assert(sock_core != NULL); 142 sock->sock_core = sock_core; 143 144 refresh_answer(&answer, NULL); 193 145 SOCKET_SET_SOCKET_ID(answer, sock_id); 194 146 195 SOCKET_SET_DATA_FRAGMENT_SIZE(answer, TCP_SOCK_FRAGMENT_SIZE);147 SOCKET_SET_DATA_FRAGMENT_SIZE(answer, FRAGMENT_SIZE); 196 148 SOCKET_SET_HEADER_SIZE(answer, sizeof(tcp_header_t)); 197 198 async_answer_3(callid, EOK, IPC_GET_ARG1(answer), 199 IPC_GET_ARG2(answer), IPC_GET_ARG3(answer)); 149 answer_call(callid, EOK, &answer, 3); 200 150 } 201 151 … … 203 153 { 204 154 int rc; 205 struct sockaddr _in*addr;206 size_t addr_ size;155 struct sockaddr *addr; 156 size_t addr_len; 207 157 socket_core_t *sock_core; 208 158 tcp_sockdata_t *socket; 209 210 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_bind()"); 211 log_msg(LOG_DEFAULT, LVL_DEBUG, " - async_data_write_accept"); 212 213 addr = NULL; 214 215 rc = async_data_write_accept((void **) &addr, false, 0, 0, 0, &addr_size); 159 160 log_msg(LVL_DEBUG, "tcp_sock_bind()"); 161 log_msg(LVL_DEBUG, " - async_data_write_accept"); 162 rc = async_data_write_accept((void **) &addr, false, 0, 0, 0, &addr_len); 216 163 if (rc != EOK) { 217 164 async_answer_0(callid, rc); 218 goto out; 219 } 220 221 if (addr_size != sizeof(struct sockaddr_in)) { 222 async_answer_0(callid, EINVAL); 223 goto out; 224 } 225 226 log_msg(LOG_DEFAULT, LVL_DEBUG, " - call socket_bind"); 165 return; 166 } 167 168 log_msg(LVL_DEBUG, " - call socket_bind"); 227 169 rc = socket_bind(&client->sockets, &gsock, SOCKET_GET_SOCKET_ID(call), 228 addr, addr_ size, TCP_FREE_PORTS_START, TCP_FREE_PORTS_END,170 addr, addr_len, TCP_FREE_PORTS_START, TCP_FREE_PORTS_END, 229 171 last_used_port); 230 172 if (rc != EOK) { 231 173 async_answer_0(callid, rc); 232 goto out;233 } 234 235 log_msg(L OG_DEFAULT, LVL_DEBUG, " - call socket_cores_find");174 return; 175 } 176 177 log_msg(LVL_DEBUG, " - call socket_cores_find"); 236 178 sock_core = socket_cores_find(&client->sockets, SOCKET_GET_SOCKET_ID(call)); 237 if (sock_core == NULL) { 238 async_answer_0(callid, ENOENT); 239 goto out; 240 } 241 242 socket = (tcp_sockdata_t *)sock_core->specific_data; 243 /* XXX Anything to do? */ 244 (void) socket; 245 246 log_msg(LOG_DEFAULT, LVL_DEBUG, " - success"); 179 if (sock_core != NULL) { 180 socket = (tcp_sockdata_t *)sock_core->specific_data; 181 /* XXX Anything to do? */ 182 (void) socket; 183 } 184 185 log_msg(LVL_DEBUG, " - success"); 247 186 async_answer_0(callid, EOK); 248 249 out:250 if (addr != NULL)251 free(addr);252 187 } 253 188 … … 264 199 tcp_sock_lconn_t *lconn; 265 200 int i; 266 int rc; 267 268 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_listen()"); 201 202 log_msg(LVL_DEBUG, "tcp_sock_listen()"); 269 203 270 204 socket_id = SOCKET_GET_SOCKET_ID(call); … … 284 218 return; 285 219 } 286 220 221 socket = (tcp_sockdata_t *)sock_core->specific_data; 222 223 /* 224 * Prepare @c backlog listening connections. 225 */ 226 fibril_mutex_lock(&socket->lock); 227 228 socket->backlog = backlog; 229 socket->lconn = calloc(sizeof(tcp_conn_t *), backlog); 230 if (socket->lconn == NULL) { 231 fibril_mutex_unlock(&socket->lock); 232 async_answer_0(callid, ENOMEM); 233 return; 234 } 235 236 log_msg(LVL_DEBUG, " - open connections"); 237 238 lsocket.addr.ipv4 = TCP_IPV4_ANY; 239 lsocket.port = sock_core->port; 240 fsocket.addr.ipv4 = TCP_IPV4_ANY; 241 fsocket.port = TCP_PORT_ANY; 242 243 for (i = 0; i < backlog; i++) { 244 245 lconn = calloc(sizeof(tcp_sock_lconn_t), 1); 246 if (lconn == NULL) { 247 /* XXX Clean up */ 248 fibril_mutex_unlock(&socket->lock); 249 async_answer_0(callid, ENOMEM); 250 return; 251 } 252 253 trc = tcp_uc_open(&lsocket, &fsocket, ap_passive, 254 tcp_open_nonblock, &conn); 255 if (conn == NULL) { 256 /* XXX Clean up */ 257 fibril_mutex_unlock(&socket->lock); 258 async_answer_0(callid, ENOMEM); 259 return; 260 } 261 262 tcp_uc_set_cstate_cb(conn, tcp_sock_cstate_cb, lconn); 263 264 assert(trc == TCP_EOK); 265 conn->name = (char *)"S"; 266 267 lconn->conn = conn; 268 lconn->socket = socket; 269 link_initialize(&lconn->ready_list); 270 socket->lconn[i] = lconn; 271 } 272 273 fibril_mutex_unlock(&socket->lock); 274 async_answer_0(callid, EOK); 275 } 276 277 static void tcp_sock_connect(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call) 278 { 279 int rc; 280 struct sockaddr_in *addr; 281 int socket_id; 282 size_t addr_len; 283 socket_core_t *sock_core; 284 tcp_sockdata_t *socket; 285 tcp_error_t trc; 286 tcp_sock_t lsocket; 287 tcp_sock_t fsocket; 288 289 log_msg(LVL_DEBUG, "tcp_sock_connect()"); 290 291 rc = async_data_write_accept((void **) &addr, false, 0, 0, 0, &addr_len); 292 if (rc != EOK || addr_len != sizeof(struct sockaddr_in)) { 293 async_answer_0(callid, rc); 294 return; 295 } 296 297 socket_id = SOCKET_GET_SOCKET_ID(call); 298 299 sock_core = socket_cores_find(&client->sockets, socket_id); 300 if (sock_core == NULL) { 301 async_answer_0(callid, ENOTSOCK); 302 return; 303 } 304 305 socket = (tcp_sockdata_t *)sock_core->specific_data; 287 306 if (sock_core->port <= 0) { 288 307 rc = socket_bind_free_port(&gsock, sock_core, … … 293 312 return; 294 313 } 295 314 296 315 last_used_port = sock_core->port; 297 316 } 298 299 socket = (tcp_sockdata_t *) sock_core->specific_data; 300 301 /* 302 * Prepare @c backlog listening connections. 303 */ 317 304 318 fibril_mutex_lock(&socket->lock); 305 306 socket->backlog = backlog; 307 socket->lconn = calloc(backlog, sizeof(tcp_conn_t *)); 308 if (socket->lconn == NULL) { 309 fibril_mutex_unlock(&socket->lock); 310 async_answer_0(callid, ENOMEM); 311 return; 312 } 313 314 log_msg(LOG_DEFAULT, LVL_DEBUG, " - open connections"); 315 316 inet_addr_any(&lsocket.addr); 317 lsocket.port = sock_core->port; 318 319 inet_addr_any(&fsocket.addr); 320 fsocket.port = TCP_PORT_ANY; 321 322 for (i = 0; i < backlog; i++) { 323 324 lconn = calloc(1, sizeof(tcp_sock_lconn_t)); 325 if (lconn == NULL) { 326 /* XXX Clean up */ 327 fibril_mutex_unlock(&socket->lock); 328 async_answer_0(callid, ENOMEM); 329 return; 330 } 331 332 trc = tcp_uc_open(&lsocket, &fsocket, ap_passive, 333 tcp_open_nonblock, &conn); 334 if (conn == NULL) { 335 /* XXX Clean up */ 336 fibril_mutex_unlock(&socket->lock); 337 async_answer_0(callid, ENOMEM); 338 return; 339 } 340 341 tcp_uc_set_cstate_cb(conn, tcp_sock_cstate_cb, lconn); 342 343 assert(trc == TCP_EOK); 344 conn->name = (char *)"S"; 345 346 lconn->conn = conn; 347 lconn->socket = socket; 348 link_initialize(&lconn->ready_list); 349 socket->lconn[i] = lconn; 350 } 351 352 fibril_mutex_unlock(&socket->lock); 353 async_answer_0(callid, EOK); 354 } 355 356 static void tcp_sock_connect(tcp_client_t *client, ipc_callid_t callid, 357 ipc_call_t call) 358 { 359 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_connect()"); 360 361 struct sockaddr_in6 *addr6 = NULL; 362 size_t addr_len; 363 int rc = async_data_write_accept((void **) &addr6, false, 0, 0, 0, &addr_len); 364 if (rc != EOK) { 365 async_answer_0(callid, rc); 366 return; 367 } 368 369 if ((addr_len != sizeof(struct sockaddr_in)) && 370 (addr_len != sizeof(struct sockaddr_in6))) { 371 async_answer_0(callid, EINVAL); 372 goto out; 373 } 374 375 struct sockaddr_in *addr = (struct sockaddr_in *) addr6; 376 377 int socket_id = SOCKET_GET_SOCKET_ID(call); 378 socket_core_t *sock_core = socket_cores_find(&client->sockets, 379 socket_id); 380 if (sock_core == NULL) { 381 async_answer_0(callid, ENOTSOCK); 382 goto out; 383 } 384 385 tcp_sockdata_t *socket = 386 (tcp_sockdata_t *) sock_core->specific_data; 387 388 if (sock_core->port <= 0) { 389 rc = socket_bind_free_port(&gsock, sock_core, 390 TCP_FREE_PORTS_START, TCP_FREE_PORTS_END, 391 last_used_port); 392 if (rc != EOK) { 393 async_answer_0(callid, rc); 394 goto out; 395 } 396 397 last_used_port = sock_core->port; 398 } 399 400 fibril_mutex_lock(&socket->lock); 401 402 if (inet_addr_is_any(&socket->laddr)) { 319 320 if (socket->laddr.ipv4 == TCP_IPV4_ANY) { 403 321 /* Determine local IP address */ 404 inet_addr_t loc_addr; 405 inet_addr_t rem_addr; 406 407 switch (addr->sin_family) { 408 case AF_INET: 409 inet_sockaddr_in_addr(addr, &rem_addr); 410 break; 411 case AF_INET6: 412 inet_sockaddr_in6_addr(addr6, &rem_addr); 413 break; 414 default: 415 fibril_mutex_unlock(&socket->lock); 416 async_answer_0(callid, EINVAL); 417 goto out; 418 } 419 322 inet_addr_t loc_addr, rem_addr; 323 324 rem_addr.ipv4 = uint32_t_be2host(addr->sin_addr.s_addr); 420 325 rc = inet_get_srcaddr(&rem_addr, 0, &loc_addr); 421 326 if (rc != EOK) { 422 327 fibril_mutex_unlock(&socket->lock); 423 328 async_answer_0(callid, rc); 424 log_msg(L OG_DEFAULT, LVL_DEBUG, "tcp_sock_connect: Failed to "329 log_msg(LVL_DEBUG, "tcp_sock_connect: Failed to " 425 330 "determine local address."); 426 goto out; 427 } 428 429 socket->laddr = loc_addr; 430 } 431 432 tcp_sock_t lsocket; 433 tcp_sock_t fsocket; 434 435 lsocket.addr = socket->laddr; 331 return; 332 } 333 334 socket->laddr.ipv4 = loc_addr.ipv4; 335 log_msg(LVL_DEBUG, "Local IP address is %x", socket->laddr.ipv4); 336 } 337 338 lsocket.addr.ipv4 = socket->laddr.ipv4; 436 339 lsocket.port = sock_core->port; 437 438 switch (addr->sin_family) { 439 case AF_INET: 440 inet_sockaddr_in_addr(addr, &fsocket.addr); 441 break; 442 case AF_INET6: 443 inet_sockaddr_in6_addr(addr6, &fsocket.addr); 444 break; 445 default: 446 fibril_mutex_unlock(&socket->lock); 447 async_answer_0(callid, EINVAL); 448 goto out; 449 } 450 340 fsocket.addr.ipv4 = uint32_t_be2host(addr->sin_addr.s_addr); 451 341 fsocket.port = uint16_t_be2host(addr->sin_port); 452 453 tcp_error_t trc = tcp_uc_open(&lsocket, &fsocket, ap_active, 0, 454 &socket->conn); 455 342 343 trc = tcp_uc_open(&lsocket, &fsocket, ap_active, 0, &socket->conn); 344 456 345 if (socket->conn != NULL) 457 socket->conn->name = (char *) 458 346 socket->conn->name = (char *)"C"; 347 459 348 fibril_mutex_unlock(&socket->lock); 460 349 461 350 switch (trc) { 462 351 case TCP_EOK: … … 469 358 assert(false); 470 359 } 471 472 if (rc == EOK) 473 fibril_add_ready(socket->recv_fibril); 474 360 475 361 async_answer_0(callid, rc); 476 477 out: 478 if (addr6 != NULL)479 free(addr6);362 363 /* Push one fragment notification to client's queue */ 364 tcp_sock_notify_data(sock_core); 365 log_msg(LVL_DEBUG, "tcp_sock_connect(): notify conn\n"); 480 366 } 481 367 … … 486 372 int asock_id; 487 373 socket_core_t *sock_core; 374 socket_core_t *asock_core; 488 375 tcp_sockdata_t *socket; 489 376 tcp_sockdata_t *asocket; … … 496 383 int rc; 497 384 498 log_msg(L OG_DEFAULT, LVL_DEBUG, "tcp_sock_accept()");385 log_msg(LVL_DEBUG, "tcp_sock_accept()"); 499 386 500 387 socket_id = SOCKET_GET_SOCKET_ID(call); … … 506 393 return; 507 394 } 508 509 if (sock_core->port <= 0) {510 rc = socket_bind_free_port(&gsock, sock_core,511 TCP_FREE_PORTS_START, TCP_FREE_PORTS_END,512 last_used_port);513 if (rc != EOK) {514 async_answer_0(callid, rc);515 return;516 }517 518 last_used_port = sock_core->port;519 }520 395 521 396 socket = (tcp_sockdata_t *)sock_core->specific_data; 522 397 fibril_mutex_lock(&socket->lock); 523 398 524 log_msg(L OG_DEFAULT, LVL_DEBUG, " - verify socket->conn");399 log_msg(LVL_DEBUG, " - verify socket->conn"); 525 400 if (socket->conn != NULL) { 526 401 fibril_mutex_unlock(&socket->lock); … … 544 419 /* Replenish listening connection */ 545 420 546 inet_addr_any(&lsocket.addr);421 lsocket.addr.ipv4 = TCP_IPV4_ANY; 547 422 lsocket.port = sock_core->port; 548 549 inet_addr_any(&fsocket.addr); 423 fsocket.addr.ipv4 = TCP_IPV4_ANY; 550 424 fsocket.port = TCP_PORT_ANY; 551 425 … … 568 442 /* Allocate socket for accepted connection */ 569 443 570 rc = tcp_sock_create(client, &asocket); 444 log_msg(LVL_DEBUG, "tcp_sock_accept(): allocate asocket\n"); 445 asocket = calloc(sizeof(tcp_sockdata_t), 1); 446 if (asocket == NULL) { 447 fibril_mutex_unlock(&socket->lock); 448 async_answer_0(callid, ENOMEM); 449 return; 450 } 451 452 fibril_mutex_initialize(&asocket->lock); 453 asocket->client = client; 454 asocket->conn = conn; 455 log_msg(LVL_DEBUG, "tcp_sock_accept():create asocket\n"); 456 457 rc = socket_create(&client->sockets, client->sess, asocket, &asock_id); 571 458 if (rc != EOK) { 572 459 fibril_mutex_unlock(&socket->lock); … … 574 461 return; 575 462 } 576 577 asocket->conn = conn; 578 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_accept():create asocket\n"); 579 580 rc = tcp_sock_finish_setup(asocket, &asock_id); 581 if (rc != EOK) { 582 tcp_sock_uncreate(asocket); 583 fibril_mutex_unlock(&socket->lock); 584 async_answer_0(callid, rc); 585 return; 586 } 587 588 fibril_add_ready(asocket->recv_fibril); 589 590 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_accept(): find acore\n"); 591 592 SOCKET_SET_DATA_FRAGMENT_SIZE(answer, TCP_SOCK_FRAGMENT_SIZE); 463 log_msg(LVL_DEBUG, "tcp_sock_accept(): find acore\n"); 464 465 asock_core = socket_cores_find(&client->sockets, asock_id); 466 assert(asock_core != NULL); 467 468 refresh_answer(&answer, NULL); 469 470 SOCKET_SET_DATA_FRAGMENT_SIZE(answer, FRAGMENT_SIZE); 593 471 SOCKET_SET_SOCKET_ID(answer, asock_id); 594 472 SOCKET_SET_ADDRESS_LENGTH(answer, sizeof(struct sockaddr_in)); 595 596 async_answer_3(callid, asocket->sock_core->socket_id, 597 IPC_GET_ARG1(answer), IPC_GET_ARG2(answer), 598 IPC_GET_ARG3(answer)); 599 473 474 answer_call(callid, asock_core->socket_id, &answer, 3); 475 600 476 /* Push one fragment notification to client's queue */ 601 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_accept(): notify data\n"); 477 log_msg(LVL_DEBUG, "tcp_sock_accept(): notify data\n"); 478 tcp_sock_notify_data(asock_core); 602 479 fibril_mutex_unlock(&socket->lock); 603 480 } … … 613 490 ipc_callid_t wcallid; 614 491 size_t length; 615 uint8_t buffer[ TCP_SOCK_FRAGMENT_SIZE];492 uint8_t buffer[FRAGMENT_SIZE]; 616 493 tcp_error_t trc; 617 494 int rc; 618 495 619 log_msg(L OG_DEFAULT, LVL_DEBUG, "tcp_sock_send()");496 log_msg(LVL_DEBUG, "tcp_sock_send()"); 620 497 socket_id = SOCKET_GET_SOCKET_ID(call); 621 498 fragments = SOCKET_GET_DATA_FRAGMENTS(call); … … 644 521 } 645 522 646 if (length > TCP_SOCK_FRAGMENT_SIZE)647 length = TCP_SOCK_FRAGMENT_SIZE;523 if (length > FRAGMENT_SIZE) 524 length = FRAGMENT_SIZE; 648 525 649 526 rc = async_data_write_finalize(wcallid, buffer, length); … … 680 557 } 681 558 682 IPC_SET_ARG1(answer, 0); 683 SOCKET_SET_DATA_FRAGMENT_SIZE(answer, TCP_SOCK_FRAGMENT_SIZE); 684 async_answer_2(callid, EOK, IPC_GET_ARG1(answer), 685 IPC_GET_ARG2(answer)); 559 refresh_answer(&answer, NULL); 560 SOCKET_SET_DATA_FRAGMENT_SIZE(answer, FRAGMENT_SIZE); 561 answer_call(callid, EOK, &answer, 2); 686 562 fibril_mutex_unlock(&socket->lock); 687 563 } … … 689 565 static void tcp_sock_sendto(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call) 690 566 { 691 log_msg(L OG_DEFAULT, LVL_DEBUG, "tcp_sock_sendto()");567 log_msg(LVL_DEBUG, "tcp_sock_sendto()"); 692 568 async_answer_0(callid, ENOTSUP); 693 569 } … … 695 571 static void tcp_sock_recvfrom(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call) 696 572 { 697 log_msg(LOG_DEFAULT, LVL_DEBUG, "%p: tcp_sock_recv[from]()", client); 698 699 int socket_id = SOCKET_GET_SOCKET_ID(call); 700 701 socket_core_t *sock_core = 702 socket_cores_find(&client->sockets, socket_id); 573 int socket_id; 574 int flags; 575 size_t addr_length, length; 576 socket_core_t *sock_core; 577 tcp_sockdata_t *socket; 578 ipc_call_t answer; 579 ipc_callid_t rcallid; 580 uint8_t buffer[FRAGMENT_SIZE]; 581 size_t data_len; 582 xflags_t xflags; 583 tcp_error_t trc; 584 struct sockaddr_in addr; 585 tcp_sock_t *rsock; 586 int rc; 587 588 log_msg(LVL_DEBUG, "%p: tcp_sock_recv[from]()", client); 589 590 socket_id = SOCKET_GET_SOCKET_ID(call); 591 flags = SOCKET_GET_FLAGS(call); 592 593 sock_core = socket_cores_find(&client->sockets, socket_id); 703 594 if (sock_core == NULL) { 704 595 async_answer_0(callid, ENOTSOCK); 705 596 return; 706 597 } 707 708 tcp_sockdata_t *socket = 709 (tcp_sockdata_t *) sock_core->specific_data; 710 598 599 socket = (tcp_sockdata_t *)sock_core->specific_data; 711 600 fibril_mutex_lock(&socket->lock); 712 601 713 602 if (socket->conn == NULL) { 714 603 fibril_mutex_unlock(&socket->lock); … … 716 605 return; 717 606 } 718 719 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_recvfrom(): lock recv_buffer_lock"); 720 721 fibril_mutex_lock(&socket->recv_buffer_lock); 722 while ((socket->recv_buffer_used == 0) && 723 (socket->recv_error == TCP_EOK)) { 724 log_msg(LOG_DEFAULT, LVL_DEBUG, "wait for recv_buffer_cv + recv_buffer_used != 0"); 725 fibril_condvar_wait(&socket->recv_buffer_cv, 726 &socket->recv_buffer_lock); 727 } 728 729 log_msg(LOG_DEFAULT, LVL_DEBUG, "Got data in sock recv_buffer"); 730 731 size_t data_len = socket->recv_buffer_used; 732 tcp_error_t trc = socket->recv_error; 733 int rc; 734 607 608 (void)flags; 609 610 trc = tcp_uc_receive(socket->conn, buffer, FRAGMENT_SIZE, &data_len, 611 &xflags); 612 log_msg(LVL_DEBUG, "**** tcp_uc_receive done"); 613 735 614 switch (trc) { 736 615 case TCP_EOK: … … 747 626 assert(false); 748 627 } 749 750 log_msg(LOG_DEFAULT, LVL_DEBUG, "**** recv result -> %d", rc); 751 628 629 log_msg(LVL_DEBUG, "**** tcp_uc_receive -> %d", rc); 752 630 if (rc != EOK) { 753 fibril_mutex_unlock(&socket->recv_buffer_lock);754 631 fibril_mutex_unlock(&socket->lock); 755 632 async_answer_0(callid, rc); 756 633 return; 757 634 } 758 759 ipc_callid_t rcallid; 760 635 761 636 if (IPC_GET_IMETHOD(call) == NET_SOCKET_RECVFROM) { 762 /* Fill address */ 763 tcp_sock_t *rsock = &socket->conn->ident.foreign; 764 struct sockaddr_in addr; 765 struct sockaddr_in6 addr6; 766 size_t addr_length; 767 768 uint16_t addr_af = inet_addr_sockaddr_in(&rsock->addr, &addr, 769 &addr6); 770 771 switch (addr_af) { 772 case AF_INET: 773 addr.sin_port = host2uint16_t_be(rsock->port); 774 775 log_msg(LOG_DEFAULT, LVL_DEBUG, "addr read receive"); 776 if (!async_data_read_receive(&rcallid, &addr_length)) { 777 fibril_mutex_unlock(&socket->recv_buffer_lock); 778 fibril_mutex_unlock(&socket->lock); 779 async_answer_0(callid, EINVAL); 780 return; 781 } 782 783 if (addr_length > sizeof(addr)) 784 addr_length = sizeof(addr); 785 786 log_msg(LOG_DEFAULT, LVL_DEBUG, "addr read finalize"); 787 rc = async_data_read_finalize(rcallid, &addr, addr_length); 788 if (rc != EOK) { 789 fibril_mutex_unlock(&socket->recv_buffer_lock); 790 fibril_mutex_unlock(&socket->lock); 791 async_answer_0(callid, EINVAL); 792 return; 793 } 794 795 break; 796 case AF_INET6: 797 addr6.sin6_port = host2uint16_t_be(rsock->port); 798 799 log_msg(LOG_DEFAULT, LVL_DEBUG, "addr6 read receive"); 800 if (!async_data_read_receive(&rcallid, &addr_length)) { 801 fibril_mutex_unlock(&socket->recv_buffer_lock); 802 fibril_mutex_unlock(&socket->lock); 803 async_answer_0(callid, EINVAL); 804 return; 805 } 806 807 if (addr_length > sizeof(addr6)) 808 addr_length = sizeof(addr6); 809 810 log_msg(LOG_DEFAULT, LVL_DEBUG, "addr6 read finalize"); 811 rc = async_data_read_finalize(rcallid, &addr6, addr_length); 812 if (rc != EOK) { 813 fibril_mutex_unlock(&socket->recv_buffer_lock); 814 fibril_mutex_unlock(&socket->lock); 815 async_answer_0(callid, EINVAL); 816 return; 817 } 818 819 break; 820 default: 821 fibril_mutex_unlock(&socket->recv_buffer_lock); 637 /* Fill addr */ 638 rsock = &socket->conn->ident.foreign; 639 addr.sin_family = AF_INET; 640 addr.sin_addr.s_addr = host2uint32_t_be(rsock->addr.ipv4); 641 addr.sin_port = host2uint16_t_be(rsock->port); 642 643 log_msg(LVL_DEBUG, "addr read receive"); 644 if (!async_data_read_receive(&rcallid, &addr_length)) { 822 645 fibril_mutex_unlock(&socket->lock); 823 646 async_answer_0(callid, EINVAL); 824 647 return; 825 648 } 826 } 827 828 log_msg(LOG_DEFAULT, LVL_DEBUG, "data read receive"); 829 830 size_t length; 649 650 if (addr_length > sizeof(addr)) 651 addr_length = sizeof(addr); 652 653 log_msg(LVL_DEBUG, "addr read finalize"); 654 rc = async_data_read_finalize(rcallid, &addr, addr_length); 655 if (rc != EOK) { 656 fibril_mutex_unlock(&socket->lock); 657 async_answer_0(callid, EINVAL); 658 return; 659 } 660 } 661 662 log_msg(LVL_DEBUG, "data read receive"); 831 663 if (!async_data_read_receive(&rcallid, &length)) { 832 fibril_mutex_unlock(&socket->recv_buffer_lock);833 664 fibril_mutex_unlock(&socket->lock); 834 665 async_answer_0(callid, EINVAL); 835 666 return; 836 667 } 837 668 838 669 if (length > data_len) 839 670 length = data_len; 840 841 log_msg(LOG_DEFAULT, LVL_DEBUG, "data read finalize"); 842 843 rc = async_data_read_finalize(rcallid, socket->recv_buffer, length); 844 845 socket->recv_buffer_used -= length; 846 847 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_recvfrom: %zu left in buffer", 848 socket->recv_buffer_used); 849 850 if (socket->recv_buffer_used > 0) { 851 memmove(socket->recv_buffer, socket->recv_buffer + length, 852 socket->recv_buffer_used); 853 tcp_sock_notify_data(socket->sock_core); 854 } 855 856 fibril_condvar_broadcast(&socket->recv_buffer_cv); 857 858 if ((length < data_len) && (rc == EOK)) 671 672 log_msg(LVL_DEBUG, "data read finalize"); 673 rc = async_data_read_finalize(rcallid, buffer, length); 674 675 if (length < data_len && rc == EOK) 859 676 rc = EOVERFLOW; 860 861 ipc_call_t answer; 862 677 863 678 SOCKET_SET_READ_DATA_LENGTH(answer, length); 864 async_answer_1(callid, EOK, IPC_GET_ARG1(answer)); 865 866 fibril_mutex_unlock(&socket->recv_buffer_lock); 679 answer_call(callid, EOK, &answer, 1); 680 681 /* Push one fragment notification to client's queue */ 682 tcp_sock_notify_data(sock_core); 867 683 fibril_mutex_unlock(&socket->lock); 868 684 } … … 875 691 tcp_error_t trc; 876 692 int rc; 877 878 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_close()"); 693 uint8_t buffer[FRAGMENT_SIZE]; 694 size_t data_len; 695 xflags_t xflags; 696 697 log_msg(LVL_DEBUG, "tcp_sock_close()"); 879 698 socket_id = SOCKET_GET_SOCKET_ID(call); 880 699 … … 895 714 return; 896 715 } 897 } 898 899 /* Grab recv_buffer_lock because of CV wait in tcp_sock_recv_fibril() */ 900 fibril_mutex_lock(&socket->recv_buffer_lock); 901 socket->sock_core = NULL; 902 fibril_mutex_unlock(&socket->recv_buffer_lock); 716 717 /* Drain incoming data. This should really be done in the background. */ 718 do { 719 trc = tcp_uc_receive(socket->conn, buffer, 720 FRAGMENT_SIZE, &data_len, &xflags); 721 } while (trc == TCP_EOK); 722 723 tcp_uc_delete(socket->conn); 724 } 903 725 904 726 rc = socket_destroy(NULL, socket_id, &client->sockets, &gsock, … … 916 738 static void tcp_sock_getsockopt(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call) 917 739 { 918 log_msg(L OG_DEFAULT, LVL_DEBUG, "tcp_sock_getsockopt()");740 log_msg(LVL_DEBUG, "tcp_sock_getsockopt()"); 919 741 async_answer_0(callid, ENOTSUP); 920 742 } … … 922 744 static void tcp_sock_setsockopt(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call) 923 745 { 924 log_msg(L OG_DEFAULT, LVL_DEBUG, "tcp_sock_setsockopt()");746 log_msg(LVL_DEBUG, "tcp_sock_setsockopt()"); 925 747 async_answer_0(callid, ENOTSUP); 926 748 } … … 933 755 tcp_sockdata_t *socket = lconn->socket; 934 756 935 log_msg(L OG_DEFAULT, LVL_DEBUG, "tcp_sock_cstate_cb()");757 log_msg(LVL_DEBUG, "tcp_sock_cstate_cb()"); 936 758 fibril_mutex_lock(&socket->lock); 937 759 assert(conn == lconn->conn); … … 946 768 list_append(&lconn->ready_list, &socket->ready); 947 769 948 log_msg(L OG_DEFAULT, LVL_DEBUG, "tcp_sock_cstate_cb(): notify accept");770 log_msg(LVL_DEBUG, "tcp_sock_cstate_cb(): notify accept"); 949 771 950 772 /* Push one accept notification to client's queue */ … … 953 775 } 954 776 955 static int tcp_sock_recv_fibril(void *arg)956 {957 tcp_sockdata_t *sock = (tcp_sockdata_t *)arg;958 size_t data_len;959 xflags_t xflags;960 tcp_error_t trc;961 962 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_recv_fibril()");963 964 fibril_mutex_lock(&sock->recv_buffer_lock);965 966 while (true) {967 log_msg(LOG_DEFAULT, LVL_DEBUG, "call tcp_uc_receive()");968 while (sock->recv_buffer_used != 0 && sock->sock_core != NULL)969 fibril_condvar_wait(&sock->recv_buffer_cv,970 &sock->recv_buffer_lock);971 972 trc = tcp_uc_receive(sock->conn, sock->recv_buffer,973 TCP_SOCK_FRAGMENT_SIZE, &data_len, &xflags);974 975 if (trc != TCP_EOK) {976 sock->recv_error = trc;977 fibril_condvar_broadcast(&sock->recv_buffer_cv);978 if (sock->sock_core != NULL)979 tcp_sock_notify_data(sock->sock_core);980 break;981 }982 983 log_msg(LOG_DEFAULT, LVL_DEBUG, "got data - broadcast recv_buffer_cv");984 985 sock->recv_buffer_used = data_len;986 fibril_condvar_broadcast(&sock->recv_buffer_cv);987 if (sock->sock_core != NULL)988 tcp_sock_notify_data(sock->sock_core);989 }990 991 fibril_mutex_unlock(&sock->recv_buffer_lock);992 993 tcp_uc_delete(sock->conn);994 995 return 0;996 }997 998 777 static void tcp_sock_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) 999 778 { … … 1013 792 break; 1014 793 1015 log_msg(L OG_DEFAULT, LVL_DEBUG, "tcp_sock_connection: METHOD=%d\n",794 log_msg(LVL_DEBUG, "tcp_sock_connection: METHOD=%d\n", 1016 795 (int)IPC_GET_IMETHOD(call)); 1017 796 … … 1056 835 } 1057 836 } 1058 1059 /* Clean up */1060 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_connection: Clean up");1061 async_hangup(client.sess);1062 socket_cores_release(NULL, &client.sockets, &gsock, tcp_free_sock_data);1063 837 } 1064 838
Note:
See TracChangeset
for help on using the changeset viewer.