now building with i2p version 0.9.39

wait for i2p router to fully start before attempting to build tunnels
version check implemented, which will run at random intervals (on average every 24hrs)
eepsite config settings save fix
This commit is contained in:
knaccc
2019-03-23 16:54:52 +00:00
parent a31043863a
commit f9208da8f7
8 changed files with 151 additions and 8 deletions
+1
View File
@@ -11,6 +11,7 @@ source "$basedir/bin/java-config.sh"
echo "*** Compiling CLI"
"$JAVA_HOME"/bin/javac --module-path target/modules/combined.jar -d target/classes/org.getmonero.i2p.zero $(find org.getmonero.i2p.zero/src -name '*.java')
cp org.getmonero.i2p.zero/src/org/getmonero/i2p/zero/VERSION target/classes/org.getmonero.i2p.zero/org/getmonero/i2p/zero/
echo "*** Packaging CLI as a modular jar"
"$JAVA_HOME"/bin/jar --create --file target/org.getmonero.i2p.zero.jar --main-class org.getmonero.i2p.zero.Main -C target/classes/org.getmonero.i2p.zero .
+1 -1
View File
@@ -17,7 +17,7 @@ fi
cd "$basedir/import/i2p.i2p"
git fetch
git checkout tags/i2p-0.9.38
git checkout tags/i2p-0.9.39
cd ..
if [ ! -d "$basedir/import/jdks" ]; then
@@ -4,26 +4,37 @@ import javafx.application.Platform;
import javafx.beans.binding.DoubleBinding;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import javafx.stage.DirectoryChooser;
import javafx.stage.Modality;
import javafx.stage.Stage;
import org.getmonero.i2p.zero.RouterWrapper;
import org.getmonero.i2p.zero.TunnelControl;
import org.getmonero.i2p.zero.UpdateCheck;
import static org.getmonero.i2p.zero.TunnelControl.*;
import java.awt.*;
import java.io.File;
import java.net.URI;
import java.text.DecimalFormat;
import java.util.Optional;
import java.util.Properties;
@@ -70,6 +81,7 @@ public class Controller {
@FXML private CheckBox eepSiteEnableLogsCheckbox;
@FXML private CheckBox eepSiteAllowDirBrowsingCheckbox;
@FXML private TextField eepSiteLocalPortField;
@FXML private TextArea helpTextArea;
DecimalFormat format2dp = new DecimalFormat("0.00");
@@ -84,6 +96,8 @@ public class Controller {
@FXML private void initialize() {
helpTextArea.setText("You are running I2P-zero version " + UpdateCheck.currentVersion + "\n\n" + helpTextArea.getText());
DirectoryChooser directoryChooser = new DirectoryChooser();
typeCol.setCellValueFactory(new PropertyValueFactory<Tunnel,String>("type"));
@@ -157,27 +171,31 @@ public class Controller {
// modifying eepSiteSecretKeyField/eepSiteLocalPortField will require the eepsite tunnel to be destroyed
// and later recreated whenever the user is finished editing settings and ticks the enabled box again
eepSiteSecretKeyField.textProperty().addListener((observable, oldValue, newValue) -> {
eepSiteEnableCheckbox.setSelected(false);
eepSiteAddrField.setText("");
String key = newValue;
if(key!=null && !key.isEmpty()) {
try {
eepSiteAddrField.setText("http://" + new TunnelControl.KeyPair(key).b32Dest);
KeyPair keyPair = new TunnelControl.KeyPair(key);
eepSiteAddrField.setText("http://" + keyPair.b32Dest);
getEepSiteTunnel().dest = keyPair.b32Dest;
getEepSiteTunnel().keyPair = keyPair;
save();
}
catch (Exception e2) {
// ignore exception. user may be part way through entering string
}
eepSiteEnableCheckbox.setSelected(false);
}
});
eepSiteGenButton.setOnAction(ev->{
getEepSiteTunnel().keyPair = KeyPair.gen();
save();
eepSiteSecretKeyField.setText(getEepSiteTunnel().keyPair.toString());
});
eepSiteLocalPortField.textProperty().addListener((ov, oldValue, newValue)->{
eepSiteEnableCheckbox.setSelected(false);
getEepSiteTunnel().port = Integer.parseInt(newValue);
save();
eepSiteEnableCheckbox.setSelected(false);
});
eepSiteEnableCheckbox.selectedProperty().addListener((ov, oldValue, newValue)->{
@@ -317,7 +335,35 @@ public class Controller {
Properties routerProperties = new Properties();
routerProperties.put("router.sharePercentage", 80);
params.entrySet().stream().forEach(e->routerProperties.put(e.getKey(), e.getValue()));
routerWrapper = new RouterWrapper(routerProperties);
routerWrapper = new RouterWrapper(routerProperties, ()-> {
Platform.runLater(()->{
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle("Update available");
alert.setHeaderText(null);
FlowPane fp = new FlowPane();
String updateUrl = "https://github.com/i2p-zero/i2p-zero";
var link = new Hyperlink(updateUrl);
TextFlow textFlow = new TextFlow(
new Text("A new version of I2P-zero is available at"),
link,
new Text("\nPlease keep your software up-to-date, as it will enhance your privacy and keep you safe from vulnerabilities")
);
textFlow.setPrefWidth(300);
link.setOnAction((ActionEvent event) -> {
try {
Desktop.getDesktop().browse(new URI(updateUrl));
}
catch (Exception e) {
e.printStackTrace();
}
});
fp.getChildren().addAll(textFlow);
alert.getDialogPane().contentProperty().set(fp);
alert.show();
});
});
routerWrapper.start();
}
@@ -148,7 +148,7 @@
<content>
<BorderPane>
<center>
<TextArea fx:id="helpTextArea" editable="false" text="I2P hides your IP address when you connect to other I2P destinations.&#10;&#10;Note that when you first start I2P, it will take a minute to warm up and establish any pre-configured tunnels.&#10;&#10;To browse I2P web sites, in the tunnels tab ensure you have your HTTP proxy running, and configure your web browser to it (usually in your browser's preferences/proxy settings). You can then access I2P websites such as http://i2pwiki.i2p&#10;&#10;You can also easily set up your own I2P website (also known as an EepSite).&#10;&#10;I2P-zero can also be used to let other applications, such as a cryptocurrency wallet, to access the I2P network. For example, if you are using a Monero wallet, your transactions will be announced over I2P instead of over the regular internet. This means that none of the other Monero I2P nodes will be able to know your IP address.&#10;&#10;I2P achives privacy by routing your traffic through a chain of other I2P nodes. None of the nodes between you and your final destination will be able to tell whether the next node in the chain is your final destination or just another link in the chain.&#10;&#10;The nodes you connect to will not know whether you are originating a tunnel, or whether you're simply acting as a link in the chain of somebody else's tunnel. &#10;&#10;I2P automatically encrypts all traffic, so no node will be able to know what kind of traffic it is forwarding on behalf of others. This means that when you participate in the I2P network, it is impossible for you to spy on the traffic of other I2P users.&#10;&#10;For more information, visit https://geti2p.net" wrapText="true" BorderPane.alignment="CENTER">
<TextArea fx:id="helpTextArea" editable="false" text="I2P hides your IP address when you connect to other I2P destinations.&#10;&#10;Note that when you first start I2P, it will take a minute to warm up and establish any pre-configured tunnels.&#10;&#10;To browse I2P web sites, in the tunnels tab ensure you have your HTTP proxy running, and configure your web browser to it (usually in your browser's preferences/proxy settings). You can then access I2P websites such as http://i2pwiki.i2p&#10;&#10;You can also easily set up your own I2P website (also known as an EepSite).&#10;&#10;I2P-zero can also be used to let other applications, such as a cryptocurrency wallet, to access the I2P network. For example, if you are using a Monero wallet, your transactions will be announced over I2P instead of over the regular internet. This means that none of the other Monero I2P nodes will be able to know your IP address.&#10;&#10;I2P achives privacy by routing your traffic through a chain of other I2P nodes. None of the nodes between you and your final destination will be able to tell whether the next node in the chain is your final destination or just another link in the chain.&#10;&#10;The nodes you connect to will not know whether you are originating a tunnel, or whether you're simply acting as a link in the chain of somebody else's tunnel. &#10;&#10;I2P automatically encrypts all traffic, so no node will be able to know what kind of traffic it is forwarding on behalf of others. This means that when you participate in the I2P network, it is impossible for you to spy on the traffic of other I2P users.&#10;" wrapText="true" BorderPane.alignment="CENTER">
<BorderPane.margin>
<Insets />
</BorderPane.margin>
@@ -1,12 +1,18 @@
package org.getmonero.i2p.zero;
import java.io.PrintStream;
import java.util.Properties;
import java.util.stream.Collectors;
public class Main {
public static PrintStream consoleOut = null;
public static void main(String[] args) {
// since i2p redirects system output, keep a reference to the console out
consoleOut = System.out;
if(TunnelControl.isPortInUse()) {
System.out.println("I2P-zero already running");
System.exit(1);
@@ -31,7 +37,9 @@ public class Main {
System.out.println("Options set: "
+ p.entrySet().stream().map(e->"--"+e.getKey()+"="+e.getValue()).collect(Collectors.joining(" ")));
RouterWrapper routerWrapper = new RouterWrapper(p);
RouterWrapper routerWrapper = new RouterWrapper(p, ()->{
Main.consoleOut.println("**** A new version of I2P-zero is available at https://github.com/i2p-zero/i2p-zero - Please keep your software up-to-date, as it will enhance your privacy and keep you safe from vulnerabilities");
});
routerWrapper.start();
Runtime.getRuntime().addShutdownHook(new Thread(()->routerWrapper.stop(true)));
@@ -27,9 +27,11 @@ public class RouterWrapper {
private TunnelControl tunnelControl;
private File i2PConfigDir;
private File i2PBaseDir;
private Runnable updateAvailableCallback;
public RouterWrapper(Properties routerProperties) {
public RouterWrapper(Properties routerProperties, Runnable updateAvailableCallback) {
this.routerProperties = routerProperties;
this.updateAvailableCallback = updateAvailableCallback;
if(!routerProperties.contains("i2p.dir.base.template")) {
routerProperties.put("i2p.dir.base.template", new File(new File(System.getProperty("java.home")), "i2p.base").getAbsolutePath());
@@ -95,9 +97,13 @@ public class RouterWrapper {
}
}
System.out.println("I2P router now running");
tunnelControl = new TunnelControl(this, i2PConfigDir, new File(i2PConfigDir, "tunnelTemp"));
new Thread(tunnelControl).start();
UpdateCheck.scheduleUpdateCheck(i2PConfigDir, router, updateAvailableCallback);
}
catch (Exception e) {
e.printStackTrace();
@@ -0,0 +1,81 @@
package org.getmonero.i2p.zero;
import net.i2p.client.streaming.I2PSocket;
import net.i2p.client.streaming.I2PSocketManager;
import net.i2p.client.streaming.I2PSocketManagerFactory;
import net.i2p.data.Destination;
import net.i2p.router.Router;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Scanner;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
public class UpdateCheck {
public static final String currentVersion = new Scanner(RouterWrapper.class.getResourceAsStream("VERSION")).useDelimiter("\\n").next();
public static void scheduleUpdateCheck(File i2PConfigDir, Router router, Runnable updateAvailableCallback) {
File updateAvailableFile = new File(i2PConfigDir, "updateAvailable");
if(updateAvailableFile.exists()) {
updateAvailableCallback.run();
}
else {
// schedule next check randomly in the next 48 hrs. On average, this call pattern will result in a check every 24 hrs.
CompletableFuture.delayedExecutor((long) (Math.random()*3600*24*2), TimeUnit.SECONDS).execute(() -> {
if(lookupUpdateAvailable(router)) {
try {
// create an empty file to indicate an update is available, so in future we don't have to keep querying the server
updateAvailableFile.createNewFile();
}
catch (Exception e) {
e.printStackTrace();
}
updateAvailableCallback.run();
}
else {
// only check again if no update available yet
scheduleUpdateCheck(i2PConfigDir, router, updateAvailableCallback);
}
});
}
}
public static boolean lookupUpdateAvailable(Router router) {
try {
String versionAvailable = null;
String host = "77ypf3rahyjegncradypnyotvn6fhq7sobhwe2gs5a2hdiwehwjq.b32.i2p";
Destination dest = router.getContext().namingService().lookup(host, null, null);
I2PSocketManager mgr = I2PSocketManagerFactory.createManager();
I2PSocket socket = mgr.connect(dest);
PrintWriter pw = new PrintWriter(socket.getOutputStream());
pw.print("GET /VERSION HTTP/1.1\r\n");
pw.print("Host: " + host + "\r\n\r\n");
pw.flush();
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String status = br.readLine();
if (status.equals("HTTP/1.1 200 OK")) {
String line;
while ((line = br.readLine()) != null) {
if (line.equals("")) break;
}
versionAvailable = br.readLine();
}
br.close();
if(versionAvailable==null) return false;
else return Float.parseFloat(currentVersion)<Float.parseFloat(versionAvailable);
}
catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
@@ -0,0 +1 @@
1.2