blob: 2a78250a007dd9ae538eb33d0d053b546293030f [file] [log] [blame]
Shuyi Chend7955ce2013-05-22 14:51:55 -07001/**
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 */
14package org.jivesoftware.smackx.bytestreams.socks5;
15
16import java.util.concurrent.ExecutorService;
17import java.util.concurrent.Executors;
18
19import org.jivesoftware.smack.PacketListener;
20import org.jivesoftware.smack.filter.AndFilter;
21import org.jivesoftware.smack.filter.IQTypeFilter;
22import org.jivesoftware.smack.filter.PacketFilter;
23import org.jivesoftware.smack.filter.PacketTypeFilter;
24import org.jivesoftware.smack.packet.IQ;
25import org.jivesoftware.smack.packet.Packet;
26import org.jivesoftware.smackx.bytestreams.BytestreamListener;
27import 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 */
37final 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}