204 lines
5.4 KiB
Java
204 lines
5.4 KiB
Java
/*
|
|
* Copyright 2015 Christian Basler
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package ch.dissem.bitmessage.entity;
|
|
|
|
import ch.dissem.bitmessage.BitmessageContext;
|
|
import ch.dissem.bitmessage.entity.valueobject.NetworkAddress;
|
|
import ch.dissem.bitmessage.utils.Encode;
|
|
import ch.dissem.bitmessage.utils.UnixTime;
|
|
|
|
import java.io.IOException;
|
|
import java.io.OutputStream;
|
|
import java.util.Random;
|
|
|
|
/**
|
|
* The 'version' command advertises this node's latest supported protocol version upon initiation.
|
|
*/
|
|
public class Version implements MessagePayload {
|
|
/**
|
|
* Identifies protocol version being used by the node. Should equal 3. Nodes should disconnect if the remote node's
|
|
* version is lower but continue with the connection if it is higher.
|
|
*/
|
|
private final int version;
|
|
|
|
/**
|
|
* bitfield of features to be enabled for this connection
|
|
*/
|
|
private final long services;
|
|
|
|
/**
|
|
* standard UNIX timestamp in seconds
|
|
*/
|
|
private final long timestamp;
|
|
|
|
/**
|
|
* The network address of the node receiving this message (not including the time or stream number)
|
|
*/
|
|
private final NetworkAddress addrRecv;
|
|
|
|
/**
|
|
* The network address of the node emitting this message (not including the time or stream number and the ip itself
|
|
* is ignored by the receiver)
|
|
*/
|
|
private final NetworkAddress addrFrom;
|
|
|
|
/**
|
|
* Random nonce used to detect connections to self.
|
|
*/
|
|
private final long nonce;
|
|
|
|
/**
|
|
* User Agent (0x00 if string is 0 bytes long). Sending nodes must not include a user_agent longer than 5000 bytes.
|
|
*/
|
|
private final String userAgent;
|
|
|
|
/**
|
|
* The stream numbers that the emitting node is interested in. Sending nodes must not include more than 160000
|
|
* stream numbers.
|
|
*/
|
|
private final long[] streams;
|
|
|
|
private Version(Builder builder) {
|
|
version = builder.version;
|
|
services = builder.services;
|
|
timestamp = builder.timestamp;
|
|
addrRecv = builder.addrRecv;
|
|
addrFrom = builder.addrFrom;
|
|
nonce = builder.nonce;
|
|
userAgent = builder.userAgent;
|
|
streams = builder.streamNumbers;
|
|
}
|
|
|
|
public int getVersion() {
|
|
return version;
|
|
}
|
|
|
|
public long getServices() {
|
|
return services;
|
|
}
|
|
|
|
public long getTimestamp() {
|
|
return timestamp;
|
|
}
|
|
|
|
public NetworkAddress getAddrRecv() {
|
|
return addrRecv;
|
|
}
|
|
|
|
public NetworkAddress getAddrFrom() {
|
|
return addrFrom;
|
|
}
|
|
|
|
public long getNonce() {
|
|
return nonce;
|
|
}
|
|
|
|
public String getUserAgent() {
|
|
return userAgent;
|
|
}
|
|
|
|
public long[] getStreams() {
|
|
return streams;
|
|
}
|
|
|
|
@Override
|
|
public Command getCommand() {
|
|
return Command.VERSION;
|
|
}
|
|
|
|
@Override
|
|
public void write(OutputStream stream) throws IOException {
|
|
Encode.int32(version, stream);
|
|
Encode.int64(services, stream);
|
|
Encode.int64(timestamp, stream);
|
|
addrRecv.write(stream, true);
|
|
addrFrom.write(stream, true);
|
|
Encode.int64(nonce, stream);
|
|
Encode.varString(userAgent, stream);
|
|
Encode.varIntList(streams, stream);
|
|
}
|
|
|
|
|
|
public static final class Builder {
|
|
private int version;
|
|
private long services;
|
|
private long timestamp;
|
|
private NetworkAddress addrRecv;
|
|
private NetworkAddress addrFrom;
|
|
private long nonce;
|
|
private String userAgent;
|
|
private long[] streamNumbers;
|
|
|
|
public Builder() {
|
|
}
|
|
|
|
public Builder defaults() {
|
|
version = BitmessageContext.CURRENT_VERSION;
|
|
services = 1;
|
|
timestamp = UnixTime.now();
|
|
nonce = new Random().nextInt();
|
|
userAgent = "/Jabit:0.0.1/";
|
|
streamNumbers = new long[]{1};
|
|
return this;
|
|
}
|
|
|
|
public Builder version(int version) {
|
|
this.version = version;
|
|
return this;
|
|
}
|
|
|
|
public Builder services(long services) {
|
|
this.services = services;
|
|
return this;
|
|
}
|
|
|
|
public Builder timestamp(long timestamp) {
|
|
this.timestamp = timestamp;
|
|
return this;
|
|
}
|
|
|
|
public Builder addrRecv(NetworkAddress addrRecv) {
|
|
this.addrRecv = addrRecv;
|
|
return this;
|
|
}
|
|
|
|
public Builder addrFrom(NetworkAddress addrFrom) {
|
|
this.addrFrom = addrFrom;
|
|
return this;
|
|
}
|
|
|
|
public Builder nonce(long nonce) {
|
|
this.nonce = nonce;
|
|
return this;
|
|
}
|
|
|
|
public Builder userAgent(String userAgent) {
|
|
this.userAgent = userAgent;
|
|
return this;
|
|
}
|
|
|
|
public Builder streams(long... streamNumbers) {
|
|
this.streamNumbers = streamNumbers;
|
|
return this;
|
|
}
|
|
|
|
public Version build() {
|
|
return new Version(this);
|
|
}
|
|
}
|
|
}
|