Changeset 43171 in vbox for trunk/src/VBox/ExtPacks
- Timestamp:
- Sep 4, 2012 5:07:27 PM (13 years ago)
- svn:sync-xref-src-repo-rev:
- 80557
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ExtPacks/VNC/VBoxVNC.cpp
r40383 r43171 28 28 #include <iprt/path.h> 29 29 #include <iprt/mem.h> 30 #include <iprt/socket.h> 30 31 #include <iprt/stream.h> 31 32 #include <iprt/string.h> … … 43 44 #define VNC_ADDRESSSIZE 60 44 45 #define VNC_PORTSSIZE 20 46 #define VNC_ADDRESS_OPTION_MAX 500 45 47 46 48 class VNCServerImpl … … 210 212 vncServer->desktopName = "VBoxVNC"; 211 213 214 #ifndef LIBVNCSERVER_IPv6 215 212 216 // get listen address 213 217 char szAddress[VNC_ADDRESSSIZE + 1] = {0}; … … 269 273 &port, sizeof(port), NULL); 270 274 LogRel(("VNC: port = %u\n", port)); 271 275 #else 276 // with IPv6 from here 277 /* 278 279 This is the deal: 280 281 Four new options are available: 282 - VNCAddress4 -> IPv4 address to use 283 - VNCPort4 -> IPv4 Port to use 284 - VNCAddress6 -> IPv6 address to use 285 - VNCPort6 -> IPv6 port to use 286 287 By default we prefer IPv6 over IPv4. 288 289 The address length can be unlimited as the interface identifier is not 290 limited by any specs - if this is wrong, and someone knows the line 291 and the RFC number, i'd appreciate a message :) 292 293 THE MAXIMUM LENGTH OF THE RETURNED VALUES MUST NOT BE GREATER THAN: 294 295 --> VBOX_ADDRESS_OPTION_MAX <-- 296 297 which is defined at the top of this file. 298 299 The way to determine which address to use is as follows: 300 301 1st - get address information from VRDEProperties 302 "TCP/Address" 303 "TCP/Ports" 304 305 2nd - if the address information is IPv4 get VNCAddress6 and VNCPort6 306 2nd - if the address information is IPv6 get VNCAddress4 and VNCPort4 307 2nd - if the address information is EMPTY and TCP/Ports returns 3389, 308 check both, VNCAddress4 and VNCAddress6 as well as the ports. 309 3389 is not a valid VNC port, therefore we assume it's not 310 been set 311 312 If one of the addresses is empty we assume to listen on any 313 interface/address for that protocol. In other words: 314 IPv4: 0.0.0.0 315 IPv6: :: 316 317 2nd - if everything is empty -> listen on all interfaces 318 319 3rd - check if the addresses are valid hand them to libvncserver 320 to open the initial sockets. 321 322 4th - after the sockets have been opened, the used port of the 323 address/protocol in TCP/Address is returned. 324 if TCP/Address is empty, prefer IPv6 325 326 */ 327 328 /* ok, now first get the address from VRDE/TCP/Address. 329 330 */ 331 // this should be put somewhere else 332 char szIPv6ListenAll[] = "::"; 333 char szIPv4ListenAll[] = "0.0.0.0"; 334 335 uint32_t ulServerPort4 = 0; 336 uint32_t ulServerPort6 = 0; 337 uint32_t cbOut = 0; 338 size_t resSize = 0; 339 RTNETADDRTYPE iAddrType = RTNETADDRTYPE_INVALID; 340 char *pszTCPAddress = NULL; 341 char *pszTCPPort = NULL; 342 char *pszVNCAddress4 = NULL; 343 char *pszVNCPort4 = NULL; 344 char *pszVNCAddress6 = NULL; 345 char *pszVNCPort6 = NULL; 346 char *pszServerAddress4 = NULL; 347 char *pszServerAddress6 = NULL; 348 char *pszGetAddrInfo4 = NULL; // used to store the result of RTSocketGetAddrInfo() 349 char *pszGetAddrInfo6 = NULL; // used to store the result of RTSocketGetAddrInfo() 350 351 // get address 352 rc = -1; 353 pszTCPAddress = (char *) RTMemTmpAlloc(VNC_ADDRESS_OPTION_MAX); 354 memset(pszTCPAddress, '\0', VNC_ADDRESS_OPTION_MAX); 355 356 rc = instance->mCallbacks->VRDECallbackProperty(instance->mCallback, 357 VRDE_QP_NETWORK_ADDRESS, 358 pszTCPAddress, 359 VNC_ADDRESS_OPTION_MAX, 360 &cbOut); 361 362 // get port (range) 363 rc = -1; 364 pszTCPPort = (char *) RTMemTmpAlloc(VNC_ADDRESS_OPTION_MAX); 365 memset(pszTCPPort,'\0',VNC_ADDRESS_OPTION_MAX); 366 367 rc = instance->mCallbacks->VRDECallbackProperty(instance->mCallback, 368 VRDE_QP_NETWORK_PORT_RANGE, 369 pszTCPPort, 370 VNC_ADDRESS_OPTION_MAX, 371 &cbOut); 372 373 Assert(cbOut < VNC_ADDRESS_OPTION_MAX); 374 375 // get tcp ports option from vrde 376 377 rc = -1; 378 379 pszTCPPort = (char *) RTMemTmpAlloc(6); 380 memset(pszTCPPort,'\0',6); 381 382 VRDEFEATURE *pVRDEFeature = (VRDEFEATURE *) RTMemTmpAlloc(VNC_ADDRESS_OPTION_MAX); 383 pVRDEFeature->u32ClientId = 0; 384 385 RTStrCopy(pVRDEFeature->achInfo, 19, "Property/TCP/Ports"); 386 387 cbOut = 1; 388 389 rc = instance->mCallbacks->VRDECallbackProperty(instance->mCallback, 390 VRDE_QP_FEATURE, 391 pVRDEFeature, 392 VNC_ADDRESS_OPTION_MAX, 393 &cbOut); 394 395 Assert(cbOut < VNC_ADDRESS_OPTION_MAX); 396 397 if (RT_SUCCESS(rc)) 398 { 399 RTStrCopy(pszTCPPort, cbOut, pVRDEFeature->achInfo); 400 } 401 402 // get VNCAddress4 403 rc = -1; 404 const uint32_t lVNCAddress4FeatureSize = sizeof(VRDEFEATURE) + 24; 405 406 pszVNCAddress4 = (char *) RTMemTmpAlloc(24); 407 memset(pszVNCAddress4,'\0',24); 408 409 pVRDEFeature->u32ClientId = 0; 410 411 RTStrCopy(pVRDEFeature->achInfo, 21, "Property/VNCAddress4"); 412 413 cbOut = 1; 414 415 rc = instance->mCallbacks->VRDECallbackProperty(instance->mCallback, 416 VRDE_QP_FEATURE, 417 pVRDEFeature, 418 VNC_ADDRESS_OPTION_MAX, 419 &cbOut); 420 421 Assert(cbOut <= 24); 422 423 if (RT_SUCCESS(rc)) 424 { 425 RTStrCopy(pszVNCAddress4,cbOut,pVRDEFeature->achInfo); 426 } 427 428 // VNCPort4 429 rc = -1; 430 pszVNCPort4 = (char *) RTMemTmpAlloc(6); 431 432 pVRDEFeature->u32ClientId = 0; 433 RTStrCopy(pVRDEFeature->achInfo, VNC_ADDRESS_OPTION_MAX, "Property/VNCPort4"); 434 435 cbOut = VNC_ADDRESS_OPTION_MAX; 436 rc = instance->mCallbacks->VRDECallbackProperty(instance->mCallback, 437 VRDE_QP_FEATURE, 438 pVRDEFeature, 439 VNC_ADDRESS_OPTION_MAX, 440 &cbOut); 441 442 443 Assert(cbOut <= VNC_ADDRESS_OPTION_MAX); 444 if (RT_SUCCESS(rc)) 445 { 446 if (cbOut < 6) 447 { 448 RTStrCopy(pszVNCPort4, cbOut, pVRDEFeature->achInfo); 449 } 450 451 } 452 453 // VNCAddress6 454 rc = -1; 455 456 pszVNCAddress6 = (char *) RTMemTmpAlloc(VNC_ADDRESS_OPTION_MAX); 457 memset(pszVNCAddress6,'\0',VNC_ADDRESS_OPTION_MAX); 458 459 pVRDEFeature->u32ClientId = 0; 460 RTStrCopy(pVRDEFeature->achInfo, 21,"Property/VNCAddress6"); 461 462 cbOut = VNC_ADDRESS_OPTION_MAX; 463 464 rc = instance->mCallbacks->VRDECallbackProperty(instance->mCallback, 465 VRDE_QP_FEATURE, 466 pVRDEFeature, 467 VNC_ADDRESS_OPTION_MAX, 468 &cbOut); 469 470 Assert(cbOut <= VNC_ADDRESS_OPTION_MAX); 471 472 if (RT_SUCCESS(rc)) 473 { 474 RTStrCopy(pszVNCAddress6, cbOut, pVRDEFeature->achInfo); 475 } 476 477 // VNCPort6 478 pszVNCPort6 = (char *) RTMemTmpAlloc(6); 479 memset(pszVNCPort6,'\0', 6); 480 481 pVRDEFeature->u32ClientId = 0; 482 RTStrCopy(pVRDEFeature->achInfo, 18 , "Property/VNCPort6"); 483 484 cbOut = 5; 485 486 rc = instance->mCallbacks->VRDECallbackProperty(instance->mCallback, 487 VRDE_QP_FEATURE, 488 pVRDEFeature, 489 VNC_ADDRESS_OPTION_MAX, 490 &cbOut); 491 492 Assert(cbOut <= 6); 493 494 if (RT_SUCCESS(rc)) 495 { 496 RTStrCopy(pszVNCPort6, cbOut, pVRDEFeature->achInfo); 497 } 498 499 rc = RTStrIsIpAddr4(pszTCPAddress); 500 501 if (RT_SUCCESS(rc)) 502 { 503 pszServerAddress4 = pszTCPAddress; 504 505 if (strlen(pszTCPPort) > 0) 506 { 507 rc = RTStrToUInt32Ex(pszTCPPort, NULL, 10, &ulServerPort4); 508 509 if (!RT_SUCCESS(rc) || ulServerPort4 > 65535) 510 ulServerPort4 = 0; 511 } 512 513 rc = RTStrIsIpAddr6(pszVNCAddress6, NULL, 0, true, true); 514 515 if (RT_SUCCESS(rc)) 516 { 517 pszServerAddress6 = pszVNCAddress6; 518 519 } 520 else 521 { 522 pszServerAddress6 = szIPv6ListenAll; 523 } 524 525 if (strlen(pszVNCPort6) > 0) 526 { 527 rc = RTStrToUInt32Ex(pszVNCPort6, NULL, 10, &ulServerPort6); 528 529 if (!RT_SUCCESS(rc) || ulServerPort6 > 65535) 530 ulServerPort6 = 0; 531 532 } 533 534 } 535 536 rc = RTStrIsIpAddr6(pszTCPAddress, NULL, 0, true, true); 537 538 if (RT_SUCCESS(rc)) 539 { 540 pszServerAddress6 = pszTCPAddress; 541 542 if (strlen(pszTCPPort) > 0) 543 { 544 rc = RTStrToUInt32Ex(pszTCPPort, NULL, 10, &ulServerPort6); 545 546 if (!RT_SUCCESS(rc) || ulServerPort6 > 65535) 547 ulServerPort6 = 0; 548 } 549 550 rc = RTStrIsIpAddr4(pszVNCAddress4); 551 552 if (RT_SUCCESS(rc)) 553 { 554 pszServerAddress4 = pszVNCAddress4; 555 556 } 557 else 558 { 559 pszServerAddress4 = szIPv4ListenAll; 560 } 561 562 if (strlen(pszVNCPort4) > 0) 563 { 564 rc = RTStrToUInt32Ex(pszVNCPort4, NULL, 10, &ulServerPort4); 565 566 if (!RT_SUCCESS(rc) || ulServerPort4 > 65535) 567 ulServerPort4 = 0; 568 569 } 570 } 571 572 if ((pszServerAddress4 != pszTCPAddress) && (pszServerAddress6 != pszTCPAddress) && (strlen(pszTCPAddress) > 0)) 573 { 574 // here we go, we prefer IPv6 over IPv4; 575 pszGetAddrInfo6 = (char *) RTMemTmpAlloc(42); 576 memset(pszGetAddrInfo6, '\0', 42); 577 resSize = 42; 578 iAddrType = RTNETADDRTYPE_IPV6; 579 580 rc = RTSocketGetAddrInfo(pszTCPAddress, pszGetAddrInfo6, &resSize, &iAddrType); 581 582 if (RT_SUCCESS(rc)) 583 { 584 pszServerAddress6 = pszGetAddrInfo6; 585 586 } 587 else 588 { 589 RTMemTmpFree(pszGetAddrInfo6); 590 pszGetAddrInfo6 = NULL; 591 } 592 593 if (!pszServerAddress6) 594 { 595 pszGetAddrInfo4 = (char *) RTMemTmpAlloc(16); 596 memset(pszGetAddrInfo4,'\0',16); 597 resSize = 16; 598 iAddrType = RTNETADDRTYPE_IPV4; 599 600 rc = RTSocketGetAddrInfo(pszTCPAddress, pszGetAddrInfo4, &resSize, &iAddrType); 601 602 if (RT_SUCCESS(rc)) 603 { 604 pszServerAddress4 = pszGetAddrInfo4; 605 } 606 else 607 { 608 RTMemTmpFree(pszGetAddrInfo4); 609 pszGetAddrInfo4 = NULL; 610 } 611 } 612 } 613 614 if (!pszServerAddress4 && strlen(pszVNCAddress4) > 0) 615 { 616 pszGetAddrInfo4 = (char *) RTMemTmpAlloc(16); 617 memset(pszGetAddrInfo4,'\0',16); 618 resSize = 16; 619 iAddrType = RTNETADDRTYPE_IPV4; 620 621 rc = RTSocketGetAddrInfo(pszVNCAddress4, pszGetAddrInfo4, &resSize, &iAddrType); 622 623 if (RT_SUCCESS(rc)) 624 pszServerAddress4 = pszGetAddrInfo4; 625 626 } 627 628 if (!pszServerAddress6 && strlen(pszVNCAddress6) > 0) 629 { 630 pszGetAddrInfo6 = (char *) RTMemTmpAlloc(42); 631 memset(pszGetAddrInfo6, '\0', 42); 632 resSize = 42; 633 iAddrType = RTNETADDRTYPE_IPV6; 634 635 rc = RTSocketGetAddrInfo(pszVNCAddress6, pszGetAddrInfo6, &resSize, &iAddrType); 636 637 if (RT_SUCCESS(rc)) 638 pszServerAddress6 = pszGetAddrInfo6; 639 640 } 641 if (!pszServerAddress4) 642 { 643 rc = RTStrIsIpAddr4(pszVNCAddress4); 644 645 if (RT_SUCCESS(rc)) 646 pszServerAddress4 = pszVNCAddress4; 647 else 648 pszServerAddress4 = szIPv4ListenAll; 649 } 650 if (!pszServerAddress6) 651 { 652 rc = RTStrIsIpAddr6(pszVNCAddress6, NULL, 0, true, true); 653 654 if (RT_SUCCESS(rc)) 655 pszServerAddress6 = pszVNCAddress6; 656 else 657 pszServerAddress6 = szIPv6ListenAll; 658 } 659 660 if (pszVNCPort4 && ulServerPort4 == 0) 661 { 662 rc = RTStrToUInt32Ex(pszVNCPort4, NULL, 10, &ulServerPort4); 663 664 if (!RT_SUCCESS(rc) || ulServerPort4 > 65535) 665 ulServerPort4 = 0; 666 } 667 if (pszVNCPort6 && ulServerPort6 == 0) 668 { 669 rc = RTStrToUInt32Ex(pszVNCPort6, NULL, 10, &ulServerPort6); 670 671 if (!RT_SUCCESS(rc) || ulServerPort6 > 65535) 672 ulServerPort6 = 0; 673 } 674 if (ulServerPort4 == 0 || ulServerPort6 == 0) 675 { 676 vncServer->autoPort = 1; 677 } 678 else 679 { 680 vncServer->port = ulServerPort4; 681 vncServer->ipv6port = ulServerPort6; 682 } 683 684 if (!rfbStringToAddr(pszServerAddress4,&vncServer->listenInterface)) 685 LogRel(("VNC: could not parse VNC server listen address IPv4 '%s'\n", pszServerAddress4)); 686 687 vncServer->listen6Interface = pszServerAddress6; 688 689 rfbInitServer(vncServer); 690 691 vncServer->newClientHook = rfbNewClientEvent; 692 vncServer->kbdAddEvent = vncKeyboardEvent; 693 vncServer->ptrAddEvent = vncMouseEvent; 694 695 // notify about the actually used port 696 int port = 0; 697 port = vncServer->ipv6port; 698 699 if (vncServer->listen6Sock < 0) 700 { 701 LogRel(("VNC: not able to bind to IPv6 socket with address '%s'\n",pszServerAddress6)); 702 port = 0; 703 704 } 705 706 instance->mCallbacks->VRDECallbackProperty(instance->mCallback, 707 VRDE_SP_NETWORK_BIND_PORT, 708 &port, sizeof(port), NULL); 709 LogRel(("VNC: port6 = %u\n", port)); 710 711 if (pVRDEFeature) 712 RTMemTmpFree(pVRDEFeature); 713 714 if (pszTCPAddress) 715 { 716 if (pszTCPAddress == pszServerAddress4) 717 pszServerAddress4 = NULL; 718 719 if (pszTCPAddress == pszServerAddress6) 720 pszServerAddress6 = NULL; 721 722 RTMemTmpFree(pszTCPAddress); 723 } 724 725 if (pszTCPPort) 726 RTMemTmpFree(pszTCPPort); 727 728 if (pszVNCAddress4) 729 RTMemTmpFree(pszVNCAddress4); 730 731 if (pszVNCPort4) 732 RTMemTmpFree(pszVNCPort4); 733 734 if (pszGetAddrInfo4) 735 RTMemTmpFree(pszGetAddrInfo4); 736 737 if (pszVNCAddress6) 738 RTMemTmpFree(pszVNCAddress6); 739 740 if (pszGetAddrInfo6) 741 RTMemTmpFree(pszGetAddrInfo6); 742 743 // with ipv6 to here 744 #endif 272 745 // let's get the password 273 746 instance->szVNCPassword[0] = '\0';
Note:
See TracChangeset
for help on using the changeset viewer.