Home | History | Annotate | Download | only in socks5
      1 /**
      2  * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
      3  * you may not use this file except in compliance with the License.
      4  * You may obtain a copy of the License at
      5  *
      6  *     http://www.apache.org/licenses/LICENSE-2.0
      7  *
      8  * Unless required by applicable law or agreed to in writing, software
      9  * distributed under the License is distributed on an "AS IS" BASIS,
     10  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     11  * See the License for the specific language governing permissions and
     12  * limitations under the License.
     13  */
     14 package org.jivesoftware.smackx.bytestreams.socks5;
     15 
     16 import java.util.concurrent.ExecutorService;
     17 import java.util.concurrent.Executors;
     18 
     19 import org.jivesoftware.smack.PacketListener;
     20 import org.jivesoftware.smack.filter.AndFilter;
     21 import org.jivesoftware.smack.filter.IQTypeFilter;
     22 import org.jivesoftware.smack.filter.PacketFilter;
     23 import org.jivesoftware.smack.filter.PacketTypeFilter;
     24 import org.jivesoftware.smack.packet.IQ;
     25 import org.jivesoftware.smack.packet.Packet;
     26 import org.jivesoftware.smackx.bytestreams.BytestreamListener;
     27 import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream;
     28 
     29 /**
     30  * InitiationListener handles all incoming SOCKS5 Bytestream initiation requests. If there are no
     31  * listeners for a SOCKS5 bytestream request InitiationListener will always refuse the request and
     32  * reply with a &lt;not-acceptable/&gt; error (<a
     33  * href="http://xmpp.org/extensions/xep-0065.html#usecase-alternate">XEP-0065</a> Section 5.2.A2).
     34  *
     35  * @author Henning Staib
     36  */
     37 final class InitiationListener implements PacketListener {
     38 
     39     /* manager containing the listeners and the XMPP connection */
     40     private final Socks5BytestreamManager manager;
     41 
     42     /* packet filter for all SOCKS5 Bytestream requests */
     43     private final PacketFilter initFilter = new AndFilter(new PacketTypeFilter(Bytestream.class),
     44                     new IQTypeFilter(IQ.Type.SET));
     45 
     46     /* executor service to process incoming requests concurrently */
     47     private final ExecutorService initiationListenerExecutor;
     48 
     49     /**
     50      * Constructor
     51      *
     52      * @param manager the SOCKS5 Bytestream manager
     53      */
     54     protected InitiationListener(Socks5BytestreamManager manager) {
     55         this.manager = manager;
     56         initiationListenerExecutor = Executors.newCachedThreadPool();
     57     }
     58 
     59     public void processPacket(final Packet packet) {
     60         initiationListenerExecutor.execute(new Runnable() {
     61 
     62             public void run() {
     63                 processRequest(packet);
     64             }
     65         });
     66     }
     67 
     68     private void processRequest(Packet packet) {
     69         Bytestream byteStreamRequest = (Bytestream) packet;
     70 
     71         // ignore request if in ignore list
     72         if (this.manager.getIgnoredBytestreamRequests().remove(byteStreamRequest.getSessionID())) {
     73             return;
     74         }
     75 
     76         // build bytestream request from packet
     77         Socks5BytestreamRequest request = new Socks5BytestreamRequest(this.manager,
     78                         byteStreamRequest);
     79 
     80         // notify listeners for bytestream initiation from a specific user
     81         BytestreamListener userListener = this.manager.getUserListener(byteStreamRequest.getFrom());
     82         if (userListener != null) {
     83             userListener.incomingBytestreamRequest(request);
     84 
     85         }
     86         else if (!this.manager.getAllRequestListeners().isEmpty()) {
     87             /*
     88              * if there is no user specific listener inform listeners for all initiation requests
     89              */
     90             for (BytestreamListener listener : this.manager.getAllRequestListeners()) {
     91                 listener.incomingBytestreamRequest(request);
     92             }
     93 
     94         }
     95         else {
     96             /*
     97              * if there is no listener for this initiation request, reply with reject message
     98              */
     99             this.manager.replyRejectPacket(byteStreamRequest);
    100         }
    101     }
    102 
    103     /**
    104      * Returns the packet filter for SOCKS5 Bytestream initialization requests.
    105      *
    106      * @return the packet filter for SOCKS5 Bytestream initialization requests
    107      */
    108     protected PacketFilter getFilter() {
    109         return this.initFilter;
    110     }
    111 
    112     /**
    113      * Shuts down the listeners executor service.
    114      */
    115     protected void shutdown() {
    116         this.initiationListenerExecutor.shutdownNow();
    117     }
    118 
    119 }
    120