root/branches/binary/server/doc/binary-protocol-plan-v2.txt @ 760

Revision 760, 27.0 kB (checked in by dsallings, 21 months ago)

Alignment fixes for 64-bit processors.

Line 
1
2
3
4Network Working Group                                   Aaron Stone, Ed.
5Internet-Draft                                           Six Apart, Ltd.
6Intended status: Informational                         December 14, 2007
7Expires: June 16, 2008
8
9
10                        Memcache Binary Protocol
11                     draft-stone-memcache-binary-01
12
13Status of this Memo
14
15   This document is an Internet-Draft and is NOT offered in accordance
16   with Section 10 of RFC 2026, and the author does not provide the IETF
17   with any rights other than to publish as an Internet-Draft.
18
19   Internet-Drafts are working documents of the Internet Engineering
20   Task Force (IETF), its areas, and its working groups.  Note that
21   other groups may also distribute working documents as Internet-
22   Drafts.
23
24   Internet-Drafts are draft documents valid for a maximum of six months
25   and may be updated, replaced, or obsoleted by other documents at any
26   time.  It is inappropriate to use Internet-Drafts as reference
27   material or to cite them other than as "work in progress."
28
29   The list of current Internet-Drafts can be accessed at
30   http://www.ietf.org/ietf/1id-abstracts.txt.
31
32   The list of Internet-Draft Shadow Directories can be accessed at
33   http://www.ietf.org/shadow.html.
34
35   This Internet-Draft will expire on June 16, 2008.
36
37Abstract
38
39   This memo explains the memcache binary protocol for informational
40   purposes.
41
42   Memcache is a high performance key-value cache.  It is intentionally
43   a dumb cache, optimized for speed only.  Applications using memcache
44   do not rely on it for data -- a persistent database with guaranteed
45   reliability is strongly recommended -- but applications can run much
46   faster when cached data is available in memcache.
47
48
49
50
51
52
53
54
55Aaron Stone               Expires June 16, 2008                 [Page 1]
56
57Internet-Draft          Memcache Binary Protocol           December 2007
58
59
60Table of Contents
61
62   1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  3
63     1.1.  Conventions Used In This Document  . . . . . . . . . . . .  3
64   2.  Packet Structure . . . . . . . . . . . . . . . . . . . . . . .  3
65   3.  Defined Values . . . . . . . . . . . . . . . . . . . . . . . .  5
66     3.1.  Magic Byte . . . . . . . . . . . . . . . . . . . . . . . .  5
67     3.2.  Response Status  . . . . . . . . . . . . . . . . . . . . .  5
68     3.3.  Command Opcodes  . . . . . . . . . . . . . . . . . . . . .  5
69     3.4.  Data Types . . . . . . . . . . . . . . . . . . . . . . . .  6
70   4.  Commands . . . . . . . . . . . . . . . . . . . . . . . . . . .  6
71     4.1.  Get, Get Quietly . . . . . . . . . . . . . . . . . . . . .  6
72     4.2.  Delete . . . . . . . . . . . . . . . . . . . . . . . . . .  7
73     4.3.  Set, Add, Replace  . . . . . . . . . . . . . . . . . . . .  7
74     4.4.  noop . . . . . . . . . . . . . . . . . . . . . . . . . . .  8
75     4.5.  Increment, Decrement . . . . . . . . . . . . . . . . . . .  8
76   5.  Example Session  . . . . . . . . . . . . . . . . . . . . . . .  9
77   6.  Security Considerations  . . . . . . . . . . . . . . . . . . . 13
78   7.  Normative References . . . . . . . . . . . . . . . . . . . . . 13
79   Appendix A.  Acknowledgments . . . . . . . . . . . . . . . . . . . 13
80   Author's Address . . . . . . . . . . . . . . . . . . . . . . . . . 13
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111Aaron Stone               Expires June 16, 2008                 [Page 2]
112
113Internet-Draft          Memcache Binary Protocol           December 2007
114
115
1161.  Introduction
117
118   Memcache is a high performance key-value cache.  It is intentionally
119   a dumb cache, optimized for speed only.  Applications using memcache
120   do not rely on it for data -- a persistent database with guaranteed
121   reliability is strongly recommended -- but applications can run much
122   faster when cached data is available in memcache.
123
124   Memcache was originally written to make LiveJournal [LJ] go faster.
125   It now powers all of the fastest web sites that you love.
126
1271.1.  Conventions Used In This Document
128
129   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
130   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
131   document are to be interpreted as described in [KEYWORDS].
132
133
1342.  Packet Structure
135
136   General format of a packet:
137
138     Byte/     0       |       1       |       2       |       3       |
139        /              |               |               |               |
140       |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
141       +---------------+---------------+---------------+---------------+
142      0/ HEADER                                                        /
143       /                                                               /
144       /                                                               /
145       /                                                               /
146       +---------------+---------------+---------------+---------------+
147     16/ COMMAND-SPECIFIC EXTRAS (as needed)                           /
148      +/  (note length in th extras length header field)               /
149       +---------------+---------------+---------------+---------------+
150      m/ Key (as needed)                                               /
151      +/  (note length in key length header field)                     /
152       +---------------+---------------+---------------+---------------+
153      n/ Value (as needed)                                             /
154      +/  (note length is total body length header field, minus        /
155      +/   sum of the extras and key length body fields)               /
156       +---------------+---------------+---------------+---------------+
157      Total 16 bytes
158
159
160
161
162
163
164
165
166
167Aaron Stone               Expires June 16, 2008                 [Page 3]
168
169Internet-Draft          Memcache Binary Protocol           December 2007
170
171
172   Request header:
173
174     Byte/     0       |       1       |       2       |       3       |
175        /              |               |               |               |
176       |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
177       +---------------+---------------+---------------+---------------+
178      0| Magic         | Opcode        | Key length                    |
179       +---------------+---------------+---------------+---------------+
180      4| Extras length | Data type     | Reserved                      |
181       +---------------+---------------+---------------+---------------+
182      8| Total body length                                             |
183       +---------------+---------------+---------------+---------------+
184     12| Message ID                                                    |
185       +---------------+---------------+---------------+---------------+
186     Total 16 bytes
187
188   Response header:
189
190     Byte/     0       |       1       |       2       |       3       |
191        /              |               |               |               |
192       |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
193       +---------------+---------------+---------------+---------------+
194      0| Magic         | Opcode        | Status                        |
195       +---------------+---------------+---------------+---------------+
196      4| Extras length | Data type     | Reserved                      |
197       +---------------+---------------+---------------+---------------+
198      8| Total body length                                             |
199       +---------------+---------------+---------------+---------------+
200     12| Message ID                                                    |
201       +---------------+---------------+---------------+---------------+
202     Total 16 bytes
203
204   Header fields:
205   Magic               Magic number.
206   Opcode              Command code.
207   Key length          Length in bytes of the text key that follows the
208                       command extras.
209   Status              Status of the response (non-zero on error).
210   Extras length       Length in bytes of the command extras.
211   Data type           Reserved for future use (Sean is using this
212                       soon).
213   Reserved            Really reserved for future use (up for grabs).
214   Total body length   Length in bytes of extra + key + value.
215   Message ID          Will be copied back to you in the response.
216                       FIXME: Can this be used to organize [UDP]
217                       packets?
218
219
220
221
222
223Aaron Stone               Expires June 16, 2008                 [Page 4]
224
225Internet-Draft          Memcache Binary Protocol           December 2007
226
227
2283.  Defined Values
229
2303.1.  Magic Byte
231
232   0x80    Request packet for this protocol version
233   0x81    Response packet for this protocol version
234
235   Magic byte / version.  For each version of the protocol, we'll use a
236   different request/reponse value pair.  This is useful for protocol
237   analyzers to know what a packet is in isolation from which direction
238   it is moving.  Note that it is common to run a memcached instance on
239   a host that also runs an application server.  Such a host will both
240   send and receive memcache packets.
241
242   The version should hopefully correspond only to different meanings of
243   the command byte.  In an ideal world, we will not change the header
244   format.  As reserved bytes are given defined meaning, the protocol
245   version / magic byte values should be incremented.
246
247   Traffic analysis tools are encouraged to identify memcache packets
248   and provide detailed interpretation if the magic bytes are recognized
249   and otherwise to provide a generic breakdown of the packet.  Note
250   that the key and value positions can always be identified even if the
251   magic byte or command opcode are not recognized.
252
2533.2.  Response Status
254
255   Possible values of this two-byte field:
256   0x0000  No error
257   0x0081  Unknown command
258   0x0001  Key not found
259   0x0002  Key exists
260
2613.3.  Command Opcodes
262
263   Possible values of the one-byte field:
264   0x00    Get
265   0x01    Set
266   0x02    Add
267   0x03    Replace
268   0x04    Delete
269   0x05    Increment
270   0x06    Decrement
271   0x07    Quit
272
273
274
275
276
277
278
279Aaron Stone               Expires June 16, 2008                 [Page 5]
280
281Internet-Draft          Memcache Binary Protocol           December 2007
282
283
284   0x08    Flush
285   0x09    GetQ
286   0x0A    No-op
287   0x0B    Version
288
2893.4.  Data Types
290
291   Possible values of the one-byte field:
292   0x00    Raw bytes
293
294
2954.  Commands
296
2974.1.  Get, Get Quietly
298
299      MUST have extras.
300      MUST have key.
301      MUST NOT have value.
302
303   o  4 byte flags
304   o  8 byte data version check
305
306   Extra data for get/getq:
307
308     Byte/     0       |       1       |       2       |       3       |
309        /              |               |               |               |
310       |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
311       +---------------+---------------+---------------+---------------+
312      0| Data version check                                            |
313       |                                                               |
314       +---------------+---------------+---------------+---------------+
315      8| Flags                                                         |
316       +---------------+---------------+---------------+---------------+
317     Total 12 bytes
318
319   The get command gets a single key.  The getq command is both mum on
320   cache miss and quiet, holding its response until a non-quiet command
321   is issued.
322
323   You're not guaranteed a response to a getq cache hit until you send a
324   non-getq command later, which uncorks the server which bundles up IOs
325   to send to the client in one go.
326
327   Clients should implement multi-get (still important for reducing
328   network roundtrips!) as n pipelined requests, the first n-1 being
329   getq, the last being a regular get. that way you're guaranteed to get
330   a response, and you know when the server's done. you can also do the
331   naive thing and send n pipelined gets, but then you could potentially
332
333
334
335Aaron Stone               Expires June 16, 2008                 [Page 6]
336
337Internet-Draft          Memcache Binary Protocol           December 2007
338
339
340   get back a lot of "NOT_FOUND!" error code packets. alternatively, you
341   can send 'n' getqs, followed by an 'echo' or 'noop' command.
342
3434.2.  Delete
344
345      MAY have extras (FIXME: Is it OK to issue a delete without
346      extras?).
347      MUST have key.
348      MUST NOT have value.
349
350   o  4 byte expiration time
351
352   Extra data for delete:
353
354     Byte/     0       |       1       |       2       |       3       |
355        /              |               |               |               |
356       |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
357       +---------------+---------------+---------------+---------------+
358      0| Expiration                                                    |
359       +---------------+---------------+---------------+---------------+
360     Total 4 bytes
361
362   When allows you to 'reserve' a key.  When 'when' is set for, say, ten
363   seconds in the future, the 'add' and 'replace' operations will fail
364   for that key until ten seconds from now.  The 'set' operation will
365   succeed regardless of any reserved deletes.  FIXME: Is the
366   reservation also cancelled?  Say there's a delete with a 10 second
367   hold.  Two seconds later, an 'add' is received.  It fails.  Two
368   second later, a 'set' is received.  Is succeeds unconditionally.
369   What if another 'add' is received two more seconds later (a total of
370   six seconds since the original 10 second delete-hold, thus still
371   within its purview).
372
3734.3.  Set, Add, Replace
374
375      MUST have extras.
376      MUST have key.
377      MUST have value.
378
379   o  4 byte flags
380   o  4 byte expiration time
381   o  8 byte data version check
382
383
384
385
386
387
388
389
390
391Aaron Stone               Expires June 16, 2008                 [Page 7]
392
393Internet-Draft          Memcache Binary Protocol           December 2007
394
395
396   Extra data for set/add/replace:
397
398     Byte/     0       |       1       |       2       |       3       |
399        /              |               |               |               |
400       |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
401       +---------------+---------------+---------------+---------------+
402      0| Data version check                                            |
403       |                                                               |
404       +---------------+---------------+---------------+---------------+
405      8| Flags                                                         |
406       +---------------+---------------+---------------+---------------+
407     12| Expiration                                                    |
408       +---------------+---------------+---------------+---------------+
409     Total 16 bytes
410
411   If the Data Version Check is present and nonzero, the set MUST
412   succeed if the key exists and has a version identifier identical to
413   the provided value, and MUST NOT succeed if the key does not exist or
414   has a different version identifier.  The set response packet will
415   include the same values in all three fields.
416
417   If the Data Version Check is zero, the set MUST succeed
418   unconditionally.  The set response packet will include idential
419   values for flags and expiration, and a new value for Data Version
420   Check, which the client SHOULD keep track of.
421
422   The key MAY be reserved according to Section 4.2, causing the set to
423   fail.
424
4254.4.  noop
426
427      MUST NOT have extras.
428      MUST NOT have key.
429      MUST NOT have value.
430
431   Used as a keep alive.  Flushes outstanding getq's.
432
4334.5.  Increment, Decrement
434
435      MUST have extras.
436      MUST have key.
437      MUST NOT have value.
438
439   o  8 byte value to add / subtract (FIXME: Is this unsigned?)
440   o  8 byte initial value (unsigned)
441   o  4 byte expiration time
442
443
444
445
446
447Aaron Stone               Expires June 16, 2008                 [Page 8]
448
449Internet-Draft          Memcache Binary Protocol           December 2007
450
451
452   Extra data for incr/decr:
453
454     Byte/     0       |       1       |       2       |       3       |
455        /              |               |               |               |
456       |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
457       +---------------+---------------+---------------+---------------+
458      0| Amount to add                                                 |
459       |                                                               |
460       +---------------+---------------+---------------+---------------+
461      8| Initial value                                                 |
462       |                                                               |
463       +---------------+---------------+---------------+---------------+
464     16| Expiration                                                    |
465       +---------------+---------------+---------------+---------------+
466     Total 20 bytes
467
468   incr/decr response body:
469
470     Byte/     0       |       1       |       2       |       3       |
471        /              |               |               |               |
472       |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
473       +---------------+---------------+---------------+---------------+
474      0| 64-bit unsigned response.                                     |
475       |                                                               |
476       +---------------+---------------+---------------+---------------+
477     Total 8 bytes
478
479   These commands will either add or remove the specified amount to the
480   requested counter.  If the counter does not exist, one of two things
481   may happen:
482   1.  If the expiration value is all one-bits (0xffffffff), the
483       operation will fail with NOT_FOUND.
484   2.  For all other expiration values, the operation will succeed by
485       seeding the value for this key with the provided initial value to
486       expire with the provided expiration time.
487
488   Note that in the creation case, flags will be set to zero (FIXME:
489   Should they be provided here as well?)
490
491
4925.  Example Session
493
494   We start up our application, and it asks for the value associated
495   with the 'Hello' key.
496
497
498
499
500
501
502
503Aaron Stone               Expires June 16, 2008                 [Page 9]
504
505Internet-Draft          Memcache Binary Protocol           December 2007
506
507
508   Get request:
509
510     Byte/     0       |       1       |       2       |       3       |
511        /              |               |               |               |
512       |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
513       +---------------+---------------+---------------+---------------+
514      0| 0x80          | 0x00          | 5 in big endian (BE)          |
515       +---------------+---------------+---------------+---------------+
516       | 12 in BE      | 0x00          |                               |
517       +---------------+---------------+---------------+---------------+
518       | 17 in BE                                                      |
519       +---------------+---------------+---------------+---------------+
520       | 0xDEADBEEF                                                    |
521       +---------------+---------------+---------------+---------------+
522     16| 0x00000000                                                    |
523       +---------------+---------------+---------------+---------------+
524     24| 0xDECAF 0x15 0xBAD 0xC0FFEE                                   |
525       |                                                               |
526       +---------------+---------------+---------------+---------------+
527     28| 'H'             'e'             'l'             'l'           |
528       | 'o'           |
529       +---------------+
530     Total 33 bytes (16 header + 12 get-extras + 5 key)
531
532   Since nobody has set this key, it returns not found.
533
534   Get response:
535
536     Byte/     0       |       1       |       2       |       3       |
537        /              |               |               |               |
538       |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
539       +---------------+---------------+---------------+---------------+
540      0| 0x81          | 0x00          | 0x0001                        |
541       +---------------+---------------+---------------+---------------+
542       | 0 in BE       | 0x00          |                               |
543       +---------------+---------------+---------------+---------------+
544       | 0 in BE                                                       |
545       +---------------+---------------+---------------+---------------+
546       | 0xDEADBEEF                                                    |
547       +---------------+---------------+---------------+---------------+
548     Total 16 bytes
549
550   Well, looks like we need to set the key!  Let's set it to expire on
551   December 15, 2007 at 9:51:09 PM.
552
553
554
555
556
557
558
559Aaron Stone               Expires June 16, 2008                [Page 10]
560
561Internet-Draft          Memcache Binary Protocol           December 2007
562
563
564   Set request:
565
566     Byte/     0       |       1       |       2       |       3       |
567        /              |               |               |               |
568       |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
569       +---------------+---------------+---------------+---------------+
570      0| 0x80          | 0x01          | 5 in BE                       |
571       +---------------+---------------+---------------+---------------+
572       | 16 in BE      | 0x00          |                               |
573       +---------------+---------------+---------------+---------------+
574       | 26 in BE                                                      |
575       +---------------+---------------+---------------+---------------+
576       | 0xDA7ABA5E                                                    |
577       +---------------+---------------+---------------+---------------+
578     16| 0x00000000                                                    |
579       +---------------+---------------+---------------+---------------+
580     20| 0xDCCB4674                                                    |
581       +---------------+---------------+---------------+---------------+
582     24| 0xDECAF 0x15 0xBAD 0xC0FFEE                                   |
583       |                                                               |
584       +---------------+---------------+---------------+---------------+
585     32| 'H'             'e'             'l'             'l'           |
586       | 'o'           | 'W'             'o'             'r'           |
587       | 'l'             'd'           |
588       +---------------+---------------+
589     Total 42 bytes (16 header + 16 set-extras + 5 key + 5 value)
590
591   The set succeeds.
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615Aaron Stone               Expires June 16, 2008                [Page 11]
616
617Internet-Draft          Memcache Binary Protocol           December 2007
618
619
620   Set response:
621
622     Byte/     0       |       1       |       2       |       3       |
623        /              |               |               |               |
624       |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
625       +---------------+---------------+---------------+---------------+
626      0| 0x81          | 0x01          | 0x0000                        |
627       +---------------+---------------+---------------+---------------+
628       | 16 in BE      | 0x00          |                               |
629       +---------------+---------------+---------------+---------------+
630       | 16 in BE                                                      |
631       +---------------+---------------+---------------+---------------+
632       | 0xDA7ABA5E                                                    |
633       +---------------+---------------+---------------+---------------+
634     16| 0x00000000                                                    |
635       +---------------+---------------+---------------+---------------+
636     20| 0xDCCB4674                                                    |
637       +---------------+---------------+---------------+---------------+
638     24| 0xDECAF 0x15 0xBAD 0xC0FFEE                                   |
639       |                                                               |
640       +---------------+---------------+---------------+---------------+
641     Total 32 bytes (16 header + 16 set-extras)
642
643   If the original get request is sent again, the key would be found.
644
645   Get response:
646
647     Byte/     0       |       1       |       2       |       3       |
648        /              |               |               |               |
649       |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
650       +---------------+---------------+---------------+---------------+
651      0| 0x81          | 0x00          | 0x00          |               |
652       +---------------+---------------+---------------+---------------+
653       | 12 in BE      | 0x00          |                               |
654       +---------------+---------------+---------------+---------------+
655       | 17 in BE                                                      |
656       +---------------+---------------+---------------+---------------+
657       | 0xDEADBEEF                                                    |
658       +---------------+---------------+---------------+---------------+
659     16| 0xDCCB4674                                                    |
660       +---------------+---------------+---------------+---------------+
661     24| 0xDECAF 0x15 0xBAD 0xC0FFEE                                   |
662       |                                                               |
663       +---------------+---------------+---------------+---------------+
664     28| 'W'             'o'             'r'             'l'           |
665       | 'd'           |
666       +---------------+
667     Total 33 bytes (16 header + 12 get-extras + 5 value)
668
669
670
671Aaron Stone               Expires June 16, 2008                [Page 12]
672
673Internet-Draft          Memcache Binary Protocol           December 2007
674
675
6766.  Security Considerations
677
678   Memcache has no authentication or security layers whatsoever.  It is
679   RECOMMENDED that memcache be deployed strictly on closed, protected,
680   back-end networks within a single data center, within a single
681   cluster of servers, or even on a single host, providing shared
682   caching for multiple applications.  Memcache MUST NOT be made
683   available on a public network.
684
685
6867.  Normative References
687
688   [KEYWORDS]
689              Bradner, S., "Key words for use in RFCs to Indicate
690              Requirement Levels", BCP 14, RFC 2119, March 1997.
691
692   [LJ]       Danga Interactive, "LJ NEEDS MOAR SPEED", 10 1999.
693
694   [UDP]      Postel, J., "User Datagram Protocol", STD 6, RFC 768,
695              August 1980.
696
697
698Appendix A.  Acknowledgments
699
700   Thanks to Brad Fitzpatrick, Anatoly Vorobey, Steven Grimm, and Dustin
701   Sallings, for their work on the memcached server.
702
703   Thanks to Sean Chittenden, Jonathan Steinert, Brian Aker, Evan
704   Martin, Nathan Neulinger, Eric Hodel, Michael Johnson, Paul Querna,
705   Jamie McCarthy, Philip Neustrom, Andrew O'Brien, Josh Rotenberg,
706   Robin H. Johnson, Tim Yardley, Paolo Borelli, Eli Bingham, Jean-
707   Francois Bustarret, Paul G, Paul Lindner, Alan Kasindorf, Chris
708   Goffinet, Tomash Brechko, and others for their work reporting bugs
709   and maintaining memcached client libraries and bindings in many
710   languages.
711
712
713Author's Address
714
715   Aaron Stone (editor)
716   Six Apart, Ltd.
717   548 4th Street
718   San Francisco, CA  94107
719   USA
720
721   Email: aaron@serendipity.palo-alto.ca.us
722
723
724
725
726
727Aaron Stone               Expires June 16, 2008                [Page 13]
728
Note: See TracBrowser for help on using the browser.