Compare commits

...

237 Commits

Author SHA1 Message Date
806d598a04 _context/getContext()
(missed one)
2004-07-15 05:23:18 +00:00
e737e5c950 * work around the disagreement between different versions of sun's compiler and JVM:
Some of them think that its ok for an inner class of a subclass to access protected data of the
outer class's parent when the parent is in another package.
Others do not.
Kaffe doesn't care (but thats because Kaffe doesn't do much for verification ;)
The JLS is aparently confusing, but it doesnt matter whether its a code or javac bug, we've got to change the code.
The simplest change would be to just make the JobImpl._context public, but I loath public data, so we make it private and add an accessor
(and change dozens of files)
whee
2004-07-15 05:12:37 +00:00
bbcde2f52b 0.3.2.2 (a lil installation testing and then i'll push) 2004-07-15 01:08:54 +00:00
f6ef77429c some boundary cases for the queue pumper's wait time 2004-07-15 01:04:13 +00:00
44491c1514 added nickster2.i2p and irc.nickster.i2p (pointing at iip) 2004-07-14 22:12:43 +00:00
71a6cf4ee6 * adjust the algorithm to deal with IO bound requests:
if more tokens become available while the first pending request is still blocked on
  read/write (aka after allocation and before next .waitForAllocation()), give the tokens
  to the next request
* refactor the satisfy{In,Out}boundRequests methods into smaller logical units
2004-07-14 21:07:57 +00:00
744ce6966f add a new throttle (and stats) based on send processing time
high send processing time and low job lag means the latency is coming from outside the jobQueue - aka bandwidth throttling
2004-07-14 20:01:40 +00:00
d25cec02c2 clean up sorting for peer reliability
increase penalties for tunnel rejection, and keep track of the 10 minute rate as well as 1 and 60
2004-07-14 19:56:38 +00:00
f02bf37fd3 stats and stats and stats
track the total allocated bytes correctly (even if we're throttled)
2004-07-14 19:54:04 +00:00
304b9d41d7 on kaffe i've periodically seen some hangs in the jobqueue, so lets try being a bit more conservative with the synchroniation, and include some debugging output in the router console to help track it down (if this doesnt fix it) 2004-07-13 20:19:28 +00:00
2d6af89f60 safer operation (for use in the sim where some things aren't always availble) 2004-07-13 20:17:15 +00:00
d6425973e2 include an objectId flag for use in the logging 2004-07-13 20:16:05 +00:00
d5ad56c4de use smaller writes to make it look more normal 2004-07-13 20:14:18 +00:00
4f1f2cc99e since people are using small buckets, the 10s replenish frequency is a really really bad idea (so default to 1s) 2004-07-13 05:49:16 +00:00
da439dd127 sanity checking for a kooky race condition 2004-07-12 21:33:32 +00:00
1375d01bdf new bandwidth allocation policy and usage to include support for partial allocations (and in turn, partial write(...)) while still keeping the FIFO ordering
this will give a much smoother traffic pattern, as instead of waiting 6 seconds to write a 32KB message under a 6KB rate, it'll write 6KB for each of the first 5 seconds, and 2KB the next
this also allows people to have small buckets (but again, bucket sizes smaller than the rate just don't make sense)
2004-07-12 21:09:05 +00:00
7b9db07f13 target=1.3 and source=1.3, not target=1.1 and source=1.3
(this is what caused the runtime errors on sun jvms but not on kaffe)
((aka i slacked and didn't test sufficiently.  off with my head))
this now builds and runs fine in sun 1.3-1.5 jvms, as well as kaffe
2004-07-12 16:39:22 +00:00
f2f26136c1 Minior cleanups -- removed commented out debugging code, wrote better
comments.
(ugha)
2004-07-12 05:12:22 +00:00
0f60ac5acf 0.3.2.1 (backwards compatible blah blah blah) 2004-07-11 18:57:01 +00:00
c28f19fe8a less painful and/or redundant penalties for failures 2004-07-11 18:50:23 +00:00
mpc
09a6dbc755 FreeBSD port 2004-07-11 13:22:37 +00:00
3bc0e0fc8a added source and target declarations for the javac commands so we can build with the 1.5^W5.0 JDK
(also added deprecation, since, well, we can :)
2004-07-11 04:16:59 +00:00
eb0e187a54 throttle tunnel participation based on whether we've had to throttle our network connection > some number of times in the last 10-20 minutes (rather than a simple "are we throttled *right now*?") 2004-07-10 22:28:34 +00:00
a788d30f34 added support for new 'clientoptions' command which alters the properties passed when creating subsequent I2CP connections
e.g.: -e "clientoptions tunnels.depthInbound=0" -e "httpclient 6666"
this updates so many files because they all need a reference to an I2PTunnel object on construction so they query tunnel.getClientOptions() instead of System.getProperties
2004-07-10 16:59:49 +00:00
591dfc961e give the reliability more positive influence so it doesn't go negative so easily
update the peerProfile's CLI to make the resulting stats easier to read
2004-07-10 04:15:51 +00:00
809e12b034 logging 2004-07-10 04:13:42 +00:00
1669d174e1 use mihi's template engine to set a random timestamper password so people dont need to think about that stuff
don't use the dyndns anymore for seeding (use dev.i2p.net/i2pdb)
2004-07-10 02:36:27 +00:00
3cfd28de43 add a new unit test for repeated fast reconnections 2004-07-10 01:58:05 +00:00
4888207eca if a client reconnects, we always want to get a new leaseSet ASAP (even if the pool hadn't been marked as stopped yet)
logging
2004-07-10 01:46:57 +00:00
294cb96107 if the job's startAfter is changed, tell the jobQueue to go through the timed jobs again in case the new time changes the scheduling 2004-07-10 01:44:27 +00:00
b648fa2b70 send the stats page out in chunks (more mem efficient, blah blah blah) 2004-07-10 01:39:54 +00:00
ab99122211 render status HTML in pieces (continued) 2004-07-09 05:33:19 +00:00
dd014fee88 send the router console out bit by bit rather than building it all up and sending it (thereby reducing its memory footprint dramatically) 2004-07-09 05:29:02 +00:00
c81f864de3 reduce the throttle threshold from 5s lag to 2s lag 2004-07-09 05:22:29 +00:00
90fe7dceec include the expiration in the error message if its dropped 2004-07-09 05:20:26 +00:00
3a568096f2 new throttling code which rejects tunnel create requests, networkDb lookup requests, and even tells the I2NP components to stop reading from the network (it doesnt affect writing to the network)
the simple RouterThrottleImpl bases its decision entirely on how congested the jobQueue is - if there are jobs that have been waiting 5+ seconds, reject everything and stop reading from the network
(each i2npMessageReader randomly waits .5-1s when throttled before rechecking it)
minor adjustments in the stats published - removing a few useless ones and adding the router.throttleNetworkCause (which is the average ms lag in the jobQueue when an I2NP reader is throttled)
2004-07-09 03:56:22 +00:00
94e694fc61 reduce the job pipeline to send a message by fetching the bids and adding the message to the connection queue synchronously
these had been broken out into seperate jobs before to reduce thread and lock contention, but that isn't as serious an issue anymore (in these cases) and the non-contention-related delays of these mini-jobs are trivial
2004-07-09 03:48:12 +00:00
bdfa6e4af5 dont penalize send failures (beyond what we already do for comm errors)
keep a rate for tunnel rejection, rather than a simple 'last' occurrance, and penalize the reliability with it
2004-07-09 03:45:11 +00:00
8e64ffb4f6 keep the relay message size rate data for the 10 minute period (so we can throttle on logical periods) 2004-07-09 03:43:07 +00:00
6c162643cb expose stat for throttling (# tunnels we're currently participating in) 2004-07-09 03:41:27 +00:00
ff7742bca3 expose some stats useful for throttling (# ready & waiting jobs and the max lag of those jobs) 2004-07-09 03:39:38 +00:00
9685884279 deal with null peer (used by the SubmitMessageHistoryJob to bw limit the history)
current 0.3.2 throws an NPE which causes the submitMessageHistory functionality to fail, which isn't really a loss since i send that data to /dev/null at the moment ;)
(but you'll want to router.keepHistory=false and router.submitHistory=false)
this'll go into the next rev, whenever it comes out
(thanks ugha!)
2004-07-07 22:23:25 +00:00
a8b0d7f999 pull out no longer relevent config parameters
start the irc proxy by default within the router
dont package up the startIrcProxy script
2004-07-07 18:06:46 +00:00
dd84233085 0.3.2 for release later today 2004-07-07 17:58:37 +00:00
fe3eac07f4 migrate the queue pumper thread to scheduled activity (instead of waking up every 500ms, check the job timings to see when we should next wake up. we also wake up whenever a new timed job is added, or the clock skew changes)
pull out some of the old unused vars/flags
2004-07-07 16:16:36 +00:00
0948686989 don't mark failing due to sendFailed (since that can be caused by a message that was about to expire anyway) 2004-07-07 16:11:46 +00:00
4c82970319 get rid of the whole slice concept
dont time out for too many messages (just time out individual ones)
however, if any of the messages that time out have been there for a minute, kill the con (since its hung)
kaffe workaround for fast closing sockets
2004-07-07 16:10:57 +00:00
fe2fede8ed removed maxWaitingJobs param 2004-07-06 18:26:04 +00:00
b23b1e5f1f instead of the maxQueuedMessages limit, use the rule 'if any of the messages time out on the queue, its going too slowly'
(this helps in situations where we've got a flash flood of small messages to send)
2004-07-06 18:24:59 +00:00
dca66c8de8 leave all threads at base priority (except the client runner, where we push at max)
don't consider a connection valid until it has been up for 30 seconds (so people who are simply establishing connections but whose nats are still messed up get the error)
when dealing with expired after accepted, dont drop unless it expired outside the fudge factor
increase the default maxWaitingJobs to 100, since we can get lots at once (and we dont gobble as much memory as we used to)
also, don't wake up the jobQueueRunner in getNext once a second, instead just let the threads updating the queue notify
2004-07-06 14:38:35 +00:00
49090014cc placeholder for overload detection 2004-07-06 14:30:52 +00:00
fa4f100705 new limiter, pull slow and not too useful tests (uncomment 'em to run 'em) 2004-07-04 04:35:16 +00:00
bbf68cd9a8 implemented the FIFO bandwidth limiter which, suprisingly, chokes read/write operations
if they would exceed the currently available # of tokens, letting through those operations
in the order they are called.  like the old trivial bandwidth limiter, this uses a token
bucket approach (keeping a pool of 'available' bytes, decrementing on their use and
periodically refilling it [up to a max limit, to prevent absurd bursts]).  on the other
hand, it doesn't have the starvation issues the old one had, which would continue to let
small operations go through (e.g. 8 byte write) and potentially block large operations
indefinitely (e.g. 32KB write).  However, this new version is, how shall I put it, context
switch heavy?  :)  We'll revise with a scheduling / queueing algorithm once we're away
from transports that require threads per connection
The two directions (input and output) are managed on their own queues, and if/when things
are backed up, you can see the details of what operations have been requested on the
router console.
Since we still need better router throttling code (to reject tunnels and back off more
accurately), I've included a minimum KBps on the limiter, currently set to 6KBps both
ways.  Once there is good throttling code, we can drop that to 1-2KBps, and maybe even
less after we do some bandwidth usage tuning.
There were also a few minor touch ups to handle message data being discarded earlier
than it had been before (since write/read operations can now take a long period of time
in the face of contention)
The five config properties for the bandwidth limiter are:
* i2np.bandwidth.inboundKBytesPerSecond
* i2np.bandwidth.outboundKBytesPerSecond
  (you can guess what those are)
* i2np.bandwidth.inboundBurstKBytes
* i2np.bandwidth.outboundBurstKBytes
  the burst KBytes specify how many bytes we'll let accumulate in the bucket, allowing
  us to burst after a period of inactivity.  excess tokens greater than this limit are
  discarded.
* i2np.bandwidth.replenishFrequencyMs
  this is an internal setting, used to specify how frequently to refil the buckets (min
  value of 1s, which is the default)
You may want to hold off on using these parameters though until the next release,
leaving it to the default of unlimited.  They are read periodically from the config file
however, so you can update them without restart / etc.  (if you want to have no limit on
the bandwidth, set the KBytesPerSecond to  a value <= 0)
2004-07-04 04:33:17 +00:00
mpc
bbc5f6588a *** empty log message *** 2004-07-04 01:53:35 +00:00
mpc
b3632a6a35 duh 2004-07-04 01:00:04 +00:00
mpc
3943c51bb4 Hmm 2004-07-04 00:57:14 +00:00
mpc
4c19ddde69 a couple locking changes 2004-07-03 22:03:49 +00:00
mpc
d8f0f1a1d3 Added test for Logger and debugged it 2004-07-03 21:53:10 +00:00
mpc
121c0d89f2 Fixed test 2004-07-03 20:58:42 +00:00
badfb9088e logging / debugging and formatting (no functional changes) 2004-07-03 19:42:34 +00:00
ff392fee14 properly fake-encrypt the data (this class is only used by the simulator or anything else w/ -Di2p.encryption=off) 2004-07-03 19:41:41 +00:00
mpc
a13693161a http://www.kirstenfan.com/galleries/magazines/fhm2002100sexy/002.jpg -- studies show charming women love computer programmers...... 2004-07-03 11:05:23 +00:00
4b8ac81669 minor refactoring, javadoc
dont add an arbitrary extra Router.CLOCK_FUDGE_FACTOR to the expiration
2004-07-02 18:57:42 +00:00
219a704ee0 bugger it, for consistency, always include the reply leaseSet with a message (later, when we want to optimize the bandwidth requirements, we can revisit) 2004-07-02 16:59:37 +00:00
3996cd1f08 make the client writer thread run at max priority, since it is very time sensitive and only executes for very brief periods 2004-07-02 16:53:49 +00:00
c636b0a0ec minor rewrite to make timing more precise (keeping a map of message add times, not just the 'last' add time) 2004-07-02 15:12:35 +00:00
aae9f671f0 added jdot.i2p (duck) 2004-07-02 13:31:09 +00:00
aec6e901ee And I thought I was dyslectic. (duck) 2004-07-02 13:18:00 +00:00
mpc
f49be25288 <Nightblade> hmm 2004-07-02 09:54:27 +00:00
mpc
f9a96126e1 I don't know how I missed this stuff before 2004-07-02 09:37:54 +00:00
8c9f58b939 Misc. stuff: javadoc, UNUSED...
shendaras
2004-07-02 02:54:04 +00:00
8a7e787f42 logging 2004-07-01 22:33:51 +00:00
148dcc084d factor out the clientWriterRunner and have it deal with multiple i2cp messages being enqueued really fast (at least, more efficiently, by pulling them all off at once and handling them in one pass) 2004-07-01 15:21:32 +00:00
15b1cbd762 synchronize the available() call, and made explicit some other synchronization 2004-07-01 15:11:34 +00:00
e9b7ca3697 dont accept outrageously long delays when building a tunnel (aka now each peer only gets the timeout to respond, instead of the full # peers * timeout to respond)
this will cause more dropped messages to show up, but in turn it will avoid slower peers (since they'll be marked down as rejecting the tunnel)
2004-07-01 15:08:18 +00:00
mpc
1b03e9a3ee Who was the idiot who came up with the idea that booleans should be numbers? 2004-07-01 09:30:52 +00:00
mpc
2b951e3f61 Change throws to asserts. If any of this stuff happens it means a code logic error or a retarded computer, so throwing it is just a waste of time. 2004-07-01 09:17:17 +00:00
mpc
f51e064cf6 *** empty log message *** 2004-07-01 02:23:59 +00:00
9640e93895 imports
shendaras
2004-06-30 13:21:15 +00:00
d5bd22040c Crappy fix for incorrect Total Bytes Sent/Total Bytes Received via BandwidthLimiter.... ah.. just read the FIXME there.
shendaras
2004-06-30 13:16:05 +00:00
dcdcb7521a dont kill the context, we may need it when tearing down the runner (e.g. to get the time) 2004-06-30 04:11:59 +00:00
4058c63884 dont be such a prude 2004-06-30 03:02:39 +00:00
dd34548cc6 publish the tunnel congestion stat 2004-06-29 22:32:31 +00:00
a6b5211fa7 congestion is only a warning, not an error 2004-06-29 22:30:14 +00:00
4e89b9c363 reliability threshold = median of active and nonfailing (inactive nonfailing can be a large number of 0 reliability peers) 2004-06-29 20:32:36 +00:00
f3e267d2d0 active peer testing - every minute, grab two reliable peers, throw a db store at them, and measure their response time
the db store sent is their own, and we use tunnels both ways, so they wont know who we are.  we also mark the
success/failure of the tunnels accordingly
2004-06-29 19:45:26 +00:00
2fd87dc1f1 when we select peers to test, lets use all of the reliable peers, not just well integrated peers 2004-06-29 19:41:30 +00:00
40b6b77cfa use the median reliability value of nonfailing peers for the reliabilty threshold, and simplify determining them for the speed and integration 2004-06-29 19:40:08 +00:00
d0c61dbf4d use the explicit max ID values (I2NPMessage.MAX_ID_VALUE and TunnelId.MAX_ID_VALUE)
logging
2004-06-29 19:32:46 +00:00
1cd5a3fcf7 include the "addedBy" if we're debugging the job, not if we're debugging JobImpl 2004-06-29 19:29:57 +00:00
af81cf2c50 explcitly define the max I2NP message ID value and validate against it 2004-06-29 19:28:40 +00:00
04373c5d1b just to be explicit about the max tunnel id 2004-06-29 19:25:23 +00:00
mpc
e9cdb0f78d new library 2004-06-29 02:55:53 +00:00
mpc
021b933ad3 new library 2004-06-28 23:55:07 +00:00
mpc
9fd067c9da Putting socks/threads/logger/misc in a separate library 2004-06-28 23:24:50 +00:00
d3f3f3bdf7 use the socketManager's new setName function (to let us log more easily) 2004-06-28 13:23:24 +00:00
72727dacd8 javadoc 2004-06-28 13:22:03 +00:00
caeb2bc4e3 the actual fix for the local eepsite problem (if getRemoteID was called *after* the remoteID was set, it would wait for 60s then fail. now we check for that)
synchronization cleanup (never get two locks)
logging
2004-06-28 13:21:18 +00:00
13974b601f added some stats (viewable on the router stat page when the i2ptunnel is run in the router's VM)
lots of logging
2004-06-28 13:18:18 +00:00
cbc6aea8b4 logging 2004-06-27 21:20:31 +00:00
290a2f7ccd (ok this is a little silly) 2004-06-27 21:08:19 +00:00
349e80f206 allow sending ASAP and remove any artificial delays 2004-06-27 20:53:32 +00:00
5c1e001a73 logging 2004-06-27 19:39:45 +00:00
mpc
f312318fab Finished winsock code cleanup 2004-06-27 13:07:06 +00:00
mpc
dc04b7cf09 Some winsock improvements 2004-06-27 09:12:05 +00:00
77a8a46d8e lets try to reduce creating new objects during finalization 2004-06-26 21:15:51 +00:00
95c7cd55c2 logging 2004-06-26 21:15:16 +00:00
5f0ef5e0e8 lets not crap on the secondary tunnel too (even though doing so isn't wrong)
this helps avoid catastrophic failures, at least a little, since a failure doesnt kill two sets of tunnels
2004-06-26 21:13:52 +00:00
1f26c603e0 for now, lets disable the tunnel pool persistance. this means that after a router crashes, tunnels it was participating in will fail even if the router comes back up before they expire.
disabling this saves us some IO contention (though this may only be relevent on my kaffe box... dunno)
2004-06-26 21:11:22 +00:00
7e2227ad42 lets keep track of how many messages die on our queue due to us being slow 2004-06-26 21:07:07 +00:00
9b4899da07 always use the cached host/port rather than grabbing the socket's InetAddress (in case it disconnects and throws NPEs)
use the NativeBigInteger as part of the session key negotiation (oops, forgot this one last time)
logging
2004-06-26 21:05:02 +00:00
mpc
83c88ac0c6 minor fixes 2004-06-26 02:26:37 +00:00
mpc
44623065b4 Threads (untested) 2004-06-26 02:16:54 +00:00
mpc
47c7c8177d Mutex code (untested) 2004-06-25 22:22:48 +00:00
mpc
bde7a5ff59 Mutex code (untested) 2004-06-25 22:19:18 +00:00
a8ad8644c8 0.3.1.5 (backwards compatible)
lots of bugfixes.  still no rate limiting, but, uh, lots of bugfixes
(release will be packaged and deployed later today)
2004-06-25 19:25:33 +00:00
4e91bb88a5 workaround an aggressively up-to-spec kaffe implementation (the spec says Socket.getInetAddress() is null if not connected,
but sun lets the getInetAddress() return a value if it had connected then disconnected, while kaffe buggers off and NPEs)
2004-06-25 19:21:11 +00:00
f60a90e2da added forum.i2p 2004-06-25 18:48:33 +00:00
784dc0f6a7 boot up quicker 2004-06-25 18:42:27 +00:00
e80e627fba more tests with the real TCP transport, not just the VM comm system (and for larger sims, dont keepHistory) 2004-06-25 18:41:50 +00:00
d5987c51c9 yet another deployment option - the user can define a jbigi.ref environmental variable to specify a file from which the name of the resource to be loaded should be found (default is "jbigi.cfg")
if that file exists, the NativeBigInteger will act as if jbigi.impl was set to the contents of that file.
For instance, a jbigi.cfg containing "win-p4" would have the NativeBigInteger search the classpath for the "win-p4" file and use it as a native library.
The jbigi.ref preempts the jbigi.impl property (only if the file exists and is not empty), but the external platform specific jbigi
preempts this (e.g. jbigi.dll or libjbigi.so), as does the jbigi.enable flag.
This option lets us have the admin console write to a file to choose which jbigi to use, rather than have to parse some shell script, etc
2004-06-25 18:32:17 +00:00
5ced441b17 dont fail the peer based on tunnel activity (it may not be their fault)
we *do* still penalize the peer based on tunnel failures, but thats in the reliability calculator, not this one.
2004-06-25 18:15:32 +00:00
57801202fd flush the protocol flag explicitly
make the tcp connection handler nonblocking by adding another (very short lived) thread - this prevents a peer connecting to us that is very slow (or unconnectable) from forcing other cons to timeout
completely ripped out the fscking bandwidth limiter until i get it more reliable
gave threads more explicit names (for the sim)
logging
2004-06-25 18:14:12 +00:00
a019399c3c reduce synchronization on static (instead use per context objects, for large sims) 2004-06-25 17:21:41 +00:00
e6f610a86c dont synchronize on statics, instead use a seperate format object per context (so large sims dont get bogged down on synchronization) 2004-06-25 17:20:08 +00:00
7ef528bbde add some minimal security to the admin console, requiring a passphrase to be entered when updating the clock offset
this works by a simple substring match of the URL - if the router.config contains the adminTimePassphrase=blah, the time update will only succeed if the URL contains "blah" in it
if the router.config does NOT contain an adminTimePassphrase, the time update WILL BE REFUSED.
aka to use the timestamper, you MUST set adminTimePassphrase AND update the clientApp.0.args= line to include the passphrase in the URL!
e.g.
 clientApp.0.args=http://localhost:7655/setTime?blah pool.ntp.org pool.ntp.org pool.ntp.org
2004-06-25 17:18:21 +00:00
a351a29bf3 if it expired waiting on the queue for processing, kill 'er 2004-06-25 17:12:01 +00:00
983d258bce logging 2004-06-25 17:09:55 +00:00
f6d38dd5e0 reduce SimpleDateFormat usage (implicit in Date.toString()) 2004-06-25 17:03:13 +00:00
d51245aada logging 2004-06-25 17:02:22 +00:00
mpc
56cf51f0f9 New configuration system 2004-06-25 01:31:02 +00:00
mpc
eb40fb9c5d typo 2004-06-24 11:51:24 +00:00
mpc
085da0cea7 Started work on a configuration options object 2004-06-24 11:47:01 +00:00
mpc
5539b19938 Added a new example program (which actually works) 2004-06-23 23:35:39 +00:00
94feb762ca keep detailed info for the sim 2004-06-23 19:55:52 +00:00
40b59d5a5a more valid display of bw usage (but not as fresh) 2004-06-23 19:54:12 +00:00
9ffd147470 handle writing the stats before the period has been reached 2004-06-23 19:53:20 +00:00
3fea4ad2ba we dont need to use this fudge in this fashion (its done on the receiving end) 2004-06-23 19:51:58 +00:00
1ab5536879 la la la
(yeah, this is what broke cvs HEAD, causing transmission failures, disconnects, encryption errors, etc.  oops)
2004-06-23 19:50:41 +00:00
9690a89a6d sliices are only too slow if there's something pending
logging mods
i really need to rewrite the tcp transport - the code is all functional, but the design sucks.
with the FIFO bandwidth limiter we could get away with a single 'send' thread rather than each TCPConnection having its own writer thread (but we'd still need the per-con reader thread, at least until nio is solid enough)
but maybe the rewrite can hold off until the AMOC implementation.  we'll see
2004-06-23 19:48:25 +00:00
mpc
8f895f4349 just starting this (backup) 2004-06-23 12:34:50 +00:00
mpc
980c0aa1d7 Added PRNG code 2004-06-23 11:56:53 +00:00
mpc
52fd6ca513 Get rid of Debian-specific Makefile -- gcc < 3.0 is obsolete 2004-06-22 22:49:59 +00:00
mpc
eb5dd2ff2e Now it compiles on Cygwin 2004-06-22 22:48:32 +00:00
7ca35452eb new target - buildclean (== distclean build)
useful for my ide so i dont have to run two targets sequentially (and 'dist' goes one step further to include javadoc, which i dont need)
2004-06-22 04:56:44 +00:00
dd781e256c new constructor 2004-06-22 04:53:22 +00:00
551a7ab82f benchmarking large messages doesnt make much sense when we can compress the payload really really well, now does it? 2004-06-22 04:52:06 +00:00
2901287d9e new command line flags to harvest from an explicit file list rather than using all files in a single directory
(this lets us specify lots of my.info references to make sure we harvest fresh data, rather than depending upon stat propogation)
usage: NetMonitor [configFilename] [--routers filename[,filename]*]
2004-06-22 04:50:43 +00:00
2b714967aa 14yyp error 2004-06-22 04:44:17 +00:00
e8734ef1e7 more logging for shutdown info 2004-06-22 04:42:27 +00:00
14b9f9509f * allow the client subsystem to tell the clientMessagePool that a message is definitely remote (since the client subsystem should know). this reduces the churn of the message pool asking all over again
* add a new ClientWriterRunner thread (1 per I2CP connection) so that a client application that hangs or otherwise doesn't read from its i2cp socket quickly doesn't hang the whole router (since we've previously used the jobQueue for pushing I2CP messages).  This may or may not clear the intermittent eepsite bug, but I'm not counting on it to (yet).
* update various points to deal with the client writer's operation (aka doSend won't throw IOException)
* logging
* lots and lots of metrics (yeah i know some of them vary based on the compiler)
2004-06-22 04:41:31 +00:00
b1f973d304 during initial router startup, we may try to publish "my.info" before the netDb/ dir is created, so lets make sure 2004-06-22 04:31:25 +00:00
2f17bfd71c minor refactoring. i hate how large that method is, but beyond the essential stuff, its pretty much just logging and benchmarking.
plus, yeah, this method still takes too long in some situations.  working on identifying why...
2004-06-22 04:29:28 +00:00
b6670ee23a lets see how fast this can theoretically go (leaving simulated delays to other components) 2004-06-22 04:26:56 +00:00
f1036df1f6 new debugging data point 2004-06-22 04:25:24 +00:00
5c3e815757 dummy DSA (for sim - dont run on live net) 2004-06-22 04:23:19 +00:00
55e780d885 logging and doc of a todo (wrt bestEffort) 2004-06-22 04:16:17 +00:00
mpc
d502df7d56 Make this compile straight out of CVS (you have to have libtomcrypt compiled in a libtomcrypt-0.96 directory in your home directory) 2004-06-21 08:21:17 +00:00
mpc
beb6cc8c0f the journey of a thousand miles begins with a single step :-) 2004-06-21 07:57:11 +00:00
mpc
c99db5e75c change preprocessor conditional to check for 1/0 instead of true/false 2004-06-21 07:50:33 +00:00
mpc
65cd70a85b LibSAM 2004-06-20 11:44:53 +00:00
5166eab5ee replaced double check locking (http://www.javaworld.com/javaworld/jw-02-2001/jw-0209-double.html) with the actual logic
- prepare the cache prior to use if you want to have the hash cache.
also fix the ejection policy to not clear the cache, but merely to remove sufficient values.
though maybe clearing the cache is the right thing to do so as to avoid ejection churn... hmm.
both of these fixes brought to you by the keen eyes of the one called mihi
2004-06-20 04:27:58 +00:00
232f6f158d removed (likely already ignored by the compiler) op. force of habit from dealing with stream.read() i suppose.
thanks mihi
2004-06-20 03:48:16 +00:00
2a07ceba62 a message send failure is no reason to drop the SAM session
for style=stream, tell the client the stream failed, and kill the virtual connection..
for raw and repliable datagrams, just carry on our merry way
2004-06-20 01:49:07 +00:00
3e4b8c7dd4 more stats 2004-06-20 01:45:25 +00:00
26138e213f new method - processingComplete(), which functions much just like OutNetMessage's discardData()
so drop the data when called, updating the MessageStateMonitor (and also telling the monitor on finalization, just cuz)
2004-06-20 01:40:12 +00:00
d82796e3ad note that we've successfully processed a message (and as such drop its payload) ASAP, and only use safely cached snippets of it afterwards 2004-06-20 01:37:01 +00:00
cdcb81c867 dont be so aggressive about waking up more jobs, since this just causes excess locking when we dont need it 2004-06-20 01:34:16 +00:00
5669e8f060 deal with discarded payloads and use the cached version 2004-06-20 01:31:23 +00:00
d84a40b4dc add some randomization to the startup time, so we're not too synchronous
also don't shut down so quickly, as the routers may dump some useful stats when they die a horrible death
2004-06-20 01:29:00 +00:00
591be43763 default to building more tunnels, because tunnels r k00l
(and fix the arg parsing)
2004-06-20 01:26:59 +00:00
97d0686354 new method: discardData() to be called as soon as we dont need the payload of a message anymore (but may still need the associated jobs/etc)
check in with the MessageStateMonitor, and cache some key attributes from the message (type, unique id, size, etc)
2004-06-20 01:21:24 +00:00
e2da05b197 more accurrate (but less lively) bandwidth rate calculation (since we dont necessarily calculate exactly on the edge of a measurement period, we use the data from the last full period)
logging on OOM
2004-06-20 01:18:31 +00:00
4f0052043d /me waves to our new friend, the MessageStateMonitor, which keeps track of how many messages we're dealing with in memory (and whether they've been processed & discarded yet) 2004-06-20 01:15:01 +00:00
cfc1d1a2db publish some new stats, including the bandwidth usage (as always, routers can chose not to publish these stats) 2004-06-20 01:12:14 +00:00
9957e6ef17 keep track of how many messages are processed in the tunnel 2004-06-20 01:09:04 +00:00
6a02c8383c the data is hopefully discarded by now, so dont try to get at it 2004-06-20 01:02:03 +00:00
bc0a4ee68d discard the data ASAP, and make sure we access only the safely cached snippets of it as necessary 2004-06-20 00:59:33 +00:00
1ca615da77 InNetMessage gets a context 2004-06-20 00:57:02 +00:00
7da0cee29a turned BandwidthLimiter into an interface, removed some of its teeth, and cleaned up TrivialBandwidthLimiter 2004-06-20 00:56:04 +00:00
f25bccd19f add some stats for the simulator (data doesnt seem that interesting, so i havent moved them to the CommSystemImpl)
use the .discardData() functionality
2004-06-20 00:53:19 +00:00
4e5a2e012c update since bw limiter interface changed (but dont bother to use it anymore here)
i wonder if i should remove the phttp transport now or keep it around in case it gets revived...
2004-06-20 00:50:38 +00:00
c9ee2a92a3 dont buffer the reads, since we dont want that buffer to interfere with either the bandwidth limiting or the AES decryption
logging
2004-06-20 00:46:57 +00:00
95a7938328 reduce the max slice time (aka max time to pump out a message + some cleanup) to 60 seconds
close connections to peers who are so slow that they leave messages on the queue to expire
reduce the default max queue size per connection to 10 messages
(as always, this is a configurable param, via "i2np.tcp.maxQueuedMessages" in router.config)
2004-06-20 00:44:43 +00:00
baedcdb2c1 handle situations where people dont specify a client name for a client app 2004-06-20 00:40:16 +00:00
bc06b3671a whenever a tunnel completes, log how many messages we passed through it in the stats:
tunnel.inboundMessagesProcessed
tunnel.outboundMessagesProcessed
tunnel.participatingMessagesProcessed
(for the various tunnel types)
2004-06-20 00:35:52 +00:00
a9172811ca reduce the grace period from 5 to 2 minutes, which will cause us to test peers more often
also add some logging (log level == debug will display why we mark a peer as failing)
2004-06-20 00:31:20 +00:00
91b1fd6d07 InNetMessage now needs a reference to a context, so give it one 2004-06-20 00:26:05 +00:00
bab7b8b9ed discard the payload of a message ASAP (even though we may need to hang on to the message for a while, for its replyJob, etc)
take note of the fact that the tunnel had activity
minor logging and formatting updates
2004-06-20 00:24:06 +00:00
1b7fb96ca8 dont expose a method we dont need to expose 2004-06-20 00:19:38 +00:00
6d84b8c02f 1) use cachedXor to cut down on the, uh, xor-ing (which involves at least one new byte[32])
2) implement an optimized 'should contain' algorithm, rather than being a wuss and building + comparing a BigInteger of the xor.
3) more unit tests
this stuff is called a *lot*, since we need to pick what bucket things go in all the time.
2004-06-20 00:18:28 +00:00
3e3749f011 added some unit tests (adding the local key (delta == 0x00) and adding 1000 random keys, all making sure nothing b0rks) 2004-06-20 00:13:05 +00:00
52384fb3a5 persist the local router's info @ netDb/my.info in addition to under netDb/routerInfo-$hash.dat
this makes it easy for harvesting with simulations
2004-06-20 00:11:23 +00:00
e401670087 i like logging, dont you like logging? 2004-06-20 00:08:59 +00:00
ae0b4c59cc include the port # in the thread name, and logging 2004-06-20 00:07:37 +00:00
0a8dc8afcc logging, its whats for dinner 2004-06-20 00:06:33 +00:00
d59b94df66 logging, deal with times when a client doesnt have a destination yet 2004-06-20 00:05:30 +00:00
e28502454b include the port in the thread name (useful for the sim) 2004-06-20 00:03:45 +00:00
bbf73f0937 enforce some sanity checks on the payload size. see recent rant in DatabaseSearchReplyMessage commit for why
this is necessary.
2004-06-19 23:58:24 +00:00
592519c45c somehow some people are getting situations where the payload doesnt decompress. wtf?
do i need to wrap the Input/Output streams we use to pipe data over the net with a verification wrapper for the messages?
e.g. prefix the serialization of all I2NPMessages sent on the wire with the SHA256 of that serialization and verify on read?
Ho hum, dunno.  maybe its something else, but the ElG/AES+SessionTag already has integrity verification so the only thing I can
think of is a checksum error that got past TCP's checking and corrupted the AES stream.
2004-06-19 23:56:41 +00:00
cc904ba9dc use new SessionConfig constructor 2004-06-19 23:46:08 +00:00
1679ba6719 so this String.getBytes(), its inefficient? you don't say...
(yeah, i know, this optimization takes advantage of the fact that the data in question uses single byte charsets)
2004-06-19 23:41:55 +00:00
07fadd4a6c avoid string.getBytes like the plague 2004-06-19 23:40:03 +00:00
57e1ff39e0 new method: cachedXor which, suprisingly, determines the xor of a hash against another hash, caching up to a certain number of values
currently uses an essentially random ejection policy, but this saves a lot of temporarly memory churn, since we xor many hashes against a router/destination's key
2004-06-19 23:35:43 +00:00
51e259c198 avoiding the String.getBytes() since its a bitch on gc (measured for this situation) 2004-06-19 23:32:41 +00:00
de334b003d for safety, always create a session config with a destination 2004-06-19 23:30:57 +00:00
a61ff12390 more microoptimizations, whee! 2004-06-19 23:28:12 +00:00
f4697be159 just a simple catch all for OOM while handling an OOM (naw, we dont recurse too much (just a little)) 2004-06-19 23:25:47 +00:00
3835fe3960 give the shutdown hook thread a name 2004-06-19 23:13:09 +00:00
76c374ef06 more accurate memory usage to reduce gc churn 2004-06-19 23:11:42 +00:00
57d24bd948 read the logger.config when its been updated, even if we dont have any log messages to write out (duh)
also, a micro-optimization for charset handling identified through profiling
2004-06-19 23:02:59 +00:00
deff14dfd8 lets see if this fixes bug 66 (http://dev.i2p.net/bugzilla/show_bug.cgi?id=66) 2004-06-13 20:27:44 +00:00
0a479be370 include NAME=val in failed lookup replies (per spec - thanks nightblade)
fixes http://dev.i2p.net/bugzilla/show_bug.cgi?id=79
2004-06-13 20:19:16 +00:00
ba6a2e3fd2 unit test for the bandwidth limiting functionality (TrivialBandwidthLimiter, BandwidthLimiter, BandwidthLimited{In,Out}putStream) 2004-06-13 20:03:21 +00:00
c3a395a41e update the bandwidth limiter config properties 2004-06-13 19:59:44 +00:00
a3136a19e9 big ol' rewrite, requiring new config settings and, er, it works pretty well.
see router.config.template mods and the new unit tests.
this implementation can cause starvation -
  e.g. lots of 1KB writes will go through before a 32KB write if the queue is low and the bwlimiter only replenishes say, 16KBps
  another impl would enforce a FIFO through thread wait/notify, etc, but would have the related overhead.
i dont know whether starvation situations will be the norm or the exception.  i'm running this on a few routers so we'll see.
2004-06-13 19:56:57 +00:00
b631568003 deal with null routers 2004-06-13 19:48:23 +00:00
1d0c03eca4 use the router context's properties (which now include the config settings) 2004-06-13 19:47:44 +00:00
eb30525a26 deal with null routers (useful for testing) 2004-06-13 19:47:02 +00:00
3e66ea3f56 include the router's config in the property settings 2004-06-13 19:45:53 +00:00
9f1189e606 use a bandwidth limited stream instead of asking for the allocation of the entire buffer at once (since, uh, its not likely that the bandwidth limiter will ever have hundreds of KBytes available for use) 2004-06-13 19:39:42 +00:00
698927bed4 logging 2004-06-13 19:37:18 +00:00
8fd02ee8dd allow the stream to optionally pull from the output stream's bandwidth limit queue (useful in very strange situations) 2004-06-13 19:36:41 +00:00
f3154e8f5e buffer between the bandwidth limiter and the raw stream 2004-06-13 19:34:46 +00:00
878af163a9 handle null boolean value (legal, but not in this context), fixes bug reported by nickster 2004-06-13 19:32:58 +00:00
da8341d014 reduced buffer size and updated domain name reference (dev.i2p.net, not i2p.dyndns.net) 2004-06-13 19:31:22 +00:00
95c33e88ed handle decompress error by propogating the IOE (thanks nickster for bug report) 2004-06-13 19:30:31 +00:00
fed8369a5f big rewrite of how we load the native implementation:
- the old method is default: it looks for jbigi.dll / libjbigi.so in the current dir (and library path)
- otherwise, you can specify -Djbigi.impl=blah and if there is a file called "blah" in the classpath (including any jar file), it will load that file as a native implementation
there are lots more javadocs now as well, and the dependency upon Log was removed (so anyone else who wants to use this just needs NativeBigInteger.java and the jbigi implementation)
2004-06-12 20:08:32 +00:00
d85806e3d5 added ferret.i2p
(duck)
2004-06-09 20:06:17 +00:00
097660ce53 Round-robin DNS NTP pool makes sense as default
Discussed at http://www.i2p.net/node/view/226 (thanks Nightblade)
(duck)
2004-06-09 14:30:26 +00:00
b08cfbbb35 we now have a website & eepproxy is launched automatically
(duck)
2004-06-09 14:27:51 +00:00
97ee3c47a0 added anonynanny.i2p
(duck)
2004-06-01 16:57:09 +00:00
05918de6ab fix bug #75
the databuffer is reused so it might contain junk, therefore only use the
available amount of bytes
(duck)
2004-05-26 12:25:04 +00:00
8d7abd8298 added hypercubus.i2p 2004-05-24 12:53:41 +00:00
727f4c3bb5 Another rfc2068 fix.
ERR_REQUEST_DENIED now returns a 403 status code. Note that I'm assuming
this error occurs because the proxy is configured to not allow connection
to non-i2p destinations. If it's issued for other reasons we might want
to consider using 503 instead.
2004-05-24 07:28:24 +00:00
7372ad0cc4 A few changes to make proxy return the proper rfc2068 status codes
instead of 404 for everything.

ERR_DESTINATION_UNKNOWN now returns 503 instead of 404 with a slightly
more clear error message.

ERR_TIMEOUT now returns 504 gateway timeout.
2004-05-24 07:08:02 +00:00
ca6884dbca imports (sorry, includes alphabetizing, wee)
(shendaras)
2004-05-24 03:21:21 +00:00
289 changed files with 13829 additions and 2649 deletions

27
apps/enclave/LICENSE Normal file
View File

@ -0,0 +1,27 @@
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

@ -0,0 +1,87 @@
#
# 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

@ -0,0 +1,87 @@
#
# 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

@ -0,0 +1,87 @@
#
# 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

@ -0,0 +1,32 @@
#
# 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

@ -0,0 +1,2 @@
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

@ -0,0 +1,27 @@
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

@ -0,0 +1,163 @@
/*
* 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 <cstdarg>
#include <cstdio>
#include <iostream>
#include <string>
using namespace std;
#include "mutex.hpp"
#include "time.hpp"
#include "logger.hpp"
using namespace Libsockthread;
/*
* Closes the log file
*/
void Logger::close(void)
{
logf_m.lock();
if (logf == 0) {
logf_m.unlock();
return;
}
if (fclose(logf) == EOF) {
cerr_m.lock();
cerr << "fclose() failed: " << strerror(errno) << '\n';
cerr_m.unlock();
}
logf = 0;
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);
string s;
Time t;
logf_m.lock();
if (logf != 0) {
/*
* Remember! If you change the format here, change it in the else too
*/
fprintf(logf, "%c %s ", ll, t.utc(s).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(s).c_str());
vfprintf(stderr, format, ap);
fputc('\n', stderr);
}
va_end(ap);
logf_m.unlock();
return;
}
/*
* Opens a log file for appending. If there already is an open log file, 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 -lpthread
int main(void)
{
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

@ -0,0 +1,96 @@
/*
* 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_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
*
* Obviously, these only work if your Logger object is called "logger" and is
* global
*/
// 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:
typedef enum {DEBUG = 0, MINOR = 1, INFO = 2, WARN = 3, ERROR = 4}
priority_t;
Logger(void)
: logf(0), loglevel(Logger::DEBUG) { }
~Logger(void) { close(); }
void close(void);
void log(priority_t priority, const char* format, ...);
priority_t get_loglevel(void)
{ 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

@ -0,0 +1,136 @@
/*
* 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.
*/
// Modelled after JThread by Jori Liesenborgs
#include <cassert>
#include "platform.hpp"
#ifdef WINTHREAD
#include <windows.h>
#else
#include <pthread.h>
#endif
using namespace std;
#include "mutex.hpp"
using namespace Libsockthread;
/*
* Creates a mutex
*/
Mutex::Mutex(void)
{
#ifdef WINTHREAD
mutex = CreateMutex(0, false, 0);
assert(mutex != 0);
#else
int rc = pthread_mutex_init(&mutex, 0);
assert(rc == 0);
#endif
}
/*
* Destroys a mutex
*/
Mutex::~Mutex(void)
{
#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(void)
{
#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(void)
{
#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 -lpthread
#include <iostream>
#include "thread.hpp"
Mutex widget;
int main(void)
{
class Mutex_test : public Thread
{
public:
Mutex_test(int n)
: testval(n) {}
void* thread(void)
{
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

@ -0,0 +1,53 @@
/*
* 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.
*/
// Modelled after JThread by Jori Liesenborgs
#ifndef LIBSOCKTHREAD_MUTEX_HPP
#define LIBSOCKTHREAD_MUTEX_HPP
namespace Libsockthread {
class Mutex {
public:
Mutex(void);
~Mutex(void);
void lock(void);
void unlock(void);
private:
#ifdef WINTHREAD
HANDLE mutex;
#else
pthread_mutex_t mutex;
#endif
};
}
#endif // LIBSOCKTHREAD_MUTEX_HPP

View File

@ -0,0 +1,63 @@
/*
* 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_PLATFORM_HPP
#define LIBSOCKTHREAD_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 INET_ADDRSTRLEN 16
#define NO_GETHOSTBYNAME2
#define NO_INET_ATON /* implies NO_INET_PTON */
#define NO_INET_NTOP
#define WINSOCK
#define WINTHREAD
#endif
#if OS == LINUX
#define NO_GETHOSTBYNAME2
#endif
#if OS == CYGWIN
#define FAST32_IS_LONG
#define INET_ADDRSTRLEN 16
#define NO_GETHOSTBYNAME2
#define NO_INET_NTOP
#define NO_INET_PTON
#endif
#endif // LIBSOCKTHREAD_PLATFORM_HPP

View File

@ -0,0 +1,277 @@
/*
* 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 <cassert>
using namespace std;
#include "platform.hpp"
#include "socket.hpp"
using namespace Libsockthread;
size_t Socket::total = 0; // the total number of sockets in use
/*
* Constructs an IPv4 TCP socket
*/
Socket::Socket(void)
{
++total;
try {
#ifdef WINSOCK
if (total == 1)
winsock_startup();
#endif
create_socket(PF_INET, SOCK_STREAM);
} catch (const Socket_error& x) {
--total;
throw;
}
}
/*
* Constructs the socket
*
* domain - either PF_INET or PF_INET6
* type - either SOCK_STREAM or SOCK_DGRAM
*/
Socket::Socket(int domain, int type)
{
++total;
try {
#ifdef WINSOCK
if (total == 1)
winsock_startup();
#endif
create_socket(domain, type);
} catch {const Socket_error& x) {
--total;
throw;
}
}
/*
* Destroys the socket
*/
Socket::~Socket(void)
{
close();
--total;
assert(total >= 0);
#ifdef WINSOCK
if (total == 0)
winsock_cleanup();
#endif
}
/*
* Closes the socket
*/
void Socket::close(void)
{
#ifdef WINSOCK
if (closesocket(sock) == SOCKET_ERROR) {
LERROR("closesocket() failed: %s", winsock_strerror(WSAGetLastError()));
}
#else
if (close(sock) == -1) {
LERROR("close() failed: %s", strerror(errno));
}
#endif
}
/*
* Creates the socket
*
* domain - either PF_INET or PF_INET6
* type - either SOCK_STREAM or SOCK_DGRAM
*/
void Socket::create_socket(int domain, int type)
{
assert((domain == PF_INET || domain == PF_INET6) &&
(type == SOCK_STREAM || type == SOCK_DGRAM));
sock = socket(domain, type, 0);
#ifdef WINSOCK
if (sock == INVALID_SOCKET)
throw Socket_error(sam_winsock_strerror(WSAGetLastError()));
#else
if (sock == -1)
throw Socket_error(strerror(errno));
#endif
}
#ifdef WINSOCK
/*
* Unloads the Winsock network subsystem
*/
void Socket::winsock_cleanup(void)
{
int rc = WSACleanup();
assert(rc != SOCKET_ERROR);
}
/*
* Loads the Winsock network sucksystem
*/
void Socket::winsock_startup(void)
{
WORD wVersionRequested = MAKEWORD(2, 2);
WSADATA wsaData;
int rc = WSAStartup(wVersionRequested, &wsaData);
if (rc != 0)
throw Socket_error(winsock_strerror(rc));
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
winsock_cleanup();
throw Socket_error("Bad Winsock version");
}
}
/*
* Apparently Winsock does not have a strerror() equivalent for its functions
*
* code - code from WSAGetLastError()
*
* Returns: error string (from http://msdn.microsoft.com/library/default.asp?
* url=/library/en-us/winsock/winsock/windows_sockets_error_codes_2.asp)
*/
const char* Socket::winsock_strerror(int code)
{
switch (code) {
case WSAEINTR:
return "Interrupted function call";
case WSAEACCES: // yes, that is the correct spelling
return "Permission denied";
case WSAEFAULT:
return "Bad address";
case WSAEINVAL:
return "Invalid argument";
case WSAEMFILE:
return "Too many open files";
case WSAEWOULDBLOCK:
return "Resource temporarily unavailable";
case WSAEINPROGRESS:
return "Operation now in progress";
case WSAEALREADY:
return "Operation already in progress";
case WSAENOTSOCK:
return "Socket operations on nonsocket";
case WSAEDESTADDRREQ:
return "Destination address required";
case WSAEMSGSIZE:
return "Message too long";
case WSAEPROTOTYPE:
return "Protocol wrong type for socket";
case WSAENOPROTOOPT:
return "Bad protocol option";
case WSAEPROTONOSUPPORT:
return "Protocol not supported";
case WSAESOCKTNOSUPPORT:
return "Socket type not supported";
case WSAEOPNOTSUPP:
return "Operation not supported";
case WSAEPFNOSUPPORT:
return "Protocol family not supported";
case WSAEAFNOSUPPORT:
return "Address family not supported by protocol family";
case WSAEADDRINUSE:
return "Address already in use";
case WSAEADDRNOTAVAIL:
return "Cannot assign requested address";
case WSAENETDOWN:
return "Network is down";
case WSAENETUNREACH:
return "Network is unreachable";
case WSAENETRESET:
return "Network dropped connection on reset";
case WSAECONNABORTED:
return "Software caused connection abort";
case WSAECONNRESET:
return "Connection reset by peer";
case WSAENOBUFS:
return "No buffer space available";
case WSAEISCONN:
return "Socket is already connected";
case WSAENOTCONN:
return "Socket is not connected";
case WSAESHUTDOWN:
return "Cannot send after socket shutdown";
case WSAETIMEDOUT:
return "Connection timed out";
case WSAECONNREFUSED:
return "Connection refused";
case WSAEHOSTDOWN:
return "Host is down";
case WSAEHOSTUNREACH:
return "No route to host";
case WSAEPROCLIM:
return "Too many processes";
case WSASYSNOTREADY:
return "Network subsystem is unavailable";
case WSAVERNOTSUPPORTED:
return "Winsock.dll version out of range";
case WSANOTINITIALISED:
return "Successful WSAStartup not yet performed";
case WSAEDISCON:
return "Graceful shutdown in progress";
case WSATYPE_NOT_FOUND:
return "Class type not found";
case WSAHOST_NOT_FOUND:
return "Host not found";
case WSATRY_AGAIN:
return "Nonauthoritative host not found";
case WSANO_RECOVERY:
return "This is a nonrecoverable error";
case WSANO_DATA:
return "Valid name, no data record of requested type";
/* None of this shit compiles under Mingw - who knows why...
case WSA_INVALID_HANDLE:
return "Specified event object handle is invalid";
case WSA_INVALID_PARAMETER:
return "One or more parameters are invalid";
case WSA_IO_INCOMPLETE:
return "Overlapped I/O event object not in signaled state";
case WSA_IO_PENDING:
return "Overlapped operations will complete later";
case WSA_NOT_ENOUGH_MEMORY:
return "Insufficient memory available";
case WSA_OPERATION_ABORTED:
return "Overlapped operation aborted";
case WSAINVALIDPROCTABLE:
return "Invalid procedure table from service provider";
case WSAINVALIDPROVIDER:
return "Invalid service provider version number";
case WSAPROVIDERFAILEDINIT:
return "Unable to initialize a service provider";
*/
case WSASYSCALLFAILURE:
return "System call failure";
default:
return "Unknown error";
}
}
#endif // WINSOCK

View File

@ -0,0 +1,64 @@
/*
* 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_HPP
#define LIBSOCKTHREAD_SOCKET_HPP
namespace Libsockthread {
class Socket_error : public runtime_error {
public:
Socket_error(const string& s)
: runtime_error(s) { }
};
class Socket {
public:
Socket(void); // throws Socket_error
Socket(int domain, int type); // throws Socket_error
~Socket(void);
void close(void);
private:
#ifdef WINSOCK
typedef SOCKET socket_t;
void winsock_cleanup(void);
void winsock_startup(void); // throws Socket_error
const char* winsock_strerror(int code);
#else
typedef int socket_t;
#endif
void create_socket(int domain, int type); // throws Socket_error
socket_t sock;
static size_t total; // the total number of sockets in memory
};
}
#endif // LIBSOCKTHREAD_SOCKET_HPP

View File

@ -0,0 +1,83 @@
/*
* 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 <arpa/inet.h>
#include <cassert>
using namespace std;
#include "platform.hpp"
#include "socket.hpp"
#include "socket_addr.hpp"
using namespace Libsockthread;
Socket_addr::Socket_addr(int domain, const string& host, uint16_t port)
: domain(domain), host(host), port(port)
{
memset(&hostaddr, 0, sizeof hostaddr);
hostaddr.sin_family = domain;
hostaddr.sin_port = htons(port);
resolve(host.c_str(), ipaddr);
int rc;
#ifdef NO_INET_ATON
rc = hostaddr.sin_addr.s_addr = inet_addr(ipaddr);
#elif defined NO_INET_PTON
rc = inet_aton(ipaddr, &hostaddr.sin_addr);
#else
rc = inet_pton(AF_INET, ipaddr, &hostaddr.sin_addr);
#endif
assert(rc != 0 && rc != -1);
}
/*
* Performs a DNS lookup on `hostname' and puts the result in `ipaddr'
*/
bool Socket::resolve(const char* hostname, char* ipaddr)
{
struct hostent *h;
#ifdef NO_GETHOSTBYNAME2
h = gethostbyname(hostname);
#else
h = gethostbyname2(hostname, domain);
#endif
if (h == 0) {
LWARN("DNS resolution failed for %s", hostname);
throw Socket_error("DNS resolution failed");
}
struct in_addr a;
a.s_addr = ((struct in_addr *)h->h_addr)->s_addr;
#ifdef NO_INET_NTOP
char *tmp;
tmp = inet_ntoa(a);
assert(tmp != 0);
strlcpy(ipaddr, tmp, INET_ADDRSTRLEN); // inet_ntoa() was very poorly designed
#else
int rc = inet_ntop(domain, &a, ipaddr, INET_ADDRSTRLEN);
assert(rc != 0);
#endif
}

View File

@ -0,0 +1,49 @@
/*
* 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_ADDR_HPP
#define LIBSOCKTHREAD_SOCKET_ADDR_HPP
namespace Libsockthread {
class Socket_addr {
public:
Socket_addr(int domain, const string& host, uint16_t port);
private:
bool resolve(const char* hostname, char* ipaddr);
int domain; // PF_INET or PF_INET6
string host;
char ipaddr[INET_ADDRSTRLEN];
struct sockaddr_in hostaddr;
uint16_t port;
};
}
#endif // LIBSOCKTHREAD_SOCKET_ADDR_HPP

View File

@ -0,0 +1,84 @@
/*
* 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.
*/
#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

@ -0,0 +1,47 @@
/*
* 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.
*/
/*
* 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

@ -0,0 +1,199 @@
/*
* 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.
*/
// Modelled after JThread by Jori Liesenborgs
#include <cassert>
#include "platform.hpp"
#ifdef WINTHREAD
#include <windows.h>
#else
#include <pthread.h>
#endif
using namespace std;
#include "mutex.hpp"
#include "thread.hpp"
using namespace Libsockthread;
/*
* Gets the return value of a finished thread
*/
void* Thread::get_retval(void)
{
void* val;
running_m.lock();
if (running)
val = 0;
else
val = retval;
running_m.unlock();
return val;
}
/*
* Checks whether the thread is running
*/
bool Thread::is_running(void)
{
running_m.lock();
bool r = running;
running_m.unlock();
return r;
}
/*
* Stops the thread
* Generally NOT a good idea
*/
void Thread::kill(void)
{
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, 0);
assert(rc);
#else
int rc = pthread_cancel(id);
assert(rc == 0);
#endif
running = false;
running_m.unlock();
}
/*
* Starts the thread
*/
void Thread::start(void)
{
#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(0, 0, &the_thread, this, 0, &id);
assert(handle != 0);
#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 -lpthread
#include <iostream>
int main(void)
{
class Thread_test : public Thread
{
public:
Thread_test(int testval)
: testval(testval) { }
int get_testval(void)
{
testval_m.lock();
int rc = testval;
testval_m.unlock();
return rc;
}
void *thread(void)
{
// 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

@ -0,0 +1,65 @@
/*
* 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.
*/
// Modelled after JThread by Jori Liesenborgs
#ifndef LIBSOCKTHREAD_THREAD_HPP
#define LIBSOCKTHREAD_THREAD_HPP
namespace Libsockthread {
class Thread {
public:
Thread(void)
: retval(0), running(false) { }
virtual ~Thread(void)
{ kill(); }
void* get_retval(void);
bool is_running(void);
void kill(void);
void start(void);
virtual void *thread(void) = 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

@ -0,0 +1,94 @@
/*
* 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 <ctime>
#include <string>
using namespace std;
#include "time.hpp"
using namespace Libsockthread;
/*
* Converts the time to an ISO 8601 standard time and date and puts it in a
* string
* Example: 2004-07-01T19:03:47Z
*/
string& Time::utc(string &s) const
{
struct tm* tm;
tm = gmtime(&unixtime);
char t[21];
strftime(t, sizeof t, "%Y-%m-%dT%H:%M:%SZ", tm);
return s = t;
}
/*
* Converts the time to an ISO 8601 standard date and puts it in a string
* Example: 2004-07-01Z
*/
string& Time::utc_date(string &s) const
{
struct tm* tm;
tm = gmtime(&unixtime);
char t[12];
strftime(t, sizeof t, "%Y-%m-%dZ", tm);
return s = t;
}
/*
* Converts the time to an ISO 8601 standard time and puts it in a string
* Example: 19:03:47Z
*/
string& Time::utc_time(string &s) const
{
struct tm* tm;
tm = gmtime(&unixtime);
char t[10];
strftime(t, sizeof t, "%H:%M:%SZ", tm);
return s = t;
}
#ifdef UNIT_TEST
// g++ -Wall -DUNIT_TEST time.cpp -o time
#include <iostream>
int main(void)
{
Time t;
string s;
cout << "Current date and time is " << t.utc(s) << '\n';
cout << "Current date is " << t.utc_date(s) << '\n';
cout << "Current time is " << t.utc_time(s) << '\n';
return 0;
}
#endif // UNIT_TEST

View File

@ -0,0 +1,48 @@
/*
* 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_TIME_HPP
#define LIBSOCKTHREAD_TIME_HPP
namespace Libsockthread {
class Time {
public:
Time(void) { now(); }
void now(void) { unixtime = time(0); }
string& utc(string &s) const;
string& utc_date(string &s) const;
string& utc_time(string &s) const;
private:
time_t unixtime;
};
}
#endif // LIBSOCKTHREAD_TIME_HPP

169
apps/enclave/src/bigint.cpp Normal file
View File

@ -0,0 +1,169 @@
/*
* 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

@ -0,0 +1,60 @@
/*
* 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

56
apps/enclave/src/chk.cpp Normal file
View File

@ -0,0 +1,56 @@
/*
* 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);
}

51
apps/enclave/src/chk.hpp Normal file
View File

@ -0,0 +1,51 @@
/*
* 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

148
apps/enclave/src/config.cpp Normal file
View File

@ -0,0 +1,148 @@
/*
* 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

@ -0,0 +1,54 @@
/*
* 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

@ -0,0 +1,61 @@
/*
* 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

@ -0,0 +1,88 @@
/*
* 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

84
apps/enclave/src/main.cpp Normal file
View File

@ -0,0 +1,84 @@
/*
* 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;
}

36
apps/enclave/src/main.hpp Normal file
View File

@ -0,0 +1,36 @@
/*
* 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

@ -0,0 +1,54 @@
/*
* 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

52
apps/enclave/src/peer.hpp Normal file
View File

@ -0,0 +1,52 @@
/*
* 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

220
apps/enclave/src/peers.cpp Normal file
View File

@ -0,0 +1,220 @@
/*
* 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

@ -0,0 +1,65 @@
/*
* 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

@ -0,0 +1,111 @@
/*
* 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

@ -0,0 +1,65 @@
/*
* 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

@ -0,0 +1,45 @@
/*
* 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

233
apps/enclave/src/rpc.cpp Normal file
View File

@ -0,0 +1,233 @@
/*
* 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";
}

65
apps/enclave/src/rpc.hpp Normal file
View File

@ -0,0 +1,65 @@
/*
* 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

249
apps/enclave/src/sam.cpp Normal file
View File

@ -0,0 +1,249 @@
/*
* 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';
}
}

66
apps/enclave/src/sam.hpp Normal file
View File

@ -0,0 +1,66 @@
/*
* 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

@ -0,0 +1,46 @@
/*
* 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

122
apps/enclave/src/sha1.cpp Normal file
View File

@ -0,0 +1,122 @@
/*
* 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);
}

56
apps/enclave/src/sha1.hpp Normal file
View File

@ -0,0 +1,56 @@
/*
* 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

@ -9,12 +9,12 @@
<target name="compile">
<mkdir dir="./build" />
<mkdir dir="./build/obj" />
<javac srcdir="./src" debug="true" destdir="./build/obj" includes="**/*.java" excludes="net/i2p/heartbeat/gui/**" classpath="../../../core/java/build/i2p.jar" />
<javac srcdir="./src" debug="true" deprecation="on" source="1.3" target="1.3" destdir="./build/obj" includes="**/*.java" excludes="net/i2p/heartbeat/gui/**" classpath="../../../core/java/build/i2p.jar" />
</target>
<target name="compileGUI">
<mkdir dir="./build" />
<mkdir dir="./build/obj" />
<javac debug="true" destdir="./build/obj">
<javac debug="true" source="1.3" target="1.3" deprecation="on" destdir="./build/obj">
<src path="src/" />
<classpath path="../../../core/java/build/i2p.jar" />
<classpath path="../../jfreechart/jfreechart-0.9.17/lib/jcommon-0.9.2.jar" />

View File

@ -358,7 +358,7 @@ public class ClientConfig {
int sendFreq = getInt(sendFrequencyVal);
int sendSize = getInt(sendSizeVal);
if ((duration <= 0) || (statFreq <= 0) || (sendFreq <= 0) || (sendSize <= 0)) {
if ((duration <= 0) || (statFreq <= 0) || (sendFreq < 0) || (sendSize <= 0)) {
if (_log.shouldLog(Log.WARN)) {
_log.warn("Invalid client config: duration [" + statDurationVal + "] stat frequency ["
+ statFrequencyVal + "] send frequency [" + sendFrequencyVal + "] send size ["
@ -424,7 +424,7 @@ public class ClientConfig {
* @return true if it was stored correctly, false if there were errors
*/
public boolean store(Properties clientConfig, int peerNum) {
if ((_peer == null) || (_sendFrequency <= 0) || (_sendSize <= 0) || (_statDuration <= 0)
if ((_peer == null) || (_sendFrequency < 0) || (_sendSize <= 0) || (_statDuration <= 0)
|| (_statFrequency <= 0) || (_statFile == null)) { return false; }
String comment = _comment;

View File

@ -90,7 +90,7 @@ class ClientEngine {
/** our actual heartbeat pumper - this drives the test */
private class ClientRunner implements Runnable {
/* (non-Javadoc)
/**
* @see java.lang.Runnable#run()
*/
public void run() {
@ -120,9 +120,12 @@ class ClientEngine {
_data.cleanup();
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
long timeToWait = nextSend - Clock.getInstance().now();
if (timeToWait > 0) {
try {
Thread.sleep(timeToWait);
} catch (InterruptedException ie) {
}
}
}
}

View File

@ -157,7 +157,7 @@ public class Heartbeat {
}
/** disconnect from the network */
private void disconnect() {
private void disconnect() { /* UNUSED */
_adapter.disconnect();
}

View File

@ -6,10 +6,10 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
import java.util.Properties;
import net.i2p.I2PAppContext;
import net.i2p.I2PException;
import net.i2p.client.I2PClient;
import net.i2p.client.I2PClientFactory;
@ -46,7 +46,7 @@ class I2PAdapter {
/** how do we talk to the router */
private I2PSession _session;
/** object that receives our i2cp notifications from the session and tells us */
private I2PListener _i2pListener;
private I2PListener _i2pListener; /* UNUSED */
/**
* This config property tells us where the private destination data for our
@ -219,7 +219,8 @@ class I2PAdapter {
DataHelper.writeDate(baos, new Date(now));
int padding = size - baos.size();
byte paddingData[] = new byte[padding];
Arrays.fill(paddingData, (byte) 0x2A);
I2PAppContext.getGlobalContext().random().nextBytes(paddingData);
//Arrays.fill(paddingData, (byte) 0x2A);
DataHelper.writeLong(baos, 2, padding);
baos.write(paddingData);
boolean sent = _session.sendMessage(peer, baos.toByteArray());
@ -577,14 +578,14 @@ class I2PAdapter {
* @see net.i2p.client.I2PSessionListener#errorOccurred(net.i2p.client.I2PSession, java.lang.String, java.lang.Throwable)
*/
public void errorOccurred(I2PSession session, String message, Throwable error) {
if (_log.shouldLog(Log.ERROR)) _log.error("Error occurred", error);
if (_log.shouldLog(Log.ERROR)) _log.error("Error occurred: " + message, error);
}
/* (non-Javadoc)
* @see net.i2p.client.I2PSessionListener#reportAbuse(net.i2p.client.I2PSession, int)
*/
public void reportAbuse(I2PSession session, int severity) {
if (_log.shouldLog(Log.ERROR)) _log.error("Abuse reported");
if (_log.shouldLog(Log.ERROR)) _log.error("Abuse reported with severity " + String.valueOf(severity));
}
/* (non-Javadoc)
@ -600,4 +601,4 @@ class I2PAdapter {
}
}
}
}
}

View File

@ -103,6 +103,11 @@ public class PeerData {
* @return when the test began
*/
public long getSessionStart() { return _sessionStart; }
/**
* sets when the test began
* @param when when it began
*/
public void setSessionStart(long when) { _sessionStart = when; }
/**
@ -332,6 +337,11 @@ public class PeerData {
* @return the time the ping was sent
*/
public long getPingSent() { return _pingSent; }
/**
* sets when we sent this ping
* @param when when we sent the ping
*/
public void setPingSent(long when) { _pingSent = when; }
/**

View File

@ -114,7 +114,7 @@ public class PeerDataWriter {
return buf.toString();
}
private static final SimpleDateFormat _fmt = new SimpleDateFormat("yyyyMMdd.HH:mm:ss.SSS", Locale.UK);
private final SimpleDateFormat _fmt = new SimpleDateFormat("yyyyMMdd.HH:mm:ss.SSS", Locale.UK);
/**
* Converts a time (long) to text
@ -127,7 +127,7 @@ public class PeerDataWriter {
}
}
private static final DecimalFormat _numFmt = new DecimalFormat("#0", new DecimalFormatSymbols(Locale.UK));
private final DecimalFormat _numFmt = new DecimalFormat("#0", new DecimalFormatSymbols(Locale.UK));
/**
* Converts a number (double) to text

View File

@ -21,7 +21,7 @@ class HeartbeatControlPane extends JPanel {
private HeartbeatMonitorGUI _gui;
private JTabbedPane _configPane;
private final static Color WHITE = new Color(255, 255, 255);
private final static Color LIGHT_BLUE = new Color(180, 180, 255);
private final static Color LIGHT_BLUE = new Color(180, 180, 255); /* UNUSED */
private final static Color BLACK = new Color(0, 0, 0);
private Color _background = WHITE;
private Color _foreground = BLACK;

View File

@ -88,7 +88,9 @@ public class HeartbeatMonitor implements PeerPlotStateFetcher.FetchStateReceptor
_gui.stateUpdated();
}
/** store the config defining what peer tests we are monitoring (and how to render) */
/**
* store the config defining what peer tests we are monitoring (and how to render)
*/
void storeConfig() {}
/**
@ -103,6 +105,10 @@ public class HeartbeatMonitor implements PeerPlotStateFetcher.FetchStateReceptor
new HeartbeatMonitor().runMonitor();
}
/**
* Called when the config is updated
* @param config the updated config
*/
public void configUpdated(PeerPlotConfig config) {
_log.debug("Config updated, revamping the gui");
_gui.stateUpdated();

View File

@ -19,7 +19,7 @@ import net.i2p.heartbeat.PeerData;
import net.i2p.util.Log;
class JFreeChartAdapter {
private final static Log _log = new Log(JFreeChartAdapter.class);
private final static Log _log = new Log(JFreeChartAdapter.class); /* UNUSED */
private final static Color WHITE = new Color(255, 255, 255);
ChartPanel createPanel(HeartbeatMonitorState state) {
@ -45,7 +45,7 @@ class JFreeChartAdapter {
updateLines(plot, state);
}
private long getFirst(HeartbeatMonitorState state) {
private long getFirst(HeartbeatMonitorState state) { /* UNUSED */
long first = -1;
for (int i = 0; i < state.getTestCount(); i++) {
List dataPoints = state.getTest(i).getCurrentData().getDataPoints();
@ -116,6 +116,7 @@ class JFreeChartAdapter {
}
/**
* @param col the collection of xy series to add to
* @param config preferences for how to display this test
* @param lineName minimal name of the test (e.g. "jxHa.32KB.60s")
* @param data List of PeerData.EventDataPoint describing all of the events in the test
@ -144,6 +145,7 @@ class JFreeChartAdapter {
/**
* Add a data series for each average that we're configured to render
*
* @param col the collection of xy series to add to
* @param config preferences for how to display this test
* @param lineName minimal name of the test (e.g. "jxHa.32KB.60s")
* @param data List of PeerData.EventDataPoint describing all of the events in the test

View File

@ -14,14 +14,21 @@ import net.i2p.util.Log;
*
*/
class JFreeChartHeartbeatPlotPane extends HeartbeatPlotPane {
private final static Log _log = new Log(JFreeChartHeartbeatPlotPane.class);
private final static Log _log = new Log(JFreeChartHeartbeatPlotPane.class); /* UNUSED */
private ChartPanel _panel;
private JFreeChartAdapter _adapter;
/**
* Creates a JFreeChart plot pane for the given gui
* @param gui the heartbeat monitor gui
*/
public JFreeChartHeartbeatPlotPane(HeartbeatMonitorGUI gui) {
super(gui);
}
/**
* Called when the state is updated
*/
public void stateUpdated() {
if (_panel == null) {
remove(0); // remove the dummy

View File

@ -18,7 +18,7 @@ import net.i2p.util.Log;
* Configure how we want to render a particular clientConfig in the GUI
*/
class PeerPlotConfig {
private final static Log _log = new Log(PeerPlotConfig.class);
private final static Log _log = new Log(PeerPlotConfig.class); /* UNUSED */
/** where can we find the current state/data (either as a filename or a URL)? */
private String _location;
/** what test are we defining the plot data for? */
@ -170,8 +170,8 @@ class PeerPlotConfig {
Destination peer = getClientConfig().getPeer();
if (peer == null)
return "????";
else
return peer.calculateHash().toBase64().substring(0, 4);
return peer.calculateHash().toBase64().substring(0, 4);
}
/**
@ -196,8 +196,8 @@ class PeerPlotConfig {
int bytes = getClientConfig().getSendSize();
if (bytes < 1024)
return bytes + "b";
else
return bytes/1024 + "kb";
return bytes/1024 + "kb";
}
/**

View File

@ -243,6 +243,7 @@ class PeerPlotConfigPane extends JPanel implements PeerPlotConfig.UpdateListener
_minutes = minutes;
_button = button;
}
/* (non-Javadoc)
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/

View File

@ -326,7 +326,7 @@ class PeerPlotStateFetcher {
}
}
private void fakeRun() {
private void fakeRun() { /* UNUSED */
try {
Destination peer = new Destination();
Destination us = new Destination();

View File

@ -94,8 +94,8 @@ class StaticPeerData extends PeerData {
Integer i = (Integer)_averageSendTimes.get(new Integer(period));
if (i == null)
return -1;
else
return i.doubleValue();
return i.doubleValue();
}
@ -109,8 +109,8 @@ class StaticPeerData extends PeerData {
Integer i = (Integer)_averageReceiveTimes.get(new Integer(period));
if (i == null)
return -1;
else
return i.doubleValue();
return i.doubleValue();
}
/**
@ -123,8 +123,8 @@ class StaticPeerData extends PeerData {
Integer i = (Integer)_lostMessages.get(new Integer(period));
if (i == null)
return -1;
else
return i.doubleValue();
return i.doubleValue();
}
/* (non-Javadoc)

View File

@ -11,7 +11,7 @@
<mkdir dir="./build/obj" />
<javac
srcdir="./src"
debug="true"
debug="true" deprecation="on" source="1.3" target="1.3"
destdir="./build/obj"
classpath="../../../core/java/build/i2p.jar:../../ministreaming/java/build/mstreaming.jar" />
</target>

View File

@ -57,14 +57,14 @@ public class HTTPListener extends Thread {
* @return Whether this is the first proxy use, no doubt.
*/
public boolean firstProxyUse() {
// FIXME: check a config option here
if (true) return false;
if (true) return false; // FIXME: check a config option here
if (proxyUsed) {
return false;
} else {
proxyUsed = true;
return true;
}
proxyUsed = true;
return true;
}
/**

View File

@ -12,7 +12,7 @@ import net.i2p.util.Log;
*/
public class ErrorHandler {
private static final Log _log = new Log(ErrorHandler.class);
private static final Log _log = new Log(ErrorHandler.class); /* UNUSED */
/* package private */ErrorHandler() {

View File

@ -13,7 +13,7 @@ import net.i2p.util.Log;
*/
public class LocalHandler {
private static final Log _log = new Log(LocalHandler.class);
private static final Log _log = new Log(LocalHandler.class); /* UNUSED */
/* package private */LocalHandler() {
}

View File

@ -18,7 +18,7 @@ import net.i2p.util.Log;
*/
public class ProxyHandler extends EepHandler {
private static final Log _log = new Log(ErrorHandler.class);
private static final Log _log = new Log(ErrorHandler.class); /* UNUSED */
private static I2PAppContext _context = new I2PAppContext();
/* package private */ProxyHandler(ErrorHandler eh) {

View File

@ -12,7 +12,7 @@ import net.i2p.util.Log;
*/
public class RootHandler {
private static final Log _log = new Log(RootHandler.class);
private static final Log _log = new Log(RootHandler.class); /* UNUSED */
private RootHandler() {
errorHandler = new ErrorHandler();
@ -60,26 +60,24 @@ public class RootHandler {
url = url.substring(7);
pos = url.indexOf("/");
String host;
String rest;
if (pos == -1) {
errorHandler.handle(req, httpl, out, "No host end in URL");
return;
}
host = url.substring(0, pos);
url = url.substring(pos);
if ("i2p".equals(host) || "i2p.i2p".equals(host)) {
// normal request; go on below...
} else if (host.endsWith(".i2p")) {
// "old" service request, send a redirect...
out.write(("HTTP/1.1 302 Moved\r\nLocation: " + "http://i2p.i2p/" + host + url + "\r\n\r\n").getBytes("ISO-8859-1"));
return;
} else {
host = url.substring(0, pos);
url = url.substring(pos);
if ("i2p".equals(host) || "i2p.i2p".equals(host)) {
// normal request; go on below...
} else if (host.endsWith(".i2p")) {
// "old" service request, send a redirect...
out
.write(("HTTP/1.1 302 Moved\r\nLocation: " + "http://i2p.i2p/" + host + url + "\r\n\r\n")
.getBytes("ISO-8859-1"));
return;
} else {
// this is for proxying to the real web
proxyHandler.handle(req, httpl, out /*, true */);
return;
}
// this is for proxying to the real web
proxyHandler.handle(req, httpl, out /*, true */);
return;
}
}
if (url.equals("/")) { // main page

View File

@ -11,7 +11,7 @@
<mkdir dir="./build/obj" />
<javac
srcdir="./src"
debug="true"
debug="true" deprecation="on" source="1.3" target="1.3"
destdir="./build/obj"
classpath="../../../core/java/build/i2p.jar:../../ministreaming/java/build/mstreaming.jar" />
</target>

View File

@ -17,6 +17,9 @@ class BufferLogger implements Logging {
private ByteArrayOutputStream _baos;
private boolean _ignore;
/**
* Constructs a buffered logger.
*/
public BufferLogger() {
_baos = new ByteArrayOutputStream(512);
_ignore = false;
@ -24,11 +27,15 @@ class BufferLogger implements Logging {
private final static String EMPTY = "";
/**
* Retrieves the buffer
* @return the buffer
*/
public String getBuffer() {
if (_ignore)
return EMPTY;
else
return new String(_baos.toByteArray());
return new String(_baos.toByteArray());
}
/**

View File

@ -46,6 +46,7 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
@ -69,6 +70,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
private I2PAppContext _context;
private static long __tunnelId = 0;
private long _tunnelId;
private Properties _clientOptions;
public static final int PACKET_DELAY = 100;
@ -104,6 +106,9 @@ public class I2PTunnel implements Logging, EventDispatcher {
_tunnelId = ++__tunnelId;
_log = _context.logManager().getLog(I2PTunnel.class);
_event = new EventDispatcherImpl();
_clientOptions = new Properties();
_clientOptions.putAll(System.getProperties());
addConnectionEventListener(lsnr);
boolean gui = true;
boolean checkRunByE = true;
@ -167,6 +172,8 @@ public class I2PTunnel implements Logging, EventDispatcher {
}
}
public Properties getClientOptions() { return _clientOptions; }
private void addtask(I2PTunnelTask tsk) {
tsk.setTunnel(this);
if (tsk.isOpen()) {
@ -197,6 +204,8 @@ public class I2PTunnel implements Logging, EventDispatcher {
if ("help".equals(cmdname)) {
runHelp(l);
} else if ("clientoptions".equals(cmdname)) {
runClientOptions(args, l);
} else if ("server".equals(cmdname)) {
runServer(args, l);
} else if ("textserver".equals(cmdname)) {
@ -262,6 +271,29 @@ public class I2PTunnel implements Logging, EventDispatcher {
l.log("list");
l.log("run <commandfile>");
}
/**
* Configure the extra I2CP options to use in any subsequent I2CP sessions.
* Usage: "clientoptions[ key=value]*" .
*
* Sets the event "clientoptions_onResult" = "ok" after completion.
*
* @param args each args[i] is a key=value pair to add to the options
* @param l logger to receive events and output
*/
public void runClientOptions(String args[], Logging l) {
_clientOptions.clear();
if (args != null) {
for (int i = 0; i < args.length; i++) {
int index = args[i].indexOf('=');
if (index <= 0) continue;
String key = args[i].substring(0, index);
String val = args[i].substring(index+1);
_clientOptions.setProperty(key, val);
}
}
notifyEvent("clientoptions_onResult", "ok");
}
/**
* Run the server pointing at the host and port specified using the private i2p
@ -304,7 +336,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
notifyEvent("serverTaskId", new Integer(-1));
return;
}
I2PTunnelServer serv = new I2PTunnelServer(serverHost, portNum, privKeyFile, args[2], l, (EventDispatcher) this);
I2PTunnelServer serv = new I2PTunnelServer(serverHost, portNum, privKeyFile, args[2], l, (EventDispatcher) this, this);
serv.setReadTimeout(readTimeout);
serv.startRunning();
addtask(serv);
@ -350,7 +382,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
return;
}
I2PTunnelServer serv = new I2PTunnelServer(serverHost, portNum, args[2], l, (EventDispatcher) this);
I2PTunnelServer serv = new I2PTunnelServer(serverHost, portNum, args[2], l, (EventDispatcher) this, this);
serv.setReadTimeout(readTimeout);
serv.startRunning();
addtask(serv);
@ -386,7 +418,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
return;
}
I2PTunnelTask task;
task = new I2PTunnelClient(port, args[1], l, ownDest, (EventDispatcher) this);
task = new I2PTunnelClient(port, args[1], l, ownDest, (EventDispatcher) this, this);
addtask(task);
notifyEvent("clientTaskId", new Integer(task.getId()));
} else {
@ -423,7 +455,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
proxy = args[1];
}
I2PTunnelTask task;
task = new I2PTunnelHTTPClient(port, l, ownDest, proxy, (EventDispatcher) this);
task = new I2PTunnelHTTPClient(port, l, ownDest, proxy, (EventDispatcher) this, this);
addtask(task);
notifyEvent("httpclientTaskId", new Integer(task.getId()));
} else {
@ -460,7 +492,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
}
I2PTunnelTask task;
task = new I2PSOCKSTunnel(port, l, ownDest, (EventDispatcher) this);
task = new I2PSOCKSTunnel(port, l, ownDest, (EventDispatcher) this, this);
addtask(task);
notifyEvent("sockstunnelTaskId", new Integer(task.getId()));
} else {
@ -779,7 +811,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
if (allargs.length() != 0) {
I2PTunnelTask task;
// pings always use the main destination
task = new I2Ping(allargs, l, false, (EventDispatcher) this);
task = new I2Ping(allargs, l, false, (EventDispatcher) this, this);
addtask(task);
notifyEvent("pingTaskId", new Integer(task.getId()));
} else {

View File

@ -19,8 +19,8 @@ public class I2PTunnelClient extends I2PTunnelClientBase {
private static final long DEFAULT_READ_TIMEOUT = 5*60*1000; // -1
protected long readTimeout = DEFAULT_READ_TIMEOUT;
public I2PTunnelClient(int localPort, String destination, Logging l, boolean ownDest, EventDispatcher notifyThis) {
super(localPort, ownDest, l, notifyThis, "SynSender");
public I2PTunnelClient(int localPort, String destination, Logging l, boolean ownDest, EventDispatcher notifyThis, I2PTunnel tunnel) {
super(localPort, ownDest, l, notifyThis, "SynSender", tunnel);
if (waitEventValue("openBaseClientResult").equals("error")) {
notifyEvent("openClientResult", "error");

View File

@ -60,8 +60,8 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
// I2PTunnelClientBase(localPort, ownDest, l, (EventDispatcher)null);
//}
public I2PTunnelClientBase(int localPort, boolean ownDest, Logging l, EventDispatcher notifyThis, String handlerName) {
super(localPort + " (uninitialized)", notifyThis);
public I2PTunnelClientBase(int localPort, boolean ownDest, Logging l, EventDispatcher notifyThis, String handlerName, I2PTunnel tunnel) {
super(localPort + " (uninitialized)", notifyThis, tunnel);
_clientId = ++__clientId;
this.localPort = localPort;
this.l = l;
@ -103,17 +103,28 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
private static I2PSocketManager socketManager;
protected static synchronized I2PSocketManager getSocketManager() {
protected synchronized I2PSocketManager getSocketManager() {
return getSocketManager(getTunnel());
}
protected static synchronized I2PSocketManager getSocketManager(I2PTunnel tunnel) {
if (socketManager == null) {
socketManager = buildSocketManager();
socketManager = buildSocketManager(tunnel);
}
return socketManager;
}
protected static I2PSocketManager buildSocketManager() {
protected I2PSocketManager buildSocketManager() {
return buildSocketManager(getTunnel());
}
protected static I2PSocketManager buildSocketManager(I2PTunnel tunnel) {
Properties props = new Properties();
props.putAll(System.getProperties());
return I2PSocketManagerFactory.createManager(I2PTunnel.host, Integer.parseInt(I2PTunnel.port), props);
if (tunnel == null)
props.putAll(System.getProperties());
else
props.putAll(tunnel.getClientOptions());
I2PSocketManager sockManager = I2PSocketManagerFactory.createManager(I2PTunnel.host, Integer.parseInt(I2PTunnel.port), props);
sockManager.setName("Client");
return sockManager;
}
public final int getLocalPort() {

View File

@ -45,7 +45,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
private String wwwProxy;
private final static byte[] ERR_REQUEST_DENIED =
("HTTP/1.1 404 Not Found\r\n"+
("HTTP/1.1 403 Access Denied\r\n"+
"Content-Type: text/html; charset=iso-8859-1\r\n"+
"Cache-control: no-cache\r\n"+
"\r\n"+
@ -54,20 +54,20 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
.getBytes();
private final static byte[] ERR_DESTINATION_UNKNOWN =
("HTTP/1.1 404 Not Found\r\n"+
("HTTP/1.1 503 Service Unavailable\r\n"+
"Content-Type: text/html; charset=iso-8859-1\r\n"+
"Cache-control: no-cache\r\n"+
"\r\n"+
"<html><body><H1>I2P ERROR: NOT FOUND</H1>"+
"That Desitination was not found. Perhaps you pasted in the wrong "+
"BASE64 I2P Destination or the link you are following is bad. "+
"The host (or the WWW proxy, if you're using one) could also be "+
"temporarily offline. You may want to <b>retry</b>. "+
"<html><body><H1>I2P ERROR: DESTINATION NOT FOUND</H1>"+
"That I2P Desitination was not found. Perhaps you pasted in the "+
"wrong BASE64 I2P Destination or the link you are following is "+
"bad. The host (or the WWW proxy, if you're using one) could also "+
"be temporarily offline. You may want to <b>retry</b>. "+
"Could not find the following Destination:<BR><BR>")
.getBytes();
private final static byte[] ERR_TIMEOUT =
("HTTP/1.1 404 Not Found\r\n"+
("HTTP/1.1 504 Gateway Timeout\r\n"+
"Content-Type: text/html; charset=iso-8859-1\r\n"+
"Cache-control: no-cache\r\n\r\n"+
"<html><body><H1>I2P ERROR: TIMEOUT</H1>"+
@ -81,8 +81,8 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
/** used to assign unique IDs to the threads / clients. no logic or functionality */
private static volatile long __clientId = 0;
public I2PTunnelHTTPClient(int localPort, Logging l, boolean ownDest, String wwwProxy, EventDispatcher notifyThis) {
super(localPort, ownDest, l, notifyThis, "HTTPHandler " + (++__clientId));
public I2PTunnelHTTPClient(int localPort, Logging l, boolean ownDest, String wwwProxy, EventDispatcher notifyThis, I2PTunnel tunnel) {
super(localPort, ownDest, l, notifyThis, "HTTPHandler " + (++__clientId), tunnel);
if (waitEventValue("openBaseClientResult").equals("error")) {
notifyEvent("openHTTPClientResult", "error");
@ -127,7 +127,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
if (pos == -1) break;
method = line.substring(0, pos);
String request = line.substring(pos + 1);
if (request.startsWith("/") && System.getProperty("i2ptunnel.noproxy") != null) {
if (request.startsWith("/") && getTunnel().getClientOptions().getProperty("i2ptunnel.noproxy") != null) {
request = "http://i2p" + request;
}
pos = request.indexOf("//");
@ -226,6 +226,8 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
Destination dest = I2PTunnel.destFromName(destination);
if (dest == null) {
l.log("Could not resolve " + destination + ".");
if (_log.shouldLog(Log.WARN))
_log.warn("Unable to resolve " + destination + " (proxy? " + usingWWWProxy + ", request: " + targetRequest);
writeErrorMessage(ERR_DESTINATION_UNKNOWN, out, targetRequest, usingWWWProxy, destination);
s.close();
return;
@ -365,6 +367,9 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
private void handleHTTPClientException(Exception ex, OutputStream out, String targetRequest,
boolean usingWWWProxy, String wwwProxy) {
if (_log.shouldLog(Log.WARN))
_log.warn("Error sending to " + wwwProxy + " (proxy? " + usingWWWProxy + ", request: " + targetRequest, ex);
if (out != null) {
try {
writeErrorMessage(ERR_DESTINATION_UNKNOWN, out, targetRequest, usingWWWProxy, wwwProxy);

View File

@ -14,8 +14,8 @@ import java.net.SocketException;
import java.util.Iterator;
import java.util.Properties;
import net.i2p.I2PException;
import net.i2p.I2PAppContext;
import net.i2p.I2PException;
import net.i2p.client.I2PClient;
import net.i2p.client.I2PClientFactory;
import net.i2p.client.streaming.I2PServerSocket;
@ -45,15 +45,15 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
/** default timeout to 3 minutes - override if desired */
private long readTimeout = DEFAULT_READ_TIMEOUT;
public I2PTunnelServer(InetAddress host, int port, String privData, Logging l, EventDispatcher notifyThis) {
super(host + ":" + port + " <- " + privData, notifyThis);
public I2PTunnelServer(InetAddress host, int port, String privData, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel) {
super(host + ":" + port + " <- " + privData, notifyThis, tunnel);
ByteArrayInputStream bais = new ByteArrayInputStream(Base64.decode(privData));
init(host, port, bais, privData, l);
}
public I2PTunnelServer(InetAddress host, int port, File privkey, String privkeyname, Logging l,
EventDispatcher notifyThis) {
super(host + ":" + port + " <- " + privkeyname, notifyThis);
EventDispatcher notifyThis, I2PTunnel tunnel) {
super(host + ":" + port + " <- " + privkeyname, notifyThis, tunnel);
try {
init(host, port, new FileInputStream(privkey), privkeyname, l);
} catch (IOException ioe) {
@ -62,8 +62,8 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
}
}
public I2PTunnelServer(InetAddress host, int port, InputStream privData, String privkeyname, Logging l, EventDispatcher notifyThis) {
super(host + ":" + port + " <- " + privkeyname, notifyThis);
public I2PTunnelServer(InetAddress host, int port, InputStream privData, String privkeyname, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel) {
super(host + ":" + port + " <- " + privkeyname, notifyThis, tunnel);
init(host, port, privData, privkeyname, l);
}
@ -73,12 +73,13 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
this.remotePort = port;
I2PClient client = I2PClientFactory.createClient();
Properties props = new Properties();
props.putAll(System.getProperties());
props.putAll(getTunnel().getClientOptions());
synchronized (slock) {
sockMgr = I2PSocketManagerFactory.createManager(privData, I2PTunnel.host, Integer.parseInt(I2PTunnel.port),
props);
}
sockMgr.setName("Server");
l.log("Ready!");
notifyEvent("openServerResult", "ok");
open = true;

View File

@ -26,16 +26,19 @@ public abstract class I2PTunnelTask implements EventDispatcher {
// I2PTunnelTask(name, (EventDispatcher)null);
//}
protected I2PTunnelTask(String name, EventDispatcher notifyThis) {
protected I2PTunnelTask(String name, EventDispatcher notifyThis, I2PTunnel tunnel) {
attachEventDispatcher(notifyThis);
this.name = name;
this.id = -1;
this.tunnel = tunnel;
}
/** for apps that use multiple I2PTunnel instances */
public void setTunnel(I2PTunnel pTunnel) {
tunnel = pTunnel;
}
public I2PTunnel getTunnel() { return tunnel; }
public int getId() {
return this.id;

View File

@ -47,15 +47,15 @@ public class I2Ping extends I2PTunnelTask implements Runnable {
// I2Ping(cmd, l, (EventDispatcher)null);
//}
public I2Ping(String cmd, Logging l, boolean ownDest, EventDispatcher notifyThis) {
super("I2Ping [" + cmd + "]", notifyThis);
public I2Ping(String cmd, Logging l, boolean ownDest, EventDispatcher notifyThis, I2PTunnel tunnel) {
super("I2Ping [" + cmd + "]", notifyThis, tunnel);
this.l = l;
command = cmd;
synchronized (slock) {
if (ownDest) {
sockMgr = I2PTunnelClient.buildSocketManager();
sockMgr = I2PTunnelClient.buildSocketManager(tunnel);
} else {
sockMgr = I2PTunnelClient.getSocketManager();
sockMgr = I2PTunnelClient.getSocketManager(tunnel);
}
}
Thread t = new I2PThread(this);

View File

@ -10,6 +10,7 @@ import java.net.Socket;
import net.i2p.client.streaming.I2PSocket;
import net.i2p.data.Destination;
import net.i2p.i2ptunnel.I2PTunnel;
import net.i2p.i2ptunnel.I2PTunnelClientBase;
import net.i2p.i2ptunnel.I2PTunnelRunner;
import net.i2p.i2ptunnel.Logging;
@ -26,8 +27,8 @@ public class I2PSOCKSTunnel extends I2PTunnelClientBase {
// I2PSOCKSTunnel(localPort, l, ownDest, (EventDispatcher)null);
//}
public I2PSOCKSTunnel(int localPort, Logging l, boolean ownDest, EventDispatcher notifyThis) {
super(localPort, ownDest, l, notifyThis, "SOCKSHandler");
public I2PSOCKSTunnel(int localPort, Logging l, boolean ownDest, EventDispatcher notifyThis, I2PTunnel tunnel) {
super(localPort, ownDest, l, notifyThis, "SOCKSHandler", tunnel);
if (waitEventValue("openBaseClientResult").equals("error")) {
notifyEvent("openSOCKSTunnelResult", "error");

View File

@ -8,7 +8,7 @@
<target name="compile">
<mkdir dir="./build" />
<mkdir dir="./build/obj" />
<javac srcdir="./src" debug="true" destdir="./build/obj" classpath="../../../core/java/build/i2p.jar" />
<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/mstreaming.jar" basedir="./build/obj" includes="**/*.class" />

View File

@ -1,31 +1,71 @@
package net.i2p.client.streaming;
/** Like a StringBuffer, but for bytes */
/**
* Like a StringBuffer, but for bytes. This class is not internally synchronized,
* so care should be taken when using in a multithreaded environment.
*
*/
public class ByteCollector {
byte[] contents;
int size;
private static final int INITIAL_CAPACITY = 1024;
private static final int SHORT_CAPACITY = 80;
/**
* New collector with the default initial capacity
*
*/
public ByteCollector() {
contents = new byte[1024];
this(INITIAL_CAPACITY);
}
/**
* New collector with an initial capacity as specified
*
*/
public ByteCollector(int capacity) {
contents = new byte[capacity];
size = 0;
}
/**
* New collector containing the specified bytes
*
*/
public ByteCollector(byte[] b) {
this();
append(b);
}
/**
* New collector with the specified byte
*
*/
public ByteCollector(byte b) {
this();
append(b);
}
/**
* Add a new byte to the collector (extending the buffer if necessary)
*
* @param b byte to add
* @return this object
*/
public ByteCollector append(byte b) {
ensureCapacity(size + 1);
contents[size++] = b;
return this;
}
/**
* Add new bytes to the collector (extending the buffer if necessary)
*
* @param b bytes to add
* @return this object
*/
public ByteCollector append(byte[] b) {
ensureCapacity(size + b.length);
System.arraycopy(b, 0, contents, size, b.length);
@ -33,10 +73,25 @@ public class ByteCollector {
return this;
}
/**
* Add new bytes to the collector (extending the buffer if necessary)
*
* @param b byte array to add from
* @param len number of bytes in the array to add
* @return this object
*/
public ByteCollector append(byte[] b, int len) {
return append(b, 0, len);
}
/**
* Add new bytes to the collector (extending the buffer if necessary)
*
* @param b byte array to add from
* @param off offset into the array to begin adding from
* @param len number of bytes in the array to add
* @return this object
*/
public ByteCollector append(byte[] b, int off, int len) {
ensureCapacity(size + len);
System.arraycopy(b, off, contents, size, len);
@ -44,17 +99,36 @@ public class ByteCollector {
return this;
}
/**
* Add the contents of the byte collector to the current collector (extending the buffer if necessary)
*
* @param bc collector to copy
* @return this object
*/
public ByteCollector append(ByteCollector bc) {
// optimieren?
return append(bc.toByteArray());
}
/**
* Copy the contents of the collector into a new array and return it
*
* @return new array containing a copy of the current collector's data
*/
public byte[] toByteArray() {
byte[] result = new byte[size];
System.arraycopy(contents, 0, result, 0, size);
return result;
}
/**
* Pull off the first $maxlen bytes from the collector, shifting the remaining
* bytes into the beginning of the collector's array.
*
* @param maxlen max number of bytes we want to pull from the collector (we will get
* less if the collector doesnt have that many bytes yet)
* @return copy of the bytes pulled from the collector
*/
public byte[] startToByteArray(int maxlen) {
if (size < maxlen) {
byte[] res = toByteArray();
@ -69,10 +143,22 @@ public class ByteCollector {
}
}
/**
* How many bytes are available for retrieval?
*
* @return number of bytes
*/
public int getCurrentSize() {
return size;
}
/**
* Make sure we have sufficient storage space.
*
* @param cap minimum number of bytes that the buffer should contain
* @return true if the the collector was expanded to meet the minimum,
* false if it was already large enough
*/
public boolean ensureCapacity(int cap) {
if (contents.length < cap) {
int l = contents.length;
@ -87,20 +173,46 @@ public class ByteCollector {
return false;
}
/**
* Does the collector have meaningful data or is it empty?
*
* @return true if it has no data
*/
public boolean isEmpty() {
return size == 0;
}
/**
* Search through the collector for the first occurrence of the sequence of
* bytes contained within the specified collector
*
* @param bc bytes that will be searched for
* @return index into the current collector, or -1 if it isn't found
*/
public int indexOf(ByteCollector bc) {
// optimieren?
return indexOf(bc.toByteArray());
}
/**
* Search through the collector for the first occurrence of the specified
* byte
*
* @param b byte that will be searched for
* @return index into the current collector, or -1 if it isn't found
*/
public int indexOf(byte b) {
// optimieren?
return indexOf(new byte[] { b});
}
/**
* Search through the collector for the first occurrence of the sequence of
* bytes
*
* @param ba bytes that will be searched for
* @return index into the current collector, or -1 if it isn't found
*/
public int indexOf(byte[] ba) {
loop: for (int i = 0; i < size - ba.length + 1; i++) {
for (int j = 0; j < ba.length; j++) {
@ -111,15 +223,28 @@ public class ByteCollector {
return -1;
}
/**
* Empty the collector. This does not affect its capacity.
*
*/
public void clear() {
size = 0;
}
/**
* Empty the collector and reduce its capacity.
*
*/
public void clearAndShorten() {
size = 0;
contents = new byte[80];
contents = new byte[SHORT_CAPACITY];
}
/**
* Render the bytes as a string
*
* @return the, uh, string
*/
public String toString() {
return new String(toByteArray());
}
@ -132,6 +257,12 @@ public class ByteCollector {
return h;
}
/**
* Compare the collectors.
*
* @return true if and only if both are the same size and the
* byte arrays they contain are equal.
*/
public boolean equals(Object o) {
if (o instanceof ByteCollector) {
ByteCollector by = (ByteCollector) o;
@ -145,7 +276,13 @@ public class ByteCollector {
}
}
public byte removeFirst() {
/**
* Remove the first byte from the collector, shifting its contents accordingly.
*
* @return byte removed
* @throws IllegalArgumentException if the collector is empty
*/
public byte removeFirst() throws IllegalArgumentException {
byte bb = contents[0];
if (size == 0) throw new IllegalArgumentException("ByteCollector is empty");
if (size > 1)

View File

@ -5,12 +5,14 @@ import java.io.InputStream;
import java.io.InterruptedIOException;
import java.io.OutputStream;
import net.i2p.I2PAppContext;
import net.i2p.I2PException;
import net.i2p.client.I2PSessionException;
import net.i2p.data.Destination;
import net.i2p.util.I2PThread;
import net.i2p.util.Log;
/**
* Initial stub implementation for the socket
*
@ -35,6 +37,9 @@ class I2PSocketImpl implements I2PSocket {
private static long __socketId = 0;
private long _bytesRead = 0;
private long _bytesWritten = 0;
private long _createdOn;
private long _closedOn;
private long _remoteIdSetTime;
private Object flagLock = new Object();
/**
@ -73,6 +78,9 @@ class I2PSocketImpl implements I2PSocket {
out = new I2POutputStream(pin);
new I2PSocketRunner(pin);
this.localID = localID;
_createdOn = I2PAppContext.getGlobalContext().clock().now();
_remoteIdSetTime = -1;
_closedOn = -1;
}
/**
@ -89,6 +97,7 @@ class I2PSocketImpl implements I2PSocket {
public void setRemoteID(String id) {
synchronized (remoteIDWaiter) {
remoteID = id;
_remoteIdSetTime = System.currentTimeMillis();
remoteIDWaiter.notifyAll();
}
}
@ -123,16 +132,23 @@ class I2PSocketImpl implements I2PSocket {
long dieAfter = System.currentTimeMillis() + maxWait;
synchronized (remoteIDWaiter) {
if (wait) {
try {
if (maxWait >= 0)
remoteIDWaiter.wait(maxWait);
else
remoteIDWaiter.wait();
} catch (InterruptedException ex) {
if (remoteID == null) {
try {
if (maxWait >= 0)
remoteIDWaiter.wait(maxWait);
else
remoteIDWaiter.wait();
} catch (InterruptedException ex) {
}
}
if ((maxWait >= 0) && (System.currentTimeMillis() >= dieAfter))
throw new InterruptedIOException("Timed out waiting for remote ID");
long now = System.currentTimeMillis();
if ((maxWait >= 0) && (now >= dieAfter)) {
long waitedExcess = now - dieAfter;
throw new InterruptedIOException("Timed out waiting for remote ID (waited " + waitedExcess
+ "ms too long [" + maxWait + "ms, remId " + remoteID
+ ", remId set " + (now-_remoteIdSetTime) + "ms ago])");
}
if (_log.shouldLog(Log.DEBUG))
_log.debug("TIMING: RemoteID set to "
@ -199,8 +215,10 @@ class I2PSocketImpl implements I2PSocket {
*/
public void close() throws IOException {
synchronized (flagLock) {
_log.debug("Closing connection");
if (_log.shouldLog(Log.DEBUG))
_log.debug("Closing connection");
closed = true;
_closedOn = I2PAppContext.getGlobalContext().clock().now();
}
out.close();
in.notifyClosed();
@ -214,6 +232,7 @@ class I2PSocketImpl implements I2PSocket {
closed = true;
closed2 = true;
sendClose = false;
_closedOn = I2PAppContext.getGlobalContext().clock().now();
}
out.close();
in.notifyClosed();
@ -248,6 +267,12 @@ class I2PSocketImpl implements I2PSocket {
_socketErrorListener.errorOccurred();
}
public long getBytesSent() { return _bytesWritten; }
public long getBytesReceived() { return _bytesRead; }
public long getCreatedOn() { return _createdOn; }
public long getClosedOn() { return _closedOn; }
private String getPrefix() { return "[" + _socketId + "]: "; }
//--------------------------------------------------
@ -273,12 +298,15 @@ class I2PSocketImpl implements I2PSocket {
throw new RuntimeException("Incorrect read() result");
}
public synchronized int read(byte[] b, int off, int len) throws IOException {
public int read(byte[] b, int off, int len) throws IOException {
if (_log.shouldLog(Log.DEBUG))
_log.debug(getPrefix() + "Read called: " + this.hashCode());
_log.debug(getPrefix() + "Read called for " + len + " bytes (avail=" + bc.getCurrentSize() + "): " + this.hashCode());
if (len == 0) return 0;
long dieAfter = System.currentTimeMillis() + readTimeout;
byte[] read = bc.startToByteArray(len);
byte[] read = null;
synchronized (bc) {
read = bc.startToByteArray(len);
}
boolean timedOut = false;
while (read.length == 0) {
@ -290,10 +318,12 @@ class I2PSocketImpl implements I2PSocket {
}
}
try {
if (readTimeout >= 0) {
wait(readTimeout);
} else {
wait();
synchronized (I2PSocketImpl.I2PInputStream.this) {
if (readTimeout >= 0) {
wait(readTimeout);
} else {
wait();
}
}
} catch (InterruptedException ex) {}
@ -302,7 +332,9 @@ class I2PSocketImpl implements I2PSocket {
throw new InterruptedIOException(getPrefix() + "Timeout reading from I2PSocket (" + readTimeout + " msecs)");
}
read = bc.startToByteArray(len);
synchronized (bc) {
read = bc.startToByteArray(len);
}
}
if (read.length > len) throw new RuntimeException("BUG");
System.arraycopy(read, 0, b, off, read.length);
@ -320,22 +352,30 @@ class I2PSocketImpl implements I2PSocket {
}
public int available() {
return bc.getCurrentSize();
synchronized (bc) {
return bc.getCurrentSize();
}
}
public void queueData(byte[] data) {
queueData(data, 0, data.length);
}
public synchronized void queueData(byte[] data, int off, int len) {
public void queueData(byte[] data, int off, int len) {
if (_log.shouldLog(Log.DEBUG))
_log.debug(getPrefix() + "Insert " + len + " bytes into queue: " + hashCode());
bc.append(data, off, len);
notifyAll();
synchronized (bc) {
bc.append(data, off, len);
}
synchronized (I2PInputStream.this) {
I2PInputStream.this.notifyAll();
}
}
public synchronized void notifyClosed() {
I2PInputStream.this.notifyAll();
public void notifyClosed() {
synchronized (I2PInputStream.this) {
I2PInputStream.this.notifyAll();
}
}
public void close() throws IOException {

View File

@ -15,6 +15,7 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import net.i2p.I2PAppContext;
import net.i2p.I2PException;
import net.i2p.client.I2PSession;
import net.i2p.client.I2PSessionException;
@ -24,6 +25,7 @@ import net.i2p.data.DataFormatException;
import net.i2p.data.Destination;
import net.i2p.util.Log;
/**
* Centralize the coordination and multiplexing of the local client's streaming.
* There should be one I2PSocketManager for each I2PSession, and if an application
@ -33,7 +35,8 @@ import net.i2p.util.Log;
*
*/
public class I2PSocketManager implements I2PSessionListener {
private final static Log _log = new Log(I2PSocketManager.class);
private I2PAppContext _context;
private Log _log;
private I2PSession _session;
private I2PServerSocketImpl _serverSocket = null;
private Object lock = new Object(); // for locking socket lists
@ -41,6 +44,8 @@ public class I2PSocketManager implements I2PSessionListener {
private HashMap _inSockets;
private I2PSocketOptions _defaultOptions;
private long _acceptTimeout;
private String _name;
private static int __managerId = 0;
public static final short ACK = 0x51;
public static final short CLOSE_OUT = 0x52;
@ -57,10 +62,24 @@ public class I2PSocketManager implements I2PSessionListener {
private static final long ACCEPT_TIMEOUT_DEFAULT = 5*1000;
public I2PSocketManager() {
this("SocketManager " + (++__managerId));
}
public I2PSocketManager(String name) {
_name = name;
_session = null;
_inSockets = new HashMap(16);
_outSockets = new HashMap(16);
_acceptTimeout = ACCEPT_TIMEOUT_DEFAULT;
_context = I2PAppContext.getGlobalContext();
_log = _context.logManager().getLog(I2PSocketManager.class);
_context.statManager().createRateStat("streaming.lifetime", "How long before the socket is closed?", "streaming", new long[] { 10*60*1000, 60*60*1000, 24*60*60*1000 });
_context.statManager().createRateStat("streaming.sent", "How many bytes are sent in the stream?", "streaming", new long[] { 10*60*1000, 60*60*1000, 24*60*60*1000 });
_context.statManager().createRateStat("streaming.received", "How many bytes are received in the stream?", "streaming", new long[] { 10*60*1000, 60*60*1000, 24*60*60*1000 });
_context.statManager().createRateStat("streaming.transferBalance", "How many streams send more than they receive (positive means more sent, negative means more received)?", "streaming", new long[] { 10*60*1000, 60*60*1000, 24*60*60*1000 });
_context.statManager().createRateStat("streaming.synNoAck", "How many times have we sent a SYN but not received an ACK?", "streaming", new long[] { 10*60*1000, 60*60*1000, 24*60*60*1000 });
_context.statManager().createRateStat("streaming.ackSendFailed", "How many times have we tried to send an ACK to a SYN and failed?", "streaming", new long[] { 10*60*1000, 60*60*1000, 24*60*60*1000 });
_context.statManager().createRateStat("streaming.nackSent", "How many times have we refused a SYN with a NACK?", "streaming", new long[] { 10*60*1000, 60*60*1000, 24*60*60*1000 });
_context.statManager().createRateStat("streaming.nackReceived", "How many times have we received a NACK to our SYN?", "streaming", new long[] { 10*60*1000, 60*60*1000, 24*60*60*1000 });
}
public I2PSession getSession() {
@ -82,12 +101,12 @@ public class I2PSocketManager implements I2PSessionListener {
public long getAcceptTimeout() { return _acceptTimeout; }
public void disconnected(I2PSession session) {
_log.info("Disconnected from the session");
_log.info(getName() + ": Disconnected from the session");
destroySocketManager();
}
public void errorOccurred(I2PSession session, String message, Throwable error) {
_log.error("Error occurred: [" + message + "]", error);
_log.error(getName() + ": Error occurred: [" + message + "]", error);
}
public void messageAvailable(I2PSession session, int msgId, long size) {
@ -95,11 +114,11 @@ public class I2PSocketManager implements I2PSessionListener {
I2PSocketImpl s;
byte msg[] = session.receiveMessage(msgId);
if (msg.length == 1 && msg[0] == -1) {
_log.debug("Ping received");
_log.debug(getName() + ": Ping received");
return;
}
if (msg.length < 4) {
_log.error("==== packet too short ====");
_log.error(getName() + ": ==== packet too short ====");
return;
}
int type = msg[0] & 0xff;
@ -107,7 +126,7 @@ public class I2PSocketManager implements I2PSessionListener {
byte[] payload = new byte[msg.length - 4];
System.arraycopy(msg, 4, payload, 0, payload.length);
if (_log.shouldLog(Log.DEBUG))
_log.debug("Message read: type = [" + Integer.toHexString(type)
_log.debug(getName() + ": Message read: type = [" + Integer.toHexString(type)
+ "] id = [" + getReadableForm(id)
+ "] payload length: [" + payload.length + "]");
switch (type) {
@ -136,9 +155,9 @@ public class I2PSocketManager implements I2PSessionListener {
return;
}
} catch (I2PException ise) {
_log.error("Error processing", ise);
_log.error(getName() + ": Error processing", ise);
} catch (IllegalStateException ise) {
_log.debug("Error processing", ise);
_log.debug(getName() + ": Error processing", ise);
}
}
@ -150,30 +169,45 @@ public class I2PSocketManager implements I2PSessionListener {
*
*/
private void ackAvailable(String id, byte payload[]) {
long begin = _context.clock().now();
I2PSocketImpl s = null;
synchronized (lock) {
s = (I2PSocketImpl) _outSockets.get(id);
}
if (s == null) {
_log.warn("No socket responsible for ACK packet");
_log.warn(getName() + ": No socket responsible for ACK packet");
return;
}
long socketRetrieved = _context.clock().now();
String remoteId = null;
remoteId = s.getRemoteID(false);
if ( (payload.length == 3) && (remoteId == null) ) {
String newID = toString(payload);
long beforeSetRemId = _context.clock().now();
s.setRemoteID(newID);
if (_log.shouldLog(Log.DEBUG)) {
_log.debug(getName() + ": ackAvailable - socket retrieval took "
+ (socketRetrieved-begin) + "ms, getRemoteId took "
+ (beforeSetRemId-socketRetrieved) + "ms, setRemoteId took "
+ (_context.clock().now()-beforeSetRemId) + "ms");
}
return;
} else {
// (payload.length != 3 || getRemoteId != null)
if (_log.shouldLog(Log.WARN)) {
if (payload.length != 3)
_log.warn("Ack packet had " + payload.length + " bytes");
_log.warn(getName() + ": Ack packet had " + payload.length + " bytes");
else
_log.warn("Remote ID already exists? " + remoteId);
_log.warn(getName() + ": Remote ID already exists? " + remoteId);
}
if (_log.shouldLog(Log.DEBUG)) {
_log.debug(getName() + ": invalid ack - socket retrieval took "
+ (socketRetrieved-begin) + "ms, overall took "
+ (_context.clock().now()-begin) + "ms");
}
return;
}
@ -189,11 +223,11 @@ public class I2PSocketManager implements I2PSessionListener {
s = (I2PSocketImpl) _outSockets.get(id);
}
_log.debug("*Disconnect outgoing for socket " + s);
_log.debug(getName() + ": *Disconnect outgoing for socket " + s);
try {
if (s != null) {
if (payload.length > 0) {
_log.debug("Disconnect packet had "
_log.debug(getName() + ": Disconnect packet had "
+ payload.length + " bytes");
}
if (s.getRemoteID(false) == null) {
@ -207,7 +241,7 @@ public class I2PSocketManager implements I2PSessionListener {
}
return;
} catch (Exception t) {
_log.error("Ignoring error on disconnect for socket " + s, t);
_log.error(getName() + ": Ignoring error on disconnect for socket " + s, t);
}
}
@ -225,12 +259,12 @@ public class I2PSocketManager implements I2PSessionListener {
// packet send outgoing
if (_log.shouldLog(Log.DEBUG))
_log.debug("*Packet send outgoing [" + payload.length + "] for socket " + s);
_log.debug(getName() + ": *Packet send outgoing [" + payload.length + "] for socket " + s);
if (s != null) {
s.queueData(payload);
return;
} else {
_log.error("Null socket with data available");
_log.error(getName() + ": Null socket with data available");
throw new IllegalStateException("Null socket with data available");
}
}
@ -258,7 +292,7 @@ public class I2PSocketManager implements I2PSessionListener {
s.setRemoteID(id);
}
}
_log.debug("*Syn! for socket " + s);
_log.debug(getName() + ": *Syn! for socket " + s);
if (!acceptConnections) {
// The app did not instantiate an I2PServerSocket
@ -268,10 +302,11 @@ public class I2PSocketManager implements I2PSessionListener {
replySentOk = _session.sendMessage(d, packet);
}
if (!replySentOk) {
_log.error("Error sending close to " + d.calculateHash().toBase64()
_log.error(getName() + ": Error sending close to " + d.calculateHash().toBase64()
+ " in response to a new con message",
new Exception("Failed creation"));
}
_context.statManager().addRateData("streaming.nackSent", 1, 1);
return;
}
@ -282,10 +317,11 @@ public class I2PSocketManager implements I2PSessionListener {
replySentOk = _session.sendMessage(d, packet);
if (!replySentOk) {
if (_log.shouldLog(Log.WARN))
_log.warn("Error sending reply to " + d.calculateHash().toBase64()
_log.warn(getName() + ": Error sending reply to " + d.calculateHash().toBase64()
+ " in response to a new con message for socket " + s,
new Exception("Failed creation"));
s.internalClose();
_context.statManager().addRateData("streaming.ackSendFailed", 1, 1);
}
} else {
// timed out or serverSocket closed
@ -293,9 +329,10 @@ public class I2PSocketManager implements I2PSessionListener {
packet[0] = CLOSE_OUT;
boolean nackSent = session.sendMessage(d, packet);
if (!nackSent) {
_log.warn("Error sending NACK for session creation for socket " + s);
_log.warn(getName() + ": Error sending NACK for session creation for socket " + s);
}
s.internalClose();
_context.statManager().addRateData("streaming,nackSent", 1, 1);
}
return;
}
@ -314,7 +351,7 @@ public class I2PSocketManager implements I2PSessionListener {
}
}
_log.debug("*Disconnect incoming for socket " + s);
_log.debug(getName() + ": *Disconnect incoming for socket " + s);
try {
if (payload.length == 0 && s != null) {
@ -322,13 +359,13 @@ public class I2PSocketManager implements I2PSessionListener {
return;
} else {
if ( (payload.length > 0) && (_log.shouldLog(Log.ERROR)) )
_log.error("Disconnect packet had " + payload.length + " bytes");
_log.error(getName() + ": Disconnect packet had " + payload.length + " bytes");
if (s != null)
s.internalClose();
return;
}
} catch (Exception t) {
_log.error("Ignoring error on disconnect", t);
_log.error(getName() + ": Ignoring error on disconnect", t);
return;
}
}
@ -346,13 +383,13 @@ public class I2PSocketManager implements I2PSessionListener {
}
if (_log.shouldLog(Log.DEBUG))
_log.debug("*Packet send incoming [" + payload.length + "] for socket " + s);
_log.debug(getName() + ": *Packet send incoming [" + payload.length + "] for socket " + s);
if (s != null) {
s.queueData(payload);
return;
} else {
_log.info("Null socket with data available");
_log.info(getName() + ": Null socket with data available");
throw new IllegalStateException("Null socket with data available");
}
}
@ -362,7 +399,7 @@ public class I2PSocketManager implements I2PSessionListener {
*
*/
private void handleUnknown(int type, String id, byte payload[]) {
_log.error("\n\n=============== Unknown packet! " + "============"
_log.error(getName() + ": \n\n=============== Unknown packet! " + "============"
+ "\nType: " + (int) type
+ "\nID: " + getReadableForm(id)
+ "\nBase64'ed Data: " + Base64.encode(payload)
@ -376,7 +413,7 @@ public class I2PSocketManager implements I2PSessionListener {
}
public void reportAbuse(I2PSession session, int severity) {
_log.error("Abuse reported [" + severity + "]");
_log.error(getName() + ": Abuse reported [" + severity + "]");
}
public void setDefaultOptions(I2PSocketOptions options) {
@ -424,31 +461,37 @@ public class I2PSocketManager implements I2PSessionListener {
boolean sent = false;
sent = _session.sendMessage(peer, packet);
if (!sent) {
_log.info("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);
synchronized (lock) {
_outSockets.remove(s.getLocalID());
}
_context.statManager().addRateData("streaming.synNoAck", 1, 1);
throw new I2PException("Error sending through I2P network");
}
remoteID = s.getRemoteID(true, options.getConnectTimeout());
if (remoteID == null)
if (remoteID == null) {
_context.statManager().addRateData("streaming.nackReceived", 1, 1);
throw new ConnectException("Connection refused by peer for socket " + s);
if ("".equals(remoteID))
}
if ("".equals(remoteID)) {
_context.statManager().addRateData("streaming.synNoAck", 1, 1);
throw new NoRouteToHostException("Unable to reach peer for socket " + s);
}
if (_log.shouldLog(Log.DEBUG))
_log.debug("TIMING: s given out for remoteID "
_log.debug(getName() + ": TIMING: s given out for remoteID "
+ getReadableForm(remoteID) + " for socket " + s);
return s;
} catch (InterruptedIOException ioe) {
if (_log.shouldLog(Log.ERROR))
_log.error("Timeout waiting for ack from syn for id "
_log.error(getName() + ": Timeout waiting for ack from syn for id "
+ getReadableForm(lcID) + " for socket " + s, ioe);
synchronized (lock) {
_outSockets.remove(s.getLocalID());
}
s.internalClose();
_context.statManager().addRateData("streaming.synNoAck", 1, 1);
throw new InterruptedIOException("Timeout waiting for ack");
} catch (ConnectException ex) {
s.internalClose();
@ -458,7 +501,7 @@ public class I2PSocketManager implements I2PSessionListener {
throw ex;
} catch (IOException ex) {
if (_log.shouldLog(Log.ERROR))
_log.error("Error sending syn on id " + getReadableForm(lcID) + " for socket " + s, ex);
_log.error(getName() + ": Error sending syn on id " + getReadableForm(lcID) + " for socket " + s, ex);
synchronized (lock) {
_outSockets.remove(s.getLocalID());
}
@ -466,7 +509,7 @@ public class I2PSocketManager implements I2PSessionListener {
throw new I2PException("Unhandled IOException occurred");
} catch (I2PException ex) {
if (_log.shouldLog(Log.INFO))
_log.info("Error sending syn on id " + getReadableForm(lcID) + " for socket " + s, ex);
_log.info(getName() + ": Error sending syn on id " + getReadableForm(lcID) + " for socket " + s, ex);
synchronized (lock) {
_outSockets.remove(s.getLocalID());
}
@ -474,7 +517,7 @@ public class I2PSocketManager implements I2PSessionListener {
throw ex;
} catch (Exception e) {
s.internalClose();
_log.error("Unhandled error connecting", e);
_log.error(getName() + ": Unhandled error connecting", e);
throw new ConnectException("Unhandled error connecting: " + e.getMessage());
}
}
@ -515,7 +558,7 @@ public class I2PSocketManager implements I2PSessionListener {
id = (String)iter.next();
sock = (I2PSocketImpl)_inSockets.get(id);
if (_log.shouldLog(Log.DEBUG))
_log.debug("Closing inSocket \""
_log.debug(getName() + ": Closing inSocket \""
+ getReadableForm(sock.getLocalID()) + "\"");
sock.internalClose();
}
@ -525,13 +568,13 @@ public class I2PSocketManager implements I2PSessionListener {
id = (String)iter.next();
sock = (I2PSocketImpl)_outSockets.get(id);
if (_log.shouldLog(Log.DEBUG))
_log.debug("Closing outSocket \""
_log.debug(getName() + ": Closing outSocket \""
+ getReadableForm(sock.getLocalID()) + "\"");
sock.internalClose();
}
}
_log.debug("Waiting for all open sockets to really close...");
_log.debug(getName() + ": Waiting for all open sockets to really close...");
synchronized (lock) {
while ((_inSockets.size() != 0) || (_outSockets.size() != 0)) {
try {
@ -541,11 +584,11 @@ public class I2PSocketManager implements I2PSessionListener {
}
try {
_log.debug("Destroying I2P session...");
_log.debug(getName() + ": Destroying I2P session...");
_session.destroySession();
_log.debug("I2P session destroyed");
_log.debug(getName() + ": I2P session destroyed");
} catch (I2PSessionException e) {
_log.error("Error destroying I2P session", e);
_log.error(getName() + ": Error destroying I2P session", e);
}
}
@ -571,21 +614,47 @@ public class I2PSocketManager implements I2PSessionListener {
try {
return _session.sendMessage(peer, new byte[] { (byte) CHAFF});
} catch (I2PException ex) {
_log.error("I2PException:", ex);
_log.error(getName() + ": I2PException:", ex);
return false;
}
}
public void removeSocket(I2PSocketImpl sock) {
synchronized (lock) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Removing socket \"" + getReadableForm(sock.getLocalID()) + "\" [" + sock + "]");
_inSockets.remove(sock.getLocalID());
_outSockets.remove(sock.getLocalID());
lock.notify();
}
long now = _context.clock().now();
long lifetime = now - sock.getCreatedOn();
long timeSinceClose = now - sock.getClosedOn();
long sent = sock.getBytesSent();
long recv = sock.getBytesReceived();
if (_log.shouldLog(Log.DEBUG)) {
_log.debug(getName() + ": Removing socket \"" + getReadableForm(sock.getLocalID()) + "\" [" + sock
+ ", send: " + sent + ", recv: " + recv
+ ", lifetime: " + lifetime + "ms, time since close: " + timeSinceClose + ")]",
new Exception("removeSocket called"));
}
_context.statManager().addRateData("streaming.lifetime", lifetime, lifetime);
_context.statManager().addRateData("streaming.sent", sent, lifetime);
_context.statManager().addRateData("streaming.received", recv, lifetime);
if (sent > recv) {
_context.statManager().addRateData("streaming.transferBalance", 1, lifetime);
} else if (recv > sent) {
_context.statManager().addRateData("streaming.transferBalance", -1, lifetime);
} else {
// noop
}
}
public String getName() { return _name; }
public void setName(String name) { _name = name; }
public static String getReadableForm(String id) {
if (id == null) return "(null)";
if (id.length() != 3) return "Bogus";

View File

@ -9,13 +9,13 @@
<target name="compile">
<mkdir dir="./build" />
<mkdir dir="./build/obj" />
<javac srcdir="./src" debug="true" destdir="./build/obj" includes="net/**/*.java" excludes="net/i2p/netmonitor/gui/**" classpath="../../../core/java/build/i2p.jar" />
<javac srcdir="./src" debug="true" source="1.3" target="1.3" deprecation="on" destdir="./build/obj" includes="net/**/*.java" excludes="net/i2p/netmonitor/gui/**" classpath="../../../core/java/build/i2p.jar" />
</target>
<target name="compileGUI" depends="builddep">
<mkdir dir="./build" />
<mkdir dir="./build/obj" />
<javac debug="true" destdir="./build/obj">
<javac debug="true" source="1.3" target="1.3" deprecation="on" destdir="./build/obj">
<src path="src/" />
<classpath path="../../../core/java/build/i2p.jar" />
<classpath path="../../jfreechart/jfreechart-0.9.17/lib/jcommon-0.9.2.jar" />

View File

@ -18,7 +18,7 @@ import net.i2p.util.Log;
* Main driver for the app that harvests data about the performance of the network,
* building summaries for each peer that change over time. <p />
*
* Usage: <code>NetMonitor [configFilename]</code> <p />
* Usage: <code>NetMonitor [configFilename] [--routers filename[,filename]*]</code> <p />
*
*
*
@ -41,15 +41,20 @@ public class NetMonitor {
private int _exportDelay;
private String _exportDir;
private String _netDbDir;
private String _explicitRouters;
private int _summaryDurationHours;
private boolean _isRunning;
private Map _peerSummaries;
public NetMonitor() {
this(CONFIG_LOCATION_DEFAULT);
this(CONFIG_LOCATION_DEFAULT, null);
}
public NetMonitor(String configLocation) {
this(configLocation, null);
}
public NetMonitor(String configLocation, String explicitFilenames) {
_configLocation = configLocation;
_explicitRouters = explicitFilenames;
_peerSummaries = new HashMap(32);
loadConfig();
}
@ -120,6 +125,8 @@ public class NetMonitor {
public int getSummaryDurationHours() { return _summaryDurationHours; }
/** where should we read the data from? */
public String getNetDbDir() { return _netDbDir; }
/** if specified, contains a set of filenames we want to harvest routerInfo data from */
public String getExplicitRouters() { return _explicitRouters; }
/**
* what peers are we keeping track of?
*
@ -203,10 +210,30 @@ public class NetMonitor {
}
}
/**
* main driver for the netMonitor. the usage is:
* <code>NetMonitor [configFilename] [--routers filename[,filename]*]</code>
*/
public static final void main(String args[]) {
if (args.length == 1)
new NetMonitor(args[0]).startMonitor();
else
new NetMonitor(CONFIG_LOCATION_DEFAULT).startMonitor();
String cfgLocation = CONFIG_LOCATION_DEFAULT;
String explicitFilenames = null;
switch (args.length) {
case 0:
break;
case 1:
cfgLocation = args[0];
break;
case 2:
explicitFilenames = args[1];
break;
case 3:
cfgLocation = args[0];
explicitFilenames = args[2];
break;
default:
System.err.println("Usage: NetMonitor [configFilename] [--routers filename[,filename]*]");
return;
}
new NetMonitor(cfgLocation, explicitFilenames).startMonitor();
}
}
}

View File

@ -7,6 +7,7 @@ import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import net.i2p.data.DataFormatException;
import net.i2p.data.RouterInfo;
@ -128,12 +129,35 @@ class NetMonitorRunner implements Runnable {
* @return list of File objects pointing at the routers around
*/
private File[] listRouters() {
File dbDir = new File(_monitor.getNetDbDir());
File files[] = dbDir.listFiles(new FilenameFilter() {
public boolean accept(File f, String name) {
return name.startsWith("routerInfo-");
}
});
if (_monitor.getExplicitRouters() != null) {
return listRoutersExplicit();
} else {
File dbDir = new File(_monitor.getNetDbDir());
File files[] = dbDir.listFiles(new FilenameFilter() {
public boolean accept(File f, String name) {
return name.startsWith("routerInfo-");
}
});
return files;
}
}
/**
* Get a list of router files that were explicitly specified by the netMonitor
*
*/
private File[] listRoutersExplicit() {
StringTokenizer tok = new StringTokenizer(_monitor.getExplicitRouters().trim(), ",");
List rv = new ArrayList();
while (tok.hasMoreTokens()) {
String name = tok.nextToken();
File cur = new File(name);
if (cur.exists())
rv.add(cur);
}
File files[] = new File[rv.size()];
for (int i = 0; i < rv.size(); i++)
files[i] = (File)rv.get(i);
return files;
}
@ -146,4 +170,4 @@ class NetMonitorRunner implements Runnable {
Thread.sleep(_monitor.getHarvestDelay());
} catch (InterruptedException ie) {}
}
}
}

View File

@ -8,7 +8,7 @@
<target name="compile">
<mkdir dir="./build" />
<mkdir dir="./build/obj" />
<javac srcdir="./src" debug="true" destdir="./build/obj" classpath="../../../core/java/build/i2p.jar:lib/javax.servlet.jar" />
<javac srcdir="./src" debug="true" source="1.3" target="1.3" deprecation="on" destdir="./build/obj" classpath="../../../core/java/build/i2p.jar:lib/javax.servlet.jar" />
</target>
<target name="jar" depends="compile">
<war destfile="./build/phttprelay.war" webxml="web.xml">

27
apps/sam/c/LICENSE Normal file
View File

@ -0,0 +1,27 @@
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

@ -0,0 +1,65 @@
#
# This Makefile is compatible with GNU Make and should work on Cygwin
#
#
# Your operating environment
#
OS = CYGWIN
#
# Directories
#
INCDIR = inc
LIBDIR = lib
OBJDIR = obj
SRCDIR = src
#
# Programs
#
AR = ar
CC = gcc
#
# Flags
#
CFLAGS = -g -march=i486 -O2 -pipe -std=c99 -Wall
CFLAGS += -DOS=$(OS)
CFLAGS += -I$(INCDIR)
#
# Object files
#
OBJS = $(OBJDIR)/sam.o \
$(OBJDIR)/snprintf.o \
$(OBJDIR)/strl.o
#
# Build rules
#
all: depend libsam
depend:
$(CC) $(CFLAGS) -MM $(SRCDIR)/*.c > .depend
$(OBJDIR)/%.o: $(SRCDIR)/%.c
$(CC) $(CFLAGS) -o $@ -c $<
libsam: $(OBJS)
$(AR) rcs $(LIBDIR)/libsam.a $(OBJS)
#
# Cleanup rules
#
clean:
-rm -f $(LIBDIR)/libsam.a $(OBJDIR)/* .depend
tidy: clean

View File

@ -0,0 +1,63 @@
#
# This Makefile is compatible with GNU Make (gmake) and should work on FreeBSD
#
#
# Your operating system
#
OS = FREEBSD
#
# Directories
#
INCDIR = inc
LIBDIR = lib
OBJDIR = obj
SRCDIR = src
#
# Programs
#
AR = ar
CC = gcc
#
# Flags
#
CFLAGS = -g -O2 -pipe -std=c99 -Wall
CFLAGS += -DOS=$(OS)
CFLAGS += -I$(INCDIR)
#
# Object files
#
OBJS = $(OBJDIR)/sam.o
#
# Build rules
#
all: depend libsam
depend:
$(CC) $(CFLAGS) -MM $(SRCDIR)/*.c > .depend
$(OBJDIR)/%.o: $(SRCDIR)/%.c
$(CC) $(CFLAGS) -o $@ -c $<
libsam: $(OBJS)
$(AR) rcs $(LIBDIR)/libsam.a $(OBJS)
#
# Cleanup rules
#
clean:
-rm -f $(LIBDIR)/libsam.a $(OBJDIR)/* .depend
tidy: clean

64
apps/sam/c/Makefile.linux Normal file
View File

@ -0,0 +1,64 @@
#
# This Makefile is compatible with GNU Make and should work on Linux (generic)
#
#
# Your operating system
#
OS = LINUX
#
# Directories
#
INCDIR = inc
LIBDIR = lib
OBJDIR = obj
SRCDIR = src
#
# Programs
#
AR = ar
CC = gcc
#
# Flags
#
CFLAGS = -g -O2 -pipe -std=c99 -Wall
CFLAGS += -DOS=$(OS)
CFLAGS += -I$(INCDIR)
#
# Object files
#
OBJS = $(OBJDIR)/sam.o \
$(OBJDIR)/strl.o
#
# Build rules
#
all: depend libsam
depend:
$(CC) $(CFLAGS) -MM $(SRCDIR)/*.c > .depend
$(OBJDIR)/%.o: $(SRCDIR)/%.c
$(CC) $(CFLAGS) -o $@ -c $<
libsam: $(OBJS)
$(AR) rcs $(LIBDIR)/libsam.a $(OBJS)
#
# Cleanup rules
#
clean:
-rm -f $(LIBDIR)/libsam.a $(OBJDIR)/* .depend
tidy: clean

64
apps/sam/c/Makefile.mingw Normal file
View File

@ -0,0 +1,64 @@
#
# This Makefile is compatible with GNU Make and should work on Windows (MingW)
#
#
# Your operating system
#
OS = MINGW
#
# Directories
#
INCDIR = inc
LIBDIR = lib
OBJDIR = obj
SRCDIR = src
#
# Programs
#
AR = C:\Dev-Cpp\bin\ar
CC = C:\Dev-Cpp\bin\gcc
#
# Flags
#
CFLAGS = -g -march=i486 -O2 -pipe -std=c99 -Wall
CFLAGS += -DOS=$(OS)
CFLAGS += -I$(INCDIR)
#
# Object files
#
OBJS = $(OBJDIR)/sam.o \
$(OBJDIR)/strl.o
#
# Build rules
#
all: depend libsam
depend:
$(CC) $(CFLAGS) -MM $(SRCDIR)/*.c > .depend
$(OBJDIR)/%.o: $(SRCDIR)/%.c
$(CC) $(CFLAGS) -o $@ -c $<
libsam: $(OBJS)
$(AR) rcs $(LIBDIR)/libsam.a $(OBJS)
#
# Cleanup rules
#
clean:
-rm -f $(LIBDIR)/libsam.a $(OBJDIR)/* .depend
tidy: clean

View File

@ -0,0 +1,7 @@
If you would like to make a donation to the author of this library, you can use
the following methods:
* E-Gold account number 1043280
* Paypal email mpc@innographx.com
If you want to use some other method, just ask.

View File

@ -0,0 +1,27 @@
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.

9
apps/sam/c/doc/todo.txt Normal file
View File

@ -0,0 +1,9 @@
I need to do these things:
* SAM raw support
* Write an instruction manual
Anyone can help with these things:
* Fix the example dgram-client.c
* Compile on as many platforms as possible

View File

@ -0,0 +1,32 @@
v1.20 2004-07-11
* Ported to FreeBSD (Makefile.freebsd)
* Full winsock compatibility - all Windows functions now return appropriate
error strings
v1.15 2004-06-23
* Added a new example program, warhammer-dgram (use with caution)
* Fixed some fatal bugs in datagram handling
* Added another error return type named SAM_TOO_BIG - some functions now
return samerr_t instead of bool
v1.10 2004-06-16
* Changed sam_strerror() to work the same as the standard library strerror()
* Ported to native MS Windows (uses the Mingw development environment)
* Fixed a probable bug in the Cygwin port
v1.05 2004-06-09
* Added an example datagram client/server program in the examples directory
* sam_read_buffer() now returns bool true if it read anything
* Added repliable datagram support - sam_connect() now has another argument
* Replaced strstr() with the more appropriate strncmp() in many places
* Fixed a parsing error for STREAM CLOSED
* Removed the old sam_naming_lookup() and renamed sam_naming_lookup_async()
to sam_naming_lookup() to replace it
* Fixed a bug in sam_stream_close() where a '\n' was not being sent after
the SAM command
* Fixed a bug where the stream ID was being improperly incremented in
sam_stream_connect()
* Added generic Linux Makefile for non-Debian distributions
v1.00 2004-06-02
* First public release

View File

@ -0,0 +1,42 @@
#
# This Makefile is compatible with GNU Make
#
#
# Programs
#
CC = gcc
#
# Flags
#
CFLAGS = -g -O2 -pipe -std=c99 -Wall
CFLAGS += -I../inc -L../lib
LIBS = -lsam
#
# Build rules
#
all: dgram-client dgram-server warhammer-dgram
dgram-client:
$(CC) $(CFLAGS) -o dgram-client.o -c dgram-client.c
$(CC) $(CFLAGS) -o dgram-client dgram-client.o $(LIBS)
dgram-server:
$(CC) $(CFLAGS) -o dgram-server.o -c dgram-server.c
$(CC) $(CFLAGS) -o dgram-server dgram-server.o $(LIBS)
warhammer-dgram:
$(CC) $(CFLAGS) -o warhammer-dgram.o -c warhammer-dgram.c
$(CC) $(CFLAGS) -o warhammer-dgram warhammer-dgram.o $(LIBS)
#
# Cleanup rules
#
clean:
-rm -f *.o *.exe dgram-client dgram-server warhammer-dgram

View File

@ -0,0 +1,42 @@
#
# This Makefile is compatible with GNU Make and has Winsock linking
#
#
# Programs
#
CC = C:\Dev-Cpp\bin\gcc
#
# Flags
#
CFLAGS = -g -O2 -pipe -std=c99 -Wall
CFLAGS += -I../inc -L../lib
LIBS = -lsam -lwsock32
#
# Build rules
#
all: dgram-client dgram-server warhammer-dgram
dgram-client:
$(CC) $(CFLAGS) -o dgram-client.o -c dgram-client.c
$(CC) $(CFLAGS) -o dgram-client dgram-client.o $(LIBS)
dgram-server:
$(CC) $(CFLAGS) -o dgram-server.o -c dgram-server.c
$(CC) $(CFLAGS) -o dgram-server dgram-server.o $(LIBS)
warhammer-dgram:
$(CC) $(CFLAGS) -o warhammer-dgram.o -c warhammer-dgram.c
$(CC) $(CFLAGS) -o warhammer-dgram warhammer-dgram.o $(LIBS)
#
# Cleanup rules
#
clean:
-rm -f *.o *.exe dgram-client dgram-server warhammer-dgram

View File

@ -0,0 +1,130 @@
/*
* 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 <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sam.h"
static void dgramback(sam_pubkey_t dest, void *data, size_t size);
static void diedback(void);
static void logback(char *s);
static void namingback(char *name, sam_pubkey_t pubkey, samerr_t result);
/*
* This is an extremely simple echo client which shows you how LibSAM
* datagrams work. We lookup the name 'dgram-server' then send some data to
* him. If everything works, we should get the same data back.
*/
/*
* NOTE!!!!!!!! This is currently broken!
*/
int main(int argc, char* argv[])
{
samerr_t rc;
/* Hook up the callback functions */
sam_dgramback = &dgramback;
sam_diedback = &diedback;
sam_logback = &logback;
sam_namingback = &namingback;
/* Connect to the SAM server -- you can use either an IP or DNS name */
rc = sam_connect("localhost", 7656, "dgram-client", SAM_DGRAM, 0);
if (rc != SAM_OK) {
fprintf(stderr, "SAM connection failed: %s\n", sam_strerror(rc));
exit(1);
}
/*
* This is equivalent to doing a DNS lookup on the normal internet. Note
* that the dgram-server must already be running for this to work.
* When the lookup completes, we send them some data (see namingback()).
*/
sam_naming_lookup("dgram-server");
/*
* Wait for something to happen, then invoke the appropriate callback
*/
while (true)
sam_read_buffer();
return 0;
}
/*
* When we receive some data, print it out to the screen
*/
static void dgramback(sam_pubkey_t dest, void *data, size_t size)
{
printf("Datagram received: %s\n", (char *)data);
free(data);
}
/*
* This is called whenever the SAM connection fails (like if the I2P router is
* shut down)
*/
static void diedback(void)
{
fprintf(stderr, "Lost SAM connection!\n");
exit(1);
}
/*
* The logging callback prints any logging messages from LibSAM
*/
static void logback(char *s)
{
fprintf(stderr, "LibSAM: %s\n", s);
}
/*
* When a name is resolved, send data to that destination address
*/
static void namingback(char *name, sam_pubkey_t pubkey, samerr_t result)
{
char *data = "Hello, invisible world!";
printf("I got %s's base 64 destination, so now I will send him some " \
"data...\n", name);
sam_dgram_send(pubkey, data, strlen(data));
/*
* ^^^ An extra NUL is appended to the data by LibSAM, so it is not
* necessary to send trailing NULs over the wire for strings. This doesn't
* cause problems with binary data, because the NUL isn't included in `size'
* in sam_dgramback().
* That is why we use strlen(data) instead of strlen(data) + 1.
*/
puts("Datagram sent");
}

View File

@ -0,0 +1,108 @@
/*
* 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 <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "sam.h"
static void dgramback(sam_pubkey_t dest, void *data, size_t size);
static void diedback(void);
static void logback(char *s);
static void namingback(char *name, sam_pubkey_t pubkey, samerr_t result);
/*
* This is an extremely simple echo server which shows you how LibSAM
* datagrams work. We echo back every datagram that is sent to us.
*/
int main(int argc, char* argv[])
{
samerr_t rc;
/* Hook up the callback functions */
sam_dgramback = &dgramback;
sam_diedback = &diedback;
sam_logback = &logback;
sam_namingback = &namingback;
/* Connect to the SAM server -- you can use either an IP or DNS name */
rc = sam_connect("127.0.0.1", 7656, "dgram-server", SAM_DGRAM, 0);
if (rc != SAM_OK) {
fprintf(stderr, "SAM connection failed: %s\n", sam_strerror(rc));
exit(1);
}
/*
* At this point we just keep polling the buffer, which causes the
* appropriate callbacks to be called whenever something happens
*/
while (true)
sam_read_buffer();
return 0;
}
/*
* When we receive some data, we just ECHO the exact same data back to them
*/
static void dgramback(sam_pubkey_t dest, void *data, size_t size)
{
puts("Echoing datagram");
sam_dgram_send(dest, data, size);
free(data);
}
/*
* This is called whenever the SAM connection fails (like if the I2P router is
* shut down)
*/
static void diedback(void)
{
fprintf(stderr, "Lost SAM connection!\n");
exit(1);
}
/*
* The logging callback prints any logging messages from LibSAM
*/
static void logback(char *s)
{
fprintf(stderr, "LibSAM: %s\n", s);
}
/*
* Not used, but the function has to be in the program anyway
*/
static void namingback(char *name, sam_pubkey_t pubkey, samerr_t result)
{
assert(false); /* we don't do any naming lookups in this program */
}

View File

@ -0,0 +1,123 @@
/*
* 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.
*/
/*
* Warhammer-dgram: a simple denial of service tool which uses datagrams, and
* illustrates how LibSAM works.
* Use only with the utmost courtesy.
*/
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sam.h"
static void dgramback(sam_pubkey_t dest, void *data, size_t size);
static void diedback(void);
static void logback(char *s);
static void namingback(char *name, sam_pubkey_t pubkey, samerr_t result);
bool gotdest = false;
sam_pubkey_t dest;
int main(int argc, char* argv[])
{
if (argc != 2) {
fprintf(stderr, "Syntax: %s <b64dest|name>\n", argv[0]);
return 1;
}
sam_dgramback = &dgramback;
sam_diedback = &diedback;
sam_logback = &logback;
sam_namingback = &namingback;
/* a tunnel length of 2 is the default - adjust to your preference vv */
samerr_t rc = sam_connect("localhost", 7656, "TRANSIENT", SAM_DGRAM, 2);
if (rc != SAM_OK) {
fprintf(stderr, "SAM connection failed: %s\n", sam_strerror(rc));
exit(1);
}
if (strlen(argv[1]) == 516) {
memcpy(dest, argv[1], SAM_PUBKEY_LEN);
gotdest = true;
}
else
sam_naming_lookup(argv[1]);
while (!gotdest)
sam_read_buffer();
char data[SAM_DGRAM_PAYLOAD_MAX];
memset(data, '#', SAM_DGRAM_PAYLOAD_MAX);
size_t sentbytes = 0;
while (true) {
rc = sam_dgram_send(dest, data, SAM_DGRAM_PAYLOAD_MAX);
if (rc != SAM_OK) {
fprintf(stderr, "sam_dgram_send() failed: %s\n", sam_strerror(rc));
return 1;
}
sentbytes += SAM_DGRAM_PAYLOAD_MAX;
printf("Bombs away! (%u kbytes sent so far)\n", sentbytes / 1024);
sam_read_buffer();
}
return 0;
}
static void dgramback(sam_pubkey_t dest, void *data, size_t size)
{
puts("Received a datagram (ignored)");
free(data);
}
static void diedback(void)
{
fprintf(stderr, "Lost SAM connection!\n");
exit(1);
}
static void logback(char *s)
{
fprintf(stderr, "LibSAM: %s\n", s);
}
static void namingback(char *name, sam_pubkey_t pubkey, samerr_t result)
{
if (result != SAM_OK) {
fprintf(stderr, "Naming lookup failed: %s\n", sam_strerror(result));
exit(1);
}
memcpy(dest, pubkey, SAM_PUBKEY_LEN);
gotdest = true;
}

144
apps/sam/c/inc/platform.h Normal file
View File

@ -0,0 +1,144 @@
/*
* 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_H
#define PLATFORM_H
/*
* Operating system
*/
#define FREEBSD 0 // FreeBSD
#define MINGW 1 // Windows native (Mingw)
#define LINUX 2 // Linux
#define CYGWIN 3 // Cygwin
#if OS == MINGW
#define INET_ADDRSTRLEN 16
#define NO_GETHOSTBYNAME2
#define NO_INET_ATON /* implies NO_INET_PTON */
#define NO_INET_NTOP
#define NO_SSIZE_T
#define NO_STRL
#define NO_Z_FORMAT
#define WINSOCK
#endif
#if OS == LINUX
#define NO_GETHOSTBYNAME2
#define NO_STRL
#define NO_Z_FORMAT
#endif
#if OS == CYGWIN
#define FAST32_IS_LONG
#define INET_ADDRSTRLEN 16
#define NO_GETHOSTBYNAME2
#define NO_INET_NTOP
#define NO_INET_PTON
#define NO_SNPRINTF
#define NO_STRL
#define NO_VSNPRINTF
#define NO_Z_FORMAT
#endif
/*
* Standard C99 includes - if your compiler doesn't have these, it's time to
* upgrade
*/
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
/*
* System includes
*/
#ifdef WINSOCK
#include <winsock.h>
#else
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/types.h>
#endif
#include <assert.h>
#include <errno.h>
#ifndef WINSOCK
#include <netdb.h>
#endif
#if defined NO_SNPRINTF || defined NO_VSNPRINTF
#include "snprintf.h"
#endif
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef NO_STRL
#include "strl.h"
#endif
#ifdef WINSOCK
#include <windows.h>
#else
#include <unistd.h>
#endif
/*
* Platform-dependent variable types
*/
#ifdef WINSOCK
typedef SOCKET socket_t;
#else
typedef int socket_t;
#endif
#ifdef NO_SSIZE_T
typedef signed long ssize_t;
#endif
/*
* Prints out the file name, line number, and function name before log message
*/
#define SAMLOG(format, ...) sam_log("%s:%d:%s: " \
format, __FILE__, __LINE__, __func__, __VA_ARGS__)
/*
* This is the same as above, except that it doesn't accept any va args
*/
#define SAMLOGS(str) sam_log("%s:%d:%s: " str, __FILE__, __LINE__, __func__)
/*
* Set this to '1' if you want the raw SAM commands to be printed on stdout
* (useful for debugging). Otherwise, set it to '0'.
*/
#define SAM_WIRETAP 0
#if SAM_WIRETAP
#include <ctype.h>
#endif
#endif /* PLATFORM_H */

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