Compare commits

...

247 Commits

Author SHA1 Message Date
503b289240 * 2004-10-10 0.4.1.2 released 2004-10-10 19:33:08 +00:00
35e3bbb862 2004-10-10 cervantes
* Update the I2PTunnel HTTP proxy to strip out the i2paddresshelper from
      the request.
2004-10-10 14:57:15 +00:00
8dc261da79 2004-10-09 jrandom
* Added a watchdog timer to do some baseline liveliness checking to help
      debug some odd errors.
    * Added a pair of summary stats for bandwidth usage, allowing easy export
      with the other stats ("bw.sendBps" and "bw.receiveBps")
    * Trimmed another memory allocation on message reception.
2004-10-10 00:03:25 +00:00
65676f8988 2004-10-08 jrandom
* Revamp the AESInputStream so it doesn't allocate any temporary objects
      during its operation.
2004-10-08 22:53:03 +00:00
730da3aa27 2004-10-08 jrandom
* Don't kill the establisher threads during a soft restart.
    * Attempt to validate the peer's routerInfo earlier during handshaking.
    * Revamp the AESOutputStream so it doesn't allocate any temporary objects
      during its operation.
2004-10-08 18:38:48 +00:00
ff8674bca9 2004-10-07 jrandom
* Reimplement the I2NP reading with less temporary memory allocation.
      There is still significant GC churn, especially under load, but this
      should help.
    * Catch some oddball errors in the transport (message timeout while
      establishing).
2004-10-08 02:08:10 +00:00
c7cfef3b61 2004-10-07 jrandom
* Expire queued messages even when the writer is blocked.
    * Reimplement most of the I2NP writing with less temporary memory
      allocations (I2NP reading still gobbles memory).
2004-10-07 19:19:51 +00:00
32188b1cc0 expose some direct byte formatting methods
allow SHA256 to be run against a partial array
append to the stats.log instead of overwriting it
2004-10-07 16:48:46 +00:00
37479d8c0d logging 2004-10-07 16:45:11 +00:00
f5c7d6576d no need to double b0rk 2004-10-07 16:42:55 +00:00
38c422bbc0 2004-10-06 jrandom
* Implement an active queue management scheme on the TCP transports,
      dropping messages probabalistically as the queue fills up.  The
      estimated queue capacity is determined by the rate at which messages
      have been sent to the peer (averaged at 1, 5, and 60m periods).  As
      we exceed 1/2 of the estimated capacity, we drop messages throughout
      the queue probabalistically with regards to their size.  This is based
      on RFC 2309's RED, with the minimum threshold set to 1/2 the
      estimated connection capacity.  We may want to consider using a send
      rate and queue size measured across all connections, to deal with our
      own local bandwidth saturation, but we'll try the per-con metrics first.
2004-10-06 21:03:51 +00:00
39d4e5ea81 list the shutdown time w/ the clock fudge factor included 2004-10-06 16:47:36 +00:00
4191ad1cbf 2004-10-06 jrandom
* Enable explicit disabling of the systray entirely for windows machines
      with strange configurations: add -Dsystray.disable=true to the java
      command line.  (thanks mihi!)
2004-10-06 13:23:38 +00:00
29287da37c 2004-10-05 jrandom
* Allow peers on the same LAN to communicate with each other safely even
      when they cannot talk to each other through the external address.
2004-10-06 01:12:03 +00:00
98c780415b 2004-10-05 jrandom
* Display how much time is left before the graceful shutdown is complete.
    * Debug some improperly failed messages on timeout or disconnection.
2004-10-05 19:21:47 +00:00
756af9c699 oops 2004-10-05 18:21:44 +00:00
7f9076bb1d updated beyond.i2p (after verification) 2004-10-05 16:04:16 +00:00
2404f1ab9a added b.i2p 2004-10-05 15:57:08 +00:00
64bcfd09ec 2004-10-05 jrandom
* Don't go into a fast busy if an I2PTunnel 'server' is explicitly killed
      (thanks mule!)
    * Handle some more error conditions regarding abruptly closing sockets
      (thanks Jonva!)
2004-10-05 15:38:37 +00:00
6251d22c6e added tinyurl.i2p 2004-10-05 15:26:20 +00:00
de1b4937a1 2004-10-04 jrandom
* Update the shitlist to reject a peer for an exponentially increasing
      period of time (with an upper bounds of an hour).
    * Various minor stat and debugging fixes
2004-10-04 17:30:22 +00:00
d092dd79ba get rid of the really really frequent temporary object creation 2004-10-04 13:53:10 +00:00
a3ba968386 24h time 2004-10-04 01:17:01 +00:00
5ca2b97128 24h time 2004-10-04 01:00:38 +00:00
c9daad1cfd added detonate.i2p 2004-10-04 00:16:13 +00:00
0526d5b53a cli to splot the stat log 2004-10-03 23:53:16 +00:00
34163fb8e4 dont overwrite index.html anymore (0.4.1.2 wont) 2004-10-03 21:06:17 +00:00
98d2d661a8 2004-10-03 jrandom
* Add a new stat logging component to optionally dump the raw stats to
      disk as they are generated, rather than rely upon the summarized data.
      By default, this is off, but the router property "stat.logFilters" can
      be set to a comma delimited list of stats (e.g. "client.sendAckTime")
      which will be written to the file "stats.log" (or whatever the property
      "stat.logFile" is set to).  This can also log profile related stats,
      such as "dbResponseTime" or "tunnelTestResponseTime".
2004-10-03 20:48:43 +00:00
d9f0a0fd74 dont list an explicit webdefault.xml (use the default) 2004-10-03 14:04:21 +00:00
d20d043e0f 2004-10-02 jrandom
* Assure that we quickly fail messages bound for shitlisted peers.
    * Address a race on startup where the first peer contacted could hang the
      router (thanks Romster!)
    * Only whine about an intermittent inability to query the time server once
2004-10-02 19:05:24 +00:00
ce186e1872 2004-10-02 jrandom
* Command line utility to verify a peer's reachability - simply run
      net.i2p.router.transport.tcp.ConnectionHandler hostname port# and it
      will print out whether that peer is reachable or not (using a simple
      verification handshake).
2004-10-02 12:31:15 +00:00
a14da92e1d * 2004-10-01 0.4.1.1 released 2004-10-01 17:23:00 +00:00
2b54d850ea logging 2004-10-01 17:19:37 +00:00
a63c1b19fc 2004-10-01 jrandom
* Handle partial reseeds, caused by seeds going away before the download
      completes (thanks Sugadude!)
2004-10-01 14:35:49 +00:00
34f74cd6ef 2004-10-01 jrandom
* Explicitly refuse IPv6 addresses, since only some peers support
      them and we want fully reachable peers.
2004-10-01 11:49:02 +00:00
c0b8e62135 2004-10-01 jrandom
* Additional error handling for a variety of transport layer errors.
2004-10-01 09:39:14 +00:00
ea24166b8e added identiguy.i2p 2004-10-01 09:32:46 +00:00
178b229d66 *cough* (oops) 2004-09-30 16:44:46 +00:00
276493da65 * 2004-09-30 0.4.1 released (not backwards compatible)
2004-09-30  jrandom
    * Bundle the configuration necessary to run an eepsite out of the box
      with Jetty - simply edit ./eepsite/docroot/index.html and give people
      the key listed on the I2PTunnel configuration page, and its up.
    * Router console cleanup, and some (off by default) tunnels -
      smtp.postman.i2p (port 7659), pop.postman.i2p (port 7660), and
      irc.baffled.i2p (port 7661)
2004-09-30 15:58:54 +00:00
e85dadfef2 added jabber-2.i2p 2004-09-30 13:25:31 +00:00
1c70efb350 added eepsite info 2004-09-30 13:23:01 +00:00
6804a0c564 * always flush the console output (duh)
* deal with some degenerate situations with identities changing and auto IP detection
* some catch-alls for cleaning up the registry on degenerate tunnels
* lots of logging
2004-09-30 13:10:02 +00:00
6eb7ecc2d4 2004-09-30 jrandom
* Bundle the configuration necessary to run an eepsite out of the box
      with Jetty - simply edit ./eepsite/docroot/index.html and give people
      the key listed on the I2PTunnel configuration page, and its up.
plus minor bugfixes / refactoring / logging
2004-09-30 06:57:22 +00:00
f4956b06b6 be more careful on startup 2004-09-30 06:51:28 +00:00
9a2f7c2660 include the timeouts due to inability to find the leaseSet 2004-09-30 00:51:35 +00:00
b6017c558a * updated stats:
- sendsPerFailure: how many partial sends we make when they all fail
- timeoutCongestionInbound: describes how much faster than our average speed we were receiving data when each partial send timed out (in Bps)
- timeoutCongestionMessage: our send processing time when each partial send timed out (in ms)
- timeoutCongestionTunnel: our tunnel test time when each partial send timed out (in ms)
- participatingMessagesProcessedActive: # of messages more than the (most recent) average that a tunnel we were participating in transmitted (for tunnels with more than the average)
* updated to use Writer for rendering the console, so we can do partial writes (and hopefully help debug some kooky threading bugs on kaffe)
2004-09-29 22:54:38 +00:00
62ed6c6a58 * updated stats:
- sendsPerFailure: how many partial sends we make when they all fail
- timeoutCongestionInbound: describes how much faster than our average speed we were receiving data when each partial send timed out (in Bps)
- timeoutCongestionMessage: our send processing time when each partial send timed out (in ms)
- timeoutCongestionTunnel: our tunnel test time when each partial send timed out (in ms)
- participatingMessagesProcessedActive: # of messages more than the (most recent) average that a tunnel we were participating in transmitted (for tunnels with more than the average)
* updated to use Writer for rendering the console, so we can do partial writes (and hopefully help debug some kooky threading bugs on kaffe)
2004-09-29 22:49:19 +00:00
24966c812f javad0c 2004-09-29 20:12:26 +00:00
ea8dc2e0af *nix daemon scripts are gone 2004-09-29 19:38:15 +00:00
010b285e67 2004-09-29 jrandom
* Always wipe the Jetty work directory on startup, so that web updates
      are reflected immediately (Jetty does not honor the cache across
      multiple executions)
in addition, refactor various file ops out of the DataHelper into FileUtil
2004-09-29 19:34:02 +00:00
774231f347 * started reducing the temporary buffers created within various crypto methods , as we've
got some pretty heavy GC churn when under load.  rough estimate is we allocate 5-8x as
much data as we need, copying it all over the place before forwarding it (or processing it).
this should cut down a few of those copies, but not enough yet.  it'd be great to get that
down to 2x.
* lots of logging
2004-09-28 20:33:23 +00:00
ff1dfd8f25 let the algorithm handle writing the output to various places in the output array (so we can cut down on temporary memory allocation) 2004-09-28 16:38:24 +00:00
2741ac195d * protocol doc & impl cleanup
* more defensive programming
* more javadoc updates
2004-09-28 08:34:48 +00:00
cf780e296e bugfixes for autodetection/update of IP address 2004-09-27 18:05:28 +00:00
0361246db0 2004-09-27 jrandom
* Limit the number of connection tags saved to 10,000.  This is a huge
      limit, but consumes no more than 1MB of RAM.  For now, we drop them
      randomly after reaching that size, forcing those dropped peers to use
      a full DH negotiation.
    * HTML cleanup in the console.
2004-09-27 07:57:43 +00:00
63355ecd5b more tcp transport updates (getting closer to the old functionality)
* avoid bad peers
* shitlist appropriately
* include the bandwidth limiter
* add socket timeouts
* deal with *cough* closing connections
* javadocs
2004-09-26 18:11:39 +00:00
0f54ba59fb die phttp die 2004-09-26 15:32:24 +00:00
b67b243ebd the following isn't the end of the 0.4.1 updates, as there are still more things left to clean
up and debug in the new tcp transport, but it all works, and i dont like having big changes
sitting on my local machine (and there's no real need for branching atm)
2004-09-26  jrandom
    * Complete rewrite of the TCP transport with IP autodetection and
      low CPU overhead reconnections.  More concise connectivity errors
      are listed on the /oldconsole.jsp as well.  The IP autodetection works
      by listening to the first person who tells you what your IP address is
      when you have not defined one yourself and you have no other TCP
      connections.
    * Update to the I2NP message format to add transparent verification at
      the I2NP level (beyond standard TCP verification).
    * Remove a potential weakness in our AESEngine's safeEncrypt and safeDecrypt
      implementation (rather than verifying with E(H(key)), we now verify with
      E(H(iv))).
    * The above changes are NOT BACKWARDS COMPATIBLE.
    * Removed all of the old unused PHTTP code.
    * Refactor various methods and clean up some javadoc.
2004-09-26 15:16:44 +00:00
4c29c20613 javadoc fix 2004-09-26 14:50:49 +00:00
mpc
4c2619d948 minor changes 2004-09-24 21:08:00 +00:00
ea5662a4a2 another minor semantic jikes warning 2004-09-23 01:21:33 +00:00
7c1ce777a1 cleanup per jikes' whining (overloaded var names, val overflow, etc) 2004-09-23 01:13:22 +00:00
3bb85f2d61 add some logical exit values (useful for scripting).thanks xolo! 2004-09-23 01:05:40 +00:00
93e36b3113 added jake.i2p 2004-09-23 00:08:51 +00:00
932fb670e3 added anonymnet.i2p sasquotch.i2p orz.i2p microbleu.i2p www/smtp/pop3.postman.i2p 2004-09-22 23:58:37 +00:00
54dce61a95 2004-09-21 jrandom
* Have two tiers of hosts.txt files - the standard "hosts.txt" and
      the new "userhosts.txt".  Updates to I2P will only overwrite the former,
      but values stored in the later take precedence.  Both are queried on
      lookup.
2004-09-22 00:10:26 +00:00
e686c0e0a2 added curiosity.i2p 2004-09-17 19:47:58 +00:00
05acf32f39 2004-09-16 jrandom
* Refactor the TCP transport to deal with changing identities gracefully,
      and to prevent some wasted effort by keeping track of what host+port
      combinations we are connected to (rather than just the identities).  Also
      catch a few configuration errors earlier.
    * Removed no longer relevent methods from the Transport API that were
      exposing ideas that probably shouldn't be exposed.
    * Removed the 0.4.0.1 specific files from i2pupdate.zip (relating to script
      updates)
2004-09-16 23:55:12 +00:00
mpc
67064012c9 added freeciv.nightblade.i2p 2004-09-16 20:50:26 +00:00
10e93c3b1b rename (wtf was i thinking "Calculator"...) 2004-09-16 02:04:40 +00:00
5b2ec1cbb5 moved udp transport to 0.4.4 instead of 1.1 2004-09-14 19:52:46 +00:00
972f701c5c ganttproject.sf.net based plan 2004-09-14 02:19:33 +00:00
51285efbc3 2004-09-13 jrandom
* Update for the SDK reconnection to deal with overflow.
    * Web improvements (@ not # on the /logs.jsp [thanks ugha!] and fixed the
      rounding on lifetime bandwidth used [thanks gott!]).
2004-09-13 03:08:16 +00:00
e2635705f9 added xolotl.i2p 2004-09-11 01:25:24 +00:00
7762107543 added modulus.i2p 2004-09-10 04:11:15 +00:00
9123ad89c8 added links to www.i2p and dev.i2p (thanks pseudonym) 2004-09-09 04:10:25 +00:00
39f3d6cc80 (release in the next hour or so)
2004-09-08  jrandom
    * Updated the "Active:" peer count to display the # of connections as well
      as the number of recently active router identities.
    * Implement some basic updating code - on startup, if there is a file named
      "i2pupdate.zip" in the I2P installation directory, extract it, delete it,
      then restart.
    * Added an ugly little script to allow launching the router on win9x
      machines without a dos box (using javaw to run a .bat file).
    * Logging updates.
    * Updated VERSION constants to 0.4.0.1
2004-09-09 02:26:42 +00:00
af5665f67c revert the last 2 changes 2004-09-08 22:25:54 +00:00
c2175cc692 corrected submission date 2004-09-08 22:15:43 +00:00
1ef371a467 reversing accidental reversion 2004-09-08 22:08:24 +00:00
58461ff5bb * Bugfix: Running the installer as a non-privileged user on Red Hat (and
hopefully any other affected *nix systems) now properly discards non-
   essential directories after installation.
* Support for Win9x in the installer and postinstall.bat.
* Changed the name of the default installation directory on all platforms
   from "I2P" to "i2p" in the installer.
* Changed "wrapper.conf" to "wrapper.config" for naming consistency with the
   other configuration files.
2004-09-08 22:04:13 +00:00
665959da90 added eepdot.i2p 2004-09-08 07:46:21 +00:00
8e63974f94 removed datagram_test.i2p 2004-09-08 07:45:11 +00:00
eae86f54ba Updates by cervantes:
* Proxy recursion disabled by default (strict)
    * Password Authentication for session commands
    * Support for http://path?i2paddresshelper=BASE64
    * Support for http://i2p/BASE64/path syntax
2004-09-08 07:25:09 +00:00
30128a122d added socks1.tor.i2p 2004-09-08 00:00:28 +00:00
56e22a39ac added sugadude.i2p 2004-09-07 22:30:53 +00:00
6ceb330baa 2004-09-07 jrandom
* Make sure that peers placed in the 'fast' group are ones we both know
      how to reach and have been able to reach recently.  These peers may
      still be placed in the 'high capacity' group however (though that group
      is only queried if the 'fast' group is too small)
    * Include some updates to the ProgileOrganizer's CLI.
2004-09-07 22:13:11 +00:00
f30509c7ba if i only had a brain... (thanks duck) 2004-09-07 20:54:44 +00:00
9489136bd6 fix the build (thanks duck) 2004-09-07 20:39:42 +00:00
05cd3d736b 2004-09-07 jrandom
* Disable the timestamper by default for all applications except the router
      (enable via -Dtime.disabled=false)
    * Simplify the retrieval of the full destination with text based browsers.
    * Bundle the updated wrapper.config and hosts.txt in the i2pupdate.tar.bz2
2004-09-07 09:49:02 +00:00
29b17772e5 dup entry 2004-09-07 07:23:49 +00:00
6151d63eac 2004-09-07 jrandom
* Write the native libraries to the current directory when they are loaded
      from a resource, and load them from that file on subsequent runs (in
      turn, we no longer *cough* delete the running libraries...)
    * Added support for a graceful restart.
    * Added new pseudo-shutdown hook specific to the router, allowing
      applications to request tasks to be run when the router shuts down.  We
      use this for integration with the service manager, since otherwise a
      graceful shutdown would cause a timeout, followed by a forced hard
      shutdown.
    * Handle a bug in the SimpleTimer with requeued tasks.
    * Made the capacity calculator a bit more dynamic by not outright ignoring
      the otherwise valid capacity data for a period with a single rejected
      tunnel (except for the 10 minute period).  In addition, peers with an
      equal capacity are ordered by speed rather than by their hashes.
    * Cleaned up the SimpleTimer, addressing some threading and synchronization
      issues.
    * When an I2PTunnel client or httpclient is explicitly closed, destroy the
      associated session (unless there are other clients using it), and deal
      with a closed session when starting a new I2PTunnel instance.
    * Refactoring and logging.
2004-09-07 07:17:02 +00:00
e57aa68854 added files.i2p 2004-09-07 00:38:19 +00:00
73fa6d9bd0 added beyond.i2p 2004-09-06 06:04:15 +00:00
da3c4b87c1 (oops, forgot to up the build # on the last round) 2004-09-06 05:21:26 +00:00
0eedc1b128 2004-09-06 jrandom
* Address a race condition in the key management code that would manifest
      itself as a corrupt router identity.
    * Properly clear old transport addresses from being displayed on the old
      console after soft restarts.
    * Properly refuse to load the client applications more than once in the
      same JVM.
    * Added support for a graceful restart (a graceful shutdown followed by a
      full JVM restart - useful for restarting client apps).
    * More defensive programming, HTML cleanup, logging
    * wrapper.config cleanup of duplicate lines
2004-09-06 05:20:40 +00:00
db339d40de 2004-09-04 jrandom
* Added some basic guards to prevent multiple instances from running.
       Specifically, a file "router.ping" in the install directory which is
       written to once a minute - if that file exists and has been modified
       within the last minute, refuse to start up.  In turn, adjust the
       service wrapper to wait a minute before restarting a crashed JVM.
     * Create a "work" directory in the I2P install dir which Jetty will
       use for all of its temporary files.
     * Tell the browser not to cache most of the router console's pages.
2004-09-04 21:54:08 +00:00
f72aa7884d added gott.i2p 2004-09-04 10:25:31 +00:00
1434f1bb40 added linuxagent.i2p 2004-09-04 10:01:58 +00:00
6bc92b26a7 2004-09-04 jrandom
* Update the SDK to automatically reconnect indefinitely with an
      exponential delay on retries (capped at 5 minutes).
2004-09-04 05:41:42 +00:00
63937d0fba 2004-09-03 jrandom
* Updated default wrapper.config to deal with the hard restart option
    * Include the history.txt in the /help.jsp page
    * HTML updates (wrapper.log, and no more unix scripts)
    * Updated VERSION constants to 0.4
2004-09-03 19:46:07 +00:00
7b86edaf7f 2004-09-03 hypercubus
* Bugfix: Installer launches postinstall.bat on WinNT/2K properly.
    * Temporarily removed install_i2p_service_unix and
      uninstall_i2p_service_unix from distribution packages.
    * postinstall.bat/postinstall.sh cleans installation directory of all files
      not applicable to the host OS.
2004-09-03 16:52:27 +00:00
49d4e565c6 2004-09-03 oOo
* Added some filters to the HTTP request, replacing the User-Agent,
      Referrer, Via, and From headers, which helps until we have a more
      comprehensive filtering system.
2004-09-03  jrandom
    * Disabled the old listener on port 7655.
2004-09-03 07:22:24 +00:00
44c54ecc16 2004-09-02 jrandom
* Cleaned up the base build.xml, adding a new target ("updater") which
      builds the file i2pupdate.tar.bz2 which can be safely extracted over
      existing installs.
2004-09-02 21:26:03 +00:00
6e543f825d new history file and RouterVersion.BUILD (displayed on the web console and in the published stats)
(see soon-to-be-posted email to the list about this stuff)
2004-09-02 20:00:28 +00:00
591800a28a *cough* 2004-09-02 08:36:26 +00:00
3340d74e3f * added www.i2p, dev.i2p, and cvs.i2p (pointing at www.i2p.net:80, dev.i2p.net:80, and cvs.i2p.net:2401, respectively)
* default the i2ptunnel listen interface to 127.0.0.1, not 0.0.0.0
* add a client tunnel listening on port 2401 pointing at cvs.i2p (but *not* started by default)
2004-09-02 08:32:05 +00:00
446d863106 use the new .jsp filenames (i'm not quite ready to drop support for this old admin console... yet) 2004-09-02 07:20:45 +00:00
8b2d27a916 the client tunnel settings are "tunnels.depthInbound", not "tunnel.depthInbound" 2004-09-02 07:07:33 +00:00
9b31f2257d file was renamed 2004-09-02 06:54:37 +00:00
252ec98e24 default to publish rankings & stats (disable via router.publishPeerRankings=false) 2004-09-02 05:41:30 +00:00
77dde5711b more aggressively delete the temp lib file 2004-09-02 05:40:25 +00:00
94e891880b keeping in pace with the wrapper logs 2004-09-02 05:27:04 +00:00
c414b3fad2 if the wrapper will write a wrapper.log in the current directory anyway, might as well use it there. 2004-09-02 05:22:12 +00:00
c0b63ee7a8 bournification 2004-09-02 05:02:53 +00:00
6fbbfbaa43 bourne-ified (damn borne agains) 2004-09-02 04:47:02 +00:00
4d663e4500 antialiasing & cleanup (thanks $anonDesigner!) 2004-09-02 02:26:13 +00:00
88ba2436c9 headless install instructions 2004-09-02 02:20:03 +00:00
bfda22ad57 * persist and honor the configuration option "visible" (default=true)
* every 30s check to make sure the icon is [not] visible (useful for broken OSes that do stupid things when you start systray4j before logging in)
* go to "/index.jsp" rather than just "/" (avoids a silly redirect)
2004-09-02 01:47:18 +00:00
b888f17672 within the installation, move readme.html to docs/readme.html 2004-09-02 01:22:33 +00:00
8aa07e6f12 synchronized on (and .wait/notify against) the ShellCommand, not the Thread.
in general the old way worked often, but would sometimes cause a race, this should be a bit safer
2004-09-01 23:08:35 +00:00
79e973af65 cleaned up a bit (thanks $anonDesigner!) 2004-09-01 22:13:01 +00:00
83c6fd43e5 * corrected: unix service install scripts erroneously pointed to 'i2psvc' instead of 'i2prouter'
* pid file naming fixed once and for all, using 'i2p.pid' ;-) ('i2prouter.pid' did not work)
2004-09-01 16:46:27 +00:00
1323d89912 last revision inadvertently launched the router console every time the router was started 2004-09-01 11:43:33 +00:00
6b89996b0b the return of Ignatious Toopie
(freshcoffee.i2p's logo is definitely cool, but imho brings too much of a "java" connotation.  perhaps we can use it on the "prerequisites: get java" page?)
2004-09-01 08:31:00 +00:00
8a9a60410c more PIDs (one for the JVM, one for the service)
the i2prouter script has some kooky naming dependencies, and the stop doesnt seem to work right, but its got pid files now... :)
2004-09-01 08:02:19 +00:00
09e8678369 pid file (not sure why the wrapper doesnt create one by default) 2004-09-01 07:53:03 +00:00
2ff7efadc2 put logs in the console buffer even if we're not sending anything to the console (since this console buffer is shown as the /logs.jsp) 2004-09-01 07:17:24 +00:00
5f3fcd2f37 some url cleanup (thanks nicktastic!) 2004-09-01 07:00:07 +00:00
7dffae4620 workaround a bug in libtool (which Kaffe uses) that b0rks on native libraries that aren't named "typically" for the OS (libjbigi.so, etc)
(sun, however, works fine with randomly named libraries)
2004-09-01 06:53:00 +00:00
ce2e7305d4 if we're doing ugly jsp taglets to filter by OS, might as well do it for both systray and service 2004-09-01 03:47:04 +00:00
4783b09f03 fixed bug in IE launch 2004-09-01 02:25:06 +00:00
15c089ca9c now opens browser to http://localhost:7657/ in all cases 2004-09-01 00:33:59 +00:00
e93a2ddd93 now directly reading the default browser from the registry on Windows 2004-08-31 23:25:47 +00:00
57b9c40609 need the jettylib to build the war 2004-08-31 22:38:00 +00:00
caaadd63ec cleaned up a little for the future revs 2004-08-31 22:26:19 +00:00
ca1b707fab note about how uninstalling the service kills the router... 2004-08-31 21:28:41 +00:00
a0499451a5 let windows users install/remove the service through the /configservice.jsp page 2004-08-31 21:25:23 +00:00
bbdf1a0b30 removing some annoying spaces on blank lines 2004-08-31 21:12:15 +00:00
bcd5230854 added 'port' preference for specification of the router console's listening port 2004-08-31 21:08:00 +00:00
5ec3d2a587 systray now reads router console port number from systray.config 2004-08-31 21:07:06 +00:00
9cb2be6ec4 erg, this should have been in the last commit... (help stuff, license stuff) 2004-08-31 03:31:18 +00:00
4e90ca0b26 * revamped (rewrote, htmlized) readme
* wrote basic license stuff
2004-08-31 03:29:20 +00:00
8c4c72c8b5 * in the multirouter (sim), give each router a randomly distributed clock skew (within the acceptable period)
* in the multirouter (sim), disable the timestamper (so the clock skew 'sticks')
* logging
2004-08-30 22:28:15 +00:00
8690d4d7a9 allow explicit overriding any logical constraints on the clock skew (useful for simulating strange things) 2004-08-30 22:23:24 +00:00
d5d9c9b483 get thee gone, extraneous comment! 2004-08-30 12:49:25 +00:00
0de8129457 * installer no longer hangs on Windows waiting for the spawned shell process to return
* shell process spawned by the installer on Windows will not create a visible command window
2004-08-30 12:28:08 +00:00
13f70ad42c systray now launches router console in config.jsp upon first launch after installation 2004-08-30 11:47:28 +00:00
49d7b568df * removed some failsafe code that had been preventing any messages from being sent down alternate tunnels in a leaseSet [oops]
this may have unintended consequences, as we need to deal with messages received from skewed clocks, but I believe the two pathways
used here are safe (we leave the larger timeout thresholds intact for dealing with remotely generated message times)
2004-08-30 08:29:06 +00:00
93afcd5c0c * removed unwanted systray window on *nix
* removed 'Shutdown I2P router' from systray menu; preferred method of shutdown is now router console
2004-08-30 01:08:13 +00:00
07ef3582f7 clarify the nextInt/nextLong boundaries (thanks oOo) 2004-08-29 22:42:21 +00:00
53c7ff14df code reuse++ (digest authentication works, nice find oOo!) 2004-08-29 22:35:55 +00:00
6b993688fc poke the systray (so that on startup, it may show the icon and/or launch the browser) 2004-08-29 21:06:15 +00:00
b9e667e155 if a netDb refetch of a lease we were able to fetch is going slowly, short circuit it by reinjecting the old (dropped) one after 10 seconds so we can attempt a resend 2004-08-29 20:56:24 +00:00
3cd26781b0 'The I2P Project' is redundant - just 'I2P', and switched version # 2004-08-29 20:34:13 +00:00
2d20ac6f29 removed unintentional duplicate copy of 'i2psvc' from 'lib/' 2004-08-29 20:15:31 +00:00
944d467654 changed deprecated 'tail -1' to 'tail -n 1'; the Java Service Wrapper team will probably change it soon, but we need this for 0.4 2004-08-29 17:59:10 +00:00
f68271c3d7 set mode_paranoid=true 2004-08-29 01:47:13 +00:00
4eb5070753 clear another possible thread leak 2004-08-27 23:52:13 +00:00
f57adc9cc4 don't fail the tunnels used to send/receive a request on a lost reply, as the potential that they're to blame is only 1 out of 5.
(and if other people's tunnels suck, that leads us to kill all of our tunnels.  which is Bad)
2004-08-27 20:56:00 +00:00
3e0b7bfeff cleaned up peer selection so we don't have to repeatedly ask the profileOrganizer the same thing over and over
(instead, have the profileOrganizer check the netDb to see if the profiled peer is reachable)
cleaned up the threshold calculation a bit more
2004-08-27 19:18:24 +00:00
faa78c67d8 router console opens automatically upon first launch (i.e. if router.config is not found) 2004-08-27 12:44:43 +00:00
a5ed02eb1c fixed some foolishness w/ booleans (thanks oOo!) 2004-08-27 02:04:49 +00:00
mpc
bfe11110aa Trying to get around CVS stupidity 2004-08-27 01:52:30 +00:00
mpc
d8b1d2382d Junking this for now.. use Stasher instead 2004-08-27 01:41:48 +00:00
mpc
7881a13610 moved some files around 2004-08-27 01:29:18 +00:00
mpc
aaa328950e invalid style error 2004-08-26 21:42:56 +00:00
d8eb1a0a4f more path woes solved, scripts launch properly from installer (yay!) 2004-08-26 19:08:25 +00:00
e3379b31cb only base the thresholds on peers who are not in recovery 2004-08-26 18:46:25 +00:00
f36ce3d245 drop the links to install/uninstall the service from this page. not worth the effort atm (they can just run the shell scripts) 2004-08-26 18:39:30 +00:00
c73f3385c0 don't ask the bandwidth limiter to authorize reading an EOF ;)
(this fixes the longstanding "-318 bytes read" bug)
2004-08-26 17:59:47 +00:00
2eb8b84bbd update to build.xml to reflect name change of 'postinstall' to 'postinstall.sh' 2004-08-26 17:25:05 +00:00
b31378ad1a local scripts are now made executable by postinstall.sh 2004-08-26 17:22:37 +00:00
53213bb553 fixed relative path problem so 'i2psvc' can be found 2004-08-26 14:48:10 +00:00
36b446c012 * never drop the threshold under the baseline (the peer selection algorithm can handle there being no fast peers, etc)
* revert some of the overly zealous peer distribution code - select randomly from the fast peers, not according to a strict LRU
(which was causing lots of queued up tunnel requests, as well as tunnel failures when they all failed)
need to think some more thunks about how to address this right now.  a few different algorithms available
to deal with different scenarios and #s of users, but nothing that by itself strikes me as 'ideal', yet.   perhaps its
time for another trip to the pub to see what inspiration can be found there ;)
2004-08-26 08:07:48 +00:00
ca70fc8dc8 load the body of the index.jsp from ./readme.html (so we can put in some intro crap w/ links and the user can change it later) 2004-08-26 08:00:16 +00:00
18ff889b56 crazy paranoia to deal with errors referencing bad dll/.so files for the service wrapper / systray / etc 2004-08-26 03:12:52 +00:00
fab3c0df3e take care of another scenario where a thread can leak 2004-08-26 03:08:19 +00:00
7e7f97d72a * add a new simplified version of java.util.Timer/TimedEvent
* removed all of the "temporary" threads used for adding timeouts to blocking socket operations:
 - use the ConnectionEstablisher's thread + a SimpleTimer.TimedEvent callback to timeout socket create
 - added a pool of socket handler threads (size=3 atm) for receiving any inbound sockets, which are
   pulled off a queue, after which a handshake occurs to verify the other side is I2NP (along side
   another SimpleTimer.TimedEvent callback in case that blocks)
this should get the last of the temporary threads (Jetty has its own thread pool for dealing with
HTTP requests, so we can ignore that thread created in the AdminRunner).  The only significant
reduction in threads left is to go with either NIO or UDP, but neither are happening in the immediate
future.
2004-08-25 20:17:46 +00:00
3a1fcf2865 oh, you mean we should actually stop waiting for something on a thread that has nothing left to do? what a concept!
(this should kill the leaking thread issue)
2004-08-25 19:49:07 +00:00
fd85416088 service wrapper is now fully integrated 2004-08-25 11:20:56 +00:00
18a6a9e965 arrggggh, 1.4-ism that kaffe supports (but sun-1.3 users havent complained about). (thanks frontier) 2004-08-25 06:47:23 +00:00
eed8d9c61b fixed dangerous comparison (== != .equals) [thanks mihi!] 2004-08-25 00:00:04 +00:00
mpc
cbe12adbe6 cervantes' web browser auto-proxy script 2004-08-24 20:58:31 +00:00
84f8931ddd oOo's timestamper fixes (wtf was i thinking with those web params? !thwap) 2004-08-24 19:59:54 +00:00
db135e502c renumber libs 2004-08-24 18:07:21 +00:00
6f205f8adf systray has its own singleton 2004-08-24 18:04:20 +00:00
e81c1df19f * helper to read the last few lines of a textfile
* use that to render the last few lines of the wrapper log on /logs.jsp (for the on demand stack trace)
* thread creation / finalization logging
* support a hard restart (stop immediately and restart the JVM) - useful for rerunning clients.config (etc)
* systray when not supported
2004-08-24 18:02:48 +00:00
71577c9b0e adding provisional support for i2p launching from installer 2004-08-24 13:01:42 +00:00
c88c245094 * moving wrapper scripts to installer/resources
* added wrapper files to the 'installer' target of the global build.xml
2004-08-24 12:25:46 +00:00
30ce04bc84 * added systray jars back to wrapper.conf
* moving wrapper.conf to installer/resources
2004-08-24 12:20:04 +00:00
205d8f7db2 initial commit of ServiceManager class; API is complete, so integration with routerconsole can proceed, but
return of error messages is not yet implemented, meaning returned exit values will all be null for now
2004-08-24 09:04:53 +00:00
d70c22d73f * systray now fully integrated into global ant build
* removed two unneeded test files i2psystray.bat, i2psystray.sh
2004-08-24 06:58:05 +00:00
920161bc07 * more code formatting
* forgot to make constructor private for singleton (d'oh!)
2004-08-24 03:32:17 +00:00
cdafefebd3 the shutdown detector is a daemon 2004-08-24 03:19:54 +00:00
f220300212 code cleanup 2004-08-24 02:37:01 +00:00
a2b86acc22 clear up a race where the timestamper might be fired when it shouldnt be 2004-08-24 00:46:31 +00:00
8e53028d78 * html cleanup
* classpath during javadoc
2004-08-23 21:55:57 +00:00
852dfa4abf removed timestamper 2004-08-23 21:50:27 +00:00
5d6845a58a added jbigi.jar, remoed systray jars 2004-08-23 21:49:39 +00:00
be846e69c5 * control the on_exit so we can shutdown gracefully (except OOMs, when we auto-restart)
* other minor wrapper details
2004-08-23 21:36:31 +00:00
eef8c06b39 new shutdown(exitCode) usage 2004-08-23 21:34:22 +00:00
54aa0fdb11 * add "dump threads"
* hook in to the service manager and let it know we're exiting gracefully (when appropriate)
* commented out but generally functional systray integration.  i cant get it to build sometimes though, something is b0rking up
2004-08-23 21:32:24 +00:00
3c62a5d2b4 * drop libsystray4j.so (for now)
* add some more targets (cleandep and distclean)
2004-08-23 21:28:25 +00:00
0fe70b660a expose as a singleton so we can .show() and .hide() 2004-08-23 21:27:23 +00:00
4f787ddb03 * moved non-source files out of the source tree
* added dependency on core to the build script (for ShellCommand)
2004-08-23 20:53:13 +00:00
be33752eb3 reformatting
(
remove
excess
newlines
)
(no logic changes)
2004-08-23 20:41:06 +00:00
a88dbbe5ba * added in the systray jars
* added loggerFilenameOverride
* removed --quiet parameter (it was bogus anyway ;)
2004-08-23 17:48:44 +00:00
9b4144b815 add support for using the '@' character in place of the rotation #, for situations where stupid config files treat '#' as the end of the line and beginning of a comment... 2004-08-23 17:47:46 +00:00
bce5b44275 standardized the spoof prevention:
- set the nonce and noncePrev for the handler when rendering the form
- include the current nonce in the hidden parameter "nonce"
- include an "action" parameter (so we know we want to execute something and hence, validate the nonce, rather than just display the page)
- if the nonce submitted doesnt match what is set in the nonce or noncePrev when validating, its invalid.  refuse to process
2004-08-23 17:11:38 +00:00
9f7320fa67 * new configservice.jsp page that shuts down the router (and has hooks for a few other things)
* new safer way of shutting down the router per discussions with oOo (dealing with a graceful
shutdown where the user updates their config before the shutdown is complete, etc)
* graceful shutdown implemented in the router - shutdownGracefully(), cancelGracefulShutdown(), shutdownInProgress()
2004-08-23 07:33:14 +00:00
e9310ee8dd updated lucky.i2p 2004-08-23 07:01:10 +00:00
be93db51f7 fixed a bug w/ mode=best_effort - we were returning false excessively 2004-08-23 05:57:24 +00:00
8e3e8ada32 * refactored and revamped the capacity threshold calculation to take
into account various skew situations and the capacity growth constant with
the intent of producing a higher quality threshold whenever possible
* increased the minimum # of fast peers from 4 to 8 (yay), which means we'll
try to have at least some peers to choose from
* added a new router config option - "router.maxParticipatingTunnels".  This is
useful for gracefully shutting down the router (aka set it to 0 and wait until
the router is no longer participating in tunnels, then shutdown).  You can
probably also come up with other situations where this is useful, but I don't
want to spoil all the fun ;)
2004-08-23 03:54:55 +00:00
4564a6e8fd added firerabbit.i2p 2004-08-23 02:21:30 +00:00
240190fa8f oOo's patch to get the console not looking toooo bad on IE, and clean up some ugliness on firefox/moz w/ larger fonts 2004-08-23 01:52:05 +00:00
4ca7c0d978 * moving ShellCommand class to the net.i2p.util package 2004-08-23 00:10:25 +00:00
190d0f9304 never ignore a (potential) tunnel failure, even though the tunnel may not have failed
(e.g. test outbound through A with a reply inbound through B.  if the message is lost, which tunnel failed?  both!)
2004-08-22 22:00:21 +00:00
b8d2a363fb added I2P website URL to header comments 2004-08-22 14:05:02 +00:00
2382785240 changed some filenames and updated credits in comment headers 2004-08-22 13:59:01 +00:00
476994595c adding the service wrapper install and uninstall scripts for *nix 2004-08-22 10:00:39 +00:00
287969f169 simple build script 2004-08-22 06:16:44 +00:00
ca93c52161 new CLI for creating signed NameReference files from a destination's private keystream
e.g. java -cp myi2p.jar;i2p.jar net.i2p.myi2p.address.CreateNameReferenceCLI eep.ref eepPriv.dat jrandom.i2p 1 eep
new CLI for importing / updating a signed NameReference into an address book
   e.g. java -cp myi2p.jar;i2p.jar net.i2p.myi2p.address.CreateEntryCLI addressbook.dat  C:\eep.ref jrandom.r00lz.i2p 0
logging / toString
2004-08-22 06:15:53 +00:00
b126b19e03 shut down the node on, er, shutdown 2004-08-22 06:12:10 +00:00
2c907060d4 forgot to add a SysTrayMenuListener for the new menu option 'Open router console' 2004-08-22 05:10:27 +00:00
e28c0d0b4a * removed systray support for KDE as it remains buggy; win32 is the only supported systray platform for now
* added an 'Open router console' option to the systray menu, for people who can't bring themselves to double-click the icon
2004-08-22 04:56:43 +00:00
918df735ed v0.0.0.0.0.1. it builds, and the core MyI2P framework is there, plus the skeleton for the MyI2P address book service
it doesn't do anything beyond compile and connect/disconnect, so no need to even bother looking at this.
but its a savepoint (iterative and incremental, 'eh?)
2004-08-22 03:44:00 +00:00
294936d137 added trailing '/' to router console url 2004-08-22 00:09:56 +00:00
115da03a23 * fixed another thread blocking problem
* made ConfigFile behave more appropriately with missing config files
* SysTray now behaves correctly when a file dialog has been canceled without any choices being made
2004-08-21 23:42:11 +00:00
cc085755aa oOo's patch to add support for temporary name<-->destination assignment (w00t!)
to use this, make a link going to http://some.name.i2p/some/path/blah?i2paddresshelper=base64Destination
e.g. http://whitehouse.gov.i2p/?i2paddresshelper=FpCkYW5pwVz36sSHoBuRT4ZvGif9QC9oQUWfz-wu4zEnJ1ewlAvinPuw3YnXUKmgLFZ0UY3wB7wqd0eQYiW2ZV1bwVhXvsyGV5ZehzxGaFu05IspCJjyaMIe90z5fyda4KgzyBwHKqwjGX57SMyn2cZhXbCKF6aNuipWxYOnL65uATDbw3jShEtL9v9299ohhGA3EcrYk3u86FgLmsOdi2GZruxy2RzioA-VKhaZl4RSJs6dFHPUYWgeLF3gT7Ciy-HbMZdDuiLTEX7mUlO0UZwnzT8mjUDeeYfyWtv9arwv-rAMeXxAVUYm7X2dDHN8TvmQCZ~LiQrnGmGReSIDKVT4u59xZX2Qg0GZf0fA5LRSW1zHLrlZWDJfNeESW57RlOkA9DDDOxwSVSw8LUQN-hPsoz~AgwA-vDklNWULqvp4lLifEJUlr5ZmnWrviLr6W6cHhdJBl89VzMThoknb5UibIvwTnu~tfA0rkyILXX07hdaoXF~prptuOhMtEcV2AAAA
this is better than the existing http://i2p/base64Destination/ since images at that page will now resolve
the name is resolved only if/when the hosts.txt doesn't have a matching entry (aka no spoofing duck.i2p),
but the name is *not* persisted to hosts.txt - if you restart your tunnel (or router, if they're in the same JVM), the address helper is lost
2004-08-21 22:39:27 +00:00
cb5e3efd8a don't force start the tunnels too early - only instantiate the tunnelControllerGroup when the CLI is run (aka after 2 minutes whem TunnelControllerGroup.main is called from clients.config) 2004-08-21 22:05:02 +00:00
274fd0b528 drop the package prefix from the search path - e.g. just load libjcpuid-x86-windows.so instead of freenet/support/CPUInformation/libjcpu-x86-windows.so 2004-08-21 18:05:36 +00:00
1431d1fecd toss the new precompiled & self detecting jbigi/jcpuid code into cvs and packaged in the new installer as lib/jbigi.jar 2004-08-21 18:03:45 +00:00
dc3d6bfc43 removing unused service wrapper libs 2004-08-21 11:13:57 +00:00
c9d4745a59 one less lib (duh) 2004-08-21 11:12:15 +00:00
921aef7f2c fixed a silly thread blocking problem 2004-08-21 11:01:12 +00:00
3c772f1974 backwards compatibility - first check for jbigi.dll / libjbigi.so, then do the new stuff ("jbigi" in a jar, followed by "net/i2p/util/libjbigi-linux-pentium4.so", etc) 2004-08-21 09:29:18 +00:00
bee9c7ee17 *cough* 2004-08-21 09:15:50 +00:00
75ca438f2f import Iakin's public domain mods plus some additional ones (support for the resource 'jbigi' anywhere in the classpath, java 1.3 support, docs) 2004-08-21 09:11:10 +00:00
9ea6eed22f added support for local build (saving as jbigi) 2004-08-21 09:04:24 +00:00
56f13c53ce bz2 2004-08-21 08:37:18 +00:00
fbc63c957a g++ 2.95.4 2004-08-21 08:21:24 +00:00
6052a9382b moved jbigi source into jbigi subdir (in parallel with other c native libs, like jcpuid) 2004-08-21 07:59:11 +00:00
f7f05cfc8b imported Iakin's public domain jcpuid library allowing the detection of CPU types from java
imported Iakin's modifications to jbigi to use the jcpuid library in detecting what jbigi implementation to load
imported and slightly updated Iakin's scripts to build jbigi for lots of architectures
(yay iakin!)
2004-08-21 07:56:53 +00:00
f4754d7481 * a missing systray.config file is now handled gracefully
* fixed javadoc warnings
2004-08-21 04:03:22 +00:00
7dc8d0cfec * systray now uses its own config file
* added config file handler class
* UrlHandler's browser launching behavior is now more sophisticated for Win32 using rundll
2004-08-21 01:43:35 +00:00
846c393168 giving systray client its own config file 2004-08-21 01:40:30 +00:00
349 changed files with 14108 additions and 9801 deletions

View File

@ -3,6 +3,7 @@
*
* Bogobot.java
* 2004 The I2P Project
* http://www.i2p.net
* This code is public domain.
*/

View File

@ -3,6 +3,7 @@
*
* Bogoparser.java
* 2004 The I2P Project
* http://www.i2p.net
* This code is public domain.
*/

View File

@ -5,9 +5,10 @@
<!-- -->
<!-- build-eclipse.xml -->
<!-- 2004 The I2P Project -->
<!-- http://www.i2p.net -->
<!-- This code is public domain. -->
<!-- -->
<!-- author hypercubus, oOo -->
<!-- authors: hypercubus, oOo -->
<!-- version 0.4 -->
<!-- ********************************************************** -->

View File

@ -5,9 +5,10 @@
<!-- -->
<!-- build.xml -->
<!-- 2004 The I2P Project -->
<!-- http://www.i2p.net -->
<!-- This code is public domain. -->
<!-- -->
<!-- author hypercubus, oOo -->
<!-- authors: hypercubus, oOo -->
<!-- version 0.4 -->
<!-- ********************************************************** -->

View File

@ -1,27 +0,0 @@
Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of any contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,87 +0,0 @@
#
# This Makefile is compatible with GNU Make and should work on Cygwin
#
#
# Your operating environment
#
OS = CYGWIN
#
# Directories
#
BINDIR = bin
LOGDIR = log
OBJDIR = obj
SRCDIR = src
SAMINCDIR = ../sam/c/inc
SAMLIBDIR = ../sam/c/lib
TOMCRYPTDIR = $(HOME)/libtomcrypt-0.96
#
# Programs
#
CC = g++
#
# Flags
#
CFLAGS = -g -march=i486 -pipe -Wall
CFLAGS += -DOS=$(OS)
#
# Libraries
#
CFLAGS += -I$(SAMINCDIR) -I$(TOMCRYPTDIR)
LDFLAGS = -L$(SAMLIBDIR) -L$(TOMCRYPTDIR)
LIBS = -lsam -ltomcrypt -lpthread
#
# Object files
#
OBJS = $(OBJDIR)/bigint.o \
$(OBJDIR)/chk.o \
$(OBJDIR)/config.o \
$(OBJDIR)/logger.o \
$(OBJDIR)/main.o \
$(OBJDIR)/mutex.o \
$(OBJDIR)/peers.o \
$(OBJDIR)/random.o \
$(OBJDIR)/rpc.o \
$(OBJDIR)/sam.o \
$(OBJDIR)/sha1.o \
$(OBJDIR)/thread.o
#
# Build rules
#
all: depend enclave
depend:
$(CC) $(CFLAGS) -MM $(SRCDIR)/*.cpp > .depend
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
$(CC) $(CFLAGS) -o $@ -c $<
enclave: $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) -o $(BINDIR)/enclave $(OBJS) $(LIBS)
#
# Cleanup rules
#
clean:
-rm -f $(BINDIR)/* $(OBJDIR)/* .depend
clean-logs:
-rm -f $(LOGDIR)/*
tidy: clean clean-logs

View File

@ -1,87 +0,0 @@
#
# This Makefile is compatible with GNU Make and should work on Linux (generic)
#
#
# Your operating environment
#
OS = LINUX
#
# Directories
#
BINDIR = bin
LOGDIR = log
OBJDIR = obj
SRCDIR = src
SAMINCDIR = ../sam/c/inc
SAMLIBDIR = ../sam/c/lib
TOMCRYPTDIR = $(HOME)/libtomcrypt-0.96
#
# Programs
#
CC = g++
#
# Flags
#
CFLAGS = -g -march=i486 -pipe -Wall
CFLAGS += -DOS=$(OS)
#
# Libraries
#
CFLAGS += -I$(SAMINCDIR) -I$(TOMCRYPTDIR)
LDFLAGS = -L$(SAMLIBDIR) -L$(TOMCRYPTDIR)
LIBS = -lsam -ltomcrypt -lpthread
#
# Object files
#
OBJS = $(OBJDIR)/bigint.o \
$(OBJDIR)/chk.o \
$(OBJDIR)/config.o \
$(OBJDIR)/logger.o \
$(OBJDIR)/main.o \
$(OBJDIR)/mutex.o \
$(OBJDIR)/peers.o \
$(OBJDIR)/random.o \
$(OBJDIR)/rpc.o \
$(OBJDIR)/sam.o \
$(OBJDIR)/sha1.o \
$(OBJDIR)/thread.o
#
# Build rules
#
all: depend enclave
depend:
$(CC) $(CFLAGS) -MM $(SRCDIR)/*.cpp > .depend
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
$(CC) $(CFLAGS) -o $@ -c $<
enclave: $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) -o $(BINDIR)/enclave $(OBJS) $(LIBS)
#
# Cleanup rules
#
clean:
-rm -f $(BINDIR)/* $(OBJDIR)/* .depend
clean-logs:
-rm -f $(LOGDIR)/*
tidy: clean clean-logs

View File

@ -1,87 +0,0 @@
#
# This Makefile is compatible with GNU Make and should work on Windows (Mingw)
#
#
# Your operating environment
#
OS = MINGW
#
# Directories
#
BINDIR = bin
LOGDIR = log
OBJDIR = obj
SRCDIR = src
SAMINCDIR = C:\cygwin\home\Administrator\cvs\i2p\apps\sam\c\inc
SAMLIBDIR = C:\cygwin\home\Administrator\cvs\i2p\apps\sam\c\lib
TOMCRYPTDIR = C:\cygwin\home\Administrator\libtomcrypt-0.96
#
# Programs
#
CC = C:\Dev-Cpp\bin\g++
#
# Flags
#
CFLAGS = -g -march=i486 -pipe -Wall
CFLAGS += -DOS=$(OS)
#
# Libraries
#
CFLAGS += -I$(SAMINCDIR) -I$(TOMCRYPTDIR)
LDFLAGS = -L$(SAMLIBDIR) -L$(TOMCRYPTDIR)
LIBS = -lsam -ltomcrypt
#
# Object files
#
OBJS = $(OBJDIR)/bigint.o \
$(OBJDIR)/chk.o \
$(OBJDIR)/config.o \
$(OBJDIR)/logger.o \
$(OBJDIR)/main.o \
$(OBJDIR)/mutex.o \
$(OBJDIR)/peers.o \
$(OBJDIR)/random.o \
$(OBJDIR)/rpc.o \
$(OBJDIR)/sam.o \
$(OBJDIR)/sha1.o \
$(OBJDIR)/thread.o
#
# Build rules
#
all: depend enclave
depend:
$(CC) $(CFLAGS) -MM $(SRCDIR)/*.cpp > .depend
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
$(CC) $(CFLAGS) -o $@ -c $<
enclave: $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) -o $(BINDIR)/enclave $(OBJS) $(LIBS)
#
# Cleanup rules
#
clean:
-rm -f $(BINDIR)/* $(OBJDIR)/* .depend
clean-logs:
-rm -f $(LOGDIR)/*
tidy: clean clean-logs

View File

@ -1,32 +0,0 @@
#
# This is the Enclave configuration file. Lines starting with # and blank lines
# are ignored.
#
# The DNS name or IP address of the SAM server you will be using
samhost=localhost
# The TCP port the SAM server is listening on
samport=7656
# The destination name of this program. This can be anything. If you run
# multiple copies of Enclave off the same SAM server then each one has to have a
# unique name.
samname=enclave
# The depth used for incoming and outgoing I2P tunnels. Using a depth of 2 is
# the default and a good choice. You can set it to 0 if you don't care about
# anonymity and just want speed.
tunneldepth=0
# The location of the peer references file. You can use an absolute or relative
# path, but absolute paths are safer.
references=cfg/peers.ref
# Record every log message at or above this priority level
# debug = 0, minor = 1, info = 2, warn = 3, error = 4
loglevel=0
# The location of the Enclave log file. You can use an absolute or relative
# path, but absolute paths are safer.
logfile=log/enclave.log

View File

@ -1,2 +0,0 @@
4KpEG0uUvTM~IZKuWZZifdmh5UU6evIPG0tE3ppoqy37AY2NJrsM8BU0EkT1SG-g18qSW9UHDp7qs7m~WzeWTXyYggEb6k6-e0GYC2Cj8ED8JV58-2~cFZumVNJ2d1hns-MGX7RZv2lz3Cz2ZVhfZxSIw9UnpV-kwVn7sQ7PBCvJYE4INbp5OlRQH1-3lXiUheoJfeZpegGTUSHUwIRWglX7w87YF~LCbJMYXDgMyA3SaxsZaun7Wc8ku4bqtbmG9u15XlmqimLUUmDG0cw77HJzqxnR1C1hx0wf-9zgH6u4jwTWk92w5tZJZSv1SHKejlPkIbRNAhZv5wroyZsn6T0koV~kTVCvbUEwILho-rHn4A6C2jLQifwE9aucziBTVq3YLK2urf1wI1jLh98iFNav40S~B2w-4xZFAQ49bOdWzY4KmVIjocVhfGi~RLl5bHD1TEJS7nOaDhI8qCSe7mR0XzZgQ~iROR~XowlwKXBzNPjKED7yN8GgV2pWRGNYAAAA
WiotuvEjGpSz7q14eZGYFpD0xNt3V~nxZdDDgKc~whkW-pardZyz~wZipHXLIOvniThDL2rxJ~OW7RxgUycCph4x--NL51kEJhMWZ~bgxPioxw-T4JGQ9LSNndt9xNOf6yhEqyokqyEOEeJjw6m2e7RX7mTRffmTlCdu6uH6rVEk22o4Uu5S26p6-LS2k9lRyMWitFd~t9cnOgLTZTE~h4d-UlAd1BGxpCTlGWcaynOQzKKtljZknZMF9Qv19MxT83t18~3IURb6aOLlC4oih9pMt1pHouZuOaStKA7cGLsXUAhSB31BvK8l4R7VhgcudwJ9EQZkZQee51hcng7K1Yqmd4lnjHHuf1mDk0YXBAWDZOM0-oEwkJWumGuYl0NUtLhNlFrBjenbjACx88qhfy6mkXfo8c-c2QqEXuD2xt4OVqrWxBTIrr1pR-E1NdIxzIvOlCbrRXaqxqu-wnrrG2vCO-1zu9NHacCVjXD7AR7p3T628wPdCUzj2~rZRcCkAAAA

View File

@ -1,27 +0,0 @@
Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of any contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,160 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
*/
#include "platform.hpp"
#include "mutex.hpp"
#include "time.hpp"
#include "logger.hpp"
using namespace Libsockthread;
/*
* Closes the log file
*/
void Logger::close()
{
logf_m.lock();
if (logf == NULL) {
logf_m.unlock();
return;
}
if (fclose(logf) == EOF) {
cerr_m.lock();
cerr << "fclose() failed: " << strerror(errno) << '\n';
cerr_m.unlock();
}
logf = NULL;
logf_m.unlock();
}
/*
* Sends a line to the log file. Uses variable arguments just like printf().
*/
void Logger::log(priority_t priority, const char* format, ...)
{
if (priority < get_loglevel())
return;
char ll;
switch (priority) {
case Logger::DEBUG:
ll = 'D';
break;
case Logger::MINOR:
ll = 'M';
break;
case Logger::INFO:
ll = 'I';
break;
case Logger::WARN:
ll = 'W';
break;
case Logger::ERROR:
ll = 'E';
break;
default:
ll = '?';
}
va_list ap;
va_start(ap, format);
Time t;
logf_m.lock();
if (logf != NULL) {
/*
* Remember! If you change the format here, change it in the else too
*/
fprintf(logf, "%c %s ", ll, t.utc().c_str());
vfprintf(logf, format, ap);
fputc('\n', logf);
if (fflush(logf) == EOF) {
cerr_m.lock();
cerr << "fflush() failed: " << strerror(errno) << '\n';
cerr_m.unlock();
}
} else {
// if they don't have an open log file, just use stderr
fprintf(stderr, "%c %s ", ll, t.utc().c_str());
vfprintf(stderr, format, ap);
fputc('\n', stderr);
}
va_end(ap);
logf_m.unlock();
return;
}
/*
* Opens a log file for appending. If a log file is already open, then it is
* closed and the new one is opened.
*
* file - file location to open
*/
bool Logger::open(const string& file)
{
close();
logf_m.lock();
logf = fopen(file.c_str(), "a");
if (logf != NULL) {
logf_m.unlock();
return true;
} else {
logf_m.unlock();
cerr_m.lock();
cerr << "fopen() failed (" << file << "): " << strerror(errno) << '\n';
cerr_m.unlock();
return false;
}
}
#ifdef UNIT_TEST
// g++ -Wall -c thread.cpp -o thread.o
// g++ -Wall -c mutex.cpp -o mutex.o
// g++ -Wall -c time.cpp -o time.o
// g++ -Wall -DUNIT_TEST -c logger.cpp -o logger.o
// g++ -Wall -DUNIT_TEST logger.o mutex.o thread.o time.o -o logger -pthread
int main()
{
Logger logger;
logger.open("delete.me");
logger.set_loglevel(Logger::MINOR);
logger.close();
LWARNS("This should appear on stderr");
logger.open("delete.me.also");
LINFO("%s\n", "hey it works");
LDEBUGS("This shouldn't be saved in the file.");
return 0;
}
#endif // UNIT_TEST

View File

@ -1,98 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
*/
#ifndef LIBSOCKTHREAD_LOGGER_HPP
#define LIBSOCKTHREAD_LOGGER_HPP
/*
* Some helpful macros:
*
* LDEBUG - debugging messages
* LMINOR - unimportant messages
* LINFO - informational messages
* LWARN - errors we automatically recover from
* LERROR - major, important errors
*
* These only work if your Logger object is called "logger"
*/
// Prints out the file name, function name, and line number before the message
#define LDEBUG(format, ...) logger.log(Logger::DEBUG, "%s:%s:%d:" \
format, __FILE__, __func__, __LINE__, __VA_ARGS__)
// This is the same as above, except it doesn't accept varargs
#define LDEBUGS(str) logger.log(Logger::DEBUG, "%s:%s:%d:" \
str, __FILE__, __func__, __LINE__);
#define LMINOR(format, ...) logger.log(Logger::MINOR, "%s:%s:%d:" \
format, __FILE__, __func__, __LINE__, __VA_ARGS__)
#define LMINORS(str) logger.log(Logger::MINOR, "%s:%s:%d:" \
str, __FILE__, __func__, __LINE__);
#define LINFO(format, ...) logger.log(Logger::INFO, "%s:%s:%d:" \
format, __FILE__, __func__, __LINE__, __VA_ARGS__)
#define LINFOS(str) logger.log(Logger::INFO, "%s:%s:%d:" \
str, __FILE__, __func__, __LINE__);
#define LWARN(format, ...) logger.log(Logger::WARN, "%s:%s:%d:" \
format, __FILE__, __func__, __LINE__, __VA_ARGS__)
#define LWARNS(str) logger.log(Logger::WARN, "%s:%s:%d:" \
str, __FILE__, __func__, __LINE__);
#define LERROR(format, ...) logger.log(Logger::ERROR, "%s:%s:%d:" \
format, __FILE__, __func__, __LINE__, __VA_ARGS__)
#define LERRORS(str) logger.log(Logger::ERROR, "%s:%s:%d:" \
str, __FILE__, __func__, __LINE__);
namespace Libsockthread {
class Logger {
public:
enum priority_t {DEBUG = 0, MINOR = 1, INFO = 2, WARN = 3,
ERROR = 4};
Logger()
: logf(NULL), loglevel(Logger::DEBUG) { }
~Logger()
{ close(); }
void close();
void log(priority_t priority, const char* format, ...);
priority_t get_loglevel()
{ loglevel_m.lock(); priority_t ll = loglevel;
loglevel_m.unlock(); return ll; }
bool open(const string& file);
void set_loglevel(priority_t priority)
{ loglevel_m.lock(); loglevel = priority; loglevel_m.unlock(); }
private:
Mutex cerr_m;
FILE* logf;
Mutex logf_m;
priority_t loglevel;
Mutex loglevel_m;
};
}
#endif // LIBSOCKTHREAD_LOGGER_HPP

View File

@ -1,134 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
*/
/*
* Modelled after JThread by Jori Liesenborgs
*/
#include "platform.hpp"
#include "mutex.hpp"
using namespace Libsockthread;
/*
* Creates a mutex
*/
Mutex::Mutex()
{
#ifdef WINTHREAD
mutex = CreateMutex(NULL, false, NULL);
assert(mutex != NULL);
#else
int rc = pthread_mutex_init(&mutex, NULL);
assert(rc == 0);
#endif
}
/*
* Destroys a mutex
*/
Mutex::~Mutex()
{
#ifdef WINTHREAD
BOOL rc = CloseHandle(mutex);
assert(rc);
#else
int rc = pthread_mutex_destroy(&mutex);
assert(rc == 0);
#endif
}
/*
* Locks the mutex
*/
void Mutex::lock()
{
#ifdef WINTHREAD
DWORD rc = WaitForSingleObject(mutex, INFINITE);
assert(rc != WAIT_FAILED);
#else
int rc = pthread_mutex_lock(&mutex);
assert(rc == 0);
#endif
}
/*
* Unlocks the mutex
*/
void Mutex::unlock()
{
#ifdef WINTHREAD
BOOL rc = ReleaseMutex(mutex);
assert(rc);
#else
int rc = pthread_mutex_unlock(&mutex);
assert(rc == 0);
#endif
}
#ifdef UNIT_TEST
// g++ -Wall -c thread.cpp -o thread.o
// g++ -Wall -DUNIT_TEST -c mutex.cpp -o mutex.o
// g++ -Wall -DUNIT_TEST mutex.o thread.o -o mutex -pthread
#include "thread.hpp"
Mutex widget;
int main()
{
class Mutex_test : public Thread
{
public:
Mutex_test(int n)
: testval(n) {}
void* thread()
{
widget.lock();
cout << "I got it! thread #" << testval << '\n';
// If this works, only one thread should be able to lock the
// widget, since it is never unlocked
return 0;
}
private:
int testval;
};
Mutex_test t1(1);
Mutex_test t2(2);
Mutex_test t3(3);
t1.start(); t2.start(); t3.start();
while (true);
return 0;
}
#endif // UNIT_TEST

View File

@ -1,57 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
*/
/*
* Modelled after JThread by Jori Liesenborgs
*/
#ifndef LIBSOCKTHREAD_MUTEX_HPP
#define LIBSOCKTHREAD_MUTEX_HPP
namespace Libsockthread {
class Mutex {
public:
Mutex();
~Mutex();
void lock();
void unlock();
private:
#ifdef WINTHREAD
HANDLE mutex;
#else
pthread_mutex_t mutex;
#endif
};
}
#endif // LIBSOCKTHREAD_MUTEX_HPP

View File

@ -1,77 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: platform.hpp,v 1.5 2004/07/22 03:54:01 mpc Exp $
*/
/*
* Global includes and platform configuration. This is used to compile the
* library, but is not intended for use by users of the library in their
* own programs.
*/
#ifndef LIBSOCKTHREAD_PLATFORM_HPP
#define LIBSOCKTHREAD_PLATFORM_HPP
/*
* Operating system
*/
#define FREEBSD 0 // FreeBSD
#define WIN32 1 // Windows
#define LINUX 2 // Linux
#if OS == WIN32
#define WINSOCK
#define WINTHREAD
#endif
#ifndef WINSOCK
#include <arpa/inet.h>
#endif
#include <cassert>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <ctime>
#include <iostream>
#ifndef WINSOCK
#include <netdb.h>
#endif
#ifndef WINTHREAD
#include <pthread.h>
#endif
#include <stdint.h> // TODO replace with Boost's version
#include <string>
#if defined WINSOCK || defined WINTHREAD
#include <windows.h>
#endif
using namespace std;
#include "types.hpp"
#endif // LIBSOCKTHREAD_PLATFORM_HPP

View File

@ -1,72 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: socket.cpp,v 1.8 2004/07/22 22:08:20 mpc Exp $
*/
#include "platform.hpp"
#include "socket_error.hpp"
#include "socket.hpp"
using namespace Libsockthread;
/*
* Closes the socket
*/
void Socket::close()
{
if (sock != SERR) {
if (close(sock) == -1)
; // FIXME log the error
}
sock = SERR;
}
/*
* Changes the address associated with the socket
*/
void Socket::set_addr(Socket_addr& addr)
{
close();
this->addr = addr;
setup_socket();
}
/*
* Prepares the socket for use
*/
void Socket::setup_socket()
{
assert(sock == SERR); // the descriptor shouldn't be active
if (!addr.is_ready())
throw Socket_error("Couldn't create socket: address isn't ready");
sock = socket(addr.get_family(), addr.get_type(), 0);
if (sock == SERR)
throw Socket_error(strerror(errno));
}

View File

@ -1,68 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: socket.hpp,v 1.8 2004/07/22 22:08:20 mpc Exp $
*/
#ifndef LIBSOCKTHREAD_SOCKET_HPP
#define LIBSOCKTHREAD_SOCKET_HPP
namespace Libsockthread {
class Socket {
public:
#ifdef WINSOCK
typedef SOCKET socket_t;
enum { SERR = SOCKET_ERROR };
#else
typedef int socket_t;
enum { SERR = -1 };
#endif
Socket()
: addr(), sock(SERR) {}
Socket(Socket_addr& addr) // throws Socket_error
: addr(addr), sock(SERR) { setup_socket(); }
void close();
size_t read(vector<uchar_t>& buf, size_t max = 0);
size_t read_until(vector<uchar_t>& buf, uchar_t delim = '\n');
void set_addr(Socket_addr& addr); // throws Socket_error
void set_blocking(bool blocking);
size_t write(vector<uchar_t>& buf);
void write_all(vector<uchar_t>& buf);
size_t write_until(vector<uchar_t& buf, uchar_t delim = '\n');
private:
void setup_socket(); // throws Socket_error
Socket_addr addr;
socket_t sock;
};
}
#endif // LIBSOCKTHREAD_SOCKET_HPP

View File

@ -1,108 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: socket_addr.cpp,v 1.4 2004/07/22 19:10:59 mpc Exp $
*/
#include "platform.hpp"
#include "socket_error.hpp"
#include "socket_addr.hpp"
using namespace Libsockthread;
Socket_addr::Socket_addr(Socket_addr& rhs)
{
delete[] ip;
if (rhs.resolved) {
if (rhs.family == AF_INET) {
ip = new char[INET_ADDRSTRLEN];
else
ip = new char[INET6_ADDRSTRLEN];
strcpy(ip, rhs.ip);
}
family = rhs.family;
host = rhs.host;
port = rhs.port;
resolved = rhs.resolved;
type = rhs.type;
}
Socket_addr& Socket_addr::operator=(const Socket_addr& rhs)
{
if (this == &rhs) // check for self-assignment: a = a
return *this;
delete[] ip;
if (rhs.resolved) {
if (rhs.family == AF_INET)
ip = new char[INET_ADDRSTRLEN];
else
ip = new char[INET6_ADDRSTRLEN];
strcpy(ip, rhs.ip);
}
family = rhs.family;
host = rhs.host;
port = rhs.port;
type = rhs.type;
return *this;
}
/*
* Performs a DNS lookup
*/
void Socket_addr::resolve()
{
resolved = false; // in case they already had a host name but just set a
// new one with set_host()
hostent* hent = gethostbyname(host.c_str());
if (hent == NULL)
throw Dns_error(hstrerror(h_errno));
assert(hent->h_addrtype == AF_INET || hent->h_addrtype == AF_INET6);
family = hent->h_addrtype;
delete[] ip;
if (family == AF_INET) {
ip = new char[INET_ADDRSTRLEN];
else
ip = new char[INET6_ADDRSTRLEN];
strcpy(ip, hent->h_addr_list[0]);
resolved = true;
}
bool Socket_addr::operator==(const Socket_addr& rhs)
{
if (rhs.family == family
&& rhs.host == host
&& strcmp(rhs.ip, ip) == 0
&& rhs.port == port
&& rhs.resolved == resolved
&& rhs.type == type)
return true;
else
return false;
}

View File

@ -1,78 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: socket_addr.hpp,v 1.4 2004/07/22 19:10:59 mpc Exp $
*/
#ifndef LIBSOCKTHREAD_SOCKET_ADDR_HPP
#define LIBSOCKTHREAD_SOCKET_ADDR_HPP
namespace Libsockthread {
class Socket_addr {
public:
Socket_addr()
: family(AF_INET), resolved(false) { }
Socket_addr(Socket_addr& rhs);
Socket_addr(int type, string& host, uint16_t port)
: family(AF_INET), host(host), type(type), port(port)
{ resolve(); } // throws Dns_error
~Socket_addr()
{ delete[] ip; }
int get_family() const
{ return family; }
const char* get_ip() const // Warning! This can be NULL!
{ return ip; }
uint16_t get_port() const
{ return port; }
int get_type() const
{ return type;
bool is_ready() const
{ return resolved; }
Socket_addr& operator=(const Socket_addr& rhs);
bool operator==(const Socket_addr& rhs);
void set_host(string& host) // throws Dns_error
{ this->host = host; resolve(); }
void set_port(uint16_t port)
{ this->port = port; }
void set_type(int type)
{ this->type = type; }
private:
void resolve(); // throws Dns_error
int family; // AF_INET or AF_INET6
string host;
char* ip;
uint16_t port;
bool resolved;
int type; // SOCK_STREAM or SOCK_DGRAM
};
}
#endif // LIBSOCKTHREAD_SOCKET_ADDR_HPP

View File

@ -1,35 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
*/
#include "platform.hpp"
#include "socket_connector.hpp"
using namespace Libsockthread;

View File

@ -1,46 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
*/
#ifndef LIBSOCKTHREAD_SOCKET_CONNECTOR_HPP
#define LIBSOCKTHREAD_SOCKET_CONNECTOR_HPP
namespace Libsockthread {
class Socket_connector : public Socket {
public:
Socket_connector(Socket_addr& addr)
: Socket(addr);
void connect();
};
}
#endif // LIBSOCKTHREAD_SOCKET_CONNECTOR_HPP

View File

@ -1,47 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef LIBSOCKTHREAD_SOCKET_ERROR_HPP
#define LIBSOCKTHREAD_SOCKET_ERROR_HPP
namespace Libsockthread {
class Socket_error : public runtime_error {
public:
Socket_error(const string& s)
: runtime_error(s) { }
};
class Dns_error : public Socket_error {
public:
Dns_error(const string& s)
: Socket_error(s) { }
};
}
#endif // LIBSOCKTHREAD_SOCKET_ERROR_HPP

View File

@ -1,35 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
*/
#include "platform.hpp"
#include "socket_listener.hpp"
using namespace Libsockthread;

View File

@ -1,47 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
*/
#ifndef LIBSOCKTHREAD_SOCKET_LISTENER_HPP
#define LIBSOCKTHREAD_SOCKET_LISTENER_HPP
namespace Libsockthread {
class Socket_listener {
public:
Socket_listener(Socket_addr& addr)
: Socket(addr);
void accept();
void listen();
};
}
#endif // LIBSOCKTHREAD_SOCKET_LISTENER_HPP

View File

@ -1,86 +0,0 @@
/*
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* $Id$
*/
#include <stddef.h>
#include <string.h>
/*
* Appends src to string dst of size siz (unlike strncat, siz is the
* full size of dst, not space left). At most siz-1 characters
* will be copied. Always NUL terminates (unless siz <= strlen(dst)).
* Returns strlen(src) + MIN(siz, strlen(initial dst)).
* If retval >= siz, truncation occurred.
*/
size_t
strlcat(char *dst, const char *src, size_t siz)
{
register char *d = dst;
register const char *s = src;
register size_t n = siz;
size_t dlen;
/* Find the end of dst and adjust bytes left but don't go past end */
while (n-- != 0 && *d != '\0')
d++;
dlen = d - dst;
n = siz - dlen;
if (n == 0)
return(dlen + strlen(s));
while (*s != '\0') {
if (n != 1) {
*d++ = *s;
n--;
}
s++;
}
*d = '\0';
return(dlen + (s - src)); /* count does not include NUL */
}
/*
* Copy src to string dst of size siz. At most siz-1 characters
* will be copied. Always NUL terminates (unless siz == 0).
* Returns strlen(src); if retval >= siz, truncation occurred.
*/
size_t
strlcpy(char *dst, const char *src, size_t siz)
{
register char *d = dst;
register const char *s = src;
register size_t n = siz;
/* Copy as many bytes as will fit */
if (n != 0 && --n != 0) {
do {
if ((*d++ = *s++) == 0)
break;
} while (--n != 0);
}
/* Not enough room in dst, add NUL and traverse rest of src */
if (n == 0) {
if (siz != 0)
*d = '\0'; /* NUL-terminate dst */
while (*s++)
;
}
return(s - src - 1); /* count does not include NUL */
}

View File

@ -1,49 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
*/
/*
* Note: The strl.c file retains its original license (at the top of strl.c)
*/
#ifndef LIBSOCKTHREAD_STRL_H
#define LIBSOCKTHREAD_STRL_H
#ifdef __cplusplus
extern "C" {
#endif
extern size_t strlcat(char *dst, const char *src, size_t siz);
extern size_t strlcpy(char *dst, const char *src, size_t siz);
#ifdef __cplusplus
}
#endif
#endif /* LIBSOCKTHREAD_STRL_H */

View File

@ -1,194 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
*/
/*
* Modelled after JThread by Jori Liesenborgs
*/
#include "platform.hpp"
#include "mutex.hpp"
#include "thread.hpp"
using namespace Libsockthread;
/*
* Gets the return value of a finished thread
*/
void* Thread::get_retval()
{
void* val;
running_m.lock();
if (running)
val = NULL;
else
val = retval;
running_m.unlock();
return val;
}
/*
* Checks whether the thread is running
*/
bool Thread::is_running()
{
running_m.lock();
bool r = running;
running_m.unlock();
return r;
}
/*
* Stops the thread
* Generally NOT a good idea
*/
void Thread::kill()
{
running_m.lock();
#ifndef NDEBUG
// make sure it as actually running first
if (!running) {
running_m.unlock();
assert(false);
}
#endif
#ifdef WINTHREAD
BOOL rc = TerminateThread(handle, NULL);
assert(rc);
#else
int rc = pthread_cancel(id);
assert(rc == 0);
#endif
running = false;
running_m.unlock();
}
/*
* Starts the thread
*/
void Thread::start()
{
#ifndef NDEBUG
// check whether the thread is already running
running_m.lock();
assert(!running);
running_m.unlock();
#endif
continue_m.lock();
#ifdef WINTHREAD
handle = CreateThread(NULL, 0, &the_thread, this, 0, &id);
assert(handle != NULL);
#else
int rc = pthread_create(&id, 0, &the_thread, this);
assert(rc == 0);
#endif
// Wait until `running' is set
running_m.lock();
while (!running) {
running_m.unlock();
running_m.lock();
}
running_m.unlock();
continue_m.unlock();
}
/*
* Wrapper for the thread
*/
void* Thread::the_thread(void *param)
{
Thread* t = static_cast<Thread*>(param);
t->running_m.lock();
t->running = true;
t->running_m.unlock();
// wait until we can continue
t->continue_m.lock();
t->continue_m.unlock();
void* ret = t->thread();
t->running_m.lock();
t->running = false;
t->retval = ret;
t->running_m.unlock();
return 0;
}
#ifdef UNIT_TEST
// g++ -Wall -c mutex.cpp -o mutex.o
// g++ -Wall -DUNIT_TEST -c thread.cpp -o thread.o
// g++ -Wall -DUNIT_TEST mutex.o thread.o -o thread -pthread
int main()
{
class Thread_test : public Thread
{
public:
Thread_test(int testval)
: testval(testval) { }
int get_testval()
{
testval_m.lock();
int rc = testval;
testval_m.unlock();
return rc;
}
void *thread()
{
// just do something
while (true) {
testval_m.lock();
++testval;
testval_m.unlock();
}
return 0;
}
private:
int testval;
Mutex testval_m;
};
Thread_test t1(1);
t1.start();
Thread_test t2(1000000);
t2.start();
Thread_test t3(-1000000);
t3.start();
while (true) {
if (t1.is_running())
cout << "t1 is running..." << t1.get_testval() << '\n';
if (t2.is_running())
cout << "t2 is running..." << t2.get_testval() << '\n';
if (t3.is_running())
cout << "t3 is running..." << t3.get_testval() << '\n';
}
return 0;
}
#endif // UNIT_TEST

View File

@ -1,69 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
*/
/*
* Modelled after JThread by Jori Liesenborgs
*/
#ifndef LIBSOCKTHREAD_THREAD_HPP
#define LIBSOCKTHREAD_THREAD_HPP
namespace Libsockthread {
class Thread {
public:
Thread()
: retval(NULL), running(false) { }
virtual ~Thread()
{ kill(); }
void* get_retval();
bool is_running();
void kill();
void start();
virtual void* thread() = 0;
private:
#ifdef WINTHREAD
static DWORD WINAPI the_thread(void* param);
HANDLE handle;
DWORD id;
#else
static void* the_thread(void* param);
pthread_t id;
#endif
Mutex continue_m;
void* retval;
bool running;
Mutex running_m;
};
}
#endif // LIBSOCKTHREAD_THREAD_HPP

View File

@ -1,85 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
*/
#include "platform.hpp"
#include "time.hpp"
using namespace Libsockthread;
/*
* Converts the time to an ISO 8601 standard date and time
* Example: 2004-07-01T19:03:47Z
*/
string& Time::utc()
{
struct tm* tm = gmtime(&unixtime);
char t[21];
strftime(t, sizeof t, "%Y-%m-%dT%H:%M:%SZ", tm);
return formatted = t;
}
/*
* Converts the time to an ISO 8601 standard date
* Example: 2004-07-01Z
*/
string& Time::utc_date()
{
struct tm* tm = gmtime(&unixtime);
char t[12];
strftime(t, sizeof t, "%Y-%m-%dZ", tm);
return formatted = t;
}
/*
* Converts the time to an ISO 8601 standard time
* Example: 19:03:47Z
*/
string& Time::utc_time()
{
struct tm* tm = gmtime(&unixtime);
char t[10];
strftime(t, sizeof t, "%H:%M:%SZ", tm);
return formatted = t;
}
#ifdef UNIT_TEST
// g++ -Wall -DUNIT_TEST time.cpp -o time
int main()
{
Time t;
cout << "Current date and time is " << t.utc() << '\n';
cout << "Current date is " << t.utc_date() << '\n';
cout << "Current time is " << t.utc_time() << '\n';
cout << "Formatted time is " << t.get_formatted() << " (should be the same)\n";
return 0;
}
#endif // UNIT_TEST

View File

@ -1,55 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
*/
#ifndef LIBSOCKTHREAD_TIME_HPP
#define LIBSOCKTHREAD_TIME_HPP
namespace Libsockthread {
class Time {
public:
Time()
{ now(); }
string& get_formatted()
{ return formatted; }
void now()
{ unixtime = time(0); }
string& utc();
string& utc_date();
string& utc_time();
private:
string formatted;
time_t unixtime;
};
}
#endif // LIBSOCKTHREAD_TIME_HPP

View File

@ -1,45 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
*/
#ifndef LIBSOCKTHREAD_TYPES_HPP
#define LIBSOCKTHREAD_TYPES_HPP
/*
* Shorten some standard variable types
*/
typedef signed char schar_t;
typedef unsigned char uchar_t;
typedef unsigned int uint_t;
typedef unsigned long ulong_t;
typedef unsigned short ushort_t;
#endif // LIBSOCKTHREAD_TYPES_HPP

View File

@ -1,169 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "platform.hpp"
#include "bigint.hpp"
/******************************************************************************/
// Note: All the const_casts below are necessary because libtomcrypt doesn't //
// have its arguments as const, even when they are not changed //
/******************************************************************************/
Bigint::Bigint(const Bigint& bigint)
{
init();
copyover_mp_int(bigint.mpi);
}
Bigint::Bigint(const uchar_t* data, size_t size)
{
init();
import_uraw(data, size);
}
Bigint::Bigint(uint16_t i)
{
init();
i = htons(i);
import_uraw(reinterpret_cast<uchar_t*>(&i), 2);
}
Bigint::Bigint(uint32_t i)
{
init();
i = htonl(i);
import_uraw(reinterpret_cast<uchar_t*>(&i), 4);
}
/*
* Replaces our current mp_int with another one
* (just a wrapper for mp_copy)
*/
void Bigint::copyover_mp_int(const mp_int& i)
{
int rc = mp_copy(const_cast<mp_int*>(&i), &mpi);
assert(rc == MP_OKAY);
}
/*
* Saves a Bigint to a raw unsigned big-endian integer
* Note that the result must be freed with delete[]
*
* size - filled with the size of the output
*
* Returns: binary data
*/
uchar_t* Bigint::export_uraw(size_t& size) const
{
uchar_t* out;
size = mp_unsigned_bin_size(const_cast<mp_int*>(&mpi));
if (size != 0) {
out = new uchar_t[size];
int rc = mp_to_unsigned_bin(const_cast<mp_int*>(&mpi), out);
assert(rc == MP_OKAY);
} else { // size == 0
size = 1;
out = new uchar_t[1];
out[0] = 0;
}
return out;
}
/*
* Loads a raw unsigned big-endian integer into Bigint
*
* data - binary data
* size - size of data
*/
void Bigint::import_uraw(const uchar_t* data, size_t size)
{
uchar_t tmp[size]; // mp_read_unsigned_bin() arg 2 is not const
memcpy(tmp, data, sizeof tmp); // I'm not taking any chances
int rc = mp_read_unsigned_bin(&mpi, tmp, sizeof tmp);
assert(rc == MP_OKAY);
}
/*
* Initialises the object
*/
void Bigint::init(void)
{
int rc = mp_init(&mpi);
assert(rc == MP_OKAY);
}
bool Bigint::operator<(const Bigint& rhs) const
{
int rc = mp_cmp(const_cast<mp_int*>(&mpi), const_cast<mp_int*>(&rhs.mpi));
if (rc == MP_LT)
return true;
else
return false;
}
Bigint& Bigint::operator=(const Bigint& rhs)
{
if (this != &rhs) // check for self-assignment: a = a
copyover_mp_int(rhs.mpi);
return *this;
}
bool Bigint::operator==(const Bigint& rhs) const
{
int rc = mp_cmp(const_cast<mp_int*>(&mpi), const_cast<mp_int*>(&rhs.mpi));
if (rc == MP_EQ)
return true;
else
return false;
}
bool Bigint::operator>(const Bigint& rhs) const
{
int rc = mp_cmp(const_cast<mp_int*>(&mpi), const_cast<mp_int*>(&rhs.mpi));
if (rc == MP_GT)
return true;
else
return false;
}
/*
* Xors another Bigint with this Bigint and puts the result in Bigint `result'.
* We can't name it "xor" because that word is reserved in C++ (see Appendex C,
* section 3.1 in TC++PL).
*
* rhs - the bigint to xor with
* result - will be filled with the result of the xor
*/
void Bigint::x_or(const Bigint& rhs, Bigint& result) const
{
int rc = mp_xor(const_cast<mp_int*>(&mpi), const_cast<mp_int*>(&rhs.mpi),
&result.mpi);
assert(rc == MP_OKAY);
}

View File

@ -1,60 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BIGINT_HPP
#define BIGINT_HPP
class Bigint {
public:
Bigint(void) { init(); }
Bigint(const Bigint& bigint);
Bigint(const uchar_t* data, size_t size);
Bigint(uint16_t i);
Bigint(uint32_t i);
~Bigint(void) { mp_clear(&mpi); }
uchar_t* export_uraw(size_t& size) const;
const mp_int& get_mp_int(void) const { return mpi; }
void import_uraw(const uchar_t* data, size_t size);
bool operator<(const Bigint& rhs) const;
Bigint& operator=(const Bigint& rhs);
bool operator==(const Bigint& rhs) const;
bool operator>(const Bigint& rhs) const;
void x_or(const Bigint& rhs, Bigint& result) const;
protected:
mp_int mpi;
private:
void copyover_mp_int(const mp_int& i);
void init(void);
};
#endif // BIGINT_HPP

View File

@ -1,56 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "platform.hpp"
#include "chk.hpp"
Chk::Chk(const uchar_t* plaintext, size_t size, const string& mime_type)
: data_size(size), mime_type(mime_type)
{
encrypt(plaintext);
}
void Chk::encrypt(const uchar_t *pt)
{
int rc = register_cipher(&twofish_desc);
assert(rc != -1);
uchar_t key[CRYPT_KEY_SIZE], iv[CRYPT_BLOCK_SIZE];
prng->get_bytes(key, CRYPT_KEY_SIZE);
prng->get_bytes(iv, CRYPT_BLOCK_SIZE);
symmetric_CTR ctr;
rc = ctr_start(find_cipher("twofish"), iv, key, CRYPT_KEY_SIZE, 0, &ctr);
assert(rc == CRYPT_OK);
ct = new uchar_t[data_size];
rc = ctr_encrypt(pt, ct, data_size, &ctr);
assert(rc == CRYPT_OK);
}

View File

@ -1,51 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CHK_HPP
#define CHK_HPP
class Chk {
public:
//Chk(const uchar_t* cypertext, size_t size);
Chk(const uchar_t* plaintext, size_t size, const string& mime_type);
~Chk(void) { delete[] ct; }
private:
static const size_t CRYPT_BLOCK_SIZE = 16;
static const size_t CRYPT_KEY_SIZE = 32;
void encrypt(const uchar_t *pt);
uchar_t* ct; // cyphertext
const size_t data_size;
const string& mime_type; // I hate mimes.
};
#endif // CHK_HPP

View File

@ -1,148 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "platform.hpp"
#include "bigint.hpp"
Config::Config(const string& file)
: file(file)
{
set_defaults();
parse();
configf.close();
}
/*
* Looks up a configuration option in the table and returns a constant value.
* This is the same as get_property() except the value returned is a constant.
*
* key - key to lookup
*
* Returns the value associated with the key
*/
const string& Config::get_cproperty(const string& key) const
{
for (cfgmap_ci i = cfgmap.begin(); i != cfgmap.end(); i++) {
const string s = i->first;
if (s == key)
return i->second;
}
LERROR << "Tried to lookup an invalid property: " << key << '\n';
assert(false);
// this should never occur, it's just to silence a compiler warning
string* s = new string;
return *s;
}
/*
* Gets a property as an integer (they are all stored as strings)
*
* key - key to lookup
*
* Returns an integer of the value associated with the key
*/
int Config::get_iproperty(const string& key) const
{
for (cfgmap_ci i = cfgmap.begin(); i != cfgmap.end(); i++) {
const string s = i->first;
if (s == key)
return atoi(i->second.c_str());
}
LERROR << "Tried to lookup an invalid property: " << key << '\n';
assert(false);
return 0;
}
/*
* Looks up a configuration option in the table and returns the value
*
* key - key to lookup
*
* Returns the value associated with the key
*/
string& Config::get_property(const string& key)
{
for (cfgmap_i i = cfgmap.begin(); i != cfgmap.end(); i++) {
const string s = i->first;
if (s == key)
return i->second;
}
LERROR << "Tried to lookup an invalid property: " << key << '\n';
assert(false);
// this should never occur, it's just to silence a compiler warning
string* s = new string;
return *s;
}
/*
* Parses the configuration file, replacing default values with user defined
* values
*/
void Config::parse(void)
{
configf.open(file.c_str());
if (!configf) {
cerr << "Error opening configuration file (" << file.c_str() << ")\n";
throw runtime_error("Error opening configuration file");
}
size_t line = 0;
string s;
for (getline(configf, s); configf; getline(configf, s)) {
line++;
if (s.size() == 0 || s[0] == '#') // blank line or comment
continue;
size_t eqpos = s.find("=");
if (eqpos == string::npos) {
cerr << "Error parsing line #" << line << " in " << file << ": "
<< s << '\n';
continue;
}
string key = s.substr(0, eqpos);
string value = s.substr(eqpos + 1);
//cout << "Inserting key = " << key << " value = " << value << '\n';
cfgmap.erase(key); // erase the default value created by set_defaults()
cfgmap.insert(make_pair(key, value));
}
}
/*
* If you (the programmer) add something to the config file you should also add
* it here, and vice versa
*/
void Config::set_defaults(void)
{
cfgmap.insert(make_pair("samhost", "localhost"));
cfgmap.insert(make_pair("samport", "7656"));
cfgmap.insert(make_pair("samname", "enclave"));
cfgmap.insert(make_pair("tunneldepth", "2"));
cfgmap.insert(make_pair("references", "cfg/peers.ref"));
cfgmap.insert(make_pair("loglevel", "1"));
cfgmap.insert(make_pair("logfile", "log/enclave.log"));
}

View File

@ -1,54 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CONFIG_HPP
#define CONFIG_HPP
class Config {
public:
Config(const string& file);
const string& get_cproperty(const string& key) const;
int get_iproperty(const string& key) const;
string& get_property(const string& key);
private:
typedef map<const string, string>::const_iterator cfgmap_ci;
typedef map<const string, string>::iterator cfgmap_i;
void parse(void);
void set_defaults(void);
ifstream configf;
const string file;
map<const string, string> cfgmap;
};
#endif // CONFIG_HPP

View File

@ -1,61 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "platform.hpp"
#include "logger.hpp"
Logger::Logger(const string& file)
: file(file)
{
set_pri(debug);
set_loglevel(static_cast<priority_t>(config->get_iproperty("loglevel")));
logf.open(file.c_str(), ios::app);
if (!logf) {
cerr << "Error opening log file (" << file.c_str() << ")\n";
throw runtime_error("Error opening log file");
}
}
#ifdef WIN_STRERROR
/*
* strerror() for primitive operating systems
*/
TCHAR* win_strerror(TCHAR* str, size_t size)
{
LPVOID lpMsgBuf;
DWORD dw = GetLastError();
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf,
0, NULL);
snprintf(str, size, "%s", lpMsgBuf);
LocalFree(lpMsgBuf);
return str;
}
#endif

View File

@ -1,88 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef LOGGER_HPP
#define LOGGER_HPP
/*
* LDEBUG - debugging messages
* LMINOR - unimportant messages
* LINFO - informational messages
* LWARN - errors we automatically recover from
* LERROR - major, important errors
*/
#if VERBOSE_LOGS
#define LDEBUG logger->set_pri(Logger::debug); (*logger) << "(D)" << __FILE__ << ':' << __LINE__ << ':' << __func__ << ": "
#define LMINOR logger->set_pri(Logger::minor); (*logger) << "(M)" << __FILE__ << ':' << __LINE__ << ':' << __func__ << ": "
#define LINFO logger->set_pri(Logger::info); (*logger) << "(I)" << __FILE__ << ':' << __LINE__ << ':' << __func__ << ": "
#define LWARN logger->set_pri(Logger::warn); (*logger) << "(W)" << __FILE__ << ':' << __LINE__ << ':' << __func__ << ": "
#define LERROR logger->set_pri(Logger::error); (*logger) << "(E)" << __FILE__ << ':' << __LINE__ << ':' << __func__ << ": "
#else
#define LDEBUG logger->set_pri(Logger::debug); (*logger) << "(D)"
#define LMINOR logger->set_pri(Logger::minor); (*logger) << "(M)"
#define LINFO logger->set_pri(Logger::info); (*logger) << "(I)"
#define LWARN logger->set_pri(Logger::warn); (*logger) << "(W)"
#define LERROR logger->set_pri(Logger::error); (*logger) << "(E)"
#endif
class Logger {
public:
typedef enum {debug = 0, minor = 1, info = 2, warn = 3, error = 4}
priority_t;
Logger(const string& file);
void flush(void) { logf.flush(); }
priority_t get_loglevel(void) const { return loglevel; }
void set_loglevel(priority_t priority) { loglevel = priority; }
Logger& operator<<(char c)
{ if (priority >= loglevel) { logf << c; flush(); } return *this; }
Logger& operator<<(const char* c)
{ if (priority >= loglevel) { logf << c; flush(); } return *this; }
Logger& operator<<(int i)
{ if (priority >= loglevel) { logf << i; flush(); } return *this; }
Logger& operator<<(const string& s)
{ if (priority >= loglevel) { logf << s; flush(); } return *this; }
Logger& operator<<(unsigned int i)
{ if (priority >= loglevel) { logf << i; flush(); } return *this; }
void set_pri(priority_t priority) { this->priority = priority; }
private:
priority_t priority; // importance of the following log message(s)
string file;
priority_t loglevel; // write log messsages at or above this priority
ofstream logf;
};
#ifdef WIN_STRERROR
TCHAR* win_strerror(TCHAR* str, size_t size);
#endif
#endif // LOGGER_HPP

View File

@ -1,84 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "platform.hpp"
#include "main.hpp"
Config *config; // Configuration options
Logger *logger; // Logging mechanism
Random *prng; // Random number generator
Sam *sam; // SAM connection
int main(int argc, char* argv[])
{
if (argc != 2) { // put some getopts stuff in here later
cerr << "Please specify the configuration file location.\n" \
"e.g. 'bin/enclave cfg/enclave.cfg'\n";
return 1;
}
try {
config = new Config(argv[1]);
} catch (const runtime_error& x) {
return 0;
}
logger = new Logger(config->get_cproperty("logfile"));
LINFO << "Enclave DHT - Built on " << __DATE__ << ' ' << __TIME__ << '\n';
prng = new Random;
try {
sam = new Sam(config->get_cproperty("samhost"),
config->get_iproperty("samport"), config->get_cproperty("samname"),
config->get_iproperty("tunneldepth"));
} catch (const Sam_error& x) {
LERROR << "SAM error: " << x.what() << '\n';
cerr << "SAM error: " << x.what() << '\n';
if (x.code() == SAM_SOCKET_ERROR) {
LERROR << "Check whether you have specified the correct SAM host " \
"and port number, and that I2P is running.\n";
cerr << "Check whether you have specified the correct SAM host " \
"and port number, and that\nI2P is running.\n";
}
return 1;
}
sam->naming_lookup();
while (sam->get_my_dest() == "")
sam->read_buffer(); // wait until we get our own dest back from lookup
sam->peers->advertise_self();
while (true)
sam->read_buffer();
delete sam;
delete prng;
delete logger;
delete config;
return 0;
}

View File

@ -1,36 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef MAIN_HPP
#define MAIN_HPP
// intentionally left blank
#endif // MAIN_HPP

View File

@ -1,54 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef NEAR_PEER_HPP
#define NEAR_PEER_HPP
//
// Used for finding the closest peers to a sha1
//
class Near_peer {
public:
Near_peer(const Bigint& distance, Peer* peer)
: distance(distance), peer(peer) {}
Peer* get_peer(void) const { return peer; }
bool operator<(const Near_peer& rhs) const
{ if (distance < rhs.distance) return true; else return false; }
protected:
const Bigint distance;
private:
Peer* peer;
};
#endif // NEAR_PEER_HPP

View File

@ -1,52 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef PEER_HPP
#define PEER_HPP
class Peer {
public:
Peer(const string& dest, const Sha1& kaddr)
: dest(dest), kaddr(kaddr), lag(-1) {}
const string& get_b64kaddr(void) const { return kaddr.b64hash(); }
const uchar_t* get_binkaddr(void) const { return kaddr.binhash(); }
const string& get_dest(void) const { return dest; }
int get_lag(void) const { return lag; }
const string get_sdest(void) const { return dest.substr(0, 8); }
void set_lag(int lag) { this->lag = lag; }
private:
const string dest;
const Sha1 kaddr;
int lag; // if -1, then it is unknown
};
#endif // PEER_HPP

View File

@ -1,220 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "platform.hpp"
#include "near_peer.hpp"
#include "rpc.hpp"
#include "sha1.hpp"
#include "peers.hpp"
/*
* Inform other peers of our existence and collect the destination addresses of
* nearby peers
*/
void Peers::advertise_self(void)
{
list<Near_peer> near_peers;
get_nearest(sam->get_my_sha1(), PAR_RPCS, near_peers);
for (list<Near_peer>::const_iterator i = near_peers.begin();
i != near_peers.end(); i++) {
Rpc rpc(i->get_peer());
rpc.find_peers(sam->get_my_sha1());
}
}
/*
* Find the `n' nearest peers by xoring a sha1 with a kaddr
*
* sha1 - sha1 to find nearness to
* n - number of peers to find
* near_peers - a list to put the found peers in
*/
void Peers::get_nearest(const Sha1& sha1, size_t n, list<Near_peer>& near_peers)
{
near_peers.clear(); // prevents duplicate peers in the list
for (peersmap_i i = peersmap.begin(); i != peersmap.end(); i++) {
const Sha1& kaddr = i->first;
Bigint distance;
sha1.x_or(kaddr, distance);
Near_peer np(distance, &(i->second));
near_peers.insert(near_peers.end(), np);
}
near_peers.sort();
while (near_peers.size() > n)
near_peers.pop_back();
}
Peer* Peers::get_peer_by_dest(const sam_pubkey_t dest)
{
const string s = dest;
return get_peer_by_dest(s);
}
/*
* Gets a peer by its base 64 destination address
*
* dest - destination
*
* Returns: pointer to peer, or 0 if the peer wasn't found
*/
Peer* Peers::get_peer_by_dest(const string& dest)
{
for (peersmap_i i = peersmap.begin(); i != peersmap.end(); i++) {
Peer& tmp = i->second;
if (tmp.get_dest() == dest)
return &(i->second);
}
return 0;
}
/*
* Gets a peer by its Kademlia address
*
* kaddr - Kademlia adddress
*
* Returns: pointer to peer, or 0 if the peer wasn't found
*/
Peer* Peers::get_peer_by_kaddr(const Sha1& kaddr)
{
peersmap_i i = peersmap.find(kaddr);
if (i != peersmap.end())
return &(i->second);
else
return 0;
}
/*
* Loads peer addresses from a file
*/
void Peers::load(void)
{
string dest;
ifstream peersf(file.c_str());
if (!peersf) {
LERROR << "Couldn't load peers reference file (" << file.c_str()
<< ")\n";
if (peersmap.size() > 0)
return;
else
throw runtime_error("No peer references in memory");
}
for (getline(peersf, dest); peersf; getline(peersf, dest))
new_peer(dest);
if (peersmap.size() > 0) {
LMINOR << peersmap.size() << " peer references in memory\n";
} else
throw runtime_error("No peer references in memory");
}
Peer* Peers::new_peer(const sam_pubkey_t dest)
{
const string s = dest;
return new_peer(s);
}
/*
* Adds a newly discovered peer to the peers map
*
* dest - destination address of the peer
*
* Returns: pointer to the peer
*/
Peer* Peers::new_peer(const string& dest)
{
// Check the destination address
if (!sam->valid_dest(dest)) {
LWARN << "Bad format in peer reference: " << dest.substr(0, 8) << '\n';
return 0;
}
// Never add our own peer to the peers we can connect to
if (dest == sam->get_my_dest()) {
LDEBUG << "Not adding my own peer reference: " << dest.substr(0, 8)
<< '\n';
return 0;
}
// Be sure that the peer is not already known to us
Peer *peer = get_peer_by_dest(dest);
if (peer != 0) {
LDEBUG << "Redundant peer reference: " << dest.substr(0, 8) << '\n';
return peer;
}
// Tests passed, add it
Sha1 sha1(dest);
pair<peersmap_i, bool> p = peersmap.insert(
make_pair(sha1, Peer(dest, sha1)));
assert(p.second);
LMINOR << "New peer reference: " << dest.substr(0, 8)
<< " (Kaddr: " << sha1.b64hash() << ")\n";
peer = &(p.first->second);
return peer;
}
/*
* Saves peer destinations to a file
*
* file - the file to save to
*/
void Peers::save(void)
{
ofstream peersf(file.c_str());
if (!peersf) {
LERROR << "Error opening peers reference file (" << file.c_str()
<< ")\n";
return;
}
LDEBUG << "Saving " << peersmap.size() + 1 << " peer references\n";
peersf << sam->get_my_dest() << '\n';
for (peersmap_ci i = peersmap.begin(); i != peersmap.end(); i++) {
const Peer& tmp = i->second;
peersf << tmp.get_dest() << '\n';
}
}
/*
* Stores data on some peers
*
* sha1 - the sha1 value for the data
* data - the data
*/
void Peers::store(const Sha1& sha1)
{
list<Near_peer> near_peers;
get_nearest(sam->get_my_sha1(), PAR_RPCS, near_peers);
for (list<Near_peer>::const_iterator i = near_peers.begin();
i != near_peers.end(); i++) {
Rpc rpc(i->get_peer());
rpc.store(sha1);
}
}

View File

@ -1,65 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef PEERS_HPP
#define PEERS_HPP
class Peers {
public:
static const int PAR_RPCS = 3; // The number of parallel RPCs to send
static const int RET_REFS = 20; // The number of peer refs to return on
// failed requests
Peers(const string& file)
: file(file)
{ load(); }
~Peers(void) { save(); }
void advertise_self(void);
void get_nearest(const Sha1& sha1, size_t n,
list<Near_peer>& near_peers);
Peer* get_peer_by_dest(const sam_pubkey_t dest);
Peer* get_peer_by_dest(const string& dest);
Peer* get_peer_by_kaddr(const Sha1& kaddr);
Peer* new_peer(const sam_pubkey_t dest);
Peer* new_peer(const string& dest);
void store(const Sha1& sha1);
private:
typedef map<const Sha1, Peer>::const_iterator peersmap_ci;
typedef map<const Sha1, Peer>::iterator peersmap_i;
void load(void);
void save(void);
const string file;
map<const Sha1, Peer> peersmap;
};
#endif // PEERS_HPP

View File

@ -1,111 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef PLATFORM_HPP
#define PLATFORM_HPP
/*
* Operating system
*/
#define FREEBSD 0 // FreeBSD (untested)
#define MINGW 1 // Windows native (Mingw)
#define LINUX 2 // Linux
#define CYGWIN 3 // Cygwin
#if OS == MINGW
#define NO_SSIZE_T
#define WIN_STRERROR
#define WINSOCK
#define WINTHREADS
#endif
/*
* System includes
*/
#include <arpa/inet.h>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#ifdef WINTHREADS
#include <windows.h>
#else
#include <pthread.h>
#endif
#include <stdexcept>
#include <stdint.h>
#include <string>
#include <time.h>
using namespace std;
#ifdef NO_SSIZE_T
typedef signed long ssize_t;
#endif
/*
* Define this to '1' to cause the printing of source code file and line number
* information with each log message. Set it to '0' for simple logging.
*/
#define VERBOSE_LOGS 0
/*
* Library includes
*/
#include "mycrypt.h" // LibTomCrypt
#include "sam.h" // LibSAM
/*
* Local includes
*/
#include "mutex.hpp" // Mutex (for thread.hpp)
#include "thread.hpp" // Thread
#include "logger.hpp" // Logger
#include "config.hpp" // Config
#include "sam_error.hpp" // for sam.hpp
#include "bigint.hpp" // for sha1.hpp
#include "sha1.hpp" // for peers.hpp
#include "peer.hpp" // for peers.hpp
#include "near_peer.hpp" // for peers.hpp
#include "peers.hpp" // for sam.hpp
#include "sam.hpp" // SAM
#include "random.hpp" // Random
/*
* Global variables
*/
extern Config *config; // Configuration options
extern Logger *logger; // Logging mechanism
extern Random *prng; // Random number generator
extern Sam *sam; // Sam connection
#endif // PLATFORM_HPP

View File

@ -1,65 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "platform.hpp"
#include "random.hpp"
/*
* Prepares the Yarrow PRNG for use
*/
Random::Random(void)
{
LMINOR << "Initalising PRNG\n";
int rc = yarrow_start(&prng);
assert(rc == CRYPT_OK);
uchar_t entropy[ENTROPY_SIZE];
size_t sz = rng_get_bytes(entropy, ENTROPY_SIZE, NULL);
assert(sz == ENTROPY_SIZE);
rc = yarrow_add_entropy(entropy, ENTROPY_SIZE, &prng);
assert(rc == CRYPT_OK);
rc = yarrow_ready(&prng);
assert(rc == CRYPT_OK);
}
/*
* Gets `size' random bytes from the PRNG
*
* random - space to fill with random bytes
* size - size of `random'
*/
void Random::get_bytes(uchar_t* random, size_t size)
{
size_t sz = yarrow_read(random, size, &prng);
assert(sz == size);
}

View File

@ -1,45 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef RANDOM_HPP
#define RANDOM_HPP
class Random {
public:
Random(void);
void get_bytes(uchar_t* random, size_t size);
private:
static const size_t ENTROPY_SIZE = 32;
prng_state prng;
};
#endif // RNG_HPP

View File

@ -1,233 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "platform.hpp"
#include "rpc.hpp"
// These can't be 'const' because I have to make them big-endian first
uint16_t Rpc::VERSION = htons(1);
uint16_t Rpc::OLDEST_GOOD_VERSION = htons(1);
/*
* Requests a peer to find the addresses of the closest peers to the specified
* sha1 and return them
*
* sha1 - closeness to this sha1
*/
void Rpc::find_peers(const Sha1& sha1)
{
LDEBUG << "To: " << peer->get_sdest() << " [" << peer->get_b64kaddr()
<< "] Msg: FIND_PEERS\n";
// VERSION + command + bin sha1
const size_t len = sizeof VERSION + 1 + Sha1::SHA1BIN_LEN;
uchar_t buf[len];
uchar_t* p = static_cast<uchar_t*>(memcpy(buf, &VERSION, sizeof VERSION));
p += sizeof VERSION;
*p = FIND_PEERS;
p++;
memcpy(p, sha1.binhash(), Sha1::SHA1BIN_LEN);
sam->send_dgram(peer->get_dest(), buf, len);
}
/*
* Returns the closest peer references to a Sha1
*
* sha1 - sha1 to test nearness to
*/
void Rpc::found_peers(const Sha1& sha1)
{
list<Near_peer> near_peers;
sam->peers->get_nearest(sha1, Peers::RET_REFS, near_peers);
LDEBUG << "To: " << peer->get_sdest() << " [" << peer->get_b64kaddr()
<< "] Msg: FOUND_PEERS (" << near_peers.size() << " peers)\n";
// VERSION + command + number of sha1s (0-255) + bin sha1s
const size_t len = sizeof VERSION + 1 + 1 +
(near_peers.size() * (SAM_PUBKEY_LEN - 1));
assert(near_peers.size() <= 255);
uchar_t buf[len];
uchar_t* p = static_cast<uchar_t*>(memcpy(buf, &VERSION, sizeof VERSION));
p += sizeof VERSION;
*p = FOUND_PEERS;
p++;
*p = near_peers.size();
p++;
for (list<Near_peer>::const_iterator i = near_peers.begin();
i != near_peers.end(); i++) {
const Peer* peer = i->get_peer();
memcpy(p, peer->get_dest().c_str(), (SAM_PUBKEY_LEN - 1));
p += SAM_PUBKEY_LEN - 1;
}
sam->send_dgram(peer->get_dest(), buf, len);
}
/*
* Parse incoming data and invoke the appropriate RPC
*
* data - the data
* size - the size of `data'
*/
void Rpc::parse(const void* data, size_t size)
{
uint16_t his_ver;
memcpy(&his_ver, data, sizeof VERSION);
if (ntohs(his_ver) < ntohs(VERSION)) {
LMINOR << "Ignored RPC from " << peer->get_sdest() << " ["
<< peer->get_b64kaddr() << "] using obsolete protocol version "
<< ntohs(his_ver) << '\n';
return;
} else if (size <= 4) {
LWARN << "RPC too small from " << peer->get_sdest() << " ["
<< peer->get_b64kaddr() << "]\n";
return;
}
const uchar_t* p = static_cast<const uchar_t*>(data);
if (p[2] == PING) { //-----------------------------------------------------
LDEBUG << "From: " << peer->get_sdest() << " [" << peer->get_b64kaddr()
<< "] Msg: PING\n";
uint32_t ptime;
if (size != sizeof VERSION + 1 + sizeof ptime) {
LWARN << "Malformed PING RPC from " << peer->get_sdest()
<< " [" << peer->get_b64kaddr() << "]\n";
return;
}
p += sizeof VERSION + 1;
memcpy(&ptime, p, sizeof ptime);
pong(ptime); // no need to ntohl() it here because we're just copying it
return;
} else if (p[2] == PONG) { //----------------------------------------------
LDEBUG << "From: " << peer->get_sdest() << " [" << peer->get_b64kaddr()
<< "] Msg: PONG\n";
uint32_t ptime;
if (size != sizeof VERSION + 1 + sizeof ptime) {
LWARN << "Malformed PONG RPC from " << peer->get_sdest()
<< " [" << peer->get_b64kaddr() << "]\n";
return;
}
p += sizeof VERSION + 1;
memcpy(&ptime, p, sizeof ptime);
ptime = ntohl(ptime);
uint32_t now = time(NULL);
peer->set_lag(now - ptime);
LDEBUG << "Lag is " << peer->get_lag() << " seconds\n";
return;
} else if (p[2] == FIND_PEERS) { //----------------------------------------
if (size != sizeof VERSION + 1 + Sha1::SHA1BIN_LEN) {
LWARN << "Malformed FIND_PEERS RPC from " << peer->get_sdest()
<< " [" << peer->get_b64kaddr() << "]\n";
return;
}
LDEBUG << "From: " << peer->get_sdest() << " [" << peer->get_b64kaddr()
<< "] Msg: FIND_PEERS\n";
found_peers(Sha1(p + 4));
return;
} else if (p[2] == FOUND_PEERS) { //---------------------------------------
const size_t refs = p[3];
if (size != sizeof VERSION + 1 + 1 + (refs * (SAM_PUBKEY_LEN - 1))) {
LWARN << "Malformed FOUND_PEERS RPC from " << peer->get_sdest()
<< " [" << peer->get_b64kaddr() << "]\n";
return;
}
LDEBUG << "From: " << peer->get_sdest() << " [" << peer->get_b64kaddr()
<< "] Msg: FOUND_PEERS (" << refs << " peers)\n";
p += sizeof VERSION + 1 + 1;
for (size_t i = 1; i <= refs; i++) {
sam_pubkey_t dest;
memcpy(dest, p, SAM_PUBKEY_LEN - 1); // - 1 == no NUL in RPC
dest[SAM_PUBKEY_LEN - 1] = '\0';
//LDEBUG << "Message had: " << dest << '\n';
sam->peers->new_peer(dest);
p += SAM_PUBKEY_LEN - 1;
}
return;
} else //------------------------------------------------------------------
LWARN << "Unknown RPC #" << static_cast<int>(p[2]) << " from "
<< peer->get_sdest() << " [" << peer->get_b64kaddr() << "]\n";
}
/*
* Sends a ping to someone
*/
void Rpc::ping(void)
{
LDEBUG << "To: " << peer->get_sdest() << " [" << peer->get_b64kaddr()
<< "] Msg: PING\n";
uint32_t now = htonl(time(NULL));
// VERSION + command + seconds since 1970
const size_t len = sizeof VERSION + 1 + sizeof now;
uchar_t buf[len];
uchar_t* p = static_cast<uchar_t*>(memcpy(buf, &VERSION, sizeof VERSION));
p += sizeof VERSION;
*p = PING;
p++;
memcpy(p, &now, sizeof now);
sam->send_dgram(peer->get_dest(), buf, len);
}
/*
* Sends a ping reply to someone
*
* ptime - the time the peer sent us (we echo the same time back)
*/
void Rpc::pong(uint32_t ptime)
{
LDEBUG << "To: " << peer->get_sdest() << " [" << peer->get_b64kaddr()
<< "] Msg: PONG\n";
// VERSION + command + pinger's seconds since 1970 echoed back
const size_t len = sizeof VERSION + 1 + sizeof ptime;
uchar_t buf[len];
uchar_t* p = static_cast<uchar_t*>(memcpy(buf, &VERSION, sizeof VERSION));
p += sizeof VERSION;
*p = PONG;
p++;
memcpy(p, &ptime, sizeof ptime);
sam->send_dgram(peer->get_dest(), buf, len);
}
/*
* Tells a peer to store some data
*
* sha1 - sha1 value for the data
* data - the data
*/
void Rpc::store(const Sha1& sha1)
{
LDEBUG << "To: " << peer->get_sdest() << " [" << peer->get_b64kaddr()
<< "] Msg: STORE\n";
}

View File

@ -1,65 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef RPC_HPP
#define RPC_HPP
class Rpc {
public:
// The PROTOCOL version we are using
static uint16_t VERSION;
// The oldest version we will talk to
static uint16_t OLDEST_GOOD_VERSION;
// RPC identifiers (0-255)
typedef enum {
PING = 0,
PONG = 1,
FIND_PEERS = 2,
FOUND_PEERS = 3,
STORE = 4
} rpc_t;
Rpc(Peer* peer)
: peer(peer) {};
void find_peers(const Sha1& sha1);
void parse(const void* data, size_t size);
void ping(void);
void store(const Sha1& sha1);
private:
void found_peers(const Sha1& sha1);
void pong(uint32_t ptime);
Peer* peer;
basic_string<uchar_t> data;
};
#endif // RPC_HPP

View File

@ -1,249 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "platform.hpp"
#include "rpc.hpp"
#include "sam.hpp"
extern "C" {
/*
* Assorted callbacks required by LibSAM - ugly, but it works
*/
static void dgramback(sam_pubkey_t dest, void* data, size_t size);
static void diedback(void);
static void logback(char* str);
static void namingback(char* name, sam_pubkey_t pubkey, samerr_t result);
}
/*
* Prevents more than one Sam object from existing in the program at a time
* (LibSAM limitation)
*/
bool Sam::exists = false;
Sam::Sam(const string& samhost, uint16_t samport, const string& destname,
uint_t tunneldepth)
{
// Only allow one Sam object to exist at a time
assert(!exists);
exists = true;
// hook up callbacks
sam_dgramback = &dgramback;
sam_diedback = &diedback;
sam_logback = &logback;
sam_namingback = &namingback;
// we haven't connected to SAM yet
set_connected(false);
// now try to connect to SAM
connect(samhost.c_str(), samport, destname.c_str(), tunneldepth);
}
Sam::~Sam(void)
{
delete peers; // this must be before set_connected(false)!
if (is_connected()) {
sam_close();
set_connected(false);
}
exists = false;
}
/*
* Connects to the SAM host
*
* samhost - host that SAM is running on (hostname or IP address)
* samport - port number that SAM is running own
* destname - the destination name of this program
* tunneldepth - how long the tunnels should be
*/
void Sam::connect(const char* samhost, uint16_t samport, const char* destname,
uint_t tunneldepth)
{
assert(!is_connected());
LMINOR << "Connecting to SAM as '" << destname << "'\n";
samerr_t rc = sam_connect(samhost, samport, destname, SAM_DGRAM, tunneldepth);
if (rc == SAM_OK)
set_connected(true);
else
throw Sam_error(rc);
}
/*
* Loads peer references from disk
* Note: this can only be called after my_dest has been set
*/
void Sam::load_peers(void)
{
peers = new Peers(config->get_cproperty("references"));
}
/*
* Converts `name' to a base 64 destination
*
* name - name to lookup
*/
void Sam::naming_lookup(const string& name) const
{
assert(is_connected());
sam_naming_lookup(name.c_str());
}
/*
* Parses an incoming datagram
*
* dest - source destination address
* data - datagram payload
* size - size of `data'
*/
void Sam::parse_dgram(const string& dest, void* data, size_t size)
{
assert(is_connected());
Peer* peer = peers->new_peer(dest);
Rpc rpc(peer);
rpc.parse(data, size);
rpc.ping();
free(data);
}
/*
* Checks the SAM connection for incoming commands and invokes callbacks
*/
void Sam::read_buffer(void)
{
assert(is_connected());
sam_read_buffer();
}
/*
* Sends a datagram to a destination
*
* dest - destination to send to
* data - data to send
* size - size of `data'
*/
void Sam::send_dgram(const string& dest, uchar_t *data, size_t size)
{
assert(is_connected());
samerr_t rc = sam_dgram_send(dest.c_str(), data, size);
assert(rc == SAM_OK); // i.e. not SAM_TOO_BIG
}
/*
* Sets the connection status
*
* connected - true for connected, false for disconnected
*/
void Sam::set_connected(bool connected)
{
if (!connected)
my_dest = "";
this->connected = connected;
}
/*
* Sets my destination address
*
* pubkey - the base 64 destination
*/
void Sam::set_my_dest(const sam_pubkey_t pubkey)
{
my_dest = pubkey;
my_sha1 = Sha1(my_dest);
}
/*
* Checks whether the destination specified is of a valid base 64 syntax
*
* Returns: true if it is valid, false if it isn't
*/
bool Sam::valid_dest(const string& dest)
{
if (dest.size() != 516)
return false;
if (dest.substr(512, 4) == "AAAA") // Note this AAAA signifies a null
return true; // certificate and doesn't actually have
else // any bearing on validity, but we'll
return false; // keep this check here for now anyway
}
/*
* * * * Callbacks * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Unfortunately these aren't part of the "Sam" object because they are function
* pointers to _C_ functions. As a hack, we just have them call the global Sam
* object.
*/
/*
* Callback: A datagram was received
*/
static void dgramback(sam_pubkey_t dest, void* data, size_t size)
{
sam->parse_dgram(dest, data, size);
}
/*
* Callback: The connection to SAM has failed
*/
static void diedback(void)
{
LERROR << "Connection to SAM lost!\n";
sam->set_connected(false);
throw Sam_error(SAM_SOCKET_ERROR);
}
/*
* Callback: A log message has been sent from LibSAM
*/
static void logback(char* str)
{
LINFO << "LibSAM: " << str << '\n';
}
/*
* Callback: A naming lookup has completed
*/
static void namingback(char* name, sam_pubkey_t pubkey, samerr_t result)
{
Sam_error res(result);
if (res.code() == SAM_OK) {
if (strcmp(name, "ME") == 0) {
sam->set_my_dest(pubkey);
sam->load_peers();
} else {
assert(false);
}
} else {
LERROR << "Naming look failed for '" << name << "': " << res.what()
<< '\n';
}
}

View File

@ -1,66 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SAM_HPP
#define SAM_HPP
class Sam {
public:
Sam(const string& samhost, uint16_t samport, const string& destname,
uint_t tunneldepth);
~Sam(void);
const string& get_my_dest(void) const { return my_dest; }
const Sha1& get_my_sha1(void) const { return my_sha1; }
void naming_lookup(const string& name = "ME") const;
void read_buffer(void);
void send_dgram(const string& dest, uchar_t *data, size_t size);
bool valid_dest(const string& dest);
Peers* peers;
//callback-private:
void load_peers(void);
void parse_dgram(const string& dest, void* data, size_t size);
void set_connected(bool connected);
void set_my_dest(const sam_pubkey_t pubkey);
private:
void connect(const char* samhost, uint16_t samport,
const char* destname, uint_t tunneldepth);
bool is_connected(void) const { return connected; }
bool connected;
static bool exists;
string my_dest;
Sha1 my_sha1;
};
#endif // SAM_HPP

View File

@ -1,46 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SAM_ERROR_HPP
#define SAM_ERROR_HPP
class Sam_error {
public:
Sam_error(samerr_t error)
: errcode(error) {}
samerr_t code(void) const { return errcode; }
const char* what(void) const { return sam_strerror(errcode); }
private:
const samerr_t errcode;
};
#endif // SAM_ERROR_HPP

View File

@ -1,122 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "platform.hpp"
#include "sha1.hpp"
Sha1::Sha1(void)
{
b64hashed = "No value!";
memset(binhashed, 0, sizeof binhashed);
}
Sha1::Sha1(const string& data)
{
/* Hash it */
hash_state md;
sha1_init(&md);
int rc = sha1_process(&md, reinterpret_cast<const uchar_t*>(data.c_str()),
data.size());
assert(rc == CRYPT_OK);
rc = sha1_done(&md, binhashed);
assert(rc == CRYPT_OK);
b64();
}
/*
* Initialises the Sha1 object from a binary hash
*/
Sha1::Sha1(const uchar_t binary[SHA1BIN_LEN])
{
memcpy(binhashed, binary, sizeof binhashed);
b64();
}
/*
* Base 64 the binary hash
*/
void Sha1::b64(void)
{
ulong_t outlen = 29;
char tmp[outlen];
// b64 FIXME: replace + with ~, and / with - to be like freenet
int rc = base64_encode(binhashed, sizeof binhashed, reinterpret_cast<uchar_t*>(tmp), &outlen);
assert(rc == CRYPT_OK);
b64hashed = tmp;
}
/*
* Compares two Sha1s, returning true if the this one is less than the right one
*/
bool Sha1::operator<(const Sha1& rhs) const
{
Bigint lhsnum(binhashed, SHA1BIN_LEN);
Bigint rhsnum(rhs.binhash(), SHA1BIN_LEN);
if (lhsnum < rhsnum)
return true;
else
return false;
}
/*
* Assigns a value from another Sha1 to this one
*/
Sha1& Sha1::operator=(const Sha1& rhs)
{
if (this != &rhs) { // check for self-assignment: a = a
b64hashed = rhs.b64hash();
memcpy(binhashed, rhs.binhash(), sizeof binhashed);
}
return *this;
}
/*
* Compares Sha1s for equality
*/
bool Sha1::operator==(const Sha1& rhs) const
{
if (memcmp(binhashed, rhs.binhash(), sizeof binhashed) == 0)
return true;
else
return false;
}
/*
* Xors this Sha1 with another, and stores the result in a Bigint
*
* rhs - sha1 to xor this one with
* result - will be filled with the result
*/
void Sha1::x_or(const Sha1& rhs, Bigint& result) const
{
Bigint lhsnum(binhashed, SHA1BIN_LEN);
Bigint rhsnum(rhs.binhash(), SHA1BIN_LEN);
lhsnum.x_or(rhsnum, result);
}

View File

@ -1,56 +0,0 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SHA1_HPP
#define SHA1_HPP
class Sha1 {
public:
static const size_t SHA1BIN_LEN = 20;
Sha1(void);
Sha1(const string& data);
Sha1(const uchar_t binary[SHA1BIN_LEN]);
const string& b64hash(void) const { return b64hashed; }
const uchar_t* binhash(void) const { return binhashed; }
bool operator<(const Sha1& rhs) const;
Sha1& operator=(const Sha1& rhs);
bool operator==(const Sha1& rhs) const;
void x_or(const Sha1& rhs, Bigint& result) const;
private:
void b64(void);
string b64hashed; // base 64 of the hash
uchar_t binhashed[SHA1BIN_LEN]; // non-NUL terminated binary hash
};
#endif // SHA1_HPP

View File

@ -4,6 +4,7 @@
<target name="build" depends="builddep, jar" />
<target name="builddep">
<ant dir="../../ministreaming/java/" target="build" />
<ant dir="../../jetty/" target="build" />
<!-- ministreaming will build core -->
</target>
<target name="compile">
@ -15,7 +16,7 @@
destdir="./build/obj"
classpath="../../../core/java/build/i2p.jar:../../ministreaming/java/build/mstreaming.jar" />
</target>
<target name="jar" depends="compile">
<target name="jar" depends="builddep, compile">
<jar destfile="./build/i2ptunnel.jar" basedir="./build/obj" includes="**/*.class">
<manifest>
<attribute name="Main-Class" value="net.i2p.i2ptunnel.I2PTunnel" />

View File

@ -17,6 +17,8 @@ import java.util.List;
import java.util.Properties;
import net.i2p.I2PException;
import net.i2p.client.I2PSession;
import net.i2p.client.I2PSessionException;
import net.i2p.client.streaming.I2PSocket;
import net.i2p.client.streaming.I2PSocketManager;
import net.i2p.client.streaming.I2PSocketManagerFactory;
@ -118,7 +120,16 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
return getSocketManager(getTunnel());
}
protected static synchronized I2PSocketManager getSocketManager(I2PTunnel tunnel) {
if (socketManager == null) {
if (socketManager != null) {
I2PSession s = socketManager.getSession();
if ( (s == null) || (s.isClosed()) ) {
_log.info("Building a new socket manager since the old one closed [s=" + s + "]");
socketManager = buildSocketManager(tunnel);
} else {
_log.info("Not building a new socket manager since the old one is open [s=" + s + "]");
}
} else {
_log.info("Building a new socket manager since there is no other one");
socketManager = buildSocketManager(tunnel);
}
return socketManager;
@ -277,7 +288,10 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
}
return false;
}
getTunnel().removeSession(sockMgr.getSession());
I2PSession session = sockMgr.getSession();
if (session != null) {
getTunnel().removeSession(session);
}
l.log("Closing client " + toString());
try {
if (ss != null) ss.close();

View File

@ -13,6 +13,7 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.StringTokenizer;
import java.util.HashMap;
import net.i2p.I2PAppContext;
import net.i2p.I2PException;
@ -48,6 +49,8 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
private List proxyList;
private HashMap addressHelpers = new HashMap();
private final static byte[] ERR_REQUEST_DENIED =
("HTTP/1.1 403 Access Denied\r\n"+
"Content-Type: text/html; charset=iso-8859-1\r\n"+
@ -135,8 +138,6 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
return null;
}
int index = I2PAppContext.getGlobalContext().random().nextInt(size);
if (index >= size) index = size - 1;
if (index < 0) return null;
String proxy = (String)proxyList.get(index);
return proxy;
}
@ -196,6 +197,47 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
if (host.toLowerCase().endsWith(".i2p")) {
destination = host;
host = getHostName(destination);
if ( (host != null) && ("i2p".equals(host)) ) {
int pos2;
if ((pos2 = request.indexOf("?")) != -1) {
// Try to find an address helper in the fragments
// and split the request into it's component parts for rebuilding later
String fragments = request.substring(pos2 + 1);
String uriPath = request.substring(0, pos2);
pos2 = fragments.indexOf(" ");
String protocolVersion = fragments.substring(pos2 + 1);
String urlEncoding = "";
fragments = fragments.substring(0, pos2);
fragments = fragments + "&";
String fragment;
while(fragments.length() > 0) {
pos2 = fragments.indexOf("&");
fragment = fragments.substring(0, pos2);
fragments = fragments.substring(pos2 + 1);
if (fragment.startsWith("i2paddresshelper")) {
pos2 = fragment.indexOf("=");
if (pos2 >= 0) {
addressHelpers.put(destination,fragment.substring(pos2 + 1));
}
} else {
// append each fragment unless it's the address helper
if ("".equals(urlEncoding)) {
urlEncoding = "?" + fragment;
} else {
urlEncoding = urlEncoding + "&" + fragment;
}
}
}
// reconstruct the request minus the i2paddresshelper GET var
request = uriPath + urlEncoding + " " + protocolVersion;
}
String addressHelper = (String) addressHelpers.get(destination);
if (addressHelper != null) {
destination = addressHelper;
host = getHostName(destination);
}
}
line = method + " " + request.substring(pos);
} else if (host.indexOf(".") != -1) {
// The request must be forwarded to a WWW proxy
@ -252,6 +294,15 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
line = "Host: " + host;
if (_log.shouldLog(Log.INFO))
_log.info(getPrefix(requestId) + "Setting host = " + host);
} else if (line.startsWith("User-Agent: ")) {
line = "User-Agent: MYOB/6.66 (AN/ON)";
} else if (line.startsWith("Referer: ")) {
// Shouldn't we be more specific, like accepting in-site referers ?
line = "Referer: i2p";
} else if (line.startsWith("Via: ")) {
line = "Via: i2p";
} else if (line.startsWith("From: ")) {
line = "From: i2p";
}
}

View File

@ -190,8 +190,8 @@ public class I2PTunnelRunner extends I2PThread implements I2PSocket.SocketErrorL
} catch (IOException ex) {
if (!finished)
_log.error("Error forwarding", ex);
else
_log.warn("You may ignore this", ex);
//else
// _log.warn("You may ignore this", ex);
} finally {
try {
out.close();

View File

@ -148,6 +148,7 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
I2PServerSocket i2pss = sockMgr.getServerSocket();
while (true) {
I2PSocket i2ps = i2pss.accept();
if (i2ps == null) throw new I2PException("I2PServerSocket closed");
I2PThread t = new I2PThread(new Handler(i2ps));
t.start();
}

View File

@ -8,6 +8,7 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Random;
import net.i2p.I2PAppContext;
import net.i2p.I2PException;
@ -28,6 +29,7 @@ public class TunnelController implements Logging {
private Properties _config;
private I2PTunnel _tunnel;
private List _messages;
private List _sessions;
private boolean _running;
/**
@ -102,6 +104,14 @@ public class TunnelController implements Logging {
*
*/
public void startTunnel() {
try {
doStartTunnel();
} catch (Exception e) {
_log.error("Error starting up the tunnel", e);
log("Error starting up the tunnel - " + e.getMessage());
}
}
private void doStartTunnel() {
if (_running) {
if (_log.shouldLog(Log.INFO))
_log.info("Already running");
@ -121,7 +131,7 @@ public class TunnelController implements Logging {
} else if ("server".equals(type)) {
startServer();
} else {
if (_log.shouldLog(Log.WARN))
if (_log.shouldLog(Log.ERROR))
_log.error("Cannot start tunnel - unknown type [" + type + "]");
}
}
@ -136,9 +146,42 @@ public class TunnelController implements Logging {
_tunnel.runHttpClient(new String[] { listenPort }, this);
else
_tunnel.runHttpClient(new String[] { listenPort, proxyList }, this);
acquire();
_running = true;
}
/**
* Note the fact that we are using some sessions, so that they dont get
* closed by some other tunnels
*/
private void acquire() {
List sessions = _tunnel.getSessions();
if (sessions != null) {
for (int i = 0; i < sessions.size(); i++) {
I2PSession session = (I2PSession)sessions.get(i);
TunnelControllerGroup.getInstance().acquire(this, session);
}
_sessions = sessions;
} else {
_log.error("No sessions to acquire?");
}
}
/**
* Note the fact that we are no longer using some sessions, and if
* no other tunnels are using them, close them.
*/
private void release() {
if (_sessions != null) {
for (int i = 0; i < _sessions.size(); i++) {
I2PSession s = (I2PSession)_sessions.get(i);
TunnelControllerGroup.getInstance().release(this, s);
}
} else {
_log.error("No sessions to release?");
}
}
private void startClient() {
setI2CPOptions();
setSessionOptions();
@ -146,6 +189,7 @@ public class TunnelController implements Logging {
String listenPort = getListenPort();
String dest = getTargetDestination();
_tunnel.runClient(new String[] { listenPort, dest }, this);
acquire();
_running = true;
}
@ -156,6 +200,7 @@ public class TunnelController implements Logging {
String targetPort = getTargetPort();
String privKeyFile = getPrivKeyFile();
_tunnel.runServer(new String[] { targetHost, targetPort, privKeyFile }, this);
acquire();
_running = true;
}
@ -193,6 +238,7 @@ public class TunnelController implements Logging {
public void stopTunnel() {
_tunnel.runClose(new String[] { "forced", "all" }, this);
release();
_running = false;
}
@ -326,14 +372,21 @@ public class TunnelController implements Logging {
Destination dest = session.getMyDestination();
if (dest != null) {
buf.append("Destination hash: ").append(dest.calculateHash().toBase64()).append("<br />\n");
buf.append("Full destination: ");
buf.append("<input type=\"text\" size=\"10\" onclick=\"this.select();\" ");
buf.append("value=\"").append(dest.toBase64()).append("\" />\n");
if ("server".equals(getType())) {
buf.append(" Give that out to people so they can view your service.");
buf.append(" If you are going to share it on irc, be sure to split it on two lines");
buf.append("Full destination: ");
buf.append("<input type=\"text\" size=\"10\" onclick=\"this.select();\" ");
buf.append("value=\"").append(dest.toBase64()).append("\" />\n");
long val = new Random().nextLong();
if (val < 0) val = 0 - val;
buf.append("<br />You can <a href=\"http://temp").append(val);
buf.append(".i2p/?i2paddresshelper=").append(dest.toBase64()).append("\">view</a>");
buf.append(" it in a browser (only when you're using the eepProxy)\n");
buf.append("<br />If you are going to share this on IRC, you need to split it up:<br />\n");
String str = dest.toBase64();
buf.append(str.substring(0, str.length()/2)).append("<br />\n");
buf.append(str.substring(str.length()/2)).append("<br />\n");
buf.append("You can also post it to <a href=\"http://forum.i2p/viewforum.php?f=16\">Eepsite announcement forum</a><br />");
}
buf.append("<br />\n");
}
}
}

View File

@ -8,13 +8,18 @@ import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.TreeMap;
import net.i2p.I2PAppContext;
import net.i2p.client.I2PSession;
import net.i2p.client.I2PSessionException;
import net.i2p.util.Log;
/**
@ -30,29 +35,33 @@ public class TunnelControllerGroup {
private List _controllers;
private String _configFile = DEFAULT_CONFIG_FILE;
public static TunnelControllerGroup getInstance() {
synchronized (TunnelControllerGroup.class) {
if (_instance == null)
_instance = new TunnelControllerGroup(DEFAULT_CONFIG_FILE);
return _instance;
}
}
/**
* Map of I2PSession to a Set of TunnelController objects
* using the session (to prevent closing the session until
* no more tunnels are using it)
*
*/
private Map _sessions;
public static TunnelControllerGroup getInstance() { return _instance; }
private TunnelControllerGroup(String configFile) {
private TunnelControllerGroup(String configFile) {
_log = I2PAppContext.getGlobalContext().logManager().getLog(TunnelControllerGroup.class);
_instance = this;
_controllers = new ArrayList();
_configFile = configFile;
_sessions = new HashMap(4);
loadControllers(_configFile);
}
public static void main(String args[]) {
if ( (args == null) || (args.length <= 0) ) {
_instance = getInstance();
new TunnelControllerGroup(DEFAULT_CONFIG_FILE);
} else if (args.length == 1) {
if (DEFAULT_CONFIG_FILE.equals(args[0]))
_instance = getInstance();
new TunnelControllerGroup(DEFAULT_CONFIG_FILE);
else
_instance = new TunnelControllerGroup(args[0]);
new TunnelControllerGroup(args[0]);
} else {
System.err.println("Usage: TunnelControllerGroup [filename]");
return;
@ -287,4 +296,61 @@ public class TunnelControllerGroup {
*/
public List getControllers() { return _controllers; }
/**
* Note the fact that the controller is using the session so that
* it isn't destroyed prematurely.
*
*/
void acquire(TunnelController controller, I2PSession session) {
synchronized (_sessions) {
Set owners = (Set)_sessions.get(session);
if (owners == null) {
owners = new HashSet(1);
_sessions.put(session, owners);
}
owners.add(controller);
}
if (_log.shouldLog(Log.INFO))
_log.info("Acquiring session " + session + " for " + controller);
}
/**
* Note the fact that the controller is no longer using the session, and if
* no other controllers are using it, destroy the session.
*
*/
void release(TunnelController controller, I2PSession session) {
boolean shouldClose = false;
synchronized (_sessions) {
Set owners = (Set)_sessions.get(session);
if (owners != null) {
owners.remove(controller);
if (owners.size() <= 0) {
if (_log.shouldLog(Log.INFO))
_log.info("After releasing session " + session + " by " + controller + ", no more owners remain");
shouldClose = true;
_sessions.remove(session);
} else {
if (_log.shouldLog(Log.INFO))
_log.info("After releasing session " + session + " by " + controller + ", " + owners.size() + " owners remain");
shouldClose = false;
}
} else {
if (_log.shouldLog(Log.WARN))
_log.warn("After releasing session " + session + " by " + controller + ", no owners were even known?!");
shouldClose = true;
}
}
if (shouldClose) {
try {
session.destroySession();
if (_log.shouldLog(Log.INFO))
_log.info("Session destroyed: " + session);
} catch (I2PSessionException ise) {
_log.error("Error closing the client session", ise);
}
}
}
}

View File

@ -8,7 +8,7 @@ import java.util.Random;
import java.util.StringTokenizer;
/**
* Uuuugly... generate the edit/add forms for the various
* Uuuugly code to generate the edit/add forms for the various
* I2PTunnel types (httpclient/client/server)
*
*/

View File

@ -47,9 +47,13 @@ public class WebStatusPageHelper {
}
public String getSummaryList() {
TunnelControllerGroup group = TunnelControllerGroup.getInstance();
if (group == null)
return "<b>I2PTunnel instances not yet started - please be patient</b>\n";
StringBuffer buf = new StringBuffer(4*1024);
buf.append("<ul>");
List tunnels = TunnelControllerGroup.getInstance().getControllers();
List tunnels = group.getControllers();
for (int i = 0; i < tunnels.size(); i++) {
buf.append("<li>\n");
getSummary(buf, i, (TunnelController)tunnels.get(i));
@ -92,24 +96,45 @@ public class WebStatusPageHelper {
return "Action <i>" + _action + "</i> unknown";
}
private String stopAll() {
List msgs = TunnelControllerGroup.getInstance().stopAllControllers();
TunnelControllerGroup group = TunnelControllerGroup.getInstance();
if (group == null)
return "<b>I2PTunnel instances not yet started - please be patient</b>\n";
List msgs = group.stopAllControllers();
return getMessages(msgs);
}
private String startAll() {
List msgs = TunnelControllerGroup.getInstance().startAllControllers();
TunnelControllerGroup group = TunnelControllerGroup.getInstance();
if (group == null)
return "<b>I2PTunnel instances not yet started - please be patient</b>\n";
List msgs = group.startAllControllers();
return getMessages(msgs);
}
private String restartAll() {
List msgs = TunnelControllerGroup.getInstance().restartAllControllers();
TunnelControllerGroup group = TunnelControllerGroup.getInstance();
if (group == null)
return "<b>I2PTunnel instances not yet started - please be patient</b>\n";
List msgs = group.restartAllControllers();
return getMessages(msgs);
}
private String reloadConfig() {
TunnelControllerGroup.getInstance().reloadControllers();
TunnelControllerGroup group = TunnelControllerGroup.getInstance();
if (group == null)
return "<b>I2PTunnel instances not yet started - please be patient</b>\n";
group.reloadControllers();
return "Config reloaded";
}
private String start() {
TunnelControllerGroup group = TunnelControllerGroup.getInstance();
if (group == null)
return "<b>I2PTunnel instances not yet started - please be patient</b>\n";
if (_controllerNum < 0) return "Invalid tunnel";
List controllers = TunnelControllerGroup.getInstance().getControllers();
List controllers = group.getControllers();
if (_controllerNum >= controllers.size()) return "Invalid tunnel";
TunnelController controller = (TunnelController)controllers.get(_controllerNum);
controller.startTunnel();
@ -117,8 +142,13 @@ public class WebStatusPageHelper {
}
private String stop() {
TunnelControllerGroup group = TunnelControllerGroup.getInstance();
if (group == null)
return "<b>I2PTunnel instances not yet started - please be patient</b>\n";
if (_controllerNum < 0) return "Invalid tunnel";
List controllers = TunnelControllerGroup.getInstance().getControllers();
List controllers = group.getControllers();
if (_controllerNum >= controllers.size()) return "Invalid tunnel";
TunnelController controller = (TunnelController)controllers.get(_controllerNum);
controller.stopTunnel();
@ -126,7 +156,11 @@ public class WebStatusPageHelper {
}
private String getMessages() {
return getMessages(TunnelControllerGroup.getInstance().clearAllMessages());
TunnelControllerGroup group = TunnelControllerGroup.getInstance();
if (group == null)
return "";
return getMessages(group.clearAllMessages());
}
private String getMessages(List msgs) {

View File

@ -7,6 +7,7 @@
<jsp:useBean class="net.i2p.i2ptunnel.WebStatusPageHelper" id="helper" scope="request" />
<jsp:setProperty name="helper" property="*" />
<h2>Messages since last page load:</h2>
<b><jsp:getProperty name="helper" property="actionResults" /></b>
<jsp:getProperty name="helper" property="summaryList" />

View File

@ -76,7 +76,7 @@ class I2PSocketImpl implements I2PSocket {
_socketId = ++__socketId;
local = mgr.getSession().getMyDestination();
String us = mgr.getSession().getMyDestination().calculateHash().toBase64().substring(0,4);
String name = us + (outgoing ? "->" : "<-") + peer.calculateHash().toBase64().subSequence(0,4);
String name = us + (outgoing ? "->" : "<-") + peer.calculateHash().toBase64().substring(0,4);
in = new I2PInputStream(name + " in");
I2PInputStream pin = new I2PInputStream(name + " out");
out = new I2POutputStream(pin);
@ -234,7 +234,7 @@ class I2PSocketImpl implements I2PSocket {
}
/**
* Close the socket from the I2P side, e. g. by a close packet.
* Close the socket from the I2P side (by a close packet)
*/
protected void internalClose() {
synchronized (flagLock) {

View File

@ -118,7 +118,7 @@ public class I2PSocketManager implements I2PSessionListener {
return;
}
if (msg.length < 4) {
_log.error(getName() + ": ==== packet too short ====");
_log.warn(getName() + ": ==== packet too short ====");
return;
}
int type = msg[0] & 0xff;
@ -155,7 +155,7 @@ public class I2PSocketManager implements I2PSessionListener {
return;
}
} catch (I2PException ise) {
_log.error(getName() + ": Error processing", ise);
_log.warn(getName() + ": Error processing", ise);
} catch (IllegalStateException ise) {
_log.debug(getName() + ": Error processing", ise);
}
@ -176,7 +176,7 @@ public class I2PSocketManager implements I2PSessionListener {
}
if (s == null) {
_log.warn(getName() + ": No socket responsible for ACK packet");
_log.warn(getName() + ": No socket responsible for ACK packet for id " + getReadableForm(id));
return;
}
@ -223,7 +223,8 @@ public class I2PSocketManager implements I2PSessionListener {
s = (I2PSocketImpl) _outSockets.get(id);
}
_log.debug(getName() + ": *Disconnect outgoing for socket " + s);
_log.debug(getName() + ": *Disconnect outgoing for socket " + s + " on id "
+ getReadableForm(id));
try {
if (s != null) {
if (payload.length > 0) {
@ -241,7 +242,7 @@ public class I2PSocketManager implements I2PSessionListener {
}
return;
} catch (Exception t) {
_log.error(getName() + ": Ignoring error on disconnect for socket " + s, t);
_log.warn(getName() + ": Ignoring error on disconnect for socket " + s, t);
}
}
@ -259,7 +260,8 @@ public class I2PSocketManager implements I2PSessionListener {
// packet send outgoing
if (_log.shouldLog(Log.DEBUG))
_log.debug(getName() + ": *Packet send outgoing [" + payload.length + "] for socket " + s);
_log.debug(getName() + ": *Packet send outgoing [" + payload.length + "] for socket "
+ s + " on id " + getReadableForm(id));
if (s != null) {
s.queueData(payload);
return;
@ -293,7 +295,8 @@ public class I2PSocketManager implements I2PSessionListener {
s.setRemoteID(id);
}
}
_log.debug(getName() + ": *Syn! for socket " + s);
_log.debug(getName() + ": *Syn! for socket " + s + " on id " + getReadableForm(newLocalID)
+ " from " + d.calculateHash().toBase64().substring(0,6));
if (!acceptConnections) {
// The app did not instantiate an I2PServerSocket
@ -303,7 +306,7 @@ public class I2PSocketManager implements I2PSessionListener {
replySentOk = _session.sendMessage(d, packet);
}
if (!replySentOk) {
_log.error(getName() + ": Error sending close to " + d.calculateHash().toBase64()
_log.warn(getName() + ": Error sending close to " + d.calculateHash().toBase64()
+ " in response to a new con message",
new Exception("Failed creation"));
}
@ -360,13 +363,13 @@ public class I2PSocketManager implements I2PSessionListener {
return;
} else {
if ( (payload.length > 0) && (_log.shouldLog(Log.ERROR)) )
_log.error(getName() + ": Disconnect packet had " + payload.length + " bytes");
_log.warn(getName() + ": Disconnect packet had " + payload.length + " bytes");
if (s != null)
s.internalClose();
return;
}
} catch (Exception t) {
_log.error(getName() + ": Ignoring error on disconnect", t);
_log.warn(getName() + ": Ignoring error on disconnect", t);
return;
}
}
@ -454,6 +457,10 @@ public class I2PSocketManager implements I2PSessionListener {
s = new I2PSocketImpl(peer, this, true, localID);
_outSockets.put(localID, s);
}
if (_log.shouldLog(Log.DEBUG))
_log.debug(getName() + ": connect(" + peer.calculateHash().toBase64().substring(0,6)
+ ", ...): localID = " + lcID);
try {
ByteArrayOutputStream pubkey = new ByteArrayOutputStream();
_session.getMyDestination().writeBytes(pubkey);
@ -462,18 +469,30 @@ public class I2PSocketManager implements I2PSessionListener {
boolean sent = false;
sent = _session.sendMessage(peer, packet);
if (!sent) {
_log.info(getName() + ": Unable to send & receive ack for SYN packet for socket " + s);
_log.info(getName() + ": Unable to send & receive ack for SYN packet for socket "
+ s + " with localID = " + lcID);
synchronized (lock) {
_outSockets.remove(s.getLocalID());
}
_context.statManager().addRateData("streaming.synNoAck", 1, 1);
throw new I2PException("Error sending through I2P network");
} else {
if (_log.shouldLog(Log.DEBUG))
_log.debug(getName() + ": syn sent ok to "
+ peer.calculateHash().toBase64().substring(0,6)
+ " with localID = " + lcID);
}
if (options != null)
remoteID = s.getRemoteID(true, options.getConnectTimeout());
else
remoteID = s.getRemoteID(true, getDefaultOptions().getConnectTimeout());
if (_log.shouldLog(Log.DEBUG))
_log.debug(getName() + ": remoteID received from "
+ peer.calculateHash().toBase64().substring(0,6)
+ ": " + getReadableForm(remoteID)
+ " with localID = " + lcID);
if (remoteID == null) {
_context.statManager().addRateData("streaming.nackReceived", 1, 1);
throw new ConnectException("Connection refused by peer for socket " + s);
@ -488,9 +507,10 @@ public class I2PSocketManager implements I2PSessionListener {
return s;
} catch (InterruptedIOException ioe) {
if (_log.shouldLog(Log.ERROR))
_log.error(getName() + ": Timeout waiting for ack from syn for id "
+ getReadableForm(lcID) + " for socket " + s, ioe);
if (_log.shouldLog(Log.WARN))
_log.warn(getName() + ": Timeout waiting for ack from syn for id "
+ lcID + " to " + peer.calculateHash().toBase64().substring(0,6)
+ " for socket " + s, ioe);
synchronized (lock) {
_outSockets.remove(s.getLocalID());
}
@ -498,14 +518,24 @@ public class I2PSocketManager implements I2PSessionListener {
_context.statManager().addRateData("streaming.synNoAck", 1, 1);
throw new InterruptedIOException("Timeout waiting for ack");
} catch (ConnectException ex) {
if (_log.shouldLog(Log.DEBUG))
_log.debug(getName() + ": Connection error waiting for ack from syn for id "
+ lcID + " to " + peer.calculateHash().toBase64().substring(0,6)
+ " for socket " + s, ex);
s.internalClose();
throw ex;
} catch (NoRouteToHostException ex) {
if (_log.shouldLog(Log.DEBUG))
_log.debug(getName() + ": No route to host waiting for ack from syn for id "
+ lcID + " to " + peer.calculateHash().toBase64().substring(0,6)
+ " for socket " + s, ex);
s.internalClose();
throw ex;
} catch (IOException ex) {
if (_log.shouldLog(Log.ERROR))
_log.error(getName() + ": Error sending syn on id " + getReadableForm(lcID) + " for socket " + s, ex);
if (_log.shouldLog(Log.WARN))
_log.warn(getName() + ": Error sending syn on id "
+ lcID + " to " + peer.calculateHash().toBase64().substring(0,6)
+ " for socket " + s, ex);
synchronized (lock) {
_outSockets.remove(s.getLocalID());
}
@ -513,7 +543,9 @@ public class I2PSocketManager implements I2PSessionListener {
throw new I2PException("Unhandled IOException occurred");
} catch (I2PException ex) {
if (_log.shouldLog(Log.INFO))
_log.info(getName() + ": Error sending syn on id " + getReadableForm(lcID) + " for socket " + s, ex);
_log.info(getName() + ": Error sending syn on id "
+ lcID + " to " + peer.calculateHash().toBase64().substring(0,6)
+ " for socket " + s, ex);
synchronized (lock) {
_outSockets.remove(s.getLocalID());
}
@ -521,7 +553,9 @@ public class I2PSocketManager implements I2PSessionListener {
throw ex;
} catch (Exception e) {
s.internalClose();
_log.error(getName() + ": Unhandled error connecting", e);
_log.warn(getName() + ": Unhandled error connecting on "
+ lcID + " to " + peer.calculateHash().toBase64().substring(0,6)
+ " for socket " + s, e);
throw new ConnectException("Unhandled error connecting: " + e.getMessage());
}
}
@ -592,7 +626,7 @@ public class I2PSocketManager implements I2PSessionListener {
_session.destroySession();
_log.debug(getName() + ": I2P session destroyed");
} catch (I2PSessionException e) {
_log.error(getName() + ": Error destroying I2P session", e);
_log.warn(getName() + ": Error destroying I2P session", e);
}
}
@ -618,15 +652,17 @@ public class I2PSocketManager implements I2PSessionListener {
try {
return _session.sendMessage(peer, new byte[] { (byte) CHAFF});
} catch (I2PException ex) {
_log.error(getName() + ": I2PException:", ex);
_log.warn(getName() + ": I2PException:", ex);
return false;
}
}
public void removeSocket(I2PSocketImpl sock) {
String localId = sock.getLocalID();
boolean removed = false;
synchronized (lock) {
_inSockets.remove(sock.getLocalID());
_outSockets.remove(sock.getLocalID());
removed = (null != _inSockets.remove(localId));
removed = removed || (null != _outSockets.remove(localId));
lock.notify();
}
@ -637,9 +673,10 @@ public class I2PSocketManager implements I2PSessionListener {
long recv = sock.getBytesReceived();
if (_log.shouldLog(Log.DEBUG)) {
_log.debug(getName() + ": Removing socket \"" + getReadableForm(sock.getLocalID()) + "\" [" + sock
_log.debug(getName() + ": Removing socket \"" + getReadableForm(localId) + "\" [" + sock
+ ", send: " + sent + ", recv: " + recv
+ ", lifetime: " + lifetime + "ms, time since close: " + timeSinceClose + ")]",
+ ", lifetime: " + lifetime + "ms, time since close: " + timeSinceClose
+ " removed? " + removed + ")]",
new Exception("removeSocket called"));
}

39
apps/myi2p/java/build.xml Normal file
View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<project basedir="." default="all" name="myi2p">
<target name="all" depends="clean, build" />
<target name="build" depends="builddep, jar" />
<target name="builddep">
<ant dir="../../../core/java/" target="build" />
</target>
<target name="compile">
<mkdir dir="./build" />
<mkdir dir="./build/obj" />
<javac
srcdir="./src"
debug="true" deprecation="on" source="1.3" target="1.3"
destdir="./build/obj"
classpath="../../../core/java/build/i2p.jar" />
</target>
<target name="jar" depends="compile">
<jar destfile="./build/myi2p.jar" basedir="./build/obj" includes="**/*.class" />
</target>
<target name="javadoc">
<mkdir dir="./build" />
<mkdir dir="./build/javadoc" />
<javadoc
sourcepath="./src:../../../core/java/src" destdir="./build/javadoc"
packagenames="*"
use="true"
splitindex="true"
windowtitle="MyI2P" />
</target>
<target name="clean">
<delete dir="./build" />
</target>
<target name="cleandep" depends="clean">
<ant dir="../../../core/java/" target="distclean" />
</target>
<target name="distclean" depends="clean">
<ant dir="../../../core/java/" target="distclean" />
</target>
</project>

View File

@ -0,0 +1,116 @@
package net.i2p.myi2p;
import net.i2p.data.Destination;
/**
* Packages up a message for delivery. The raw format of the message within a
* repliable datagram is
* <code>MyI2P $maj.$min $service $type\n$payload</code>
* where <code>$maj.$min</code> is currently 1.0, $service is the type of MyI2P
* service, $type is the type of message within that service, and $payload is
* the data specific to that type.
*
*/
public class MyI2PMessage {
private Destination _peer;
private String _service;
private String _type;
private byte[] _payload;
private static final byte[] MESSAGE_PREFIX = "MyI2P 1.0 ".getBytes();
/**
* Build a new MyI2P message to be sent.
*
* @param to address to send the message
* @param service what MyI2P service is involved
* @param type type of message within that service is involved
* @param data payload of the message to deliver
*/
public MyI2PMessage(Destination to, String service, String type, byte data[]) {
_peer = to;
_service = service;
_type = type;
_payload = data;
}
/**
* Read in the MyI2P data from the given datagram info.
*
* @param from authenticated from address
* @param dgramPayload raw MyI2P formatted message
* @throws IllegalArgumentException if the message is not a valid MyI2P message
*/
public MyI2PMessage(Destination from, byte dgramPayload[]) throws IllegalArgumentException {
_peer = from;
int index = 0;
while (index < dgramPayload.length) {
if (index >= MESSAGE_PREFIX.length) break;
if (dgramPayload[index] != MESSAGE_PREFIX[index])
throw new IllegalArgumentException("Invalid payload (not a MyI2P message)");
index++;
}
// $service $type\n$payload
StringBuffer service = new StringBuffer(8);
while (index < dgramPayload.length) {
if (dgramPayload[index] == ' ') {
_service = service.toString();
index++;
break;
} else if (dgramPayload[index] == '\n') {
throw new IllegalArgumentException("Ran into newline while reading the service");
} else {
service.append((char)dgramPayload[index]);
index++;
}
}
StringBuffer type = new StringBuffer(8);
while (index < dgramPayload.length) {
if (dgramPayload[index] == '\n') {
_type = type.toString();
index++;
break;
} else {
service.append((char)dgramPayload[index]);
index++;
}
}
_payload = new byte[dgramPayload.length-index];
System.arraycopy(dgramPayload, index, _payload, 0, _payload.length);
}
/** who is this message from or who is it going to? */
public Destination getPeer() { return _peer; }
/** what MyI2P service is this bound for (addressBook, blog, etc)? */
public String getServiceType() { return _service; }
/** within that service, what type of message is this? */
public String getMessageType() { return _type; }
/** what is the raw data for the particular message? */
public byte[] getPayload() { return _payload; }
/**
* Retrieve the raw payload, suitable for wrapping in an I2PDatagramMaker
* and sending to another MyI2P node.
*
* @throws IllegalStateException if some data is missing
*/
public byte[] toRawPayload() throws IllegalStateException {
if (_service == null) throw new IllegalStateException("Service is null");
if (_type == null) throw new IllegalStateException("Type is null");
if (_payload == null) throw new IllegalStateException("Payload is null");
byte service[] = _service.getBytes();
byte type[] = _type.getBytes();
byte rv[] = new byte[MESSAGE_PREFIX.length + service.length + 1 + type.length + 1 + _payload.length];
System.arraycopy(MESSAGE_PREFIX, 0, rv, 0, MESSAGE_PREFIX.length);
System.arraycopy(service, 0, rv, MESSAGE_PREFIX.length, service.length);
rv[MESSAGE_PREFIX.length + service.length] = ' ';
System.arraycopy(type, 0, rv, MESSAGE_PREFIX.length + service.length + 1, type.length);
rv[MESSAGE_PREFIX.length + service.length + 1 + type.length] = '\n';
System.arraycopy(_payload, 0, rv, MESSAGE_PREFIX.length + service.length + 1 + type.length + 1, _payload.length);
return rv;
}
}

View File

@ -0,0 +1,266 @@
package net.i2p.myi2p;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import net.i2p.I2PAppContext;
import net.i2p.util.Log;
/**
* Main controller for a MyI2P node, coordinating all network communication and
* distributing messages to the appropriate services.
*
*/
public class Node {
private static List _nodes = new ArrayList(1);
/**
* Return a list of Node instances that are currently
* operating in the JVM
*/
private static List nodes() {
synchronized (_nodes) {
return new ArrayList(_nodes);
}
}
private I2PAppContext _context;
private Log _log;
private NodeAdapter _adapter;
/**
* contains configuration properties, such where our router is, what
* services to run, etc
*
*/
private Properties _config;
/** filename where _config is stored */
private String _configFile = DEFAULT_CONFIG_FILE;
/** mapping of service name (String) to Service for all services loaded */
private Map _services;
private static final String DEFAULT_CONFIG_FILE = "myi2p.config";
private static final String DEFAULT_KEY_FILE = "myi2p.keys";
private static final String PROP_KEY_FILE = "keyFile";
public Node(I2PAppContext context) {
_context = context;
_log = context.logManager().getLog(Node.class);
_config = new Properties();
_services = new HashMap(1);
if (_log.shouldLog(Log.CRIT))
_log.log(Log.CRIT, "Node created");
_adapter = new NodeAdapter(_context, this);
}
/**
* Main driver for the node. Usage: <code>Node [configFile]</code>
*
*/
public static void main(String args[]) {
String filename = DEFAULT_CONFIG_FILE;
if ( (args != null) && (args.length == 1) )
filename = args[0];
Node node = new Node(I2PAppContext.getGlobalContext());
node.setConfigFile(filename);
node.loadConfig();
node.startup();
while (true) {
//try { Thread.sleep(10*1000); } catch (InterruptedException ie) {}
//node.shutdown();
//if (true) return;
synchronized (node) {
try { node.wait(); } catch (InterruptedException ie) {}
}
}
}
public Properties getConfig() {
synchronized (_config) {
return new Properties(_config);
}
}
public void setConfig(Properties props) {
synchronized (_config) {
_config.clear();
_config.putAll(props);
}
}
public String getConfigFile() { return _configFile; }
public void setConfigFile(String filename) { _configFile = filename; }
/**
* Load up the config and all of the services
*
*/
public void loadConfig() {
FileInputStream fis = null;
try {
File cfgFile = new File(_configFile);
if (cfgFile.exists()) {
fis = new FileInputStream(cfgFile);
Properties props = new Properties();
props.load(fis);
setConfig(props);
if (_log.shouldLog(Log.INFO))
_log.info("Config loaded from " + _configFile);
} else {
if (_log.shouldLog(Log.ERROR))
_log.error("Config file " + _configFile + " does not exist, so we aren't going to do much");
}
} catch (IOException ioe) {
if (_log.shouldLog(Log.ERROR))
_log.error("Error reading config file " + _configFile, ioe);
} finally {
if (fis != null) try { fis.close(); } catch (IOException ioe) {}
}
}
/**
* Boot up the node, connect to the router, and start all the services
*
*/
public void startup() {
boolean connected = connect();
if (connected) {
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
public void run() { shutdown(); }
}));
loadServices();
startServices();
synchronized (_nodes) {
_nodes.add(this);
}
if (_log.shouldLog(Log.INFO))
_log.info("Node started");
} else {
if (_log.shouldLog(Log.ERROR))
_log.error("Unable to connect, startup didn't do much");
}
}
/**
* Drop any connections to the network and stop all services
*
*/
public void shutdown() {
disconnect();
stopServices();
synchronized (_nodes) {
_nodes.remove(this);
}
}
/**
* Send a message from the node to the peer as specified in the message
*
* @return true if it was sent
*/
public boolean sendMessage(MyI2PMessage msg) {
return _adapter.sendMessage(msg);
}
private void loadServices() {
Properties config = getConfig();
int i = 0;
while (true) {
String classname = config.getProperty("service."+i+".classname");
if ( (classname == null) || (classname.trim().length() <= 0) )
break;
boolean ok = loadService("service." + i + ".", config);
if (ok) i++;
}
if (_log.shouldLog(Log.INFO))
_log.info(i + " services loaded");
}
private boolean loadService(String prefix, Properties config) {
String classname = config.getProperty(prefix + "classname");
String type = config.getProperty(prefix + "type");
if (type == null) return false;
Properties opts = new Properties();
int i = 0;
while (true) {
String name = config.getProperty(prefix + "option." + i + ".name");
String value = config.getProperty(prefix + "option." + i + ".value");
if ( (name == null) || (name.trim().length() <= 0) || (value == null) || (value.trim().length() <= 0) )
break;
opts.setProperty(name.trim(), value.trim());
i++;
}
try {
Class cls = Class.forName(classname);
Object obj = cls.newInstance();
if (obj instanceof Service) {
Service service = (Service)obj;
service.setType(type);
service.setOptions(opts);
service.setNode(this);
service.setContext(_context);
synchronized (_services) {
_services.put(type, service);
}
if (_log.shouldLog(Log.INFO))
_log.info("Service " + type + " loaded");
return true;
} else {
if (_log.shouldLog(Log.ERROR))
_log.error("Error loading service " + type + ": not a service [" + classname + "]");
}
} catch (ClassNotFoundException cnfe) {
if (_log.shouldLog(Log.ERROR))
_log.error("Error loading service " + type + ": class " + classname + " is invalid", cnfe);
} catch (InstantiationException ie) {
if (_log.shouldLog(Log.ERROR))
_log.error("Error instantiating service " + type + ": class " + classname + " could not be created", ie);
} catch (IllegalAccessException iae) {
if (_log.shouldLog(Log.ERROR))
_log.error("Error creating service " + type + ": class " + classname + " could not be accessed", iae);
}
return false;
}
private boolean connect() {
Properties config = getConfig();
File keyFile = new File(config.getProperty(PROP_KEY_FILE, DEFAULT_KEY_FILE));
return _adapter.connect(config, keyFile);
}
private void disconnect() {
_adapter.disconnect();
}
private void startServices() {
for (Iterator iter = _services.values().iterator(); iter.hasNext(); ) {
Service service = (Service)iter.next();
service.startup();
}
}
private void stopServices() {
for (Iterator iter = _services.values().iterator(); iter.hasNext(); ) {
Service service = (Service)iter.next();
service.shutdown();
}
}
void handleMessage(MyI2PMessage msg) {
Service service = (Service)_services.get(msg.getServiceType());
if (service == null) {
if (_log.shouldLog(Log.ERROR))
_log.error("Message received for an unknown service ["
+ msg.getServiceType() + "] from "
+ msg.getPeer().calculateHash().toBase64());
} else {
service.receiveMessage(msg);
}
}
}

View File

@ -0,0 +1,178 @@
package net.i2p.myi2p;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
import net.i2p.I2PAppContext;
import net.i2p.I2PException;
import net.i2p.client.I2PClient;
import net.i2p.client.I2PClientFactory;
import net.i2p.client.I2PSession;
import net.i2p.client.I2PSessionListener;
import net.i2p.client.I2PSessionException;
import net.i2p.client.datagram.I2PDatagramDissector;
import net.i2p.client.datagram.I2PDatagramMaker;
import net.i2p.client.datagram.I2PInvalidDatagramException;
import net.i2p.data.DataFormatException;
import net.i2p.data.Destination;
import net.i2p.util.Log;
/**
* Bind the MyI2P node to the I2P network, handling messages, sessions,
* etc.
*
*/
public class NodeAdapter implements I2PSessionListener {
private I2PAppContext _context;
private Log _log;
private Node _node;
private I2PSession _session;
public NodeAdapter(I2PAppContext context, Node node) {
_node = node;
_context = context;
_log = context.logManager().getLog(NodeAdapter.class);
}
boolean sendMessage(MyI2PMessage msg) {
if (_session == null) {
if (_log.shouldLog(Log.ERROR))
_log.error("Cannot send the message, as we are not connected");
return false;
}
try {
I2PDatagramMaker builder = new I2PDatagramMaker(_session);
byte dgram[] = builder.makeI2PDatagram(msg.toRawPayload());
return _session.sendMessage(msg.getPeer(), dgram);
} catch (IllegalStateException ise) {
if (_log.shouldLog(Log.ERROR))
_log.error("MyI2PMessage was not valid", ise);
return false;
} catch (I2PSessionException ise) {
if (_log.shouldLog(Log.ERROR))
_log.error("Error sending to the peer", ise);
return false;
}
}
/**
* Connect to the network using the current I2CP config and the private
* key file specified in the node config. If the file does not exist, a new
* destination will be created.
*
* @param config MyI2P node and I2CP configuration
* @param keyFile file to load the private keystream from (if it doesn't
* exist, a new one will be created and stored at that location)
*
* @return true if connection was successful, false otherwise
*/
boolean connect(Properties config, File keyFile) {
I2PClient client = I2PClientFactory.createClient();
if (!keyFile.exists()) {
File parent = keyFile.getParentFile();
if (parent != null) parent.mkdirs();
FileOutputStream fos = null;
try {
fos = new FileOutputStream(keyFile);
Destination dest = client.createDestination(fos);
if (_log.shouldLog(Log.INFO))
_log.info("New destination created ["
+ dest.calculateHash().toBase64()
+ "] with keys at " + keyFile);
} catch (IOException ioe) {
if (_log.shouldLog(Log.ERROR))
_log.error("Error writing new keystream to " + keyFile, ioe);
return false;
} catch (I2PException ie) {
if (_log.shouldLog(Log.ERROR))
_log.error("Internal error creating new destination", ie);
return false;
} finally {
if (fos != null) try { fos.close(); } catch (IOException ioe) {}
}
}
FileInputStream fis = null;
try {
fis = new FileInputStream(keyFile);
_session = client.createSession(fis, config);
if (_session == null) {
_log.error("wtf, why did it create a null session?");
return false;
}
_session.setSessionListener(this);
_session.connect();
if (_log.shouldLog(Log.INFO))
_log.info("I2P session created");
return true;
} catch (IOException ioe) {
if (_log.shouldLog(Log.ERROR))
_log.error("Unable to read the keystream from " + keyFile, ioe);
return false;
} catch (I2PSessionException ise) {
if (_log.shouldLog(Log.ERROR))
_log.error("Unable to connect to the router", ise);
return false;
} finally {
if (fis != null) try { fis.close(); } catch (IOException ioe) {}
}
}
void disconnect() {
if (_session != null) {
try {
_session.destroySession();
} catch (I2PSessionException ise) {
if (_log.shouldLog(Log.WARN))
_log.warn("Error destroying the session in shutdown", ise);
}
_session = null;
}
}
public void disconnected(I2PSession session) {
if (_log.shouldLog(Log.INFO))
_log.info("Session disconnected");
}
public void errorOccurred(I2PSession session, String message, Throwable error) {
if (_log.shouldLog(Log.ERROR))
_log.error("Session error occurred - " + message, error);
}
public void messageAvailable(I2PSession session, int msgId, long size) {
if (_log.shouldLog(Log.INFO))
_log.info("message available [" + msgId + "/"+ size + " bytes]");
try {
byte data[] = session.receiveMessage(msgId);
I2PDatagramDissector dissector = new I2PDatagramDissector();
dissector.loadI2PDatagram(data);
try {
MyI2PMessage msg = new MyI2PMessage(dissector.getSender(), dissector.getPayload());
_node.handleMessage(msg);
} catch (IllegalArgumentException iae) {
if (_log.shouldLog(Log.ERROR))
_log.error("Message is a valid datagram but invalid MyI2P message", iae);
}
} catch (I2PSessionException ise) {
if (_log.shouldLog(Log.ERROR))
_log.error("Error retrieving message payload for message " + msgId, ise);
} catch (I2PInvalidDatagramException iide) {
if (_log.shouldLog(Log.ERROR))
_log.error("Message received was not a valid repliable datagram", iide);
} catch (DataFormatException dfe) {
if (_log.shouldLog(Log.ERROR))
_log.error("Message received was a corrupt repliable datagram", dfe);
}
}
public void reportAbuse(I2PSession session, int severity) {
if (_log.shouldLog(Log.INFO))
_log.info("abuse occurred");
}
}

View File

@ -0,0 +1,35 @@
package net.i2p.myi2p;
import java.util.Properties;
import net.i2p.I2PAppContext;
/**
* Defines a service that can operate within a MyI2P node, responding to
* messages and performing whatever tasks are necessary.
*
*/
public interface Service {
/** what type of message will this service respond to? */
public String getType();
public void setType(String type);
/** what node is this service hooked into */
public Node getNode();
public void setNode(Node node);
/** what options specific to this node does the service have? */
public Properties getOptions();
public void setOptions(Properties opts);
/** give the service a scope */
public I2PAppContext getContext();
public void setContext(I2PAppContext context);
/** called when a message is received for the service */
public void receiveMessage(MyI2PMessage msg);
/** start the service up - the node is ready */
public void startup();
/** shut the service down - the node is going offline */
public void shutdown();
}

View File

@ -0,0 +1,36 @@
package net.i2p.myi2p;
import java.util.Properties;
import net.i2p.I2PAppContext;
import net.i2p.myi2p.Service;
import net.i2p.myi2p.Node;
import net.i2p.myi2p.MyI2PMessage;
/**
* Base service implementation
*
*/
public abstract class ServiceImpl implements Service {
private I2PAppContext _context;
private Node _node;
private Properties _options;
private String _serviceType;
public ServiceImpl() {
_context = null;
_node = null;
_options = null;
_serviceType = null;
}
// base inspectors / mutators
public Node getNode() { return _node; }
public void setNode(Node node) { _node = node; }
public I2PAppContext getContext() { return _context; }
public void setContext(I2PAppContext context) { _context = context; }
public Properties getOptions() { return _options; }
public void setOptions(Properties opts) { _options = opts; }
public String getType() { return _serviceType; }
public void setType(String type) { _serviceType = type; }
}

View File

@ -0,0 +1,126 @@
package net.i2p.myi2p.address;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import net.i2p.I2PAppContext;
import net.i2p.data.DataHelper;
import net.i2p.data.DataFormatException;
/**
* Main lookup component for maintaining references to other I2P destinations.
*
*/
public class AddressBook {
private I2PAppContext _context;
/** Name (String) to AddressBookEntry */
private Map _entries;
/**
* List of NameReference that has been received but whose preferred
* name conflicts with an existing entry.
*/
private List _conflictingReferences;
public AddressBook(I2PAppContext context) {
_context = context;
_entries = new HashMap(16);
_conflictingReferences = new ArrayList(0);
}
/** retrieve a list of entry names (strings) */
public Set getEntryNames() {
synchronized (_entries) {
return new HashSet(_entries.keySet());
}
}
public AddressBookEntry getEntry(String name) {
synchronized (_entries) {
return (AddressBookEntry)_entries.get(name);
}
}
public AddressBookEntry addEntry(AddressBookEntry entry) {
synchronized (_entries) {
return (AddressBookEntry)_entries.put(entry.getLocalName(), entry);
}
}
public void removeEntry(String name) {
synchronized (_entries) {
_entries.remove(name);
}
}
public int getConflictingReferenceCount() {
synchronized (_conflictingReferences) {
return _conflictingReferences.size();
}
}
public NameReference getConflictingReference(int index) {
synchronized (_conflictingReferences) {
return (NameReference)_conflictingReferences.get(index);
}
}
public void addConflictingReference(NameReference ref) {
synchronized (_conflictingReferences) {
_conflictingReferences.add(ref);
}
}
public void removeConflictingReference(int index) {
synchronized (_conflictingReferences) {
_conflictingReferences.remove(index);
}
}
public void read(InputStream in) throws IOException {
try {
int numEntries = (int)DataHelper.readLong(in, 2);
if (numEntries < 0) throw new IOException("Corrupt AddressBook - " + numEntries + " entries?");
for (int i = 0; i < numEntries; i++) {
AddressBookEntry entry = new AddressBookEntry(_context);
entry.read(in);
addEntry(entry);
}
int numConflicting = (int)DataHelper.readLong(in, 2);
if (numConflicting < 0) throw new IOException("Corrupt AddressBook - " + numConflicting + " conflicting?");
for (int i = 0; i < numConflicting; i++) {
NameReference ref = new NameReference(_context);
ref.read(in);
addConflictingReference(ref);
}
} catch (DataFormatException dfe) {
throw new IOException("Corrupt address book - " + dfe.getMessage());
}
}
public void write(OutputStream out) throws IOException {
try {
synchronized (_entries) {
DataHelper.writeLong(out, 2, _entries.size());
for (Iterator iter = _entries.values().iterator(); iter.hasNext(); ) {
AddressBookEntry entry = (AddressBookEntry)iter.next();
entry.write(out);
}
}
synchronized (_conflictingReferences) {
DataHelper.writeLong(out, 2, _conflictingReferences.size());
for (int i = 0; i < _conflictingReferences.size(); i++) {
NameReference ref = (NameReference)_conflictingReferences.get(i);
ref.write(out);
}
}
} catch (DataFormatException dfe) {
throw new IOException("Corrupt address book - " + dfe.getMessage());
}
}
public String toString() {
return "Entries: " + _entries.size() + " conflicting: " + _conflictingReferences.size();
}
}

View File

@ -0,0 +1,142 @@
package net.i2p.myi2p.address;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
import java.util.Properties;
import net.i2p.I2PAppContext;
import net.i2p.data.DataHelper;
import net.i2p.data.DataFormatException;
/**
* Implements a local address book entry, pointing at a known secure
* NameReference as well as an optional Subscription.
*
*/
public class AddressBookEntry {
private I2PAppContext _context;
private String _localName;
private Properties _options;
private NameReference _reference;
private Subscription _subscription;
private long _addedOn;
public AddressBookEntry(I2PAppContext context) {
_context = context;
_localName = null;
_options = new Properties();
_reference = null;
_subscription = null;
_addedOn = context.clock().now();
}
/** Local (unique) name we use to reference the given destination */
public String getLocalName() { return _localName; }
public void setLocalName(String name) { _localName = name; }
public Properties getOptions() {
synchronized (_options) {
return new Properties(_options);
}
}
public void setOptions(Properties props) {
synchronized (_options) {
_options.clear();
if (props != null)
_options.putAll(props);
}
}
/** Secure name reference, provided by the destination */
public NameReference getNameReference() { return _reference; }
public void setNameReference(NameReference ref) { _reference = ref; }
/**
* If specified, the details of our subscription to the MyI2P address
* book at the referenced destination.
*
*/
public Subscription getSubscription() { return _subscription; }
public void setSubscription(Subscription sub) { _subscription = sub; }
/** When this entry was added */
public long getAddedOn() { return _addedOn; }
public void setAddedOn(long when) { _addedOn = when; }
/** load the data from the stream */
public void read(InputStream in) throws IOException {
try {
Boolean localNameDefined = DataHelper.readBoolean(in);
if ( (localNameDefined != null) && (localNameDefined.booleanValue()) )
_localName = DataHelper.readString(in);
else
_localName = null;
Date when = DataHelper.readDate(in);
if (when == null)
_addedOn = -1;
else
_addedOn = when.getTime();
Properties props = DataHelper.readProperties(in);
setOptions(props);
Boolean refDefined = DataHelper.readBoolean(in);
if ( (refDefined != null) && (refDefined.booleanValue()) ) {
_reference = new NameReference(_context);
_reference.read(in);
} else {
_reference = null;
}
Boolean subDefined = DataHelper.readBoolean(in);
if ( (subDefined != null) && (subDefined.booleanValue()) ) {
Subscription sub = new Subscription(_context);
sub.read(in);
_subscription = sub;
} else {
_subscription = null;
}
} catch (DataFormatException dfe) {
throw new IOException("Corrupt subscription: " + dfe.getMessage());
}
}
/** persist the data to the stream */
public void write(OutputStream out) throws IOException {
try {
if ( (_localName != null) && (_localName.trim().length() > 0) ) {
DataHelper.writeBoolean(out, Boolean.TRUE);
DataHelper.writeString(out, _localName);
} else {
DataHelper.writeBoolean(out, Boolean.FALSE);
}
DataHelper.writeDate(out, new Date(_addedOn));
synchronized (_options) {
DataHelper.writeProperties(out, _options);
}
if (_reference != null) {
DataHelper.writeBoolean(out, Boolean.TRUE);
_reference.write(out);
} else {
DataHelper.writeBoolean(out, Boolean.FALSE);
}
if (_subscription != null) {
DataHelper.writeBoolean(out, Boolean.TRUE);
_subscription.write(out);
} else {
DataHelper.writeBoolean(out, Boolean.FALSE);
}
} catch (DataFormatException dfe) {
throw new IOException("Corrupt subscription: " + dfe.getMessage());
}
}
}

View File

@ -0,0 +1,90 @@
package net.i2p.myi2p.address;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import net.i2p.data.DataHelper;
import net.i2p.data.DataFormatException;
import net.i2p.util.Log;
import net.i2p.myi2p.Service;
import net.i2p.myi2p.ServiceImpl;
import net.i2p.myi2p.Node;
import net.i2p.myi2p.MyI2PMessage;
/**
* Main service handler / coordinator for the MyI2P address book.
*
*/
public class AddressBookService extends ServiceImpl {
private Log _log;
private AddressBook _addressBook;
/** contains a mapping of event time (Long) to description (String) */
private Map _activityLog;
private String _addressBookFile;
private static String PROP_ADDRESSBOOK_FILE = "datafile";
private static String DEFAULT_ADDRESSBOOK_FILE = "addressbook.dat";
public static final String SERVICE_TYPE = "AddressBook";
public String getType() { return SERVICE_TYPE; }
public void startup() {
_log = getContext().logManager().getLog(AddressBookService.class);
_addressBookFile = getOptions().getProperty(PROP_ADDRESSBOOK_FILE, DEFAULT_ADDRESSBOOK_FILE);
File file = new File(_addressBookFile);
if (file.exists()) {
loadData(file);
} else {
_addressBook = new AddressBook(getContext());
_activityLog = new HashMap(16);
}
}
public void shutdown() {
File file = new File(_addressBookFile);
storeData(file);
}
public void receiveMessage(MyI2PMessage msg) {
_log.info("Received a " + msg.getMessageType() + " from "
+ msg.getPeer().calculateHash().toBase64()
+ new String(msg.getPayload()));
}
/** load everything from disk */
private void loadData(File dataFile) {
AddressBookServiceData data = new AddressBookServiceData(getContext());
data.load(dataFile);
if (data.getErrorMessage() != null) {
_log.warn(data.getErrorMessage(), data.getError());
_addressBook = new AddressBook(getContext());
_activityLog = new HashMap(16);
} else {
_addressBook = data.getAddressBook();
_activityLog = data.getActivityLog();
}
}
/** persist everything to disk */
private void storeData(File dataFile) {
AddressBookServiceData data = new AddressBookServiceData(getContext());
data.setActivityLog(_activityLog);
data.setAddressBook(_addressBook);
data.store(dataFile);
if (data.getErrorMessage() != null) {
_log.warn(data.getErrorMessage(), data.getError());
}
}
}

View File

@ -0,0 +1,104 @@
package net.i2p.myi2p.address;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import net.i2p.I2PAppContext;
import net.i2p.data.DataHelper;
import net.i2p.util.Log;
/**
* Component for loading and storing the service data to disk
*
*/
public class AddressBookServiceData {
private I2PAppContext _context;
private Log _log;
private AddressBook _addressBook;
private Map _activityLog;
private Exception _error;
private String _errorMessage;
public AddressBookServiceData(I2PAppContext context) {
_context = context;
_log = context.logManager().getLog(AddressBookServiceData.class);
_addressBook = null;
_activityLog = null;
_error = null;
_errorMessage = null;
}
public AddressBook getAddressBook() { return _addressBook; }
public void setAddressBook(AddressBook book) { _addressBook = book; }
public Map getActivityLog() { return _activityLog; }
public void setActivityLog(Map log) { _activityLog = log; }
public Exception getError() { return _error; }
public String getErrorMessage() { return _errorMessage; }
public void load(File from) {
FileInputStream fis = null;
try {
fis = new FileInputStream(from);
AddressBook addressBook = new AddressBook(_context);
addressBook.read(fis);
_addressBook = addressBook;
if (_log.shouldLog(Log.DEBUG))
_log.debug("Address book: " + addressBook);
Properties props = DataHelper.readProperties(fis);
Map log = new HashMap(props.size());
for (Iterator iter = props.keySet().iterator(); iter.hasNext(); ) {
String key = (String)iter.next();
String event = props.getProperty(key);
long when = 0;
try {
when = Long.parseLong(key);
while (log.containsKey(new Long(when)))
when++;
log.put(new Long(when), event);
if (_log.shouldLog(Log.DEBUG))
_log.debug("Activity log: on " + new Date(when) + ": " + event);
} catch (NumberFormatException nfe) {
if (_log.shouldLog(Log.WARN))
_log.warn("Corrupt activity log entry: when=" + key, nfe);
}
}
_activityLog = log;
} catch (Exception e) {
_error = e;
_errorMessage = "Error reading the address book from " + from;
}
}
public void store(File to) {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(to);
_addressBook.write(fos);
Properties props = new Properties();
for (Iterator iter = _activityLog.keySet().iterator(); iter.hasNext(); ) {
Long when = (Long)iter.next();
String msg = (String)_activityLog.get(when);
props.setProperty(when.toString(), msg);
}
DataHelper.writeProperties(fos, props);
} catch (Exception e) {
_error = e;
_errorMessage = "Error writing the address book to " + to;
} finally {
if (fos != null) try { fos.close(); } catch (IOException ioe) {}
}
}
}

View File

@ -0,0 +1,154 @@
package net.i2p.myi2p.address;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import net.i2p.I2PAppContext;
import net.i2p.data.Destination;
import net.i2p.util.Log;
/**
* CreateEntryCLI addressBookFile referenceFile localName subscriptionFrequencyHours [ key=value]*
*/
public class CreateEntryCLI {
private I2PAppContext _context;
private String _args[];
private String _addressBook;
private String _referenceFile;
private String _localName;
private int _subscriptionFrequencyHours;
private Properties _options;
public CreateEntryCLI(String args[]) {
_context = new I2PAppContext();
_args = args;
_options = new Properties();
}
public void execute() {
if (parseArgs())
doExecute();
else
System.err.println("Usage: CreateEntryCLI addressBookFile referenceFile localName subscriptionFrequencyHours[ key=value]*");
}
private boolean parseArgs() {
if ( (_args == null) || (_args.length < 3) )
return false;
_addressBook = _args[0];
_referenceFile = _args[1];
_localName = _args[2];
try {
_subscriptionFrequencyHours = Integer.parseInt(_args[3]);
} catch (NumberFormatException nfe) {
return false;
}
for (int i = 4; i < _args.length; i++) {
int eq = _args[i].indexOf('=');
if ( (eq <= 0) || (eq >= _args[i].length() - 1) )
continue;
String key = _args[i].substring(0,eq);
String val = _args[i].substring(eq+1);
_options.setProperty(key, val);
}
return true;
}
private void doExecute() {
AddressBookServiceData data = new AddressBookServiceData(_context);
File f = new File(_addressBook);
if (f.exists()) {
data.load(f);
if (data.getError() != null) {
if (data.getErrorMessage() != null)
System.err.println(data.getErrorMessage());
data.getError().printStackTrace();
return;
}
} else {
data.setAddressBook(new AddressBook(_context));
data.setActivityLog(new HashMap());
}
NameReference ref = null;
FileInputStream fis = null;
try {
fis = new FileInputStream(_referenceFile);
ref = new NameReference(_context);
ref.read(fis);
} catch (Exception e) {
System.err.println("Name reference under " + _referenceFile + " is corrupt");
e.printStackTrace();
return;
} finally {
if (fis != null) try { fis.close(); } catch (IOException ioe) {}
}
AddressBook book = data.getAddressBook();
Map activityLog = data.getActivityLog();
AddressBookEntry oldEntry = book.getEntry(_localName);
AddressBookEntry entry = new AddressBookEntry(_context);
entry.setLocalName(_localName);
entry.setNameReference(ref);
Subscription sub = new Subscription(_context);
sub.setQueryFrequencyMinutes(60*_subscriptionFrequencyHours);
entry.setSubscription(sub);
entry.setOptions(_options);
if (oldEntry == null) {
book.addEntry(entry);
System.out.println("New address book entry added for " + entry.getLocalName());
activityLog.put(new Long(_context.clock().now()), "New address book entry added for " + entry.getLocalName());
} else {
Destination oldDest = oldEntry.getNameReference().getDestination();
if (oldDest.equals(ref.getDestination())) {
if (ref.getSequenceNum() < oldEntry.getNameReference().getSequenceNum()) {
System.err.println("Not updating the address book - newer reference for " + entry.getLocalName() + " exists");
return;
} else {
// same or newer rev
if (null != entry.getSubscription()) {
if (null != oldEntry.getSubscription()) {
entry.getSubscription().setLastQueryAttempt(oldEntry.getSubscription().getLastQueryAttempt());
entry.getSubscription().setLastQuerySuccess(oldEntry.getSubscription().getLastQuerySuccess());
}
}
book.addEntry(entry);
System.err.println("Updating the options and subscription for an existing reference to " + entry.getLocalName());
activityLog.put(new Long(_context.clock().now()), "Updating options and subscription for " + entry.getLocalName());
}
} else {
book.addConflictingReference(ref);
System.out.println("Old entry exists for " + _localName + " - adding a conflicting reference");
System.out.println("Existing entry points to " + oldEntry.getNameReference().getDestination().calculateHash().toBase64());
System.out.println("New entry points to " + entry.getNameReference().getDestination().calculateHash().toBase64());
activityLog.put(new Long(_context.clock().now()), "Adding conflicting reference for " + entry.getLocalName());
}
}
data.setAddressBook(book);
data.setActivityLog(activityLog);
data.store(f);
if (data.getError() != null) {
if (data.getErrorMessage() != null)
System.err.println(data.getErrorMessage());
data.getError().printStackTrace();
return;
}
}
public static void main(String args[]) {
CreateEntryCLI cli = new CreateEntryCLI(args);
cli.execute();
}
}

View File

@ -0,0 +1,125 @@
package net.i2p.myi2p.address;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.Properties;
import net.i2p.I2PAppContext;
import net.i2p.data.Destination;
import net.i2p.data.PrivateKey;
import net.i2p.data.SigningPrivateKey;
import net.i2p.util.Log;
/**
* CreateNameReferenceCLI outputFile privateDestFile preferredName sequenceNum serviceType[ key=value]*
*/
public class CreateNameReferenceCLI {
private I2PAppContext _context;
private String _args[];
private String _outputFile;
private String _destFile;
private String _preferredName;
private long _sequenceNum;
private String _serviceType;
private Properties _options;
public CreateNameReferenceCLI(String[] args) {
_context = new I2PAppContext();
_args = args;
_options = new Properties();
}
public void execute() {
if (parseArgs())
doExecute();
else
System.err.println("Usage: CreateNameReferenceCLI outputFile privateDestFile preferredName sequenceNum serviceType[ key=value]*");
}
private boolean parseArgs() {
if ( (_args == null) || (_args.length < 4) )
return false;
_outputFile = _args[0];
_destFile = _args[1];
_preferredName = _args[2];
try {
_sequenceNum = Long.parseLong(_args[3]);
} catch (NumberFormatException nfe) {
return false;
}
_serviceType = _args[4];
for (int i = 5; i < _args.length; i++) {
int eq = _args[i].indexOf('=');
if ( (eq <= 0) || (eq >= _args[i].length() - 1) )
continue;
String key = _args[i].substring(0,eq);
String val = _args[i].substring(eq+1);
_options.setProperty(key, val);
}
return true;
}
private void doExecute() {
Destination dest = null;
SigningPrivateKey priv = null;
FileInputStream fis = null;
try {
fis = new FileInputStream(_destFile);
dest = new Destination();
dest.readBytes(fis);
PrivateKey whocares = new PrivateKey();
whocares.readBytes(fis);
priv = new SigningPrivateKey();
priv.readBytes(fis);
} catch (Exception e) {
System.err.println("Destination private keys under " + _destFile + " are corrupt");
e.printStackTrace();
return;
} finally {
if (fis != null) try { fis.close(); } catch (IOException ioe) {}
}
NameReference ref = new NameReference(_context);
ref.setDestination(dest);
ref.setPreferredName(_preferredName);
ref.setSequenceNum(_sequenceNum);
ref.setServiceType(_serviceType);
if (_options != null) {
for (Iterator iter = _options.keySet().iterator(); iter.hasNext(); ) {
String key = (String)iter.next();
String val = _options.getProperty(key);
ref.setOption(key, val);
}
}
try {
ref.sign(priv);
} catch (IllegalStateException ise) {
System.err.println("Error signing the new reference");
ise.printStackTrace();
}
FileOutputStream fos = null;
try {
fos = new FileOutputStream(_outputFile);
ref.write(fos);
} catch (IOException ioe) {
System.err.println("Error writing out the new reference");
ioe.printStackTrace();
} finally {
if (fos != null) try { fos.close(); } catch (IOException ioe) {}
}
System.out.println("Reference created at " + _outputFile);
}
public static void main(String args[]) {
CreateNameReferenceCLI cli = new CreateNameReferenceCLI(args);
cli.execute();
}
}

View File

@ -0,0 +1,198 @@
package net.i2p.myi2p.address;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
import net.i2p.I2PAppContext;
import net.i2p.data.DataHelper;
import net.i2p.data.DataFormatException;
import net.i2p.data.Destination;
import net.i2p.data.Signature;
import net.i2p.data.SigningPrivateKey;
import net.i2p.util.Log;
/**
* Define a verified and immutable reference to a particular I2P destination.
*
*/
public class NameReference {
private I2PAppContext _context;
private Log _log;
private Destination _destination;
private String _preferredName;
private String _serviceType;
private long _sequenceNum;
private Properties _options;
private Signature _signature;
public static final byte[] VERSION_PREFIX = "MyI2P_NameReference_1.0".getBytes();
public NameReference(I2PAppContext context) {
_context = context;
_log = context.logManager().getLog(NameReference.class);
_destination = null;
_preferredName = null;
_serviceType = null;
_sequenceNum = -1;
_options = new Properties();
_signature = null;
}
/** retrieve the destination this reference points at */
public Destination getDestination() { return _destination; }
public void setDestination(Destination dest) { _destination = dest; }
/** retrieve the name this destination would like to be called */
public String getPreferredName() { return _preferredName; }
public void setPreferredName(String name) { _preferredName = name; }
/** retrieve the type of service at this destination (eepsite, ircd, etc) */
public String getServiceType() { return _serviceType; }
public void setServiceType(String type) { _serviceType = type; }
/**
* data point to allow the reference to be updated. The reference with the
* larger sequence number should clobber an older reference.
*
*/
public long getSequenceNum() { return _sequenceNum; }
public void setSequenceNum(long num) { _sequenceNum = num; }
/** Get a list of option names (strings) */
public Set getOptionNames() { return new HashSet(_options.keySet()); }
/** Access any options published in the reference */
public String getOption(String name) { return (String)_options.getProperty(name); }
/**
* Specify a particular value for an option. If the value is null, the
* entry is removed. The name cannot have an '=' or newline, and the
* value cannot have a newline.
*
* @throws IllegalArgumentException if the name or value is illegal
*/
public void setOption(String name, String value) {
if (name == null) throw new IllegalArgumentException("Missing name");
if (name.indexOf('=') != -1)
throw new IllegalArgumentException("Name cannot have an = sign");
if (name.indexOf('\n') != -1)
throw new IllegalArgumentException("Name cannot have a newline");
if (value != null) {
if (value.indexOf('\n') != -1)
throw new IllegalArgumentException("Values do not allow newlines");
_options.setProperty(name, value);
} else {
_options.remove(name);
}
}
/** Access the DSA signature authenticating this reference */
public Signature getSignature() { return _signature; }
public void setSignature(Signature sig) { _signature = sig; }
/** Verify the DSA signature, returning true if it is valid, false otherwise */
public boolean validate() {
try {
byte raw[] = toSignableByteArray();
return _context.dsa().verifySignature(_signature, raw, _destination.getSigningPublicKey());
} catch (IllegalStateException ise) {
return false;
}
}
/**
* Sign the data
*
* @throws IllegalStateException if the data is invalid
*/
public void sign(SigningPrivateKey key) throws IllegalStateException {
byte signable[] = toSignableByteArray();
_signature = _context.dsa().sign(signable, key);
}
/**
* Retrieve the full serialized and signed version of this name reference
*
* @throws IllegalStateException if the signature or other data is invalid
*/
public void write(OutputStream out) throws IllegalStateException, IOException {
if (_signature == null) throw new IllegalStateException("No signature");
byte signable[] = toSignableByteArray();
out.write(signable);
try {
_signature.writeBytes(out);
} catch (DataFormatException dfe) {
throw new IllegalStateException("Signature was corrupt - " + dfe.getMessage());
}
}
/**
* Retrieve the signable (but not including the signature) name reference
*
* @throws IllegalStateException if the data is invalid
*/
private byte[] toSignableByteArray() throws IllegalStateException {
if (_sequenceNum < 0) throw new IllegalStateException("Sequence number is invalid");
if (_preferredName == null) throw new IllegalStateException("Preferred name is invalid");
if (_serviceType == null) throw new IllegalStateException("Service type is invalid");
if (_options == null) throw new IllegalStateException("Options not constructed");
if (_destination == null) throw new IllegalStateException("Destination not specified");
ByteArrayOutputStream baos = new ByteArrayOutputStream(512);
try {
baos.write(VERSION_PREFIX);
_destination.writeBytes(baos);
DataHelper.writeLong(baos, 4, _sequenceNum);
DataHelper.writeString(baos, _preferredName);
DataHelper.writeString(baos, _serviceType);
DataHelper.writeProperties(baos, _options); // sorts alphabetically
return baos.toByteArray();
} catch (DataFormatException dfe) {
if (_log.shouldLog(Log.ERROR))
_log.error("Corrupted trying to write entry", dfe);
return null;
} catch (IOException ioe) {
if (_log.shouldLog(Log.ERROR))
_log.error("IOError writing to memory?", ioe);
return null;
}
}
/**
* Read a full signed reference from the given stream
*
* @throws DataFormatException if the reference is corrupt
* @throws IOException if there is an error reading the stream
*/
public void read(InputStream in) throws DataFormatException, IOException {
byte versionBuf[] = new byte[VERSION_PREFIX.length];
int len = DataHelper.read(in, versionBuf);
if (len != versionBuf.length)
throw new IllegalArgumentException("Version length too short ("+ len + ")");
if (!DataHelper.eq(versionBuf, VERSION_PREFIX))
throw new IllegalArgumentException("Version mismatch (" + new String(versionBuf) + ")");
Destination dest = new Destination();
dest.readBytes(in);
long seq = DataHelper.readLong(in, 4);
String name = DataHelper.readString(in);
String type = DataHelper.readString(in);
Properties opts = DataHelper.readProperties(in);
Signature sig = new Signature();
sig.readBytes(in);
// ok, nothing b0rked
_destination = dest;
_sequenceNum = seq;
_preferredName = name;
_serviceType = type;
_options = opts;
_signature = sig;
}
}

View File

@ -0,0 +1,66 @@
package net.i2p.myi2p.address;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
import net.i2p.I2PAppContext;
import net.i2p.data.DataHelper;
import net.i2p.data.DataFormatException;
/**
* Contains the preferences for subscribing to a particular peer's address
* book.
*/
public class Subscription {
private I2PAppContext _context;
private int _queryFrequencyMinutes;
private long _lastQueryAttempt;
private long _lastQuerySuccess;
/** no subscription more often than 4 times a day */
public static final int MIN_FREQUENCY = 6*60*60*1000;
public Subscription(I2PAppContext context) {
_context = context;
}
/** how often do we want to query the peer (in minutes) */
public int getQueryFrequencyMinutes() { return _queryFrequencyMinutes; }
public void setQueryFrequencyMinutes(int freq) { _queryFrequencyMinutes = freq; }
/** when did we last successfully query the peer */
public long getLastQuerySuccess() { return _lastQuerySuccess; }
public void setLastQuerySuccess(long when) { _lastQuerySuccess = when; }
/** when did we last attempt to query the peer */
public long getLastQueryAttempt() { return _lastQueryAttempt; }
public void setLastQueryAttempt(long when) { _lastQueryAttempt = when; }
/** load the data from the stream */
public void read(InputStream in) throws IOException {
try {
int freq = (int)DataHelper.readLong(in, 2);
Date attempt = DataHelper.readDate(in);
Date success = DataHelper.readDate(in);
_queryFrequencyMinutes = (freq < MIN_FREQUENCY ? MIN_FREQUENCY : freq);
_lastQueryAttempt = (attempt != null ? attempt.getTime() : -1);
_lastQuerySuccess = (success != null ? success.getTime() : -1);
} catch (DataFormatException dfe) {
throw new IOException("Corrupt subscription: " + dfe.getMessage());
}
}
/** persist the data to the stream */
public void write(OutputStream out) throws IOException {
try {
DataHelper.writeLong(out, 2, _queryFrequencyMinutes);
DataHelper.writeDate(out, new Date(_lastQueryAttempt));
DataHelper.writeDate(out, new Date(_lastQuerySuccess));
} catch (DataFormatException dfe) {
throw new IOException("Corrupt subscription: " + dfe.getMessage());
}
}
}

3
apps/myi2p/myi2p.config Normal file
View File

@ -0,0 +1,3 @@
keyFile=myi2p.keys
service.0.classname=net.i2p.myi2p.address.AddressBookService
service.0.type=AddressBook

View File

@ -0,0 +1,180 @@
/*******************************************************
** Proxy Auto Configure Script with I2P Host Detection.
**
** Author: Cervantes
** License: Public Domain
** Date: 11 May 2004
**
** Revised: 07 Sep 2004
** Changes:
** Proxy recursion disabled by default (strict)
** Password Authentication for session commands
** Support for http://path?i2paddresshelper=BASE64
** Support for http://i2p/BASE64/path syntax
** Revised: 17 May 2004
** Changes:
** Ability for the user to control the proxy
** status on a per browser-session basis.
********************************************************/
/* C O N F I G U R A T I O N
*/
/* Replace normal with "PROXY yourproxy:port" if you run
** behind a Proxy Server by default.
*/
var normal = "DIRECT";
/* Specify the I2P proxy connection details here.
*/
var i2pProxy = "PROXY 127.0.0.1:4444";
/* Set the default status of proxy detection here:
**
**
** [1] "auto" => Proxy will be used automatically if
** '-> an ".i2p" url is detected.
** '-> You will only be anonymous for ".i2p" domains.
**
** [2] "on" => Proxy is enabled all the time. (safest)
** '-> NB. Normal web available only via
** '-> i2p outproxies.
** '-> You can be fairly confident of anonymity.
**
** [3] "off" => Completely Bypass the proxy and therefore i2p.
** '-> no i2p sites will be accessible...
** '-> ...your browsing habits can potentially
** '-> be traced back to you!
**
*/
var proxyStatus = "auto";
/* By setting statusKeyword to "all" you can set these options at runtime
** for the duration of the browser session by entering special commands
** into your browser address bar.
**
** Due to limitations in the way proxy scripting works, a malicious site
** could change your status mode by linking to command keywords...
** eg. <img src="i2p.off" ...
** This is why the default setting for statusKeyword is "limited", which only
** allows you to set the proxy status to "on". See also keywordAuthPassword.
**
** [1] "all" => All proxy status urls are available.
** '-> i2p.on, i2p.off, i2p.auto (respective to proxyStatus settings)
** '-> WARNING: Setting "all" is a big risk to your anonymity!
** '-> In this mode it is highly recommended you set an AuthPassword too!
**
** [2] "limited" => Only i2p.on is available..
** '-> This setting lasts for the duration of the browser setting.
** '-> You have to close your browser in order to revert to
** '-> your default proxyStatus configuration.
**
** [3] "off" => No command urls available.
** '-> The status mode can only be altered by editing the above
** '-> proxyStatus setting. (safest)
**
*/
var statusKeyword = "all";
/*
** By default if proxyStatus is set to "auto" the config script
** will fall back to your normal connection settings if the
** i2p proxy is offline. This is handy for browsing your locally
** hosted eepsites when your router is not running (for instance).
** However this can mean that requests to external eepsites could
** be forwarded to the outweb and potentially compromise some of
** your rights to anonymity.
** Setting "true" here enables strict mode where all requests to ".i2p"
** sites will be rejected if the i2p proxy is offline. (safest)
*/
var strict = true;
/*
** By setting an authentication password, all activated session keywords
** will require the addition of a password to prevent malicious sites from
** hijacking your proxy settings. ie. <img src="i2p.off" ...
** Users should append whatever they set here to any command keywords
** they use.
** eg. i2p.on.passw0rd
** If left blank, authentication is ignored - it is recommended that
** you use "limited" statusKeyword mode if you choose not to require a password.
** If you do require this feature then you should replace the default "passw0rd" with
** one of your own (recommend at least 8 letters with a case-sensitive alpha-numeric
** mix of characters).
**
*/
var keywordAuthPassword = "passw0rd";
/* E N D C O N F I G U R A T I O N
*/
/* Allows the proxy to fallback on "normal" settings
** '-> if the i2p router is offline.
*/
if (strict == false) {
i2pProxy = i2pProxy + "; " + normal;
}
/*Check for User Authentication Password.
*/
if (keywordAuthPassword != "") {
keywordAuthPassword = "." + keywordAuthPassword;
}
/* This function gets called every time a url is submitted
*/
function FindProxyForURL(url, host) {
/* checks for a special command url that
** '-> changes the status of the proxy script.
*/
if (statusKeyword != "off") {
if (host == "i2p.off" + keywordAuthPassword && statusKeyword == "all") {
/*Proxy is bypassed - outweb available only
*/
proxyStatus = "off";
} else if (host == "i2p.auto" + keywordAuthPassword && statusKeyword == "all") {
/* Proxy is used only for .i2p hosts otherwise
** '-> browse as normal.
*/
proxyStatus = "auto";
} else if (host == "i2p.on" + keywordAuthPassword && (statusKeyword == "limited" ||
statusKeyword == "all" )) {
/* Only I2P traffic is accepted.
*/
proxyStatus = "on";
}
}
if (proxyStatus == "off") {
/* Proxy is completely bypassed.
*/
return normal;
} else if (proxyStatus == "on") {
/* All requests are forward to the proxy.
*/
return i2pProxy;
}
host = host.toLowerCase();
/* check tld for "i2p" or oOo's new "i2paddresshelper" syntax - if found then redirect
** '-> request to the i2p proxy
*/
if (url.match(/^http:\/\/i2p\/[a-zA-Z0-9\-\~]{516}|i2paddresshelper=/i) ||
shExpMatch(host, "*.i2p")) { // seems more reliable than:
return i2pProxy; // dnsDomainIs(host, ".i2p") ||
} else { // i2pRegex.test(host)
return normal;
}
}

View File

@ -4,6 +4,7 @@
<target name="build" depends="builddep, jar" />
<target name="builddep">
<ant dir="../../../router/java/" target="build" />
<ant dir="../../systray/java/" target="build" />
<!-- router will build core -->
</target>
<target name="prepare">
@ -15,8 +16,16 @@
<javac
srcdir="./src"
debug="true" deprecation="on" source="1.3" target="1.3"
destdir="./build/obj"
classpath="../../../core/java/build/i2p.jar:../../../router/java/build/router.jar:../../jetty/jettylib/org.mortbay.jetty-jdk1.2.jar" />
destdir="./build/obj">
<classpath>
<pathelement location="../../../core/java/build/i2p.jar" />
<pathelement location="../../../router/java/build/router.jar" />
<pathelement location="../../jetty/jettylib/org.mortbay.jetty-jdk1.2.jar" />
<pathelement location="../../systray/java/build/systray.jar" />
<pathelement location="../../systray/java/lib/systray4j.jar" />
<pathelement location="../../../installer/lib/wrapper/win32/wrapper.jar" /> <!-- we dont care if we're not on win32 -->
</classpath>
</javac>
</target>
<target name="jar" depends="compile">
<jar destfile="./build/routerconsole.jar" basedir="./build/obj" includes="**/*.class">
@ -44,6 +53,8 @@
<pathelement location="../../jetty/jettylib/jasper-runtime.jar" />
<pathelement location="../../jetty/jettylib/javax.servlet.jar" />
<pathelement location="../../jetty/jettylib/ant.jar" />
<pathelement location="../../systray/java/build/obj" />
<pathelement location="../../../installer/lib/wrapper/win32/wrapper.jar" /> <!-- we dont care if we're not on win32 -->
<pathelement location="build/routerconsole.jar" />
</classpath>
<arg value="-d" />
@ -77,7 +88,7 @@
<mkdir dir="./build" />
<mkdir dir="./build/javadoc" />
<javadoc
sourcepath="./src:../../../core/java/src:../../router/java/src" destdir="./build/javadoc"
sourcepath="./src:../../../core/java/src:../../../router/java/src:../../systray/java/src" destdir="./build/javadoc"
packagenames="*"
use="true"
splitindex="true"
@ -88,10 +99,12 @@
</target>
<target name="cleandep" depends="clean">
<!-- router will clean core -->
<ant dir="../../../router/java/" target="distclean" />
<ant dir="../../../router/java/" target="cleandep" />
<ant dir="../../systray/java/" target="cleandep" />
</target>
<target name="distclean" depends="clean">
<!-- router will clean core -->
<ant dir="../../../router/java/" target="distclean" />
<ant dir="../../systray/java/" target="distclean" />
</target>
</project>

View File

@ -145,11 +145,16 @@ public class ConfigNetHandler extends FormHandler {
}
int fetched = 0;
int errors = 0;
for (Iterator iter = urls.iterator(); iter.hasNext(); ) {
fetchSeed(seedURL, (String)iter.next());
fetched++;
try {
fetchSeed(seedURL, (String)iter.next());
fetched++;
} catch (Exception e) {
errors++;
}
}
addFormNotice("Reseeded with " + fetched + " peers");
addFormNotice("Reseeded with " + fetched + " peers (and " + errors + " failures)");
} catch (Throwable t) {
_context.logManager().getLog(ConfigNetHandler.class).error("Error reseeding", t);
addFormError("Error reseeding (RESEED_EXCEPTION)");
@ -157,7 +162,7 @@ public class ConfigNetHandler extends FormHandler {
}
private void fetchSeed(String seedURL, String peer) throws Exception {
URL url = new URL(seedURL + "/routerInfo-" + peer + ".dat");
URL url = new URL(seedURL + (seedURL.endsWith("/") ? "" : "/") + "routerInfo-" + peer + ".dat");
byte data[] = readURL(url);
writeSeed(peer, data);
@ -222,9 +227,10 @@ public class ConfigNetHandler extends FormHandler {
updateRates();
if (_timeSyncEnabled) {
// Time sync enable, means NOT disabled
_context.router().setConfigSetting(Timestamper.PROP_DISABLED, "false");
} else {
_context.router().setConfigSetting(Timestamper.PROP_DISABLED, "false");
_context.router().setConfigSetting(Timestamper.PROP_DISABLED, "true");
}
boolean saved = _context.router().saveConfig();

View File

@ -51,8 +51,8 @@ public class ConfigNetHelper {
}
public String getEnableTimeSyncChecked() {
String enabled = _context.getProperty(Timestamper.PROP_DISABLED, "true");
if ( (enabled == null) || (!"true".equalsIgnoreCase(enabled)) )
String disabled = _context.getProperty(Timestamper.PROP_DISABLED, "false");
if ( (disabled != null) && ("true".equalsIgnoreCase(disabled)) )
return "";
else
return " checked ";

View File

@ -0,0 +1,110 @@
package net.i2p.router.web;
import java.io.IOException;
import net.i2p.router.ClientTunnelSettings;
import net.i2p.router.Router;
import net.i2p.apps.systray.SysTray;
import org.tanukisoftware.wrapper.WrapperManager;
/**
* Handler to deal with form submissions from the service config form and act
* upon the values.
*
*/
public class ConfigServiceHandler extends FormHandler {
public void ConfigNetHandler() {}
private class UpdateWrapperManagerTask implements Runnable {
private int _exitCode;
public UpdateWrapperManagerTask(int exitCode) {
_exitCode = exitCode;
}
public void run() {
try {
WrapperManager.signalStopped(_exitCode);
} catch (Throwable t) {
t.printStackTrace();
}
}
}
protected void processForm() {
if (_action == null) return;
if ("Shutdown gracefully".equals(_action)) {
_context.router().addShutdownTask(new UpdateWrapperManagerTask(Router.EXIT_GRACEFUL));
_context.router().shutdownGracefully();
addFormNotice("Graceful shutdown initiated");
} else if ("Shutdown immediately".equals(_action)) {
_context.router().addShutdownTask(new UpdateWrapperManagerTask(Router.EXIT_HARD));
_context.router().shutdown(Router.EXIT_HARD);
addFormNotice("Shutdown immediately! boom bye bye bad bwoy");
} else if ("Cancel graceful shutdown".equals(_action)) {
_context.router().cancelGracefulShutdown();
addFormNotice("Graceful shutdown cancelled");
} else if ("Graceful restart".equals(_action)) {
_context.router().addShutdownTask(new UpdateWrapperManagerTask(Router.EXIT_GRACEFUL_RESTART));
_context.router().shutdownGracefully(Router.EXIT_GRACEFUL_RESTART);
addFormNotice("Graceful restart requested");
} else if ("Hard restart".equals(_action)) {
_context.router().addShutdownTask(new UpdateWrapperManagerTask(Router.EXIT_HARD_RESTART));
_context.router().shutdown(Router.EXIT_HARD_RESTART);
addFormNotice("Hard restart requested");
} else if ("Run I2P on startup".equals(_action)) {
installService();
} else if ("Don't run I2P on startup".equals(_action)) {
uninstallService();
} else if ("Dump threads".equals(_action)) {
try {
WrapperManager.requestThreadDump();
} catch (Throwable t) {
addFormError("Warning: unable to contact the service manager - " + t.getMessage());
}
addFormNotice("Threads dumped to wrapper.log");
} else if ("Show systray icon".equals(_action)) {
try {
SysTray tray = SysTray.getInstance();
if (tray != null) {
tray.show();
addFormNotice("Systray enabled");
} else {
addFormNotice("Systray not supported on this platform");
}
} catch (Throwable t) {
addFormError("Warning: unable to contact the systray manager - " + t.getMessage());
}
} else if ("Hide systray icon".equals(_action)) {
try {
SysTray tray = SysTray.getInstance();
if (tray != null) {
tray.hide();
addFormNotice("Systray disabled");
} else {
addFormNotice("Systray not supported on this platform");
}
} catch (Throwable t) {
addFormError("Warning: unable to contact the systray manager - " + t.getMessage());
}
} else {
addFormNotice("Blah blah blah. whatever. I'm not going to " + _action);
}
}
private void installService() {
try {
Runtime.getRuntime().exec("install_i2p_service_winnt.bat");
addFormNotice("Service installed");
} catch (IOException ioe) {
addFormError("Warning: unable to install the service - " + ioe.getMessage());
}
}
private void uninstallService() {
try {
Runtime.getRuntime().exec("uninstall_i2p_service_winnt.bat");
addFormNotice("Service removed");
} catch (IOException ioe) {
addFormError("Warning: unable to remove the service - " + ioe.getMessage());
}
}
}

View File

@ -0,0 +1,56 @@
package net.i2p.router.web;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
import net.i2p.router.RouterContext;
import net.i2p.util.FileUtil;
public class ContentHelper {
private String _page;
private int _maxLines;
private RouterContext _context;
/**
* Configure this bean to query a particular router context
*
* @param contextId begging few characters of the routerHash, or null to pick
* the first one we come across.
*/
public void setContextId(String contextId) {
try {
_context = ContextHelper.getContext(contextId);
} catch (Throwable t) {
t.printStackTrace();
}
}
public ContentHelper() {}
public void setPage(String page) { _page = page; }
public void setMaxLines(String lines) {
if (lines != null) {
try {
_maxLines = Integer.parseInt(lines);
} catch (NumberFormatException nfe) {
_maxLines = -1;
}
} else {
_maxLines = -1;
}
}
public String getContent() {
String str = FileUtil.readTextFile(_page, _maxLines);
if (str == null)
return "";
else
return str;
}
public String getTextContent() {
String str = FileUtil.readTextFile(_page, _maxLines);
if (str == null)
return "";
else
return "<pre>" + str + "</pre>";
}
}

View File

@ -19,14 +19,20 @@ import net.i2p.router.ClientTunnelSettings;
*/
public class FormHandler {
protected RouterContext _context;
private String _nonce;
protected String _action;
private List _errors;
private List _notices;
private boolean _processed;
private boolean _valid;
public FormHandler() {
_errors = new ArrayList();
_notices = new ArrayList();
_action = null;
_processed = false;
_valid = true;
_nonce = null;
}
/**
@ -43,6 +49,9 @@ public class FormHandler {
}
}
public void setNonce(String val) { _nonce = val; }
public void setAction(String val) { _action = val; }
/**
* Override this to perform the final processing (in turn, adding formNotice
* and formError messages, etc)
@ -72,6 +81,7 @@ public class FormHandler {
*
*/
public String getErrors() {
validate();
return render(_errors);
}
@ -81,12 +91,43 @@ public class FormHandler {
*
*/
public String getNotices() {
validate();
return render(_notices);
}
/**
* Make sure the nonce was set correctly, otherwise someone could just
* create a link like /confignet.jsp?hostname=localhost and break the
* user's node (or worse).
*
*/
private void validate() {
if (_processed) return;
_valid = true;
if (_action == null) {
// not a form submit
_valid = false;
return;
}
if (_nonce == null) {
addFormError("You trying to mess with me? Huh? Are you?");
_valid = false;
return;
}
String nonce = System.getProperty(getClass().getName() + ".nonce");
String noncePrev = System.getProperty(getClass().getName() + ".noncePrev");
if ( ( (nonce == null) || (!_nonce.equals(nonce)) ) &&
( (noncePrev == null) || (!_nonce.equals(noncePrev)) ) ) {
addFormError("Invalid nonce, are you being spoofed?");
_valid = false;
}
}
private String render(List source) {
if (!_processed) {
processForm();
if (_valid)
processForm();
_processed = true;
}
if (source.size() <= 0) {

View File

@ -5,6 +5,7 @@ import java.io.IOException;
import java.util.List;
import net.i2p.router.RouterContext;
import net.i2p.util.FileUtil;
public class LogsHelper {
private RouterContext _context;
@ -27,7 +28,31 @@ public class LogsHelper {
public String getLogs() {
List msgs = _context.logManager().getBuffer().getMostRecentMessages();
StringBuffer buf = new StringBuffer(16*1024);
buf.append("<h2>Most recent console messages:</h2><ul>");
buf.append("<ul>");
buf.append("<code>\n");
for (int i = msgs.size(); i > 0; i--) {
String msg = (String)msgs.get(i - 1);
buf.append("<li>");
buf.append(msg);
buf.append("</li>\n");
}
buf.append("</code></ul>\n");
return buf.toString();
}
public String getServiceLogs() {
String str = FileUtil.readTextFile("wrapper.log", 500);
if (str == null)
return "";
else
return "<pre>" + str + "</pre>";
}
public String getConnectionLogs() {
List msgs = _context.commSystem().getMostRecentErrorMessages();
StringBuffer buf = new StringBuffer(16*1024);
buf.append("<ul>");
buf.append("<code>\n");
for (int i = msgs.size(); i > 0; i--) {
String msg = (String)msgs.get(i - 1);

View File

@ -2,11 +2,14 @@ package net.i2p.router.web;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import net.i2p.router.RouterContext;
public class NetDbHelper {
private RouterContext _context;
private Writer _out;
/**
* Configure this bean to query a particular router context
*
@ -23,13 +26,21 @@ public class NetDbHelper {
public NetDbHelper() {}
public void setWriter(Writer writer) { _out = writer; }
public String getNetDbSummary() {
ByteArrayOutputStream baos = new ByteArrayOutputStream(32*1024);
try {
_context.netDb().renderStatusHTML(baos);
if (_out != null) {
_context.netDb().renderStatusHTML(_out);
return "";
} else {
ByteArrayOutputStream baos = new ByteArrayOutputStream(32*1024);
_context.netDb().renderStatusHTML(new OutputStreamWriter(baos));
return new String(baos.toByteArray());
}
} catch (IOException ioe) {
ioe.printStackTrace();
return "";
}
return new String(baos.toByteArray());
}
}

View File

@ -0,0 +1,34 @@
package net.i2p.router.web;
import net.i2p.data.DataHelper;
import net.i2p.router.RouterContext;
/**
* Simple helper to query the appropriate router for data necessary to render
* any emergency notices
*/
public class NoticeHelper {
private RouterContext _context;
/**
* Configure this bean to query a particular router context
*
* @param contextId begging few characters of the routerHash, or null to pick
* the first one we come across.
*/
public void setContextId(String contextId) {
try {
_context = ContextHelper.getContext(contextId);
} catch (Throwable t) {
t.printStackTrace();
}
}
public String getSystemNotice() {
if (_context.router().gracefulShutdownInProgress()) {
return "Graceful shutdown in "
+ DataHelper.formatDuration(_context.router().getShutdownTimeRemaining());
} else {
return "";
}
}
}

View File

@ -2,6 +2,8 @@ package net.i2p.router.web;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.List;
import net.i2p.router.RouterContext;
@ -9,6 +11,7 @@ import net.i2p.router.admin.StatsGenerator;
public class OldConsoleHelper {
private RouterContext _context;
private Writer _out;
/**
* Configure this bean to query a particular router context
*
@ -25,11 +28,20 @@ public class OldConsoleHelper {
public OldConsoleHelper() {}
public void setWriter(Writer writer) {
_out = writer;
}
public String getConsole() {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream(128*1024);
_context.router().renderStatusHTML(baos);
return baos.toString();
if (_out != null) {
_context.router().renderStatusHTML(_out);
return "";
} else {
ByteArrayOutputStream baos = new ByteArrayOutputStream(128*1024);
_context.router().renderStatusHTML(new OutputStreamWriter(baos));
return baos.toString();
}
} catch (IOException ioe) {
return "<b>Error rending the console</b>";
}
@ -38,9 +50,14 @@ public class OldConsoleHelper {
public String getStats() {
StatsGenerator gen = new StatsGenerator(_context);
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream(32*1024);
gen.generateStatsPage(baos);
return baos.toString();
if (_out != null) {
gen.generateStatsPage(_out);
return "";
} else {
ByteArrayOutputStream baos = new ByteArrayOutputStream(32*1024);
gen.generateStatsPage(new OutputStreamWriter(baos));
return baos.toString();
}
} catch (IOException ioe) {
return "<b>Error rending the console</b>";
}

View File

@ -2,6 +2,7 @@ package net.i2p.router.web;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import net.i2p.router.RouterContext;
@ -26,7 +27,7 @@ public class ProfilesHelper {
public String getProfileSummary() {
ByteArrayOutputStream baos = new ByteArrayOutputStream(16*1024);
try {
_context.profileOrganizer().renderStatusHTML(baos);
_context.profileOrganizer().renderStatusHTML(new OutputStreamWriter(baos));
} catch (IOException ioe) {
ioe.printStackTrace();
}
@ -36,7 +37,7 @@ public class ProfilesHelper {
public String getShitlistSummary() {
ByteArrayOutputStream baos = new ByteArrayOutputStream(4*1024);
try {
_context.shitlist().renderStatusHTML(baos);
_context.shitlist().renderStatusHTML(new OutputStreamWriter(baos));
} catch (IOException ioe) {
ioe.printStackTrace();
}

View File

@ -1,12 +1,16 @@
package net.i2p.router.web;
import java.io.File;
import java.io.IOException;
import java.util.List;
import net.i2p.router.RouterContext;
import net.i2p.apps.systray.SysTray;
import net.i2p.util.FileUtil;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.servlet.WebApplicationContext;
import org.mortbay.http.DigestAuthenticator;
import org.mortbay.http.handler.SecurityHandler;
import org.mortbay.http.HashUserRealm;
import org.mortbay.http.HttpRequest;
@ -19,6 +23,10 @@ public class RouterConsoleRunner {
private String _listenHost = "127.0.0.1";
private String _webAppsDir = "./webapps/";
static {
System.setProperty("org.mortbay.http.Version.paranoid", "true");
}
public RouterConsoleRunner(String args[]) {
if (args.length == 3) {
_listenPort = args[0].trim();
@ -33,6 +41,14 @@ public class RouterConsoleRunner {
}
public void startConsole() {
File workDir = new File("work");
boolean workDirRemoved = FileUtil.rmdir(workDir, false);
if (!workDirRemoved)
System.err.println("ERROR: Unable to remove Jetty temporary work directory");
boolean workDirCreated = workDir.mkdirs();
if (!workDirCreated)
System.err.println("ERROR: Unable to create Jetty temporary work directory");
_server = new Server();
WebApplicationContext contexts[] = null;
try {
@ -51,6 +67,11 @@ public class RouterConsoleRunner {
} catch (MultiException me) {
me.printStackTrace();
}
try {
SysTray tray = SysTray.getInstance();
} catch (Throwable t) {
t.printStackTrace();
}
}
private void initialize(WebApplicationContext context) {
@ -60,6 +81,7 @@ public class RouterConsoleRunner {
realm.put("admin", password);
realm.addUserToRole("admin", "routerAdmin");
context.setRealm(realm);
context.setAuthenticator(new DigestAuthenticator());
context.addHandler(0, new SecurityHandler());
SecurityConstraint constraint = new SecurityConstraint("admin", "routerAdmin");
constraint.setAuthenticate(true);

View File

@ -0,0 +1,65 @@
/*
* I2P - An anonymous, secure, and fully-distributed communication network.
*
* ServiceManager.java
* 2004 The I2P Project
* http://www.i2p.net
* This code is public domain.
*/
package net.i2p.router.web;
//import java.io.InputStream;
import net.i2p.util.ShellCommand;
/**
* Handles installation and uninstallation of I2P as a service.
*
* @author hypercubus
*/
public class ServiceManager {
private static final boolean IS_WINDOWS = System.getProperty("os.name").startsWith("Windows") ? true : false;
private ShellCommand _shellCommand = new ShellCommand();
/**
* Invokes the service wrapper installation script via a shell process.
*
* @return <code>null</code> if the installation was successful, otherwise
* a <code>String</code> containing the shell output including error
* messages is returned.
*/
public String installService() {
return exec("install_i2p_service_" + (IS_WINDOWS ? "winnt.bat" : "unix"));
}
/**
* Invokes the service wrapper uninstallation script via a shell process.
*
* @return <code>null</code> if the uninstallation was successful, otherwise
* a <code>String</code> containing the shell output including error
* messages is returned.
*/
public String uninstallService() {
return exec("uninstall_i2p_service_" + (IS_WINDOWS ? "winnt.bat" : "unix"));
}
private String exec(String command) {
// InputStream StdoutStream = _shellCommand.getInputStream();
// InputStream StderrStream = _shellCommand.getErrorStream();
StringBuffer result = null;
if (_shellCommand.executeAndWait(command))
return null;
else
if (result.toString().equals(""))
return null;
else
return result.toString();
}
}

View File

@ -2,6 +2,7 @@ package net.i2p.router.web;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.text.DecimalFormat;
import net.i2p.data.DataHelper;
@ -49,7 +50,7 @@ public class SummaryHelper {
*
*/
public String getVersion() {
return RouterVersion.VERSION;
return RouterVersion.VERSION + "-" + RouterVersion.BUILD;
}
/**
* Retrieve a pretty printed uptime count (ala 4d or 7h or 39m)
@ -78,10 +79,20 @@ public class SummaryHelper {
}
/**
* How many active peers the router has.
* How many peers we are talking to now
*
*/
public int getActivePeers() {
if (_context == null)
return 0;
else
return _context.commSystem().countActivePeers();
}
/**
* How many active identities have we spoken with recently
*
*/
public int getActiveProfiles() {
if (_context == null)
return 0;
else
@ -287,26 +298,27 @@ public class SummaryHelper {
}
private static String getTransferred(long bytes) {
double val = bytes;
int scale = 0;
if (bytes > 1024*1024*1024) {
// gigs transferred
scale = 3;
bytes /= (1024*1024*1024);
val /= (double)(1024*1024*1024);
} else if (bytes > 1024*1024) {
// megs transferred
scale = 2;
bytes /= (1024*1024);
val /= (double)(1024*1024);
} else if (bytes > 1024) {
// kbytes transferred
scale = 1;
bytes /= 1024;
val /= (double)1024;
} else {
scale = 0;
}
DecimalFormat fmt = new DecimalFormat("##0.00");
String str = fmt.format(bytes);
String str = fmt.format(val);
switch (scale) {
case 1: return str + "KB";
case 2: return str + "MB";
@ -323,7 +335,9 @@ public class SummaryHelper {
public String getDestinations() {
ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
try {
_context.clientManager().renderStatusHTML(baos);
OutputStreamWriter osw = new OutputStreamWriter(baos);
_context.clientManager().renderStatusHTML(osw);
osw.flush();
return new String(baos.toByteArray());
} catch (IOException ioe) {
_context.logManager().getLog(SummaryHelper.class).error("Error rendering client info", ioe);
@ -386,8 +400,7 @@ public class SummaryHelper {
if (_context == null)
return "0ms";
Rate delayRate = _context.statManager().getRate("transport.sendProcessingTime").getRate(60*1000);
return ((int)delayRate.getAverageValue()) + "ms";
return _context.throttle().getMessageDelay() + "ms";
}
/**
@ -399,7 +412,6 @@ public class SummaryHelper {
if (_context == null)
return "0ms";
Rate lagRate = _context.statManager().getRate("tunnel.testSuccessTime").getRate(10*60*1000);
return ((int)lagRate.getAverageValue()) + "ms";
return _context.throttle().getTunnelLag() + "ms";
}
}

Some files were not shown because too many files have changed in this diff Show More