1 17 package org.alfresco.filesys.smb.server.win32; 18 19 import java.util.ArrayList ; 20 import java.util.List ; 21 22 import org.alfresco.filesys.netbios.NetBIOSName; 23 import org.alfresco.filesys.netbios.win32.NetBIOS; 24 import org.alfresco.filesys.netbios.win32.NetBIOSSocket; 25 import org.alfresco.filesys.netbios.win32.Win32NetBIOS; 26 import org.alfresco.filesys.netbios.win32.WinsockError; 27 import org.alfresco.filesys.netbios.win32.WinsockNetBIOSException; 28 import org.alfresco.filesys.server.config.ServerConfiguration; 29 import org.alfresco.filesys.smb.mailslot.HostAnnouncer; 30 import org.alfresco.filesys.smb.mailslot.Win32NetBIOSHostAnnouncer; 31 import org.alfresco.filesys.smb.mailslot.WinsockNetBIOSHostAnnouncer; 32 import org.alfresco.filesys.smb.server.PacketHandler; 33 import org.alfresco.filesys.smb.server.SMBServer; 34 import org.alfresco.filesys.smb.server.SMBSrvSession; 35 import org.alfresco.filesys.smb.server.SessionSocketHandler; 36 import org.apache.commons.logging.Log; 37 import org.apache.commons.logging.LogFactory; 38 39 47 public class Win32NetBIOSSessionSocketHandler extends SessionSocketHandler implements LanaListener 48 { 49 50 52 private static final Log logger = LogFactory.getLog("org.alfresco.smb.protocol"); 53 54 58 public static final long LANAPollingInterval = 5000; 60 62 private String m_srvName; 63 64 66 private byte[] m_acceptClient; 67 68 70 private NetBIOSName m_nbName; 71 private int m_nameNum; 72 73 75 private NetBIOSName m_wksNbName; 76 private int m_wksNameNum; 77 78 80 private int m_lana = -1; 81 82 85 private boolean m_lanaValid; 86 87 89 private long m_lanaPoll; 90 91 93 private boolean m_useWinsock; 94 95 97 private NetBIOSSocket m_nbSocket; 98 99 102 private NetBIOSSocket m_wksSocket; 103 104 110 public Win32NetBIOSSessionSocketHandler(SMBServer srv, boolean debug) 111 { 112 super("Win32 NetBIOS", srv, debug); 113 114 116 if (srv.getConfiguration().getWin32ServerName() != null) 117 m_srvName = srv.getConfiguration().getWin32ServerName(); 118 else 119 m_srvName = srv.getConfiguration().getServerName(); 120 121 123 NetBIOSName accName = new NetBIOSName("*", NetBIOSName.WorkStation, false); 124 m_acceptClient = accName.getNetBIOSName(); 125 126 128 m_lana = srv.getConfiguration().getWin32LANA(); 129 130 132 m_useWinsock = srv.getConfiguration().useWinsockNetBIOS(); 133 134 136 if (logger.isDebugEnabled() && hasDebug()) 137 logger.debug("[SMB] Win32 NetBIOS server " + m_srvName + " (using " + 138 (isUsingWinsock() ? "Winsock" : "Netbios() API") + ")"); 139 140 142 m_lanaPoll = LANAPollingInterval; 143 } 144 145 152 public Win32NetBIOSSessionSocketHandler(SMBServer srv, int lana, boolean debug) 153 { 154 super("Win32 NetBIOS", srv, debug); 155 156 158 if (srv.getConfiguration().getWin32ServerName() != null) 159 m_srvName = srv.getConfiguration().getWin32ServerName(); 160 else 161 m_srvName = srv.getConfiguration().getServerName(); 162 163 165 NetBIOSName accName = new NetBIOSName("*", NetBIOSName.WorkStation, false); 166 m_acceptClient = accName.getNetBIOSName(); 167 168 170 m_lana = lana; 171 172 174 m_useWinsock = srv.getConfiguration().useWinsockNetBIOS(); 175 176 178 if (logger.isDebugEnabled() && hasDebug()) 179 logger.debug("[SMB] Win32 NetBIOS server " + m_srvName + " (using " + 180 (isUsingWinsock() ? "Winsock" : "Netbios() API") + ")"); 181 182 184 m_lanaPoll = LANAPollingInterval; 185 } 186 187 194 public Win32NetBIOSSessionSocketHandler(SMBServer srv, String nbName, boolean debug) 195 { 196 super("Win32 NetBIOS", srv, debug); 197 198 200 m_srvName = nbName; 201 202 204 NetBIOSName accName = new NetBIOSName("*", NetBIOSName.WorkStation, false); 205 m_acceptClient = accName.getNetBIOSName(); 206 207 209 m_lana = srv.getConfiguration().getWin32LANA(); 210 211 213 m_useWinsock = srv.getConfiguration().useWinsockNetBIOS(); 214 215 217 if (logger.isDebugEnabled() && hasDebug()) 218 logger.debug("[SMB] Win32 NetBIOS server " + m_srvName + " (using " + 219 (isUsingWinsock() ? "Winsock" : "Netbios() API") + ")"); 220 221 223 m_lanaPoll = LANAPollingInterval; 224 } 225 226 231 public final int getLANANumber() 232 { 233 return m_lana; 234 } 235 236 241 public final long getLANAOfflinePollingInterval() 242 { 243 return m_lanaPoll; 244 } 245 246 251 public final int getNameNumber() 252 { 253 return m_nameNum; 254 } 255 256 261 public final String getServerName() 262 { 263 return m_srvName; 264 } 265 266 271 public final boolean isUsingWinsock() 272 { 273 return m_useWinsock; 274 } 275 276 281 public void initialize() throws Exception 282 { 283 284 287 int[] lanas = Win32NetBIOS.LanaEnumerate(); 288 if (lanas != null && lanas.length > 0) 289 { 290 291 294 if (m_lana == -1) 295 m_lana = lanas[0]; 296 else 297 { 298 299 301 boolean lanaOnline = false; 302 int idx = 0; 303 304 while (idx < lanas.length && lanaOnline == false) 305 { 306 307 309 if (lanas[idx++] == getLANANumber()) 310 lanaOnline = true; 311 } 312 313 316 if (lanaOnline == false) 317 { 318 319 321 m_lanaValid = false; 322 return; 323 } 324 } 325 } 326 else 327 { 328 329 331 if (m_lana == -1) 332 throw new Exception ("No Win32 NetBIOS LANAs available"); 333 334 336 m_lanaValid = false; 337 return; 338 } 339 340 342 m_nbName = new NetBIOSName(m_srvName, NetBIOSName.FileServer, false); 343 m_wksNbName = new NetBIOSName(m_srvName, NetBIOSName.WorkStation, false); 344 345 347 if ( isUsingWinsock()) 348 initializeWinsockNetBIOS(); 349 else 350 initializeNetbiosAPI(); 351 352 354 m_lanaValid = true; 355 } 356 357 362 private final void initializeNetbiosAPI() 363 throws Exception 364 { 365 367 Win32NetBIOS.Reset(m_lana); 368 369 371 m_nameNum = Win32NetBIOS.AddName(m_lana, m_nbName.getNetBIOSName()); 372 if (m_nameNum < 0) 373 throw new Exception ("Win32 NetBIOS AddName failed (file server), status = 0x" 374 + Integer.toHexString(-m_nameNum) + ", " + NetBIOS.getErrorString(-m_nameNum)); 375 376 379 m_wksNameNum = Win32NetBIOS.AddName(m_lana, m_wksNbName.getNetBIOSName()); 380 if (m_wksNameNum < 0) 381 throw new Exception ("Win32 NetBIOS AddName failed (workstation), status = 0x" 382 + Integer.toHexString(-m_wksNameNum) + ", " + NetBIOS.getErrorString(-m_wksNameNum)); 383 } 384 385 390 private final void initializeWinsockNetBIOS() 391 throws Exception 392 { 393 395 m_nbSocket = NetBIOSSocket.createListenerSocket( getLANANumber(), m_nbName); 396 397 399 m_wksSocket = NetBIOSSocket.createListenerSocket( getLANANumber(), m_wksNbName); 400 } 401 402 408 public final boolean isLANAValid() 409 { 410 return m_lanaValid; 411 } 412 413 416 public void shutdownRequest() 417 { 418 super.shutdownRequest(); 419 420 422 if ( isLANAValid()) 423 Win32NetBIOS.Reset(m_lana); 424 425 427 if ( isUsingWinsock()) 428 { 429 if ( m_nbSocket != null) 430 { 431 m_nbSocket.closeSocket(); 432 m_nbSocket = null; 433 } 434 435 if ( m_wksSocket != null) 436 { 437 m_wksSocket.closeSocket(); 438 m_wksSocket = null; 439 } 440 } 441 } 442 443 446 public void run() 447 { 448 449 try 450 { 451 452 454 clearShutdown(); 455 456 458 while (hasShutdown() == false) 459 { 460 461 463 if (isLANAValid()) 464 { 465 467 if ( isUsingWinsock()) 468 { 469 471 runWinsock(); 472 } 473 else 474 { 475 477 runNetBIOS(); 478 } 479 } 480 else 481 { 482 483 485 try 486 { 487 Thread.sleep(getLANAOfflinePollingInterval()); 488 } 489 catch (Exception ex) 490 { 491 } 492 493 496 try 497 { 498 initialize(); 499 } 500 catch (Exception ex) 501 { 502 503 505 if (logger.isDebugEnabled() && hasDebug()) 506 { 507 logger.debug("[SMB] Win32 NetBIOS Failed To ReInitialize LANA"); 508 logger.debug(" " + ex.getMessage()); 509 } 510 } 511 512 514 if (logger.isDebugEnabled() && hasDebug() && isLANAValid()) 515 logger.debug("[SMB] Win32 NetBIOS LANA " + getLANANumber() + " Back Online"); 516 } 517 } 518 } 519 catch (Exception ex) 520 { 521 522 525 if (hasShutdown() == false) 526 { 527 logger.debug("[SMB] Win32 NetBIOS Server error : " + ex.toString()); 528 logger.debug(ex); 529 } 530 } 531 532 534 if (logger.isDebugEnabled() && hasDebug()) 535 logger.debug("[SMB] Win32 NetBIOS session handler closed"); 536 } 537 538 543 private final void runNetBIOS() 544 throws Exception 545 { 546 548 if (logger.isDebugEnabled() && hasDebug()) 549 logger.debug("[SMB] Waiting for Win32 NetBIOS session request (Netbios API) ..."); 550 551 553 byte[] callerNameBuf = new byte[NetBIOS.NCBNameSize]; 554 String callerName = null; 555 556 callerNameBuf[0] = '\0'; 557 callerName = null; 558 559 561 int lsn = Win32NetBIOS.Listen(m_lana, m_nbName.getNetBIOSName(), m_acceptClient, callerNameBuf); 562 563 565 if ( hasShutdown()) 566 return; 567 568 570 if (callerNameBuf[0] != '\0') 571 callerName = new String (callerNameBuf).trim(); 572 else 573 callerName = ""; 574 575 577 if (lsn >= 0) 578 { 579 580 582 try 583 { 584 585 587 if (logger.isDebugEnabled() && hasDebug()) 588 logger.debug("[SMB] Win32 NetBIOS session request received, lsn=" + lsn + ", caller=[" 589 + callerName + "]"); 590 591 593 PacketHandler pktHandler = new Win32NetBIOSPacketHandler(m_lana, lsn, callerName); 594 595 597 SMBSrvSession srvSess = new SMBSrvSession(pktHandler, getServer()); 598 srvSess.setSessionId(getNextSessionId()); 599 srvSess.setUniqueId(pktHandler.getShortName() + srvSess.getSessionId()); 600 srvSess.setDebugPrefix("[" + pktHandler.getShortName() + srvSess.getSessionId() + "] "); 601 602 604 getServer().addSession(srvSess); 605 606 608 Thread srvThread = new Thread (srvSess); 609 srvThread.setDaemon(true); 610 srvThread.setName("Sess_W" + srvSess.getSessionId() + "_LSN" + lsn); 611 srvThread.start(); 612 } 613 catch (Exception ex) 614 { 615 616 618 if (logger.isDebugEnabled() && hasDebug()) 619 logger.debug("[SMB] Win32 NetBIOS Failed to create session, " + ex.toString()); 620 } 621 } 622 else 623 { 624 625 628 int sts = -lsn; 629 630 if (sts == NetBIOS.NRC_Bridge) 631 { 632 633 635 m_lanaValid = false; 636 637 639 if (logger.isDebugEnabled() && hasDebug()) 640 logger.debug("[SMB] Win32 NetBIOS LANA offline/disabled, LANA=" + getLANANumber()); 641 } 642 else if (logger.isDebugEnabled() && hasDebug()) 643 logger.debug("[SMB] Win32 NetBIOS Listen error, 0x" + Integer.toHexString(-lsn) + ", " 644 + NetBIOS.getErrorString(-lsn)); 645 } 646 } 647 648 653 private final void runWinsock() 654 throws Exception 655 { 656 658 if (logger.isDebugEnabled() && hasDebug()) 659 logger.debug("[SMB] Waiting for Win32 NetBIOS session request (Winsock) ..."); 660 661 663 NetBIOSSocket sessSock = null; 664 665 try 666 { 667 669 sessSock = m_nbSocket.listen(); 670 } 671 catch ( WinsockNetBIOSException ex) 672 { 673 675 if ( ex.getErrorCode() == WinsockError.WsaENetDown) 676 { 677 679 if ( isLANAOnline(m_lana) == false) 680 { 681 684 if ( m_nbSocket != null) 685 { 686 m_nbSocket.closeSocket(); 687 m_nbSocket = null; 688 } 689 690 if ( m_wksSocket != null) 691 { 692 m_wksSocket.closeSocket(); 693 m_wksSocket = null; 694 } 695 696 698 m_lanaValid = false; 699 700 702 if (logger.isDebugEnabled() && hasDebug()) 703 logger.debug("[SMB] Winsock NetBIOS network down, LANA=" + m_lana); 704 } 705 } 706 else 707 { 708 710 if (hasShutdown() == false && logger.isDebugEnabled() && hasDebug()) 711 logger.debug("[SMB] Winsock NetBIOS listen error, " + ex.getMessage()); 712 } 713 } 714 715 717 if ( hasShutdown()) 718 return; 719 720 722 if (sessSock != null) 723 { 724 725 727 try 728 { 729 730 732 if (logger.isDebugEnabled() && hasDebug()) 733 logger.debug("[SMB] Winsock NetBIOS session request received, caller=" 734 + sessSock.getName()); 735 736 738 PacketHandler pktHandler = new WinsockNetBIOSPacketHandler(m_lana, sessSock); 739 740 742 SMBSrvSession srvSess = new SMBSrvSession(pktHandler, getServer()); 743 srvSess.setSessionId(getNextSessionId()); 744 srvSess.setUniqueId(pktHandler.getShortName() + srvSess.getSessionId()); 745 srvSess.setDebugPrefix("[" + pktHandler.getShortName() + srvSess.getSessionId() + "] "); 746 747 749 getServer().addSession(srvSess); 750 751 753 Thread srvThread = new Thread (srvSess); 754 srvThread.setDaemon(true); 755 srvThread.setName("Sess_WS" + srvSess.getSessionId()); 756 srvThread.start(); 757 } 758 catch (Exception ex) 759 { 760 761 763 if (logger.isDebugEnabled() && hasDebug()) 764 logger.debug("[SMB] Winsock NetBIOS Failed to create session, " + ex.toString()); 765 } 766 } 767 } 768 769 775 public final static void createSessionHandlers(SMBServer server, boolean sockDbg) 776 { 777 778 780 ServerConfiguration config = server.getConfiguration(); 781 782 784 if (logger.isDebugEnabled() && sockDbg) 785 { 786 int[] lanas = Win32NetBIOS.LanaEnumerate(); 787 788 StringBuilder lanaStr = new StringBuilder (); 789 if (lanas != null && lanas.length > 0) 790 { 791 for (int i = 0; i < lanas.length; i++) 792 { 793 lanaStr.append(Integer.toString(lanas[i])); 794 lanaStr.append(" "); 795 } 796 } 797 logger.debug("[SMB] Win32 NetBIOS Available LANAs: " + lanaStr.toString()); 798 } 799 800 803 Win32NetBIOSSessionSocketHandler sessHandler = null; 804 List <Win32NetBIOSSessionSocketHandler> lanaListeners = new ArrayList <Win32NetBIOSSessionSocketHandler>(); 805 806 if (config.getWin32LANA() != -1) 807 { 808 809 811 sessHandler = new Win32NetBIOSSessionSocketHandler(server, config.getWin32LANA(), sockDbg); 812 813 try 814 { 815 sessHandler.initialize(); 816 } 817 catch (Exception ex) 818 { 819 820 822 if (logger.isDebugEnabled() && sockDbg) 823 { 824 logger.debug("[SMB] Win32 NetBIOS failed to create session handler for LANA " 825 + config.getWin32LANA()); 826 logger.debug(" " + ex.getMessage()); 827 } 828 } 829 830 832 server.addSessionHandler(sessHandler); 833 834 836 Thread nbThread = new Thread (sessHandler); 837 nbThread.setName("Win32NB_Handler_" + config.getWin32LANA()); 838 nbThread.start(); 839 840 842 if (logger.isDebugEnabled() && sockDbg) 843 logger.debug("[SMB] Win32 NetBIOS created session handler on LANA " + config.getWin32LANA()); 844 845 847 if (config.hasWin32EnableAnnouncer()) 848 { 849 850 852 HostAnnouncer hostAnnouncer = null; 853 854 String domain = config.getDomainName(); 855 int intvl = config.getWin32HostAnnounceInterval(); 856 857 if ( config.useWinsockNetBIOS()) 858 { 859 861 hostAnnouncer = new WinsockNetBIOSHostAnnouncer(sessHandler, domain, intvl); 862 } 863 else 864 { 865 867 hostAnnouncer = new Win32NetBIOSHostAnnouncer(sessHandler, domain, intvl); 868 } 869 870 872 hostAnnouncer.setDebug(sockDbg); 873 874 876 server.addHostAnnouncer(hostAnnouncer); 877 hostAnnouncer.start(); 878 879 881 if (logger.isDebugEnabled() && sockDbg) 882 logger.debug("[SMB] Win32 NetBIOS host announcer enabled on LANA " + config.getWin32LANA()); 883 } 884 885 887 if ( sessHandler instanceof LanaListener) 888 lanaListeners.add( sessHandler); 889 } 890 else 891 { 892 893 895 int[] lanas = Win32NetBIOS.LanaEnumerate(); 896 897 if (lanas != null && lanas.length > 0) 898 { 899 900 902 for (int i = 0; i < lanas.length; i++) 903 { 904 905 907 int lana = lanas[i]; 908 909 911 sessHandler = new Win32NetBIOSSessionSocketHandler(server, lana, sockDbg); 912 913 try 914 { 915 sessHandler.initialize(); 916 } 917 catch (Exception ex) 918 { 919 920 922 if (logger.isDebugEnabled() && sockDbg) 923 { 924 logger.debug("[SMB] Win32 NetBIOS failed to create session handler for LANA " + lana); 925 logger.debug(" " + ex.getMessage()); 926 } 927 } 928 929 931 server.addSessionHandler(sessHandler); 932 933 935 Thread nbThread = new Thread (sessHandler); 936 nbThread.setName("Win32NB_Handler_" + lana); 937 nbThread.start(); 938 939 941 if (logger.isDebugEnabled() && sockDbg) 942 logger.debug("[SMB] Win32 NetBIOS created session handler on LANA " + lana); 943 944 946 if (config.hasWin32EnableAnnouncer()) 947 { 948 949 951 HostAnnouncer hostAnnouncer = null; 952 953 String domain = config.getDomainName(); 954 int intvl = config.getWin32HostAnnounceInterval(); 955 956 if ( config.useWinsockNetBIOS()) 957 { 958 960 hostAnnouncer = new WinsockNetBIOSHostAnnouncer(sessHandler, domain, intvl); 961 } 962 else 963 { 964 966 hostAnnouncer = new Win32NetBIOSHostAnnouncer(sessHandler, domain, intvl); 967 } 968 969 971 hostAnnouncer.setDebug(sockDbg); 972 973 975 server.addHostAnnouncer(hostAnnouncer); 976 hostAnnouncer.start(); 977 978 980 if (logger.isDebugEnabled() && sockDbg) 981 logger.debug("[SMB] Win32 NetBIOS host announcer enabled on LANA " + lana); 982 } 983 984 986 if ( sessHandler instanceof LanaListener) 987 lanaListeners.add( sessHandler); 988 } 989 } 990 991 993 Win32NetBIOSLanaMonitor lanaMonitor = new Win32NetBIOSLanaMonitor(server, lanas, LANAPollingInterval, sockDbg); 994 995 997 if ( lanaListeners.size() > 0) 998 { 999 for ( Win32NetBIOSSessionSocketHandler handler : lanaListeners) 1000 { 1001 1003 lanaMonitor.addLanaListener( handler.getLANANumber(), handler); 1004 } 1005 } 1006 } 1007 } 1008 1009 1015 private final boolean isLANAOnline(int lana) 1016 { 1017 1019 int[] lanas = Win32NetBIOS.LanaEnumerate(); 1020 1021 if (lanas != null && lanas.length > 0) 1022 { 1023 1025 for (int i = 0; i < lanas.length; i++) 1026 { 1027 if ( lanas[i] == lana) 1028 return true; 1029 } 1030 } 1031 1032 1034 return false; 1035 } 1036 1037 1043 public void lanaStatusChange(int lana, boolean online) 1044 { 1045 1048 if ( online == false) 1049 { 1050 1052 m_lanaValid = false; 1053 1054 1056 if ( m_nbSocket != null) 1057 { 1058 m_nbSocket.closeSocket(); 1059 m_nbSocket = null; 1060 } 1061 1062 if ( m_wksSocket != null) 1063 { 1064 m_wksSocket.closeSocket(); 1065 m_wksSocket = null; 1066 } 1067 } 1068 } 1069} 1070 | Popular Tags |