diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHandler.java
index cf1caf99b0b9171c28d06d680e12566cced25968..3561def5842863e0b02b15b474c99212bd2b3841 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHandler.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHandler.java
@@ -49,6 +49,7 @@ public class ConfigNetHandler extends FormHandler {
     private boolean _enableLoadTesting;
     private String _sharePct;
     private boolean _ratesOnly;
+    private boolean _udpDisabled;
     private final Map<String, String> changes = new HashMap();
     private static final String PROP_HIDDEN = Router.PROP_HIDDEN_HIDDEN; // see Router for other choice
     
@@ -130,6 +131,11 @@ public class ConfigNetHandler extends FormHandler {
         _ratesOnly = true;
     }
     
+    /** @since 0.8.13 */
+    public void setDisableUDP(String foo) {
+        _udpDisabled = true;
+    }
+    
     private void recheckReachability() {
         _context.commSystem().recheckReachability();
         addFormNotice(_("Rechecking router reachability..."));
@@ -270,6 +276,16 @@ public class ConfigNetHandler extends FormHandler {
             }
             changes.put(UDPTransport.PROP_LAPTOP_MODE, "" + _laptop);
 
+            if (_context.getBooleanPropertyDefaultTrue(TransportManager.PROP_ENABLE_UDP) !=
+                !_udpDisabled) {
+                if (_udpDisabled)
+                    addFormNotice(_("Disabling UDP"));
+                else
+                    addFormNotice(_("Enabling UDP"));
+                restartRequired = true;
+            }
+            changes.put(TransportManager.PROP_ENABLE_UDP, "" + (!_udpDisabled));
+
             if (_requireIntroductions) {
                 changes.put(UDPTransport.PROP_FORCE_INTRODUCERS, "true");
                 addFormNotice(_("Requiring SSU introducers"));
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHelper.java
index fdbe77f9edc8570154207dccef35f0389c628ff3..e9d3b152992bedb6af17eef8937bf65024edf6fd 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHelper.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHelper.java
@@ -135,6 +135,16 @@ public class ConfigNetHelper extends HelperBase {
         return "";
     }
 
+    /**
+     * default false, inverse of default true property
+     * @since 0.8.13
+     */
+    public String getUdpDisabledChecked() {
+        if (!_context.getBooleanPropertyDefaultTrue(TransportManager.PROP_ENABLE_UDP))
+            return CHECKED;
+        return "";
+    }
+
     public String getRequireIntroductionsChecked() {
         short status = _context.commSystem().getReachabilityStatus();
         switch (status) {
diff --git a/apps/routerconsole/jsp/confignet.jsp b/apps/routerconsole/jsp/confignet.jsp
index d11dfba91d3572d34191669d8e1b92166d11d608..59b3f27d336121130407c1a7ba66429a39819d61 100644
--- a/apps/routerconsole/jsp/confignet.jsp
+++ b/apps/routerconsole/jsp/confignet.jsp
@@ -68,6 +68,8 @@
  </p><p><b><%=intl._("UDP Configuration:")%></b><br>
  <%=intl._("UDP port:")%>
  <input name ="udpPort" type="text" size="5" maxlength="5" value="<jsp:getProperty name="nethelper" property="configuredUdpPort" />" ><br>
+ <input type="checkbox" class="optbox" name="disableUDP" value="disabled" <%=nethelper.getUdpDisabledChecked() %> >
+ <%=intl._("Completely disable")%> <i><%=intl._("(select only if behind a firewall that blocks outbound UDP)")%></i><br>
 <% /********
 <!-- let's keep this simple...
 <input type="checkbox" class="optbox" name="requireIntroductions" value="true" <jsp:getProperty name="nethelper" property="requireIntroductionsChecked" /> />
diff --git a/apps/sam/java/build.xml b/apps/sam/java/build.xml
index 4433c057543ae511bb5b7a83a20ee29169507fbd..849fbd55d74830eb90573e1f601af9c1b4bf79d5 100644
--- a/apps/sam/java/build.xml
+++ b/apps/sam/java/build.xml
@@ -21,7 +21,10 @@
             </classpath>
         </depend>
     </target>
+
     <property name="javac.compilerargs" value="" />
+
+    <!-- compile everything including client classes -->
     <target name="compile" depends="depend">
         <mkdir dir="./build" />
         <mkdir dir="./build/obj" />
@@ -34,6 +37,7 @@
             <compilerarg line="${javac.compilerargs}" />
         </javac>
     </target>
+
     <target name="compileTest" depends="compile">
         <javac 
             srcdir="./test" 
@@ -59,10 +63,26 @@
         </exec>
     </target>
 
+    <!-- does not include client classes, moved to samclient.jar -->
     <target name="jar" depends="compile, jarUpToDate, listChangedFiles" unless="jar.uptodate" >
         <!-- set if unset -->
         <property name="workspace.changes.tr" value="" />
-        <jar destfile="./build/sam.jar" basedir="./build/obj" includes="**/*.class">
+        <jar destfile="./build/sam.jar" basedir="./build/obj" includes="**/*.class" excludes="net/i2p/sam/client/*">
+            <manifest>
+                <attribute name="Main-Class" value="net.i2p.sam.SAMBridge" />
+                <attribute name="Class-Path" value="i2p.jar mstreaming.jar streaming.jar" />
+                <attribute name="Implementation-Version" value="${full.version}" />
+                <attribute name="Build-Date" value="${build.timestamp}" />
+                <attribute name="Base-Revision" value="${workspace.version}" />
+                <attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
+            </manifest>
+        </jar>
+    </target>
+
+    <target name="clientjar" depends="compile, listChangedFiles" >
+        <!-- set if unset -->
+        <property name="workspace.changes.tr" value="" />
+        <jar destfile="./build/samclient.jar" basedir="./build/obj" includes="net/i2p/sam/client/*.class">
             <manifest>
                 <attribute name="Main-Class" value="net.i2p.sam.SAMBridge" />
                 <attribute name="Class-Path" value="i2p.jar mstreaming.jar streaming.jar" />
diff --git a/apps/sam/java/src/net/i2p/sam/client/package.html b/apps/sam/java/src/net/i2p/sam/client/package.html
new file mode 100644
index 0000000000000000000000000000000000000000..e07cf020e2d388f2a96ac53245c5602a99264deb
--- /dev/null
+++ b/apps/sam/java/src/net/i2p/sam/client/package.html
@@ -0,0 +1,15 @@
+<html><head></head><body>
+<p>
+Demo and test client classes.
+But if you are writing a Java app, you should probably be using
+native I2CP, not SAM.
+</p><p>
+SAMClientEventListenerImpl, SAMEventHandler, and SAMReader
+are a SAM client API in Java, useful for event based streaming (or
+for testing the SAM bridge).
+</p><p>
+SAMStreamSink and SAMStreamSend
+are a pair of SAM demo apps
+mirroring the streaming lib's
+StreamSink and StreamSend demo apps for transferring files.
+</p></body></html>
diff --git a/build.xml b/build.xml
index 91abfea569dd853d651f5eb966c57a2180a5426b..2382c9ea582b324ed8c1d0194d2b3328044a53bc 100644
--- a/build.xml
+++ b/build.xml
@@ -402,7 +402,7 @@
             <group title="Desktopgui Application" packages="net.i2p.desktopgui:net.i2p.desktopgui.*" />
             <group title="I2PSnark Application" packages="org.klomp.snark:org.klomp.snark.*" />
             <group title="I2PTunnel Application" packages="net.i2p.i2ptunnel:net.i2p.i2ptunnel.*" />
-            <group title="SAM Bridge" packages="net.i2p.sam:net.i2p.sam.client" />
+            <group title="SAM Bridge" packages="net.i2p.sam" />
             <group title="SusiDNS Application" packages="i2p.susi.dns" />
             <group title="SusiMail Application" packages="i2p.susi.webmail:i2p.susi.webmail.*:i2p.susi.debug:i2p.susi.util" />
             <group title="Systray Application" packages="net.i2p.apps.systray" />
@@ -618,6 +618,15 @@
         </copy>
     </target>
 
+    <target name="preppkgRepack" depends="preppkg-linux, preppkg-freebsd, preppkg-osx, preppkg-windows, jbigi">
+        <ant target="repack200" />
+        <!-- no use doing repack200 on jbigi.jar -->
+        <copy file="build/jbigi.jar" todir="pkg-temp/lib" />
+        <copy todir="pkg-temp/lib/wrapper/solaris/">
+            <fileset dir="installer/lib/wrapper/solaris/" />
+        </copy>
+    </target>
+
     <target name="preppkg-freebsd" depends="preppkg-unix">
         <copy todir="pkg-temp/lib/wrapper/freebsd/">
             <fileset dir="installer/lib/wrapper/freebsd/" />
@@ -865,10 +874,12 @@
     <target name="updater200WithJettyFixes" depends="prepjupdatefixes, preplicenses, pack200, zipit200" />
     <target name="updater200WithJettyFixesAndJbigi" depends="prepjupdatefixes, prepjbigiupdate, preplicenses, pack200, zipit200" />
     <target name="updater" depends="prepupdate, preplicenses, zipit" />
+    <target name="updaterRepack" depends="prepupdate, preplicenses, repack200, zipit" />
     <target name="updaterWithJavadoc" depends="prepupdate, preplicenses, copyJavadoc, zipit" />
     <target name="updater200WithJavadoc" depends="prepupdate, preplicenses, copyJavadoc, pack200, zipit200" />
     <target name="updaterWithGeoIP" depends="prepupdate, prepgeoupdate, preplicenses, zipit" />
     <target name="updaterWithJetty" depends="prepjupdate, preplicenses, zipit" />
+    <target name="updaterWithJettyRepack" depends="prepjupdate, preplicenses, repack200, zipit" />
     <target name="updaterWithJettyFixes" depends="prepjupdatefixes, preplicenses, zipit" />
     <target name="updaterWithJettyFixesAndJbigi" depends="prepjupdatefixes, prepjbigiupdate, preplicenses, zipit" />
     <target name="updaterWithJettyFixesAndGeoIP" depends="prepjupdatefixes, prepgeoupdate, preplicenses, zipit" />
@@ -893,24 +904,47 @@
     </target>
 
     <target name="pack200">
-<!-- *nix here -->
+        <!-- pack200 will only pack to a .pack file, and only from a .jar file, so we put another .jar on the end -->
+        <!-- *nix here -->
         <exec executable="sh" osfamily="unix" failonerror="true">
             <arg value="-c" />
             <arg value="for i in pkg-temp/lib/*.jar pkg-temp/webapps/*war; do echo pack200 $i; mv $i $i.jar; pack200 -g $i.pack $i.jar; rm -f $i.jar; done" />
         </exec>
         <exec executable="sh" osfamily="mac" failonerror="true">
             <arg value="-c" />
-            <!-- pack200 will only pack to a .pack file, and only from a .jar file, so we put another .jar on the end -->
             <arg value="for i in pkg-temp/lib/*.jar pkg-temp/webapps/*war; do echo pack200 $i; mv $i $i.jar; pack200 -g $i.pack $i.jar; rm -f $i.jar; done" />
         </exec>
-<!-- windoz here : i admit, i hate escaped symbols in xml, indeed = =! -->
-		<exec executable="cmd" osfamily="windows" failonerror="true">
-			<arg value="/c" />
-			<arg value="for %i in (pkg-temp\webapps\*.war) do move %i %i.jar &amp;&amp; pack200 -g pkg-temp\webapps\%~ni.war.pack %i.jar &amp;&amp; del %i.jar" />
+        <!-- windoz here : i admit, i hate escaped symbols in xml, indeed = =! -->
+        <exec executable="cmd" osfamily="windows" failonerror="true">
+            <arg value="/c" />
+            <arg value="for %i in (pkg-temp\webapps\*.war) do move %i %i.jar &amp;&amp; pack200 -g pkg-temp\webapps\%~ni.war.pack %i.jar &amp;&amp; del %i.jar" />
+        </exec>
+        <exec executable="cmd" osfamily="windows" failonerror="true">
+                <arg value="/c" />
+                <arg value="for %i in (pkg-temp\lib\*.jar) do pack200 -g %i.pack %i &amp;&amp; del %i" />
+        </exec>
+    </target>
+
+    <!-- saves about 1% on average (more on jars with multiple compiled po files since they have lots of common strings) -->
+    <target name="repack200">
+        <!-- pack200 will only repack a .jar file, so we put another .jar on the end -->
+        <!-- *nix here -->
+        <exec executable="sh" osfamily="unix" failonerror="true">
+            <arg value="-c" />
+            <arg value="for i in pkg-temp/lib/*.jar pkg-temp/webapps/*war; do echo pack200 -r $i; mv $i $i.jar; pack200 -r $i.jar; mv $i.jar $i; done" />
+        </exec>
+        <exec executable="sh" osfamily="mac" failonerror="true">
+            <arg value="-c" />
+            <arg value="for i in pkg-temp/lib/*.jar pkg-temp/webapps/*war; do echo pack200 -r $i; mv $i $i.jar; pack200 -r $i.jar; mv $i.jar $i; done" />
+        </exec>
+        <!-- windoz here : i admit, i hate escaped symbols in xml, indeed = =! -->
+        <exec executable="cmd" osfamily="windows" failonerror="true">
+            <arg value="/c" />
+            <arg value="for %i in (pkg-temp\webapps\*.war) do move %i %i.jar &amp;&amp; pack200 -r %i.jar &amp;&amp; move %i.jar %i" />
         </exec>
-		<exec executable="cmd" osfamily="windows" failonerror="true">
-			<arg value="/c" />
-			<arg value="for %i in (pkg-temp\lib\*.jar) do move %i %i.jar &amp;&amp; pack200 -g pkg-temp\lib\%~ni.jar.pack %i.jar &amp;&amp; del %i.jar" />
+        <exec executable="cmd" osfamily="windows" failonerror="true">
+                <arg value="/c" />
+                <arg value="for %i in (pkg-temp\lib\*.jar) do pack200 -r %i" />
         </exec>
     </target>
 
@@ -1267,7 +1301,7 @@
 <!--
     <target name="release" depends="distclean, updaterWithJettyFixesAndJbigi , updater200WithJettyFixes, preppkg, installer, getReleaseNumber" >
 -->
-    <target name="release" depends="verifyReleaseBuildNumbers, distclean, testscripts, updater, updater200, preppkg, installer" >
+    <target name="release" depends="verifyReleaseBuildNumbers, distclean, testscripts, updaterRepack, updater200, preppkgRepack, installer" >
         <echo message="================================================================" />
         <echo message="Did you update these files?" />
         <exec executable="ls" failonerror="true">
diff --git a/history.txt b/history.txt
index d72793f5ca3dc3e57e71e02e0b32d0d77533f767..df478a1914fac2b187b25c10e084ac875dc03534 100644
--- a/history.txt
+++ b/history.txt
@@ -1,3 +1,9 @@
+2012-01-27 zzz
+  * Build: Repack release jars with pack200 -r, saves about 1% and
+           might save a little memory at runtime too
+  * confignet: Add UDP disable option
+  * SAM: Remove client demo classes from sam.jar
+
 2012-01-26 zzz
   * configclients: Fix form action default
   * NetDB: Increase min ff to 200