This commit is contained in:
33
src/com/wentch/redkale/net/icep/BindingIcepServlet.java
Normal file
33
src/com/wentch/redkale/net/icep/BindingIcepServlet.java
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.wentch.redkale.net.icep;
|
||||
|
||||
import com.wentch.redkale.net.icep.attr.*;
|
||||
import com.wentch.redkale.net.icep.stun.*;
|
||||
import com.wentch.redkale.util.*;
|
||||
import java.io.*;
|
||||
import java.nio.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
@AutoLoad(false)
|
||||
public class BindingIcepServlet extends IcepServlet {
|
||||
|
||||
@Override
|
||||
public void execute(IcepRequest request, IcepResponse response) throws IOException {
|
||||
StunPacket packet = request.getStunPacket();
|
||||
ByteBuffer buffer = response.getContext().pollBuffer();
|
||||
packet.addAttribute(new XorMappedAddressAttribute(request.getRemoteAddress()));
|
||||
packet.getHeader().setRequestid((short) (StunHeader.TYPE_SUCCESS | StunHeader.ACTION_BINDING));
|
||||
packet.encode(buffer);
|
||||
buffer.flip();
|
||||
Utility.println("响应结果: ", buffer);
|
||||
response.finish(buffer);
|
||||
}
|
||||
|
||||
}
|
||||
33
src/com/wentch/redkale/net/icep/IcepContext.java
Normal file
33
src/com/wentch/redkale/net/icep/IcepContext.java
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.wentch.redkale.net.icep;
|
||||
|
||||
import com.wentch.redkale.convert.bson.*;
|
||||
import com.wentch.redkale.net.*;
|
||||
import com.wentch.redkale.util.*;
|
||||
import com.wentch.redkale.watch.*;
|
||||
import java.net.*;
|
||||
import java.nio.*;
|
||||
import java.nio.charset.*;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.logging.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
public final class IcepContext extends Context {
|
||||
|
||||
protected final BsonFactory bsonFactory;
|
||||
|
||||
public IcepContext(long serverStartTime, Logger logger, ExecutorService executor, ObjectPool<ByteBuffer> bufferPool,
|
||||
ObjectPool<Response> responsePool, int maxbody, Charset charset, InetSocketAddress address, PrepareServlet prepare,
|
||||
WatchFactory watch, int readTimeoutSecond, int writeTimeoutSecond) {
|
||||
super(serverStartTime, logger, executor, bufferPool, responsePool, maxbody, charset,
|
||||
address, prepare, watch, readTimeoutSecond, writeTimeoutSecond);
|
||||
this.bsonFactory = BsonFactory.root();
|
||||
}
|
||||
}
|
||||
29
src/com/wentch/redkale/net/icep/IcepException.java
Normal file
29
src/com/wentch/redkale/net/icep/IcepException.java
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.wentch.redkale.net.icep;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
public class IcepException extends RuntimeException {
|
||||
|
||||
public IcepException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public IcepException(String s) {
|
||||
super(s);
|
||||
}
|
||||
|
||||
public IcepException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public IcepException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
40
src/com/wentch/redkale/net/icep/IcepPrepareServlet.java
Normal file
40
src/com/wentch/redkale/net/icep/IcepPrepareServlet.java
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.wentch.redkale.net.icep;
|
||||
|
||||
import com.wentch.redkale.net.*;
|
||||
import com.wentch.redkale.util.*;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
public class IcepPrepareServlet extends PrepareServlet<IcepRequest, IcepResponse> {
|
||||
|
||||
private final HashMap<Integer, IcepServlet> servletmaps = new HashMap<>();
|
||||
|
||||
public IcepPrepareServlet() {
|
||||
this.servletmaps.put(0x0001, new BindingIcepServlet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Context context, AnyValue config) {
|
||||
}
|
||||
|
||||
// 28.[00,03,00,08, 21,12,a4,42,45,6f,4e,77,4e,47,71,55,32,37,77,39, 00,19,00,04,11,00,00,00]
|
||||
@Override
|
||||
public void execute(IcepRequest request, IcepResponse response) throws IOException {
|
||||
IcepServlet servlet = servletmaps.get(request.getRequestid());
|
||||
if (servlet != null) {
|
||||
servlet.execute(request, response);
|
||||
} else {
|
||||
response.finish();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
74
src/com/wentch/redkale/net/icep/IcepRequest.java
Normal file
74
src/com/wentch/redkale/net/icep/IcepRequest.java
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.wentch.redkale.net.icep;
|
||||
|
||||
import com.wentch.redkale.net.*;
|
||||
import com.wentch.redkale.net.icep.stun.*;
|
||||
import com.wentch.redkale.util.*;
|
||||
import java.net.*;
|
||||
import java.nio.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
public class IcepRequest extends Request {
|
||||
|
||||
private int requestid;
|
||||
|
||||
private StunPacket stunPacket;
|
||||
|
||||
protected IcepRequest(IcepContext context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
// 20.[00,01,00,00,21,12,a4,42,63,6a,30,65,62,43,44,57,67,76,68,58]
|
||||
@Override
|
||||
protected int readHeader(ByteBuffer buffer) {
|
||||
Utility.println(Utility.now() + "-------" + getRemoteAddress() + " ", buffer);
|
||||
if (buffer.remaining() < 20) return -1;
|
||||
this.requestid = buffer.getShort();
|
||||
short typeid = (short) ((this.requestid >> 16) & 0xffff);
|
||||
short actionid = (short) (this.requestid & 0xffff);
|
||||
byte[] bytes = new byte[16];
|
||||
buffer.get(bytes);
|
||||
StunHeader header = new StunHeader(typeid, actionid, bytes);
|
||||
this.stunPacket = new StunPacket(header);
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
int a = 0xabcd0000;
|
||||
System.out.println(Integer.toHexString((a >> 16) & 0xffff));
|
||||
}
|
||||
|
||||
public InetSocketAddress getRemoteAddress() {
|
||||
return (InetSocketAddress) channel.getRemoteAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readBody(ByteBuffer buffer) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void prepare() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void recycle() {
|
||||
|
||||
}
|
||||
|
||||
public int getRequestid() {
|
||||
return requestid;
|
||||
}
|
||||
|
||||
public StunPacket getStunPacket() {
|
||||
return stunPacket;
|
||||
}
|
||||
|
||||
}
|
||||
25
src/com/wentch/redkale/net/icep/IcepResponse.java
Normal file
25
src/com/wentch/redkale/net/icep/IcepResponse.java
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.wentch.redkale.net.icep;
|
||||
|
||||
import com.wentch.redkale.net.*;
|
||||
import com.wentch.redkale.util.*;
|
||||
import java.util.concurrent.atomic.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
public class IcepResponse extends Response<IcepRequest> {
|
||||
|
||||
protected IcepResponse(Context context, IcepRequest request) {
|
||||
super(context, request);
|
||||
}
|
||||
|
||||
public static ObjectPool<Response> createPool(AtomicLong creatCounter, AtomicLong cycleCounter, int max, Creator<Response> creator) {
|
||||
return new ObjectPool<>(creatCounter, cycleCounter, max, creator, (x) -> ((IcepResponse) x).prepare(), (x) -> ((IcepResponse) x).recycle());
|
||||
}
|
||||
}
|
||||
67
src/com/wentch/redkale/net/icep/IcepServer.java
Normal file
67
src/com/wentch/redkale/net/icep/IcepServer.java
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.wentch.redkale.net.icep;
|
||||
|
||||
import com.wentch.redkale.net.*;
|
||||
import com.wentch.redkale.util.*;
|
||||
import com.wentch.redkale.util.AnyValue.DefaultAnyValue;
|
||||
import com.wentch.redkale.watch.*;
|
||||
import java.nio.*;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.atomic.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
public final class IcepServer extends Server {
|
||||
|
||||
public IcepServer() {
|
||||
this(System.currentTimeMillis(), null);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
DefaultAnyValue conf = new DefaultAnyValue();
|
||||
conf.addValue("host", "10.28.2.207");
|
||||
conf.addValue("port", "3478");
|
||||
final CountDownLatch cdl = new CountDownLatch(1);
|
||||
final IcepServer server = new IcepServer();
|
||||
server.init(conf);
|
||||
server.start();
|
||||
cdl.await();
|
||||
}
|
||||
|
||||
public IcepServer(long serverStartTime, final WatchFactory watch) {
|
||||
super(serverStartTime, "UDP", new IcepPrepareServlet(), watch);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(AnyValue config) throws Exception {
|
||||
super.init(config);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Context createContext() {
|
||||
final int port = this.address.getPort();
|
||||
AtomicLong createBufferCounter = watch == null ? new AtomicLong() : watch.createWatchNumber("ICEP_" + port + ".Buffer.creatCounter");
|
||||
AtomicLong cycleBufferCounter = watch == null ? new AtomicLong() : watch.createWatchNumber("ICEP_" + port + ".Buffer.cycleCounter");
|
||||
int rcapacity = Math.max(this.capacity, 16 * 1024 + 8); //兼容 HTTP 2.0
|
||||
ObjectPool<ByteBuffer> bufferPool = new ObjectPool<>(createBufferCounter, cycleBufferCounter, this.bufferPoolSize,
|
||||
(Object... params) -> ByteBuffer.allocateDirect(rcapacity), null, (e) -> {
|
||||
if (e == null || e.isReadOnly() || e.capacity() != rcapacity) return false;
|
||||
e.clear();
|
||||
return true;
|
||||
});
|
||||
AtomicLong createResponseCounter = watch == null ? new AtomicLong() : watch.createWatchNumber("ICEP_" + port + ".Response.creatCounter");
|
||||
AtomicLong cycleResponseCounter = watch == null ? new AtomicLong() : watch.createWatchNumber("ICEP_" + port + ".Response.cycleCounter");
|
||||
ObjectPool<Response> responsePool = IcepResponse.createPool(createResponseCounter, cycleResponseCounter, this.responsePoolSize, null);
|
||||
IcepContext icepcontext = new IcepContext(this.serverStartTime, this.logger, executor, bufferPool, responsePool,
|
||||
this.maxbody, this.charset, this.address, this.prepare, this.watch, this.readTimeoutSecond, this.writeTimeoutSecond);
|
||||
responsePool.setCreator((Object... params) -> new IcepResponse(icepcontext, new IcepRequest(icepcontext)));
|
||||
return icepcontext;
|
||||
}
|
||||
}
|
||||
28
src/com/wentch/redkale/net/icep/IcepServlet.java
Normal file
28
src/com/wentch/redkale/net/icep/IcepServlet.java
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.wentch.redkale.net.icep;
|
||||
|
||||
import com.wentch.redkale.net.*;
|
||||
import com.wentch.redkale.util.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
public abstract class IcepServlet implements Servlet<IcepRequest, IcepResponse> {
|
||||
|
||||
AnyValue conf; //当前HttpServlet的配置
|
||||
|
||||
@Override
|
||||
public final boolean equals(Object obj) {
|
||||
return obj != null && obj.getClass() == this.getClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int hashCode() {
|
||||
return this.getClass().hashCode();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.wentch.redkale.net.icep.attr;
|
||||
|
||||
import com.wentch.redkale.net.icep.*;
|
||||
import com.wentch.redkale.net.icep.stun.*;
|
||||
import com.wentch.redkale.util.*;
|
||||
import java.net.*;
|
||||
import java.nio.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
public class XorMappedAddressAttribute extends StunAttribute {
|
||||
|
||||
private InetSocketAddress address;
|
||||
|
||||
public XorMappedAddressAttribute() {
|
||||
}
|
||||
|
||||
public XorMappedAddressAttribute(InetSocketAddress address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StunAttribute decode(final ByteBuffer buffer, final byte[] transactionid) {
|
||||
final short attrid = buffer.getShort();
|
||||
if (attrid != getAttributeid()) throw new IcepException(this.getClass().getSimpleName() + " has illegal attributeid " + attrid);
|
||||
final int bodysize = buffer.getShort() & 0xffff;
|
||||
final short family = buffer.getShort();
|
||||
if (bodysize == 24 && family != 0x0002) throw new IcepException("bodysize = " + bodysize + " but family = " + family);
|
||||
if (bodysize == 12 && family != 0x0001) throw new IcepException("bodysize = " + bodysize + " but family = " + family);
|
||||
final int port = (buffer.getShort() ^ ((transactionid[0] << 8 & 0x0000FF00) | (transactionid[1] & 0x000000FF))) & 0xffff;
|
||||
byte[] bytes = new byte[family == 0x0002 ? 16 : 4];
|
||||
buffer.get(bytes);
|
||||
for (int i = 0; i <= bytes.length; i++) {
|
||||
bytes[i] ^= transactionid[i];
|
||||
}
|
||||
try {
|
||||
this.address = new InetSocketAddress(InetAddress.getByAddress(bytes), port);
|
||||
} catch (UnknownHostException e) {
|
||||
throw new IcepException("port = " + port + " and address = " + Utility.binToHexString(bytes), e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer encode(final ByteBuffer buffer, final byte[] transactionid) {
|
||||
final boolean ipv6 = this.address.getAddress() instanceof Inet6Address;
|
||||
buffer.putShort((short) getAttributeid());
|
||||
buffer.putShort((short) (ipv6 ? 24 : 12));
|
||||
buffer.putShort((short) (ipv6 ? 0x0002 : 0x0001));
|
||||
buffer.putShort((short) (this.address.getPort() ^ ((transactionid[0] << 8 & 0x0000FF00) | (transactionid[1] & 0x000000FF))));
|
||||
final byte[] bytes = this.address.getAddress().getAddress();
|
||||
for (int i = 0; i <= bytes.length; i++) {
|
||||
bytes[i] ^= transactionid[i];
|
||||
}
|
||||
buffer.put(bytes);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public short getAttributeid() {
|
||||
return 0x0020;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "XOR-MAPPED-ADDRESS";
|
||||
}
|
||||
|
||||
public InetSocketAddress getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
}
|
||||
23
src/com/wentch/redkale/net/icep/stun/StunAttribute.java
Normal file
23
src/com/wentch/redkale/net/icep/stun/StunAttribute.java
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.wentch.redkale.net.icep.stun;
|
||||
|
||||
import java.nio.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
public abstract class StunAttribute {
|
||||
|
||||
public abstract StunAttribute decode(final ByteBuffer buffer, final byte[] transactionid);
|
||||
|
||||
public abstract ByteBuffer encode(final ByteBuffer buffer, final byte[] transactionid);
|
||||
|
||||
public abstract short getAttributeid();
|
||||
|
||||
public abstract String getName();
|
||||
}
|
||||
139
src/com/wentch/redkale/net/icep/stun/StunHeader.java
Normal file
139
src/com/wentch/redkale/net/icep/stun/StunHeader.java
Normal file
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.wentch.redkale.net.icep.stun;
|
||||
|
||||
import com.wentch.redkale.util.*;
|
||||
import java.nio.*;
|
||||
import java.security.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
public class StunHeader {
|
||||
|
||||
public static final int MAGIC_COOKIE = 0x2112A442;
|
||||
|
||||
//---------------------------- type -------------------------
|
||||
private static final int TYPE_BIT_MASK = 0x0110;
|
||||
|
||||
public static final short TYPE_REQUEST = 0x0000;
|
||||
|
||||
public static final short TYPE_INDICATION = 0x0010;
|
||||
|
||||
public static final short TYPE_SUCCESS = 0x0100;
|
||||
|
||||
public static final short TYPE_ERROR = 0x0110;
|
||||
|
||||
//---------------------------- action -------------------------
|
||||
public static final int ACTION_BIT_MASK = 0xCEEF;
|
||||
|
||||
public static final short ACTION_BINDING = 0x0001;
|
||||
|
||||
public static final short ACTION_ALLOCATE = 0x0003;
|
||||
|
||||
public static final short ACTION_REFRESH = 0x0004;
|
||||
|
||||
public static final short ACTION_SEND = 0x0006;
|
||||
|
||||
public static final short ACTION_DATA = 0x0007;
|
||||
|
||||
public static final short ACTION_CREATE_PERMISSION = 0x0008;
|
||||
|
||||
public static final short ACTION_CHANNELBIND = 0x0009;
|
||||
|
||||
//-----------------------------------------------------------
|
||||
private short typeid; //无符号 2bytes
|
||||
|
||||
private short actionid; //无符号 2bytes
|
||||
|
||||
private int bodysize; //无符号 2bytes
|
||||
|
||||
private byte[] transactionid; //RFC5389 =MAGIC_COOKIE + byte[12] = byte[16];
|
||||
|
||||
public static byte[] generateTransactionid() {
|
||||
byte[] transactions = new byte[16];
|
||||
// Get a secure PRNG
|
||||
SecureRandom random = new SecureRandom();
|
||||
random.nextBytes(transactions);
|
||||
transactions[0] = 0x21;
|
||||
transactions[1] = 0x12;
|
||||
transactions[2] = (byte) 0xA4;
|
||||
transactions[3] = 0x42;
|
||||
return transactions;
|
||||
}
|
||||
|
||||
public StunHeader(short typeid, short actionid, byte[] transactionid0) {
|
||||
this.typeid = typeid;
|
||||
this.actionid = actionid;
|
||||
this.transactionid = transactionid0 == null ? generateTransactionid() : transactionid0;
|
||||
}
|
||||
|
||||
public StunHeader decode(final ByteBuffer buffer) {
|
||||
short requestid = buffer.getShort();
|
||||
this.typeid = (short) (requestid << 2);
|
||||
this.actionid = (short) (requestid & 0xff);
|
||||
this.bodysize = buffer.getShort() & 0xffff;
|
||||
this.transactionid = new byte[16];
|
||||
buffer.get(transactionid);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ByteBuffer encode(final ByteBuffer buffer) {
|
||||
buffer.putShort((short) (this.typeid << 8 | this.actionid)); //requestid
|
||||
buffer.putShort((short) 0); //bodysize
|
||||
buffer.put(transactionid);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getClass().getSimpleName() + "[typeid = " + format(typeid) + ", actionid = " + format(actionid)
|
||||
+ ", bodysize = " + (int) (bodysize) + ", transactionid = " + Utility.binToHexString(transactionid) + "]";
|
||||
}
|
||||
|
||||
private static String format(short value) {
|
||||
String str = Integer.toHexString(value);
|
||||
if (str.length() == 1) return "0x000" + str;
|
||||
if (str.length() == 2) return "0x00" + str;
|
||||
if (str.length() == 3) return "0x0" + str;
|
||||
return "0x" + str;
|
||||
}
|
||||
|
||||
public void setRequestid(short requestid) {
|
||||
this.typeid = (short) (requestid << 2);
|
||||
this.actionid = (short) (requestid & 0xff);
|
||||
}
|
||||
|
||||
public void setBodysize(char bodysize) {
|
||||
this.bodysize = bodysize;
|
||||
}
|
||||
|
||||
public void setTypeid(short typeid) {
|
||||
this.typeid = typeid;
|
||||
}
|
||||
|
||||
public void setActionid(short actionid) {
|
||||
this.actionid = actionid;
|
||||
}
|
||||
|
||||
public short getTypeid() {
|
||||
return typeid;
|
||||
}
|
||||
|
||||
public short getActionid() {
|
||||
return actionid;
|
||||
}
|
||||
|
||||
public int getBodysize() {
|
||||
return bodysize;
|
||||
}
|
||||
|
||||
public byte[] getTransactionid() {
|
||||
return transactionid;
|
||||
}
|
||||
|
||||
}
|
||||
51
src/com/wentch/redkale/net/icep/stun/StunPacket.java
Normal file
51
src/com/wentch/redkale/net/icep/stun/StunPacket.java
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.wentch.redkale.net.icep.stun;
|
||||
|
||||
import java.nio.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
public class StunPacket {
|
||||
|
||||
private StunHeader header;
|
||||
|
||||
private final List<StunAttribute> attributes = new ArrayList<>();
|
||||
|
||||
public StunPacket(StunHeader header) {
|
||||
this.header = header;
|
||||
}
|
||||
|
||||
public ByteBuffer encode(final ByteBuffer buffer) {
|
||||
int start = buffer.position();
|
||||
header.encode(buffer);
|
||||
final byte[] transactionid = header.getTransactionid();
|
||||
for (StunAttribute attr : attributes) {
|
||||
attr.encode(buffer, transactionid);
|
||||
}
|
||||
int end = buffer.position();
|
||||
buffer.position(start + 2);
|
||||
buffer.putShort((short) (end - start - 20));
|
||||
buffer.position(end);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public void addAttribute(StunAttribute attribute) {
|
||||
this.attributes.add(attribute);
|
||||
}
|
||||
|
||||
public StunHeader getHeader() {
|
||||
return header;
|
||||
}
|
||||
|
||||
public List<StunAttribute> getAttributes() {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user