Commit Graph

3690 Commits

Author SHA1 Message Date
Adam Ierymenko
4f3f471b4c GitHub issue #460 2017-03-17 18:19:51 -07:00
Adam Ierymenko
e10325e133 GitHub issue #461 -- plus a bit of cleanup and optimization 2017-03-17 17:15:23 -07:00
Adam Ierymenko
ef46d3c97d LZ4 cleanup 2017-03-17 23:09:18 +00:00
Adam Ierymenko
a9c08c5975 . 2017-03-17 22:35:56 +00:00
Adam Ierymenko
c467c3b7e4 ARM tweaks 2017-03-17 22:26:08 +00:00
Adam Ierymenko
cdc0eaec3a Fix attempt to WHOIS self. 2017-03-17 22:13:34 +00:00
Adam Ierymenko
a7cb738175 . 2017-03-17 14:25:54 -07:00
Adam Ierymenko
d1bb22a583 . 2017-03-17 14:09:30 -07:00
Adam Ierymenko
553d972de5 bump that version. bump it good. 2017-03-17 13:56:45 -07:00
Adam Ierymenko
cc883cc3d8 Merge branch 'master' of http://10.6.6.2/zerotier/ZeroTierOne 2017-03-17 13:56:01 -07:00
Adam Ierymenko
c6a39ed927 Fixes for possible ARM issues, cleanup, fix for spurious meaningless exceptions on NETWORK_CONFIG_REQUEST 2017-03-17 13:55:26 -07:00
Adam Ierymenko
df30255542 Merge branch 'master' into dev 2017-03-17 12:37:23 -07:00
Adam Ierymenko
d5102539dd Merge pull request #457 from skunkwerks/master
build: use clang on FreeBSD
2017-03-17 12:18:54 -07:00
Adam Ierymenko
e3feaf3f5d Warning removal, and dev is now 1.2.1 2017-03-16 16:45:11 -07:00
Dave Cottlehuber
25dc596397 build: use clang on FreeBSD
this avoids a whopping 500+Mb dependency on gcc and friends at runtime
2017-03-16 12:58:04 +01:00
Adam Ierymenko
0daff26fba Version 1.2.0 is a major milestone release representing almost nine months of work. It includes our rules engine for distributed network packet filtering and security monitoring, federated roots, and many other architectural and UI improvements and bug fixes.
The largest new feature in 1.2.0, and the product of many months of work, is our advanced network rules engine. With this release we achieve traffic control, security monitoring, and micro-segmentation capability on par with many enterprise SDN solutions designed for use in advanced data centers and corporate networks.

Rules allow you to filter packets on your network and vector traffic to security observers. Security observation can be performed in-band using REDIRECT or out of band using TEE.

Tags and capabilites provide advanced methods for implementing fine grained permission structures and micro-segmentation schemes without bloating the size and complexity of your rules table.

See the [rules engine announcement blog post](https://www.zerotier.com/blog/?p=927) for an in-depth discussion of theory and implementation. The [manual](https://www.zerotier.com/manual.shtml) contains detailed information on rule, tag, and capability use, and the `rule-compiler/` subfolder of the ZeroTier source tree contains a JavaScript function to compile rules in our human-readable rule definition language into rules suitable for import into a network controller. (ZeroTier Central uses this same script to compile rules on [my.zerotier.com](https://my.zerotier.com/).)

It's now possible to create your own root servers and add them to the root server pool on your nodes. This is done by creating what's called a "moon," which is a signed enumeration of root servers and their stable points on the network. Refer to the [manual](https://www.zerotier.com/manual.shtml) for instructions.

Federated roots achieve a number of things:

 * You can deploy your own infrastructure to reduce dependency on ours.
 * You can deploy roots *inside your LAN* to ensure that network connectivity inside your facility still works if the Internet goes down. This is the first step toward making ZeroTier viable as an in-house SDN solution.
 * Roots can be deployed inside national boundaries for countries with data residency laws or "great firewalls." (As of 1.2.0 there is still no way to force all traffic to use these roots, but that will be easy to do in a later version.)
 * Last but not least this makes ZeroTier somewhat less centralized by eliminating any hard dependency on ZeroTier, Inc.'s infrastructure.

Our roots will of course remain and continue to provide zero-configuration instant-on deployment, a secure global authority for identities, and free traffic relaying for those who can't establish peer to peer connections.

An element of our design philosophy is "features are bugs." This isn't an absolute dogma but more of a guiding principle. We try as hard as we can to avoid adding features, especially "knobs" that must be tweaked by a user.

As of 1.2.0 we've decided that certain knobs are unavoidable, and so there is now a `local.conf` file that can be used to configure them. See the ZeroTier One documentation for these. They include:

 * Blacklisting interfaces you want to make sure ZeroTier doesn't use for network traffic, such as VPNs, slow links, or backplanes designated for only certain kinds of traffic.
 * Turning uPnP/NAT-PMP on or off.
 * Configuring software updates on Windows and Mac platforms.
 * Defining trusted paths (the old trusted paths file is now deprecated)
 * Setting the ZeroTier main port so it doesn't have to be changed on the command line, which is very inconvenient in many cases.

A good software update system for Windows and Mac clients has been a missing feature in previous versions. It does exist but we've been shy about using it so far due to its fragility in some environments.

We've greatly improved this mechanism in 1.2.0. Not only does it now do a better job of actually invoking the update, but it also transfers updates in-band using the ZeroTier protocol. This means it can work in environments that do not allows http/https traffic or that force it through proxies. There's also now an update channel setting: `beta` or `release` (the default).

Software updates are authenticated three ways:

 1. ZeroTier's own signing key is used to sign all updates and this signature is checked prior to installation. ZeroTier, Inc.'s signatures are performed on an air-gapped machine.

 2. Updates for Mac and Windows are signed using Apple and Microsoft (DigiCert EV) keys and will not install unless these signatures are also valid.

 3. The new in-band update mechanism also authenticates the source of the update via ZeroTier's built-in security features. This provides transport security, while 1 and 2 provide security of the update at rest.

Updates are now configurable via `local.conf`. There are three options: `disable`, `download`, and `apply`. The third (apply) is the default for official builds on Windows and Mac, making updates happen silently and automatically as they do for popular browsers like Chrome and Firefox. Updates are disabled by default on Linux and other Unix-type systems as these are typically updated through package managers.

Version 1.2.0 is now aware of the link quality of direct paths with other 1.2.0 nodes. This information isn't used yet but is visible through the JSON API. (Quality always shows as 100% with pre-1.2.0 nodes.) Quality is measured passively with no additional overhead using a counter based packet loss detection algorithm.

This information is visible from the command line via `listpeers`:

    200 listpeers XXXXXXXXXX 199.XXX.XXX.XXX/9993;10574;15250;1.00 48 1.2.0 LEAF
    200 listpeers XXXXXXXXXX 195.XXX.XXX.XXX/45584;467;7608;0.44 290 1.2.0 LEAF

The first peer's path is at 100% (1.00), while the second peer's path is suffering quite a bit of packet loss (0.44).

Link quality awareness is a precursor to intelligent multi-path and QoS support, which will in future versions bring us to feature parity with SD-WAN products like Cisco iWAN.

Version 1.2.0 adds anti-DOS (denial of service) rate limits and other hardening for improved resiliency against a number of denial of service attack scenarios.

It also adds a mechanism for instantaneous credential revocation. This can be used to revoke certificates of membership instantly to kick a node off a network (for private networks) and also to revoke capabilities and tags. The new controller sends revocations by default when a peer is de-authorized.

Revocations propagate using a "rumor mill" peer to peer algorithm. This means that a controller need only successfully send a revocation to at least one member of a network with connections to other active members. At this point the revocation will flood through the network peer to peer very quickly. This helps make revocations more robust in the face of poor connectivity with the controller or attempts to incapacitate the controller with denial of service attacks, as well as making revocations faster on huge networks.

The Mac has a whole new UI built natively in Objective-C. It provides a pulldown similar in appearance and operation to the Mac WiFi task bar menu.

The Windows UI has also been improved and now provides a task bar icon that can be right-clicked to manage networks. Both now expose managed route and IP permissions, allowing nodes to easily opt in to full tunnel operation if you have a router configured on your network.

A special kind of public network called an ad-hoc network may be accessed by joining a network ID with the format:

    ffSSSSEEEE000000
    | |   |   |
    | |   |   Reserved for future use, must be 0
    | |   End of port range (hex)
    | Start of port range (hex)
    Reserved ZeroTier address prefix indicating a controller-less network

Ad-hoc networks are public (no access control) networks that have no network controller. Instead their configuration and other credentials are generated locally. Ad-hoc networks permit only IPv6 UDP and TCP unicast traffic (no multicast or broadcast) using 6plane format NDP-emulated IPv6 addresses. In addition an ad-hoc network ID encodes an IP port range. UDP packets and TCP SYN (connection open) packets are only allowed to desintation ports within the encoded range.

For example `ff00160016000000` is an ad-hoc network allowing only SSH, while `ff0000ffff000000` is an ad-hoc network allowing any UDP or TCP port.

Keep in mind that these networks are public and anyone in the entire world can join them. Care must be taken to avoid exposing vulnerable services or sharing unwanted files or other resources.

The network controller has been largely rewritten to use a simple in-filesystem JSON data store in place of SQLite, and it is now included by default in all Windows, Mac, Linux, and BSD builds. This means any desktop or server node running ZeroTier One can now be a controller with no recompilation needed.

If you have data in an old SQLite3 controller we've included a NodeJS script in `controller/migrate-sqlite` to migrate data to the new format. If you don't migrate, members will start getting `NOT_FOUND` when they attempt to query for updates.

 * **The Windows HyperV 100% CPU bug is FINALLY DEAD**: This long-running problem turns out to have been an issue with Windows itself, but one we were triggering by placing invalid data into the Windows registry. Microsoft is aware of the issue but we've also fixed the triggering problem on our side. ZeroTier should now co-exist quite well with HyperV and should now be able to be bridged with a HyperV virtual switch.
 * **Segmenation faults on musl-libc based Linux systems**: Alpine Linux and some embedded Linux systems that use musl libc (a minimal libc) experienced segmentation faults. These were due to a smaller default stack size. A work-around that sets the stack size for new threads has been added.
 * **Windows firewall blocks local JSON API**: On some Windows systems the firewall likes to block 127.0.0.1:9993 for mysterious reasons. This is now fixed in the installer via the addition of another firewall exemption rule.
 * **UI crash on embedded Windows due to missing fonts**: The MSI installer now ships fonts and will install them if they are not present, so this should be fixed.

 * **Improved dead path detection**: ZeroTier is now more aggressive about expiring paths that do not seem to be active. If a path seems marginal it is re-confirmed before re-use.
 * **Minor performance improvements**: We've reduced unnecessary memcpy's and made a few other performance improvements in the core.
 * **Linux static binaries**: For our official packages (the ones in the download.zerotier.com apt and yum repositories) we now build Linux binaries with static linking. Hopefully this will stop all the bug reports relating to library inconsistencies, as well as allowing our deb packages to run on a wider variety of Debian-based distributions. (There are far too many of these to support officially!) The overhead for this is very small, especially since we built our static versions against musl-libc. Distribution maintainers are of course free to build dynamically linked versions for inclusion into distributions; this only affects our official binaries.

Merge branch 'master' of github.com:zerotier/ZeroTierOne
2017-03-14 22:08:48 -07:00
Adam Ierymenko
94ba5b3fbe Version 1.2.0 is a major milestone release representing almost nine months of work. It includes our rules engine for distributed network packet filtering and security monitoring, federated roots, and many other architectural and UI improvements and bug fixes.
The largest new feature in 1.2.0, and the product of many months of work, is our advanced network rules engine. With this release we achieve traffic control, security monitoring, and micro-segmentation capability on par with many enterprise SDN solutions designed for use in advanced data centers and corporate networks.

Rules allow you to filter packets on your network and vector traffic to security observers. Security observation can be performed in-band using REDIRECT or out of band using TEE.

Tags and capabilites provide advanced methods for implementing fine grained permission structures and micro-segmentation schemes without bloating the size and complexity of your rules table.

See the [rules engine announcement blog post](https://www.zerotier.com/blog/?p=927) for an in-depth discussion of theory and implementation. The [manual](https://www.zerotier.com/manual.shtml) contains detailed information on rule, tag, and capability use, and the `rule-compiler/` subfolder of the ZeroTier source tree contains a JavaScript function to compile rules in our human-readable rule definition language into rules suitable for import into a network controller. (ZeroTier Central uses this same script to compile rules on [my.zerotier.com](https://my.zerotier.com/).)

It's now possible to create your own root servers and add them to the root server pool on your nodes. This is done by creating what's called a "moon," which is a signed enumeration of root servers and their stable points on the network. Refer to the [manual](https://www.zerotier.com/manual.shtml) for instructions.

Federated roots achieve a number of things:

 * You can deploy your own infrastructure to reduce dependency on ours.
 * You can deploy roots *inside your LAN* to ensure that network connectivity inside your facility still works if the Internet goes down. This is the first step toward making ZeroTier viable as an in-house SDN solution.
 * Roots can be deployed inside national boundaries for countries with data residency laws or "great firewalls." (As of 1.2.0 there is still no way to force all traffic to use these roots, but that will be easy to do in a later version.)
 * Last but not least this makes ZeroTier somewhat less centralized by eliminating any hard dependency on ZeroTier, Inc.'s infrastructure.

Our roots will of course remain and continue to provide zero-configuration instant-on deployment, a secure global authority for identities, and free traffic relaying for those who can't establish peer to peer connections.

An element of our design philosophy is "features are bugs." This isn't an absolute dogma but more of a guiding principle. We try as hard as we can to avoid adding features, especially "knobs" that must be tweaked by a user.

As of 1.2.0 we've decided that certain knobs are unavoidable, and so there is now a `local.conf` file that can be used to configure them. See the ZeroTier One documentation for these. They include:

 * Blacklisting interfaces you want to make sure ZeroTier doesn't use for network traffic, such as VPNs, slow links, or backplanes designated for only certain kinds of traffic.
 * Turning uPnP/NAT-PMP on or off.
 * Configuring software updates on Windows and Mac platforms.
 * Defining trusted paths (the old trusted paths file is now deprecated)
 * Setting the ZeroTier main port so it doesn't have to be changed on the command line, which is very inconvenient in many cases.

A good software update system for Windows and Mac clients has been a missing feature in previous versions. It does exist but we've been shy about using it so far due to its fragility in some environments.

We've greatly improved this mechanism in 1.2.0. Not only does it now do a better job of actually invoking the update, but it also transfers updates in-band using the ZeroTier protocol. This means it can work in environments that do not allows http/https traffic or that force it through proxies. There's also now an update channel setting: `beta` or `release` (the default).

Software updates are authenticated three ways:

 1. ZeroTier's own signing key is used to sign all updates and this signature is checked prior to installation. ZeroTier, Inc.'s signatures are performed on an air-gapped machine.

 2. Updates for Mac and Windows are signed using Apple and Microsoft (DigiCert EV) keys and will not install unless these signatures are also valid.

 3. The new in-band update mechanism also authenticates the source of the update via ZeroTier's built-in security features. This provides transport security, while 1 and 2 provide security of the update at rest.

Updates are now configurable via `local.conf`. There are three options: `disable`, `download`, and `apply`. The third (apply) is the default for official builds on Windows and Mac, making updates happen silently and automatically as they do for popular browsers like Chrome and Firefox. Updates are disabled by default on Linux and other Unix-type systems as these are typically updated through package managers.

Version 1.2.0 is now aware of the link quality of direct paths with other 1.2.0 nodes. This information isn't used yet but is visible through the JSON API. (Quality always shows as 100% with pre-1.2.0 nodes.) Quality is measured passively with no additional overhead using a counter based packet loss detection algorithm.

This information is visible from the command line via `listpeers`:

    200 listpeers XXXXXXXXXX 199.XXX.XXX.XXX/9993;10574;15250;1.00 48 1.2.0 LEAF
    200 listpeers XXXXXXXXXX 195.XXX.XXX.XXX/45584;467;7608;0.44 290 1.2.0 LEAF

The first peer's path is at 100% (1.00), while the second peer's path is suffering quite a bit of packet loss (0.44).

Link quality awareness is a precursor to intelligent multi-path and QoS support, which will in future versions bring us to feature parity with SD-WAN products like Cisco iWAN.

Version 1.2.0 adds anti-DOS (denial of service) rate limits and other hardening for improved resiliency against a number of denial of service attack scenarios.

It also adds a mechanism for instantaneous credential revocation. This can be used to revoke certificates of membership instantly to kick a node off a network (for private networks) and also to revoke capabilities and tags. The new controller sends revocations by default when a peer is de-authorized.

Revocations propagate using a "rumor mill" peer to peer algorithm. This means that a controller need only successfully send a revocation to at least one member of a network with connections to other active members. At this point the revocation will flood through the network peer to peer very quickly. This helps make revocations more robust in the face of poor connectivity with the controller or attempts to incapacitate the controller with denial of service attacks, as well as making revocations faster on huge networks.

The Mac has a whole new UI built natively in Objective-C. It provides a pulldown similar in appearance and operation to the Mac WiFi task bar menu.

The Windows UI has also been improved and now provides a task bar icon that can be right-clicked to manage networks. Both now expose managed route and IP permissions, allowing nodes to easily opt in to full tunnel operation if you have a router configured on your network.

A special kind of public network called an ad-hoc network may be accessed by joining a network ID with the format:

    ffSSSSEEEE000000
    | |   |   |
    | |   |   Reserved for future use, must be 0
    | |   End of port range (hex)
    | Start of port range (hex)
    Reserved ZeroTier address prefix indicating a controller-less network

Ad-hoc networks are public (no access control) networks that have no network controller. Instead their configuration and other credentials are generated locally. Ad-hoc networks permit only IPv6 UDP and TCP unicast traffic (no multicast or broadcast) using 6plane format NDP-emulated IPv6 addresses. In addition an ad-hoc network ID encodes an IP port range. UDP packets and TCP SYN (connection open) packets are only allowed to desintation ports within the encoded range.

For example `ff00160016000000` is an ad-hoc network allowing only SSH, while `ff0000ffff000000` is an ad-hoc network allowing any UDP or TCP port.

Keep in mind that these networks are public and anyone in the entire world can join them. Care must be taken to avoid exposing vulnerable services or sharing unwanted files or other resources.

The network controller has been largely rewritten to use a simple in-filesystem JSON data store in place of SQLite, and it is now included by default in all Windows, Mac, Linux, and BSD builds. This means any desktop or server node running ZeroTier One can now be a controller with no recompilation needed.

If you have data in an old SQLite3 controller we've included a NodeJS script in `controller/migrate-sqlite` to migrate data to the new format. If you don't migrate, members will start getting `NOT_FOUND` when they attempt to query for updates.

 * **The Windows HyperV 100% CPU bug is FINALLY DEAD**: This long-running problem turns out to have been an issue with Windows itself, but one we were triggering by placing invalid data into the Windows registry. Microsoft is aware of the issue but we've also fixed the triggering problem on our side. ZeroTier should now co-exist quite well with HyperV and should now be able to be bridged with a HyperV virtual switch.
 * **Segmenation faults on musl-libc based Linux systems**: Alpine Linux and some embedded Linux systems that use musl libc (a minimal libc) experienced segmentation faults. These were due to a smaller default stack size. A work-around that sets the stack size for new threads has been added.
 * **Windows firewall blocks local JSON API**: On some Windows systems the firewall likes to block 127.0.0.1:9993 for mysterious reasons. This is now fixed in the installer via the addition of another firewall exemption rule.
 * **UI crash on embedded Windows due to missing fonts**: The MSI installer now ships fonts and will install them if they are not present, so this should be fixed.

 * **Improved dead path detection**: ZeroTier is now more aggressive about expiring paths that do not seem to be active. If a path seems marginal it is re-confirmed before re-use.
 * **Minor performance improvements**: We've reduced unnecessary memcpy's and made a few other performance improvements in the core.
 * **Linux static binaries**: For our official packages (the ones in the download.zerotier.com apt and yum repositories) we now build Linux binaries with static linking. Hopefully this will stop all the bug reports relating to library inconsistencies, as well as allowing our deb packages to run on a wider variety of Debian-based distributions. (There are far too many of these to support officially!) The overhead for this is very small, especially since we built our static versions against musl-libc. Distribution maintainers are of course free to build dynamically linked versions for inclusion into distributions; this only affects our official binaries.
2017-03-14 22:07:26 -07:00
Adam Ierymenko
002f9bb105 . 2017-03-14 22:05:39 -07:00
Adam Ierymenko
e86b1146a6 Windows version bump. 2017-03-14 21:35:41 -07:00
Adam Ierymenko
d44fb3a2f6 bump bump bump that version 2017-03-14 21:23:47 -07:00
Adam Ierymenko
1ef3069a7e 1.2.0 release notes and a few final tweaks and cleanup. 2017-03-14 21:21:12 -07:00
Adam Ierymenko
f99b62c48d fix stupid thing. 2017-03-14 15:38:24 -07:00
Adam Ierymenko
0fd45a640b Allow multiple architectures in software update dist .json file arch fields. 2017-03-14 15:19:16 -07:00
Adam Ierymenko
0b0d03dbe2 Merge branch 'dev' of http://10.187.63.16/zerotier/ZeroTierOne into dev 2017-03-14 14:40:27 -07:00
Adam Ierymenko
533baf921f Software update cleanup, and a fix for updates on Windows. 2017-03-14 14:40:17 -07:00
Adam Ierymenko
8e9767f3c6 Merge branch 'dev' of http://10.6.6.2/zerotier/ZeroTierOne into dev 2017-03-14 13:17:16 -07:00
Adam Ierymenko
27d4bedd73 Wait a minute (literally) before doing software update check on startup. 2017-03-14 13:17:10 -07:00
Adam Ierymenko
c1c26ec73a Version 1.2.0 bump 2017-03-13 15:41:42 -07:00
Adam Ierymenko
8f592ff6e8 Controller performance tweaks. 2017-03-13 13:58:29 -07:00
Adam Ierymenko
37629aaf87 Use cache on requests to decrease DB load. 2017-03-13 12:22:06 -07:00
Adam Ierymenko
d09d193715 release notes, and delete MANUAL from this repo for now since it isn't quite done and will take shape on the web site 2017-03-13 09:37:24 -07:00
Adam Ierymenko
010d0a7d56 Docs and a bit of cleanup. In particular ALL makes no sense for revocations because they have IDs. In that case you would just revoke the COM. 2017-03-13 06:53:23 -07:00
Adam Ierymenko
902807ea50 Software update check every 10min. 2017-03-10 22:03:07 -08:00
Adam Ierymenko
d0224b3623 Software update fix. 2017-03-10 22:02:08 -08:00
Adam Ierymenko
0f3148bda2 Roots need to respond to lots of WHOISes 2017-03-10 20:08:07 -08:00
Adam Ierymenko
e3b1fc2ac0 Tweak WHOIS path for federation. 2017-03-10 19:52:08 -08:00
Adam Ierymenko
6194d2af3d Return 200 from JSON API when moon is POSTed. 2017-03-10 19:37:03 -08:00
Adam Ierymenko
db87d95c1d getUpstreamPeer issue with interim federated roots 2017-03-10 19:31:51 -08:00
Adam Ierymenko
47166c9614 Sigh. Another thinko. 2017-03-10 17:54:14 -08:00
Adam Ierymenko
ecacdf27a9 Build fix (typo) 2017-03-10 17:45:05 -08:00
Adam Ierymenko
aad6f79efa Also must mask off counter bits in IV in cryptField. 2017-03-10 17:44:25 -08:00
Adam Ierymenko
0c00b83702 cryptField() used to obscure extended fields in HELLO cannot use mangleKey() 2017-03-10 17:34:41 -08:00
Adam Ierymenko
7320e26730 Merge branch 'edge' of http://10.6.6.2/zerotier/ZeroTierOne into edge 2017-03-10 11:34:00 -08:00
Grant Limberg
1520534660 fix some rediculousness in NDK-14
Apparently having -fPIC on the command line multiple times turns it back off
2017-03-09 17:48:40 -08:00
Adam Ierymenko
6d6719da27 Clarify key semantics. 2017-03-08 17:03:32 -08:00
Adam Ierymenko
20085cd15b No need to put time in .moon filename. 2017-03-08 16:51:12 -08:00
Adam Ierymenko
9b001823f6 Add ifdef for synology around synology-only code in Linux Ethernet tap. 2017-03-08 16:12:54 -08:00
Grant Limberg
ed4f84cc57 Fix exception thrown in NetworkMonitor thread that can cause the UI to stop polling service for updates 2017-03-08 14:54:58 -08:00
Grant Limberg
c8e66a2b45 Don't crash when attempting to join a network while the zerotier service isn't running 2017-03-08 14:50:37 -08:00
Adam Ierymenko
6eb2e3ffa9 forgot to add prereq for adduser getent on fedora 2017-03-08 13:13:12 -08:00