KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > alfresco > filesys > smb > server > win32 > Win32NetBIOSSessionSocketHandler


1 /*
2  * Copyright (C) 2005 Alfresco, Inc.
3  *
4  * Licensed under the Mozilla Public License version 1.1
5  * with a permitted attribution clause. You may obtain a
6  * copy of the License at
7  *
8  * http://www.alfresco.org/legal/license.txt
9  *
10  * Unless required by applicable law or agreed to in writing,
11  * software distributed under the License is distributed on an
12  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13  * either express or implied. See the License for the specific
14  * language governing permissions and limitations under the
15  * License.
16  */

17 package org.alfresco.filesys.smb.server.win32;
18
19 import java.util.ArrayList JavaDoc;
20 import java.util.List JavaDoc;
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 /**
40  * Win32 NetBIOS Session Socket Handler Class
41  *
42  * <p>Uses the Win32 Netbios() call to provide the low level session layer for better integration with
43  * Windows.
44  *
45  * @author GKSpencer
46  */

47 public class Win32NetBIOSSessionSocketHandler extends SessionSocketHandler implements LanaListener
48 {
49
50     // Debug logging
51

52     private static final Log logger = LogFactory.getLog("org.alfresco.smb.protocol");
53
54     // Constants
55
//
56
// Default LANA offline polling interval
57

58     public static final long LANAPollingInterval = 5000; // 5 seconds
59

60     // File server name
61

62     private String JavaDoc m_srvName;
63
64     // Accept connections from any clients or the named client only
65

66     private byte[] m_acceptClient;
67
68     // Local NetBIOS name to listen for sessions on and assigned name number
69

70     private NetBIOSName m_nbName;
71     private int m_nameNum;
72
73     // Workstation NetBIOS name and assigned name number
74

75     private NetBIOSName m_wksNbName;
76     private int m_wksNameNum;
77
78     // NetBIOS LAN adapter to use
79

80     private int m_lana = -1;
81
82     // Flag to indicate if the LANA is valid or the network adapter is currently
83
// unplugged/offline/disabled
84

85     private boolean m_lanaValid;
86
87     // Polling interval in milliseconds to check if the configured LANA is back online
88

89     private long m_lanaPoll;
90     
91     // Flag to indicate if we are using Win32 Netbios() or Winsock calls
92

93     private boolean m_useWinsock;
94     
95     // Winsock Netbios socket to listen for incoming connections
96

97     private NetBIOSSocket m_nbSocket;
98     
99     // Dummy socket used to register the workstation name that some clients search for, although they connect
100
// to the file server service
101

102     private NetBIOSSocket m_wksSocket;
103
104     /**
105      * Class constructor
106      *
107      * @param srv SMBServer
108      * @param debug boolean
109      */

110     public Win32NetBIOSSessionSocketHandler(SMBServer srv, boolean debug)
111     {
112         super("Win32 NetBIOS", srv, debug);
113
114         // Get the Win32 NetBIOS file server name
115

116         if (srv.getConfiguration().getWin32ServerName() != null)
117             m_srvName = srv.getConfiguration().getWin32ServerName();
118         else
119             m_srvName = srv.getConfiguration().getServerName();
120
121         // Get the accepted client string, defaults to '*' to accept any client connection
122

123         NetBIOSName accName = new NetBIOSName("*", NetBIOSName.WorkStation, false);
124         m_acceptClient = accName.getNetBIOSName();
125
126         // Set the LANA to use, or -1 to use the first available
127

128         m_lana = srv.getConfiguration().getWin32LANA();
129
130         // Set the Win32 NetBIOS code to use either the Netbios() API call or Winsock NetBIOS calls
131

132         m_useWinsock = srv.getConfiguration().useWinsockNetBIOS();
133         
134         // Debug
135

136         if (logger.isDebugEnabled() && hasDebug())
137             logger.debug("[SMB] Win32 NetBIOS server " + m_srvName + " (using " +
138                     (isUsingWinsock() ? "Winsock" : "Netbios() API") + ")");
139
140         // Set the LANA offline polling interval
141

142         m_lanaPoll = LANAPollingInterval;
143     }
144
145     /**
146      * Class constructor
147      *
148      * @param srv SMBServer
149      * @param lana int
150      * @param debug boolean
151      */

152     public Win32NetBIOSSessionSocketHandler(SMBServer srv, int lana, boolean debug)
153     {
154         super("Win32 NetBIOS", srv, debug);
155
156         // Get the Win32 NetBIOS file server name
157

158         if (srv.getConfiguration().getWin32ServerName() != null)
159             m_srvName = srv.getConfiguration().getWin32ServerName();
160         else
161             m_srvName = srv.getConfiguration().getServerName();
162
163         // Get the accepted client string, defaults to '*' to accept any client connection
164

165         NetBIOSName accName = new NetBIOSName("*", NetBIOSName.WorkStation, false);
166         m_acceptClient = accName.getNetBIOSName();
167
168         // Set the LANA to use, or -1 to use the first available
169

170         m_lana = lana;
171
172         // Set the Win32 NetBIOS code to use either the Netbios() API call or Winsock NetBIOS calls
173

174         m_useWinsock = srv.getConfiguration().useWinsockNetBIOS();
175         
176         // Debug
177

178         if (logger.isDebugEnabled() && hasDebug())
179             logger.debug("[SMB] Win32 NetBIOS server " + m_srvName + " (using " +
180                     (isUsingWinsock() ? "Winsock" : "Netbios() API") + ")");
181
182         // Set the LANA offline polling interval
183

184         m_lanaPoll = LANAPollingInterval;
185     }
186
187     /**
188      * Class constructor
189      *
190      * @param srv SMBServer
191      * @param nbName String
192      * @param debug boolean
193      */

194     public Win32NetBIOSSessionSocketHandler(SMBServer srv, String JavaDoc nbName, boolean debug)
195     {
196         super("Win32 NetBIOS", srv, debug);
197
198         // Set the Win32 NetBIOS file server name
199

200         m_srvName = nbName;
201
202         // Get the accepted client string, defaults to '*' to accept any client connection
203

204         NetBIOSName accName = new NetBIOSName("*", NetBIOSName.WorkStation, false);
205         m_acceptClient = accName.getNetBIOSName();
206
207         // Set the LANA to use, or -1 to use the first available
208

209         m_lana = srv.getConfiguration().getWin32LANA();
210
211         // Set the Win32 NetBIOS code to use either the Netbios() API call or Winsock NetBIOS calls
212

213         m_useWinsock = srv.getConfiguration().useWinsockNetBIOS();
214         
215         // Debug
216

217         if (logger.isDebugEnabled() && hasDebug())
218             logger.debug("[SMB] Win32 NetBIOS server " + m_srvName + " (using " +
219                     (isUsingWinsock() ? "Winsock" : "Netbios() API") + ")");
220
221         // Set the LANA offline polling interval
222

223         m_lanaPoll = LANAPollingInterval;
224     }
225
226     /**
227      * Return the LANA number that is being used
228      *
229      * @return int
230      */

231     public final int getLANANumber()
232     {
233         return m_lana;
234     }
235
236     /**
237      * Return the LANA offline polling interval to check for the LANA coming back online
238      *
239      * @return long
240      */

241     public final long getLANAOfflinePollingInterval()
242     {
243         return m_lanaPoll;
244     }
245
246     /**
247      * Return the assigned NetBIOS name number
248      *
249      * @return int
250      */

251     public final int getNameNumber()
252     {
253         return m_nameNum;
254     }
255
256     /**
257      * Return the local server name
258      *
259      * @return String
260      */

261     public final String JavaDoc getServerName()
262     {
263         return m_srvName;
264     }
265
266     /**
267      * Determine if Netbios() API calls or Winsock calls are being used
268      *
269      * @return boolean
270      */

271     public final boolean isUsingWinsock()
272     {
273         return m_useWinsock;
274     }
275     
276     /**
277      * Initialize the session socket handler.
278      *
279      * @throws Exception
280      */

281     public void initialize() throws Exception JavaDoc
282     {
283
284         // Enumerate the LAN adapters, use the first available if the LANA has not been specified in
285
// the configuration
286

287         int[] lanas = Win32NetBIOS.LanaEnumerate();
288         if (lanas != null && lanas.length > 0)
289         {
290
291             // Check if the LANA has been specified via the configuration, if not then use the first
292
// available
293

294             if (m_lana == -1)
295                 m_lana = lanas[0];
296             else
297             {
298
299                 // Check if the required LANA is available
300

301                 boolean lanaOnline = false;
302                 int idx = 0;
303
304                 while (idx < lanas.length && lanaOnline == false)
305                 {
306
307                     // Check if the LANA is listed
308

309                     if (lanas[idx++] == getLANANumber())
310                         lanaOnline = true;
311                 }
312
313                 // If the LANA is not available the main listener thread will poll the available
314
// LANAs until the required LANA is available
315

316                 if (lanaOnline == false)
317                 {
318
319                     // Indicate that the LANA is not offline/unplugged/disabled
320

321                     m_lanaValid = false;
322                     return;
323                 }
324             }
325         }
326         else
327         {
328
329             // If the LANA has not been set throw an exception as no LANAs are available
330

331             if (m_lana == -1)
332                 throw new Exception JavaDoc("No Win32 NetBIOS LANAs available");
333
334             // The required LANA is offline/unplugged/disabled
335

336             m_lanaValid = false;
337             return;
338         }
339
340         // Create the local NetBIOS name to listen for incoming connections on
341

342         m_nbName = new NetBIOSName(m_srvName, NetBIOSName.FileServer, false);
343         m_wksNbName = new NetBIOSName(m_srvName, NetBIOSName.WorkStation, false);
344
345         // Initialize the Win32 NetBIOS interface, either Winsock or Netbios() API
346

347         if ( isUsingWinsock())
348             initializeWinsockNetBIOS();
349         else
350             initializeNetbiosAPI();
351         
352         // Indicate that the LANA is valid
353

354         m_lanaValid = true;
355     }
356
357     /**
358      * Initialize the Win32 Netbios() API interface, add the server names
359      *
360      * @exception Exception If the NetBIOS add name fails
361      */

362     private final void initializeNetbiosAPI()
363         throws Exception JavaDoc
364     {
365         // Reset the LANA
366

367         Win32NetBIOS.Reset(m_lana);
368
369         // Add the NetBIOS name to the local name table
370

371         m_nameNum = Win32NetBIOS.AddName(m_lana, m_nbName.getNetBIOSName());
372         if (m_nameNum < 0)
373             throw new Exception JavaDoc("Win32 NetBIOS AddName failed (file server), status = 0x"
374                     + Integer.toHexString(-m_nameNum) + ", " + NetBIOS.getErrorString(-m_nameNum));
375
376         // Register a NetBIOS name for the server name with the workstation name type, some clients
377
// use this name to find the server
378

379         m_wksNameNum = Win32NetBIOS.AddName(m_lana, m_wksNbName.getNetBIOSName());
380         if (m_wksNameNum < 0)
381             throw new Exception JavaDoc("Win32 NetBIOS AddName failed (workstation), status = 0x"
382                     + Integer.toHexString(-m_wksNameNum) + ", " + NetBIOS.getErrorString(-m_wksNameNum));
383     }
384
385     /**
386      * Initialize the Winsock NetBIOS interface
387      *
388      * @exception Exception If a Winsock error occurs
389      */

390     private final void initializeWinsockNetBIOS()
391         throws Exception JavaDoc
392     {
393         // Create the NetBIOS listener socket, this will add the file server name
394

395         m_nbSocket = NetBIOSSocket.createListenerSocket( getLANANumber(), m_nbName);
396         
397         // Create a NetBIOS socket using the workstation name, some clients search for this name
398

399         m_wksSocket = NetBIOSSocket.createListenerSocket( getLANANumber(), m_wksNbName);
400     }
401     
402     /**
403      * Check if the LANA is valid and accepting incoming sessions or the associated network adapter
404      * is unplugged/disabled/offline.
405      *
406      * @return boolean
407      */

408     public final boolean isLANAValid()
409     {
410         return m_lanaValid;
411     }
412
413     /**
414      * Shutdown the Win32 NetBIOS interface
415      */

416     public void shutdownRequest()
417     {
418         super.shutdownRequest();
419         
420         // Reset the LANA, if valid, to wake the main session listener thread
421

422         if ( isLANAValid())
423             Win32NetBIOS.Reset(m_lana);
424         
425         // If Winsock calls are being used close the sockets
426

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     /**
444      * Run the NetBIOS session socket handler
445      */

446     public void run()
447     {
448
449         try
450         {
451
452             // Clear the shutdown flag
453

454             clearShutdown();
455
456             // Wait for incoming connection requests
457

458             while (hasShutdown() == false)
459             {
460
461                 // Check if the LANA is valid and ready to accept incoming sessions
462

463                 if (isLANAValid())
464                 {
465                     // Wait for an incoming session request
466

467                     if ( isUsingWinsock())
468                     {
469                         // Wait for an incoming session request using the Winsock NetBIOS interface
470

471                         runWinsock();
472                     }
473                     else
474                     {
475                         // Wait for an incoming session request using the Win32 Netbios() API interface
476

477                         runNetBIOS();
478                     }
479                 }
480                 else
481                 {
482
483                     // Sleep for a short while ...
484

485                     try
486                     {
487                         Thread.sleep(getLANAOfflinePollingInterval());
488                     }
489                     catch (Exception JavaDoc ex)
490                     {
491                     }
492
493                     // Check if the network adapter/LANA is back online, if so then re-initialize
494
// the LANA to start accepting sessions again
495

496                     try
497                     {
498                         initialize();
499                     }
500                     catch (Exception JavaDoc ex)
501                     {
502
503                         // DEBUG
504

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                     // DEBUG
513

514                     if (logger.isDebugEnabled() && hasDebug() && isLANAValid())
515                         logger.debug("[SMB] Win32 NetBIOS LANA " + getLANANumber() + " Back Online");
516                 }
517             }
518         }
519         catch (Exception JavaDoc ex)
520         {
521
522             // Do not report an error if the server has shutdown, closing the server socket
523
// causes an exception to be thrown.
524

525             if (hasShutdown() == false)
526             {
527                 logger.debug("[SMB] Win32 NetBIOS Server error : " + ex.toString());
528                 logger.debug(ex);
529             }
530         }
531
532         // Debug
533

534         if (logger.isDebugEnabled() && hasDebug())
535             logger.debug("[SMB] Win32 NetBIOS session handler closed");
536     }
537
538     /**
539      * Run the Win32 Netbios() API listen code
540      *
541      * @exception Exception If an unhandled error occurs
542      */

543     private final void runNetBIOS()
544         throws Exception JavaDoc
545     {
546         // Debug
547

548         if (logger.isDebugEnabled() && hasDebug())
549             logger.debug("[SMB] Waiting for Win32 NetBIOS session request (Netbios API) ...");
550
551         // Clear the caller name
552

553         byte[] callerNameBuf = new byte[NetBIOS.NCBNameSize];
554         String JavaDoc callerName = null;
555         
556         callerNameBuf[0] = '\0';
557         callerName = null;
558
559         // Wait for a new NetBIOS session
560

561         int lsn = Win32NetBIOS.Listen(m_lana, m_nbName.getNetBIOSName(), m_acceptClient, callerNameBuf);
562
563         // Check if the session listener has been shutdown
564

565         if ( hasShutdown())
566             return;
567         
568         // Get the caller name, if available
569

570         if (callerNameBuf[0] != '\0')
571             callerName = new String JavaDoc(callerNameBuf).trim();
572         else
573             callerName = "";
574
575         // Create a packet handler and thread for the new session
576

577         if (lsn >= 0)
578         {
579
580             // Create a new session thread
581

582             try
583             {
584
585                 // Debug
586

587                 if (logger.isDebugEnabled() && hasDebug())
588                     logger.debug("[SMB] Win32 NetBIOS session request received, lsn=" + lsn + ", caller=["
589                             + callerName + "]");
590
591                 // Create a packet handler for the session
592

593                 PacketHandler pktHandler = new Win32NetBIOSPacketHandler(m_lana, lsn, callerName);
594
595                 // Create a server session for the new request, and set the session id.
596

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                 // Add the session to the active session list
603

604                 getServer().addSession(srvSess);
605
606                 // Start the new session in a seperate thread
607

608                 Thread JavaDoc srvThread = new Thread JavaDoc(srvSess);
609                 srvThread.setDaemon(true);
610                 srvThread.setName("Sess_W" + srvSess.getSessionId() + "_LSN" + lsn);
611                 srvThread.start();
612             }
613             catch (Exception JavaDoc ex)
614             {
615
616                 // Debug
617

618                 if (logger.isDebugEnabled() && hasDebug())
619                     logger.debug("[SMB] Win32 NetBIOS Failed to create session, " + ex.toString());
620             }
621         }
622         else
623         {
624
625             // Check if the error indicates the network adapter is
626
// unplugged/offline/disabled
627

628             int sts = -lsn;
629
630             if (sts == NetBIOS.NRC_Bridge)
631             {
632
633                 // Indicate that the LANA is no longer valid
634

635                 m_lanaValid = false;
636
637                 // DEBUG
638

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     /**
649      * Run the Winsock NetBIOS listen code
650      *
651      * @exception Exception If an unhandled error occurs
652      */

653     private final void runWinsock()
654         throws Exception JavaDoc
655     {
656         // Debug
657

658         if (logger.isDebugEnabled() && hasDebug())
659             logger.debug("[SMB] Waiting for Win32 NetBIOS session request (Winsock) ...");
660         
661         // Wait for a new NetBIOS session
662

663         NetBIOSSocket sessSock = null;
664         
665         try
666         {
667             // Wait for an incoming session connection
668

669             sessSock = m_nbSocket.listen();
670         }
671         catch ( WinsockNetBIOSException ex)
672         {
673             // Check if the network is down
674

675             if ( ex.getErrorCode() == WinsockError.WsaENetDown)
676             {
677                 // Check if the LANA we are listening on is no longer valid
678

679                 if ( isLANAOnline(m_lana) == false)
680                 {
681                     // Network/LANA is offline, cleanup the current listening sockets and wait for the
682
// LANA to come back online
683

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                     // Indciate that the LANA is no longer valid
697

698                     m_lanaValid = false;
699
700                     // Debug
701

702                     if (logger.isDebugEnabled() && hasDebug())
703                         logger.debug("[SMB] Winsock NetBIOS network down, LANA=" + m_lana);
704                 }
705             }
706             else
707             {
708                 // Debug
709

710                 if (hasShutdown() == false && logger.isDebugEnabled() && hasDebug())
711                     logger.debug("[SMB] Winsock NetBIOS listen error, " + ex.getMessage());
712             }
713         }
714
715         // Check if the session listener has been shutdown
716

717         if ( hasShutdown())
718             return;
719         
720         // Create a packet handler and thread for the new session
721

722         if (sessSock != null)
723         {
724
725             // Create a new session thread
726

727             try
728             {
729
730                 // Debug
731

732                 if (logger.isDebugEnabled() && hasDebug())
733                     logger.debug("[SMB] Winsock NetBIOS session request received, caller="
734                             + sessSock.getName());
735
736                 // Create a packet handler for the session
737

738                 PacketHandler pktHandler = new WinsockNetBIOSPacketHandler(m_lana, sessSock);
739
740                 // Create a server session for the new request, and set the session id.
741

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                 // Add the session to the active session list
748

749                 getServer().addSession(srvSess);
750
751                 // Start the new session in a seperate thread
752

753                 Thread JavaDoc srvThread = new Thread JavaDoc(srvSess);
754                 srvThread.setDaemon(true);
755                 srvThread.setName("Sess_WS" + srvSess.getSessionId());
756                 srvThread.start();
757             }
758             catch (Exception JavaDoc ex)
759             {
760
761                 // Debug
762

763                 if (logger.isDebugEnabled() && hasDebug())
764                     logger.debug("[SMB] Winsock NetBIOS Failed to create session, " + ex.toString());
765             }
766         }
767     }
768     
769     /**
770      * Create the Win32 NetBIOS session socket handlers for the main SMB/CIFS server
771      *
772      * @param server SMBServer
773      * @param sockDbg boolean
774      */

775     public final static void createSessionHandlers(SMBServer server, boolean sockDbg)
776     {
777
778         // Access the server configuration
779

780         ServerConfiguration config = server.getConfiguration();
781
782         // DEBUG
783

784         if (logger.isDebugEnabled() && sockDbg)
785         {
786             int[] lanas = Win32NetBIOS.LanaEnumerate();
787
788             StringBuilder JavaDoc lanaStr = new StringBuilder JavaDoc();
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         // Check if the Win32 NetBIOS session handler should use a particular LANA/network adapter
801
// or should use all available LANAs/network adapters (that have NetBIOS enabled).
802

803         Win32NetBIOSSessionSocketHandler sessHandler = null;
804         List JavaDoc<Win32NetBIOSSessionSocketHandler> lanaListeners = new ArrayList JavaDoc<Win32NetBIOSSessionSocketHandler>();
805         
806         if (config.getWin32LANA() != -1)
807         {
808
809             // Create a single Win32 NetBIOS session handler using the specified LANA
810

811             sessHandler = new Win32NetBIOSSessionSocketHandler(server, config.getWin32LANA(), sockDbg);
812
813             try
814             {
815                 sessHandler.initialize();
816             }
817             catch (Exception JavaDoc ex)
818             {
819
820                 // DEBUG
821

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             // Add the session handler to the SMB/CIFS server
831

832             server.addSessionHandler(sessHandler);
833
834             // Run the NetBIOS session handler in a seperate thread
835

836             Thread JavaDoc nbThread = new Thread JavaDoc(sessHandler);
837             nbThread.setName("Win32NB_Handler_" + config.getWin32LANA());
838             nbThread.start();
839
840             // DEBUG
841

842             if (logger.isDebugEnabled() && sockDbg)
843                 logger.debug("[SMB] Win32 NetBIOS created session handler on LANA " + config.getWin32LANA());
844
845             // Check if a host announcer should be enabled
846

847             if (config.hasWin32EnableAnnouncer())
848             {
849
850                 // Create a host announcer
851

852                 HostAnnouncer hostAnnouncer = null;
853
854                 String JavaDoc domain = config.getDomainName();
855                 int intvl = config.getWin32HostAnnounceInterval();
856                 
857                 if ( config.useWinsockNetBIOS())
858                 {
859                     // Create a Winsock NetBIOS announcer
860

861                     hostAnnouncer = new WinsockNetBIOSHostAnnouncer(sessHandler, domain, intvl);
862                 }
863                 else
864                 {
865                     // Create a Win32 Netbios() API announcer
866

867                     hostAnnouncer = new Win32NetBIOSHostAnnouncer(sessHandler, domain, intvl);
868                 }
869                 
870                 // Enable announcer debug
871

872                 hostAnnouncer.setDebug(sockDbg);
873
874                 // Add the host announcer to the SMB/CIFS server list
875

876                 server.addHostAnnouncer(hostAnnouncer);
877                 hostAnnouncer.start();
878
879                 // DEBUG
880

881                 if (logger.isDebugEnabled() && sockDbg)
882                     logger.debug("[SMB] Win32 NetBIOS host announcer enabled on LANA " + config.getWin32LANA());
883             }
884             
885             // Check if the session handler implements the LANA listener interface
886

887             if ( sessHandler instanceof LanaListener)
888                 lanaListeners.add( sessHandler);
889         }
890         else
891         {
892
893             // Get a list of the available LANAs
894

895             int[] lanas = Win32NetBIOS.LanaEnumerate();
896
897             if (lanas != null && lanas.length > 0)
898             {
899
900                 // Create a session handler for each available LANA
901

902                 for (int i = 0; i < lanas.length; i++)
903                 {
904
905                     // Get the current LANA
906

907                     int lana = lanas[i];
908
909                     // Create a session handler
910

911                     sessHandler = new Win32NetBIOSSessionSocketHandler(server, lana, sockDbg);
912
913                     try
914                     {
915                         sessHandler.initialize();
916                     }
917                     catch (Exception JavaDoc ex)
918                     {
919
920                         // DEBUG
921

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                     // Add the session handler to the SMB/CIFS server
930

931                     server.addSessionHandler(sessHandler);
932
933                     // Run the NetBIOS session handler in a seperate thread
934

935                     Thread JavaDoc nbThread = new Thread JavaDoc(sessHandler);
936                     nbThread.setName("Win32NB_Handler_" + lana);
937                     nbThread.start();
938
939                     // DEBUG
940

941                     if (logger.isDebugEnabled() && sockDbg)
942                         logger.debug("[SMB] Win32 NetBIOS created session handler on LANA " + lana);
943
944                     // Check if a host announcer should be enabled
945

946                     if (config.hasWin32EnableAnnouncer())
947                     {
948
949                         // Create a host announcer
950

951                         HostAnnouncer hostAnnouncer = null;
952
953                         String JavaDoc domain = config.getDomainName();
954                         int intvl = config.getWin32HostAnnounceInterval();
955                         
956                         if ( config.useWinsockNetBIOS())
957                         {
958                             // Create a Winsock NetBIOS announcer
959

960                             hostAnnouncer = new WinsockNetBIOSHostAnnouncer(sessHandler, domain, intvl);
961                         }
962                         else
963                         {
964                             // Create a Win32 Netbios() API announcer
965

966                             hostAnnouncer = new Win32NetBIOSHostAnnouncer(sessHandler, domain, intvl);
967                         }
968                         
969                         // Enable announcer debug
970

971                         hostAnnouncer.setDebug(sockDbg);
972
973                         // Add the host announcer to the SMB/CIFS server list
974

975                         server.addHostAnnouncer(hostAnnouncer);
976                         hostAnnouncer.start();
977
978                         // DEBUG
979

980                         if (logger.isDebugEnabled() && sockDbg)
981                             logger.debug("[SMB] Win32 NetBIOS host announcer enabled on LANA " + lana);
982                     }
983
984                     // Check if the session handler implements the LANA listener interface
985

986                     if ( sessHandler instanceof LanaListener)
987                         lanaListeners.add( sessHandler);
988                 }
989             }
990
991             // Create a LANA monitor to check for new LANAs becoming available
992

993             Win32NetBIOSLanaMonitor lanaMonitor = new Win32NetBIOSLanaMonitor(server, lanas, LANAPollingInterval, sockDbg);
994             
995             // Register any session handlers that are LANA listeners
996

997             if ( lanaListeners.size() > 0)
998             {
999                 for ( Win32NetBIOSSessionSocketHandler handler : lanaListeners)
1000                {
1001                    // Register the LANA listener
1002

1003                    lanaMonitor.addLanaListener( handler.getLANANumber(), handler);
1004                }
1005            }
1006        }
1007    }
1008    
1009    /**
1010     * Check if the specified LANA is online
1011     *
1012     * @param lana int
1013     * @return boolean
1014     */

1015    private final boolean isLANAOnline(int lana)
1016    {
1017        // Get a list of the available LANAs
1018

1019        int[] lanas = Win32NetBIOS.LanaEnumerate();
1020
1021        if (lanas != null && lanas.length > 0)
1022        {
1023            // Check if the specified LANA is available
1024

1025            for (int i = 0; i < lanas.length; i++)
1026            {
1027                if ( lanas[i] == lana)
1028                    return true;
1029            }
1030        }
1031        
1032        // LANA not online
1033

1034        return false;
1035    }
1036
1037    /**
1038     * LANA listener status change callback
1039     *
1040     * @param lana int
1041     * @param online boolean
1042     */

1043    public void lanaStatusChange(int lana, boolean online)
1044    {
1045        // If the LANA has gone offline, close the listening socket and wait for the LANA to
1046
// come back online
1047

1048        if ( online == false)
1049        {
1050            // Indicate that the LANA is offline
1051

1052            m_lanaValid = false;
1053            
1054            // Close the listening sockets
1055

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