Changeset 988 for vendor/current/source3/libsmb/unexpected.c
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/libsmb/unexpected.c
r740 r988 21 21 #include "includes.h" 22 22 #include "../lib/util/tevent_ntstatus.h" 23 #include "lib/async_req/async_sock.h" 23 #include "lib/util_tsock.h" 24 #include "lib/tsocket/tsocket.h" 24 25 #include "libsmb/nmblib.h" 26 #include "lib/util/sys_rw.h" 25 27 26 28 static const char *nmbd_socket_dir(void) … … 41 43 struct tevent_context *ev; 42 44 int listen_sock; 45 struct tevent_fd *listen_fde; 43 46 int max_clients; 44 47 int num_clients; … … 54 57 char *mailslot_name; 55 58 56 int sock; 57 struct tevent_req *read_req; 59 struct { 60 uint8_t byte; 61 struct iovec iov[1]; 62 } ack; 63 64 struct tstream_context *sock; 58 65 struct tevent_queue *out_queue; 59 66 }; … … 71 78 { 72 79 struct nb_packet_server *result; 73 struct tevent_fd *fde;74 80 NTSTATUS status; 75 76 result = TALLOC_ZERO_P(mem_ctx, struct nb_packet_server); 81 int rc; 82 83 result = talloc_zero(mem_ctx, struct nb_packet_server); 77 84 if (result == NULL) { 78 85 status = NT_STATUS_NO_MEMORY; … … 88 95 goto fail; 89 96 } 97 rc = listen(result->listen_sock, 5); 98 if (rc < 0) { 99 status = map_nt_error_from_unix(errno); 100 goto fail; 101 } 90 102 talloc_set_destructor(result, nb_packet_server_destructor); 91 103 92 fde = tevent_add_fd(ev, result, result->listen_sock, TEVENT_FD_READ, 93 nb_packet_server_listener, result); 94 if (fde == NULL) { 104 result->listen_fde = tevent_add_fd(ev, result, 105 result->listen_sock, 106 TEVENT_FD_READ, 107 nb_packet_server_listener, 108 result); 109 if (result->listen_fde == NULL) { 95 110 status = NT_STATUS_NO_MEMORY; 96 111 goto fail; … … 106 121 static int nb_packet_server_destructor(struct nb_packet_server *s) 107 122 { 123 TALLOC_FREE(s->listen_fde); 124 108 125 if (s->listen_sock != -1) { 109 126 close(s->listen_sock); … … 117 134 void *private_data); 118 135 static void nb_packet_got_query(struct tevent_req *req); 136 static void nb_packet_client_ack_done(struct tevent_req *req); 119 137 static void nb_packet_client_read_done(struct tevent_req *req); 120 138 … … 131 149 socklen_t len; 132 150 int sock; 151 int ret; 133 152 134 153 len = sizeof(sunaddr); … … 141 160 DEBUG(6,("accepted socket %d\n", sock)); 142 161 143 client = TALLOC_ZERO_P(server, struct nb_packet_client);162 client = talloc_zero(server, struct nb_packet_client); 144 163 if (client == NULL) { 145 164 DEBUG(10, ("talloc failed\n")); … … 147 166 return; 148 167 } 149 client->sock = sock; 168 ret = tstream_bsd_existing_socket(client, sock, &client->sock); 169 if (ret != 0) { 170 DEBUG(10, ("tstream_bsd_existing_socket failed\n")); 171 close(sock); 172 return; 173 } 174 150 175 client->server = server; 151 176 talloc_set_destructor(client, nb_packet_client_destructor); … … 159 184 } 160 185 161 req = read_packet_send(client, ev, client->sock,162 sizeof(struct nb_packet_query),163 nb_packet_client_more, NULL);186 req = tstream_read_packet_send(client, ev, client->sock, 187 sizeof(struct nb_packet_query), 188 nb_packet_client_more, NULL); 164 189 if (req == NULL) { 165 DEBUG(10, (" read_packet_send failed\n"));190 DEBUG(10, ("tstream_read_packet_send failed\n")); 166 191 TALLOC_FREE(client); 167 192 return; … … 201 226 static int nb_packet_client_destructor(struct nb_packet_client *c) 202 227 { 203 if (c->sock != -1) { 204 close(c->sock); 205 c->sock = -1; 206 } 228 tevent_queue_stop(c->out_queue); 229 TALLOC_FREE(c->sock); 230 207 231 DLIST_REMOVE(c->server->clients, c); 208 232 c->server->num_clients -= 1; … … 216 240 struct nb_packet_query q; 217 241 uint8_t *buf; 218 ssize_t nread , nwritten;242 ssize_t nread; 219 243 int err; 220 char c; 221 222 nread = read_packet_recv(req, talloc_tos(), &buf, &err); 244 245 nread = tstream_read_packet_recv(req, talloc_tos(), &buf, &err); 223 246 TALLOC_FREE(req); 224 247 if (nread < (ssize_t)sizeof(struct nb_packet_query)) { … … 251 274 } 252 275 253 /* 254 * Yes, this is a blocking write of 1 byte into a unix 255 * domain socket that has never been written to. Highly 256 * unlikely that this actually blocks. 257 */ 258 c = 0; 259 nwritten = sys_write(client->sock, &c, sizeof(c)); 260 if (nwritten != sizeof(c)) { 261 DEBUG(10, ("Could not write success indicator to client: %s\n", 262 strerror(errno))); 276 client->ack.byte = 0; 277 client->ack.iov[0].iov_base = &client->ack.byte; 278 client->ack.iov[0].iov_len = 1; 279 req = tstream_writev_queue_send(client, client->server->ev, 280 client->sock, 281 client->out_queue, 282 client->ack.iov, 1); 283 if (req == NULL) { 284 DEBUG(10, ("tstream_writev_queue_send failed\n")); 263 285 TALLOC_FREE(client); 264 286 return; 265 287 } 266 267 client->read_req = read_packet_send(client, client->server->ev, 268 client->sock, 1, NULL, NULL); 269 if (client->read_req == NULL) { 288 tevent_req_set_callback(req, nb_packet_client_ack_done, client); 289 290 req = tstream_read_packet_send(client, client->server->ev, 291 client->sock, 1, NULL, NULL); 292 if (req == NULL) { 270 293 DEBUG(10, ("Could not activate reader for client exit " 271 294 "detection\n")); … … 273 296 return; 274 297 } 275 tevent_req_set_callback( client->read_req, nb_packet_client_read_done,298 tevent_req_set_callback(req, nb_packet_client_read_done, 276 299 client); 300 } 301 302 static void nb_packet_client_ack_done(struct tevent_req *req) 303 { 304 struct nb_packet_client *client = tevent_req_callback_data( 305 req, struct nb_packet_client); 306 ssize_t nwritten; 307 int err; 308 309 nwritten = tstream_writev_queue_recv(req, &err); 310 311 TALLOC_FREE(req); 312 313 if (nwritten == -1) { 314 DEBUG(10, ("tstream_writev_queue_recv failed: %s\n", 315 strerror(err))); 316 TALLOC_FREE(client); 317 return; 318 } 277 319 } 278 320 … … 285 327 int err; 286 328 287 nread = read_packet_recv(req, talloc_tos(), &buf, &err);329 nread = tstream_read_packet_recv(req, talloc_tos(), &buf, &err); 288 330 TALLOC_FREE(req); 289 331 if (nread == 1) { … … 379 421 } 380 422 381 state = TALLOC_ZERO_P(client, struct nb_packet_client_state);423 state = talloc_zero(client, struct nb_packet_client_state); 382 424 if (state == NULL) { 383 425 DEBUG(10, ("talloc failed\n")); … … 398 440 state->iov[1].iov_len = state->hdr.len; 399 441 400 TALLOC_FREE(client->read_req);401 402 req = writev_send(client, client->server->ev,client->out_queue,403 client->sock, true,state->iov, 2);442 req = tstream_writev_queue_send(state, client->server->ev, 443 client->sock, 444 client->out_queue, 445 state->iov, 2); 404 446 if (req == NULL) { 405 DEBUG(10, (" writev_send failed\n"));447 DEBUG(10, ("tstream_writev_queue_send failed\n")); 406 448 return; 407 449 } … … 417 459 int err; 418 460 419 nwritten = writev_recv(req, &err);461 nwritten = tstream_writev_queue_recv(req, &err); 420 462 421 463 TALLOC_FREE(req); … … 423 465 424 466 if (nwritten == -1) { 425 DEBUG(10, (" writevfailed: %s\n", strerror(err)));467 DEBUG(10, ("tstream_writev_queue failed: %s\n", strerror(err))); 426 468 TALLOC_FREE(client); 427 } 428 429 if (tevent_queue_length(client->out_queue) == 0) { 430 client->read_req = read_packet_send(client, client->server->ev, 431 client->sock, 1, 432 NULL, NULL); 433 if (client->read_req == NULL) { 434 DEBUG(10, ("Could not activate reader for client exit " 435 "detection\n")); 436 TALLOC_FREE(client); 437 return; 438 } 439 tevent_req_set_callback(client->read_req, 440 nb_packet_client_read_done, 441 client); 469 return; 442 470 } 443 471 } 444 472 445 473 struct nb_packet_reader { 446 intsock;474 struct tstream_context *sock; 447 475 }; 448 476 449 477 struct nb_packet_reader_state { 450 478 struct tevent_context *ev; 451 struct sockaddr_un addr;452 479 struct nb_packet_query query; 453 480 const char *mailslot_name; … … 457 484 }; 458 485 459 static int nb_packet_reader_destructor(struct nb_packet_reader *r);460 486 static void nb_packet_reader_connected(struct tevent_req *subreq); 461 487 static void nb_packet_reader_sent_query(struct tevent_req *subreq); … … 470 496 struct tevent_req *req, *subreq; 471 497 struct nb_packet_reader_state *state; 472 char *path; 498 struct tsocket_address *laddr; 499 char *rpath; 500 struct tsocket_address *raddr; 501 int ret; 473 502 474 503 req = tevent_req_create(mem_ctx, &state, … … 486 515 } 487 516 488 state->reader = TALLOC_ZERO_P(state, struct nb_packet_reader);517 state->reader = talloc_zero(state, struct nb_packet_reader); 489 518 if (tevent_req_nomem(state->reader, req)) { 490 519 return tevent_req_post(req, ev); 491 520 } 492 521 493 path = talloc_asprintf(talloc_tos(), "%s/%s", nmbd_socket_dir(), 494 "unexpected"); 495 if (tevent_req_nomem(path, req)) { 496 return tevent_req_post(req, ev); 497 } 498 state->addr.sun_family = AF_UNIX; 499 strlcpy(state->addr.sun_path, path, sizeof(state->addr.sun_path)); 500 TALLOC_FREE(path); 501 502 state->reader->sock = socket(AF_UNIX, SOCK_STREAM, 0); 503 if (state->reader->sock == -1) { 522 ret = tsocket_address_unix_from_path(state, "", &laddr); 523 if (ret != 0) { 504 524 tevent_req_nterror(req, map_nt_error_from_unix(errno)); 505 525 return tevent_req_post(req, ev); 506 526 } 507 talloc_set_destructor(state->reader, nb_packet_reader_destructor); 508 509 subreq = async_connect_send(state, ev, state->reader->sock, 510 (struct sockaddr *)(void *)&state->addr, 511 sizeof(state->addr)); 527 rpath = talloc_asprintf(state, "%s/%s", nmbd_socket_dir(), 528 "unexpected"); 529 if (tevent_req_nomem(rpath, req)) { 530 return tevent_req_post(req, ev); 531 } 532 ret = tsocket_address_unix_from_path(state, rpath, &raddr); 533 if (ret != 0) { 534 tevent_req_nterror(req, map_nt_error_from_unix(errno)); 535 return tevent_req_post(req, ev); 536 } 537 538 subreq = tstream_unix_connect_send(state, ev, laddr, raddr); 512 539 if (tevent_req_nomem(subreq, req)) { 513 540 return tevent_req_post(req, ev); … … 515 542 tevent_req_set_callback(subreq, nb_packet_reader_connected, req); 516 543 return req; 517 }518 519 static int nb_packet_reader_destructor(struct nb_packet_reader *r)520 {521 if (r->sock != -1) {522 close(r->sock);523 r->sock = -1;524 }525 return 0;526 544 } 527 545 … … 535 553 int num_iovecs = 1; 536 554 537 res = async_connect_recv(subreq, &err); 555 res = tstream_unix_connect_recv(subreq, &err, state->reader, 556 &state->reader->sock); 538 557 TALLOC_FREE(subreq); 539 558 if (res == -1) { 540 DEBUG(10, (" async_connect failed: %s\n", strerror(err)));559 DEBUG(10, ("tstream_unix_connect failed: %s\n", strerror(err))); 541 560 tevent_req_nterror(req, map_nt_error_from_unix(err)); 542 561 return; … … 553 572 } 554 573 555 subreq = writev_send(state, state->ev, NULL, state->reader->sock,556 true,state->iov, num_iovecs);574 subreq = tstream_writev_send(state, state->ev, state->reader->sock, 575 state->iov, num_iovecs); 557 576 if (tevent_req_nomem(subreq, req)) { 558 577 return; … … 570 589 int err; 571 590 572 written = writev_recv(subreq, &err);591 written = tstream_writev_recv(subreq, &err); 573 592 TALLOC_FREE(subreq); 574 593 if (written == -1) { … … 580 599 return; 581 600 } 582 subreq = read_packet_send(state, state->ev, state->reader->sock, 583 sizeof(state->c), NULL, NULL); 601 subreq = tstream_read_packet_send(state, state->ev, 602 state->reader->sock, 603 sizeof(state->c), NULL, NULL); 584 604 if (tevent_req_nomem(subreq, req)) { 585 605 return; … … 598 618 uint8_t *buf; 599 619 600 nread = read_packet_recv(subreq, state, &buf, &err);620 nread = tstream_read_packet_recv(subreq, state, &buf, &err); 601 621 TALLOC_FREE(subreq); 602 622 if (nread == -1) { … … 623 643 624 644 if (tevent_req_is_nterror(req, &status)) { 645 tevent_req_received(req); 625 646 return status; 626 647 } 627 648 *preader = talloc_move(mem_ctx, &state->reader); 649 tevent_req_received(req); 628 650 return NT_STATUS_OK; 629 651 } … … 649 671 return NULL; 650 672 } 651 subreq = read_packet_send(state, ev, reader->sock,652 sizeof(struct nb_packet_client_header),653 nb_packet_read_more, state);673 subreq = tstream_read_packet_send(state, ev, reader->sock, 674 sizeof(struct nb_packet_client_header), 675 nb_packet_read_more, state); 654 676 if (tevent_req_nomem(subreq, req)) { 655 677 return tevent_req_post(req, ev); … … 683 705 int err; 684 706 685 nread = read_packet_recv(subreq, state, &state->buf, &err);707 nread = tstream_read_packet_recv(subreq, state, &state->buf, &err); 686 708 if (nread == -1) { 687 709 tevent_req_nterror(req, map_nt_error_from_unix(err)); … … 702 724 703 725 if (tevent_req_is_nterror(req, &status)) { 726 tevent_req_received(req); 704 727 return status; 705 728 } … … 712 735 state->hdr.type, state->hdr.ip, state->hdr.port); 713 736 if (packet == NULL) { 737 tevent_req_received(req); 714 738 return NT_STATUS_INVALID_NETWORK_RESPONSE; 715 739 } 716 740 *ppacket = packet; 741 tevent_req_received(req); 717 742 return NT_STATUS_OK; 718 743 }
Note:
See TracChangeset
for help on using the changeset viewer.