Run reformat and organize imports

This commit is contained in:
Manfred Karrer 2016-01-21 02:48:44 +01:00
parent f723bf5737
commit cb685d3b5c
73 changed files with 802 additions and 829 deletions

View File

@ -19,7 +19,10 @@ package io.bitsquare.locale;
import io.bitsquare.user.Preferences;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
public class CountryUtil {

View File

@ -86,7 +86,7 @@ public class OfferAvailabilityProtocol {
model.p2PService.addDecryptedMailListener(decryptedMailListener);
model.setPeerAddress(model.offer.getOffererAddress());
taskRunner = new TaskRunner<>(model,
() -> {
log.debug("sequence at sendOfferAvailabilityRequest completed");

View File

@ -106,7 +106,7 @@ public class User implements Serializable {
String english = LanguageUtil.getEnglishLanguageLocaleCode();
if (!acceptedLanguageLocaleCodes.contains(english))
acceptedLanguageLocaleCodes.add(english);
acceptedArbitrators = new ArrayList<>();
}
storage.queueUpForSave();

View File

@ -387,8 +387,7 @@ public class Notification {
if (stage.isShowing()) {
stage.toFront();
}
else {
} else {
stage.show();
}
@ -530,14 +529,11 @@ public class Notification {
final EventHandler<NotificationEvent> HANDLER;
if (NotificationEvent.NOTIFICATION_PRESSED == TYPE) {
HANDLER = getOnNotificationPressed();
}
else if (NotificationEvent.SHOW_NOTIFICATION == TYPE) {
} else if (NotificationEvent.SHOW_NOTIFICATION == TYPE) {
HANDLER = getOnShowNotification();
}
else if (NotificationEvent.HIDE_NOTIFICATION == TYPE) {
} else if (NotificationEvent.HIDE_NOTIFICATION == TYPE) {
HANDLER = getOnHideNotification();
}
else {
} else {
HANDLER = null;
}
if (null == HANDLER) return;

View File

@ -58,8 +58,7 @@ public class FxmlViewLoader implements ViewLoader {
if (fxmlView == null) {
convention = defaultConvention;
specifiedLocation = defaultLocation;
}
else {
} else {
convention = fxmlView.convention();
specifiedLocation = fxmlView.location();
}

View File

@ -18,8 +18,7 @@
package io.bitsquare.gui.common.view;
import javafx.fxml.FXML;
import javafx.scene.*;
import javafx.scene.Node;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -27,7 +26,9 @@ public abstract class AbstractView<R extends Node, M> implements View {
protected final Logger log = LoggerFactory.getLogger(this.getClass());
protected @FXML R root;
protected
@FXML
R root;
protected final M model;
public AbstractView(M model) {

View File

@ -17,7 +17,7 @@
package io.bitsquare.gui.common.view;
import javafx.scene.*;
import javafx.scene.Node;
public abstract class ActivatableView<R extends Node, M> extends InitializableView<R, M> {

View File

@ -17,9 +17,8 @@
package io.bitsquare.gui.common.view;
import java.util.HashMap;
import javax.inject.Inject;
import java.util.HashMap;
public class CachingViewLoader implements ViewLoader {

View File

@ -17,12 +17,11 @@
package io.bitsquare.gui.common.view;
import java.util.function.Function;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.function.Function;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)

View File

@ -17,12 +17,11 @@
package io.bitsquare.gui.common.view;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.Initializable;
import javafx.scene.*;
import javafx.scene.Node;
import java.net.URL;
import java.util.ResourceBundle;
public abstract class InitializableView<R extends Node, M> extends AbstractView<R, M> implements Initializable {

View File

@ -17,7 +17,7 @@
package io.bitsquare.gui.common.view;
import javafx.scene.*;
import javafx.scene.Node;
public interface View {
Node getRoot();

View File

@ -17,11 +17,9 @@
package io.bitsquare.gui.common.view.guice;
import io.bitsquare.gui.common.view.ViewFactory;
import com.google.common.base.Preconditions;
import com.google.inject.Injector;
import io.bitsquare.gui.common.view.ViewFactory;
public class InjectorViewFactory implements ViewFactory {

View File

@ -117,8 +117,7 @@ public class InfoDisplay extends Parent {
link.setStyle("-fx-focus-color: transparent;");
link.setOnAction(onAction.get());
getParent().layout();
}
else {
} else {
onAction.get().handle(actionEvent);
}
}

View File

@ -18,17 +18,18 @@
package io.bitsquare.gui.components;
import io.bitsquare.gui.util.validation.InputValidator;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.geometry.Insets;
import javafx.geometry.Point2D;
import javafx.scene.control.*;
import javafx.scene.effect.*;
import javafx.scene.layout.*;
import javafx.scene.paint.*;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.effect.BlurType;
import javafx.scene.effect.DropShadow;
import javafx.scene.effect.Effect;
import javafx.scene.layout.Region;
import javafx.scene.paint.Color;
import javafx.stage.Window;
import org.controlsfx.control.PopOver;
/**

View File

@ -19,8 +19,10 @@ package io.bitsquare.gui.components;
import javafx.animation.FadeTransition;
import javafx.animation.Interpolator;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.util.Duration;
// TODO replace with new notification component from lighthouse/bitcoinJ

View File

@ -25,12 +25,11 @@
package io.bitsquare.gui.components.confidence.behavior;
import com.sun.javafx.scene.control.behavior.BehaviorBase;
import io.bitsquare.gui.components.confidence.ConfidenceProgressIndicator;
import java.util.Collections;
import com.sun.javafx.scene.control.behavior.BehaviorBase;
// TODO Copied form OpenJFX, check license issues and way how we integrated it
// We changed behaviour which was not exposed via APIs

View File

@ -17,24 +17,25 @@
package io.bitsquare.gui.components.processbar;
import com.sun.javafx.scene.control.behavior.BehaviorBase;
import com.sun.javafx.scene.control.behavior.KeyBinding;
import com.sun.javafx.scene.control.skin.BehaviorSkinBase;
import io.bitsquare.gui.util.Colors;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.layout.Border;
import javafx.scene.layout.BorderStroke;
import javafx.scene.layout.BorderStrokeStyle;
import javafx.scene.layout.BorderWidths;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.paint.*;
import javafx.scene.shape.*;
import com.sun.javafx.scene.control.behavior.BehaviorBase;
import com.sun.javafx.scene.control.behavior.KeyBinding;
import com.sun.javafx.scene.control.skin.BehaviorSkinBase;
class ProcessStepBarSkin<T> extends BehaviorSkinBase<ProcessStepBar<T>, BehaviorBase<ProcessStepBar<T>>> {
private final ProcessStepBar<T> controller;

View File

@ -113,8 +113,7 @@ public class AccountView extends ActivatableView<TabPane, AccountViewModel> {
tab = arbitratorRegistrationTab;
arbitratorRegistrationView = (ArbitratorRegistrationView) view;
arbitratorRegistrationView.onTabSelection(true);
}
else {
} else {
throw new IllegalArgumentException("View not supported: " + view);
}

View File

@ -17,11 +17,10 @@
package io.bitsquare.gui.main.account;
import com.google.inject.Inject;
import io.bitsquare.gui.common.model.ViewModel;
import io.bitsquare.user.User;
import com.google.inject.Inject;
class AccountViewModel implements ViewModel {
private final User user;

View File

@ -22,19 +22,23 @@ import io.bitsquare.gui.common.view.InitializableView;
import io.bitsquare.gui.common.view.Wizard;
import io.bitsquare.gui.main.help.Help;
import io.bitsquare.gui.main.help.HelpId;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.PasswordField;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javax.inject.Inject;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.layout.*;
@FxmlView
public class ChangePasswordView extends InitializableView<GridPane, ChangePasswordViewModel> implements Wizard.Step {
@FXML HBox buttonsHBox;
@FXML Button saveButton, skipButton;
@FXML PasswordField oldPasswordField, passwordField, repeatedPasswordField;
@FXML
HBox buttonsHBox;
@FXML
Button saveButton, skipButton;
@FXML
PasswordField oldPasswordField, passwordField, repeatedPasswordField;
private Wizard wizard;

View File

@ -17,12 +17,10 @@
package io.bitsquare.gui.main.account.content.changepassword;
import com.google.inject.Inject;
import io.bitsquare.gui.common.model.ViewModel;
import io.bitsquare.gui.util.validation.InputValidator;
import io.bitsquare.gui.util.validation.PasswordValidator;
import com.google.inject.Inject;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
@ -74,12 +72,10 @@ class ChangePasswordViewModel implements ViewModel {
return true;
else
errorMessage = "The 2 passwords does not match.";
}
else {
} else {
errorMessage = result.errorMessage;
}
}
else {
} else {
errorMessage = result.errorMessage;
}
return false;

View File

@ -104,7 +104,7 @@ public class PasswordView extends ActivatableView<GridPane, Void> {
keyCrypterScrypt = (KeyCrypterScrypt) wallet.getKeyCrypter();
else
keyCrypterScrypt = ScryptUtil.getKeyCrypterScrypt();
ScryptUtil.deriveKeyWithScrypt(keyCrypterScrypt, passwordField.getText(), aesKey -> {
deriveStatusLabel.setText("");

View File

@ -38,8 +38,10 @@ import javax.inject.Inject;
@FxmlView
public class AccountSetupWizard extends ActivatableView implements Wizard {
@FXML VBox leftVBox;
@FXML AnchorPane content;
@FXML
VBox leftVBox;
@FXML
AnchorPane content;
private WizardItem seedWords, password, fiatAccount, restrictions;
private Navigation.Listener listener;
@ -63,8 +65,7 @@ public class AccountSetupWizard extends ActivatableView implements Wizard {
if (viewClass == SeedWordsView.class) {
seedWords.show();
}
else if (viewClass == PasswordView.class) {
} else if (viewClass == PasswordView.class) {
seedWords.onCompleted();
password.show();
} else if (viewClass == ArbitratorSelectionView.class) {
@ -107,8 +108,7 @@ public class AccountSetupWizard extends ActivatableView implements Wizard {
if (currentStep instanceof SeedWordsView) {
seedWords.onCompleted();
password.show();
}
else if (currentStep instanceof PasswordView) {
} else if (currentStep instanceof PasswordView) {
password.onCompleted();
restrictions.show();
} else if (currentStep instanceof ArbitratorSelectionView) {

View File

@ -38,7 +38,8 @@ import javax.inject.Inject;
@FxmlView
public class FundsView extends ActivatableViewAndModel<TabPane, Activatable> {
@FXML Tab reservedTab, withdrawalTab, transactionsTab;
@FXML
Tab reservedTab, withdrawalTab, transactionsTab;
private Navigation.Listener navigationListener;
private ChangeListener<Tab> tabChangeListener;

View File

@ -47,7 +47,8 @@ import java.util.stream.Stream;
@FxmlView
public class ReservedView extends ActivatableView<VBox, Void> {
@FXML TableView<ReservedListItem> table;
@FXML
TableView<ReservedListItem> table;
@FXML
TableColumn<ReservedListItem, ReservedListItem> labelColumn, addressColumn, balanceColumn, confidenceColumn;
@ -154,8 +155,7 @@ public class ReservedView extends ActivatableView<VBox, Void> {
});
}
setGraphic(hyperlink);
}
else {
} else {
setGraphic(null);
setId(null);
}
@ -233,8 +233,7 @@ public class ReservedView extends ActivatableView<VBox, Void> {
if (item != null && !empty) {
setGraphic(item.getProgressIndicator());
}
else {
} else {
setGraphic(null);
}
}

View File

@ -17,8 +17,8 @@
~ along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
-->
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.layout.AnchorPane?>
<TabPane fx:id="root" fx:controller="io.bitsquare.gui.main.offer.BuyOfferView"
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0"
AnchorPane.topAnchor="0.0"

View File

@ -17,8 +17,8 @@
~ along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
-->
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.layout.AnchorPane?>
<TabPane fx:id="root" fx:controller="io.bitsquare.gui.main.offer.SellOfferView"
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0"
AnchorPane.topAnchor="0.0"

View File

@ -274,7 +274,7 @@ class OfferBookViewModel extends ActivatableViewModel {
boolean directionResult = offer.getDirection() != direction;
boolean currencyResult = offer.getCurrencyCode().equals(tradeCurrency.getCode());
boolean paymentMethodResult = true;
if (!(paymentMethod instanceof AllPaymentMethodsEntry))
if (!(paymentMethod instanceof AllPaymentMethodsEntry))
paymentMethodResult = offer.getPaymentMethod().equals(paymentMethod);
return directionResult && currencyResult && paymentMethodResult;

View File

@ -277,7 +277,7 @@ class TakeOfferDataModel extends ActivatableDataModel {
boolean isMinAmountLessOrEqualAmount() {
//noinspection SimplifiableIfStatement
if (offer != null && offer.getMinAmount() != null && amountAsCoin.get() != null)
if (offer != null && offer.getMinAmount() != null && amountAsCoin.get() != null)
return !offer.getMinAmount().isGreaterThan(amountAsCoin.get());
return true;
}

View File

@ -38,7 +38,8 @@ import javax.inject.Inject;
@FxmlView
public class PortfolioView extends ActivatableViewAndModel<TabPane, Activatable> {
@FXML Tab openOffersTab, pendingTradesTab, closedTradesTab;
@FXML
Tab openOffersTab, pendingTradesTab, closedTradesTab;
private final Tab failedTradesTab = new Tab("Failed");
private Tab currentTab;
private Navigation.Listener navigationListener;

View File

@ -100,8 +100,7 @@ public class ClosedTradesView extends ActivatableViewAndModel<VBox, ClosedTrades
offerDetailsPopup.show(tradable.getOffer());
});
setGraphic(hyperlink);
}
else {
} else {
setGraphic(null);
setId(null);
}

View File

@ -91,8 +91,7 @@ class ClosedTradesViewModel extends ActivatableWithDataModel<ClosedTradesDataMod
log.error("That must not happen. We got a pending state but we are in the closed trades list.");
return trade.getState().toString();
}
}
else if (item.getTradable() instanceof OpenOffer) {
} else if (item.getTradable() instanceof OpenOffer) {
OpenOffer.State state = ((OpenOffer) item.getTradable()).getState();
log.trace("OpenOffer state {}", state);
switch (state) {

View File

@ -32,8 +32,10 @@ import javax.inject.Inject;
@FxmlView
public class FailedTradesView extends ActivatableViewAndModel<VBox, FailedTradesViewModel> {
@FXML TableView<FailedTradesListItem> table;
@FXML TableColumn<FailedTradesListItem, FailedTradesListItem> priceColumn, amountColumn, volumeColumn,
@FXML
TableView<FailedTradesListItem> table;
@FXML
TableColumn<FailedTradesListItem, FailedTradesListItem> priceColumn, amountColumn, volumeColumn,
directionColumn, dateColumn, tradeIdColumn, stateColumn;
private final TradeDetailsPopup tradeDetailsPopup;
@ -86,8 +88,7 @@ public class FailedTradesView extends ActivatableViewAndModel<VBox, FailedTrades
tradeDetailsPopup.show(trade);
});
setGraphic(hyperlink);
}
else {
} else {
setGraphic(null);
setId(null);
}

View File

@ -17,14 +17,13 @@
package io.bitsquare.gui.main.portfolio.pendingtrades.steps;
import io.bitsquare.gui.util.Colors;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.*;
import de.jensd.fx.fontawesome.AwesomeDude;
import de.jensd.fx.fontawesome.AwesomeIcon;
import io.bitsquare.gui.util.Colors;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
public class TradeWizardItem extends Button {
public Class<? extends TradeStepDetailsView> getViewClass() {

View File

@ -65,7 +65,7 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
transactionFeeFocusedListener = (o, oldValue, newValue) -> {
model.onFocusOutTransactionFeeTextField(oldValue, newValue, transactionFeeInputTextField.getText());
};
addTitledGroupBg(root, ++gridRow, 5, "Display options", Layout.GROUP_DISTANCE);
useAnimationsCheckBox = addLabelCheckBox(root, gridRow, "Use animations:", "", Layout.FIRST_ROW_AND_GROUP_DISTANCE).second;
useEffectsCheckBox = addLabelCheckBox(root, ++gridRow, "Use effects:", "").second;

View File

@ -364,7 +364,7 @@ public class FormBuilder {
public static Tuple2<Label, CheckBox> addLabelCheckBox(GridPane gridPane, int rowIndex, String title, String checkBoxTitle, double top) {
Label label = addLabel(gridPane, rowIndex, title, -3);
GridPane.setMargin(label, new Insets(top, 0, 0, 0));
CheckBox checkBox = new CheckBox(checkBoxTitle);
GridPane.setRowIndex(checkBox, rowIndex);
GridPane.setColumnIndex(checkBox, 1);

View File

@ -18,14 +18,12 @@
package io.bitsquare.gui.util;
import com.google.common.base.Stopwatch;
import java.util.concurrent.TimeUnit;
import javafx.animation.AnimationTimer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.TimeUnit;
public class Profiler {
private static final Logger log = LoggerFactory.getLogger(Profiler.class);

View File

@ -50,8 +50,7 @@ public class OptionalBtcValidator extends BtcValidator {
result = validateIfNotNegative(input)
.and(validateIfNotFractionalBtcValue(input))
.and(validateIfNotExceedsMaxBtcValue(input));
}
else {
} else {
// we accept zero input
return new ValidationResult(true);
}

View File

@ -48,8 +48,7 @@ public class OptionalFiatValidator extends FiatValidator {
result = validateIfNotNegative(input)
.and(validateIfNotExceedsMinFiatValue(input))
.and(validateIfNotExceedsMaxFiatValue(input));
}
else {
} else {
// we accept zero input
return new ValidationResult(true);
}

View File

@ -31,7 +31,7 @@ public final class PasswordValidator extends InputValidator {
if (externalValidationResult != null && !externalValidationResult.isValid)
return externalValidationResult;
return result;
}

View File

@ -18,7 +18,6 @@
package io.bitsquare.app;
import org.junit.Test;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
@ -26,7 +25,7 @@ import org.springframework.mock.env.MockPropertySource;
import static io.bitsquare.app.BitsquareEnvironment.*;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.*;
import static org.junit.Assert.assertThat;
import static org.springframework.core.env.PropertySource.named;
import static org.springframework.core.env.StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME;
import static org.springframework.core.env.StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME;

View File

@ -14,7 +14,7 @@
~ You should have received a copy of the GNU Affero General Public License
~ along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
-->
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane xmlns:fx="http://javafx.com/fxml">
</AnchorPane>

View File

@ -15,7 +15,7 @@
~ along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
-->
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane fx:id="root" fx:controller="io.bitsquare.common.fxml.FxmlViewLoaderTests$MissingFxmlViewAnnotation"
xmlns:fx="http://javafx.com/fxml">
</AnchorPane>

View File

@ -15,7 +15,7 @@
~ along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
-->
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane fx:id="root" fx:controller="io.bitsquare.common.fxml.FxmlViewLoaderTests$WellFormed"
xmlns:fx="http://javafx.com/fxml">
</AnchorPane>

View File

@ -19,24 +19,18 @@ package io.bitsquare.common.fxml;
import io.bitsquare.gui.common.ViewfxException;
import io.bitsquare.gui.common.fxml.FxmlViewLoader;
import io.bitsquare.gui.common.view.AbstractView;
import io.bitsquare.gui.common.view.FxmlView;
import io.bitsquare.gui.common.view.View;
import io.bitsquare.gui.common.view.ViewFactory;
import io.bitsquare.gui.common.view.ViewLoader;
import java.util.ResourceBundle;
import io.bitsquare.gui.common.view.*;
import javafx.fxml.LoadException;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import java.util.ResourceBundle;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.junit.Assert.*;
import static org.junit.Assert.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;

View File

@ -20,11 +20,11 @@ package io.bitsquare.common.support;
import io.bitsquare.gui.common.view.AbstractView;
import io.bitsquare.gui.common.view.CachingViewLoader;
import io.bitsquare.gui.common.view.ViewLoader;
import org.junit.Test;
import static org.mockito.BDDMockito.then;
import static org.mockito.Mockito.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
public class CachingViewLoaderTests {

View File

@ -670,7 +670,7 @@ public class SocksDialog extends Dialog implements WindowListener,
}// end guiInit
/*
* // Main //////////////////////////////////// public static void
* // Main //////////////////////////////////// public static void
* main(String[] args) throws Exception{ Frame f = new
* Frame("Test for SocksDialog"); f.add("Center", new
* Label("Fill the Dialog")); SocksDialog socksdialog = new SocksDialog(f);

View File

@ -198,7 +198,7 @@ public class SocksServerSocket extends ServerSocket {
private void processReply(ProxyMessage reply) throws SocksException {
localPort = reply.port;
/*
* If the server have assigned same host as it was contacted on it might
* If the server have assigned same host as it was contacted on it might
* return an address of all zeros
*/
if (reply.host.equals("0.0.0.0")) {

View File

@ -346,7 +346,7 @@ public class SocksSocket extends Socket {
private void processReply(ProxyMessage reply) throws SocksException {
localPort = reply.port;
/*
* If the server have assigned same host as it was contacted on it might
* If the server have assigned same host as it was contacted on it might
* return an address of all zeros
*/
if (reply.host.equals("0.0.0.0")) {

View File

@ -169,7 +169,7 @@ public class Ident {
// /////////////////////////////////////////////
// USED for Testing
/*
* public static void main(String[] args) throws IOException{
* public static void main(String[] args) throws IOException{
*
* Socket s = null; s = new Socket("gp101-16", 1391);
*

View File

@ -25,7 +25,8 @@ public class FileUtilities {
/**
* Closes both input and output streams when done.
* @param in Stream to read from
*
* @param in Stream to read from
* @param out Stream to write to
* @throws java.io.IOException - If close on input or output fails
*/
@ -39,7 +40,8 @@ public class FileUtilities {
/**
* Won't close the input stream when it's done, needed to handle ZipInputStreams
* @param in Won't be closed
*
* @param in Won't be closed
* @param out Will be closed
* @throws java.io.IOException - If close on output fails
*/
@ -84,7 +86,8 @@ public class FileUtilities {
/**
* Reads the input stream, deletes fileToWriteTo if it exists and over writes it with the stream.
* @param readFrom Stream to read from
*
* @param readFrom Stream to read from
* @param fileToWriteTo File to write to
* @throws java.io.IOException - If any of the file operations fail
*/
@ -110,8 +113,9 @@ public class FileUtilities {
/**
* This has to exist somewhere! Why isn't it a part of the standard Java library?
*
* @param destinationDirectory Directory files are to be extracted to
* @param zipFileInputStream Stream to unzip
* @param zipFileInputStream Stream to unzip
* @throws java.io.IOException - If there are any file errors
*/
public static void extractContentFromZip(File destinationDirectory, InputStream zipFileInputStream)

View File

@ -80,8 +80,7 @@ abstract public class OnionProxyContext {
/**
* Sets environment variables and working directory needed for Tor
*
* @param processBuilder
* we will call start on this to run Tor
* @param processBuilder we will call start on this to run Tor
*/
void setEnvironmentArgsAndWorkingDirectoryForStart(ProcessBuilder processBuilder) {
processBuilder.directory(getWorkingDirectory());
@ -164,7 +163,7 @@ abstract public class OnionProxyContext {
* Files we pull out of the AAR or JAR are typically at the root but for
* executables outside of Android the executable for a particular platform
* is in a specific sub-directory.
*
*
* @return Path to executable in JAR Resources
*/
protected abstract String getPathToTorExecutable();

View File

@ -50,11 +50,11 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS;
* Note that you will most likely need to actually call into the
* AndroidOnionProxyManager or JavaOnionProxyManager in order to create the
* right bindings for your environment.
* <p/>
* <p>
* This class is thread safe but that's mostly because we hit everything over
* the head with 'synchronized'. Given the way this class is used there
* shouldn't be any performance implications of this.
* <p/>
* <p>
* This class began life as TorPlugin from the Briar Project
*/
public abstract class OnionProxyManager {
@ -98,17 +98,13 @@ public abstract class OnionProxyManager {
* given time for bootstrap to finish and if it doesn't then will restart
* the bootstrap process the given number of repeats.
*
* @param secondsBeforeTimeOut
* Seconds to wait for boot strapping to finish
* @param numberOfRetries
* Number of times to try recycling the Tor OP before giving up
* on bootstrapping working
* @param secondsBeforeTimeOut Seconds to wait for boot strapping to finish
* @param numberOfRetries Number of times to try recycling the Tor OP before giving up
* on bootstrapping working
* @return True if bootstrap succeeded, false if there is a problem or the
* bootstrap couldn't complete in the given time.
* @throws java.lang.InterruptedException
* - You know, if we are interrupted
* @throws java.io.IOException
* - IO Exceptions
* bootstrap couldn't complete in the given time.
* @throws java.lang.InterruptedException - You know, if we are interrupted
* @throws java.io.IOException - IO Exceptions
*/
public synchronized boolean startWithRepeat(int secondsBeforeTimeOut, int numberOfRetries)
throws InterruptedException, IOException {
@ -165,8 +161,7 @@ public abstract class OnionProxyManager {
* listening on
*
* @return Discovered socks port
* @throws java.io.IOException
* - File errors
* @throws java.io.IOException - File errors
*/
public synchronized int getIPv4LocalHostSocksPort() throws IOException {
if (isRunning() == false) {
@ -191,14 +186,11 @@ public abstract class OnionProxyManager {
/**
* Publishes a hidden service
*
* @param hiddenServicePort
* The port that the hidden service will accept connections on
* @param localPort
* The local port that the hidden service will relay connections
* to
* @param hiddenServicePort The port that the hidden service will accept connections on
* @param localPort The local port that the hidden service will relay connections
* to
* @return The hidden service's onion address in the form X.onion.
* @throws java.io.IOException
* - File errors
* @throws java.io.IOException - File errors
*/
public synchronized String publishHiddenService(int hiddenServicePort, int localPort) throws IOException {
if (controlConnection == null) {
@ -283,8 +275,7 @@ public abstract class OnionProxyManager {
* going to work until you either call startWithRepeat or
* installAndStartTorOp
*
* @throws java.io.IOException
* - File errors
* @throws java.io.IOException - File errors
*/
public synchronized void stop() throws IOException {
try {
@ -308,8 +299,7 @@ public abstract class OnionProxyManager {
* to network connections.
*
* @return True if running
* @throws java.io.IOException
* - IO exceptions
* @throws java.io.IOException - IO exceptions
*/
public synchronized boolean isRunning() throws IOException {
return isBootstrapped() && isNetworkEnabled();
@ -318,11 +308,9 @@ public abstract class OnionProxyManager {
/**
* Tells the Tor OP if it should accept network connections
*
* @param enable
* If true then the Tor OP will accept SOCKS connections,
* otherwise not.
* @throws java.io.IOException
* - IO exceptions
* @param enable If true then the Tor OP will accept SOCKS connections,
* otherwise not.
* @throws java.io.IOException - IO exceptions
*/
public synchronized void enableNetwork(boolean enable) throws IOException {
if (controlConnection == null) {
@ -336,9 +324,8 @@ public abstract class OnionProxyManager {
* Specifies if Tor OP is accepting network connections
*
* @return True if network is enabled (that doesn't mean that the device is
* online, only that the Tor OP is trying to connect to the network)
* @throws java.io.IOException
* - IO exceptions
* online, only that the Tor OP is trying to connect to the network)
* @throws java.io.IOException - IO exceptions
*/
public synchronized boolean isNetworkEnabled() throws IOException {
if (controlConnection == null) {
@ -391,10 +378,8 @@ public abstract class OnionProxyManager {
* to actually connect it to the network.
*
* @return True if all files installed and Tor OP successfully started
* @throws java.io.IOException
* - IO Exceptions
* @throws java.lang.InterruptedException
* - If we are, well, interrupted
* @throws java.io.IOException - IO Exceptions
* @throws java.lang.InterruptedException - If we are, well, interrupted
*/
public synchronized boolean installAndStartTorOp() throws IOException, InterruptedException {
// The Tor OP will die if it looses the connection to its socket so if
@ -598,8 +583,7 @@ public abstract class OnionProxyManager {
/**
* Alas old versions of Android do not support setExecutable.
*
* @param f
* File to make executable
* @param f File to make executable
* @return True if it worked, otherwise false.
*/
protected abstract boolean setExecutable(File f);

View File

@ -34,6 +34,7 @@ import java.util.Scanner;
public class OsData {
public enum OsType {Windows, Linux32, Linux64, Mac, Android}
private static OsType detectedType = null;
public static OsType getOsType() {
@ -50,7 +51,7 @@ public class OsData {
protected static OsType actualGetOsType() {
//This also works for ART
if (System.getProperty("java.vm.name").contains("Dalvik")) {
if (System.getProperty("java.vm.name").contains("Dalvik")) {
return OsType.Android;
}

View File

@ -22,8 +22,9 @@ import java.util.concurrent.TimeUnit;
public interface WriteObserver {
/**
* Waits timeout of unit to see if file is modified
*
* @param timeout How long to wait before returning
* @param unit Unit to wait in
* @param unit Unit to wait in
* @return True if file was modified, false if it was not
*/
boolean poll(long timeout, TimeUnit unit);

View File

@ -18,212 +18,212 @@ import java.util.concurrent.atomic.AtomicBoolean;
public abstract class Connection implements Closeable {
private static final Logger log = LoggerFactory.getLogger(Connection.class);
private static final Logger log = LoggerFactory.getLogger(Connection.class);
private final Socket socket;
private final ObjectOutputStream out;
private final ObjectInputStream in;
private final LinkedList<ConnectionListener> connectionListeners;
private final String peer;
private boolean running;
private final AtomicBoolean available;
private final AtomicBoolean listening;
private final Socket socket;
private final ObjectOutputStream out;
private final ObjectInputStream in;
private final LinkedList<ConnectionListener> connectionListeners;
private final String peer;
private boolean running;
private final AtomicBoolean available;
private final AtomicBoolean listening;
private final ExecutorService executorService;
private final InputStreamListener inputStreamListener;
private final ExecutorService executorService;
private final InputStreamListener inputStreamListener;
private final AtomicBoolean heartBeating;
private final AtomicBoolean heartBeating;
public Connection(String peer, Socket socket) throws IOException {
this(peer, socket, Node.prepareOOSForSocket(socket), new ObjectInputStream(socket.getInputStream()));
}
Connection(String peer, Socket socket, ObjectOutputStream out, ObjectInputStream in) {
log.debug("Initiating new connection");
this.available = new AtomicBoolean(false);
this.peer = peer;
this.socket = socket;
this.in = in;
this.out = out;
running = true;
listening = new AtomicBoolean(false);
heartBeating = new AtomicBoolean(false);
this.connectionListeners = new LinkedList<>();
this.inputStreamListener = new InputStreamListener();
executorService = Executors.newCachedThreadPool();
}
public abstract boolean isIncoming();
public void addMessageListener(ConnectionListener listener) {
synchronized (connectionListeners) {
connectionListeners.add(listener);
public Connection(String peer, Socket socket) throws IOException {
this(peer, socket, Node.prepareOOSForSocket(socket), new ObjectInputStream(socket.getInputStream()));
}
}
protected void setConnectionListeners(Collection<ConnectionListener> listeners) {
synchronized (listeners) {
this.connectionListeners.clear();
this.connectionListeners.addAll(listeners);
Connection(String peer, Socket socket, ObjectOutputStream out, ObjectInputStream in) {
log.debug("Initiating new connection");
this.available = new AtomicBoolean(false);
this.peer = peer;
this.socket = socket;
this.in = in;
this.out = out;
running = true;
listening = new AtomicBoolean(false);
heartBeating = new AtomicBoolean(false);
this.connectionListeners = new LinkedList<>();
this.inputStreamListener = new InputStreamListener();
executorService = Executors.newCachedThreadPool();
}
}
public void removeMessageListener(ConnectionListener listener) {
synchronized (connectionListeners) {
connectionListeners.remove(listener);
}
}
public abstract boolean isIncoming();
void sendMsg(Message msg) throws IOException {
out.writeObject(msg);
out.flush();
}
public void sendMessage(ContainerMessage msg) throws IOException {
if (!available.get())
throw new IOException("Connection is not yet available!");
sendMsg(msg);
}
protected void onMessage(Message msg) throws IOException {
log.debug("RXD: " + msg.toString());
if (msg instanceof ContainerMessage) {
synchronized (connectionListeners) {
for (ConnectionListener l : connectionListeners)
l.onMessage(this, (ContainerMessage) msg);
}
} else {
if (msg instanceof ControlMessage) {
switch ((ControlMessage) msg) {
case DISCONNECT:
close(false, PredefinedDisconnectReason.createReason(PredefinedDisconnectReason.CONNECTION_CLOSED, true));
break;
case AVAILABLE:
startHeartbeat();
onReady();
break;
default:
break;
public void addMessageListener(ConnectionListener listener) {
synchronized (connectionListeners) {
connectionListeners.add(listener);
}
}
}
}
protected void onReady() {
if (!available.getAndSet(true)) {
synchronized (connectionListeners) {
for (ConnectionListener l : connectionListeners) {
l.onReady(this);
protected void setConnectionListeners(Collection<ConnectionListener> listeners) {
synchronized (listeners) {
this.connectionListeners.clear();
this.connectionListeners.addAll(listeners);
}
}
}
}
protected abstract void onDisconnect();
private void onDisconn(DisconnectReason reason) {
onDisconnect();
synchronized (connectionListeners) {
for (ConnectionListener l : connectionListeners) {
l.onDisconnect(this, reason);
}
public void removeMessageListener(ConnectionListener listener) {
synchronized (connectionListeners) {
connectionListeners.remove(listener);
}
}
}
private void onTimeout() {
try {
close(false, PredefinedDisconnectReason.TIMEOUT);
} catch (IOException e1) {
void sendMsg(Message msg) throws IOException {
out.writeObject(msg);
out.flush();
}
}
protected void onError(Exception e) {
synchronized (connectionListeners) {
for (ConnectionListener l : connectionListeners) {
l.onError(this, new ConnectionException(e));
}
public void sendMessage(ContainerMessage msg) throws IOException {
if (!available.get())
throw new IOException("Connection is not yet available!");
sendMsg(msg);
}
}
public void close() throws IOException {
close(true, PredefinedDisconnectReason.createReason(PredefinedDisconnectReason.CONNECTION_CLOSED, false));
}
private void close(boolean graceful, DisconnectReason reason) throws IOException {
running = false;
onDisconn(reason);
if (graceful) {
try {
sendMsg(ControlMessage.DISCONNECT);
} catch (Exception e) {
onError(e);
}
}
out.close();
in.close();
socket.close();
}
public String getPeer() {
return peer;
}
void startHeartbeat() {
if (!heartBeating.getAndSet(true)) {
log.debug("Starting Heartbeat");
executorService.submit(new Runnable() {
public void run() {
try {
Thread.sleep(30000);
while (running) {
try {
log.debug("TX Heartbeat");
sendMsg(ControlMessage.HEARTBEAT);
Thread.sleep(30000);
} catch (IOException e) {
e.printStackTrace();
}
protected void onMessage(Message msg) throws IOException {
log.debug("RXD: " + msg.toString());
if (msg instanceof ContainerMessage) {
synchronized (connectionListeners) {
for (ConnectionListener l : connectionListeners)
l.onMessage(this, (ContainerMessage) msg);
}
} catch (InterruptedException e) {
}
}
});
}
}
public void listen() throws ConnectionException {
if (listening.getAndSet(true))
throw new ConnectionException("Already Listening!");
executorService.submit(inputStreamListener);
}
private class InputStreamListener implements Runnable {
@Override
public void run() {
while (running) {
try {
Message msg = (Message) in.readObject();
onMessage(msg);
} catch (ClassNotFoundException | IOException e) {
if (e instanceof SocketTimeoutException) {
onTimeout();
} else {
if (running) {
onError(new ConnectionException(e));
// TODO: Fault Tolerance?
if (e instanceof EOFException) {
try {
close(false, PredefinedDisconnectReason.RESET);
} catch (IOException e1) {
e1.printStackTrace();
} else {
if (msg instanceof ControlMessage) {
switch ((ControlMessage) msg) {
case DISCONNECT:
close(false, PredefinedDisconnectReason.createReason(PredefinedDisconnectReason.CONNECTION_CLOSED, true));
break;
case AVAILABLE:
startHeartbeat();
onReady();
break;
default:
break;
}
}
}
}
protected void onReady() {
if (!available.getAndSet(true)) {
synchronized (connectionListeners) {
for (ConnectionListener l : connectionListeners) {
l.onReady(this);
}
}
}
}
protected abstract void onDisconnect();
private void onDisconn(DisconnectReason reason) {
onDisconnect();
synchronized (connectionListeners) {
for (ConnectionListener l : connectionListeners) {
l.onDisconnect(this, reason);
}
}
}
private void onTimeout() {
try {
close(false, PredefinedDisconnectReason.TIMEOUT);
} catch (IOException e1) {
}
}
protected void onError(Exception e) {
synchronized (connectionListeners) {
for (ConnectionListener l : connectionListeners) {
l.onError(this, new ConnectionException(e));
}
}
}
public void close() throws IOException {
close(true, PredefinedDisconnectReason.createReason(PredefinedDisconnectReason.CONNECTION_CLOSED, false));
}
private void close(boolean graceful, DisconnectReason reason) throws IOException {
running = false;
onDisconn(reason);
if (graceful) {
try {
sendMsg(ControlMessage.DISCONNECT);
} catch (Exception e) {
onError(e);
}
}
out.close();
in.close();
socket.close();
}
public String getPeer() {
return peer;
}
void startHeartbeat() {
if (!heartBeating.getAndSet(true)) {
log.debug("Starting Heartbeat");
executorService.submit(new Runnable() {
public void run() {
try {
Thread.sleep(30000);
while (running) {
try {
log.debug("TX Heartbeat");
sendMsg(ControlMessage.HEARTBEAT);
Thread.sleep(30000);
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (InterruptedException e) {
}
}
});
}
}
public void listen() throws ConnectionException {
if (listening.getAndSet(true))
throw new ConnectionException("Already Listening!");
executorService.submit(inputStreamListener);
}
private class InputStreamListener implements Runnable {
@Override
public void run() {
while (running) {
try {
Message msg = (Message) in.readObject();
onMessage(msg);
} catch (ClassNotFoundException | IOException e) {
if (e instanceof SocketTimeoutException) {
onTimeout();
} else {
if (running) {
onError(new ConnectionException(e));
// TODO: Fault Tolerance?
if (e instanceof EOFException) {
try {
close(false, PredefinedDisconnectReason.RESET);
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
}
}
}
}
}
}
}
}
}

View File

@ -5,12 +5,12 @@ import io.nucleo.net.proto.exceptions.ConnectionException;
public interface ConnectionListener {
public abstract void onMessage(Connection con, ContainerMessage msg);
public abstract void onMessage(Connection con, ContainerMessage msg);
public void onDisconnect(Connection con, DisconnectReason reason);
public void onDisconnect(Connection con, DisconnectReason reason);
public void onError(Connection con, ConnectionException e);
public void onError(Connection con, ConnectionException e);
public void onReady(Connection con);
public void onReady(Connection con);
}

View File

@ -2,10 +2,10 @@ package io.nucleo.net;
public interface DisconnectReason {
public abstract String toString();
public abstract String toString();
public boolean isGraceful();
public boolean isGraceful();
public boolean isRemote();
public boolean isRemote();
}

View File

@ -29,363 +29,363 @@ import java.util.regex.Pattern;
public class Node {
/**
* Use this whenever to flush the socket header over the socket!
*
* @param socket the socket to construct an objectOutputStream from
* @return the outputstream from the socket
* @throws IOException in case something goes wrong, duh!
*/
static ObjectOutputStream prepareOOSForSocket(Socket socket) throws IOException {
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
/**
* Use this whenever to flush the socket header over the socket!
*
* @param socket the socket to construct an objectOutputStream from
* @return the outputstream from the socket
* @throws IOException in case something goes wrong, duh!
*/
static ObjectOutputStream prepareOOSForSocket(Socket socket) throws IOException {
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
out.flush();
return out;
}
private static final Logger log = LoggerFactory.getLogger(Node.class);
private final ServiceDescriptor descriptor;
private final HashMap<String, Connection> connections;
@SuppressWarnings("rawtypes")
private final TorNode tor;
private final AtomicBoolean serverRunning;
public Node(TCPServiceDescriptor descriptor) {
this(null, descriptor);
}
public Node(HiddenServiceDescriptor descriptor, TorNode<?, ?> tor) {
this(tor, descriptor);
}
private Node(TorNode<?, ?> tor, ServiceDescriptor descriptor) {
this.connections = new HashMap<>();
this.descriptor = descriptor;
this.tor = tor;
this.serverRunning = new AtomicBoolean(false);
}
public String getLocalName() {
return descriptor.getFullAddress();
}
public Connection connect(String peer, Collection<ConnectionListener> listeners)
throws NumberFormatException, IOException {
if (!serverRunning.get()) {
throw new IOException("This node has not been started yet!");
}
if (peer.equals(descriptor.getFullAddress()))
throw new IOException("If you find yourself talking to yourself too often, you should really seek help!");
synchronized (connections) {
if (connections.containsKey(peer))
throw new IOException("Already connected to " + peer);
out.flush();
return out;
}
final Socket sock = connectToService(peer);
return new OutgoingConnection(peer, sock, listeners);
}
private static final Logger log = LoggerFactory.getLogger(Node.class);
private Socket connectToService(String hostname, int port) throws IOException, UnknownHostException, SocketException {
final Socket sock;
if (tor != null)
sock = tor.connectToHiddenService(hostname, port);
else
sock = new Socket(hostname, port);
sock.setSoTimeout(60000);
return sock;
}
private final ServiceDescriptor descriptor;
private Socket connectToService(String peer) throws IOException, UnknownHostException, SocketException {
final String[] split = peer.split(Pattern.quote(":"));
return connectToService(split[0], Integer.parseInt(split[1]));
private final HashMap<String, Connection> connections;
}
@SuppressWarnings("rawtypes")
private final TorNode tor;
public synchronized Server startListening(ServerConnectListener listener) throws IOException {
if (serverRunning.getAndSet(true))
throw new IOException("This node is already listening!");
final Server server = new Server(descriptor.getServerSocket(), listener);
server.start();
return server;
}
private final AtomicBoolean serverRunning;
public Connection getConnection(String peerAddress) {
synchronized (connections) {
return connections.get(peerAddress);
}
}
public Set<Connection> getConnections() {
synchronized (connections) {
return new HashSet<Connection>(connections.values());
}
}
public class Server extends Thread {
private boolean running;
private final ServerSocket serverSocket;
private final ExecutorService executorService;
private final ServerConnectListener serverConnectListener;
private Server(ServerSocket serverSocket, ServerConnectListener listener) {
super("Server");
this.serverSocket = descriptor.getServerSocket();
this.serverConnectListener = listener;
running = true;
executorService = Executors.newCachedThreadPool();
public Node(TCPServiceDescriptor descriptor) {
this(null, descriptor);
}
public void shutdown() throws IOException {
running = false;
synchronized (connections) {
final Set<Connection> conns = new HashSet<Connection>(connections.values());
for (Connection con : conns) {
con.close();
public Node(HiddenServiceDescriptor descriptor, TorNode<?, ?> tor) {
this(tor, descriptor);
}
private Node(TorNode<?, ?> tor, ServiceDescriptor descriptor) {
this.connections = new HashMap<>();
this.descriptor = descriptor;
this.tor = tor;
this.serverRunning = new AtomicBoolean(false);
}
public String getLocalName() {
return descriptor.getFullAddress();
}
public Connection connect(String peer, Collection<ConnectionListener> listeners)
throws NumberFormatException, IOException {
if (!serverRunning.get()) {
throw new IOException("This node has not been started yet!");
}
}
serverSocket.close();
try {
executorService.awaitTermination(2, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
Node.this.serverRunning.set(false);
log.debug("Server successfully shutdown");
}
@Override
public void run() {
try {
while (running) {
final Socket socket = serverSocket.accept();
log.info("Accepting Client on port " + socket.getLocalPort());
executorService.submit(new Acceptor(socket));
if (peer.equals(descriptor.getFullAddress()))
throw new IOException("If you find yourself talking to yourself too often, you should really seek help!");
synchronized (connections) {
if (connections.containsKey(peer))
throw new IOException("Already connected to " + peer);
}
} catch (IOException e) {
if (running)
e.printStackTrace();
}
final Socket sock = connectToService(peer);
return new OutgoingConnection(peer, sock, listeners);
}
private boolean verifyIdentity(HELOMessage helo, ObjectInputStream in) throws IOException {
log.debug("Verifying HELO msg");
final Socket sock = connectToService(helo.getHostname(), helo.getPort());
log.debug("Connected to advertised client " + helo.getPeer());
ObjectOutputStream out = prepareOOSForSocket(sock);
final IDMessage challenge = new IDMessage(descriptor);
out.writeObject(challenge);
log.debug("Sent IDMessage to");
out.flush();
// wait for other side to close
try {
while (sock.getInputStream().read() != -1)
;
} catch (IOException e) {
// no matter
}
out.close();
sock.close();
log.debug("Closed socket after sending IDMessage");
try {
log.debug("Waiting for response of challenge");
IDMessage response = (IDMessage) in.readObject();
log.debug("Got response for challenge");
final boolean verified = challenge.verify(response);
log.debug("Response verified correctly!");
return verified;
} catch (ClassNotFoundException e) {
new ProtocolViolationException(e).printStackTrace();
}
return false;
private Socket connectToService(String hostname, int port) throws IOException, UnknownHostException, SocketException {
final Socket sock;
if (tor != null)
sock = tor.connectToHiddenService(hostname, port);
else
sock = new Socket(hostname, port);
sock.setSoTimeout(60000);
return sock;
}
private class Acceptor implements Runnable {
private Socket connectToService(String peer) throws IOException, UnknownHostException, SocketException {
final String[] split = peer.split(Pattern.quote(":"));
return connectToService(split[0], Integer.parseInt(split[1]));
private final Socket socket;
}
private Acceptor(Socket socket) {
this.socket = socket;
}
public synchronized Server startListening(ServerConnectListener listener) throws IOException {
if (serverRunning.getAndSet(true))
throw new IOException("This node is already listening!");
final Server server = new Server(descriptor.getServerSocket(), listener);
server.start();
return server;
}
@Override
public void run() {
{
try {
socket.setSoTimeout(60 * 1000);
} catch (SocketException e2) {
e2.printStackTrace();
public Connection getConnection(String peerAddress) {
synchronized (connections) {
return connections.get(peerAddress);
}
}
public Set<Connection> getConnections() {
synchronized (connections) {
return new HashSet<Connection>(connections.values());
}
}
public class Server extends Thread {
private boolean running;
private final ServerSocket serverSocket;
private final ExecutorService executorService;
private final ServerConnectListener serverConnectListener;
private Server(ServerSocket serverSocket, ServerConnectListener listener) {
super("Server");
this.serverSocket = descriptor.getServerSocket();
this.serverConnectListener = listener;
running = true;
executorService = Executors.newCachedThreadPool();
}
public void shutdown() throws IOException {
running = false;
synchronized (connections) {
final Set<Connection> conns = new HashSet<Connection>(connections.values());
for (Connection con : conns) {
con.close();
}
}
serverSocket.close();
try {
socket.close();
executorService.awaitTermination(2, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
Node.this.serverRunning.set(false);
log.debug("Server successfully shutdown");
}
@Override
public void run() {
try {
while (running) {
final Socket socket = serverSocket.accept();
log.info("Accepting Client on port " + socket.getLocalPort());
executorService.submit(new Acceptor(socket));
}
} catch (IOException e) {
if (running)
e.printStackTrace();
}
return;
}
}
ObjectInputStream objectInputStream = null;
ObjectOutputStream out = null;
private boolean verifyIdentity(HELOMessage helo, ObjectInputStream in) throws IOException {
log.debug("Verifying HELO msg");
final Socket sock = connectToService(helo.getHostname(), helo.getPort());
// get incoming data
try {
out = prepareOOSForSocket(socket);
objectInputStream = new ObjectInputStream(socket.getInputStream());
} catch (EOFException e) {
log.info("Got bogus incoming connection");
} catch (IOException e) {
e.printStackTrace();
log.debug("Connected to advertised client " + helo.getPeer());
ObjectOutputStream out = prepareOOSForSocket(sock);
final IDMessage challenge = new IDMessage(descriptor);
out.writeObject(challenge);
log.debug("Sent IDMessage to");
out.flush();
// wait for other side to close
try {
socket.close();
} catch (IOException e1) {
while (sock.getInputStream().read() != -1)
;
} catch (IOException e) {
// no matter
}
return;
}
out.close();
sock.close();
log.debug("Closed socket after sending IDMessage");
try {
log.debug("Waiting for response of challenge");
IDMessage response = (IDMessage) in.readObject();
log.debug("Got response for challenge");
final boolean verified = challenge.verify(response);
log.debug("Response verified correctly!");
return verified;
} catch (ClassNotFoundException e) {
new ProtocolViolationException(e).printStackTrace();
}
return false;
}
String peer = null;
try {
log.debug("Waiting for HELO or Identification");
final Message helo = (Message) objectInputStream.readObject();
if (helo instanceof HELOMessage) {
peer = ((HELOMessage) helo).getPeer();
log.debug("Got HELO from " + peer);
boolean alreadyConnected;
synchronized (connections) {
alreadyConnected = connections.containsKey(peer);
}
if (alreadyConnected || !verifyIdentity((HELOMessage) helo, objectInputStream)) {
log.debug(alreadyConnected ? ("already connected to " + peer) : "verification failed");
out.writeObject(alreadyConnected ? ControlMessage.ALREADY_CONNECTED : ControlMessage.HANDSHAKE_FAILED);
out.writeObject(ControlMessage.DISCONNECT);
out.flush();
out.close();
objectInputStream.close();
socket.close();
return;
}
log.debug("Verification of " + peer + " successful");
} else if (helo instanceof IDMessage) {
peer = ((IDMessage) helo).getPeer();
log.debug("got IDMessage from " + peer);
final Connection client = connections.get(peer);
if (client != null) {
log.debug("Got preexisting connection for " + peer);
client.sendMsg(((IDMessage) helo).reply());
log.debug("Sent response for challenge");
} else {
log.debug("Got IDMessage for unknown connection to " + peer);
}
out.flush();
out.close();
objectInputStream.close();
socket.close();
log.debug("Closed socket for identification");
return;
private class Acceptor implements Runnable {
private final Socket socket;
private Acceptor(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
{
try {
socket.setSoTimeout(60 * 1000);
} catch (SocketException e2) {
e2.printStackTrace();
try {
socket.close();
} catch (IOException e) {
}
return;
}
ObjectInputStream objectInputStream = null;
ObjectOutputStream out = null;
// get incoming data
try {
out = prepareOOSForSocket(socket);
objectInputStream = new ObjectInputStream(socket.getInputStream());
} catch (EOFException e) {
log.info("Got bogus incoming connection");
} catch (IOException e) {
e.printStackTrace();
try {
socket.close();
} catch (IOException e1) {
}
return;
}
String peer = null;
try {
log.debug("Waiting for HELO or Identification");
final Message helo = (Message) objectInputStream.readObject();
if (helo instanceof HELOMessage) {
peer = ((HELOMessage) helo).getPeer();
log.debug("Got HELO from " + peer);
boolean alreadyConnected;
synchronized (connections) {
alreadyConnected = connections.containsKey(peer);
}
if (alreadyConnected || !verifyIdentity((HELOMessage) helo, objectInputStream)) {
log.debug(alreadyConnected ? ("already connected to " + peer) : "verification failed");
out.writeObject(alreadyConnected ? ControlMessage.ALREADY_CONNECTED : ControlMessage.HANDSHAKE_FAILED);
out.writeObject(ControlMessage.DISCONNECT);
out.flush();
out.close();
objectInputStream.close();
socket.close();
return;
}
log.debug("Verification of " + peer + " successful");
} else if (helo instanceof IDMessage) {
peer = ((IDMessage) helo).getPeer();
log.debug("got IDMessage from " + peer);
final Connection client = connections.get(peer);
if (client != null) {
log.debug("Got preexisting connection for " + peer);
client.sendMsg(((IDMessage) helo).reply());
log.debug("Sent response for challenge");
} else {
log.debug("Got IDMessage for unknown connection to " + peer);
}
out.flush();
out.close();
objectInputStream.close();
socket.close();
log.debug("Closed socket for identification");
return;
} else
throw new ClassNotFoundException("First Message was neither HELO, nor ID");
} catch (ClassNotFoundException e) {
new ProtocolViolationException(e);
} catch (IOException e) {
try {
objectInputStream.close();
out.close();
socket.close();
} catch (IOException e1) {
}
return;
}
// Here we go
log.debug("Incoming Connection ready!");
try {
// TODO: listeners are only added afterwards, so messages can be lost!
IncomingConnection incomingConnection = new IncomingConnection(peer, socket, out, objectInputStream);
serverConnectListener.onConnect(incomingConnection);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
private class IncomingConnection extends Connection {
private IncomingConnection(String peer, Socket socket, ObjectOutputStream out, ObjectInputStream in)
throws IOException {
super(peer, socket, out, in);
synchronized (connections) {
connections.put(peer, this);
}
sendMsg(ControlMessage.AVAILABLE);
}
@Override
public void listen() throws ConnectionException {
super.listen();
onReady();
}
@Override
protected void onMessage(Message msg) throws IOException {
if ((msg instanceof ControlMessage) && (ControlMessage.HEARTBEAT == msg)) {
log.debug("RX+REPLY HEARTBEAT");
try {
sendMsg(ControlMessage.HEARTBEAT);
} catch (IOException e) {
onError(e);
}
} else
throw new ClassNotFoundException("First Message was neither HELO, nor ID");
} catch (ClassNotFoundException e) {
new ProtocolViolationException(e);
} catch (IOException e) {
try {
objectInputStream.close();
out.close();
socket.close();
} catch (IOException e1) {
super.onMessage(msg);
}
@Override
public void onDisconnect() {
synchronized (connections) {
connections.remove(getPeer());
}
return;
}
// Here we go
log.debug("Incoming Connection ready!");
try {
// TODO: listeners are only added afterwards, so messages can be lost!
IncomingConnection incomingConnection = new IncomingConnection(peer, socket, out, objectInputStream);
serverConnectListener.onConnect(incomingConnection);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
private class IncomingConnection extends Connection {
private IncomingConnection(String peer, Socket socket, ObjectOutputStream out, ObjectInputStream in)
throws IOException {
super(peer, socket, out, in);
synchronized (connections) {
connections.put(peer, this);
}
sendMsg(ControlMessage.AVAILABLE);
}
@Override
public void listen() throws ConnectionException {
super.listen();
onReady();
}
@Override
protected void onMessage(Message msg) throws IOException {
if ((msg instanceof ControlMessage) && (ControlMessage.HEARTBEAT == msg)) {
log.debug("RX+REPLY HEARTBEAT");
try {
sendMsg(ControlMessage.HEARTBEAT);
} catch (IOException e) {
onError(e);
@Override
public boolean isIncoming() {
return true;
}
} else
super.onMessage(msg);
}
@Override
public void onDisconnect() {
synchronized (connections) {
connections.remove(getPeer());
}
private class OutgoingConnection extends Connection {
private OutgoingConnection(String peer, Socket socket, Collection<ConnectionListener> listeners)
throws IOException {
super(peer, socket);
synchronized (connections) {
connections.put(peer, this);
}
setConnectionListeners(listeners);
try {
listen();
} catch (ConnectionException e) {
// Never happens
}
log.debug("Sending HELO");
sendMsg(new HELOMessage(descriptor));
log.debug("Sent HELO");
}
@Override
public void onDisconnect() {
synchronized (connections) {
connections.remove(getPeer());
}
}
@Override
public boolean isIncoming() {
return false;
}
}
@Override
public boolean isIncoming() {
return true;
}
}
private class OutgoingConnection extends Connection {
private OutgoingConnection(String peer, Socket socket, Collection<ConnectionListener> listeners)
throws IOException {
super(peer, socket);
synchronized (connections) {
connections.put(peer, this);
}
setConnectionListeners(listeners);
try {
listen();
} catch (ConnectionException e) {
// Never happens
}
log.debug("Sending HELO");
sendMsg(new HELOMessage(descriptor));
log.debug("Sent HELO");
}
@Override
public void onDisconnect() {
synchronized (connections) {
connections.remove(getPeer());
}
}
@Override
public boolean isIncoming() {
return false;
}
}
}

View File

@ -1,52 +1,52 @@
package io.nucleo.net;
public enum PredefinedDisconnectReason implements DisconnectReason {
TIMEOUT("due to timed out", false, true),
CONNECTION_CLOSED("as ordered", true),
RESET("due to remote reset (EOF)", false, true),
UNKNOWN("for unknown reasons", false);
TIMEOUT("due to timed out", false, true),
CONNECTION_CLOSED("as ordered", true),
RESET("due to remote reset (EOF)", false, true),
UNKNOWN("for unknown reasons", false);
private Boolean remote;
private final boolean graceful;
private final String description;
private Boolean remote;
private final boolean graceful;
private final String description;
private PredefinedDisconnectReason(String description, boolean graceful) {
this.description = description;
this.graceful = graceful;
}
private PredefinedDisconnectReason(String description, boolean graceful) {
this.description = description;
this.graceful = graceful;
}
private PredefinedDisconnectReason(String description, boolean graceful, boolean remote) {
this.description = description;
this.graceful = graceful;
this.remote = remote;
}
private PredefinedDisconnectReason(String description, boolean graceful, boolean remote) {
this.description = description;
this.graceful = graceful;
this.remote = remote;
}
public static PredefinedDisconnectReason createReason(PredefinedDisconnectReason reason, boolean remote) {
reason.remote = remote;
return reason;
}
public static PredefinedDisconnectReason createReason(PredefinedDisconnectReason reason, boolean remote) {
reason.remote = remote;
return reason;
}
@Override
public boolean isGraceful() {
return graceful;
}
@Override
public boolean isGraceful() {
return graceful;
}
@Override
public boolean isRemote() {
if (remote == null)
return false;
return remote;
@Override
public boolean isRemote() {
if (remote == null)
return false;
return remote;
}
}
public String toString() {
StringBuilder bld = new StringBuilder("Connection closed ");
if (remote != null)
bld.append(remote ? "remotely " : "locally ");
bld.append(description).append(" (");
bld.append(graceful ? "graceful" : "irregular").append(" disconnect)");
return bld.toString();
public String toString() {
StringBuilder bld = new StringBuilder("Connection closed ");
if (remote != null)
bld.append(remote ? "remotely " : "locally ");
bld.append(description).append(" (");
bld.append(graceful ? "graceful" : "irregular").append(" disconnect)");
return bld.toString();
}
}
}

View File

@ -2,11 +2,11 @@ package io.nucleo.net;
public interface ServerConnectListener {
/**
* Called whenever an incoming connection was set up properly.
* Connection.listen() needs to be called ASAP for the connection to become available
*
* @param con the newly established connection
*/
public void onConnect(Connection con);
/**
* Called whenever an incoming connection was set up properly.
* Connection.listen() needs to be called ASAP for the connection to become available
*
* @param con the newly established connection
*/
public void onConnect(Connection con);
}

View File

@ -5,14 +5,14 @@ import java.io.Serializable;
public class ContainerMessage implements Message {
private static final long serialVersionUID = 9219884444024922023L;
private final Serializable payload;
private static final long serialVersionUID = 9219884444024922023L;
private final Serializable payload;
public ContainerMessage(Serializable payload) {
this.payload = payload;
}
public ContainerMessage(Serializable payload) {
this.payload = payload;
}
public Serializable getPayload() {
return payload;
}
public Serializable getPayload() {
return payload;
}
}

View File

@ -1,9 +1,9 @@
package io.nucleo.net.proto;
public enum ControlMessage implements Message {
HEARTBEAT,
AVAILABLE,
HANDSHAKE_FAILED,
ALREADY_CONNECTED,
DISCONNECT;
HEARTBEAT,
AVAILABLE,
HANDSHAKE_FAILED,
ALREADY_CONNECTED,
DISCONNECT;
}

View File

@ -6,30 +6,30 @@ import java.util.regex.Pattern;
public class HELOMessage implements Message {
private static final long serialVersionUID = -4582946298578924930L;
private final String peer;
private static final long serialVersionUID = -4582946298578924930L;
private final String peer;
public HELOMessage(ServiceDescriptor descriptor) {
this(descriptor.getFullAddress());
}
public HELOMessage(ServiceDescriptor descriptor) {
this(descriptor.getFullAddress());
}
private HELOMessage(String peer) {
this.peer = peer;
}
private HELOMessage(String peer) {
this.peer = peer;
}
public String getPeer() {
return peer;
}
public String getPeer() {
return peer;
}
public String getHostname() {
return peer.split(Pattern.quote(":"))[0];
}
public String getHostname() {
return peer.split(Pattern.quote(":"))[0];
}
public int getPort() {
return Integer.parseInt(peer.split(Pattern.quote(":"))[1]);
}
public int getPort() {
return Integer.parseInt(peer.split(Pattern.quote(":"))[1]);
}
public String toString() {
return "HELO " + peer;
}
public String toString() {
return "HELO " + peer;
}
}

View File

@ -7,42 +7,42 @@ import java.security.SecureRandom;
public class IDMessage implements Message {
private static final long serialVersionUID = -2214485311644580948L;
private static SecureRandom rnd;
private static final long serialVersionUID = -2214485311644580948L;
private static SecureRandom rnd;
static {
try {
rnd = SecureRandom.getInstance("SHA1PRNG");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
static {
try {
rnd = SecureRandom.getInstance("SHA1PRNG");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
}
private final String id;
private final long nonce;
private final String id;
private final long nonce;
public IDMessage(ServiceDescriptor descriptor) {
this(descriptor.getFullAddress(), rnd.nextLong());
}
public IDMessage(ServiceDescriptor descriptor) {
this(descriptor.getFullAddress(), rnd.nextLong());
}
private IDMessage(String id, long nonce) {
this.id = id;
this.nonce = nonce;
}
private IDMessage(String id, long nonce) {
this.id = id;
this.nonce = nonce;
}
public String getPeer() {
return id;
}
public String getPeer() {
return id;
}
public IDMessage reply() {
return new IDMessage(id, nonce);
}
public IDMessage reply() {
return new IDMessage(id, nonce);
}
public boolean verify(IDMessage msg) {
return id.equals(msg.id) && (nonce == msg.nonce);
}
public boolean verify(IDMessage msg) {
return id.equals(msg.id) && (nonce == msg.nonce);
}
public String toString() {
return "ID " + id;
}
public String toString() {
return "ID " + id;
}
}

View File

@ -1,16 +1,16 @@
package io.nucleo.net.proto.exceptions;
public class ConnectionException extends Exception {
public ConnectionException(String msg) {
super(msg);
}
public ConnectionException(String msg) {
super(msg);
}
public ConnectionException(Throwable cause) {
super(cause);
}
public ConnectionException(Throwable cause) {
super(cause);
}
public ConnectionException(String msg, Throwable cause) {
super(msg, cause);
}
public ConnectionException(String msg, Throwable cause) {
super(msg, cause);
}
}

View File

@ -2,18 +2,18 @@ package io.nucleo.net.proto.exceptions;
public class ProtocolViolationException extends Exception {
public ProtocolViolationException() {
}
public ProtocolViolationException() {
}
public ProtocolViolationException(Throwable cause) {
super(cause);
}
public ProtocolViolationException(Throwable cause) {
super(cause);
}
public ProtocolViolationException(String msg) {
super(msg);
}
public ProtocolViolationException(String msg) {
super(msg);
}
public ProtocolViolationException(String msg, Throwable cause) {
super(msg, cause);
}
public ProtocolViolationException(String msg, Throwable cause) {
super(msg, cause);
}
}

View File

@ -24,7 +24,7 @@ public class Utils {
return port;
} catch (IOException ignored) {
return new Random().nextInt(10000) + 50000;
}
}
}
public static byte[] compress(Serializable input) {

View File

@ -23,7 +23,7 @@ public class SeedNodeRequestDataManager extends RequestDataManager {
if (dataStorage.getMap().isEmpty()) {
if (requestDataFromAuthenticatedSeedNodeTimer == null)
requestDataFromAuthenticatedSeedNodeTimer = UserThread.runAfterRandomDelay(()
-> requestDataFromAuthenticatedSeedNode(peerAddress, connection), 2, 5, TimeUnit.SECONDS);
-> requestDataFromAuthenticatedSeedNode(peerAddress, connection), 2, 5, TimeUnit.SECONDS);
}
super.onPeerAuthenticated(peerAddress, connection);
}

View File

@ -10,7 +10,7 @@ public final class DataResponse implements Message {
// That object is sent over the wire, so we need to take care of version compatibility.
private static final long serialVersionUID = Version.NETWORK_PROTOCOL_VERSION;
private final int networkId = Version.getNetworkId();
public final HashSet<ProtectedData> set;
public DataResponse(HashSet<ProtectedData> set) {

View File

@ -60,7 +60,7 @@ public class P2PDataStorage implements MessageListener {
storage = new Storage<>(storageDir);
removeExpiredEntriesExecutor = Utilities.getScheduledThreadPoolExecutor("removeExpiredEntries", 1, 10, 5);
init();
}

View File

@ -44,6 +44,7 @@ public class P2PServiceTest {
private P2PService p2PService1, p2PService2, p2PService3;
private SeedNode seedNode1, seedNode2, seedNode3;
private File dir1, dir2, dir3;
@Before
public void setup() throws InterruptedException, CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException, CryptoException {
Security.addProvider(new BouncyCastleProvider());

View File

@ -40,7 +40,8 @@
<!-- broken with Java 8 (MSHADE-174), using ProGuard instead. -->
<minimizeJar>false</minimizeJar>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>io.bitsquare.p2p.seed.SeedNodeMain</mainClass>
</transformer>
</transformers>