KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > freecs > core > Listener


1 /**
2  * Copyright (C) 2003 Manfred Andres
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17  *
18  * Created on 18.10.2003
19  */

20
21 package freecs.core;
22
23 import java.io.IOException JavaDoc;
24 import java.net.InetAddress JavaDoc;
25 import java.net.InetSocketAddress JavaDoc;
26 import java.net.NetworkInterface JavaDoc;
27 import java.net.ServerSocket JavaDoc;
28 import java.nio.channels.CancelledKeyException JavaDoc;
29 import java.nio.channels.SelectionKey JavaDoc;
30 import java.nio.channels.Selector JavaDoc;
31 import java.nio.channels.ServerSocketChannel JavaDoc;
32 import java.nio.channels.SocketChannel JavaDoc;
33 import java.nio.channels.spi.SelectorProvider JavaDoc;
34 import java.util.Enumeration JavaDoc;
35 import java.util.HashMap JavaDoc;
36 import java.util.Iterator JavaDoc;
37 import java.util.Vector JavaDoc;
38
39 import freecs.Server;
40 import freecs.util.TrafficMonitor;
41 import freecs.util.TrafficMonitor.AddressState;
42
43 /**
44  * @author Manfred Andres
45  *
46  * freecs.core
47  */

48 public class Listener extends Thread JavaDoc {
49     private HashMap JavaDoc ia2ssc = null;
50     private static final Listener l = new Listener();
51     private Selector JavaDoc sel;
52 // private ServerSocketChannel ssc;
53

54     public Listener() {
55         try {
56             sel = SelectorProvider.provider().openSelector();
57         } catch (Exception JavaDoc e) {
58             Server.debug (this, "Unable to start Listener!", e, Server.MSG_ERROR, Server.LVL_HALT);
59         }
60     }
61     
62     public static void updateSscRecieveBuffer(int rbw) {
63         if (l.ia2ssc==null)
64             return;
65         for (Iterator JavaDoc i = l.ia2ssc.values().iterator(); i.hasNext(); ) {
66             try {
67                 ServerSocketChannel JavaDoc ssc = (ServerSocketChannel JavaDoc) i.next();
68                 if (ssc.socket().getReceiveBufferSize() == rbw)
69                     continue;
70                 ssc.socket().setReceiveBufferSize(rbw);
71             } catch (IOException JavaDoc ioe) {
72                 Server.debug("static Listener", "updateSscRecieveBuffer: exception during updating recievebuffer-window",ioe, Server.MSG_ERROR, Server.LVL_MAJOR);
73             }
74         }
75     }
76     
77     public static void startListener() throws IOException JavaDoc {
78         if (l.ia2ssc==null)
79             l.initSSC ();
80         if (!l.isAlive()) {
81             l.setName("Listener");
82             // l.setPriority(MAX_PRIORITY-3);
83
l.start();
84         }
85     }
86
87     private void bindSSC (InetAddress JavaDoc ia) throws IOException JavaDoc {
88         if (ia2ssc.get(ia)!=null)
89             return;
90         ServerSocketChannel JavaDoc ssc = ServerSocketChannel.open();
91         ServerSocket JavaDoc ssoc = ssc.socket();
92         ssoc.setReceiveBufferSize(Server.srv.TCP_RECEIVE_BUFFER_WINDOW);
93         ssoc.setReuseAddress(true);
94         ssc.configureBlocking(false);
95         ssc.socket().bind(new InetSocketAddress JavaDoc (ia, Integer.parseInt(Server.srv.getProperty("port"))));
96         if (Server.srv.allowedLoginHosts == null)
97             Server.srv.allowedLoginHosts = new Vector JavaDoc();
98         Server.srv.allowedLoginHosts.addElement (ia);
99         ssc.register(sel, SelectionKey.OP_ACCEPT);
100         ia2ssc.put(ia, ssc);
101     }
102     
103     private void reinitSSC () throws IOException JavaDoc {
104         if (ia2ssc != null) {
105             for (Iterator JavaDoc i = ia2ssc.values().iterator(); i.hasNext(); ) {
106                 ServerSocketChannel JavaDoc ssc = (ServerSocketChannel JavaDoc) i.next();
107                 ssc.close();
108             }
109         }
110         initSSC();
111     }
112
113     private void initSSC () {
114         if (ia2ssc == null)
115             ia2ssc = new HashMap JavaDoc();
116         try {
117             if (Server.srv.getProperty("bindIp")!=null) {
118                 String JavaDoc addresses[] = Server.srv.getProperty("bindIp").split(",");
119                 for (int i = 0; i < addresses.length; i++) {
120                     bindSSC(InetAddress.getByName(addresses[i]));
121                 }
122             } else {
123                 for (Enumeration JavaDoc e = NetworkInterface.getNetworkInterfaces(); e.hasMoreElements(); ) {
124                     NetworkInterface JavaDoc ni = (NetworkInterface JavaDoc) e.nextElement();
125                     for (Enumeration JavaDoc ee = ni.getInetAddresses(); ee.hasMoreElements(); )
126                         bindSSC((InetAddress JavaDoc) ee.nextElement());
127                 }
128             }
129         } catch (IOException JavaDoc ioe) {
130             Server.debug(this, "initSSC: exception during obtaining ip-adresses", ioe, Server.MSG_ERROR, Server.LVL_HALT);
131         }
132     }
133     
134     public void run () {
135         long lastMessage = 0;
136         while (Server.srv.isRunning()) {
137             try {
138                 if (Server.DEBUG || lastMessage + 5000 > System.currentTimeMillis()) {
139                     Server.log ("[Listener]", "loopstart", Server.MSG_STATE, Server.LVL_VERY_VERBOSE);
140                     lastMessage = System.currentTimeMillis();
141                 }
142                 while (sel.selectNow() < 1) try {
143                     Thread.sleep(100);
144                 } catch (InterruptedException JavaDoc ie) { }
145             } catch (IOException JavaDoc ioe) {
146                 Server.debug (this, "run: ", ioe, Server.MSG_ERROR, Server.LVL_MAJOR);
147                 try {
148                     reinitSSC();
149                 } catch (IOException JavaDoc iioe) {
150                     Server.debug (this, "MAJOR ERROR ON REOPENING LISTENER!", iioe, Server.MSG_ERROR, Server.LVL_MAJOR);
151                     break;
152                 }
153             } catch (Exception JavaDoc e) {
154                 Server.debug (this, "run: ", e, Server.MSG_ERROR, Server.LVL_MAJOR);
155             }
156             for (Iterator JavaDoc i = sel.selectedKeys().iterator(); i.hasNext(); ) try {
157                 SelectionKey JavaDoc ck = (SelectionKey JavaDoc) i.next();
158                 i.remove();
159                 if (ck.isAcceptable()) {
160                     accept(ck);
161                 } else {
162                     Server.log (this, ".run: SelectionKey doesn't have Accept in its interestOps! " + ck.toString(), Server.MSG_STATE, Server.LVL_MAJOR);
163                 }
164             } catch (CancelledKeyException JavaDoc cke) { }
165             try {
166                 Thread.sleep(33);
167             } catch (InterruptedException JavaDoc ie) {}
168         }
169         for (Iterator JavaDoc i = sel.keys().iterator(); i.hasNext(); ) {
170             SelectionKey JavaDoc ck = (SelectionKey JavaDoc) i.next();
171             try {
172                 ck.channel().close();
173                 ck.cancel();
174                 i.remove();
175             } catch (Exception JavaDoc e) {
176                 Server.debug (this, "final cleanup: ", e, Server.MSG_ERROR, Server.LVL_MAJOR);
177             }
178         }
179     }
180
181     private void accept (SelectionKey JavaDoc sk) {
182         if (sk == null) return;
183         ServerSocketChannel JavaDoc ssc = (ServerSocketChannel JavaDoc) sk.channel();
184         SocketChannel JavaDoc sc;
185         try {
186             sc = ssc.accept();
187             if (sc == null)
188                 return;
189             InetAddress JavaDoc ia = sc.socket ().getInetAddress ();
190            // check if this host is banned for the listener
191
// FIXME: This is considered ALPHA:
192
// the traffic-monitor does the banning, this is untested
193
if (Server.srv.USE_TRAFFIC_MONITOR) {
194                if (Server.srv.isBanned (ia) && !Server.srv.isAdminHost(ia)){
195                    sc.close();
196                    return;
197                }
198             
199                AddressState as = TrafficMonitor.tm.mayPass (ia);
200                if (as!=null) {
201                    sc.close();
202                    StringBuffer JavaDoc tsb = new StringBuffer JavaDoc ("TrafficMonitor is refusing connection to banned host: ");
203                    tsb.append (ia.getHostAddress());
204                    tsb.append ("(");
205                    tsb.append (ia.getHostName());
206                    tsb.append (")");
207                    Server.log (this, tsb.toString (), Server.MSG_TRAFFIC, Server.LVL_MAJOR);
208                    tsb = new StringBuffer JavaDoc("reached ");
209                    tsb.append (as.reqCount);
210                    tsb.append (" connects within ");
211                    tsb.append (as.diff);
212                    tsb.append (" millis");
213                    Server.srv.banHost (ia, System.currentTimeMillis() + Server.srv.HOST_BAN_DURATION, tsb.toString());
214                    return;
215                }
216             }
217             CentralSelector.cSel.registerSC (sc, Server.REQUEST_TYPE_HTTP);
218         } catch (Exception JavaDoc e) {
219             Server.debug (this, "accept: Exception encountered during accept: ", e, Server.MSG_ERROR, Server.LVL_MAJOR);
220         }
221     }
222
223     public String JavaDoc toString() { return "[Listener]"; }
224 }
225
Popular Tags