]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libgo: Merge to master revision 19184.
authorIan Lance Taylor <ian@gcc.gnu.org>
Fri, 6 Jun 2014 22:37:27 +0000 (22:37 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Fri, 6 Jun 2014 22:37:27 +0000 (22:37 +0000)
The next revision, 19185, renames several runtime files, and
will be handled in a separate change.

From-SVN: r211328

322 files changed:
gcc/testsuite/go.test/test/deferfin.go
gcc/testsuite/go.test/test/fixedbugs/issue4618.go
gcc/testsuite/go.test/test/fixedbugs/issue4667.go
libgo/MERGE
libgo/Makefile.am
libgo/Makefile.in
libgo/go/archive/tar/common.go
libgo/go/archive/tar/reader.go
libgo/go/archive/tar/reader_test.go
libgo/go/archive/tar/stat_atim.go
libgo/go/archive/tar/stat_unix.go
libgo/go/archive/tar/testdata/xattrs.tar [new file with mode: 0644]
libgo/go/archive/tar/writer.go
libgo/go/archive/tar/writer_test.go
libgo/go/archive/zip/reader_test.go
libgo/go/archive/zip/register.go
libgo/go/archive/zip/testdata/zip64-2.zip [new file with mode: 0644]
libgo/go/archive/zip/writer_test.go
libgo/go/bufio/bufio_test.go
libgo/go/bufio/scan.go
libgo/go/bufio/scan_test.go
libgo/go/compress/bzip2/bzip2_test.go
libgo/go/compress/bzip2/huffman.go
libgo/go/compress/flate/flate_test.go
libgo/go/compress/gzip/gunzip_test.go
libgo/go/compress/gzip/gzip_test.go
libgo/go/compress/lzw/reader_test.go
libgo/go/compress/zlib/reader_test.go
libgo/go/container/heap/heap.go
libgo/go/container/list/list.go
libgo/go/container/list/list_test.go
libgo/go/crypto/cipher/cbc.go
libgo/go/crypto/cipher/cbc_aes_test.go
libgo/go/crypto/md5/gen.go
libgo/go/crypto/md5/md5_test.go
libgo/go/crypto/md5/md5block.go
libgo/go/crypto/md5/md5block_generic.go [new file with mode: 0644]
libgo/go/crypto/rand/rand_unix.go
libgo/go/crypto/rand/util_test.go
libgo/go/crypto/rc4/rc4.go
libgo/go/crypto/rc4/rc4_ref.go
libgo/go/crypto/rc4/rc4_test.go
libgo/go/crypto/rsa/rsa.go
libgo/go/crypto/rsa/rsa_test.go
libgo/go/crypto/sha1/sha1_test.go
libgo/go/crypto/sha1/sha1block.go
libgo/go/crypto/sha1/sha1block_decl.go
libgo/go/crypto/sha1/sha1block_generic.go [new file with mode: 0644]
libgo/go/crypto/subtle/constant_time.go
libgo/go/crypto/tls/common.go
libgo/go/crypto/tls/conn.go
libgo/go/crypto/tls/handshake_client.go
libgo/go/crypto/tls/handshake_client_test.go
libgo/go/crypto/tls/handshake_messages.go
libgo/go/crypto/tls/handshake_server.go
libgo/go/crypto/tls/handshake_server_test.go
libgo/go/crypto/tls/key_agreement.go
libgo/go/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-ECDSA
libgo/go/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-RSA
libgo/go/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-ECDSA
libgo/go/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-RSA
libgo/go/crypto/tls/testdata/Client-TLSv10-ECDHE-ECDSA-AES
libgo/go/crypto/tls/testdata/Client-TLSv10-ECDHE-RSA-AES
libgo/go/crypto/tls/testdata/Client-TLSv10-RSA-RC4
libgo/go/crypto/tls/testdata/Client-TLSv11-ECDHE-ECDSA-AES
libgo/go/crypto/tls/testdata/Client-TLSv11-ECDHE-RSA-AES
libgo/go/crypto/tls/testdata/Client-TLSv11-RSA-RC4
libgo/go/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-ECDSA
libgo/go/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-RSA
libgo/go/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-ECDSA
libgo/go/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSA
libgo/go/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES
libgo/go/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES-GCM
libgo/go/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-AES
libgo/go/crypto/tls/testdata/Client-TLSv12-RSA-RC4
libgo/go/crypto/tls/testdata/Server-SSLv3-RSA-3DES
libgo/go/crypto/tls/testdata/Server-SSLv3-RSA-AES
libgo/go/crypto/tls/testdata/Server-SSLv3-RSA-RC4
libgo/go/crypto/tls/testdata/Server-TLSv10-ECDHE-ECDSA-AES
libgo/go/crypto/tls/testdata/Server-TLSv10-RSA-3DES
libgo/go/crypto/tls/testdata/Server-TLSv10-RSA-AES
libgo/go/crypto/tls/testdata/Server-TLSv10-RSA-RC4
libgo/go/crypto/tls/testdata/Server-TLSv11-RSA-RC4
libgo/go/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceECDSA
libgo/go/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceRSA
libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndECDSAGiven
libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndGiven
libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedNotGiven
libgo/go/crypto/tls/testdata/Server-TLSv12-ECDHE-ECDSA-AES
libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicket
libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-3DES
libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-AES
libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-AES-GCM
libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-RC4
libgo/go/crypto/tls/testdata/Server-TLSv12-Resume
libgo/go/crypto/tls/testdata/Server-TLSv12-SNI
libgo/go/crypto/tls/tls.go
libgo/go/crypto/x509/pkix/pkix.go
libgo/go/crypto/x509/root_unix.go
libgo/go/crypto/x509/x509.go
libgo/go/crypto/x509/x509_test.go
libgo/go/database/sql/convert.go
libgo/go/database/sql/convert_test.go
libgo/go/debug/dwarf/const.go
libgo/go/debug/dwarf/entry.go
libgo/go/debug/dwarf/open.go
libgo/go/debug/dwarf/testdata/typedef.elf4 [new file with mode: 0644]
libgo/go/debug/dwarf/type.go
libgo/go/debug/dwarf/type_test.go
libgo/go/debug/dwarf/typeunit.go [new file with mode: 0644]
libgo/go/debug/dwarf/unit.go
libgo/go/debug/elf/elf_test.go
libgo/go/debug/elf/file.go
libgo/go/debug/elf/testdata/hello.c [new file with mode: 0644]
libgo/go/debug/goobj/read.go
libgo/go/debug/gosym/pclntab.go
libgo/go/debug/gosym/symtab.go
libgo/go/debug/macho/fat.go [new file with mode: 0644]
libgo/go/debug/macho/file.go
libgo/go/debug/macho/file_test.go
libgo/go/debug/macho/macho.go
libgo/go/debug/macho/testdata/fat-gcc-386-amd64-darwin-exec [new file with mode: 0644]
libgo/go/debug/pe/file.go
libgo/go/debug/plan9obj/file.go [new file with mode: 0644]
libgo/go/debug/plan9obj/file_test.go [new file with mode: 0644]
libgo/go/debug/plan9obj/plan9obj.go [new file with mode: 0644]
libgo/go/debug/plan9obj/testdata/386-plan9-exec [new file with mode: 0644]
libgo/go/debug/plan9obj/testdata/amd64-plan9-exec [new file with mode: 0644]
libgo/go/debug/plan9obj/testdata/hello.c [new file with mode: 0644]
libgo/go/encoding/ascii85/ascii85_test.go
libgo/go/encoding/asn1/asn1.go
libgo/go/encoding/asn1/asn1_test.go
libgo/go/encoding/asn1/marshal.go
libgo/go/encoding/base32/base32_test.go
libgo/go/encoding/base64/base64_test.go
libgo/go/encoding/binary/binary_test.go
libgo/go/encoding/binary/varint_test.go
libgo/go/encoding/gob/codec_test.go
libgo/go/encoding/gob/decode.go
libgo/go/encoding/gob/encoder_test.go
libgo/go/encoding/json/encode.go
libgo/go/encoding/json/encode_test.go
libgo/go/encoding/json/scanner_test.go
libgo/go/encoding/xml/read.go
libgo/go/expvar/expvar.go
libgo/go/expvar/expvar_test.go
libgo/go/fmt/fmt_test.go
libgo/go/fmt/format.go
libgo/go/fmt/scan.go
libgo/go/go/build/build.go
libgo/go/go/build/deps_test.go
libgo/go/go/doc/example.go
libgo/go/go/parser/parser.go
libgo/go/go/parser/short_test.go
libgo/go/go/scanner/scanner.go
libgo/go/go/scanner/scanner_test.go
libgo/go/io/multi.go
libgo/go/math/big/arith.go
libgo/go/math/big/int.go
libgo/go/math/big/int_test.go
libgo/go/math/big/rat.go
libgo/go/math/big/rat_test.go
libgo/go/mime/multipart/formdata_test.go
libgo/go/mime/type_unix.go
libgo/go/net/conn_test.go
libgo/go/net/dial_test.go
libgo/go/net/dialgoogle_test.go
libgo/go/net/fd_plan9.go
libgo/go/net/fd_windows.go
libgo/go/net/file_plan9.go
libgo/go/net/file_test.go
libgo/go/net/file_unix.go
libgo/go/net/http/chunked.go
libgo/go/net/http/chunked_test.go
libgo/go/net/http/cookiejar/jar.go
libgo/go/net/http/export_test.go
libgo/go/net/http/fs.go
libgo/go/net/http/fs_test.go
libgo/go/net/http/httputil/chunked.go
libgo/go/net/http/httputil/chunked_test.go
libgo/go/net/http/httputil/dump.go
libgo/go/net/http/httputil/dump_test.go
libgo/go/net/http/httputil/httputil.go [new file with mode: 0644]
libgo/go/net/http/httputil/persist.go
libgo/go/net/http/httputil/reverseproxy.go
libgo/go/net/http/httputil/reverseproxy_test.go
libgo/go/net/http/proxy_test.go
libgo/go/net/http/request_test.go
libgo/go/net/http/requestwrite_test.go
libgo/go/net/http/response.go
libgo/go/net/http/response_test.go
libgo/go/net/http/responsewrite_test.go
libgo/go/net/http/serve_test.go
libgo/go/net/http/server.go
libgo/go/net/http/transfer.go
libgo/go/net/http/transfer_test.go
libgo/go/net/http/transport.go
libgo/go/net/http/transport_test.go
libgo/go/net/interface_linux.go
libgo/go/net/ipsock_plan9.go
libgo/go/net/lookup_plan9.go
libgo/go/net/mail/message.go
libgo/go/net/mail/message_test.go
libgo/go/net/rpc/server.go
libgo/go/net/sockopt_plan9.go [new file with mode: 0644]
libgo/go/net/tcpsock_plan9.go
libgo/go/net/tcpsockopt_plan9.go [new file with mode: 0644]
libgo/go/net/tcpsockopt_windows.go
libgo/go/net/udpsock_plan9.go
libgo/go/net/unicast_posix_test.go
libgo/go/net/unixsock_posix.go
libgo/go/net/z_last_test.go
libgo/go/os/dir_unix.go
libgo/go/os/env_unix_test.go
libgo/go/os/error_unix.go
libgo/go/os/exec/exec.go
libgo/go/os/exec/exec_test.go
libgo/go/os/exec/lp_unix.go
libgo/go/os/exec/lp_unix_test.go
libgo/go/os/exec_posix.go
libgo/go/os/exec_unix.go
libgo/go/os/file_plan9.go
libgo/go/os/file_posix.go
libgo/go/os/file_unix.go
libgo/go/os/os_test.go
libgo/go/os/os_unix_test.go
libgo/go/os/path_unix.go
libgo/go/os/pipe_bsd.go
libgo/go/os/signal/signal_test.go
libgo/go/os/signal/signal_unix.go
libgo/go/os/stat_solaris.go
libgo/go/os/user/lookup_unix.go
libgo/go/path/filepath/path_unix.go
libgo/go/reflect/makefunc.go
libgo/go/reflect/makefuncgo_386.go
libgo/go/reflect/makefuncgo_amd64.go
libgo/go/reflect/value.go
libgo/go/regexp/regexp.go
libgo/go/regexp/syntax/parse_test.go
libgo/go/runtime/append_test.go
libgo/go/runtime/chan_test.go
libgo/go/runtime/debug/garbage.go
libgo/go/runtime/debug/stack.go
libgo/go/runtime/error.go
libgo/go/runtime/export_test.go
libgo/go/runtime/lfstack_test.go
libgo/go/runtime/map_test.go
libgo/go/runtime/mem.go
libgo/go/runtime/memmove_test.go
libgo/go/runtime/pprof/pprof.go
libgo/go/runtime/pprof/pprof_test.go
libgo/go/runtime/proc_test.go
libgo/go/sync/pool.go
libgo/go/sync/pool_test.go
libgo/go/syscall/consistency_unix_test.go
libgo/go/syscall/libcall_posix.go
libgo/go/syscall/lsf_linux.go
libgo/go/syscall/mksyscall.awk
libgo/go/syscall/rlimit_unix_test.go [moved from libgo/go/syscall/rlimit_linux_test.go with 74% similarity]
libgo/go/syscall/socket.go
libgo/go/syscall/socket_posix.go
libgo/go/syscall/socket_xnet.go
libgo/go/syscall/syscall_unix.go
libgo/go/testing/benchmark.go
libgo/go/testing/benchmark_test.go
libgo/go/testing/testing.go
libgo/go/text/scanner/scanner_test.go
libgo/go/text/tabwriter/tabwriter.go
libgo/go/text/tabwriter/tabwriter_test.go
libgo/go/text/template/exec.go
libgo/go/text/template/exec_test.go
libgo/go/time/format_test.go [new file with mode: 0644]
libgo/go/time/internal_test.go
libgo/go/time/sleep_test.go
libgo/go/time/sys_unix.go
libgo/go/time/time_test.go
libgo/go/time/zoneinfo.go
libgo/go/time/zoneinfo_plan9.go
libgo/go/time/zoneinfo_read.go
libgo/go/time/zoneinfo_test.go [new file with mode: 0644]
libgo/go/time/zoneinfo_unix.go
libgo/go/time/zoneinfo_windows.go
libgo/go/unicode/letter.go
libgo/go/unicode/script_test.go
libgo/go/unicode/tables.go
libgo/merge.sh
libgo/mksysinfo.sh
libgo/runtime/chan.c
libgo/runtime/env_posix.c
libgo/runtime/go-append.c
libgo/runtime/go-defer.c
libgo/runtime/go-defer.h
libgo/runtime/go-panic.c
libgo/runtime/go-setenv.c
libgo/runtime/go-string-to-byte-array.c
libgo/runtime/go-string-to-int-array.c
libgo/runtime/go-unwind.c
libgo/runtime/go-varargs.c
libgo/runtime/lock_futex.c
libgo/runtime/lock_sema.c
libgo/runtime/malloc.goc
libgo/runtime/malloc.h
libgo/runtime/mcentral.c
libgo/runtime/mfinal.c [deleted file]
libgo/runtime/mgc0.c
libgo/runtime/mheap.c
libgo/runtime/mprof.goc
libgo/runtime/msize.c
libgo/runtime/netpoll.goc
libgo/runtime/netpoll_epoll.c
libgo/runtime/netpoll_kqueue.c
libgo/runtime/netpoll_select.c
libgo/runtime/netpoll_stub.c
libgo/runtime/panic.c
libgo/runtime/proc.c
libgo/runtime/race.h
libgo/runtime/runtime.c
libgo/runtime/runtime.h
libgo/runtime/sema.goc
libgo/runtime/signal_unix.c
libgo/runtime/string.goc
libgo/runtime/time.goc

index fa5a93354dce57c851dac4d49450c72ac56bef07..80372916d20b303303483f6ea36911b20482c8dc 100644 (file)
@@ -34,17 +34,17 @@ func main() {
        for i := 0; i < N; i++ {
                go func() {
                        defer wg.Done()
-                       v := new(int)
+                       v := new(string)
                        f := func() {
-                               if *v != 0 {
+                               if *v != "" {
                                        panic("oops")
                                }
                        }
-                       if *v != 0 {
+                       if *v != "" {
                                // let the compiler think f escapes
                                sink = f
                        }
-                       runtime.SetFinalizer(v, func(p *int) {
+                       runtime.SetFinalizer(v, func(p *string) {
                                atomic.AddInt32(&count, -1)
                        })
                        defer f()
index ff91ae70673afae7cb82f94d6afb7456bda8475d..fe875b35013f9a7bf7f8d09a011eb1476a8bf309 100644 (file)
@@ -30,7 +30,7 @@ func G() {
 func main() {
        nf := testing.AllocsPerRun(100, F)
        ng := testing.AllocsPerRun(100, G)
-       if int(nf) != 1 {
+       if int(nf) > 1 {
                fmt.Printf("AllocsPerRun(100, F) = %v, want 1\n", nf)
                os.Exit(1)
        }
index 3a00a31952c327b9d93d7674801d14116c33f0cf..18d773c2cfb9a21201ec3530bdeed8141719834d 100644 (file)
@@ -26,11 +26,11 @@ func F() {
 func main() {
        nf := testing.AllocsPerRun(100, F)
        ng := testing.AllocsPerRun(100, G)
-       if int(nf) != 1 {
+       if int(nf) > 1 {
                fmt.Printf("AllocsPerRun(100, F) = %v, want 1\n", nf)
                os.Exit(1)
        }
-       if int(ng) != 1 {
+       if int(ng) > 1 {
                fmt.Printf("AllocsPerRun(100, G) = %v, want 1\n", ng)
                os.Exit(1)
        }
index d789afe1d3d5b33cf582ea7c62d9a084b0f7fd00..2ef8f7a9489efb31f54aff54e6ca7379e6f790d6 100644 (file)
@@ -1,4 +1,4 @@
-00cce3a34d7e
+50c8fc924389
 
 The first line of this file holds the Mercurial revision number of the
 last merge done from the master library sources.
index b6be7e48867d8d5d9d6b132adc4d8960023b5cdc..a88f0b7f24c3c798de24b68165ddf4297aeff030 100644 (file)
@@ -199,7 +199,8 @@ toolexeclibgodebug_DATA = \
        debug/goobj.gox \
        debug/gosym.gox \
        debug/macho.gox \
-       debug/pe.gox
+       debug/pe.gox \
+       debug/plan9obj.gox
 
 toolexeclibgoencodingdir = $(toolexeclibgodir)/encoding
 
@@ -500,7 +501,6 @@ runtime_files = \
        runtime/mcache.c \
        runtime/mcentral.c \
        $(runtime_mem_file) \
-       runtime/mfinal.c \
        runtime/mfixalloc.c \
        runtime/mgc0.c \
        runtime/mheap.c \
@@ -1144,7 +1144,8 @@ go_crypto_hmac_files = \
        go/crypto/hmac/hmac.go
 go_crypto_md5_files = \
        go/crypto/md5/md5.go \
-       go/crypto/md5/md5block.go
+       go/crypto/md5/md5block.go \
+       go/crypto/md5/md5block_generic.go
 go_crypto_rand_files = \
        go/crypto/rand/rand.go \
        go/crypto/rand/rand_unix.go \
@@ -1158,7 +1159,8 @@ go_crypto_rsa_files = \
        go/crypto/rsa/rsa.go
 go_crypto_sha1_files = \
        go/crypto/sha1/sha1.go \
-       go/crypto/sha1/sha1block.go
+       go/crypto/sha1/sha1block.go \
+       go/crypto/sha1/sha1block_generic.go
 go_crypto_sha256_files = \
        go/crypto/sha256/sha256.go \
        go/crypto/sha256/sha256block.go
@@ -1208,6 +1210,7 @@ go_debug_dwarf_files = \
        go/debug/dwarf/line.go \
        go/debug/dwarf/open.go \
        go/debug/dwarf/type.go \
+       go/debug/dwarf/typeunit.go \
        go/debug/dwarf/unit.go
 go_debug_elf_files = \
        go/debug/elf/elf.go \
@@ -1218,11 +1221,15 @@ go_debug_gosym_files = \
        go/debug/gosym/pclntab.go \
        go/debug/gosym/symtab.go
 go_debug_macho_files = \
+       go/debug/macho/fat.go \
        go/debug/macho/file.go \
        go/debug/macho/macho.go
 go_debug_pe_files = \
        go/debug/pe/file.go \
        go/debug/pe/pe.go
+go_debug_plan9obj_files = \
+       go/debug/plan9obj/file.go \
+       go/debug/plan9obj/plan9obj.go
 
 go_encoding_ascii85_files = \
        go/encoding/ascii85/ascii85.go
@@ -1452,6 +1459,7 @@ go_net_http_pprof_files = \
 go_net_http_httputil_files = \
        go/net/http/httputil/chunked.go \
        go/net/http/httputil/dump.go \
+       go/net/http/httputil/httputil.go \
        go/net/http/httputil/persist.go \
        go/net/http/httputil/reverseproxy.go
 
@@ -1876,6 +1884,7 @@ libgo_go_objs = \
        debug/gosym.lo \
        debug/macho.lo \
        debug/pe.lo \
+       debug/plan9obj.lo \
        encoding/ascii85.lo \
        encoding/asn1.lo \
        encoding/base32.lo \
@@ -2636,6 +2645,15 @@ debug/pe/check: $(CHECK_DEPS)
        @$(CHECK)
 .PHONY: debug/pe/check
 
+@go_include@ debug/plan9obj.lo.dep
+debug/plan9obj.lo.dep: $(go_debug_plan9obj_files)
+       $(BUILDDEPS)
+debug/plan9obj.lo: $(go_debug_plan9obj_files)
+       $(BUILDPACKAGE)
+debug/plan9obj/check: $(CHECK_DEPS)
+       @$(CHECK)
+.PHONY: debug/plan9obj/check
+
 @go_include@ encoding/asn1.lo.dep
 encoding/asn1.lo.dep: $(go_encoding_asn1_files)
        $(BUILDDEPS)
@@ -3435,6 +3453,8 @@ debug/macho.gox: debug/macho.lo
        $(BUILDGOX)
 debug/pe.gox: debug/pe.lo
        $(BUILDGOX)
+debug/plan9obj.gox: debug/plan9obj.lo
+       $(BUILDGOX)
 
 encoding/ascii85.gox: encoding/ascii85.lo
        $(BUILDGOX)
@@ -3659,6 +3679,7 @@ TEST_PACKAGES = \
        debug/elf/check \
        debug/macho/check \
        debug/pe/check \
+       debug/plan9obj/check \
        encoding/ascii85/check \
        encoding/asn1/check \
        encoding/base32/check \
index eb731e43912461ce31cbf22efec9454ec065e284..73620f772d882720581d187006cc0f7acd280bfd 100644 (file)
@@ -148,21 +148,21 @@ am__DEPENDENCIES_2 = bufio.lo bytes.lo bytes/index.lo crypto.lo \
        crypto/sha512.lo crypto/subtle.lo crypto/tls.lo crypto/x509.lo \
        crypto/x509/pkix.lo database/sql.lo database/sql/driver.lo \
        debug/dwarf.lo debug/elf.lo debug/goobj.lo debug/gosym.lo \
-       debug/macho.lo debug/pe.lo encoding/ascii85.lo \
-       encoding/asn1.lo encoding/base32.lo encoding/base64.lo \
-       encoding/binary.lo encoding/csv.lo encoding/gob.lo \
-       encoding/hex.lo encoding/json.lo encoding/pem.lo \
-       encoding/xml.lo exp/proxy.lo exp/terminal.lo html/template.lo \
-       go/ast.lo go/build.lo go/doc.lo go/format.lo go/parser.lo \
-       go/printer.lo go/scanner.lo go/token.lo hash/adler32.lo \
-       hash/crc32.lo hash/crc64.lo hash/fnv.lo net/http/cgi.lo \
-       net/http/cookiejar.lo net/http/fcgi.lo net/http/httptest.lo \
-       net/http/httputil.lo net/http/pprof.lo image/color.lo \
-       image/color/palette.lo image/draw.lo image/gif.lo \
-       image/jpeg.lo image/png.lo index/suffixarray.lo io/ioutil.lo \
-       log/syslog.lo log/syslog/syslog_c.lo math/big.lo math/cmplx.lo \
-       math/rand.lo mime/multipart.lo net/http.lo net/mail.lo \
-       net/rpc.lo net/smtp.lo net/textproto.lo net/url.lo \
+       debug/macho.lo debug/pe.lo debug/plan9obj.lo \
+       encoding/ascii85.lo encoding/asn1.lo encoding/base32.lo \
+       encoding/base64.lo encoding/binary.lo encoding/csv.lo \
+       encoding/gob.lo encoding/hex.lo encoding/json.lo \
+       encoding/pem.lo encoding/xml.lo exp/proxy.lo exp/terminal.lo \
+       html/template.lo go/ast.lo go/build.lo go/doc.lo go/format.lo \
+       go/parser.lo go/printer.lo go/scanner.lo go/token.lo \
+       hash/adler32.lo hash/crc32.lo hash/crc64.lo hash/fnv.lo \
+       net/http/cgi.lo net/http/cookiejar.lo net/http/fcgi.lo \
+       net/http/httptest.lo net/http/httputil.lo net/http/pprof.lo \
+       image/color.lo image/color/palette.lo image/draw.lo \
+       image/gif.lo image/jpeg.lo image/png.lo index/suffixarray.lo \
+       io/ioutil.lo log/syslog.lo log/syslog/syslog_c.lo math/big.lo \
+       math/cmplx.lo math/rand.lo mime/multipart.lo net/http.lo \
+       net/mail.lo net/rpc.lo net/smtp.lo net/textproto.lo net/url.lo \
        old/regexp.lo old/template.lo os/exec.lo $(am__DEPENDENCIES_1) \
        os/signal.lo os/user.lo path/filepath.lo regexp/syntax.lo \
        net/rpc/jsonrpc.lo runtime/debug.lo runtime/pprof.lo \
@@ -213,8 +213,8 @@ am__objects_6 = go-append.lo go-assert.lo go-assert-interface.lo \
        go-unsafe-new.lo go-unsafe-newarray.lo go-unsafe-pointer.lo \
        go-unwind.lo go-varargs.lo chan.lo cpuprof.lo env_posix.lo \
        lfstack.lo $(am__objects_1) mcache.lo mcentral.lo \
-       $(am__objects_2) mfinal.lo mfixalloc.lo mgc0.lo mheap.lo \
-       msize.lo $(am__objects_3) panic.lo parfor.lo print.lo proc.lo \
+       $(am__objects_2) mfixalloc.lo mgc0.lo mheap.lo msize.lo \
+       $(am__objects_3) panic.lo parfor.lo print.lo proc.lo \
        runtime.lo signal_unix.lo thread.lo yield.lo $(am__objects_4) \
        iface.lo malloc.lo map.lo mprof.lo netpoll.lo reflect.lo \
        runtime1.lo sema.lo sigqueue.lo string.lo time.lo \
@@ -591,7 +591,8 @@ toolexeclibgodebug_DATA = \
        debug/goobj.gox \
        debug/gosym.gox \
        debug/macho.gox \
-       debug/pe.gox
+       debug/pe.gox \
+       debug/plan9obj.gox
 
 toolexeclibgoencodingdir = $(toolexeclibgodir)/encoding
 toolexeclibgoencoding_DATA = \
@@ -829,7 +830,6 @@ runtime_files = \
        runtime/mcache.c \
        runtime/mcentral.c \
        $(runtime_mem_file) \
-       runtime/mfinal.c \
        runtime/mfixalloc.c \
        runtime/mgc0.c \
        runtime/mheap.c \
@@ -1302,7 +1302,8 @@ go_crypto_hmac_files = \
 
 go_crypto_md5_files = \
        go/crypto/md5/md5.go \
-       go/crypto/md5/md5block.go
+       go/crypto/md5/md5block.go \
+       go/crypto/md5/md5block_generic.go
 
 go_crypto_rand_files = \
        go/crypto/rand/rand.go \
@@ -1320,7 +1321,8 @@ go_crypto_rsa_files = \
 
 go_crypto_sha1_files = \
        go/crypto/sha1/sha1.go \
-       go/crypto/sha1/sha1block.go
+       go/crypto/sha1/sha1block.go \
+       go/crypto/sha1/sha1block_generic.go
 
 go_crypto_sha256_files = \
        go/crypto/sha256/sha256.go \
@@ -1375,6 +1377,7 @@ go_debug_dwarf_files = \
        go/debug/dwarf/line.go \
        go/debug/dwarf/open.go \
        go/debug/dwarf/type.go \
+       go/debug/dwarf/typeunit.go \
        go/debug/dwarf/unit.go
 
 go_debug_elf_files = \
@@ -1389,6 +1392,7 @@ go_debug_gosym_files = \
        go/debug/gosym/symtab.go
 
 go_debug_macho_files = \
+       go/debug/macho/fat.go \
        go/debug/macho/file.go \
        go/debug/macho/macho.go
 
@@ -1396,6 +1400,10 @@ go_debug_pe_files = \
        go/debug/pe/file.go \
        go/debug/pe/pe.go
 
+go_debug_plan9obj_files = \
+       go/debug/plan9obj/file.go \
+       go/debug/plan9obj/plan9obj.go
+
 go_encoding_ascii85_files = \
        go/encoding/ascii85/ascii85.go
 
@@ -1656,6 +1664,7 @@ go_net_http_pprof_files = \
 go_net_http_httputil_files = \
        go/net/http/httputil/chunked.go \
        go/net/http/httputil/dump.go \
+       go/net/http/httputil/httputil.go \
        go/net/http/httputil/persist.go \
        go/net/http/httputil/reverseproxy.go
 
@@ -1947,6 +1956,7 @@ libgo_go_objs = \
        debug/gosym.lo \
        debug/macho.lo \
        debug/pe.lo \
+       debug/plan9obj.lo \
        encoding/ascii85.lo \
        encoding/asn1.lo \
        encoding/base32.lo \
@@ -2187,6 +2197,7 @@ TEST_PACKAGES = \
        debug/elf/check \
        debug/macho/check \
        debug/pe/check \
+       debug/plan9obj/check \
        encoding/ascii85/check \
        encoding/asn1/check \
        encoding/base32/check \
@@ -2472,7 +2483,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mcentral.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mem.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mem_posix_memalign.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mfinal.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mfixalloc.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mgc0.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mheap.Plo@am__quote@
@@ -3081,13 +3091,6 @@ mem.lo: runtime/mem.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mem.lo `test -f 'runtime/mem.c' || echo '$(srcdir)/'`runtime/mem.c
 
-mfinal.lo: runtime/mfinal.c
-@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mfinal.lo -MD -MP -MF $(DEPDIR)/mfinal.Tpo -c -o mfinal.lo `test -f 'runtime/mfinal.c' || echo '$(srcdir)/'`runtime/mfinal.c
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/mfinal.Tpo $(DEPDIR)/mfinal.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='runtime/mfinal.c' object='mfinal.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mfinal.lo `test -f 'runtime/mfinal.c' || echo '$(srcdir)/'`runtime/mfinal.c
-
 mfixalloc.lo: runtime/mfixalloc.c
 @am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mfixalloc.lo -MD -MP -MF $(DEPDIR)/mfixalloc.Tpo -c -o mfixalloc.lo `test -f 'runtime/mfixalloc.c' || echo '$(srcdir)/'`runtime/mfixalloc.c
 @am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/mfixalloc.Tpo $(DEPDIR)/mfixalloc.Plo
@@ -5014,6 +5017,15 @@ debug/pe/check: $(CHECK_DEPS)
        @$(CHECK)
 .PHONY: debug/pe/check
 
+@go_include@ debug/plan9obj.lo.dep
+debug/plan9obj.lo.dep: $(go_debug_plan9obj_files)
+       $(BUILDDEPS)
+debug/plan9obj.lo: $(go_debug_plan9obj_files)
+       $(BUILDPACKAGE)
+debug/plan9obj/check: $(CHECK_DEPS)
+       @$(CHECK)
+.PHONY: debug/plan9obj/check
+
 @go_include@ encoding/asn1.lo.dep
 encoding/asn1.lo.dep: $(go_encoding_asn1_files)
        $(BUILDDEPS)
@@ -5805,6 +5817,8 @@ debug/macho.gox: debug/macho.lo
        $(BUILDGOX)
 debug/pe.gox: debug/pe.lo
        $(BUILDGOX)
+debug/plan9obj.gox: debug/plan9obj.lo
+       $(BUILDGOX)
 
 encoding/ascii85.gox: encoding/ascii85.lo
        $(BUILDGOX)
index 1b961e3ec637c4630018d17ac69131cc3b364277..e8b973c1faf0b5b8566b9bc0fc1f9fe4226ae3d4 100644 (file)
@@ -57,6 +57,7 @@ type Header struct {
        Devminor   int64     // minor number of character or block device
        AccessTime time.Time // access time
        ChangeTime time.Time // status change time
+       Xattrs     map[string]string
 }
 
 // File name constants from the tar spec.
@@ -189,6 +190,7 @@ const (
        paxSize     = "size"
        paxUid      = "uid"
        paxUname    = "uname"
+       paxXattr    = "SCHILY.xattr."
        paxNone     = ""
 )
 
index b2d62f3c51c171e10ff237fb25f5e6acbd03341a..7cb6e649c7bec17549063c890ad12f296e3e93a7 100644 (file)
@@ -139,8 +139,14 @@ func mergePAX(hdr *Header, headers map[string]string) error {
                                return err
                        }
                        hdr.Size = int64(size)
+               default:
+                       if strings.HasPrefix(k, paxXattr) {
+                               if hdr.Xattrs == nil {
+                                       hdr.Xattrs = make(map[string]string)
+                               }
+                               hdr.Xattrs[k[len(paxXattr):]] = v
+                       }
                }
-
        }
        return nil
 }
index 12856165656a6bb477eddac8aba7e17790870636..f84dbebe98996d18d1cb6eafcf92340b87b03ef7 100644 (file)
@@ -161,6 +161,46 @@ var untarTests = []*untarTest{
                        },
                },
        },
+       {
+               file: "testdata/xattrs.tar",
+               headers: []*Header{
+                       {
+                               Name:       "small.txt",
+                               Mode:       0644,
+                               Uid:        1000,
+                               Gid:        10,
+                               Size:       5,
+                               ModTime:    time.Unix(1386065770, 448252320),
+                               Typeflag:   '0',
+                               Uname:      "alex",
+                               Gname:      "wheel",
+                               AccessTime: time.Unix(1389782991, 419875220),
+                               ChangeTime: time.Unix(1389782956, 794414986),
+                               Xattrs: map[string]string{
+                                       "user.key":  "value",
+                                       "user.key2": "value2",
+                                       // Interestingly, selinux encodes the terminating null inside the xattr
+                                       "security.selinux": "unconfined_u:object_r:default_t:s0\x00",
+                               },
+                       },
+                       {
+                               Name:       "small2.txt",
+                               Mode:       0644,
+                               Uid:        1000,
+                               Gid:        10,
+                               Size:       11,
+                               ModTime:    time.Unix(1386065770, 449252304),
+                               Typeflag:   '0',
+                               Uname:      "alex",
+                               Gname:      "wheel",
+                               AccessTime: time.Unix(1389782991, 419875220),
+                               ChangeTime: time.Unix(1386065770, 449252304),
+                               Xattrs: map[string]string{
+                                       "security.selinux": "unconfined_u:object_r:default_t:s0\x00",
+                               },
+                       },
+               },
+       },
 }
 
 func TestReader(t *testing.T) {
@@ -180,7 +220,7 @@ testLoop:
                                f.Close()
                                continue testLoop
                        }
-                       if *hdr != *header {
+                       if !reflect.DeepEqual(*hdr, *header) {
                                t.Errorf("test %d, entry %d: Incorrect header:\nhave %+v\nwant %+v",
                                        i, j, *hdr, *header)
                        }
@@ -253,7 +293,7 @@ func TestIncrementalRead(t *testing.T) {
                }
 
                // check the header
-               if *hdr != *headers[nread] {
+               if !reflect.DeepEqual(*hdr, *headers[nread]) {
                        t.Errorf("Incorrect header:\nhave %+v\nwant %+v",
                                *hdr, headers[nread])
                }
@@ -321,7 +361,7 @@ func TestParsePAXHeader(t *testing.T) {
                {"mtime", "mtime=1350244992.023960108", "30 mtime=1350244992.023960108\n"}}
        for _, test := range paxTests {
                key, expected, raw := test[0], test[1], test[2]
-               reader := bytes.NewBuffer([]byte(raw))
+               reader := bytes.NewReader([]byte(raw))
                headers, err := parsePAX(reader)
                if err != nil {
                        t.Errorf("Couldn't parse correctly formatted headers: %v", err)
@@ -337,7 +377,7 @@ func TestParsePAXHeader(t *testing.T) {
                        t.Error("Buffer wasn't consumed")
                }
        }
-       badHeader := bytes.NewBuffer([]byte("3 somelongkey="))
+       badHeader := bytes.NewReader([]byte("3 somelongkey="))
        if _, err := parsePAX(badHeader); err != ErrHeader {
                t.Fatal("Unexpected success when parsing bad header")
        }
index 6029b0871231316aad7e4667658c04ba969fc8ce..cf9cc79c5915bace0af0e81fa4df961f3a68553c 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build linux openbsd
+// +build linux dragonfly openbsd solaris
 
 package tar
 
index 92bc92424293aa8c76b549d030a6559e7f4844df..cb843db4cfd65815830128cc0aa285dee36f7123 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build linux darwin freebsd openbsd netbsd
+// +build linux darwin dragonfly freebsd openbsd netbsd solaris
 
 package tar
 
diff --git a/libgo/go/archive/tar/testdata/xattrs.tar b/libgo/go/archive/tar/testdata/xattrs.tar
new file mode 100644 (file)
index 0000000..9701950
Binary files /dev/null and b/libgo/go/archive/tar/testdata/xattrs.tar differ
index 549f1464c38b0b2667843f1ba3db9c967525d3f7..9ee94992970eca4bf7b8ec7770616e0ef4767d45 100644 (file)
@@ -236,6 +236,12 @@ func (tw *Writer) writeHeader(hdr *Header, allowPax bool) error {
                return tw.err
        }
 
+       if allowPax {
+               for k, v := range hdr.Xattrs {
+                       paxHeaders[paxXattr+k] = v
+               }
+       }
+
        if len(paxHeaders) > 0 {
                if !allowPax {
                        return errInvalidHeader
index 30ebf977acfc09f9c0764065004526069f12cd2b..2b9ea658db479193aebd5e3f391ea361b2869e79 100644 (file)
@@ -10,6 +10,7 @@ import (
        "io"
        "io/ioutil"
        "os"
+       "reflect"
        "strings"
        "testing"
        "testing/iotest"
@@ -338,6 +339,45 @@ func TestPaxNonAscii(t *testing.T) {
        }
 }
 
+func TestPaxXattrs(t *testing.T) {
+       xattrs := map[string]string{
+               "user.key": "value",
+       }
+
+       // Create an archive with an xattr
+       fileinfo, err := os.Stat("testdata/small.txt")
+       if err != nil {
+               t.Fatal(err)
+       }
+       hdr, err := FileInfoHeader(fileinfo, "")
+       if err != nil {
+               t.Fatalf("os.Stat: %v", err)
+       }
+       contents := "Kilts"
+       hdr.Xattrs = xattrs
+       var buf bytes.Buffer
+       writer := NewWriter(&buf)
+       if err := writer.WriteHeader(hdr); err != nil {
+               t.Fatal(err)
+       }
+       if _, err = writer.Write([]byte(contents)); err != nil {
+               t.Fatal(err)
+       }
+       if err := writer.Close(); err != nil {
+               t.Fatal(err)
+       }
+       // Test that we can get the xattrs back out of the archive.
+       reader := NewReader(&buf)
+       hdr, err = reader.Next()
+       if err != nil {
+               t.Fatal(err)
+       }
+       if !reflect.DeepEqual(hdr.Xattrs, xattrs) {
+               t.Fatalf("xattrs did not survive round trip: got %+v, want %+v",
+                       hdr.Xattrs, xattrs)
+       }
+}
+
 func TestPAXHeader(t *testing.T) {
        medName := strings.Repeat("CD", 50)
        longName := strings.Repeat("AB", 100)
index 78875ecbf0e0684018b9faae73df79a99d4e03b6..5652f3a50074b6b2ebef61a87c729dca1fe77a8c 100644 (file)
@@ -235,6 +235,18 @@ var tests = []ZipTest{
                        },
                },
        },
+       // Another zip64 file with different Extras fields. (golang.org/issue/7069)
+       {
+               Name: "zip64-2.zip",
+               File: []ZipTestFile{
+                       {
+                               Name:    "README",
+                               Content: []byte("This small file is in ZIP64 format.\n"),
+                               Mtime:   "08-10-12 14:33:32",
+                               Mode:    0644,
+                       },
+               },
+       },
 }
 
 var crossPlatform = []ZipTestFile{
@@ -343,19 +355,13 @@ func readTestFile(t *testing.T, zt ZipTest, ft ZipTestFile, f *File) {
 
        testFileMode(t, zt.Name, f, ft.Mode)
 
-       size0 := f.UncompressedSize
-
        var b bytes.Buffer
        r, err := f.Open()
        if err != nil {
-               t.Error(err)
+               t.Errorf("%s: %v", zt.Name, err)
                return
        }
 
-       if size1 := f.UncompressedSize; size0 != size1 {
-               t.Errorf("file %q changed f.UncompressedSize from %d to %d", f.Name, size0, size1)
-       }
-
        _, err = io.Copy(&b, r)
        if err != ft.ContentErr {
                t.Errorf("%s: copying contents: %v (want %v)", zt.Name, err, ft.ContentErr)
@@ -365,6 +371,14 @@ func readTestFile(t *testing.T, zt ZipTest, ft ZipTestFile, f *File) {
        }
        r.Close()
 
+       size := uint64(f.UncompressedSize)
+       if size == uint32max {
+               size = f.UncompressedSize64
+       }
+       if g := uint64(b.Len()); g != size {
+               t.Errorf("%v: read %v bytes but f.UncompressedSize == %v", f.Name, g, size)
+       }
+
        var c []byte
        if ft.Content != nil {
                c = ft.Content
index c046f081b736cd4cb884029097a1308595459d6b..4211ec7af7ba8ee56c5dcd194959230c5a000e07 100644 (file)
@@ -6,6 +6,7 @@ package zip
 
 import (
        "compress/flate"
+       "errors"
        "io"
        "io/ioutil"
        "sync"
@@ -21,12 +22,50 @@ type Compressor func(io.Writer) (io.WriteCloser, error)
 // when they're finished reading.
 type Decompressor func(io.Reader) io.ReadCloser
 
+var flateWriterPool sync.Pool
+
+func newFlateWriter(w io.Writer) io.WriteCloser {
+       fw, ok := flateWriterPool.Get().(*flate.Writer)
+       if ok {
+               fw.Reset(w)
+       } else {
+               fw, _ = flate.NewWriter(w, 5)
+       }
+       return &pooledFlateWriter{fw: fw}
+}
+
+type pooledFlateWriter struct {
+       mu sync.Mutex // guards Close and Write
+       fw *flate.Writer
+}
+
+func (w *pooledFlateWriter) Write(p []byte) (n int, err error) {
+       w.mu.Lock()
+       defer w.mu.Unlock()
+       if w.fw == nil {
+               return 0, errors.New("Write after Close")
+       }
+       return w.fw.Write(p)
+}
+
+func (w *pooledFlateWriter) Close() error {
+       w.mu.Lock()
+       defer w.mu.Unlock()
+       var err error
+       if w.fw != nil {
+               err = w.fw.Close()
+               flateWriterPool.Put(w.fw)
+               w.fw = nil
+       }
+       return err
+}
+
 var (
        mu sync.RWMutex // guards compressor and decompressor maps
 
        compressors = map[uint16]Compressor{
                Store:   func(w io.Writer) (io.WriteCloser, error) { return &nopCloser{w}, nil },
-               Deflate: func(w io.Writer) (io.WriteCloser, error) { return flate.NewWriter(w, 5) },
+               Deflate: func(w io.Writer) (io.WriteCloser, error) { return newFlateWriter(w), nil },
        }
 
        decompressors = map[uint16]Decompressor{
diff --git a/libgo/go/archive/zip/testdata/zip64-2.zip b/libgo/go/archive/zip/testdata/zip64-2.zip
new file mode 100644 (file)
index 0000000..f844e35
Binary files /dev/null and b/libgo/go/archive/zip/testdata/zip64-2.zip differ
index 8b1c4dfd265f69fae24817ae803fd08719c3947b..4bfa87080906e1d8176de54947a0efea2e701dce 100644 (file)
@@ -125,3 +125,21 @@ func testReadFile(t *testing.T, f *File, wt *WriteTest) {
                t.Errorf("File contents %q, want %q", b, wt.Data)
        }
 }
+
+func BenchmarkCompressedZipGarbage(b *testing.B) {
+       b.ReportAllocs()
+       var buf bytes.Buffer
+       bigBuf := bytes.Repeat([]byte("a"), 1<<20)
+       for i := 0; i < b.N; i++ {
+               buf.Reset()
+               zw := NewWriter(&buf)
+               for j := 0; j < 3; j++ {
+                       w, _ := zw.CreateHeader(&FileHeader{
+                               Name:   "foo",
+                               Method: Deflate,
+                       })
+                       w.Write(bigBuf)
+               }
+               zw.Close()
+       }
+}
index 5cd030714de7cc6f404207071643978a577697b6..3c86857e107c20be9b9120055f92afa031fd24f1 100644 (file)
@@ -65,12 +65,12 @@ func readBytes(buf *Reader) string {
 
 func TestReaderSimple(t *testing.T) {
        data := "hello world"
-       b := NewReader(bytes.NewBufferString(data))
+       b := NewReader(strings.NewReader(data))
        if s := readBytes(b); s != "hello world" {
                t.Errorf("simple hello world test failed: got %q", s)
        }
 
-       b = NewReader(newRot13Reader(bytes.NewBufferString(data)))
+       b = NewReader(newRot13Reader(strings.NewReader(data)))
        if s := readBytes(b); s != "uryyb jbeyq" {
                t.Errorf("rot13 hello world test failed: got %q", s)
        }
@@ -161,7 +161,7 @@ func TestReader(t *testing.T) {
                                        readmaker := readMakers[i]
                                        bufreader := bufreaders[j]
                                        bufsize := bufsizes[k]
-                                       read := readmaker.fn(bytes.NewBufferString(text))
+                                       read := readmaker.fn(strings.NewReader(text))
                                        buf := NewReaderSize(read, bufsize)
                                        s := bufreader.fn(buf)
                                        if s != text {
@@ -479,7 +479,7 @@ func TestWriteErrors(t *testing.T) {
 
 func TestNewReaderSizeIdempotent(t *testing.T) {
        const BufSize = 1000
-       b := NewReaderSize(bytes.NewBufferString("hello world"), BufSize)
+       b := NewReaderSize(strings.NewReader("hello world"), BufSize)
        // Does it recognize itself?
        b1 := NewReaderSize(b, BufSize)
        if b1 != b {
@@ -677,7 +677,7 @@ func TestLineTooLong(t *testing.T) {
        for i := 0; i < minReadBufferSize*5/2; i++ {
                data = append(data, '0'+byte(i%10))
        }
-       buf := bytes.NewBuffer(data)
+       buf := bytes.NewReader(data)
        l := NewReaderSize(buf, minReadBufferSize)
        line, isPrefix, err := l.ReadLine()
        if !isPrefix || !bytes.Equal(line, data[:minReadBufferSize]) || err != nil {
@@ -702,7 +702,7 @@ func TestLineTooLong(t *testing.T) {
 func TestReadAfterLines(t *testing.T) {
        line1 := "this is line1"
        restData := "this is line2\nthis is line 3\n"
-       inbuf := bytes.NewBuffer([]byte(line1 + "\n" + restData))
+       inbuf := bytes.NewReader([]byte(line1 + "\n" + restData))
        outbuf := new(bytes.Buffer)
        maxLineLength := len(line1) + len(restData)/2
        l := NewReaderSize(inbuf, maxLineLength)
@@ -728,7 +728,7 @@ func TestReadEmptyBuffer(t *testing.T) {
 }
 
 func TestLinesAfterRead(t *testing.T) {
-       l := NewReaderSize(bytes.NewBuffer([]byte("foo")), minReadBufferSize)
+       l := NewReaderSize(bytes.NewReader([]byte("foo")), minReadBufferSize)
        _, err := ioutil.ReadAll(l)
        if err != nil {
                t.Error(err)
@@ -818,7 +818,7 @@ func createTestInput(n int) []byte {
 
 func TestReaderWriteTo(t *testing.T) {
        input := createTestInput(8192)
-       r := NewReader(onlyReader{bytes.NewBuffer(input)})
+       r := NewReader(onlyReader{bytes.NewReader(input)})
        w := new(bytes.Buffer)
        if n, err := r.WriteTo(w); err != nil || n != int64(len(input)) {
                t.Fatalf("r.WriteTo(w) = %d, %v, want %d, nil", n, err, len(input))
@@ -877,7 +877,7 @@ func TestWriterReadFrom(t *testing.T) {
                        input := createTestInput(8192)
                        b := new(bytes.Buffer)
                        w := NewWriter(wfunc(b))
-                       r := rfunc(bytes.NewBuffer(input))
+                       r := rfunc(bytes.NewReader(input))
                        if n, err := w.ReadFrom(r); err != nil || n != int64(len(input)) {
                                t.Errorf("ws[%d],rs[%d]: w.ReadFrom(r) = %d, %v, want %d, nil", wi, ri, n, err, len(input))
                                continue
@@ -1112,63 +1112,83 @@ func (w onlyWriter) Write(b []byte) (int, error) {
 
 func BenchmarkReaderCopyOptimal(b *testing.B) {
        // Optimal case is where the underlying reader implements io.WriterTo
+       srcBuf := bytes.NewBuffer(make([]byte, 8192))
+       src := NewReader(srcBuf)
+       dstBuf := new(bytes.Buffer)
+       dst := onlyWriter{dstBuf}
        for i := 0; i < b.N; i++ {
-               b.StopTimer()
-               src := NewReader(bytes.NewBuffer(make([]byte, 8192)))
-               dst := onlyWriter{new(bytes.Buffer)}
-               b.StartTimer()
+               srcBuf.Reset()
+               src.Reset(srcBuf)
+               dstBuf.Reset()
                io.Copy(dst, src)
        }
 }
 
 func BenchmarkReaderCopyUnoptimal(b *testing.B) {
        // Unoptimal case is where the underlying reader doesn't implement io.WriterTo
+       srcBuf := bytes.NewBuffer(make([]byte, 8192))
+       src := NewReader(onlyReader{srcBuf})
+       dstBuf := new(bytes.Buffer)
+       dst := onlyWriter{dstBuf}
        for i := 0; i < b.N; i++ {
-               b.StopTimer()
-               src := NewReader(onlyReader{bytes.NewBuffer(make([]byte, 8192))})
-               dst := onlyWriter{new(bytes.Buffer)}
-               b.StartTimer()
+               srcBuf.Reset()
+               src.Reset(onlyReader{srcBuf})
+               dstBuf.Reset()
                io.Copy(dst, src)
        }
 }
 
 func BenchmarkReaderCopyNoWriteTo(b *testing.B) {
+       srcBuf := bytes.NewBuffer(make([]byte, 8192))
+       srcReader := NewReader(srcBuf)
+       src := onlyReader{srcReader}
+       dstBuf := new(bytes.Buffer)
+       dst := onlyWriter{dstBuf}
        for i := 0; i < b.N; i++ {
-               b.StopTimer()
-               src := onlyReader{NewReader(bytes.NewBuffer(make([]byte, 8192)))}
-               dst := onlyWriter{new(bytes.Buffer)}
-               b.StartTimer()
+               srcBuf.Reset()
+               srcReader.Reset(srcBuf)
+               dstBuf.Reset()
                io.Copy(dst, src)
        }
 }
 
 func BenchmarkWriterCopyOptimal(b *testing.B) {
        // Optimal case is where the underlying writer implements io.ReaderFrom
+       srcBuf := bytes.NewBuffer(make([]byte, 8192))
+       src := onlyReader{srcBuf}
+       dstBuf := new(bytes.Buffer)
+       dst := NewWriter(dstBuf)
        for i := 0; i < b.N; i++ {
-               b.StopTimer()
-               src := onlyReader{bytes.NewBuffer(make([]byte, 8192))}
-               dst := NewWriter(new(bytes.Buffer))
-               b.StartTimer()
+               srcBuf.Reset()
+               dstBuf.Reset()
+               dst.Reset(dstBuf)
                io.Copy(dst, src)
        }
 }
 
 func BenchmarkWriterCopyUnoptimal(b *testing.B) {
+       srcBuf := bytes.NewBuffer(make([]byte, 8192))
+       src := onlyReader{srcBuf}
+       dstBuf := new(bytes.Buffer)
+       dst := NewWriter(onlyWriter{dstBuf})
        for i := 0; i < b.N; i++ {
-               b.StopTimer()
-               src := onlyReader{bytes.NewBuffer(make([]byte, 8192))}
-               dst := NewWriter(onlyWriter{new(bytes.Buffer)})
-               b.StartTimer()
+               srcBuf.Reset()
+               dstBuf.Reset()
+               dst.Reset(onlyWriter{dstBuf})
                io.Copy(dst, src)
        }
 }
 
 func BenchmarkWriterCopyNoReadFrom(b *testing.B) {
+       srcBuf := bytes.NewBuffer(make([]byte, 8192))
+       src := onlyReader{srcBuf}
+       dstBuf := new(bytes.Buffer)
+       dstWriter := NewWriter(dstBuf)
+       dst := onlyWriter{dstWriter}
        for i := 0; i < b.N; i++ {
-               b.StopTimer()
-               src := onlyReader{bytes.NewBuffer(make([]byte, 8192))}
-               dst := onlyWriter{NewWriter(new(bytes.Buffer))}
-               b.StartTimer()
+               srcBuf.Reset()
+               dstBuf.Reset()
+               dstWriter.Reset(dstBuf)
                io.Copy(dst, src)
        }
 }
index 423505fbcbbb232219c4b927a024d92ebba44a7a..77b2c2ac6f8472fa55e56bb8600d17338aa32ea9 100644 (file)
@@ -306,7 +306,7 @@ func isSpace(r rune) bool {
                return true
        }
        switch r {
-       case '\u1680', '\u180e', '\u2028', '\u2029', '\u202f', '\u205f', '\u3000':
+       case '\u1680', '\u2028', '\u2029', '\u202f', '\u205f', '\u3000':
                return true
        }
        return false
index c1483b2685855da7b49c560e95ccc73549356c04..4ac529fd6dd71ea797e13bfd4383424bd8201081 100644 (file)
@@ -38,7 +38,7 @@ var scanTests = []string{
 
 func TestScanByte(t *testing.T) {
        for n, test := range scanTests {
-               buf := bytes.NewBufferString(test)
+               buf := strings.NewReader(test)
                s := NewScanner(buf)
                s.Split(ScanBytes)
                var i int
@@ -60,7 +60,7 @@ func TestScanByte(t *testing.T) {
 // Test that the rune splitter returns same sequence of runes (not bytes) as for range string.
 func TestScanRune(t *testing.T) {
        for n, test := range scanTests {
-               buf := bytes.NewBufferString(test)
+               buf := strings.NewReader(test)
                s := NewScanner(buf)
                s.Split(ScanRunes)
                var i, runeCount int
@@ -104,7 +104,7 @@ var wordScanTests = []string{
 // Test that the word splitter returns the same data as strings.Fields.
 func TestScanWords(t *testing.T) {
        for n, test := range wordScanTests {
-               buf := bytes.NewBufferString(test)
+               buf := strings.NewReader(test)
                s := NewScanner(buf)
                s.Split(ScanWords)
                words := strings.Fields(test)
@@ -135,7 +135,7 @@ func TestScanWords(t *testing.T) {
 // reads in Scanner.Scan.
 type slowReader struct {
        max int
-       buf *bytes.Buffer
+       buf io.Reader
 }
 
 func (sr *slowReader) Read(p []byte) (n int, err error) {
@@ -248,7 +248,7 @@ func TestScanLineTooLong(t *testing.T) {
 
 // Test that the line splitter handles a final line without a newline.
 func testNoNewline(text string, lines []string, t *testing.T) {
-       buf := bytes.NewBufferString(text)
+       buf := strings.NewReader(text)
        s := NewScanner(&slowReader{7, buf})
        s.Split(ScanLines)
        for lineNum := 0; s.Scan(); lineNum++ {
@@ -328,7 +328,7 @@ func TestSplitError(t *testing.T) {
        }
        // Read the data.
        const text = "abcdefghijklmnopqrstuvwxyz"
-       buf := bytes.NewBufferString(text)
+       buf := strings.NewReader(text)
        s := NewScanner(&slowReader{1, buf})
        s.Split(errorSplit)
        var i int
index ada1f9a001636ff977061007ae452350db047496..cd647e5ae0048031b17d2f2331cf969a24475ada 100644 (file)
@@ -14,7 +14,7 @@ import (
 )
 
 func TestBitReader(t *testing.T) {
-       buf := bytes.NewBuffer([]byte{0xaa})
+       buf := bytes.NewReader([]byte{0xaa})
        br := newBitReader(buf)
        if n := br.ReadBits(1); n != 1 {
                t.Errorf("read 1 wrong")
@@ -31,7 +31,7 @@ func TestBitReader(t *testing.T) {
 }
 
 func TestBitReaderLarge(t *testing.T) {
-       buf := bytes.NewBuffer([]byte{0x12, 0x34, 0x56, 0x78})
+       buf := bytes.NewReader([]byte{0x12, 0x34, 0x56, 0x78})
        br := newBitReader(buf)
        if n := br.ReadBits(32); n != 0x12345678 {
                t.Errorf("got: %x want: %x", n, 0x12345678)
@@ -43,7 +43,7 @@ func readerFromHex(s string) io.Reader {
        if err != nil {
                panic("readerFromHex: bad input")
        }
-       return bytes.NewBuffer(data)
+       return bytes.NewReader(data)
 }
 
 func decompressHex(s string) (out []byte, err error) {
@@ -191,7 +191,7 @@ func benchmarkDecode(b *testing.B, testfile int) {
        }
        b.SetBytes(int64(len(compressed)))
        for i := 0; i < b.N; i++ {
-               r := bytes.NewBuffer(compressed)
+               r := bytes.NewReader(compressed)
                io.Copy(ioutil.Discard, NewReader(r))
        }
 }
@@ -201,7 +201,7 @@ func BenchmarkDecodeTwain(b *testing.B)  { benchmarkDecode(b, twain) }
 
 func TestBufferOverrun(t *testing.T) {
        // Tests https://code.google.com/p/go/issues/detail?id=5747.
-       buffer := bytes.NewBuffer([]byte(bufferOverrunBase64))
+       buffer := bytes.NewReader([]byte(bufferOverrunBase64))
        decoder := base64.NewDecoder(base64.StdEncoding, buffer)
        decompressor := NewReader(decoder)
        // This shouldn't panic.
index 8f6b0c9cad33789f6c2622020404fcb00cacafba..75a6223d8134c42fb41ba9c95050a2bc2c45271e 100644 (file)
@@ -190,7 +190,37 @@ func buildHuffmanNode(t *huffmanTree, codes []huffmanCode, level uint32) (nodeIn
        right := codes[firstRightIndex:]
 
        if len(left) == 0 || len(right) == 0 {
-               return 0, StructuralError("superfluous level in Huffman tree")
+               // There is a superfluous level in the Huffman tree indicating
+               // a bug in the encoder. However, this bug has been observed in
+               // the wild so we handle it.
+
+               // If this function was called recursively then we know that
+               // len(codes) >= 2 because, otherwise, we would have hit the
+               // "leaf node" case, below, and not recursed.
+               //
+               // However, for the initial call it's possible that len(codes)
+               // is zero or one. Both cases are invalid because a zero length
+               // tree cannot encode anything and a length-1 tree can only
+               // encode EOF and so is superfluous. We reject both.
+               if len(codes) < 2 {
+                       return 0, StructuralError("empty Huffman tree")
+               }
+
+               // In this case the recursion doesn't always reduce the length
+               // of codes so we need to ensure termination via another
+               // mechanism.
+               if level == 31 {
+                       // Since len(codes) >= 2 the only way that the values
+                       // can match at all 32 bits is if they are equal, which
+                       // is invalid. This ensures that we never enter
+                       // infinite recursion.
+                       return 0, StructuralError("equal symbols in Huffman tree")
+               }
+
+               if len(left) == 0 {
+                       return buildHuffmanNode(t, right, level+1)
+               }
+               return buildHuffmanNode(t, left, level+1)
        }
 
        nodeIndex = uint16(t.nextNode)
index 57fea5ab4dcfa65a207a60396827d510ae13962f..068766323358ecb74ab82c63c5f4e0c9636c5d93 100644 (file)
@@ -14,7 +14,7 @@ import (
 )
 
 func TestUncompressedSource(t *testing.T) {
-       decoder := NewReader(bytes.NewBuffer([]byte{0x01, 0x01, 0x00, 0xfe, 0xff, 0x11}))
+       decoder := NewReader(bytes.NewReader([]byte{0x01, 0x01, 0x00, 0xfe, 0xff, 0x11}))
        output := make([]byte, 1)
        n, error := decoder.Read(output)
        if n != 1 || error != nil {
index 572fb584885fbfd35e73abfe2f84e3b938ecf6f2..561537373770fdb5713aa151dba523ba008dca36 100644 (file)
@@ -284,7 +284,7 @@ var gunzipTests = []gunzipTest{
 func TestDecompressor(t *testing.T) {
        b := new(bytes.Buffer)
        for _, tt := range gunzipTests {
-               in := bytes.NewBuffer(tt.gzip)
+               in := bytes.NewReader(tt.gzip)
                gzip, err := NewReader(in)
                if err != nil {
                        t.Errorf("%s: NewReader: %s", tt.name, err)
index 119be2e135be34defe891aa2b7226f92305bfa83..09271b24e92037492a7e9e753ec58f96a88d8ace 100644 (file)
@@ -85,7 +85,7 @@ func TestRoundTrip(t *testing.T) {
 func TestLatin1(t *testing.T) {
        latin1 := []byte{0xc4, 'u', 0xdf, 'e', 'r', 'u', 'n', 'g', 0}
        utf8 := "Äußerung"
-       z := Reader{r: bufio.NewReader(bytes.NewBuffer(latin1))}
+       z := Reader{r: bufio.NewReader(bytes.NewReader(latin1))}
        s, err := z.readString()
        if err != nil {
                t.Fatalf("readString: %v", err)
index 6f155b1bdee76ee543e1cb5bf7316c11da72fbcb..9006c91c233c62bf5ca585c5c652451322223a1b 100644 (file)
@@ -127,7 +127,7 @@ func benchmarkDecoder(b *testing.B, n int) {
                if len(buf0) > n-i {
                        buf0 = buf0[:n-i]
                }
-               io.Copy(w, bytes.NewBuffer(buf0))
+               w.Write(buf0)
        }
        w.Close()
        buf1 := compressed.Bytes()
@@ -135,7 +135,7 @@ func benchmarkDecoder(b *testing.B, n int) {
        runtime.GC()
        b.StartTimer()
        for i := 0; i < b.N; i++ {
-               io.Copy(ioutil.Discard, NewReader(bytes.NewBuffer(buf1), LSB, 8))
+               io.Copy(ioutil.Discard, NewReader(bytes.NewReader(buf1), LSB, 8))
        }
 }
 
index 3b02a086845806222e48910920b50c855092a02e..218ccba14110fcdcd0a64a778891c377d454284b 100644 (file)
@@ -102,7 +102,7 @@ var zlibTests = []zlibTest{
 func TestDecompressor(t *testing.T) {
        b := new(bytes.Buffer)
        for _, tt := range zlibTests {
-               in := bytes.NewBuffer(tt.compressed)
+               in := bytes.NewReader(tt.compressed)
                zlib, err := NewReaderDict(in, tt.dict)
                if err != nil {
                        if err != tt.err {
index 52c8507b4219bfe9af5a19d449b2fcf0bd2b5e52..3fe2327ad2dab76673edc1b63e6a1eb07d5b9d6c 100644 (file)
@@ -22,7 +22,7 @@ import "sort"
 // min-heap with the following invariants (established after
 // Init has been called or if the data is empty or sorted):
 //
-//     !h.Less(j, i) for 0 <= i < h.Len() and j = 2*i+1 or 2*i+2 and j < h.Len()
+//     !h.Less(j, i) for 0 <= i < h.Len() and 2*i+1 <= j <= 2*i+2 and j < h.Len()
 //
 // Note that Push and Pop in this interface are for package heap's
 // implementation to call.  To add and remove things from the heap,
index 1cc7e311bb896996baa9a9f55e129adb78c23502..0256768efe58adab88c3a89a60946b606e6336a0 100755 (executable)
@@ -180,18 +180,18 @@ func (l *List) MoveToBack(e *Element) {
 }
 
 // MoveBefore moves element e to its new position before mark.
-// If e is not an element of l, or e == mark, the list is not modified.
+// If e or mark is not an element of l, or e == mark, the list is not modified.
 func (l *List) MoveBefore(e, mark *Element) {
-       if e.list != l || e == mark {
+       if e.list != l || e == mark || mark.list != l {
                return
        }
        l.insert(l.remove(e), mark.prev)
 }
 
 // MoveAfter moves element e to its new position after mark.
-// If e is not an element of l, or e == mark, the list is not modified.
+// If e or mark is not an element of l, or e == mark, the list is not modified.
 func (l *List) MoveAfter(e, mark *Element) {
-       if e.list != l || e == mark {
+       if e.list != l || e == mark || mark.list != l {
                return
        }
        l.insert(l.remove(e), mark)
index df06c423fe5b7dc558861a6e3848c32a58100e84..4d8bfc2bf0791bd6148420e374e306e1a0dd3beb 100755 (executable)
@@ -324,3 +324,20 @@ func TestInsertAfterUnknownMark(t *testing.T) {
        l.InsertAfter(1, new(Element))
        checkList(t, &l, []interface{}{1, 2, 3})
 }
+
+// Test that a list l is not modified when calling MoveAfter or MoveBefore with a mark that is not an element of l.
+func TestMoveUnkownMark(t *testing.T) {
+       var l1 List
+       e1 := l1.PushBack(1)
+
+       var l2 List
+       e2 := l2.PushBack(2)
+
+       l1.MoveAfter(e1, e2)
+       checkList(t, &l1, []interface{}{1})
+       checkList(t, &l2, []interface{}{2})
+
+       l1.MoveBefore(e1, e2)
+       checkList(t, &l1, []interface{}{1})
+       checkList(t, &l2, []interface{}{2})
+}
index 9a2aece0e1b5f33020295ad6c23d931ddbac9844..241e122ee80079e31e36d6b545ba9b00a4893fd6 100644 (file)
@@ -48,13 +48,22 @@ func (x *cbcEncrypter) CryptBlocks(dst, src []byte) {
        if len(dst) < len(src) {
                panic("crypto/cipher: output smaller than input")
        }
+
+       iv := x.iv
+
        for len(src) > 0 {
-               xorBytes(x.iv, x.iv, src[:x.blockSize])
-               x.b.Encrypt(x.iv, x.iv)
-               copy(dst, x.iv)
+               // Write the xor to dst, then encrypt in place.
+               xorBytes(dst[:x.blockSize], src[:x.blockSize], iv)
+               x.b.Encrypt(dst[:x.blockSize], dst[:x.blockSize])
+
+               // Move to the next block with this block as the next iv.
+               iv = dst[:x.blockSize]
                src = src[x.blockSize:]
                dst = dst[x.blockSize:]
        }
+
+       // Save the iv for the next CryptBlocks call.
+       copy(x.iv, iv)
 }
 
 func (x *cbcEncrypter) SetIV(iv []byte) {
@@ -85,14 +94,35 @@ func (x *cbcDecrypter) CryptBlocks(dst, src []byte) {
        if len(dst) < len(src) {
                panic("crypto/cipher: output smaller than input")
        }
-       for len(src) > 0 {
-               x.b.Decrypt(x.tmp, src[:x.blockSize])
-               xorBytes(x.tmp, x.tmp, x.iv)
-               copy(x.iv, src)
-               copy(dst, x.tmp)
-               src = src[x.blockSize:]
-               dst = dst[x.blockSize:]
+       if len(src) == 0 {
+               return
        }
+
+       // For each block, we need to xor the decrypted data with the previous block's ciphertext (the iv).
+       // To avoid making a copy each time, we loop over the blocks BACKWARDS.
+       end := len(src)
+       start := end - x.blockSize
+       prev := start - x.blockSize
+
+       // Copy the last block of ciphertext in preparation as the new iv.
+       copy(x.tmp, src[start:end])
+
+       // Loop over all but the first block.
+       for start > 0 {
+               x.b.Decrypt(dst[start:end], src[start:end])
+               xorBytes(dst[start:end], dst[start:end], src[prev:start])
+
+               end = start
+               start = prev
+               prev -= x.blockSize
+       }
+
+       // The first block is special because it uses the saved iv.
+       x.b.Decrypt(dst[start:end], src[start:end])
+       xorBytes(dst[start:end], dst[start:end], x.iv)
+
+       // Set the new iv to the first block we copied earlier.
+       x.iv, x.tmp = x.tmp, x.iv
 }
 
 func (x *cbcDecrypter) SetIV(iv []byte) {
index cee3a784b5074949a3916912d6a9ea4ae9ff393c..bf9e7ad7018a290cbd199cd50ebd49e12cae3068 100644 (file)
@@ -63,28 +63,42 @@ var cbcAESTests = []struct {
        },
 }
 
-func TestCBC_AES(t *testing.T) {
-       for _, tt := range cbcAESTests {
-               test := tt.name
-
-               c, err := aes.NewCipher(tt.key)
+func TestCBCEncrypterAES(t *testing.T) {
+       for _, test := range cbcAESTests {
+               c, err := aes.NewCipher(test.key)
                if err != nil {
-                       t.Errorf("%s: NewCipher(%d bytes) = %s", test, len(tt.key), err)
+                       t.Errorf("%s: NewCipher(%d bytes) = %s", test.name, len(test.key), err)
                        continue
                }
 
-               encrypter := cipher.NewCBCEncrypter(c, tt.iv)
-               d := make([]byte, len(tt.in))
-               encrypter.CryptBlocks(d, tt.in)
-               if !bytes.Equal(tt.out, d) {
-                       t.Errorf("%s: CBCEncrypter\nhave %x\nwant %x", test, d, tt.out)
+               encrypter := cipher.NewCBCEncrypter(c, test.iv)
+
+               data := make([]byte, len(test.in))
+               copy(data, test.in)
+
+               encrypter.CryptBlocks(data, data)
+               if !bytes.Equal(test.out, data) {
+                       t.Errorf("%s: CBCEncrypter\nhave %x\nwant %x", test.name, data, test.out)
                }
+       }
+}
+
+func TestCBCDecrypterAES(t *testing.T) {
+       for _, test := range cbcAESTests {
+               c, err := aes.NewCipher(test.key)
+               if err != nil {
+                       t.Errorf("%s: NewCipher(%d bytes) = %s", test.name, len(test.key), err)
+                       continue
+               }
+
+               decrypter := cipher.NewCBCDecrypter(c, test.iv)
+
+               data := make([]byte, len(test.out))
+               copy(data, test.out)
 
-               decrypter := cipher.NewCBCDecrypter(c, tt.iv)
-               p := make([]byte, len(d))
-               decrypter.CryptBlocks(p, d)
-               if !bytes.Equal(tt.in, p) {
-                       t.Errorf("%s: CBCDecrypter\nhave %x\nwant %x", test, d, tt.in)
+               decrypter.CryptBlocks(data, data)
+               if !bytes.Equal(test.in, data) {
+                       t.Errorf("%s: CBCDecrypter\nhave %x\nwant %x", test.name, data, test.in)
                }
        }
 }
index 397e2647e4bef36c000a4c8004ec8c90b6d21358..75295e4fcb070a21ad94bb491da7e858a2db3aa5 100644 (file)
@@ -167,8 +167,6 @@ var program = `// Copyright 2013 The Go Authors. All rights reserved.
 // DO NOT EDIT.
 // Generate with: go run gen.go{{if .Full}} -full{{end}} | gofmt >md5block.go
 
-// +build !amd64,!386,!arm
-
 package md5
 
 import (
@@ -204,7 +202,7 @@ func init() {
        littleEndian = *(*[4]byte)(unsafe.Pointer(&x)) == y
 }
 
-func block(dig *digest, p []byte) {
+func blockGeneric(dig *digest, p []byte) {
        a := dig.s[0]
        b := dig.s[1]
        c := dig.s[2]
index a8b7a1a525284b3f72cb32ca3b8cf6f26312cac7..e7faf4961e43cce6c96c515bd38b39c0a874719d 100644 (file)
@@ -5,6 +5,7 @@
 package md5
 
 import (
+       "crypto/rand"
        "fmt"
        "io"
        "testing"
@@ -105,6 +106,18 @@ func TestLarge(t *testing.T) {
        }
 }
 
+// Tests that blockGeneric (pure Go) and block (in assembly for amd64, 386, arm) match.
+func TestBlockGeneric(t *testing.T) {
+       gen, asm := New().(*digest), New().(*digest)
+       buf := make([]byte, BlockSize*20) // arbitrary factor
+       rand.Read(buf)
+       blockGeneric(gen, buf)
+       block(asm, buf)
+       if *gen != *asm {
+               t.Error("block and blockGeneric resulted in different states")
+       }
+}
+
 var bench = New()
 var buf = make([]byte, 8192+1)
 var sum = make([]byte, bench.Size())
index c1a87e4640bb969ccab76d8ab03ce1153ca27190..e2a17677757e55ac0b07d2477513fb38734524ba 100644 (file)
@@ -5,8 +5,6 @@
 // DO NOT EDIT.
 // Generate with: go run gen.go -full | gofmt >md5block.go
 
-// +build !amd64,!386,!arm
-
 package md5
 
 import (
@@ -24,7 +22,7 @@ func init() {
        littleEndian = *(*[4]byte)(unsafe.Pointer(&x)) == y
 }
 
-func block(dig *digest, p []byte) {
+func blockGeneric(dig *digest, p []byte) {
        a := dig.s[0]
        b := dig.s[1]
        c := dig.s[2]
diff --git a/libgo/go/crypto/md5/md5block_generic.go b/libgo/go/crypto/md5/md5block_generic.go
new file mode 100644 (file)
index 0000000..239bf4d
--- /dev/null
@@ -0,0 +1,9 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !amd64,!386,!arm
+
+package md5
+
+var block = blockGeneric
index 238ceee557dbcb391cf09e2941186d04af0c5c69..0fbd7eaf5794bab6492f4e84d894df833cf42bf6 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin dragonfly freebsd linux netbsd openbsd plan9
+// +build darwin dragonfly freebsd linux netbsd openbsd plan9 solaris
 
 // Unix cryptographically secure pseudorandom number
 // generator.
index 33f9820371a7166522a67a25cbc5f2238d304dfd..1e2a4dd84b715da3478e242f69e48e80552bb425 100644 (file)
@@ -6,6 +6,7 @@ package rand_test
 
 import (
        "crypto/rand"
+       "math/big"
        "testing"
 )
 
@@ -24,3 +25,41 @@ func TestPrimeSmall(t *testing.T) {
                }
        }
 }
+
+// Test that passing bits < 2 causes Prime to return nil, error
+func TestPrimeBitsLt2(t *testing.T) {
+       if p, err := rand.Prime(rand.Reader, 1); p != nil || err == nil {
+               t.Errorf("Prime should return nil, error when called with bits < 2")
+       }
+}
+
+func TestInt(t *testing.T) {
+       // start at 128 so the case of (max.BitLen() % 8) == 0 is covered
+       for n := 128; n < 140; n++ {
+               b := new(big.Int).SetInt64(int64(n))
+               if i, err := rand.Int(rand.Reader, b); err != nil {
+                       t.Fatalf("Can't generate random value: %v, %v", i, err)
+               }
+       }
+}
+
+func testIntPanics(t *testing.T, b *big.Int) {
+       defer func() {
+               if err := recover(); err == nil {
+                       t.Errorf("Int should panic when called with max <= 0: %v", b)
+               }
+       }()
+       rand.Int(rand.Reader, b)
+}
+
+// Test that passing a new big.Int as max causes Int to panic
+func TestIntEmptyMaxPanics(t *testing.T) {
+       b := new(big.Int)
+       testIntPanics(t, b)
+}
+
+// Test that passing a negative value as max causes Int to panic
+func TestIntNegativeMaxPanics(t *testing.T) {
+       b := new(big.Int).SetInt64(int64(-1))
+       testIntPanics(t, b)
+}
index 3d717c63b0c81cee2e51aa90b404cc6e91446d02..9acb681bfb64e5f8ae875049ed9d071d4f65a0f2 100644 (file)
@@ -50,3 +50,20 @@ func (c *Cipher) Reset() {
        }
        c.i, c.j = 0, 0
 }
+
+// xorKeyStreamGeneric sets dst to the result of XORing src with the
+// key stream.  Dst and src may be the same slice but otherwise should
+// not overlap.
+//
+// This is the pure Go version. rc4_{amd64,386,arm}* contain assembly
+// implementations. This is here for tests and to prevent bitrot.
+func (c *Cipher) xorKeyStreamGeneric(dst, src []byte) {
+       i, j := c.i, c.j
+       for k, v := range src {
+               i += 1
+               j += uint8(c.s[i])
+               c.s[i], c.s[j] = c.s[j], c.s[i]
+               dst[k] = v ^ uint8(c.s[uint8(c.s[i]+c.s[j])])
+       }
+       c.i, c.j = i, j
+}
index bca4d28e1d1d8a2d6a2b5763395dea9bc88a9c10..bdf5e1db2ddf127801d7b182bacf0e08d726adf6 100644 (file)
@@ -9,12 +9,5 @@ package rc4
 // XORKeyStream sets dst to the result of XORing src with the key stream.
 // Dst and src may be the same slice but otherwise should not overlap.
 func (c *Cipher) XORKeyStream(dst, src []byte) {
-       i, j := c.i, c.j
-       for k, v := range src {
-               i += 1
-               j += uint8(c.s[i])
-               c.s[i], c.s[j] = c.s[j], c.s[i]
-               dst[k] = v ^ uint8(c.s[uint8(c.s[i]+c.s[j])])
-       }
-       c.i, c.j = i, j
+       c.xorKeyStreamGeneric(dst, src)
 }
index 7b4df6791d9aa4629e7c14322cec1478fc0d9863..af7988246329d5c4018db2506ebcfcb19427e071 100644 (file)
@@ -117,19 +117,30 @@ func TestGolden(t *testing.T) {
 }
 
 func TestBlock(t *testing.T) {
+       testBlock(t, (*Cipher).XORKeyStream)
+}
+
+// Test the pure Go version.
+// Because we have assembly for amd64, 386, and arm, this prevents
+// bitrot of the reference implementations.
+func TestBlockGeneric(t *testing.T) {
+       testBlock(t, (*Cipher).xorKeyStreamGeneric)
+}
+
+func testBlock(t *testing.T, xor func(c *Cipher, dst, src []byte)) {
        c1a, _ := NewCipher(golden[0].key)
        c1b, _ := NewCipher(golden[1].key)
        data1 := make([]byte, 1<<20)
        for i := range data1 {
-               c1a.XORKeyStream(data1[i:i+1], data1[i:i+1])
-               c1b.XORKeyStream(data1[i:i+1], data1[i:i+1])
+               xor(c1a, data1[i:i+1], data1[i:i+1])
+               xor(c1b, data1[i:i+1], data1[i:i+1])
        }
 
        c2a, _ := NewCipher(golden[0].key)
        c2b, _ := NewCipher(golden[1].key)
        data2 := make([]byte, 1<<20)
-       c2a.XORKeyStream(data2, data2)
-       c2b.XORKeyStream(data2, data2)
+       xor(c2a, data2, data2)
+       xor(c2b, data2, data2)
 
        if !bytes.Equal(data1, data2) {
                t.Fatalf("bad block")
index c7353ea311aadc87c15c756b86073187a507e458..c8f1febe64705e2306c794036c7c64045d371050 100644 (file)
@@ -120,16 +120,18 @@ func (priv *PrivateKey) Validate() error {
        return nil
 }
 
-// GenerateKey generates an RSA keypair of the given bit size.
+// GenerateKey generates an RSA keypair of the given bit size using the
+// random source random (for example, crypto/rand.Reader).
 func GenerateKey(random io.Reader, bits int) (priv *PrivateKey, err error) {
        return GenerateMultiPrimeKey(random, 2, bits)
 }
 
 // GenerateMultiPrimeKey generates a multi-prime RSA keypair of the given bit
-// size, as suggested in [1]. Although the public keys are compatible
-// (actually, indistinguishable) from the 2-prime case, the private keys are
-// not. Thus it may not be possible to export multi-prime private keys in
-// certain formats or to subsequently import them into other code.
+// size and the given random source, as suggested in [1]. Although the public
+// keys are compatible (actually, indistinguishable) from the 2-prime case,
+// the private keys are not. Thus it may not be possible to export multi-prime
+// private keys in certain formats or to subsequently import them into other
+// code.
 //
 // Table 1 in [2] suggests maximum numbers of primes for a given size.
 //
index cf193c669f3d7e452cbc525226af28a230d5e46a..4ee1c3a8b2afc6e4be23c041f7b40629a61c1e1b 100644 (file)
@@ -197,7 +197,7 @@ func TestEncryptOAEP(t *testing.T) {
                public := PublicKey{n, test.e}
 
                for j, message := range test.msgs {
-                       randomSource := bytes.NewBuffer(message.seed)
+                       randomSource := bytes.NewReader(message.seed)
                        out, err := EncryptOAEP(sha1, randomSource, &public, message.in, nil)
                        if err != nil {
                                t.Errorf("#%d,%d error: %s", i, j, err)
index 6d2a9f24dcb9966ecb4f454b2fddd44a73a17d09..4a629518b761eb3c64813c35c0305a6f227fcbe2 100644 (file)
@@ -7,6 +7,7 @@
 package sha1
 
 import (
+       "crypto/rand"
        "fmt"
        "io"
        "testing"
@@ -90,6 +91,18 @@ func TestBlockSize(t *testing.T) {
        }
 }
 
+// Tests that blockGeneric (pure Go) and block (in assembly for amd64, 386, arm) match.
+func TestBlockGeneric(t *testing.T) {
+       gen, asm := New().(*digest), New().(*digest)
+       buf := make([]byte, BlockSize*20) // arbitrary factor
+       rand.Read(buf)
+       blockGeneric(gen, buf)
+       block(asm, buf)
+       if *gen != *asm {
+               t.Error("block and blockGeneric resulted in different states")
+       }
+}
+
 var bench = New()
 var buf = make([]byte, 8192)
 
index 92224fc0ef8fa17421afb784f4fbe2e40d394496..fde3c981c083f46c24b620c63758200df8c238b0 100644 (file)
@@ -2,12 +2,6 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !amd64,!386
-
-// SHA1 block step.
-// In its own file so that a faster assembly or C version
-// can be substituted easily.
-
 package sha1
 
 const (
@@ -17,7 +11,9 @@ const (
        _K3 = 0xCA62C1D6
 )
 
-func block(dig *digest, p []byte) {
+// blockGeneric is a portable, pure Go version of the SHA1 block step.
+// It's used by sha1block_generic.go and tests.
+func blockGeneric(dig *digest, p []byte) {
        var w [16]uint32
 
        h0, h1, h2, h3, h4 := dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4]
index 4cb157fff6d608809f8c63f5f7e28090df406065..b2c68f0e8baaf2f1d65d18f278530e4ebe1afea4 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build amd64 386
+// +build amd64 386 arm
 
 package sha1
 
diff --git a/libgo/go/crypto/sha1/sha1block_generic.go b/libgo/go/crypto/sha1/sha1block_generic.go
new file mode 100644 (file)
index 0000000..2c78683
--- /dev/null
@@ -0,0 +1,9 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !amd64,!386,!arm
+
+package sha1
+
+var block = blockGeneric
index dfb658465e9bdffaec2e5f7f0b1165c8ee6b8661..de1a4e8c54da1a4c59d6f88b9b3e78a9fe68f44e 100644 (file)
@@ -10,6 +10,10 @@ package subtle
 // and y, have equal contents. The time taken is a function of the length of
 // the slices and is independent of the contents.
 func ConstantTimeCompare(x, y []byte) int {
+       if len(x) != len(y) {
+               panic("subtle: slices have different lengths")
+       }
+
        var v byte
 
        for i := 0; i < len(x); i++ {
index b7229d29f8b73499770b5039f65c6e398ac1ed84..7ce2077de41aaf70b3f687c63f0414e435f8bf7d 100644 (file)
@@ -5,9 +5,11 @@
 package tls
 
 import (
+       "container/list"
        "crypto"
        "crypto/rand"
        "crypto/x509"
+       "fmt"
        "io"
        "math/big"
        "strings"
@@ -64,7 +66,7 @@ const (
 )
 
 // TLS extension numbers
-var (
+const (
        extensionServerName          uint16 = 0
        extensionStatusRequest       uint16 = 5
        extensionSupportedCurves     uint16 = 10
@@ -72,11 +74,17 @@ var (
        extensionSignatureAlgorithms uint16 = 13
        extensionSessionTicket       uint16 = 35
        extensionNextProtoNeg        uint16 = 13172 // not IANA assigned
+       extensionRenegotiationInfo   uint16 = 0xff01
+)
+
+// TLS signaling cipher suite values
+const (
+       scsvRenegotiation uint16 = 0x00ff
 )
 
 // TLS Elliptic Curves
 // http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8
-var (
+const (
        curveP256 uint16 = 23
        curveP384 uint16 = 24
        curveP521 uint16 = 25
@@ -84,7 +92,7 @@ var (
 
 // TLS Elliptic Curve Point Formats
 // http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-9
-var (
+const (
        pointFormatUncompressed uint8 = 0
 )
 
@@ -167,6 +175,29 @@ const (
        RequireAndVerifyClientCert
 )
 
+// ClientSessionState contains the state needed by clients to resume TLS
+// sessions.
+type ClientSessionState struct {
+       sessionTicket      []uint8             // Encrypted ticket used for session resumption with server
+       vers               uint16              // SSL/TLS version negotiated for the session
+       cipherSuite        uint16              // Ciphersuite negotiated for the session
+       masterSecret       []byte              // MasterSecret generated by client on a full handshake
+       serverCertificates []*x509.Certificate // Certificate chain presented by the server
+}
+
+// ClientSessionCache is a cache of ClientSessionState objects that can be used
+// by a client to resume a TLS session with a given server. ClientSessionCache
+// implementations should expect to be called concurrently from different
+// goroutines.
+type ClientSessionCache interface {
+       // Get searches for a ClientSessionState associated with the given key.
+       // On return, ok is true if one was found.
+       Get(sessionKey string) (session *ClientSessionState, ok bool)
+
+       // Put adds the ClientSessionState to the cache with the given key.
+       Put(sessionKey string, cs *ClientSessionState)
+}
+
 // A Config structure is used to configure a TLS client or server. After one
 // has been passed to a TLS function it must not be modified.
 type Config struct {
@@ -200,8 +231,9 @@ type Config struct {
        // NextProtos is a list of supported, application level protocols.
        NextProtos []string
 
-       // ServerName is included in the client's handshake to support virtual
-       // hosting.
+       // ServerName is used to verify the hostname on the returned
+       // certificates unless InsecureSkipVerify is given. It is also included
+       // in the client's handshake to support virtual hosting.
        ServerName string
 
        // ClientAuth determines the server's policy for
@@ -245,6 +277,10 @@ type Config struct {
        // connections using that key are compromised.
        SessionTicketKey [32]byte
 
+       // SessionCache is a cache of ClientSessionState entries for TLS session
+       // resumption.
+       ClientSessionCache ClientSessionCache
+
        // MinVersion contains the minimum SSL/TLS version that is acceptable.
        // If zero, then SSLv3 is taken as the minimum.
        MinVersion uint16
@@ -406,6 +442,77 @@ type handshakeMessage interface {
        unmarshal([]byte) bool
 }
 
+// lruSessionCache is a ClientSessionCache implementation that uses an LRU
+// caching strategy.
+type lruSessionCache struct {
+       sync.Mutex
+
+       m        map[string]*list.Element
+       q        *list.List
+       capacity int
+}
+
+type lruSessionCacheEntry struct {
+       sessionKey string
+       state      *ClientSessionState
+}
+
+// NewLRUClientSessionCache returns a ClientSessionCache with the given
+// capacity that uses an LRU strategy. If capacity is < 1, a default capacity
+// is used instead.
+func NewLRUClientSessionCache(capacity int) ClientSessionCache {
+       const defaultSessionCacheCapacity = 64
+
+       if capacity < 1 {
+               capacity = defaultSessionCacheCapacity
+       }
+       return &lruSessionCache{
+               m:        make(map[string]*list.Element),
+               q:        list.New(),
+               capacity: capacity,
+       }
+}
+
+// Put adds the provided (sessionKey, cs) pair to the cache.
+func (c *lruSessionCache) Put(sessionKey string, cs *ClientSessionState) {
+       c.Lock()
+       defer c.Unlock()
+
+       if elem, ok := c.m[sessionKey]; ok {
+               entry := elem.Value.(*lruSessionCacheEntry)
+               entry.state = cs
+               c.q.MoveToFront(elem)
+               return
+       }
+
+       if c.q.Len() < c.capacity {
+               entry := &lruSessionCacheEntry{sessionKey, cs}
+               c.m[sessionKey] = c.q.PushFront(entry)
+               return
+       }
+
+       elem := c.q.Back()
+       entry := elem.Value.(*lruSessionCacheEntry)
+       delete(c.m, entry.sessionKey)
+       entry.sessionKey = sessionKey
+       entry.state = cs
+       c.q.MoveToFront(elem)
+       c.m[sessionKey] = elem
+}
+
+// Get returns the ClientSessionState value associated with a given key. It
+// returns (nil, false) if no value is found.
+func (c *lruSessionCache) Get(sessionKey string) (*ClientSessionState, bool) {
+       c.Lock()
+       defer c.Unlock()
+
+       if elem, ok := c.m[sessionKey]; ok {
+               c.q.MoveToFront(elem)
+               return elem.Value.(*lruSessionCacheEntry).state, true
+       }
+       return nil, false
+}
+
 // TODO(jsing): Make these available to both crypto/x509 and crypto/tls.
 type dsaSignature struct {
        R, S *big.Int
@@ -435,3 +542,7 @@ func initDefaultCipherSuites() {
                varDefaultCipherSuites[i] = suite.id
        }
 }
+
+func unexpectedMessageError(wanted, got interface{}) error {
+       return fmt.Errorf("tls: received unexpected handshake message of type %T when waiting for %T", got, wanted)
+}
index 2e64b88a68971f35340b1db04facb63abf041674..c33549c9efffa3ee83d17b6f6d21e0eaef213483 100644 (file)
@@ -12,6 +12,7 @@ import (
        "crypto/subtle"
        "crypto/x509"
        "errors"
+       "fmt"
        "io"
        "net"
        "sync"
@@ -518,14 +519,17 @@ func (c *Conn) readRecord(want recordType) error {
        // else application data.  (We don't support renegotiation.)
        switch want {
        default:
-               return c.sendAlert(alertInternalError)
+               c.sendAlert(alertInternalError)
+               return errors.New("tls: unknown record type requested")
        case recordTypeHandshake, recordTypeChangeCipherSpec:
                if c.handshakeComplete {
-                       return c.sendAlert(alertInternalError)
+                       c.sendAlert(alertInternalError)
+                       return errors.New("tls: handshake or ChangeCipherSpec requested after handshake complete")
                }
        case recordTypeApplicationData:
                if !c.handshakeComplete {
-                       return c.sendAlert(alertInternalError)
+                       c.sendAlert(alertInternalError)
+                       return errors.New("tls: application data record requested before handshake complete")
                }
        }
 
@@ -562,10 +566,12 @@ Again:
        vers := uint16(b.data[1])<<8 | uint16(b.data[2])
        n := int(b.data[3])<<8 | int(b.data[4])
        if c.haveVers && vers != c.vers {
-               return c.sendAlert(alertProtocolVersion)
+               c.sendAlert(alertProtocolVersion)
+               return fmt.Errorf("tls: received record with version %x when expecting version %x", vers, c.vers)
        }
        if n > maxCiphertext {
-               return c.sendAlert(alertRecordOverflow)
+               c.sendAlert(alertRecordOverflow)
+               return fmt.Errorf("tls: oversized record received with length %d", n)
        }
        if !c.haveVers {
                // First message, be extra suspicious:
@@ -577,7 +583,8 @@ Again:
                // well under a kilobyte.  If the length is >= 12 kB,
                // it's probably not real.
                if (typ != recordTypeAlert && typ != want) || vers >= 0x1000 || n >= 0x3000 {
-                       return c.sendAlert(alertUnexpectedMessage)
+                       c.sendAlert(alertUnexpectedMessage)
+                       return fmt.Errorf("tls: first record does not look like a TLS handshake")
                }
        }
        if err := b.readFromUntil(c.conn, recordHeaderLen+n); err != nil {
@@ -799,6 +806,8 @@ func (c *Conn) readHandshake() (interface{}, error) {
                m = new(clientHelloMsg)
        case typeServerHello:
                m = new(serverHelloMsg)
+       case typeNewSessionTicket:
+               m = new(newSessionTicketMsg)
        case typeCertificate:
                m = new(certificateMsg)
        case typeCertificateRequest:
@@ -988,10 +997,10 @@ func (c *Conn) VerifyHostname(host string) error {
        c.handshakeMutex.Lock()
        defer c.handshakeMutex.Unlock()
        if !c.isClient {
-               return errors.New("VerifyHostname called on TLS server connection")
+               return errors.New("tls: VerifyHostname called on TLS server connection")
        }
        if !c.handshakeComplete {
-               return errors.New("TLS handshake has not yet been performed")
+               return errors.New("tls: handshake has not yet been performed")
        }
        return c.peerCertificates[0].VerifyHostname(host)
 }
index 85e4adefcb0944a8c88a200ebabd311fbca9c97a..fd1303eebb947ff7d3a35ad46530c44f6460a05c 100644 (file)
@@ -12,24 +12,37 @@ import (
        "crypto/x509"
        "encoding/asn1"
        "errors"
+       "fmt"
        "io"
+       "net"
        "strconv"
 )
 
+type clientHandshakeState struct {
+       c            *Conn
+       serverHello  *serverHelloMsg
+       hello        *clientHelloMsg
+       suite        *cipherSuite
+       finishedHash finishedHash
+       masterSecret []byte
+       session      *ClientSessionState
+}
+
 func (c *Conn) clientHandshake() error {
        if c.config == nil {
                c.config = defaultConfig()
        }
 
        hello := &clientHelloMsg{
-               vers:               c.config.maxVersion(),
-               compressionMethods: []uint8{compressionNone},
-               random:             make([]byte, 32),
-               ocspStapling:       true,
-               serverName:         c.config.ServerName,
-               supportedCurves:    []uint16{curveP256, curveP384, curveP521},
-               supportedPoints:    []uint8{pointFormatUncompressed},
-               nextProtoNeg:       len(c.config.NextProtos) > 0,
+               vers:                c.config.maxVersion(),
+               compressionMethods:  []uint8{compressionNone},
+               random:              make([]byte, 32),
+               ocspStapling:        true,
+               serverName:          c.config.ServerName,
+               supportedCurves:     []uint16{curveP256, curveP384, curveP521},
+               supportedPoints:     []uint8{pointFormatUncompressed},
+               nextProtoNeg:        len(c.config.NextProtos) > 0,
+               secureRenegotiation: true,
        }
 
        possibleCipherSuites := c.config.cipherSuites()
@@ -51,21 +64,61 @@ NextCipherSuite:
                }
        }
 
-       t := uint32(c.config.time().Unix())
-       hello.random[0] = byte(t >> 24)
-       hello.random[1] = byte(t >> 16)
-       hello.random[2] = byte(t >> 8)
-       hello.random[3] = byte(t)
-       _, err := io.ReadFull(c.config.rand(), hello.random[4:])
+       _, err := io.ReadFull(c.config.rand(), hello.random)
        if err != nil {
                c.sendAlert(alertInternalError)
-               return errors.New("short read from Rand")
+               return errors.New("tls: short read from Rand: " + err.Error())
        }
 
        if hello.vers >= VersionTLS12 {
                hello.signatureAndHashes = supportedSKXSignatureAlgorithms
        }
 
+       var session *ClientSessionState
+       var cacheKey string
+       sessionCache := c.config.ClientSessionCache
+       if c.config.SessionTicketsDisabled {
+               sessionCache = nil
+       }
+
+       if sessionCache != nil {
+               hello.ticketSupported = true
+
+               // Try to resume a previously negotiated TLS session, if
+               // available.
+               cacheKey = clientSessionCacheKey(c.conn.RemoteAddr(), c.config)
+               candidateSession, ok := sessionCache.Get(cacheKey)
+               if ok {
+                       // Check that the ciphersuite/version used for the
+                       // previous session are still valid.
+                       cipherSuiteOk := false
+                       for _, id := range hello.cipherSuites {
+                               if id == candidateSession.cipherSuite {
+                                       cipherSuiteOk = true
+                                       break
+                               }
+                       }
+
+                       versOk := candidateSession.vers >= c.config.minVersion() &&
+                               candidateSession.vers <= c.config.maxVersion()
+                       if versOk && cipherSuiteOk {
+                               session = candidateSession
+                       }
+               }
+       }
+
+       if session != nil {
+               hello.sessionTicket = session.sessionTicket
+               // A random session ID is used to detect when the
+               // server accepted the ticket and is resuming a session
+               // (see RFC 5077).
+               hello.sessionId = make([]byte, 16)
+               if _, err := io.ReadFull(c.config.rand(), hello.sessionId); err != nil {
+                       c.sendAlert(alertInternalError)
+                       return errors.New("tls: short read from Rand: " + err.Error())
+               }
+       }
+
        c.writeRecord(recordTypeHandshake, hello.marshal())
 
        msg, err := c.readHandshake()
@@ -74,51 +127,103 @@ NextCipherSuite:
        }
        serverHello, ok := msg.(*serverHelloMsg)
        if !ok {
-               return c.sendAlert(alertUnexpectedMessage)
+               c.sendAlert(alertUnexpectedMessage)
+               return unexpectedMessageError(serverHello, msg)
        }
 
        vers, ok := c.config.mutualVersion(serverHello.vers)
        if !ok || vers < VersionTLS10 {
                // TLS 1.0 is the minimum version supported as a client.
-               return c.sendAlert(alertProtocolVersion)
+               c.sendAlert(alertProtocolVersion)
+               return fmt.Errorf("tls: server selected unsupported protocol version %x", serverHello.vers)
        }
        c.vers = vers
        c.haveVers = true
 
-       finishedHash := newFinishedHash(c.vers)
-       finishedHash.Write(hello.marshal())
-       finishedHash.Write(serverHello.marshal())
+       suite := mutualCipherSuite(c.config.cipherSuites(), serverHello.cipherSuite)
+       if suite == nil {
+               c.sendAlert(alertHandshakeFailure)
+               return fmt.Errorf("tls: server selected an unsupported cipher suite")
+       }
 
-       if serverHello.compressionMethod != compressionNone {
-               return c.sendAlert(alertUnexpectedMessage)
+       hs := &clientHandshakeState{
+               c:            c,
+               serverHello:  serverHello,
+               hello:        hello,
+               suite:        suite,
+               finishedHash: newFinishedHash(c.vers),
+               session:      session,
        }
 
-       if !hello.nextProtoNeg && serverHello.nextProtoNeg {
-               c.sendAlert(alertHandshakeFailure)
-               return errors.New("server advertised unrequested NPN")
+       hs.finishedHash.Write(hs.hello.marshal())
+       hs.finishedHash.Write(hs.serverHello.marshal())
+
+       isResume, err := hs.processServerHello()
+       if err != nil {
+               return err
        }
 
-       suite := mutualCipherSuite(c.config.cipherSuites(), serverHello.cipherSuite)
-       if suite == nil {
-               return c.sendAlert(alertHandshakeFailure)
+       if isResume {
+               if err := hs.establishKeys(); err != nil {
+                       return err
+               }
+               if err := hs.readSessionTicket(); err != nil {
+                       return err
+               }
+               if err := hs.readFinished(); err != nil {
+                       return err
+               }
+               if err := hs.sendFinished(); err != nil {
+                       return err
+               }
+       } else {
+               if err := hs.doFullHandshake(); err != nil {
+                       return err
+               }
+               if err := hs.establishKeys(); err != nil {
+                       return err
+               }
+               if err := hs.sendFinished(); err != nil {
+                       return err
+               }
+               if err := hs.readSessionTicket(); err != nil {
+                       return err
+               }
+               if err := hs.readFinished(); err != nil {
+                       return err
+               }
        }
 
-       msg, err = c.readHandshake()
+       if sessionCache != nil && hs.session != nil && session != hs.session {
+               sessionCache.Put(cacheKey, hs.session)
+       }
+
+       c.didResume = isResume
+       c.handshakeComplete = true
+       c.cipherSuite = suite.id
+       return nil
+}
+
+func (hs *clientHandshakeState) doFullHandshake() error {
+       c := hs.c
+
+       msg, err := c.readHandshake()
        if err != nil {
                return err
        }
        certMsg, ok := msg.(*certificateMsg)
        if !ok || len(certMsg.certificates) == 0 {
-               return c.sendAlert(alertUnexpectedMessage)
+               c.sendAlert(alertUnexpectedMessage)
+               return unexpectedMessageError(certMsg, msg)
        }
-       finishedHash.Write(certMsg.marshal())
+       hs.finishedHash.Write(certMsg.marshal())
 
        certs := make([]*x509.Certificate, len(certMsg.certificates))
        for i, asn1Data := range certMsg.certificates {
                cert, err := x509.ParseCertificate(asn1Data)
                if err != nil {
                        c.sendAlert(alertBadCertificate)
-                       return errors.New("failed to parse certificate from server: " + err.Error())
+                       return errors.New("tls: failed to parse certificate from server: " + err.Error())
                }
                certs[i] = cert
        }
@@ -148,21 +253,23 @@ NextCipherSuite:
        case *rsa.PublicKey, *ecdsa.PublicKey:
                break
        default:
-               return c.sendAlert(alertUnsupportedCertificate)
+               c.sendAlert(alertUnsupportedCertificate)
+               return fmt.Errorf("tls: server's certificate contains an unsupported type of public key: %T", certs[0].PublicKey)
        }
 
        c.peerCertificates = certs
 
-       if serverHello.ocspStapling {
+       if hs.serverHello.ocspStapling {
                msg, err = c.readHandshake()
                if err != nil {
                        return err
                }
                cs, ok := msg.(*certificateStatusMsg)
                if !ok {
-                       return c.sendAlert(alertUnexpectedMessage)
+                       c.sendAlert(alertUnexpectedMessage)
+                       return unexpectedMessageError(cs, msg)
                }
-               finishedHash.Write(cs.marshal())
+               hs.finishedHash.Write(cs.marshal())
 
                if cs.statusType == statusTypeOCSP {
                        c.ocspResponse = cs.response
@@ -174,12 +281,12 @@ NextCipherSuite:
                return err
        }
 
-       keyAgreement := suite.ka(c.vers)
+       keyAgreement := hs.suite.ka(c.vers)
 
        skx, ok := msg.(*serverKeyExchangeMsg)
        if ok {
-               finishedHash.Write(skx.marshal())
-               err = keyAgreement.processServerKeyExchange(c.config, hello, serverHello, certs[0], skx)
+               hs.finishedHash.Write(skx.marshal())
+               err = keyAgreement.processServerKeyExchange(c.config, hs.hello, hs.serverHello, certs[0], skx)
                if err != nil {
                        c.sendAlert(alertUnexpectedMessage)
                        return err
@@ -208,7 +315,7 @@ NextCipherSuite:
                // ClientCertificateType, unless there is some external
                // arrangement to the contrary.
 
-               finishedHash.Write(certReq.marshal())
+               hs.finishedHash.Write(certReq.marshal())
 
                var rsaAvail, ecdsaAvail bool
                for _, certType := range certReq.certificateTypes {
@@ -271,9 +378,10 @@ NextCipherSuite:
 
        shd, ok := msg.(*serverHelloDoneMsg)
        if !ok {
-               return c.sendAlert(alertUnexpectedMessage)
+               c.sendAlert(alertUnexpectedMessage)
+               return unexpectedMessageError(shd, msg)
        }
-       finishedHash.Write(shd.marshal())
+       hs.finishedHash.Write(shd.marshal())
 
        // If the server requested a certificate then we have to send a
        // Certificate message, even if it's empty because we don't have a
@@ -283,17 +391,17 @@ NextCipherSuite:
                if chainToSend != nil {
                        certMsg.certificates = chainToSend.Certificate
                }
-               finishedHash.Write(certMsg.marshal())
+               hs.finishedHash.Write(certMsg.marshal())
                c.writeRecord(recordTypeHandshake, certMsg.marshal())
        }
 
-       preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hello, certs[0])
+       preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hs.hello, certs[0])
        if err != nil {
                c.sendAlert(alertInternalError)
                return err
        }
        if ckx != nil {
-               finishedHash.Write(ckx.marshal())
+               hs.finishedHash.Write(ckx.marshal())
                c.writeRecord(recordTypeHandshake, ckx.marshal())
        }
 
@@ -305,7 +413,7 @@ NextCipherSuite:
 
                switch key := c.config.Certificates[0].PrivateKey.(type) {
                case *ecdsa.PrivateKey:
-                       digest, _, hashId := finishedHash.hashForClientCertificate(signatureECDSA)
+                       digest, _, hashId := hs.finishedHash.hashForClientCertificate(signatureECDSA)
                        r, s, err := ecdsa.Sign(c.config.rand(), key, digest)
                        if err == nil {
                                signed, err = asn1.Marshal(ecdsaSignature{r, s})
@@ -313,7 +421,7 @@ NextCipherSuite:
                        certVerify.signatureAndHash.signature = signatureECDSA
                        certVerify.signatureAndHash.hash = hashId
                case *rsa.PrivateKey:
-                       digest, hashFunc, hashId := finishedHash.hashForClientCertificate(signatureRSA)
+                       digest, hashFunc, hashId := hs.finishedHash.hashForClientCertificate(signatureRSA)
                        signed, err = rsa.SignPKCS1v15(c.config.rand(), key, hashFunc, digest)
                        certVerify.signatureAndHash.signature = signatureRSA
                        certVerify.signatureAndHash.hash = hashId
@@ -321,79 +429,157 @@ NextCipherSuite:
                        err = errors.New("unknown private key type")
                }
                if err != nil {
-                       return c.sendAlert(alertInternalError)
+                       c.sendAlert(alertInternalError)
+                       return errors.New("tls: failed to sign handshake with client certificate: " + err.Error())
                }
                certVerify.signature = signed
 
-               finishedHash.Write(certVerify.marshal())
+               hs.finishedHash.Write(certVerify.marshal())
                c.writeRecord(recordTypeHandshake, certVerify.marshal())
        }
 
-       masterSecret := masterFromPreMasterSecret(c.vers, preMasterSecret, hello.random, serverHello.random)
-       clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
-               keysFromMasterSecret(c.vers, masterSecret, hello.random, serverHello.random, suite.macLen, suite.keyLen, suite.ivLen)
+       hs.masterSecret = masterFromPreMasterSecret(c.vers, preMasterSecret, hs.hello.random, hs.serverHello.random)
+       return nil
+}
+
+func (hs *clientHandshakeState) establishKeys() error {
+       c := hs.c
 
-       var clientCipher interface{}
-       var clientHash macFunction
-       if suite.cipher != nil {
-               clientCipher = suite.cipher(clientKey, clientIV, false /* not for reading */)
-               clientHash = suite.mac(c.vers, clientMAC)
+       clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
+               keysFromMasterSecret(c.vers, hs.masterSecret, hs.hello.random, hs.serverHello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen)
+       var clientCipher, serverCipher interface{}
+       var clientHash, serverHash macFunction
+       if hs.suite.cipher != nil {
+               clientCipher = hs.suite.cipher(clientKey, clientIV, false /* not for reading */)
+               clientHash = hs.suite.mac(c.vers, clientMAC)
+               serverCipher = hs.suite.cipher(serverKey, serverIV, true /* for reading */)
+               serverHash = hs.suite.mac(c.vers, serverMAC)
        } else {
-               clientCipher = suite.aead(clientKey, clientIV)
+               clientCipher = hs.suite.aead(clientKey, clientIV)
+               serverCipher = hs.suite.aead(serverKey, serverIV)
        }
+
+       c.in.prepareCipherSpec(c.vers, serverCipher, serverHash)
        c.out.prepareCipherSpec(c.vers, clientCipher, clientHash)
-       c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
+       return nil
+}
 
-       if serverHello.nextProtoNeg {
-               nextProto := new(nextProtoMsg)
-               proto, fallback := mutualProtocol(c.config.NextProtos, serverHello.nextProtos)
-               nextProto.proto = proto
-               c.clientProtocol = proto
-               c.clientProtocolFallback = fallback
+func (hs *clientHandshakeState) serverResumedSession() bool {
+       // If the server responded with the same sessionId then it means the
+       // sessionTicket is being used to resume a TLS session.
+       return hs.session != nil && hs.hello.sessionId != nil &&
+               bytes.Equal(hs.serverHello.sessionId, hs.hello.sessionId)
+}
 
-               finishedHash.Write(nextProto.marshal())
-               c.writeRecord(recordTypeHandshake, nextProto.marshal())
+func (hs *clientHandshakeState) processServerHello() (bool, error) {
+       c := hs.c
+
+       if hs.serverHello.compressionMethod != compressionNone {
+               c.sendAlert(alertUnexpectedMessage)
+               return false, errors.New("tls: server selected unsupported compression format")
        }
 
-       finished := new(finishedMsg)
-       finished.verifyData = finishedHash.clientSum(masterSecret)
-       finishedHash.Write(finished.marshal())
-       c.writeRecord(recordTypeHandshake, finished.marshal())
+       if !hs.hello.nextProtoNeg && hs.serverHello.nextProtoNeg {
+               c.sendAlert(alertHandshakeFailure)
+               return false, errors.New("server advertised unrequested NPN extension")
+       }
 
-       var serverCipher interface{}
-       var serverHash macFunction
-       if suite.cipher != nil {
-               serverCipher = suite.cipher(serverKey, serverIV, true /* for reading */)
-               serverHash = suite.mac(c.vers, serverMAC)
-       } else {
-               serverCipher = suite.aead(serverKey, serverIV)
+       if hs.serverResumedSession() {
+               // Restore masterSecret and peerCerts from previous state
+               hs.masterSecret = hs.session.masterSecret
+               c.peerCertificates = hs.session.serverCertificates
+               return true, nil
        }
-       c.in.prepareCipherSpec(c.vers, serverCipher, serverHash)
+       return false, nil
+}
+
+func (hs *clientHandshakeState) readFinished() error {
+       c := hs.c
+
        c.readRecord(recordTypeChangeCipherSpec)
        if err := c.error(); err != nil {
                return err
        }
 
-       msg, err = c.readHandshake()
+       msg, err := c.readHandshake()
        if err != nil {
                return err
        }
        serverFinished, ok := msg.(*finishedMsg)
        if !ok {
-               return c.sendAlert(alertUnexpectedMessage)
+               c.sendAlert(alertUnexpectedMessage)
+               return unexpectedMessageError(serverFinished, msg)
        }
 
-       verify := finishedHash.serverSum(masterSecret)
+       verify := hs.finishedHash.serverSum(hs.masterSecret)
        if len(verify) != len(serverFinished.verifyData) ||
                subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 {
-               return c.sendAlert(alertHandshakeFailure)
+               c.sendAlert(alertHandshakeFailure)
+               return errors.New("tls: server's Finished message was incorrect")
        }
+       hs.finishedHash.Write(serverFinished.marshal())
+       return nil
+}
 
-       c.handshakeComplete = true
-       c.cipherSuite = suite.id
+func (hs *clientHandshakeState) readSessionTicket() error {
+       if !hs.serverHello.ticketSupported {
+               return nil
+       }
+
+       c := hs.c
+       msg, err := c.readHandshake()
+       if err != nil {
+               return err
+       }
+       sessionTicketMsg, ok := msg.(*newSessionTicketMsg)
+       if !ok {
+               c.sendAlert(alertUnexpectedMessage)
+               return unexpectedMessageError(sessionTicketMsg, msg)
+       }
+       hs.finishedHash.Write(sessionTicketMsg.marshal())
+
+       hs.session = &ClientSessionState{
+               sessionTicket:      sessionTicketMsg.ticket,
+               vers:               c.vers,
+               cipherSuite:        hs.suite.id,
+               masterSecret:       hs.masterSecret,
+               serverCertificates: c.peerCertificates,
+       }
+
+       return nil
+}
+
+func (hs *clientHandshakeState) sendFinished() error {
+       c := hs.c
+
+       c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
+       if hs.serverHello.nextProtoNeg {
+               nextProto := new(nextProtoMsg)
+               proto, fallback := mutualProtocol(c.config.NextProtos, hs.serverHello.nextProtos)
+               nextProto.proto = proto
+               c.clientProtocol = proto
+               c.clientProtocolFallback = fallback
+
+               hs.finishedHash.Write(nextProto.marshal())
+               c.writeRecord(recordTypeHandshake, nextProto.marshal())
+       }
+
+       finished := new(finishedMsg)
+       finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret)
+       hs.finishedHash.Write(finished.marshal())
+       c.writeRecord(recordTypeHandshake, finished.marshal())
        return nil
 }
 
+// clientSessionCacheKey returns a key used to cache sessionTickets that could
+// be used to resume previously negotiated TLS sessions with a server.
+func clientSessionCacheKey(serverAddr net.Addr, config *Config) string {
+       if len(config.ServerName) > 0 {
+               return config.ServerName
+       }
+       return serverAddr.String()
+}
+
 // mutualProtocol finds the mutual Next Protocol Negotiation protocol given the
 // set of client and server supported protocols. The set of client supported
 // protocols must not be empty. It returns the resulting protocol and flag
index 766cb1320e777b923772db14d16139290257ce7f..0d73c8e2f97fccb2e46ff6d5781414e0b8a9aa21 100644 (file)
@@ -353,3 +353,87 @@ func TestHandshakeClientCertECDSA(t *testing.T) {
        runClientTestTLS10(t, test)
        runClientTestTLS12(t, test)
 }
+
+func TestClientResumption(t *testing.T) {
+       serverConfig := &Config{
+               CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA},
+               Certificates: testConfig.Certificates,
+       }
+       clientConfig := &Config{
+               CipherSuites:       []uint16{TLS_RSA_WITH_RC4_128_SHA},
+               InsecureSkipVerify: true,
+               ClientSessionCache: NewLRUClientSessionCache(32),
+       }
+
+       testResumeState := func(test string, didResume bool) {
+               hs, err := testHandshake(clientConfig, serverConfig)
+               if err != nil {
+                       t.Fatalf("%s: handshake failed: %s", test, err)
+               }
+               if hs.DidResume != didResume {
+                       t.Fatalf("%s resumed: %v, expected: %v", test, hs.DidResume, didResume)
+               }
+       }
+
+       testResumeState("Handshake", false)
+       testResumeState("Resume", true)
+
+       if _, err := io.ReadFull(serverConfig.rand(), serverConfig.SessionTicketKey[:]); err != nil {
+               t.Fatalf("Failed to invalidate SessionTicketKey")
+       }
+       testResumeState("InvalidSessionTicketKey", false)
+       testResumeState("ResumeAfterInvalidSessionTicketKey", true)
+
+       clientConfig.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_RC4_128_SHA}
+       testResumeState("DifferentCipherSuite", false)
+       testResumeState("DifferentCipherSuiteRecovers", true)
+
+       clientConfig.ClientSessionCache = nil
+       testResumeState("WithoutSessionCache", false)
+}
+
+func TestLRUClientSessionCache(t *testing.T) {
+       // Initialize cache of capacity 4.
+       cache := NewLRUClientSessionCache(4)
+       cs := make([]ClientSessionState, 6)
+       keys := []string{"0", "1", "2", "3", "4", "5", "6"}
+
+       // Add 4 entries to the cache and look them up.
+       for i := 0; i < 4; i++ {
+               cache.Put(keys[i], &cs[i])
+       }
+       for i := 0; i < 4; i++ {
+               if s, ok := cache.Get(keys[i]); !ok || s != &cs[i] {
+                       t.Fatalf("session cache failed lookup for added key: %s", keys[i])
+               }
+       }
+
+       // Add 2 more entries to the cache. First 2 should be evicted.
+       for i := 4; i < 6; i++ {
+               cache.Put(keys[i], &cs[i])
+       }
+       for i := 0; i < 2; i++ {
+               if s, ok := cache.Get(keys[i]); ok || s != nil {
+                       t.Fatalf("session cache should have evicted key: %s", keys[i])
+               }
+       }
+
+       // Touch entry 2. LRU should evict 3 next.
+       cache.Get(keys[2])
+       cache.Put(keys[0], &cs[0])
+       if s, ok := cache.Get(keys[3]); ok || s != nil {
+               t.Fatalf("session cache should have evicted key 3")
+       }
+
+       // Update entry 0 in place.
+       cache.Put(keys[0], &cs[3])
+       if s, ok := cache.Get(keys[0]); !ok || s != &cs[3] {
+               t.Fatalf("session cache failed update for key 0")
+       }
+
+       // Adding a nil entry is valid.
+       cache.Put(keys[0], nil)
+       if s, ok := cache.Get(keys[0]); !ok || s != nil {
+               t.Fatalf("failed to add nil entry to cache")
+       }
+}
index 83952000f6ec8130c5331daf0367a0f0aef146ce..fbdd0b9a78f4433ef10d9274ac56584cef116104 100644 (file)
@@ -7,20 +7,21 @@ package tls
 import "bytes"
 
 type clientHelloMsg struct {
-       raw                []byte
-       vers               uint16
-       random             []byte
-       sessionId          []byte
-       cipherSuites       []uint16
-       compressionMethods []uint8
-       nextProtoNeg       bool
-       serverName         string
-       ocspStapling       bool
-       supportedCurves    []uint16
-       supportedPoints    []uint8
-       ticketSupported    bool
-       sessionTicket      []uint8
-       signatureAndHashes []signatureAndHash
+       raw                 []byte
+       vers                uint16
+       random              []byte
+       sessionId           []byte
+       cipherSuites        []uint16
+       compressionMethods  []uint8
+       nextProtoNeg        bool
+       serverName          string
+       ocspStapling        bool
+       supportedCurves     []uint16
+       supportedPoints     []uint8
+       ticketSupported     bool
+       sessionTicket       []uint8
+       signatureAndHashes  []signatureAndHash
+       secureRenegotiation bool
 }
 
 func (m *clientHelloMsg) equal(i interface{}) bool {
@@ -42,7 +43,8 @@ func (m *clientHelloMsg) equal(i interface{}) bool {
                bytes.Equal(m.supportedPoints, m1.supportedPoints) &&
                m.ticketSupported == m1.ticketSupported &&
                bytes.Equal(m.sessionTicket, m1.sessionTicket) &&
-               eqSignatureAndHashes(m.signatureAndHashes, m1.signatureAndHashes)
+               eqSignatureAndHashes(m.signatureAndHashes, m1.signatureAndHashes) &&
+               m.secureRenegotiation == m1.secureRenegotiation
 }
 
 func (m *clientHelloMsg) marshal() []byte {
@@ -80,6 +82,10 @@ func (m *clientHelloMsg) marshal() []byte {
                extensionsLength += 2 + 2*len(m.signatureAndHashes)
                numExtensions++
        }
+       if m.secureRenegotiation {
+               extensionsLength += 1
+               numExtensions++
+       }
        if numExtensions > 0 {
                extensionsLength += 4 * numExtensions
                length += 2 + extensionsLength
@@ -114,13 +120,13 @@ func (m *clientHelloMsg) marshal() []byte {
        }
        if m.nextProtoNeg {
                z[0] = byte(extensionNextProtoNeg >> 8)
-               z[1] = byte(extensionNextProtoNeg)
+               z[1] = byte(extensionNextProtoNeg & 0xff)
                // The length is always 0
                z = z[4:]
        }
        if len(m.serverName) > 0 {
                z[0] = byte(extensionServerName >> 8)
-               z[1] = byte(extensionServerName)
+               z[1] = byte(extensionServerName & 0xff)
                l := len(m.serverName) + 5
                z[2] = byte(l >> 8)
                z[3] = byte(l)
@@ -224,6 +230,13 @@ func (m *clientHelloMsg) marshal() []byte {
                        z = z[2:]
                }
        }
+       if m.secureRenegotiation {
+               z[0] = byte(extensionRenegotiationInfo >> 8)
+               z[1] = byte(extensionRenegotiationInfo & 0xff)
+               z[2] = 0
+               z[3] = 1
+               z = z[5:]
+       }
 
        m.raw = x
 
@@ -256,6 +269,9 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool {
        m.cipherSuites = make([]uint16, numCipherSuites)
        for i := 0; i < numCipherSuites; i++ {
                m.cipherSuites[i] = uint16(data[2+2*i])<<8 | uint16(data[3+2*i])
+               if m.cipherSuites[i] == scsvRenegotiation {
+                       m.secureRenegotiation = true
+               }
        }
        data = data[2+cipherSuiteLen:]
        if len(data) < 1 {
@@ -379,6 +395,11 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool {
                                m.signatureAndHashes[i].signature = d[1]
                                d = d[2:]
                        }
+               case extensionRenegotiationInfo + 1:
+                       if length != 1 || data[0] != 0 {
+                               return false
+                       }
+                       m.secureRenegotiation = true
                }
                data = data[length:]
        }
@@ -387,16 +408,17 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool {
 }
 
 type serverHelloMsg struct {
-       raw               []byte
-       vers              uint16
-       random            []byte
-       sessionId         []byte
-       cipherSuite       uint16
-       compressionMethod uint8
-       nextProtoNeg      bool
-       nextProtos        []string
-       ocspStapling      bool
-       ticketSupported   bool
+       raw                 []byte
+       vers                uint16
+       random              []byte
+       sessionId           []byte
+       cipherSuite         uint16
+       compressionMethod   uint8
+       nextProtoNeg        bool
+       nextProtos          []string
+       ocspStapling        bool
+       ticketSupported     bool
+       secureRenegotiation bool
 }
 
 func (m *serverHelloMsg) equal(i interface{}) bool {
@@ -414,7 +436,8 @@ func (m *serverHelloMsg) equal(i interface{}) bool {
                m.nextProtoNeg == m1.nextProtoNeg &&
                eqStrings(m.nextProtos, m1.nextProtos) &&
                m.ocspStapling == m1.ocspStapling &&
-               m.ticketSupported == m1.ticketSupported
+               m.ticketSupported == m1.ticketSupported &&
+               m.secureRenegotiation == m1.secureRenegotiation
 }
 
 func (m *serverHelloMsg) marshal() []byte {
@@ -441,6 +464,10 @@ func (m *serverHelloMsg) marshal() []byte {
        if m.ticketSupported {
                numExtensions++
        }
+       if m.secureRenegotiation {
+               extensionsLength += 1
+               numExtensions++
+       }
        if numExtensions > 0 {
                extensionsLength += 4 * numExtensions
                length += 2 + extensionsLength
@@ -469,7 +496,7 @@ func (m *serverHelloMsg) marshal() []byte {
        }
        if m.nextProtoNeg {
                z[0] = byte(extensionNextProtoNeg >> 8)
-               z[1] = byte(extensionNextProtoNeg)
+               z[1] = byte(extensionNextProtoNeg & 0xff)
                z[2] = byte(nextProtoLen >> 8)
                z[3] = byte(nextProtoLen)
                z = z[4:]
@@ -494,6 +521,13 @@ func (m *serverHelloMsg) marshal() []byte {
                z[1] = byte(extensionSessionTicket)
                z = z[4:]
        }
+       if m.secureRenegotiation {
+               z[0] = byte(extensionRenegotiationInfo >> 8)
+               z[1] = byte(extensionRenegotiationInfo & 0xff)
+               z[2] = 0
+               z[3] = 1
+               z = z[5:]
+       }
 
        m.raw = x
 
@@ -573,6 +607,11 @@ func (m *serverHelloMsg) unmarshal(data []byte) bool {
                                return false
                        }
                        m.ticketSupported = true
+               case extensionRenegotiationInfo:
+                       if length != 1 || data[0] != 0 {
+                               return false
+                       }
+                       m.secureRenegotiation = true
                }
                data = data[length:]
        }
index c9ccf675cd8a14b73955899c98fe422d43443910..12e5ff1e5895b9052b2751e043a51c8db7e39a78 100644 (file)
@@ -12,6 +12,7 @@ import (
        "crypto/x509"
        "encoding/asn1"
        "errors"
+       "fmt"
        "io"
 )
 
@@ -100,11 +101,13 @@ func (hs *serverHandshakeState) readClientHello() (isResume bool, err error) {
        var ok bool
        hs.clientHello, ok = msg.(*clientHelloMsg)
        if !ok {
-               return false, c.sendAlert(alertUnexpectedMessage)
+               c.sendAlert(alertUnexpectedMessage)
+               return false, unexpectedMessageError(hs.clientHello, msg)
        }
        c.vers, ok = config.mutualVersion(hs.clientHello.vers)
        if !ok {
-               return false, c.sendAlert(alertProtocolVersion)
+               c.sendAlert(alertProtocolVersion)
+               return false, fmt.Errorf("tls: client offered an unsupported, maximum protocol version of %x", hs.clientHello.vers)
        }
        c.haveVers = true
 
@@ -142,20 +145,18 @@ Curves:
        }
 
        if !foundCompression {
-               return false, c.sendAlert(alertHandshakeFailure)
+               c.sendAlert(alertHandshakeFailure)
+               return false, errors.New("tls: client does not support uncompressed connections")
        }
 
        hs.hello.vers = c.vers
-       t := uint32(config.time().Unix())
        hs.hello.random = make([]byte, 32)
-       hs.hello.random[0] = byte(t >> 24)
-       hs.hello.random[1] = byte(t >> 16)
-       hs.hello.random[2] = byte(t >> 8)
-       hs.hello.random[3] = byte(t)
-       _, err = io.ReadFull(config.rand(), hs.hello.random[4:])
+       _, err = io.ReadFull(config.rand(), hs.hello.random)
        if err != nil {
-               return false, c.sendAlert(alertInternalError)
+               c.sendAlert(alertInternalError)
+               return false, err
        }
+       hs.hello.secureRenegotiation = hs.clientHello.secureRenegotiation
        hs.hello.compressionMethod = compressionNone
        if len(hs.clientHello.serverName) > 0 {
                c.serverName = hs.clientHello.serverName
@@ -170,7 +171,8 @@ Curves:
        }
 
        if len(config.Certificates) == 0 {
-               return false, c.sendAlert(alertInternalError)
+               c.sendAlert(alertInternalError)
+               return false, errors.New("tls: no certificates configured")
        }
        hs.cert = &config.Certificates[0]
        if len(hs.clientHello.serverName) > 0 {
@@ -199,7 +201,8 @@ Curves:
        }
 
        if hs.suite == nil {
-               return false, c.sendAlert(alertHandshakeFailure)
+               c.sendAlert(alertHandshakeFailure)
+               return false, errors.New("tls: no cipher suite supported by both client and server")
        }
 
        return false, nil
@@ -349,7 +352,8 @@ func (hs *serverHandshakeState) doFullHandshake() error {
        // certificate message, even if it's empty.
        if config.ClientAuth >= RequestClientCert {
                if certMsg, ok = msg.(*certificateMsg); !ok {
-                       return c.sendAlert(alertHandshakeFailure)
+                       c.sendAlert(alertUnexpectedMessage)
+                       return unexpectedMessageError(certMsg, msg)
                }
                hs.finishedHash.Write(certMsg.marshal())
 
@@ -376,7 +380,8 @@ func (hs *serverHandshakeState) doFullHandshake() error {
        // Get client key exchange
        ckx, ok := msg.(*clientKeyExchangeMsg)
        if !ok {
-               return c.sendAlert(alertUnexpectedMessage)
+               c.sendAlert(alertUnexpectedMessage)
+               return unexpectedMessageError(ckx, msg)
        }
        hs.finishedHash.Write(ckx.marshal())
 
@@ -393,7 +398,8 @@ func (hs *serverHandshakeState) doFullHandshake() error {
                }
                certVerify, ok := msg.(*certificateVerifyMsg)
                if !ok {
-                       return c.sendAlert(alertUnexpectedMessage)
+                       c.sendAlert(alertUnexpectedMessage)
+                       return unexpectedMessageError(certVerify, msg)
                }
 
                switch key := pub.(type) {
@@ -473,7 +479,8 @@ func (hs *serverHandshakeState) readFinished() error {
                }
                nextProto, ok := msg.(*nextProtoMsg)
                if !ok {
-                       return c.sendAlert(alertUnexpectedMessage)
+                       c.sendAlert(alertUnexpectedMessage)
+                       return unexpectedMessageError(nextProto, msg)
                }
                hs.finishedHash.Write(nextProto.marshal())
                c.clientProtocol = nextProto.proto
@@ -485,13 +492,15 @@ func (hs *serverHandshakeState) readFinished() error {
        }
        clientFinished, ok := msg.(*finishedMsg)
        if !ok {
-               return c.sendAlert(alertUnexpectedMessage)
+               c.sendAlert(alertUnexpectedMessage)
+               return unexpectedMessageError(clientFinished, msg)
        }
 
        verify := hs.finishedHash.clientSum(hs.masterSecret)
        if len(verify) != len(clientFinished.verifyData) ||
                subtle.ConstantTimeCompare(verify, clientFinished.verifyData) != 1 {
-               return c.sendAlert(alertHandshakeFailure)
+               c.sendAlert(alertHandshakeFailure)
+               return errors.New("tls: client's Finished message is incorrect")
        }
 
        hs.finishedHash.Write(clientFinished.marshal())
@@ -594,7 +603,8 @@ func (hs *serverHandshakeState) processCertsFromClient(certificates [][]byte) (c
                case *ecdsa.PublicKey, *rsa.PublicKey:
                        pub = key
                default:
-                       return nil, c.sendAlert(alertUnsupportedCertificate)
+                       c.sendAlert(alertUnsupportedCertificate)
+                       return nil, fmt.Errorf("tls: client's certificate contains an unsupported public key of type %T", certs[0].PublicKey)
                }
                c.peerCertificates = certs
                return pub, nil
index 1eb420af4764c60f377ef7a9a45d76982f96526a..4f41ab9b78c2866aa4c0495413a28e793fbffc2a 100644 (file)
@@ -20,6 +20,7 @@ import (
        "os"
        "os/exec"
        "path/filepath"
+       "strings"
        "testing"
        "time"
 )
@@ -53,7 +54,7 @@ func init() {
        testConfig.BuildNameToCertificate()
 }
 
-func testClientHelloFailure(t *testing.T, m handshakeMessage, expected error) {
+func testClientHelloFailure(t *testing.T, m handshakeMessage, expectedSubStr string) {
        // Create in-memory network connection,
        // send message to server.  Should return
        // expected error.
@@ -68,20 +69,20 @@ func testClientHelloFailure(t *testing.T, m handshakeMessage, expected error) {
        }()
        err := Server(s, testConfig).Handshake()
        s.Close()
-       if e, ok := err.(*net.OpError); !ok || e.Err != expected {
-               t.Errorf("Got error: %s; expected: %s", err, expected)
+       if err == nil || !strings.Contains(err.Error(), expectedSubStr) {
+               t.Errorf("Got error: %s; expected to match substring '%s'", err, expectedSubStr)
        }
 }
 
 func TestSimpleError(t *testing.T) {
-       testClientHelloFailure(t, &serverHelloDoneMsg{}, alertUnexpectedMessage)
+       testClientHelloFailure(t, &serverHelloDoneMsg{}, "unexpected handshake message")
 }
 
 var badProtocolVersions = []uint16{0x0000, 0x0005, 0x0100, 0x0105, 0x0200, 0x0205}
 
 func TestRejectBadProtocolVersion(t *testing.T) {
        for _, v := range badProtocolVersions {
-               testClientHelloFailure(t, &clientHelloMsg{vers: v}, alertProtocolVersion)
+               testClientHelloFailure(t, &clientHelloMsg{vers: v}, "unsupported, maximum protocol version")
        }
 }
 
@@ -91,7 +92,7 @@ func TestNoSuiteOverlap(t *testing.T) {
                cipherSuites:       []uint16{0xff00},
                compressionMethods: []uint8{0},
        }
-       testClientHelloFailure(t, clientHello, alertHandshakeFailure)
+       testClientHelloFailure(t, clientHello, "no cipher suite supported by both client and server")
 }
 
 func TestNoCompressionOverlap(t *testing.T) {
@@ -100,7 +101,7 @@ func TestNoCompressionOverlap(t *testing.T) {
                cipherSuites:       []uint16{TLS_RSA_WITH_RC4_128_SHA},
                compressionMethods: []uint8{0xff},
        }
-       testClientHelloFailure(t, clientHello, alertHandshakeFailure)
+       testClientHelloFailure(t, clientHello, "client does not support uncompressed connections")
 }
 
 func TestTLS12OnlyCipherSuites(t *testing.T) {
@@ -177,10 +178,12 @@ func TestClose(t *testing.T) {
 
 func testHandshake(clientConfig, serverConfig *Config) (state ConnectionState, err error) {
        c, s := net.Pipe()
+       done := make(chan bool)
        go func() {
                cli := Client(c, clientConfig)
                cli.Handshake()
                c.Close()
+               done <- true
        }()
        server := Server(s, serverConfig)
        err = server.Handshake()
@@ -188,6 +191,7 @@ func testHandshake(clientConfig, serverConfig *Config) (state ConnectionState, e
                state = server.ConnectionState()
        }
        s.Close()
+       <-done
        return
 }
 
@@ -490,9 +494,9 @@ func TestHandshakeServerSNI(t *testing.T) {
 
 // TestCipherSuiteCertPreferance ensures that we select an RSA ciphersuite with
 // an RSA certificate and an ECDSA ciphersuite with an ECDSA certificate.
-func TestCipherSuiteCertPreferance(t *testing.T) {
+func TestCipherSuiteCertPreferenceECDSA(t *testing.T) {
        config := *testConfig
-       config.CipherSuites = []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}
+       config.CipherSuites = []uint16{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA}
        config.PreferServerCipherSuites = true
 
        test := &serverTest{
index 7e820c1e7e91c978e41f489fa04ddfae80899c24..861faf0e85a0495c058de1f543986ad4dd04121f 100644 (file)
@@ -19,6 +19,9 @@ import (
        "math/big"
 )
 
+var errClientKeyExchange = errors.New("tls: invalid ClientKeyExchange message")
+var errServerKeyExchange = errors.New("tls: invalid ServerKeyExchange message")
+
 // rsaKeyAgreement implements the standard TLS key agreement where the client
 // encrypts the pre-master secret to the server's public key.
 type rsaKeyAgreement struct{}
@@ -35,14 +38,14 @@ func (ka rsaKeyAgreement) processClientKeyExchange(config *Config, cert *Certifi
        }
 
        if len(ckx.ciphertext) < 2 {
-               return nil, errors.New("bad ClientKeyExchange")
+               return nil, errClientKeyExchange
        }
 
        ciphertext := ckx.ciphertext
        if version != VersionSSL30 {
                ciphertextLen := int(ckx.ciphertext[0])<<8 | int(ckx.ciphertext[1])
                if ciphertextLen != len(ckx.ciphertext)-2 {
-                       return nil, errors.New("bad ClientKeyExchange")
+                       return nil, errClientKeyExchange
                }
                ciphertext = ckx.ciphertext[2:]
        }
@@ -61,7 +64,7 @@ func (ka rsaKeyAgreement) processClientKeyExchange(config *Config, cert *Certifi
 }
 
 func (ka rsaKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
-       return errors.New("unexpected ServerKeyExchange")
+       return errors.New("tls: unexpected ServerKeyExchange")
 }
 
 func (ka rsaKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
@@ -271,11 +274,11 @@ Curve:
 
 func (ka *ecdheKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
        if len(ckx.ciphertext) == 0 || int(ckx.ciphertext[0]) != len(ckx.ciphertext)-1 {
-               return nil, errors.New("bad ClientKeyExchange")
+               return nil, errClientKeyExchange
        }
        x, y := elliptic.Unmarshal(ka.curve, ckx.ciphertext[1:])
        if x == nil {
-               return nil, errors.New("bad ClientKeyExchange")
+               return nil, errClientKeyExchange
        }
        x, _ = ka.curve.ScalarMult(x, y, ka.privateKey)
        preMasterSecret := make([]byte, (ka.curve.Params().BitSize+7)>>3)
@@ -285,8 +288,6 @@ func (ka *ecdheKeyAgreement) processClientKeyExchange(config *Config, cert *Cert
        return preMasterSecret, nil
 }
 
-var errServerKeyExchange = errors.New("invalid ServerKeyExchange")
-
 func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
        if len(skx.key) < 4 {
                return errServerKeyExchange
index 990a8c6b2abbaa4cc5f71c583e6ecb3390352e41..0d2294a710713292c5f7e4ca579aaa62f0e70cfc 100644 (file)
@@ -1,67 +1,67 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 70 01 00 00  6c 03 03 00 00 00 00 00  |....p...l.......|
+00000000  16 03 01 00 75 01 00 00  71 03 03 00 00 00 00 00  |....u...q.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
 00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
-00000040  00 2f 00 35 c0 12 00 0a  01 00 00 29 00 05 00 05  |./.5.......)....|
+00000040  00 2f 00 35 c0 12 00 0a  01 00 00 2e 00 05 00 05  |./.5............|
 00000050  01 00 00 00 00 00 0a 00  08 00 06 00 17 00 18 00  |................|
 00000060  19 00 0b 00 02 01 00 00  0d 00 0a 00 08 04 01 04  |................|
-00000070  03 02 01 02 03                                    |.....|
+00000070  03 02 01 02 03 ff 01 00  01 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 01 00 54 02 00 00  50 03 01 52 ac 77 f8 34  |....T...P..R.w.4|
-00000010  93 89 d0 c8 9e 83 58 9b  46 f1 4e 67 40 4c ea 67  |......X.F.Ng@L.g|
-00000020  6b 70 0e 24 0e 95 3e 49  96 56 7d 20 2e 80 c6 ef  |kp.$..>I.V} ....|
-00000030  c7 dc 41 e1 86 f4 7c d9  8a 01 b5 70 9e 02 20 6b  |..A...|....p.. k|
-00000040  bb 4a 4c 8f ed 79 dc 15  be 16 cb ef c0 09 00 00  |.JL..y..........|
-00000050  08 00 0b 00 04 03 00 01  02 16 03 01 02 0e 0b 00  |................|
-00000060  02 0a 00 02 07 00 02 04  30 82 02 00 30 82 01 62  |........0...0..b|
-00000070  02 09 00 b8 bf 2d 47 a0  d2 eb f4 30 09 06 07 2a  |.....-G....0...*|
-00000080  86 48 ce 3d 04 01 30 45  31 0b 30 09 06 03 55 04  |.H.=..0E1.0...U.|
-00000090  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
-000000a0  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
-000000b0  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
-000000c0  64 67 69 74 73 20 50 74  79 20 4c 74 64 30 1e 17  |dgits Pty Ltd0..|
-000000d0  0d 31 32 31 31 32 32 31  35 30 36 33 32 5a 17 0d  |.121122150632Z..|
-000000e0  32 32 31 31 32 30 31 35  30 36 33 32 5a 30 45 31  |221120150632Z0E1|
-000000f0  0b 30 09 06 03 55 04 06  13 02 41 55 31 13 30 11  |.0...U....AU1.0.|
-00000100  06 03 55 04 08 13 0a 53  6f 6d 65 2d 53 74 61 74  |..U....Some-Stat|
-00000110  65 31 21 30 1f 06 03 55  04 0a 13 18 49 6e 74 65  |e1!0...U....Inte|
-00000120  72 6e 65 74 20 57 69 64  67 69 74 73 20 50 74 79  |rnet Widgits Pty|
-00000130  20 4c 74 64 30 81 9b 30  10 06 07 2a 86 48 ce 3d  | Ltd0..0...*.H.=|
-00000140  02 01 06 05 2b 81 04 00  23 03 81 86 00 04 00 c4  |....+...#.......|
-00000150  a1 ed be 98 f9 0b 48 73  36 7e c3 16 56 11 22 f2  |......Hs6~..V.".|
-00000160  3d 53 c3 3b 4d 21 3d cd  6b 75 e6 f6 b0 dc 9a df  |=S.;M!=.ku......|
-00000170  26 c1 bc b2 87 f0 72 32  7c b3 64 2f 1c 90 bc ea  |&.....r2|.d/....|
-00000180  68 23 10 7e fe e3 25 c0  48 3a 69 e0 28 6d d3 37  |h#.~..%.H:i.(m.7|
-00000190  00 ef 04 62 dd 0d a0 9c  70 62 83 d8 81 d3 64 31  |...b....pb....d1|
-000001a0  aa 9e 97 31 bd 96 b0 68  c0 9b 23 de 76 64 3f 1a  |...1...h..#.vd?.|
-000001b0  5c 7f e9 12 0e 58 58 b6  5f 70 dd 9b d8 ea d5 d7  |\....XX._p......|
-000001c0  f5 d5 cc b9 b6 9f 30 66  5b 66 9a 20 e2 27 e5 bf  |......0f[f. .'..|
-000001d0  fe 3b 30 09 06 07 2a 86  48 ce 3d 04 01 03 81 8c  |.;0...*.H.=.....|
-000001e0  00 30 81 88 02 42 01 88  a2 4f eb e2 45 c5 48 7d  |.0...B...O..E.H}|
-000001f0  1b ac f5 ed 98 9d ae 47  70 c0 5e 1b b6 2f bd f1  |.......Gp.^../..|
-00000200  b6 4d b7 61 40 d3 11 a2  ce ee 0b 7e 92 7e ff 76  |.M.a@......~.~.v|
-00000210  9d c3 3b 7e a5 3f ce fa  10 e2 59 ec 47 2d 7c ac  |..;~.?....Y.G-|.|
-00000220  da 4e 97 0e 15 a0 6f d0  02 42 01 4d fc be 67 13  |.N....o..B.M..g.|
-00000230  9c 2d 05 0e bd 3f a3 8c  25 c1 33 13 83 0d 94 06  |.-...?..%.3.....|
-00000240  bb d4 37 7a f6 ec 7a c9  86 2e dd d7 11 69 7f 85  |..7z..z......i..|
-00000250  7c 56 de fb 31 78 2b e4  c7 78 0d ae cb be 9e 4e  ||V..1x+..x.....N|
-00000260  36 24 31 7b 6a 0f 39 95  12 07 8f 2a 16 03 01 00  |6$1{j.9....*....|
-00000270  d5 0c 00 00 d1 03 00 17  41 04 13 22 64 a7 fc 9c  |........A.."d...|
-00000280  f8 90 f2 4d 68 a1 cc b0  03 48 d7 e5 14 1e 3b e9  |...Mh....H....;.|
-00000290  d0 be 49 ee c7 b3 98 b5  b2 9c 52 d0 ab 28 b5 16  |..I.......R..(..|
-000002a0  ef 17 ee 7a 64 a3 81 8b  0e 3f 44 81 18 67 2c c1  |...zd....?D..g,.|
-000002b0  17 da be f4 59 bc 0e d8  c5 4f 00 8a 30 81 87 02  |....Y....O..0...|
-000002c0  41 0f be e7 a5 29 04 dc  89 b5 02 bd 59 8f c1 66  |A....)......Y..f|
-000002d0  47 1c c0 ad 25 52 22 91  fc 6a 17 37 cc b5 a7 42  |G...%R"..j.7...B|
-000002e0  06 36 44 7a 78 33 df 25  34 85 82 9b 9d ed 98 1c  |.6Dzx3.%4.......|
-000002f0  43 72 3e 79 61 0d ca 5f  a1 2e ff 47 bf ae 11 c6  |Cr>ya.._...G....|
-00000300  60 ec 02 42 00 de 6f 7b  44 78 f5 70 9c 95 f6 09  |`..B..o{Dx.p....|
-00000310  9f 84 f5 10 c8 f3 b2 ab  4c 67 07 c1 6f a2 94 18  |........Lg..o...|
-00000320  3b b0 6b d9 43 70 e3 d5  ef be 23 79 5f 84 33 20  |;.k.Cp....#y_.3 |
-00000330  0c c3 f6 cd d9 18 d3 0a  a5 e8 2e 27 69 07 47 72  |...........'i.Gr|
-00000340  d4 cd 38 3e 30 9e 16 03  01 00 0e 0d 00 00 06 03  |..8>0...........|
-00000350  01 02 40 00 00 0e 00 00  00                       |..@......|
+00000000  16 03 01 00 59 02 00 00  55 03 01 52 cc 57 59 e6  |....Y...U..R.WY.|
+00000010  12 4c 15 38 e6 b7 2c 9e  b5 82 bb b5 9d f5 71 4a  |.L.8..,.......qJ|
+00000020  66 21 30 c2 44 69 ec 7c  8a 37 8b 20 1e 9c 78 3a  |f!0.Di.|.7. ..x:|
+00000030  bf d0 e0 37 6b 88 5c 8f  90 a8 92 c3 f6 b7 ad fc  |...7k.\.........|
+00000040  56 4a 50 34 ce 8f 08 e5  08 40 71 9b c0 09 00 00  |VJP4.....@q.....|
+00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
+00000060  01 02 0e 0b 00 02 0a 00  02 07 00 02 04 30 82 02  |.............0..|
+00000070  00 30 82 01 62 02 09 00  b8 bf 2d 47 a0 d2 eb f4  |.0..b.....-G....|
+00000080  30 09 06 07 2a 86 48 ce  3d 04 01 30 45 31 0b 30  |0...*.H.=..0E1.0|
+00000090  09 06 03 55 04 06 13 02  41 55 31 13 30 11 06 03  |...U....AU1.0...|
+000000a0  55 04 08 13 0a 53 6f 6d  65 2d 53 74 61 74 65 31  |U....Some-State1|
+000000b0  21 30 1f 06 03 55 04 0a  13 18 49 6e 74 65 72 6e  |!0...U....Intern|
+000000c0  65 74 20 57 69 64 67 69  74 73 20 50 74 79 20 4c  |et Widgits Pty L|
+000000d0  74 64 30 1e 17 0d 31 32  31 31 32 32 31 35 30 36  |td0...1211221506|
+000000e0  33 32 5a 17 0d 32 32 31  31 32 30 31 35 30 36 33  |32Z..22112015063|
+000000f0  32 5a 30 45 31 0b 30 09  06 03 55 04 06 13 02 41  |2Z0E1.0...U....A|
+00000100  55 31 13 30 11 06 03 55  04 08 13 0a 53 6f 6d 65  |U1.0...U....Some|
+00000110  2d 53 74 61 74 65 31 21  30 1f 06 03 55 04 0a 13  |-State1!0...U...|
+00000120  18 49 6e 74 65 72 6e 65  74 20 57 69 64 67 69 74  |.Internet Widgit|
+00000130  73 20 50 74 79 20 4c 74  64 30 81 9b 30 10 06 07  |s Pty Ltd0..0...|
+00000140  2a 86 48 ce 3d 02 01 06  05 2b 81 04 00 23 03 81  |*.H.=....+...#..|
+00000150  86 00 04 00 c4 a1 ed be  98 f9 0b 48 73 36 7e c3  |...........Hs6~.|
+00000160  16 56 11 22 f2 3d 53 c3  3b 4d 21 3d cd 6b 75 e6  |.V.".=S.;M!=.ku.|
+00000170  f6 b0 dc 9a df 26 c1 bc  b2 87 f0 72 32 7c b3 64  |.....&.....r2|.d|
+00000180  2f 1c 90 bc ea 68 23 10  7e fe e3 25 c0 48 3a 69  |/....h#.~..%.H:i|
+00000190  e0 28 6d d3 37 00 ef 04  62 dd 0d a0 9c 70 62 83  |.(m.7...b....pb.|
+000001a0  d8 81 d3 64 31 aa 9e 97  31 bd 96 b0 68 c0 9b 23  |...d1...1...h..#|
+000001b0  de 76 64 3f 1a 5c 7f e9  12 0e 58 58 b6 5f 70 dd  |.vd?.\....XX._p.|
+000001c0  9b d8 ea d5 d7 f5 d5 cc  b9 b6 9f 30 66 5b 66 9a  |...........0f[f.|
+000001d0  20 e2 27 e5 bf fe 3b 30  09 06 07 2a 86 48 ce 3d  | .'...;0...*.H.=|
+000001e0  04 01 03 81 8c 00 30 81  88 02 42 01 88 a2 4f eb  |......0...B...O.|
+000001f0  e2 45 c5 48 7d 1b ac f5  ed 98 9d ae 47 70 c0 5e  |.E.H}.......Gp.^|
+00000200  1b b6 2f bd f1 b6 4d b7  61 40 d3 11 a2 ce ee 0b  |../...M.a@......|
+00000210  7e 92 7e ff 76 9d c3 3b  7e a5 3f ce fa 10 e2 59  |~.~.v..;~.?....Y|
+00000220  ec 47 2d 7c ac da 4e 97  0e 15 a0 6f d0 02 42 01  |.G-|..N....o..B.|
+00000230  4d fc be 67 13 9c 2d 05  0e bd 3f a3 8c 25 c1 33  |M..g..-...?..%.3|
+00000240  13 83 0d 94 06 bb d4 37  7a f6 ec 7a c9 86 2e dd  |.......7z..z....|
+00000250  d7 11 69 7f 85 7c 56 de  fb 31 78 2b e4 c7 78 0d  |..i..|V..1x+..x.|
+00000260  ae cb be 9e 4e 36 24 31  7b 6a 0f 39 95 12 07 8f  |....N6$1{j.9....|
+00000270  2a 16 03 01 00 d5 0c 00  00 d1 03 00 17 41 04 00  |*............A..|
+00000280  3d 87 12 2c c5 fd db 6e  ab 0c 7c 54 85 fc d3 13  |=..,...n..|T....|
+00000290  34 1e 13 83 2c 60 05 67  83 f0 3a cc c6 27 84 63  |4...,`.g..:..'.c|
+000002a0  90 4e 25 26 0f 03 ca f3  ae 7e 44 c6 94 0d e4 1b  |.N%&.....~D.....|
+000002b0  4a 53 e2 d7 f0 5c 83 64  37 c0 0f d1 9e 86 de 00  |JS...\.d7.......|
+000002c0  8a 30 81 87 02 41 4f 85  6d 11 af d1 27 9c de 21  |.0...AO.m...'..!|
+000002d0  d7 e5 96 ad 4f 6a a1 5c  2b 63 22 0e 4f 22 77 16  |....Oj.\+c".O"w.|
+000002e0  ec 6e db 38 1a df 28 4e  ee 9e a4 c1 e7 d3 02 74  |.n.8..(N.......t|
+000002f0  07 3f 58 7f 82 51 2d 9e  78 6b bd 28 77 20 c1 40  |.?X..Q-.xk.(w .@|
+00000300  09 71 ba b9 23 c7 82 02  42 01 13 1b 64 c4 1f c6  |.q..#...B...d...|
+00000310  1f f3 f4 51 8c 64 92 37  5e f0 5c 11 c9 ee 43 55  |...Q.d.7^.\...CU|
+00000320  a0 83 52 8b d9 2d d1 22  2c 2e 2c e0 04 a6 59 b3  |..R..-.",.,...Y.|
+00000330  f9 33 d8 e4 9a 0b 2b 95  c6 41 5d 60 a3 d1 9f 31  |.3....+..A]`...1|
+00000340  14 5d a3 31 6e 70 f1 e7  35 5a f9 16 03 01 00 0e  |.].1np..5Z......|
+00000350  0d 00 00 06 03 01 02 40  00 00 0e 00 00 00        |.......@......|
 >>> Flow 3 (client to server)
 00000000  16 03 01 02 0a 0b 00 02  06 00 02 03 00 02 00 30  |...............0|
 00000010  82 01 fc 30 82 01 5e 02  09 00 9a 30 84 6c 26 35  |...0..^....0.l&5|
 000002a0  85 6a 42 9b f9 7e 7e 31  c2 e5 bd 66 02 41 4b 49  |.jB..~~1...f.AKI|
 000002b0  c6 cd 02 e3 83 f7 03 50  18 6d b4 c9 51 02 c0 ab  |.......P.m..Q...|
 000002c0  87 bc e0 3e 4b 89 53 3a  e2 65 89 97 02 c1 87 f1  |...>K.S:.e......|
-000002d0  67 d0 f2 06 28 4e 51 4e  fd f0 01 ee b8 6b e0 01  |g...(NQN.....k..|
-000002e0  1c 57 7e a8 fc 82 71 26  10 42 27 8c 5d c8 a9 14  |.W~...q&.B'.]...|
-000002f0  03 01 00 01 01 16 03 01  00 30 6e 6b 80 06 bb 98  |.........0nk....|
-00000300  c1 47 e3 92 1b 4d 98 4a  b4 3f 18 2e 73 a9 57 84  |.G...M.J.?..s.W.|
-00000310  92 b5 cb 45 db bb db 89  dd 10 04 7c 60 3e a0 d1  |...E.......|`>..|
-00000320  22 1d 7c 51 11 28 09 4a  26 f6                    |".|Q.(.J&.|
+000002d0  67 d0 f2 06 28 4e 51 4e  fd f0 01 c1 1f 1d 1c 32  |g...(NQN.......2|
+000002e0  1f 91 5d 06 f5 44 1b a0  1b 61 43 6b de 81 bd 14  |..]..D...aCk....|
+000002f0  03 01 00 01 01 16 03 01  00 30 fe bb 82 52 2d 8a  |.........0...R-.|
+00000300  81 87 ba 2c 18 5b 93 07  78 30 85 f3 5f 4f df 3f  |...,.[..x0.._O.?|
+00000310  1a fc 01 b9 a5 32 99 d3  40 0b ef c5 b8 32 f4 7e  |.....2..@....2.~|
+00000320  d2 93 0f 19 24 87 c5 18  e2 8b                    |....$.....|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 30 05 ba 98 98 0f  |..........0.....|
-00000010  f9 f8 f4 4d 9a 29 99 ce  d7 d4 9a 4b d1 ed 54 d1  |...M.).....K..T.|
-00000020  a7 32 9a b8 ce 80 53 c4  50 61 83 37 35 c8 99 25  |.2....S.Pa.75..%|
-00000030  0b ac 66 91 62 ce 12 ba  cf dc 6f                 |..f.b.....o|
+00000000  14 03 01 00 01 01 16 03  01 00 30 84 a0 90 cb 8b  |..........0.....|
+00000010  43 ad 66 06 ef f1 4b 5c  85 cc 4e 12 60 44 b4 be  |C.f...K\..N.`D..|
+00000020  ed 94 23 69 bf 7a cc e9  a7 17 db 9a ec d5 9b 15  |..#i.z..........|
+00000030  92 62 5e bb ac db 78 50  d1 b2 0c                 |.b^...xP...|
 >>> Flow 5 (client to server)
-00000000  17 03 01 00 20 7a 1e c3  4c 5f dd f1 14 f4 97 45  |.... z..L_.....E|
-00000010  21 4f 75 a5 a5 53 4a d7  91 a4 ad 1b cd 4b da 5a  |!Ou..SJ......K.Z|
-00000020  92 96 48 1f bc 17 03 01  00 20 a4 c9 d5 67 2f d9  |..H...... ...g/.|
-00000030  d2 ee e4 82 a5 ff 2d fa  41 8f 3d cc 3d ce 08 4a  |......-.A.=.=..J|
-00000040  39 7d 0c 6c 69 a4 71 e2  c0 98 15 03 01 00 20 19  |9}.li.q....... .|
-00000050  ae 20 b2 ff ce d4 71 37  ed 92 6a b3 3c 8d df 00  |. ....q7..j.<...|
-00000060  3b 69 5d f9 45 b1 8b 33  37 fe 52 d2 a1 56 01     |;i].E..37.R..V.|
+00000000  17 03 01 00 20 b4 fd 9e  0a 69 49 16 72 52 8b 81  |.... ....iI.rR..|
+00000010  50 87 07 77 d4 9a 07 06  88 e0 43 43 32 a0 7c f9  |P..w......CC2.|.|
+00000020  13 88 3f 87 36 17 03 01  00 20 6e 96 f6 4c f8 8d  |..?.6.... n..L..|
+00000030  1b 15 ff 3e 7c 5e fc f0  81 6e 5e 26 3c 42 96 dc  |...>|^...n^&<B..|
+00000040  69 79 b8 73 9c 1d eb 31  5d 94 15 03 01 00 20 b4  |iy.s...1]..... .|
+00000050  68 2c 4d 74 ed a5 bc f4  e3 56 bd 3e 19 78 fc 8a  |h,Mt.....V.>.x..|
+00000060  1e f0 4c 7e f9 11 de e1  15 38 9b ed 6f 9b 34     |..L~.....8..o.4|
index 2030e4b7f9fd45211b559a10754fce61c06f8c87..36f6eb16371c2fe355b02bde25c055a392320187 100644 (file)
@@ -1,64 +1,64 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 70 01 00 00  6c 03 03 00 00 00 00 00  |....p...l.......|
+00000000  16 03 01 00 75 01 00 00  71 03 03 00 00 00 00 00  |....u...q.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
 00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
-00000040  00 2f 00 35 c0 12 00 0a  01 00 00 29 00 05 00 05  |./.5.......)....|
+00000040  00 2f 00 35 c0 12 00 0a  01 00 00 2e 00 05 00 05  |./.5............|
 00000050  01 00 00 00 00 00 0a 00  08 00 06 00 17 00 18 00  |................|
 00000060  19 00 0b 00 02 01 00 00  0d 00 0a 00 08 04 01 04  |................|
-00000070  03 02 01 02 03                                    |.....|
+00000070  03 02 01 02 03 ff 01 00  01 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 01 00 4a 02 00 00  46 03 01 52 ac 77 f8 32  |....J...F..R.w.2|
-00000010  42 f3 96 ae d6 f1 36 23  a4 c5 c0 ba 05 5a 67 bb  |B.....6#.....Zg.|
-00000020  12 5c 64 95 96 3d cc 0c  3a 85 38 20 13 48 bf 31  |.\d..=..:.8 .H.1|
-00000030  52 76 11 55 05 5d 24 5a  53 17 9e be d5 88 c1 d7  |Rv.U.]$ZS.......|
-00000040  88 35 b9 70 2b 66 46 35  a6 aa ff 8f 00 05 00 16  |.5.p+fF5........|
-00000050  03 01 02 be 0b 00 02 ba  00 02 b7 00 02 b4 30 82  |..............0.|
-00000060  02 b0 30 82 02 19 a0 03  02 01 02 02 09 00 85 b0  |..0.............|
-00000070  bb a4 8a 7f b8 ca 30 0d  06 09 2a 86 48 86 f7 0d  |......0...*.H...|
-00000080  01 01 05 05 00 30 45 31  0b 30 09 06 03 55 04 06  |.....0E1.0...U..|
-00000090  13 02 41 55 31 13 30 11  06 03 55 04 08 13 0a 53  |..AU1.0...U....S|
-000000a0  6f 6d 65 2d 53 74 61 74  65 31 21 30 1f 06 03 55  |ome-State1!0...U|
-000000b0  04 0a 13 18 49 6e 74 65  72 6e 65 74 20 57 69 64  |....Internet Wid|
-000000c0  67 69 74 73 20 50 74 79  20 4c 74 64 30 1e 17 0d  |gits Pty Ltd0...|
-000000d0  31 30 30 34 32 34 30 39  30 39 33 38 5a 17 0d 31  |100424090938Z..1|
-000000e0  31 30 34 32 34 30 39 30  39 33 38 5a 30 45 31 0b  |10424090938Z0E1.|
-000000f0  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-00000100  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-00000110  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-00000120  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-00000130  4c 74 64 30 81 9f 30 0d  06 09 2a 86 48 86 f7 0d  |Ltd0..0...*.H...|
-00000140  01 01 01 05 00 03 81 8d  00 30 81 89 02 81 81 00  |.........0......|
-00000150  bb 79 d6 f5 17 b5 e5 bf  46 10 d0 dc 69 be e6 2b  |.y......F...i..+|
-00000160  07 43 5a d0 03 2d 8a 7a  43 85 b7 14 52 e7 a5 65  |.CZ..-.zC...R..e|
-00000170  4c 2c 78 b8 23 8c b5 b4  82 e5 de 1f 95 3b 7e 62  |L,x.#........;~b|
-00000180  a5 2c a5 33 d6 fe 12 5c  7a 56 fc f5 06 bf fa 58  |.,.3...\zV.....X|
-00000190  7b 26 3f b5 cd 04 d3 d0  c9 21 96 4a c7 f4 54 9f  |{&?......!.J..T.|
-000001a0  5a bf ef 42 71 00 fe 18  99 07 7f 7e 88 7d 7d f1  |Z..Bq......~.}}.|
-000001b0  04 39 c4 a2 2e db 51 c9  7c e3 c0 4c 3b 32 66 01  |.9....Q.|..L;2f.|
-000001c0  cf af b1 1d b8 71 9a 1d  db db 89 6b ae da 2d 79  |.....q.....k..-y|
-000001d0  02 03 01 00 01 a3 81 a7  30 81 a4 30 1d 06 03 55  |........0..0...U|
-000001e0  1d 0e 04 16 04 14 b1 ad  e2 85 5a cf cb 28 db 69  |..........Z..(.i|
-000001f0  ce 23 69 de d3 26 8e 18  88 39 30 75 06 03 55 1d  |.#i..&...90u..U.|
-00000200  23 04 6e 30 6c 80 14 b1  ad e2 85 5a cf cb 28 db  |#.n0l......Z..(.|
-00000210  69 ce 23 69 de d3 26 8e  18 88 39 a1 49 a4 47 30  |i.#i..&...9.I.G0|
-00000220  45 31 0b 30 09 06 03 55  04 06 13 02 41 55 31 13  |E1.0...U....AU1.|
-00000230  30 11 06 03 55 04 08 13  0a 53 6f 6d 65 2d 53 74  |0...U....Some-St|
-00000240  61 74 65 31 21 30 1f 06  03 55 04 0a 13 18 49 6e  |ate1!0...U....In|
-00000250  74 65 72 6e 65 74 20 57  69 64 67 69 74 73 20 50  |ternet Widgits P|
-00000260  74 79 20 4c 74 64 82 09  00 85 b0 bb a4 8a 7f b8  |ty Ltd..........|
-00000270  ca 30 0c 06 03 55 1d 13  04 05 30 03 01 01 ff 30  |.0...U....0....0|
-00000280  0d 06 09 2a 86 48 86 f7  0d 01 01 05 05 00 03 81  |...*.H..........|
-00000290  81 00 08 6c 45 24 c7 6b  b1 59 ab 0c 52 cc f2 b0  |...lE$.k.Y..R...|
-000002a0  14 d7 87 9d 7a 64 75 b5  5a 95 66 e4 c5 2b 8e ae  |....zdu.Z.f..+..|
-000002b0  12 66 1f eb 4f 38 b3 6e  60 d3 92 fd f7 41 08 b5  |.f..O8.n`....A..|
-000002c0  25 13 b1 18 7a 24 fb 30  1d ba ed 98 b9 17 ec e7  |%...z$.0........|
-000002d0  d7 31 59 db 95 d3 1d 78  ea 50 56 5c d5 82 5a 2d  |.1Y....x.PV\..Z-|
-000002e0  5a 5f 33 c4 b6 d8 c9 75  90 96 8c 0f 52 98 b5 cd  |Z_3....u....R...|
-000002f0  98 1f 89 20 5f f2 a0 1c  a3 1b 96 94 dd a9 fd 57  |... _..........W|
-00000300  e9 70 e8 26 6d 71 99 9b  26 6e 38 50 29 6c 90 a7  |.p.&mq..&n8P)l..|
-00000310  bd d9 16 03 01 00 0e 0d  00 00 06 03 01 02 40 00  |..............@.|
-00000320  00 0e 00 00 00                                    |.....|
+00000000  16 03 01 00 51 02 00 00  4d 03 01 52 cc 57 59 78  |....Q...M..R.WYx|
+00000010  63 f8 d6 ea 32 6f 22 7c  7b fb ab 48 c8 3b d9 ed  |c...2o"|{..H.;..|
+00000020  5b 01 e0 0a 36 d8 26 57  56 dd e4 20 ed c9 d8 e5  |[...6.&WV.. ....|
+00000030  5c 2a 1b b6 d2 bd 32 5d  42 fe 4b d1 89 4c 1f b0  |\*....2]B.K..L..|
+00000040  5d fc 1f d4 4a f3 ef 06  28 1a d3 09 00 05 00 00  |]...J...(.......|
+00000050  05 ff 01 00 01 00 16 03  01 02 be 0b 00 02 ba 00  |................|
+00000060  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
+00000070  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
+00000080  09 2a 86 48 86 f7 0d 01  01 05 05 00 30 45 31 0b  |.*.H........0E1.|
+00000090  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
+000000a0  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
+000000b0  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
+000000c0  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
+000000d0  4c 74 64 30 1e 17 0d 31  30 30 34 32 34 30 39 30  |Ltd0...100424090|
+000000e0  39 33 38 5a 17 0d 31 31  30 34 32 34 30 39 30 39  |938Z..1104240909|
+000000f0  33 38 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |38Z0E1.0...U....|
+00000100  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
+00000110  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
+00000120  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
+00000130  74 73 20 50 74 79 20 4c  74 64 30 81 9f 30 0d 06  |ts Pty Ltd0..0..|
+00000140  09 2a 86 48 86 f7 0d 01  01 01 05 00 03 81 8d 00  |.*.H............|
+00000150  30 81 89 02 81 81 00 bb  79 d6 f5 17 b5 e5 bf 46  |0.......y......F|
+00000160  10 d0 dc 69 be e6 2b 07  43 5a d0 03 2d 8a 7a 43  |...i..+.CZ..-.zC|
+00000170  85 b7 14 52 e7 a5 65 4c  2c 78 b8 23 8c b5 b4 82  |...R..eL,x.#....|
+00000180  e5 de 1f 95 3b 7e 62 a5  2c a5 33 d6 fe 12 5c 7a  |....;~b.,.3...\z|
+00000190  56 fc f5 06 bf fa 58 7b  26 3f b5 cd 04 d3 d0 c9  |V.....X{&?......|
+000001a0  21 96 4a c7 f4 54 9f 5a  bf ef 42 71 00 fe 18 99  |!.J..T.Z..Bq....|
+000001b0  07 7f 7e 88 7d 7d f1 04  39 c4 a2 2e db 51 c9 7c  |..~.}}..9....Q.||
+000001c0  e3 c0 4c 3b 32 66 01 cf  af b1 1d b8 71 9a 1d db  |..L;2f......q...|
+000001d0  db 89 6b ae da 2d 79 02  03 01 00 01 a3 81 a7 30  |..k..-y........0|
+000001e0  81 a4 30 1d 06 03 55 1d  0e 04 16 04 14 b1 ad e2  |..0...U.........|
+000001f0  85 5a cf cb 28 db 69 ce  23 69 de d3 26 8e 18 88  |.Z..(.i.#i..&...|
+00000200  39 30 75 06 03 55 1d 23  04 6e 30 6c 80 14 b1 ad  |90u..U.#.n0l....|
+00000210  e2 85 5a cf cb 28 db 69  ce 23 69 de d3 26 8e 18  |..Z..(.i.#i..&..|
+00000220  88 39 a1 49 a4 47 30 45  31 0b 30 09 06 03 55 04  |.9.I.G0E1.0...U.|
+00000230  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
+00000240  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
+00000250  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
+00000260  64 67 69 74 73 20 50 74  79 20 4c 74 64 82 09 00  |dgits Pty Ltd...|
+00000270  85 b0 bb a4 8a 7f b8 ca  30 0c 06 03 55 1d 13 04  |........0...U...|
+00000280  05 30 03 01 01 ff 30 0d  06 09 2a 86 48 86 f7 0d  |.0....0...*.H...|
+00000290  01 01 05 05 00 03 81 81  00 08 6c 45 24 c7 6b b1  |..........lE$.k.|
+000002a0  59 ab 0c 52 cc f2 b0 14  d7 87 9d 7a 64 75 b5 5a  |Y..R.......zdu.Z|
+000002b0  95 66 e4 c5 2b 8e ae 12  66 1f eb 4f 38 b3 6e 60  |.f..+...f..O8.n`|
+000002c0  d3 92 fd f7 41 08 b5 25  13 b1 18 7a 24 fb 30 1d  |....A..%...z$.0.|
+000002d0  ba ed 98 b9 17 ec e7 d7  31 59 db 95 d3 1d 78 ea  |........1Y....x.|
+000002e0  50 56 5c d5 82 5a 2d 5a  5f 33 c4 b6 d8 c9 75 90  |PV\..Z-Z_3....u.|
+000002f0  96 8c 0f 52 98 b5 cd 98  1f 89 20 5f f2 a0 1c a3  |...R...... _....|
+00000300  1b 96 94 dd a9 fd 57 e9  70 e8 26 6d 71 99 9b 26  |......W.p.&mq..&|
+00000310  6e 38 50 29 6c 90 a7 bd  d9 16 03 01 00 0e 0d 00  |n8P)l...........|
+00000320  00 06 03 01 02 40 00 00  0e 00 00 00              |.....@......|
 >>> Flow 3 (client to server)
 00000000  16 03 01 02 0a 0b 00 02  06 00 02 03 00 02 00 30  |...............0|
 00000010  82 01 fc 30 82 01 5e 02  09 00 9a 30 84 6c 26 35  |...0..^....0.l&5|
 000002e0  85 6a 42 9b f9 7e 7e 31  c2 e5 bd 66 02 41 4b 49  |.jB..~~1...f.AKI|
 000002f0  c6 cd 02 e3 83 f7 03 50  18 6d b4 c9 51 02 c0 ab  |.......P.m..Q...|
 00000300  87 bc e0 3e 4b 89 53 3a  e2 65 89 97 02 c1 87 f1  |...>K.S:.e......|
-00000310  67 d0 f2 06 28 4e 51 4e  fd f0 01 92 6d 54 ed 77  |g...(NQN....mT.w|
-00000320  96 b9 6c 79 66 fc c7 4e  db 53 7a 61 f3 31 9b 14  |..lyf..N.Sza.1..|
-00000330  03 01 00 01 01 16 03 01  00 24 4d cd f0 d5 d5 4c  |.........$M....L|
-00000340  2b 51 9f 88 04 10 65 c9  1c 92 26 d0 07 0a af 06  |+Q....e...&.....|
-00000350  bd 0a 2d 1e e6 dd 2a a5  3f c9 39 2d f8 0d        |..-...*.?.9-..|
+00000310  67 d0 f2 06 28 4e 51 4e  fd f0 01 65 a4 80 ad 7e  |g...(NQN...e...~|
+00000320  a3 bc 1d 1a 83 3a db 30  c7 67 96 cf e7 aa dc 14  |.....:.0.g......|
+00000330  03 01 00 01 01 16 03 01  00 24 d9 38 91 04 a4 ac  |.........$.8....|
+00000340  eb d7 4c 7a c6 07 25 72  a0 f7 3f 6d 37 cc db 40  |..Lz..%r..?m7..@|
+00000350  c0 26 9b be 03 55 2d 24  c5 b3 4f 6d 56 c4        |.&...U-$..OmV.|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 24 79 e0 a5 d6 1c  |..........$y....|
-00000010  2d c9 2f 3d 35 96 2f ce  97 9c 33 38 8b fc ba 02  |-./=5./...38....|
-00000020  6f 46 13 64 82 d5 ff 9d  16 9a ad 90 e3 ec 46     |oF.d..........F|
+00000000  14 03 01 00 01 01 16 03  01 00 24 b8 8d b1 db 80  |..........$.....|
+00000010  1d 26 9e 41 d0 48 40 0d  6a 94 e6 42 93 60 58 d1  |.&.A.H@.j..B.`X.|
+00000020  b2 13 7c 6f ec 1c f5 2a  1e 82 14 6f 0f 13 a7     |..|o...*...o...|
 >>> Flow 5 (client to server)
-00000000  17 03 01 00 1a 8b 3c 90  3e 94 ef fd 6e 32 42 fa  |......<.>...n2B.|
-00000010  70 0b d0 65 62 23 25 a4  0f b5 a7 9a 45 f0 52 15  |p..eb#%.....E.R.|
-00000020  03 01 00 16 74 72 64 8d  b8 41 13 07 49 7c d7 d0  |....trd..A..I|..|
-00000030  b6 c9 cf 33 20 69 5e f4  d2 a8                    |...3 i^...|
+00000000  17 03 01 00 1a ea f3 99  a3 b1 7e 9a 29 ad 31 18  |..........~.).1.|
+00000010  1b 5b 7c 71 ae 5b c6 ba  8e 8e 36 f6 ab 2c dd 15  |.[|q.[....6..,..|
+00000020  03 01 00 16 82 cf f4 83  05 4c 86 e2 47 cc 6f 2c  |.........L..G.o,|
+00000030  6d 50 c6 09 3b fd a8 5e  12 3c                    |mP..;..^.<|
index 11fd37a9f675d3f0a2954c95bdb975e50be319a8..9e4ea6654431f6503bbc3b77a69e8b8cb5b29d5f 100644 (file)
@@ -1,67 +1,67 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 70 01 00 00  6c 03 03 00 00 00 00 00  |....p...l.......|
+00000000  16 03 01 00 75 01 00 00  71 03 03 00 00 00 00 00  |....u...q.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
 00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
-00000040  00 2f 00 35 c0 12 00 0a  01 00 00 29 00 05 00 05  |./.5.......)....|
+00000040  00 2f 00 35 c0 12 00 0a  01 00 00 2e 00 05 00 05  |./.5............|
 00000050  01 00 00 00 00 00 0a 00  08 00 06 00 17 00 18 00  |................|
 00000060  19 00 0b 00 02 01 00 00  0d 00 0a 00 08 04 01 04  |................|
-00000070  03 02 01 02 03                                    |.....|
+00000070  03 02 01 02 03 ff 01 00  01 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 01 00 54 02 00 00  50 03 01 52 ac 77 f7 ee  |....T...P..R.w..|
-00000010  90 30 d2 75 be d4 70 dd  2d 4f a7 9e 0f 6f 0b ac  |.0.u..p.-O...o..|
-00000020  bf 02 7d 53 1d 05 7f 93  9a c3 50 20 c8 18 17 c2  |..}S......P ....|
-00000030  70 76 8d a8 52 c8 b7 ff  32 35 cb bb 7e e0 4c 9c  |pv..R...25..~.L.|
-00000040  42 69 90 26 b5 c8 b7 22  da 52 db f9 c0 09 00 00  |Bi.&...".R......|
-00000050  08 00 0b 00 04 03 00 01  02 16 03 01 02 0e 0b 00  |................|
-00000060  02 0a 00 02 07 00 02 04  30 82 02 00 30 82 01 62  |........0...0..b|
-00000070  02 09 00 b8 bf 2d 47 a0  d2 eb f4 30 09 06 07 2a  |.....-G....0...*|
-00000080  86 48 ce 3d 04 01 30 45  31 0b 30 09 06 03 55 04  |.H.=..0E1.0...U.|
-00000090  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
-000000a0  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
-000000b0  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
-000000c0  64 67 69 74 73 20 50 74  79 20 4c 74 64 30 1e 17  |dgits Pty Ltd0..|
-000000d0  0d 31 32 31 31 32 32 31  35 30 36 33 32 5a 17 0d  |.121122150632Z..|
-000000e0  32 32 31 31 32 30 31 35  30 36 33 32 5a 30 45 31  |221120150632Z0E1|
-000000f0  0b 30 09 06 03 55 04 06  13 02 41 55 31 13 30 11  |.0...U....AU1.0.|
-00000100  06 03 55 04 08 13 0a 53  6f 6d 65 2d 53 74 61 74  |..U....Some-Stat|
-00000110  65 31 21 30 1f 06 03 55  04 0a 13 18 49 6e 74 65  |e1!0...U....Inte|
-00000120  72 6e 65 74 20 57 69 64  67 69 74 73 20 50 74 79  |rnet Widgits Pty|
-00000130  20 4c 74 64 30 81 9b 30  10 06 07 2a 86 48 ce 3d  | Ltd0..0...*.H.=|
-00000140  02 01 06 05 2b 81 04 00  23 03 81 86 00 04 00 c4  |....+...#.......|
-00000150  a1 ed be 98 f9 0b 48 73  36 7e c3 16 56 11 22 f2  |......Hs6~..V.".|
-00000160  3d 53 c3 3b 4d 21 3d cd  6b 75 e6 f6 b0 dc 9a df  |=S.;M!=.ku......|
-00000170  26 c1 bc b2 87 f0 72 32  7c b3 64 2f 1c 90 bc ea  |&.....r2|.d/....|
-00000180  68 23 10 7e fe e3 25 c0  48 3a 69 e0 28 6d d3 37  |h#.~..%.H:i.(m.7|
-00000190  00 ef 04 62 dd 0d a0 9c  70 62 83 d8 81 d3 64 31  |...b....pb....d1|
-000001a0  aa 9e 97 31 bd 96 b0 68  c0 9b 23 de 76 64 3f 1a  |...1...h..#.vd?.|
-000001b0  5c 7f e9 12 0e 58 58 b6  5f 70 dd 9b d8 ea d5 d7  |\....XX._p......|
-000001c0  f5 d5 cc b9 b6 9f 30 66  5b 66 9a 20 e2 27 e5 bf  |......0f[f. .'..|
-000001d0  fe 3b 30 09 06 07 2a 86  48 ce 3d 04 01 03 81 8c  |.;0...*.H.=.....|
-000001e0  00 30 81 88 02 42 01 88  a2 4f eb e2 45 c5 48 7d  |.0...B...O..E.H}|
-000001f0  1b ac f5 ed 98 9d ae 47  70 c0 5e 1b b6 2f bd f1  |.......Gp.^../..|
-00000200  b6 4d b7 61 40 d3 11 a2  ce ee 0b 7e 92 7e ff 76  |.M.a@......~.~.v|
-00000210  9d c3 3b 7e a5 3f ce fa  10 e2 59 ec 47 2d 7c ac  |..;~.?....Y.G-|.|
-00000220  da 4e 97 0e 15 a0 6f d0  02 42 01 4d fc be 67 13  |.N....o..B.M..g.|
-00000230  9c 2d 05 0e bd 3f a3 8c  25 c1 33 13 83 0d 94 06  |.-...?..%.3.....|
-00000240  bb d4 37 7a f6 ec 7a c9  86 2e dd d7 11 69 7f 85  |..7z..z......i..|
-00000250  7c 56 de fb 31 78 2b e4  c7 78 0d ae cb be 9e 4e  ||V..1x+..x.....N|
-00000260  36 24 31 7b 6a 0f 39 95  12 07 8f 2a 16 03 01 00  |6$1{j.9....*....|
-00000270  d6 0c 00 00 d2 03 00 17  41 04 14 a3 b3 8a d0 9a  |........A.......|
-00000280  93 50 4e 4c ad b1 61 10  09 96 cc 65 d0 85 02 17  |.PNL..a....e....|
-00000290  e6 12 56 e5 f3 6b 97 0e  4e 04 60 49 46 39 a9 a9  |..V..k..N.`IF9..|
-000002a0  70 20 fa 28 d7 91 01 24  3a 52 90 7d ac dc 1c 87  |p .(...$:R.}....|
-000002b0  fe 05 2a 23 ff d6 f7 84  ad 08 00 8b 30 81 88 02  |..*#........0...|
-000002c0  42 00 f0 df fd cb 17 ba  68 6e 1c b5 6c ee 29 68  |B.......hn..l.)h|
-000002d0  a4 a7 15 c8 88 cd 60 57  fd ec b3 53 31 6f 19 64  |......`W...S1o.d|
-000002e0  fd 91 c8 59 c3 19 d3 67  5d 38 26 07 c5 93 c1 92  |...Y...g]8&.....|
-000002f0  86 5b 89 99 01 24 db ab  d0 51 a3 6a 54 e8 7f bb  |.[...$...Q.jT...|
-00000300  de 9c 1c 02 42 01 7c d6  5f b8 f9 15 b4 a2 89 04  |....B.|._.......|
-00000310  46 36 2f a9 cc 5c 7c 78  24 17 fd 11 b8 3f 0b 4a  |F6/..\|x$....?.J|
-00000320  5e 4d 55 1a 65 b2 27 d8  51 97 6c d8 a7 b2 62 30  |^MU.e.'.Q.l...b0|
-00000330  01 3d b0 ef 27 fe f6 cd  40 0e 7b 54 c6 bc 38 b0  |.=..'...@.{T..8.|
-00000340  b1 b2 37 6c 87 ac d1 16  03 01 00 0e 0d 00 00 06  |..7l............|
-00000350  03 01 02 40 00 00 0e 00  00 00                    |...@......|
+00000000  16 03 01 00 59 02 00 00  55 03 01 52 cc 57 58 fc  |....Y...U..R.WX.|
+00000010  46 e4 45 fc 07 cb ec 16  cc ce 87 96 0e f6 d9 c7  |F.E.............|
+00000020  49 2e ec 53 30 07 cd 01  1d 49 2e 20 2b bc 5c 11  |I..S0....I. +.\.|
+00000030  90 55 88 3f ec e4 30 b3  58 e7 d2 82 32 15 dd b4  |.U.?..0.X...2...|
+00000040  1f e2 4c 1d 08 f9 a0 8d  75 8b 63 c2 c0 09 00 00  |..L.....u.c.....|
+00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
+00000060  01 02 0e 0b 00 02 0a 00  02 07 00 02 04 30 82 02  |.............0..|
+00000070  00 30 82 01 62 02 09 00  b8 bf 2d 47 a0 d2 eb f4  |.0..b.....-G....|
+00000080  30 09 06 07 2a 86 48 ce  3d 04 01 30 45 31 0b 30  |0...*.H.=..0E1.0|
+00000090  09 06 03 55 04 06 13 02  41 55 31 13 30 11 06 03  |...U....AU1.0...|
+000000a0  55 04 08 13 0a 53 6f 6d  65 2d 53 74 61 74 65 31  |U....Some-State1|
+000000b0  21 30 1f 06 03 55 04 0a  13 18 49 6e 74 65 72 6e  |!0...U....Intern|
+000000c0  65 74 20 57 69 64 67 69  74 73 20 50 74 79 20 4c  |et Widgits Pty L|
+000000d0  74 64 30 1e 17 0d 31 32  31 31 32 32 31 35 30 36  |td0...1211221506|
+000000e0  33 32 5a 17 0d 32 32 31  31 32 30 31 35 30 36 33  |32Z..22112015063|
+000000f0  32 5a 30 45 31 0b 30 09  06 03 55 04 06 13 02 41  |2Z0E1.0...U....A|
+00000100  55 31 13 30 11 06 03 55  04 08 13 0a 53 6f 6d 65  |U1.0...U....Some|
+00000110  2d 53 74 61 74 65 31 21  30 1f 06 03 55 04 0a 13  |-State1!0...U...|
+00000120  18 49 6e 74 65 72 6e 65  74 20 57 69 64 67 69 74  |.Internet Widgit|
+00000130  73 20 50 74 79 20 4c 74  64 30 81 9b 30 10 06 07  |s Pty Ltd0..0...|
+00000140  2a 86 48 ce 3d 02 01 06  05 2b 81 04 00 23 03 81  |*.H.=....+...#..|
+00000150  86 00 04 00 c4 a1 ed be  98 f9 0b 48 73 36 7e c3  |...........Hs6~.|
+00000160  16 56 11 22 f2 3d 53 c3  3b 4d 21 3d cd 6b 75 e6  |.V.".=S.;M!=.ku.|
+00000170  f6 b0 dc 9a df 26 c1 bc  b2 87 f0 72 32 7c b3 64  |.....&.....r2|.d|
+00000180  2f 1c 90 bc ea 68 23 10  7e fe e3 25 c0 48 3a 69  |/....h#.~..%.H:i|
+00000190  e0 28 6d d3 37 00 ef 04  62 dd 0d a0 9c 70 62 83  |.(m.7...b....pb.|
+000001a0  d8 81 d3 64 31 aa 9e 97  31 bd 96 b0 68 c0 9b 23  |...d1...1...h..#|
+000001b0  de 76 64 3f 1a 5c 7f e9  12 0e 58 58 b6 5f 70 dd  |.vd?.\....XX._p.|
+000001c0  9b d8 ea d5 d7 f5 d5 cc  b9 b6 9f 30 66 5b 66 9a  |...........0f[f.|
+000001d0  20 e2 27 e5 bf fe 3b 30  09 06 07 2a 86 48 ce 3d  | .'...;0...*.H.=|
+000001e0  04 01 03 81 8c 00 30 81  88 02 42 01 88 a2 4f eb  |......0...B...O.|
+000001f0  e2 45 c5 48 7d 1b ac f5  ed 98 9d ae 47 70 c0 5e  |.E.H}.......Gp.^|
+00000200  1b b6 2f bd f1 b6 4d b7  61 40 d3 11 a2 ce ee 0b  |../...M.a@......|
+00000210  7e 92 7e ff 76 9d c3 3b  7e a5 3f ce fa 10 e2 59  |~.~.v..;~.?....Y|
+00000220  ec 47 2d 7c ac da 4e 97  0e 15 a0 6f d0 02 42 01  |.G-|..N....o..B.|
+00000230  4d fc be 67 13 9c 2d 05  0e bd 3f a3 8c 25 c1 33  |M..g..-...?..%.3|
+00000240  13 83 0d 94 06 bb d4 37  7a f6 ec 7a c9 86 2e dd  |.......7z..z....|
+00000250  d7 11 69 7f 85 7c 56 de  fb 31 78 2b e4 c7 78 0d  |..i..|V..1x+..x.|
+00000260  ae cb be 9e 4e 36 24 31  7b 6a 0f 39 95 12 07 8f  |....N6$1{j.9....|
+00000270  2a 16 03 01 00 d5 0c 00  00 d1 03 00 17 41 04 5e  |*............A.^|
+00000280  6d f1 9c b6 ec 5b c9 fc  16 b2 75 63 90 82 23 8f  |m....[....uc..#.|
+00000290  14 6f 53 b1 23 06 fa c7  b9 b4 d2 59 3d 4f 94 a2  |.oS.#......Y=O..|
+000002a0  02 af 0a 1e 94 f7 4d 31  c1 b3 a7 c4 67 89 67 da  |......M1....g.g.|
+000002b0  71 de 5a 1d ca 79 b8 f3  9e 6a 42 f8 60 8b 2a 00  |q.Z..y...jB.`.*.|
+000002c0  8a 30 81 87 02 42 00 85  32 00 54 ab af 7a 95 32  |.0...B..2.T..z.2|
+000002d0  f9 c7 e3 34 23 ed 1c 5d  7b a2 78 bf f1 a3 3f 53  |...4#..]{.x...?S|
+000002e0  ad c4 56 1f f6 98 9e 29  66 ef 52 21 80 d6 21 e7  |..V....)f.R!..!.|
+000002f0  61 fd 75 90 37 ec 13 0a  f4 c2 47 a4 a7 41 87 24  |a.u.7.....G..A.$|
+00000300  0c c6 c0 09 f0 54 c4 df  02 41 30 3e a5 6c a2 5d  |.....T...A0>.l.]|
+00000310  76 66 fb a2 f5 2d ef ee  63 63 b4 9a db 84 23 db  |vf...-..cc....#.|
+00000320  e9 0d 5f 43 cc 6b ef 4a  7f a2 1d 6b 6c 7f 1f ba  |.._C.k.J...kl...|
+00000330  52 5f 6c 3f cc 77 54 ef  75 1f c2 1e da 6f d3 07  |R_l?.wT.u....o..|
+00000340  23 7d 54 6d 40 88 0d 6e  72 90 8e 16 03 01 00 0e  |#}Tm@..nr.......|
+00000350  0d 00 00 06 03 01 02 40  00 00 0e 00 00 00        |.......@......|
 >>> Flow 3 (client to server)
 00000000  16 03 01 01 fb 0b 00 01  f7 00 01 f4 00 01 f1 30  |...............0|
 00000010  82 01 ed 30 82 01 58 a0  03 02 01 02 02 01 00 30  |...0..X........0|
 00000220  a7 24 20 3e b2 56 1c ce  97 28 5e f8 2b 2d 4f 9e  |.$ >.V...(^.+-O.|
 00000230  f1 07 9f 6c 4b 5b 83 56  e2 32 42 e9 58 b6 d7 49  |...lK[.V.2B.X..I|
 00000240  a6 b5 68 1a 41 03 56 6b  dc 5a 89 16 03 01 00 86  |..h.A.Vk.Z......|
-00000250  0f 00 00 82 00 80 1b 62  58 10 7f d1 fb 94 fd 4e  |.......bX......N|
-00000260  29 d8 ce fb 46 c4 16 ce  32 a0 a6 40 10 a8 24 0c  |)...F...2..@..$.|
-00000270  c3 a2 50 34 2c 50 e4 b9  0f d8 2a d1 c6 d5 d9 ee  |..P4,P....*.....|
-00000280  66 38 dd 68 7d 9f a4 78  b7 9c e3 fb 29 d9 8d ff  |f8.h}..x....)...|
-00000290  0e b4 94 6e a9 58 a3 74  d7 b7 47 1a 0f 37 2b ab  |...n.X.t..G..7+.|
-000002a0  cc ee 90 36 58 72 2a cb  2a 0f 2f 1b a0 fa 43 18  |...6Xr*.*./...C.|
-000002b0  1f 4a 24 9a 67 55 11 e5  b9 f3 f0 d2 ff 66 26 dd  |.J$.gU.......f&.|
-000002c0  b9 d1 ab b3 35 52 95 98  dd 86 8a 1b f8 8e ba 7e  |....5R.........~|
-000002d0  10 07 0f a6 85 dc 14 03  01 00 01 01 16 03 01 00  |................|
-000002e0  30 c6 a2 49 6c 31 b1 a8  d2 9e 0c 96 b1 0b 0d 57  |0..Il1.........W|
-000002f0  8d f0 93 37 93 ea 06 b5  a7 d7 ba 3f 0e a2 f5 6a  |...7.......?...j|
-00000300  38 88 cc 53 66 18 61 a5  e1 79 99 59 0e 44 58 79  |8..Sf.a..y.Y.DXy|
-00000310  c7                                                |.|
+00000250  0f 00 00 82 00 80 0d cf  9a c6 5e 57 60 b9 a4 87  |..........^W`...|
+00000260  ae 83 25 4a d5 af 02 69  4d a1 0b ac 0c 97 58 30  |..%J...iM.....X0|
+00000270  cc 9d 45 6a eb e3 a5 b1  f9 63 9c 05 04 8f 55 b3  |..Ej.....c....U.|
+00000280  5b 7c 5b f6 36 2d b1 89  84 21 ce a6 ce be 66 c6  |[|[.6-...!....f.|
+00000290  06 4a 07 8a a0 13 ee f1  52 ea 65 71 b7 49 b7 49  |.J......R.eq.I.I|
+000002a0  dc 0a d0 c6 c3 69 ef 67  97 6b d8 41 e0 d1 a4 66  |.....i.g.k.A...f|
+000002b0  cc 3c ba 4a 63 46 af e1  7f 16 2e 73 5c 69 17 45  |.<.JcF.....s\i.E|
+000002c0  b3 2d e2 7c 92 4c de 02  c6 97 d3 9c e0 d5 9c 22  |.-.|.L........."|
+000002d0  30 21 11 5e 1c 1a 14 03  01 00 01 01 16 03 01 00  |0!.^............|
+000002e0  30 db d7 9e 46 3e 5a 60  5d 21 22 34 ca 9a 3b 3c  |0...F>Z`]!"4..;<|
+000002f0  a6 41 12 42 b9 78 d7 39  4b 51 d0 d0 3e 7e ba 4c  |.A.B.x.9KQ..>~.L|
+00000300  7c 8d 4b 03 e5 fe 4c 59  a6 9f a1 5d 46 54 56 61  ||.K...LY...]FTVa|
+00000310  33                                                |3|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 30 68 f5 47 9c 34  |..........0h.G.4|
-00000010  ba c1 96 05 d0 bd 77 e9  6c fb 88 c8 45 f5 fe 37  |......w.l...E..7|
-00000020  e2 6b b9 3c 95 36 bf cc  76 2b 1c 3e 1e 8f 63 e7  |.k.<.6..v+.>..c.|
-00000030  9b c2 84 fb 76 cf 97 a0  da 96 42                 |....v.....B|
+00000000  14 03 01 00 01 01 16 03  01 00 30 72 c2 59 5a f3  |..........0r.YZ.|
+00000010  6f db 45 d0 4b 8c b9 49  25 25 cd eb 00 c7 99 6c  |o.E.K..I%%.....l|
+00000020  a7 4d 5a 4c f3 05 7d b0  fb 97 1a 40 0d 42 ca ad  |.MZL..}....@.B..|
+00000030  df 57 6c 47 40 13 49 47  09 7c 2e                 |.WlG@.IG.|.|
 >>> Flow 5 (client to server)
-00000000  17 03 01 00 20 99 81 8e  c7 04 d1 03 0c 80 e2 44  |.... ..........D|
-00000010  14 7c 74 5a 85 36 55 f0  62 d5 36 d4 da 6f 43 98  |.|tZ.6U.b.6..oC.|
-00000020  36 7c 53 76 89 17 03 01  00 20 ec d3 7f fa 49 6c  |6|Sv..... ....Il|
-00000030  60 89 16 ee 6a 1f 69 4f  5a 88 0c 5c 89 a6 e0 3f  |`...j.iOZ..\...?|
-00000040  38 89 fa da 39 16 d2 9b  08 1f 15 03 01 00 20 64  |8...9......... d|
-00000050  a1 7a 98 b4 ff 54 a4 a0  e1 01 e4 0b 6c 67 80 b6  |.z...T......lg..|
-00000060  b6 76 90 e5 e5 cf 9b ca  fe 5c a3 4a 24 53 e4     |.v.......\.J$S.|
+00000000  17 03 01 00 20 c5 99 ba  cc 39 bb db 07 27 3c 05  |.... ....9...'<.|
+00000010  fb 79 ce bd ec 8c 67 20  c8 46 3b ad bf 8c 66 fc  |.y....g .F;...f.|
+00000020  55 de 73 0f 71 17 03 01  00 20 7b 3e 2b 60 c0 df  |U.s.q.... {>+`..|
+00000030  ca b1 c4 19 28 de 3e 8e  20 8b 4a 4a 07 52 5f 8c  |....(.>. .JJ.R_.|
+00000040  1b 4f 54 15 69 31 f7 46  03 94 15 03 01 00 20 fc  |.OT.i1.F...... .|
+00000050  b9 06 b4 6d 60 28 3f 4f  b2 9a e8 1c 74 d3 15 a6  |...m`(?O....t...|
+00000060  7b 49 85 d0 2f 83 bf 4d  7f 60 6e 18 bf c7 34     |{I../..M.`n...4|
index f689b8e41e6b4642041952b82e91a0ddf5799a2e..c21579c93297adbb0a9d9a83f33ad97e1a4deb01 100644 (file)
@@ -1,64 +1,64 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 70 01 00 00  6c 03 03 00 00 00 00 00  |....p...l.......|
+00000000  16 03 01 00 75 01 00 00  71 03 03 00 00 00 00 00  |....u...q.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
 00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
-00000040  00 2f 00 35 c0 12 00 0a  01 00 00 29 00 05 00 05  |./.5.......)....|
+00000040  00 2f 00 35 c0 12 00 0a  01 00 00 2e 00 05 00 05  |./.5............|
 00000050  01 00 00 00 00 00 0a 00  08 00 06 00 17 00 18 00  |................|
 00000060  19 00 0b 00 02 01 00 00  0d 00 0a 00 08 04 01 04  |................|
-00000070  03 02 01 02 03                                    |.....|
+00000070  03 02 01 02 03 ff 01 00  01 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 01 00 4a 02 00 00  46 03 01 52 ac 77 f7 f0  |....J...F..R.w..|
-00000010  99 da 46 81 2b c1 04 7a  9e 61 bf 0f 67 e3 40 ed  |..F.+..z.a..g.@.|
-00000020  9c 69 17 75 6f 64 63 14  4f 0f 99 20 06 c2 0e 89  |.i.uodc.O.. ....|
-00000030  2e 5a bb e6 ce e1 39 f6  11 53 a5 92 95 61 b4 e3  |.Z....9..S...a..|
-00000040  20 35 72 f8 e3 8d 19 6e  e3 5c a9 af 00 05 00 16  | 5r....n.\......|
-00000050  03 01 02 be 0b 00 02 ba  00 02 b7 00 02 b4 30 82  |..............0.|
-00000060  02 b0 30 82 02 19 a0 03  02 01 02 02 09 00 85 b0  |..0.............|
-00000070  bb a4 8a 7f b8 ca 30 0d  06 09 2a 86 48 86 f7 0d  |......0...*.H...|
-00000080  01 01 05 05 00 30 45 31  0b 30 09 06 03 55 04 06  |.....0E1.0...U..|
-00000090  13 02 41 55 31 13 30 11  06 03 55 04 08 13 0a 53  |..AU1.0...U....S|
-000000a0  6f 6d 65 2d 53 74 61 74  65 31 21 30 1f 06 03 55  |ome-State1!0...U|
-000000b0  04 0a 13 18 49 6e 74 65  72 6e 65 74 20 57 69 64  |....Internet Wid|
-000000c0  67 69 74 73 20 50 74 79  20 4c 74 64 30 1e 17 0d  |gits Pty Ltd0...|
-000000d0  31 30 30 34 32 34 30 39  30 39 33 38 5a 17 0d 31  |100424090938Z..1|
-000000e0  31 30 34 32 34 30 39 30  39 33 38 5a 30 45 31 0b  |10424090938Z0E1.|
-000000f0  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-00000100  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-00000110  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-00000120  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-00000130  4c 74 64 30 81 9f 30 0d  06 09 2a 86 48 86 f7 0d  |Ltd0..0...*.H...|
-00000140  01 01 01 05 00 03 81 8d  00 30 81 89 02 81 81 00  |.........0......|
-00000150  bb 79 d6 f5 17 b5 e5 bf  46 10 d0 dc 69 be e6 2b  |.y......F...i..+|
-00000160  07 43 5a d0 03 2d 8a 7a  43 85 b7 14 52 e7 a5 65  |.CZ..-.zC...R..e|
-00000170  4c 2c 78 b8 23 8c b5 b4  82 e5 de 1f 95 3b 7e 62  |L,x.#........;~b|
-00000180  a5 2c a5 33 d6 fe 12 5c  7a 56 fc f5 06 bf fa 58  |.,.3...\zV.....X|
-00000190  7b 26 3f b5 cd 04 d3 d0  c9 21 96 4a c7 f4 54 9f  |{&?......!.J..T.|
-000001a0  5a bf ef 42 71 00 fe 18  99 07 7f 7e 88 7d 7d f1  |Z..Bq......~.}}.|
-000001b0  04 39 c4 a2 2e db 51 c9  7c e3 c0 4c 3b 32 66 01  |.9....Q.|..L;2f.|
-000001c0  cf af b1 1d b8 71 9a 1d  db db 89 6b ae da 2d 79  |.....q.....k..-y|
-000001d0  02 03 01 00 01 a3 81 a7  30 81 a4 30 1d 06 03 55  |........0..0...U|
-000001e0  1d 0e 04 16 04 14 b1 ad  e2 85 5a cf cb 28 db 69  |..........Z..(.i|
-000001f0  ce 23 69 de d3 26 8e 18  88 39 30 75 06 03 55 1d  |.#i..&...90u..U.|
-00000200  23 04 6e 30 6c 80 14 b1  ad e2 85 5a cf cb 28 db  |#.n0l......Z..(.|
-00000210  69 ce 23 69 de d3 26 8e  18 88 39 a1 49 a4 47 30  |i.#i..&...9.I.G0|
-00000220  45 31 0b 30 09 06 03 55  04 06 13 02 41 55 31 13  |E1.0...U....AU1.|
-00000230  30 11 06 03 55 04 08 13  0a 53 6f 6d 65 2d 53 74  |0...U....Some-St|
-00000240  61 74 65 31 21 30 1f 06  03 55 04 0a 13 18 49 6e  |ate1!0...U....In|
-00000250  74 65 72 6e 65 74 20 57  69 64 67 69 74 73 20 50  |ternet Widgits P|
-00000260  74 79 20 4c 74 64 82 09  00 85 b0 bb a4 8a 7f b8  |ty Ltd..........|
-00000270  ca 30 0c 06 03 55 1d 13  04 05 30 03 01 01 ff 30  |.0...U....0....0|
-00000280  0d 06 09 2a 86 48 86 f7  0d 01 01 05 05 00 03 81  |...*.H..........|
-00000290  81 00 08 6c 45 24 c7 6b  b1 59 ab 0c 52 cc f2 b0  |...lE$.k.Y..R...|
-000002a0  14 d7 87 9d 7a 64 75 b5  5a 95 66 e4 c5 2b 8e ae  |....zdu.Z.f..+..|
-000002b0  12 66 1f eb 4f 38 b3 6e  60 d3 92 fd f7 41 08 b5  |.f..O8.n`....A..|
-000002c0  25 13 b1 18 7a 24 fb 30  1d ba ed 98 b9 17 ec e7  |%...z$.0........|
-000002d0  d7 31 59 db 95 d3 1d 78  ea 50 56 5c d5 82 5a 2d  |.1Y....x.PV\..Z-|
-000002e0  5a 5f 33 c4 b6 d8 c9 75  90 96 8c 0f 52 98 b5 cd  |Z_3....u....R...|
-000002f0  98 1f 89 20 5f f2 a0 1c  a3 1b 96 94 dd a9 fd 57  |... _..........W|
-00000300  e9 70 e8 26 6d 71 99 9b  26 6e 38 50 29 6c 90 a7  |.p.&mq..&n8P)l..|
-00000310  bd d9 16 03 01 00 0e 0d  00 00 06 03 01 02 40 00  |..............@.|
-00000320  00 0e 00 00 00                                    |.....|
+00000000  16 03 01 00 51 02 00 00  4d 03 01 52 cc 57 58 bd  |....Q...M..R.WX.|
+00000010  25 74 73 5e 31 99 73 f1  c6 a1 9b f0 07 09 97 d7  |%ts^1.s.........|
+00000020  b6 b9 65 a3 08 16 0b 4c  4a 06 00 20 ef 0b 97 cb  |..e....LJ.. ....|
+00000030  3c cf 05 b6 fe 62 d7 15  29 cf c8 56 e0 7e d7 92  |<....b..)..V.~..|
+00000040  11 86 86 49 a0 b1 12 2f  dc 15 f7 67 00 05 00 00  |...I.../...g....|
+00000050  05 ff 01 00 01 00 16 03  01 02 be 0b 00 02 ba 00  |................|
+00000060  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
+00000070  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
+00000080  09 2a 86 48 86 f7 0d 01  01 05 05 00 30 45 31 0b  |.*.H........0E1.|
+00000090  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
+000000a0  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
+000000b0  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
+000000c0  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
+000000d0  4c 74 64 30 1e 17 0d 31  30 30 34 32 34 30 39 30  |Ltd0...100424090|
+000000e0  39 33 38 5a 17 0d 31 31  30 34 32 34 30 39 30 39  |938Z..1104240909|
+000000f0  33 38 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |38Z0E1.0...U....|
+00000100  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
+00000110  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
+00000120  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
+00000130  74 73 20 50 74 79 20 4c  74 64 30 81 9f 30 0d 06  |ts Pty Ltd0..0..|
+00000140  09 2a 86 48 86 f7 0d 01  01 01 05 00 03 81 8d 00  |.*.H............|
+00000150  30 81 89 02 81 81 00 bb  79 d6 f5 17 b5 e5 bf 46  |0.......y......F|
+00000160  10 d0 dc 69 be e6 2b 07  43 5a d0 03 2d 8a 7a 43  |...i..+.CZ..-.zC|
+00000170  85 b7 14 52 e7 a5 65 4c  2c 78 b8 23 8c b5 b4 82  |...R..eL,x.#....|
+00000180  e5 de 1f 95 3b 7e 62 a5  2c a5 33 d6 fe 12 5c 7a  |....;~b.,.3...\z|
+00000190  56 fc f5 06 bf fa 58 7b  26 3f b5 cd 04 d3 d0 c9  |V.....X{&?......|
+000001a0  21 96 4a c7 f4 54 9f 5a  bf ef 42 71 00 fe 18 99  |!.J..T.Z..Bq....|
+000001b0  07 7f 7e 88 7d 7d f1 04  39 c4 a2 2e db 51 c9 7c  |..~.}}..9....Q.||
+000001c0  e3 c0 4c 3b 32 66 01 cf  af b1 1d b8 71 9a 1d db  |..L;2f......q...|
+000001d0  db 89 6b ae da 2d 79 02  03 01 00 01 a3 81 a7 30  |..k..-y........0|
+000001e0  81 a4 30 1d 06 03 55 1d  0e 04 16 04 14 b1 ad e2  |..0...U.........|
+000001f0  85 5a cf cb 28 db 69 ce  23 69 de d3 26 8e 18 88  |.Z..(.i.#i..&...|
+00000200  39 30 75 06 03 55 1d 23  04 6e 30 6c 80 14 b1 ad  |90u..U.#.n0l....|
+00000210  e2 85 5a cf cb 28 db 69  ce 23 69 de d3 26 8e 18  |..Z..(.i.#i..&..|
+00000220  88 39 a1 49 a4 47 30 45  31 0b 30 09 06 03 55 04  |.9.I.G0E1.0...U.|
+00000230  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
+00000240  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
+00000250  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
+00000260  64 67 69 74 73 20 50 74  79 20 4c 74 64 82 09 00  |dgits Pty Ltd...|
+00000270  85 b0 bb a4 8a 7f b8 ca  30 0c 06 03 55 1d 13 04  |........0...U...|
+00000280  05 30 03 01 01 ff 30 0d  06 09 2a 86 48 86 f7 0d  |.0....0...*.H...|
+00000290  01 01 05 05 00 03 81 81  00 08 6c 45 24 c7 6b b1  |..........lE$.k.|
+000002a0  59 ab 0c 52 cc f2 b0 14  d7 87 9d 7a 64 75 b5 5a  |Y..R.......zdu.Z|
+000002b0  95 66 e4 c5 2b 8e ae 12  66 1f eb 4f 38 b3 6e 60  |.f..+...f..O8.n`|
+000002c0  d3 92 fd f7 41 08 b5 25  13 b1 18 7a 24 fb 30 1d  |....A..%...z$.0.|
+000002d0  ba ed 98 b9 17 ec e7 d7  31 59 db 95 d3 1d 78 ea  |........1Y....x.|
+000002e0  50 56 5c d5 82 5a 2d 5a  5f 33 c4 b6 d8 c9 75 90  |PV\..Z-Z_3....u.|
+000002f0  96 8c 0f 52 98 b5 cd 98  1f 89 20 5f f2 a0 1c a3  |...R...... _....|
+00000300  1b 96 94 dd a9 fd 57 e9  70 e8 26 6d 71 99 9b 26  |......W.p.&mq..&|
+00000310  6e 38 50 29 6c 90 a7 bd  d9 16 03 01 00 0e 0d 00  |n8P)l...........|
+00000320  00 06 03 01 02 40 00 00  0e 00 00 00              |.....@......|
 >>> Flow 3 (client to server)
 00000000  16 03 01 01 fb 0b 00 01  f7 00 01 f4 00 01 f1 30  |...............0|
 00000010  82 01 ed 30 82 01 58 a0  03 02 01 02 02 01 00 30  |...0..X........0|
 00000260  e6 bd 77 82 6f 23 b6 e0  bd a2 92 b7 3a ac e8 56  |..w.o#......:..V|
 00000270  f1 af 54 5e 46 87 e9 3b  33 e7 b8 28 b7 d6 c8 90  |..T^F..;3..(....|
 00000280  35 d4 1c 43 d1 30 6f 55  4e 0a 70 16 03 01 00 86  |5..C.0oUN.p.....|
-00000290  0f 00 00 82 00 80 4d 9d  67 d8 0f e2 4e f4 bc eb  |......M.g...N...|
-000002a0  5f ad 77 c6 4d d4 2f 2c  77 dd a5 f7 4c 87 7e 99  |_.w.M./,w...L.~.|
-000002b0  86 70 f3 8a 9d b4 29 21  75 17 f1 cf 66 63 a1 76  |.p....)!u...fc.v|
-000002c0  3c 6c d7 3c 23 ee 35 1a  18 46 86 60 25 81 e3 25  |<l.<#.5..F.`%..%|
-000002d0  df ab 2c 28 26 53 a8 92  6c 35 5a 9a cc cb d5 43  |..,(&S..l5Z....C|
-000002e0  74 2f 6e a3 df d3 60 6a  97 97 71 ce 81 10 51 2d  |t/n...`j..q...Q-|
-000002f0  50 f7 8a b2 ff d2 56 ba  e3 e5 03 e9 99 79 9e b4  |P.....V......y..|
-00000300  a7 16 6e 08 98 1b f0 a5  d1 81 79 cc f4 48 34 58  |..n.......y..H4X|
-00000310  df 69 49 b5 77 81 14 03  01 00 01 01 16 03 01 00  |.iI.w...........|
-00000320  24 a2 58 ce 9a 68 34 da  df f7 21 41 da da 3d f1  |$.X..h4...!A..=.|
-00000330  a1 cf 87 9e 50 96 aa 3d  80 71 50 0f 30 56 75 fe  |....P..=.qP.0Vu.|
-00000340  97 48 66 de 13                                    |.Hf..|
+00000290  0f 00 00 82 00 80 41 42  bb be 9d a4 d3 e9 24 f2  |......AB......$.|
+000002a0  6c 7d b0 68 10 7a 88 e3  41 5d 24 f9 b2 a6 4c 31  |l}.h.z..A]$...L1|
+000002b0  2b 90 51 49 65 3d d4 4b  1f 69 93 91 c0 a2 ec 2c  |+.QIe=.K.i.....,|
+000002c0  d0 48 e1 64 7f ef 8b da  be 8c 0a 19 8b ff c7 37  |.H.d...........7|
+000002d0  3d b8 8c 6d 2f 28 bd ba  96 6e c5 ed fa 29 c5 42  |=..m/(...n...).B|
+000002e0  f2 24 b9 b5 55 1e 12 46  a5 bb 7c 41 2a b0 02 44  |.$..U..F..|A*..D|
+000002f0  68 89 e9 92 e3 ad 50 44  f1 18 e7 e4 ee 2c 74 40  |h.....PD.....,t@|
+00000300  82 39 a3 cf 30 54 fb 53  42 f1 18 28 8a f4 ef 65  |.9..0T.SB..(...e|
+00000310  f2 33 6a e7 2a 48 14 03  01 00 01 01 16 03 01 00  |.3j.*H..........|
+00000320  24 d8 a8 6d 1c 31 f7 cc  06 57 ef cf 7e 9b ac d3  |$..m.1...W..~...|
+00000330  6b 50 b2 d8 c6 41 a2 c8  a6 f5 53 b3 d4 af e8 71  |kP...A....S....q|
+00000340  88 9e 7e d9 57                                    |..~.W|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 24 83 7b dc b5 11  |..........$.{...|
-00000010  28 12 6b d0 8a a3 dd f2  eb 29 cb fd 04 54 a1 31  |(.k......)...T.1|
-00000020  8c 08 40 c3 bd 21 3a 13  be 57 47 89 f3 26 30     |..@..!:..WG..&0|
+00000000  14 03 01 00 01 01 16 03  01 00 24 71 90 c8 76 87  |..........$q..v.|
+00000010  7f 07 da de 41 93 59 f4  e9 64 73 49 d3 15 b0 7d  |....A.Y..dsI...}|
+00000020  d7 86 06 85 62 71 9f 57  db 1a 81 82 ed 9b df     |....bq.W.......|
 >>> Flow 5 (client to server)
-00000000  17 03 01 00 1a 52 d0 be  a9 8f fb 91 38 7b a4 82  |.....R......8{..|
-00000010  5d ff 93 61 f8 e9 80 b4  26 0e 21 42 2d 44 5a 15  |]..a....&.!B-DZ.|
-00000020  03 01 00 16 49 68 5c 35  7e 9d eb ed 16 a4 60 16  |....Ih\5~.....`.|
-00000030  fb 25 80 5c 15 9e 31 68  aa 5b                    |.%.\..1h.[|
+00000000  17 03 01 00 1a 35 83 3e  0a 4d 7b 58 4d 6b 9e d7  |.....5.>.M{XMk..|
+00000010  77 32 dd b0 93 25 d1 fc  e2 08 ad 2c 91 fd ce 15  |w2...%.....,....|
+00000020  03 01 00 16 56 9c d9 6e  45 4c 95 8a 2d 75 7e 52  |....V..nEL..-u~R|
+00000030  0a 75 0a f0 a1 52 91 c4  d2 b4                    |.u...R....|
index f1e925d6509a4d2004d487600ae0020a6e2a9bf2..b89d02c3687f08e792c4015f7ce230566a08da9f 100644 (file)
@@ -1,86 +1,87 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 70 01 00 00  6c 03 03 00 00 00 00 00  |....p...l.......|
+00000000  16 03 01 00 75 01 00 00  71 03 03 00 00 00 00 00  |....u...q.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
 00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
-00000040  00 2f 00 35 c0 12 00 0a  01 00 00 29 00 05 00 05  |./.5.......)....|
+00000040  00 2f 00 35 c0 12 00 0a  01 00 00 2e 00 05 00 05  |./.5............|
 00000050  01 00 00 00 00 00 0a 00  08 00 06 00 17 00 18 00  |................|
 00000060  19 00 0b 00 02 01 00 00  0d 00 0a 00 08 04 01 04  |................|
-00000070  03 02 01 02 03                                    |.....|
+00000070  03 02 01 02 03 ff 01 00  01 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 01 00 54 02 00 00  50 03 01 52 ac 77 f7 24  |....T...P..R.w.$|
-00000010  5b 96 60 d7 6a 2e 9f 05  ea 1e 61 15 64 16 ab a6  |[.`.j.....a.d...|
-00000020  a8 4e 72 f2 09 14 c2 fd  64 2d 22 20 e9 e3 04 64  |.Nr.....d-" ...d|
-00000030  7a 93 f1 de 0c d5 f9 5a  9a 5b d3 af 2b 03 84 bd  |z......Z.[..+...|
-00000040  69 71 dd 35 a7 ca 52 bf  90 a1 03 f0 c0 09 00 00  |iq.5..R.........|
-00000050  08 00 0b 00 04 03 00 01  02 16 03 01 02 0e 0b 00  |................|
-00000060  02 0a 00 02 07 00 02 04  30 82 02 00 30 82 01 62  |........0...0..b|
-00000070  02 09 00 b8 bf 2d 47 a0  d2 eb f4 30 09 06 07 2a  |.....-G....0...*|
-00000080  86 48 ce 3d 04 01 30 45  31 0b 30 09 06 03 55 04  |.H.=..0E1.0...U.|
-00000090  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
-000000a0  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
-000000b0  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
-000000c0  64 67 69 74 73 20 50 74  79 20 4c 74 64 30 1e 17  |dgits Pty Ltd0..|
-000000d0  0d 31 32 31 31 32 32 31  35 30 36 33 32 5a 17 0d  |.121122150632Z..|
-000000e0  32 32 31 31 32 30 31 35  30 36 33 32 5a 30 45 31  |221120150632Z0E1|
-000000f0  0b 30 09 06 03 55 04 06  13 02 41 55 31 13 30 11  |.0...U....AU1.0.|
-00000100  06 03 55 04 08 13 0a 53  6f 6d 65 2d 53 74 61 74  |..U....Some-Stat|
-00000110  65 31 21 30 1f 06 03 55  04 0a 13 18 49 6e 74 65  |e1!0...U....Inte|
-00000120  72 6e 65 74 20 57 69 64  67 69 74 73 20 50 74 79  |rnet Widgits Pty|
-00000130  20 4c 74 64 30 81 9b 30  10 06 07 2a 86 48 ce 3d  | Ltd0..0...*.H.=|
-00000140  02 01 06 05 2b 81 04 00  23 03 81 86 00 04 00 c4  |....+...#.......|
-00000150  a1 ed be 98 f9 0b 48 73  36 7e c3 16 56 11 22 f2  |......Hs6~..V.".|
-00000160  3d 53 c3 3b 4d 21 3d cd  6b 75 e6 f6 b0 dc 9a df  |=S.;M!=.ku......|
-00000170  26 c1 bc b2 87 f0 72 32  7c b3 64 2f 1c 90 bc ea  |&.....r2|.d/....|
-00000180  68 23 10 7e fe e3 25 c0  48 3a 69 e0 28 6d d3 37  |h#.~..%.H:i.(m.7|
-00000190  00 ef 04 62 dd 0d a0 9c  70 62 83 d8 81 d3 64 31  |...b....pb....d1|
-000001a0  aa 9e 97 31 bd 96 b0 68  c0 9b 23 de 76 64 3f 1a  |...1...h..#.vd?.|
-000001b0  5c 7f e9 12 0e 58 58 b6  5f 70 dd 9b d8 ea d5 d7  |\....XX._p......|
-000001c0  f5 d5 cc b9 b6 9f 30 66  5b 66 9a 20 e2 27 e5 bf  |......0f[f. .'..|
-000001d0  fe 3b 30 09 06 07 2a 86  48 ce 3d 04 01 03 81 8c  |.;0...*.H.=.....|
-000001e0  00 30 81 88 02 42 01 88  a2 4f eb e2 45 c5 48 7d  |.0...B...O..E.H}|
-000001f0  1b ac f5 ed 98 9d ae 47  70 c0 5e 1b b6 2f bd f1  |.......Gp.^../..|
-00000200  b6 4d b7 61 40 d3 11 a2  ce ee 0b 7e 92 7e ff 76  |.M.a@......~.~.v|
-00000210  9d c3 3b 7e a5 3f ce fa  10 e2 59 ec 47 2d 7c ac  |..;~.?....Y.G-|.|
-00000220  da 4e 97 0e 15 a0 6f d0  02 42 01 4d fc be 67 13  |.N....o..B.M..g.|
-00000230  9c 2d 05 0e bd 3f a3 8c  25 c1 33 13 83 0d 94 06  |.-...?..%.3.....|
-00000240  bb d4 37 7a f6 ec 7a c9  86 2e dd d7 11 69 7f 85  |..7z..z......i..|
-00000250  7c 56 de fb 31 78 2b e4  c7 78 0d ae cb be 9e 4e  ||V..1x+..x.....N|
-00000260  36 24 31 7b 6a 0f 39 95  12 07 8f 2a 16 03 01 00  |6$1{j.9....*....|
-00000270  d5 0c 00 00 d1 03 00 17  41 04 65 02 4b f2 bc 54  |........A.e.K..T|
-00000280  3d c2 42 3d 8d 06 b4 9a  7a 15 c8 04 0f 2b a0 f8  |=.B=....z....+..|
-00000290  ee e8 5d 52 10 c3 36 30  e0 cc 34 67 bb 83 29 ea  |..]R..60..4g..).|
-000002a0  d3 47 56 54 95 c5 29 25  53 d8 97 15 66 69 f2 cb  |.GVT..)%S...fi..|
-000002b0  59 05 97 f7 ac 66 27 d9  19 4a 00 8a 30 81 87 02  |Y....f'..J..0...|
-000002c0  41 6a 3c ca 93 ea 20 84  0e 04 2b 1b 52 28 32 29  |Aj<... ...+.R(2)|
-000002d0  af b9 8d fb 1c 5c c3 02  6b 45 02 c7 25 4e 19 51  |.....\..kE..%N.Q|
-000002e0  19 8b 3c 34 5d 20 b8 77  77 4a f1 b1 ba 47 03 14  |..<4] .wwJ...G..|
-000002f0  09 74 42 df 82 39 b0 51  54 ad e9 4d 1a 9d b9 18  |.tB..9.QT..M....|
-00000300  14 58 02 42 01 b8 18 1d  a1 53 a2 52 ad a3 13 85  |.X.B.....S.R....|
-00000310  f5 fb c4 75 0e 6b f1 f9  a6 7d 21 63 d0 fe 20 ba  |...u.k...}!c.. .|
-00000320  4b 38 3d 25 12 dc 73 5e  1d 5e 23 e5 52 ae cf 62  |K8=%..s^.^#.R..b|
-00000330  5a f4 a5 11 b7 33 1e 08  06 32 bb 7f 8d 40 db 5f  |Z....3...2...@._|
-00000340  f7 39 93 0e 32 9e 16 03  01 00 04 0e 00 00 00     |.9..2..........|
+00000000  16 03 01 00 59 02 00 00  55 03 01 52 cc 57 58 a5  |....Y...U..R.WX.|
+00000010  0d f3 9c e1 2f 44 99 dc  f2 26 bc c2 44 4a 0f ab  |..../D...&..DJ..|
+00000020  6d 40 3b 5a 98 21 43 9e  c0 39 03 20 03 46 6f c2  |m@;Z.!C..9. .Fo.|
+00000030  bd 1f bc cc 2d b2 eb 22  91 23 df 20 28 c5 df ea  |....-..".#. (...|
+00000040  70 1a dc 07 b9 19 a1 d0  03 74 81 a8 c0 09 00 00  |p........t......|
+00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
+00000060  01 02 0e 0b 00 02 0a 00  02 07 00 02 04 30 82 02  |.............0..|
+00000070  00 30 82 01 62 02 09 00  b8 bf 2d 47 a0 d2 eb f4  |.0..b.....-G....|
+00000080  30 09 06 07 2a 86 48 ce  3d 04 01 30 45 31 0b 30  |0...*.H.=..0E1.0|
+00000090  09 06 03 55 04 06 13 02  41 55 31 13 30 11 06 03  |...U....AU1.0...|
+000000a0  55 04 08 13 0a 53 6f 6d  65 2d 53 74 61 74 65 31  |U....Some-State1|
+000000b0  21 30 1f 06 03 55 04 0a  13 18 49 6e 74 65 72 6e  |!0...U....Intern|
+000000c0  65 74 20 57 69 64 67 69  74 73 20 50 74 79 20 4c  |et Widgits Pty L|
+000000d0  74 64 30 1e 17 0d 31 32  31 31 32 32 31 35 30 36  |td0...1211221506|
+000000e0  33 32 5a 17 0d 32 32 31  31 32 30 31 35 30 36 33  |32Z..22112015063|
+000000f0  32 5a 30 45 31 0b 30 09  06 03 55 04 06 13 02 41  |2Z0E1.0...U....A|
+00000100  55 31 13 30 11 06 03 55  04 08 13 0a 53 6f 6d 65  |U1.0...U....Some|
+00000110  2d 53 74 61 74 65 31 21  30 1f 06 03 55 04 0a 13  |-State1!0...U...|
+00000120  18 49 6e 74 65 72 6e 65  74 20 57 69 64 67 69 74  |.Internet Widgit|
+00000130  73 20 50 74 79 20 4c 74  64 30 81 9b 30 10 06 07  |s Pty Ltd0..0...|
+00000140  2a 86 48 ce 3d 02 01 06  05 2b 81 04 00 23 03 81  |*.H.=....+...#..|
+00000150  86 00 04 00 c4 a1 ed be  98 f9 0b 48 73 36 7e c3  |...........Hs6~.|
+00000160  16 56 11 22 f2 3d 53 c3  3b 4d 21 3d cd 6b 75 e6  |.V.".=S.;M!=.ku.|
+00000170  f6 b0 dc 9a df 26 c1 bc  b2 87 f0 72 32 7c b3 64  |.....&.....r2|.d|
+00000180  2f 1c 90 bc ea 68 23 10  7e fe e3 25 c0 48 3a 69  |/....h#.~..%.H:i|
+00000190  e0 28 6d d3 37 00 ef 04  62 dd 0d a0 9c 70 62 83  |.(m.7...b....pb.|
+000001a0  d8 81 d3 64 31 aa 9e 97  31 bd 96 b0 68 c0 9b 23  |...d1...1...h..#|
+000001b0  de 76 64 3f 1a 5c 7f e9  12 0e 58 58 b6 5f 70 dd  |.vd?.\....XX._p.|
+000001c0  9b d8 ea d5 d7 f5 d5 cc  b9 b6 9f 30 66 5b 66 9a  |...........0f[f.|
+000001d0  20 e2 27 e5 bf fe 3b 30  09 06 07 2a 86 48 ce 3d  | .'...;0...*.H.=|
+000001e0  04 01 03 81 8c 00 30 81  88 02 42 01 88 a2 4f eb  |......0...B...O.|
+000001f0  e2 45 c5 48 7d 1b ac f5  ed 98 9d ae 47 70 c0 5e  |.E.H}.......Gp.^|
+00000200  1b b6 2f bd f1 b6 4d b7  61 40 d3 11 a2 ce ee 0b  |../...M.a@......|
+00000210  7e 92 7e ff 76 9d c3 3b  7e a5 3f ce fa 10 e2 59  |~.~.v..;~.?....Y|
+00000220  ec 47 2d 7c ac da 4e 97  0e 15 a0 6f d0 02 42 01  |.G-|..N....o..B.|
+00000230  4d fc be 67 13 9c 2d 05  0e bd 3f a3 8c 25 c1 33  |M..g..-...?..%.3|
+00000240  13 83 0d 94 06 bb d4 37  7a f6 ec 7a c9 86 2e dd  |.......7z..z....|
+00000250  d7 11 69 7f 85 7c 56 de  fb 31 78 2b e4 c7 78 0d  |..i..|V..1x+..x.|
+00000260  ae cb be 9e 4e 36 24 31  7b 6a 0f 39 95 12 07 8f  |....N6$1{j.9....|
+00000270  2a 16 03 01 00 d5 0c 00  00 d1 03 00 17 41 04 3c  |*............A.<|
+00000280  f8 33 94 22 ad fb 45 01  10 5c 8e b1 09 19 da de  |.3."..E..\......|
+00000290  21 0a 09 72 af 25 6f 2f  63 4d 8c 6b b6 a6 00 02  |!..r.%o/cM.k....|
+000002a0  4d 6c fe 71 9e 45 74 13  db b5 7a a1 74 f0 16 35  |Ml.q.Et...z.t..5|
+000002b0  50 fd ab 45 4c 64 9f 4d  80 a9 5c 85 ee 20 33 00  |P..ELd.M..\.. 3.|
+000002c0  8a 30 81 87 02 42 01 73  bc ac 1a 30 11 5f 93 95  |.0...B.s...0._..|
+000002d0  00 03 ba d6 f3 02 cd c9  a0 15 bf 9a 1a 59 24 1e  |.............Y$.|
+000002e0  3e 99 6b da b1 81 e1 eb  da fd 8e 73 d6 94 1e ce  |>.k........s....|
+000002f0  04 cf 41 33 cd e5 8d f0  e2 50 b9 9b 49 df bc 51  |..A3.....P..I..Q|
+00000300  2d 5c 12 5c b3 8b 81 73  02 41 3c bf 11 5c 10 be  |-\.\...s.A<..\..|
+00000310  f2 e7 59 2f 9a d7 0e 49  a3 17 7d 20 cc bc 17 1f  |..Y/...I..} ....|
+00000320  2d 1b 19 90 52 c5 16 08  b3 3c b0 33 9d 03 45 75  |-...R....<.3..Eu|
+00000330  0c 3f ac 7b 0b b2 69 f4  a5 7c fc 49 a6 54 55 84  |.?.{..i..|.I.TU.|
+00000340  2f 19 f1 de 1b 92 3d fb  68 5d ea 16 03 01 00 04  |/.....=.h]......|
+00000350  0e 00 00 00                                       |....|
 >>> Flow 3 (client to server)
 00000000  16 03 01 00 46 10 00 00  42 41 04 1e 18 37 ef 0d  |....F...BA...7..|
 00000010  19 51 88 35 75 71 b5 e5  54 5b 12 2e 8f 09 67 fd  |.Q.5uq..T[....g.|
 00000020  a7 24 20 3e b2 56 1c ce  97 28 5e f8 2b 2d 4f 9e  |.$ >.V...(^.+-O.|
 00000030  f1 07 9f 6c 4b 5b 83 56  e2 32 42 e9 58 b6 d7 49  |...lK[.V.2B.X..I|
 00000040  a6 b5 68 1a 41 03 56 6b  dc 5a 89 14 03 01 00 01  |..h.A.Vk.Z......|
-00000050  01 16 03 01 00 30 6d 72  30 82 5b 76 0b bd a7 a2  |.....0mr0.[v....|
-00000060  ed 1e de bd 14 1d 25 69  97 4c ad 9c b1 50 8e 2f  |......%i.L...P./|
-00000070  a0 65 ac e7 52 e0 b4 fb  f9 8c e7 26 09 96 53 6f  |.e..R......&..So|
-00000080  bc 77 24 8c 1f a7                                 |.w$...|
+00000050  01 16 03 01 00 30 c7 cf  21 f8 0c 94 5b 11 ef ee  |.....0..!...[...|
+00000060  d0 d3 3a d5 ba 2d 19 8b  5b 53 68 94 f1 49 8b 19  |..:..-..[Sh..I..|
+00000070  f3 80 d5 55 52 7d 72 af  38 73 35 df 6e 04 4b ca  |...UR}r.8s5.n.K.|
+00000080  64 b7 ff c3 e1 eb                                 |d.....|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 30 a0 97 45 7d 58  |..........0..E}X|
-00000010  2d 6e 6b 51 ad 5b 4f e0  f3 58 d3 48 a6 e1 b7 71  |-nkQ.[O..X.H...q|
-00000020  f8 94 e2 fe c5 c9 b2 0b  27 4f 48 11 df 01 5f ef  |........'OH..._.|
-00000030  5d 9c f5 85 91 39 75 f4  21 1b ed                 |]....9u.!..|
+00000000  14 03 01 00 01 01 16 03  01 00 30 59 2c 4c 03 7f  |..........0Y,L..|
+00000010  aa a8 ca d8 2a b0 35 71  ea 3a 2b d4 b1 9f 13 f9  |....*.5q.:+.....|
+00000020  c2 7b fb 21 52 15 73 e6  71 d4 65 8e 21 25 1a 63  |.{.!R.s.q.e.!%.c|
+00000030  03 d3 a5 6b 17 0e e7 18  84 17 d8                 |...k.......|
 >>> Flow 5 (client to server)
-00000000  17 03 01 00 20 31 c0 13  eb 77 e7 51 f6 14 fc bd  |.... 1...w.Q....|
-00000010  94 32 2c 31 58 28 72 29  a9 6a 11 56 f2 c1 de 96  |.2,1X(r).j.V....|
-00000020  e0 cd cf 4a 47 17 03 01  00 20 b2 95 e4 81 56 f3  |...JG.... ....V.|
-00000030  f8 6a b1 4f a0 41 41 fd  1f 7e b8 bb 7f 71 80 0d  |.j.O.AA..~...q..|
-00000040  22 9f 46 be cb b9 b6 bd  c0 0e 15 03 01 00 20 fa  |".F........... .|
-00000050  4e 05 c4 29 a5 92 4e 68  34 b7 5b 99 a8 b3 46 1b  |N..)..Nh4.[...F.|
-00000060  f9 f6 fc e5 b4 f4 cd c4  be 1a b2 af b7 13 43     |..............C|
+00000000  17 03 01 00 20 8d 73 59  92 ce 93 78 e6 63 cf 9d  |.... .sY...x.c..|
+00000010  bc 44 40 76 c7 66 3f 15  3a 0a 91 9b 94 49 ec cc  |.D@v.f?.:....I..|
+00000020  7c 1a 6c b2 85 17 03 01  00 20 2e 6a dd 85 be 12  ||.l...... .j....|
+00000030  c1 45 e4 04 bf 46 70 19  12 d1 1a 28 f6 22 30 a2  |.E...Fp....(."0.|
+00000040  fe 98 a8 11 c2 c4 19 46  c6 7e 15 03 01 00 20 a7  |.......F.~.... .|
+00000050  71 3d 87 94 9d 6c c5 dd  de 44 54 47 d5 06 37 82  |q=...l...DTG..7.|
+00000060  36 e0 c2 e5 91 74 a8 88  28 2f 87 7d a1 a7 e3     |6....t..(/.}...|
index f4904a3db6367cbe889bc510a0f679a0fef9d7f6..ae03ea4584dab042c8d12164ea6bb0fdd74cac97 100644 (file)
@@ -1,97 +1,97 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 70 01 00 00  6c 03 03 00 00 00 00 00  |....p...l.......|
+00000000  16 03 01 00 75 01 00 00  71 03 03 00 00 00 00 00  |....u...q.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
 00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
-00000040  00 2f 00 35 c0 12 00 0a  01 00 00 29 00 05 00 05  |./.5.......)....|
+00000040  00 2f 00 35 c0 12 00 0a  01 00 00 2e 00 05 00 05  |./.5............|
 00000050  01 00 00 00 00 00 0a 00  08 00 06 00 17 00 18 00  |................|
 00000060  19 00 0b 00 02 01 00 00  0d 00 0a 00 08 04 01 04  |................|
-00000070  03 02 01 02 03                                    |.....|
+00000070  03 02 01 02 03 ff 01 00  01 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 01 00 54 02 00 00  50 03 01 52 ac 77 f7 b6  |....T...P..R.w..|
-00000010  40 88 14 a0 46 9b 24 3c  7c 8d cb 63 70 b3 fc 60  |@...F.$<|..cp..`|
-00000020  fb 04 97 82 c4 f6 d4 02  ab c6 5b 20 da cf c2 62  |..........[ ...b|
-00000030  87 5b 67 63 3a fa e1 f7  cd 64 d2 84 ee 95 bb 86  |.[gc:....d......|
-00000040  f5 c7 32 20 74 99 34 6c  ad 92 07 de c0 13 00 00  |..2 t.4l........|
-00000050  08 00 0b 00 04 03 00 01  02 16 03 01 02 be 0b 00  |................|
-00000060  02 ba 00 02 b7 00 02 b4  30 82 02 b0 30 82 02 19  |........0...0...|
-00000070  a0 03 02 01 02 02 09 00  85 b0 bb a4 8a 7f b8 ca  |................|
-00000080  30 0d 06 09 2a 86 48 86  f7 0d 01 01 05 05 00 30  |0...*.H........0|
-00000090  45 31 0b 30 09 06 03 55  04 06 13 02 41 55 31 13  |E1.0...U....AU1.|
-000000a0  30 11 06 03 55 04 08 13  0a 53 6f 6d 65 2d 53 74  |0...U....Some-St|
-000000b0  61 74 65 31 21 30 1f 06  03 55 04 0a 13 18 49 6e  |ate1!0...U....In|
-000000c0  74 65 72 6e 65 74 20 57  69 64 67 69 74 73 20 50  |ternet Widgits P|
-000000d0  74 79 20 4c 74 64 30 1e  17 0d 31 30 30 34 32 34  |ty Ltd0...100424|
-000000e0  30 39 30 39 33 38 5a 17  0d 31 31 30 34 32 34 30  |090938Z..1104240|
-000000f0  39 30 39 33 38 5a 30 45  31 0b 30 09 06 03 55 04  |90938Z0E1.0...U.|
-00000100  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
-00000110  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
-00000120  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
-00000130  64 67 69 74 73 20 50 74  79 20 4c 74 64 30 81 9f  |dgits Pty Ltd0..|
-00000140  30 0d 06 09 2a 86 48 86  f7 0d 01 01 01 05 00 03  |0...*.H.........|
-00000150  81 8d 00 30 81 89 02 81  81 00 bb 79 d6 f5 17 b5  |...0.......y....|
-00000160  e5 bf 46 10 d0 dc 69 be  e6 2b 07 43 5a d0 03 2d  |..F...i..+.CZ..-|
-00000170  8a 7a 43 85 b7 14 52 e7  a5 65 4c 2c 78 b8 23 8c  |.zC...R..eL,x.#.|
-00000180  b5 b4 82 e5 de 1f 95 3b  7e 62 a5 2c a5 33 d6 fe  |.......;~b.,.3..|
-00000190  12 5c 7a 56 fc f5 06 bf  fa 58 7b 26 3f b5 cd 04  |.\zV.....X{&?...|
-000001a0  d3 d0 c9 21 96 4a c7 f4  54 9f 5a bf ef 42 71 00  |...!.J..T.Z..Bq.|
-000001b0  fe 18 99 07 7f 7e 88 7d  7d f1 04 39 c4 a2 2e db  |.....~.}}..9....|
-000001c0  51 c9 7c e3 c0 4c 3b 32  66 01 cf af b1 1d b8 71  |Q.|..L;2f......q|
-000001d0  9a 1d db db 89 6b ae da  2d 79 02 03 01 00 01 a3  |.....k..-y......|
-000001e0  81 a7 30 81 a4 30 1d 06  03 55 1d 0e 04 16 04 14  |..0..0...U......|
-000001f0  b1 ad e2 85 5a cf cb 28  db 69 ce 23 69 de d3 26  |....Z..(.i.#i..&|
-00000200  8e 18 88 39 30 75 06 03  55 1d 23 04 6e 30 6c 80  |...90u..U.#.n0l.|
-00000210  14 b1 ad e2 85 5a cf cb  28 db 69 ce 23 69 de d3  |.....Z..(.i.#i..|
-00000220  26 8e 18 88 39 a1 49 a4  47 30 45 31 0b 30 09 06  |&...9.I.G0E1.0..|
-00000230  03 55 04 06 13 02 41 55  31 13 30 11 06 03 55 04  |.U....AU1.0...U.|
-00000240  08 13 0a 53 6f 6d 65 2d  53 74 61 74 65 31 21 30  |...Some-State1!0|
-00000250  1f 06 03 55 04 0a 13 18  49 6e 74 65 72 6e 65 74  |...U....Internet|
-00000260  20 57 69 64 67 69 74 73  20 50 74 79 20 4c 74 64  | Widgits Pty Ltd|
-00000270  82 09 00 85 b0 bb a4 8a  7f b8 ca 30 0c 06 03 55  |...........0...U|
-00000280  1d 13 04 05 30 03 01 01  ff 30 0d 06 09 2a 86 48  |....0....0...*.H|
-00000290  86 f7 0d 01 01 05 05 00  03 81 81 00 08 6c 45 24  |.............lE$|
-000002a0  c7 6b b1 59 ab 0c 52 cc  f2 b0 14 d7 87 9d 7a 64  |.k.Y..R.......zd|
-000002b0  75 b5 5a 95 66 e4 c5 2b  8e ae 12 66 1f eb 4f 38  |u.Z.f..+...f..O8|
-000002c0  b3 6e 60 d3 92 fd f7 41  08 b5 25 13 b1 18 7a 24  |.n`....A..%...z$|
-000002d0  fb 30 1d ba ed 98 b9 17  ec e7 d7 31 59 db 95 d3  |.0.........1Y...|
-000002e0  1d 78 ea 50 56 5c d5 82  5a 2d 5a 5f 33 c4 b6 d8  |.x.PV\..Z-Z_3...|
-000002f0  c9 75 90 96 8c 0f 52 98  b5 cd 98 1f 89 20 5f f2  |.u....R...... _.|
-00000300  a0 1c a3 1b 96 94 dd a9  fd 57 e9 70 e8 26 6d 71  |.........W.p.&mq|
-00000310  99 9b 26 6e 38 50 29 6c  90 a7 bd d9 16 03 01 00  |..&n8P)l........|
-00000320  cb 0c 00 00 c7 03 00 17  41 04 eb a8 6e 0a 31 5e  |........A...n.1^|
-00000330  20 2a 31 db 85 82 43 e0  b6 ca a5 3c 1c e1 32 52  | *1...C....<..2R|
-00000340  e8 75 50 f2 e2 e0 de 30  06 3f e5 6d 8f d5 00 61  |.uP....0.?.m...a|
-00000350  22 8a bc e0 58 4a 37 3b  fd b7 67 2e c4 07 22 4c  |"...XJ7;..g..."L|
-00000360  ac 27 6d bb 10 b6 e3 6e  34 35 00 80 8c e7 14 84  |.'m....n45......|
-00000370  84 d0 ab f9 8f c7 ae 6d  34 c7 f8 9e e4 93 3e 67  |.......m4.....>g|
-00000380  be 03 7a 7a 5b 30 15 99  e2 e8 ff c1 28 af 40 9a  |..zz[0......(.@.|
-00000390  20 8c 11 e1 c7 12 fe bc  b5 12 51 f8 59 ed af a2  | .........Q.Y...|
-000003a0  78 d2 77 e2 bc 0e 97 0b  69 8f 98 40 04 6e 59 4e  |x.w.....i..@.nYN|
-000003b0  6d 50 c2 06 7e a6 74 27  97 a0 35 43 7d 9f 44 66  |mP..~.t'..5C}.Df|
-000003c0  17 91 fe 19 50 c2 d4 9a  f7 4f 0b 8a 40 c9 33 c8  |....P....O..@.3.|
-000003d0  a5 b0 0a d4 18 72 4a 1d  5d cd b3 9a 62 d9 1d 04  |.....rJ.]...b...|
-000003e0  d2 42 04 a1 27 5a 19 02  19 d9 cd ab 16 03 01 00  |.B..'Z..........|
-000003f0  04 0e 00 00 00                                    |.....|
+00000000  16 03 01 00 59 02 00 00  55 03 01 52 cc 57 58 f3  |....Y...U..R.WX.|
+00000010  e4 e3 02 40 35 40 24 91  0a 0b 54 1b 46 0d c1 46  |...@5@$...T.F..F|
+00000020  7f 9c dd 08 ec 9c 63 73  13 cd e8 20 3c c2 72 a5  |......cs... <.r.|
+00000030  8d 4e 66 14 83 b1 27 c9  51 7e a6 46 7c 38 e1 66  |.Nf...'.Q~.F|8.f|
+00000040  3f f6 9c e2 8d e0 51 29  fc 76 ee d0 c0 13 00 00  |?.....Q).v......|
+00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
+00000060  01 02 be 0b 00 02 ba 00  02 b7 00 02 b4 30 82 02  |.............0..|
+00000070  b0 30 82 02 19 a0 03 02  01 02 02 09 00 85 b0 bb  |.0..............|
+00000080  a4 8a 7f b8 ca 30 0d 06  09 2a 86 48 86 f7 0d 01  |.....0...*.H....|
+00000090  01 05 05 00 30 45 31 0b  30 09 06 03 55 04 06 13  |....0E1.0...U...|
+000000a0  02 41 55 31 13 30 11 06  03 55 04 08 13 0a 53 6f  |.AU1.0...U....So|
+000000b0  6d 65 2d 53 74 61 74 65  31 21 30 1f 06 03 55 04  |me-State1!0...U.|
+000000c0  0a 13 18 49 6e 74 65 72  6e 65 74 20 57 69 64 67  |...Internet Widg|
+000000d0  69 74 73 20 50 74 79 20  4c 74 64 30 1e 17 0d 31  |its Pty Ltd0...1|
+000000e0  30 30 34 32 34 30 39 30  39 33 38 5a 17 0d 31 31  |00424090938Z..11|
+000000f0  30 34 32 34 30 39 30 39  33 38 5a 30 45 31 0b 30  |0424090938Z0E1.0|
+00000100  09 06 03 55 04 06 13 02  41 55 31 13 30 11 06 03  |...U....AU1.0...|
+00000110  55 04 08 13 0a 53 6f 6d  65 2d 53 74 61 74 65 31  |U....Some-State1|
+00000120  21 30 1f 06 03 55 04 0a  13 18 49 6e 74 65 72 6e  |!0...U....Intern|
+00000130  65 74 20 57 69 64 67 69  74 73 20 50 74 79 20 4c  |et Widgits Pty L|
+00000140  74 64 30 81 9f 30 0d 06  09 2a 86 48 86 f7 0d 01  |td0..0...*.H....|
+00000150  01 01 05 00 03 81 8d 00  30 81 89 02 81 81 00 bb  |........0.......|
+00000160  79 d6 f5 17 b5 e5 bf 46  10 d0 dc 69 be e6 2b 07  |y......F...i..+.|
+00000170  43 5a d0 03 2d 8a 7a 43  85 b7 14 52 e7 a5 65 4c  |CZ..-.zC...R..eL|
+00000180  2c 78 b8 23 8c b5 b4 82  e5 de 1f 95 3b 7e 62 a5  |,x.#........;~b.|
+00000190  2c a5 33 d6 fe 12 5c 7a  56 fc f5 06 bf fa 58 7b  |,.3...\zV.....X{|
+000001a0  26 3f b5 cd 04 d3 d0 c9  21 96 4a c7 f4 54 9f 5a  |&?......!.J..T.Z|
+000001b0  bf ef 42 71 00 fe 18 99  07 7f 7e 88 7d 7d f1 04  |..Bq......~.}}..|
+000001c0  39 c4 a2 2e db 51 c9 7c  e3 c0 4c 3b 32 66 01 cf  |9....Q.|..L;2f..|
+000001d0  af b1 1d b8 71 9a 1d db  db 89 6b ae da 2d 79 02  |....q.....k..-y.|
+000001e0  03 01 00 01 a3 81 a7 30  81 a4 30 1d 06 03 55 1d  |.......0..0...U.|
+000001f0  0e 04 16 04 14 b1 ad e2  85 5a cf cb 28 db 69 ce  |.........Z..(.i.|
+00000200  23 69 de d3 26 8e 18 88  39 30 75 06 03 55 1d 23  |#i..&...90u..U.#|
+00000210  04 6e 30 6c 80 14 b1 ad  e2 85 5a cf cb 28 db 69  |.n0l......Z..(.i|
+00000220  ce 23 69 de d3 26 8e 18  88 39 a1 49 a4 47 30 45  |.#i..&...9.I.G0E|
+00000230  31 0b 30 09 06 03 55 04  06 13 02 41 55 31 13 30  |1.0...U....AU1.0|
+00000240  11 06 03 55 04 08 13 0a  53 6f 6d 65 2d 53 74 61  |...U....Some-Sta|
+00000250  74 65 31 21 30 1f 06 03  55 04 0a 13 18 49 6e 74  |te1!0...U....Int|
+00000260  65 72 6e 65 74 20 57 69  64 67 69 74 73 20 50 74  |ernet Widgits Pt|
+00000270  79 20 4c 74 64 82 09 00  85 b0 bb a4 8a 7f b8 ca  |y Ltd...........|
+00000280  30 0c 06 03 55 1d 13 04  05 30 03 01 01 ff 30 0d  |0...U....0....0.|
+00000290  06 09 2a 86 48 86 f7 0d  01 01 05 05 00 03 81 81  |..*.H...........|
+000002a0  00 08 6c 45 24 c7 6b b1  59 ab 0c 52 cc f2 b0 14  |..lE$.k.Y..R....|
+000002b0  d7 87 9d 7a 64 75 b5 5a  95 66 e4 c5 2b 8e ae 12  |...zdu.Z.f..+...|
+000002c0  66 1f eb 4f 38 b3 6e 60  d3 92 fd f7 41 08 b5 25  |f..O8.n`....A..%|
+000002d0  13 b1 18 7a 24 fb 30 1d  ba ed 98 b9 17 ec e7 d7  |...z$.0.........|
+000002e0  31 59 db 95 d3 1d 78 ea  50 56 5c d5 82 5a 2d 5a  |1Y....x.PV\..Z-Z|
+000002f0  5f 33 c4 b6 d8 c9 75 90  96 8c 0f 52 98 b5 cd 98  |_3....u....R....|
+00000300  1f 89 20 5f f2 a0 1c a3  1b 96 94 dd a9 fd 57 e9  |.. _..........W.|
+00000310  70 e8 26 6d 71 99 9b 26  6e 38 50 29 6c 90 a7 bd  |p.&mq..&n8P)l...|
+00000320  d9 16 03 01 00 cb 0c 00  00 c7 03 00 17 41 04 30  |.............A.0|
+00000330  a3 31 3d 66 ce 80 2a fb  1d 11 66 f6 35 cb c9 d2  |.1=f..*...f.5...|
+00000340  53 fd 18 37 84 75 7e 00  55 92 0c 6d e5 40 46 77  |S..7.u~.U..m.@Fw|
+00000350  d8 17 d4 81 13 74 90 e0  7c 4b 58 25 65 99 8e 18  |.....t..|KX%e...|
+00000360  9f d7 af e0 70 f8 c6 99  13 2d 0e 28 32 02 40 00  |....p....-.(2.@.|
+00000370  80 b3 34 d4 4a d7 c1 8e  1d f6 23 ef 04 0c d6 bb  |..4.J.....#.....|
+00000380  40 8c 85 0f ce a6 8e d2  29 3d 81 0f 47 ce 59 dc  |@.......)=..G.Y.|
+00000390  dc 56 68 b1 11 af 98 3a  07 4b 7a d9 6e 08 c5 ff  |.Vh....:.Kz.n...|
+000003a0  b2 54 06 72 f3 d2 19 22  df ee 90 fc 8a 4d 76 c1  |.T.r...".....Mv.|
+000003b0  c2 d4 af d7 77 82 79 3d  12 0f 9c 56 28 a6 43 ea  |....w.y=...V(.C.|
+000003c0  a3 71 c2 af bf 52 40 4a  fa c7 3e d3 ae 8e 84 42  |.q...R@J..>....B|
+000003d0  5f fd 9f a7 0f 94 8c fa  15 86 23 28 be 2b 3a 32  |_.........#(.+:2|
+000003e0  cb e5 18 5c 2d d6 d9 94  5f a4 b7 05 d0 a0 ab aa  |...\-..._.......|
+000003f0  c3 16 03 01 00 04 0e 00  00 00                    |..........|
 >>> Flow 3 (client to server)
 00000000  16 03 01 00 46 10 00 00  42 41 04 1e 18 37 ef 0d  |....F...BA...7..|
 00000010  19 51 88 35 75 71 b5 e5  54 5b 12 2e 8f 09 67 fd  |.Q.5uq..T[....g.|
 00000020  a7 24 20 3e b2 56 1c ce  97 28 5e f8 2b 2d 4f 9e  |.$ >.V...(^.+-O.|
 00000030  f1 07 9f 6c 4b 5b 83 56  e2 32 42 e9 58 b6 d7 49  |...lK[.V.2B.X..I|
 00000040  a6 b5 68 1a 41 03 56 6b  dc 5a 89 14 03 01 00 01  |..h.A.Vk.Z......|
-00000050  01 16 03 01 00 30 33 95  ec 63 ff 89 fe 3b f8 80  |.....03..c...;..|
-00000060  1b 05 c6 29 a4 72 78 af  04 c1 21 53 fd 02 28 36  |...).rx...!S..(6|
-00000070  29 b1 c7 a8 25 02 3d b0  ad 5b f3 52 9c a0 f5 8d  |)...%.=..[.R....|
-00000080  da 03 65 b6 ac 27                                 |..e..'|
+00000050  01 16 03 01 00 30 34 e6  9a 20 8c 33 d7 85 ae 83  |.....04.. .3....|
+00000060  f1 8f 46 68 63 3f a3 23  88 f8 00 9b 01 a7 80 c6  |..Fhc?.#........|
+00000070  8b 45 6e 5a c1 2f 62 5f  70 b6 20 1e 58 18 53 6b  |.EnZ./b_p. .X.Sk|
+00000080  e2 cb ce 2c 97 7c                                 |...,.||
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 30 20 59 0a 77 5a  |..........0 Y.wZ|
-00000010  15 63 2b 9e f0 ff 27 ce  a8 57 89 e3 32 91 2d 5b  |.c+...'..W..2.-[|
-00000020  55 e1 c0 fd 50 69 c8 e1  d8 02 e3 3f d4 56 d7 b8  |U...Pi.....?.V..|
-00000030  80 5f 83 53 5e 2e 17 c3  41 72 bd                 |._.S^...Ar.|
+00000000  14 03 01 00 01 01 16 03  01 00 30 ff 81 ba a6 cc  |..........0.....|
+00000010  c5 25 83 eb 65 99 39 4d  19 39 c1 8c cf b5 30 58  |.%..e.9M.9....0X|
+00000020  aa 6f e1 f4 f7 da 88 14  39 c0 1b 5a f3 05 bd 8c  |.o......9..Z....|
+00000030  6b af 52 32 0f 1e 87 0c  7a 39 3a                 |k.R2....z9:|
 >>> Flow 5 (client to server)
-00000000  17 03 01 00 20 f5 42 0c  71 9c 27 35 6f 89 96 ca  |.... .B.q.'5o...|
-00000010  25 55 ce d3 81 3a 99 6e  c3 25 29 c6 71 05 f2 e2  |%U...:.n.%).q...|
-00000020  4d 21 6f d9 d6 17 03 01  00 20 a2 03 64 b9 0e e9  |M!o...... ..d...|
-00000030  cf 8e aa 15 f4 46 66 52  a6 c1 8b 00 3b 22 36 cc  |.....FfR....;"6.|
-00000040  34 b6 43 08 a5 73 eb 3f  1f e6 15 03 01 00 20 52  |4.C..s.?...... R|
-00000050  4d 42 9f 91 8e 0d d9 3f  ca 35 7f 47 af 30 14 5c  |MB.....?.5.G.0.\|
-00000060  10 6d de 84 84 36 2e f3  24 44 a3 5f 2b e4 7e     |.m...6..$D._+.~|
+00000000  17 03 01 00 20 72 b0 d7  a5 88 02 64 29 65 4b d5  |.... r.....d)eK.|
+00000010  f7 0b 74 bd df af ce 2d  02 6b 01 37 fb 44 80 e6  |..t....-.k.7.D..|
+00000020  f4 e1 17 e6 7f 17 03 01  00 20 18 8a 94 81 86 56  |......... .....V|
+00000030  eb 7e 77 48 03 ce b4 8c  2b 75 b8 06 eb 66 5f 77  |.~wH....+u...f_w|
+00000040  df 98 1f cd 6d bd 39 38  06 fc 15 03 01 00 20 d1  |....m.98...... .|
+00000050  bd 74 3b eb a2 f6 be ad  ab df 5f 99 c2 92 fd 9b  |.t;......._.....|
+00000060  e7 9a 03 a5 f4 00 99 8c  f8 85 34 2d 15 a0 30     |..........4-..0|
index a69125574734c210166103b41fd6446100796eeb..1a6c42c14581e82068c5041faac002d2db4de2a3 100644 (file)
@@ -1,63 +1,64 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 70 01 00 00  6c 03 03 00 00 00 00 00  |....p...l.......|
+00000000  16 03 01 00 75 01 00 00  71 03 03 00 00 00 00 00  |....u...q.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
 00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
-00000040  00 2f 00 35 c0 12 00 0a  01 00 00 29 00 05 00 05  |./.5.......)....|
+00000040  00 2f 00 35 c0 12 00 0a  01 00 00 2e 00 05 00 05  |./.5............|
 00000050  01 00 00 00 00 00 0a 00  08 00 06 00 17 00 18 00  |................|
 00000060  19 00 0b 00 02 01 00 00  0d 00 0a 00 08 04 01 04  |................|
-00000070  03 02 01 02 03                                    |.....|
+00000070  03 02 01 02 03 ff 01 00  01 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 01 00 4a 02 00 00  46 03 01 52 ac 77 f7 17  |....J...F..R.w..|
-00000010  4c 25 27 29 1a fe 71 9e  69 96 e9 a7 8a 5f dc 47  |L%')..q.i...._.G|
-00000020  b1 70 9a 23 e0 3a 32 95  4e 73 a4 20 b1 7a f0 69  |.p.#.:2.Ns. .z.i|
-00000030  f6 26 55 0b 6b 77 cc b6  f2 03 5b 6c 81 25 28 ea  |.&U.kw....[l.%(.|
-00000040  4b 2e ac 7a fe 54 62 bf  62 b4 0c e3 00 05 00 16  |K..z.Tb.b.......|
-00000050  03 01 02 be 0b 00 02 ba  00 02 b7 00 02 b4 30 82  |..............0.|
-00000060  02 b0 30 82 02 19 a0 03  02 01 02 02 09 00 85 b0  |..0.............|
-00000070  bb a4 8a 7f b8 ca 30 0d  06 09 2a 86 48 86 f7 0d  |......0...*.H...|
-00000080  01 01 05 05 00 30 45 31  0b 30 09 06 03 55 04 06  |.....0E1.0...U..|
-00000090  13 02 41 55 31 13 30 11  06 03 55 04 08 13 0a 53  |..AU1.0...U....S|
-000000a0  6f 6d 65 2d 53 74 61 74  65 31 21 30 1f 06 03 55  |ome-State1!0...U|
-000000b0  04 0a 13 18 49 6e 74 65  72 6e 65 74 20 57 69 64  |....Internet Wid|
-000000c0  67 69 74 73 20 50 74 79  20 4c 74 64 30 1e 17 0d  |gits Pty Ltd0...|
-000000d0  31 30 30 34 32 34 30 39  30 39 33 38 5a 17 0d 31  |100424090938Z..1|
-000000e0  31 30 34 32 34 30 39 30  39 33 38 5a 30 45 31 0b  |10424090938Z0E1.|
-000000f0  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-00000100  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-00000110  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-00000120  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-00000130  4c 74 64 30 81 9f 30 0d  06 09 2a 86 48 86 f7 0d  |Ltd0..0...*.H...|
-00000140  01 01 01 05 00 03 81 8d  00 30 81 89 02 81 81 00  |.........0......|
-00000150  bb 79 d6 f5 17 b5 e5 bf  46 10 d0 dc 69 be e6 2b  |.y......F...i..+|
-00000160  07 43 5a d0 03 2d 8a 7a  43 85 b7 14 52 e7 a5 65  |.CZ..-.zC...R..e|
-00000170  4c 2c 78 b8 23 8c b5 b4  82 e5 de 1f 95 3b 7e 62  |L,x.#........;~b|
-00000180  a5 2c a5 33 d6 fe 12 5c  7a 56 fc f5 06 bf fa 58  |.,.3...\zV.....X|
-00000190  7b 26 3f b5 cd 04 d3 d0  c9 21 96 4a c7 f4 54 9f  |{&?......!.J..T.|
-000001a0  5a bf ef 42 71 00 fe 18  99 07 7f 7e 88 7d 7d f1  |Z..Bq......~.}}.|
-000001b0  04 39 c4 a2 2e db 51 c9  7c e3 c0 4c 3b 32 66 01  |.9....Q.|..L;2f.|
-000001c0  cf af b1 1d b8 71 9a 1d  db db 89 6b ae da 2d 79  |.....q.....k..-y|
-000001d0  02 03 01 00 01 a3 81 a7  30 81 a4 30 1d 06 03 55  |........0..0...U|
-000001e0  1d 0e 04 16 04 14 b1 ad  e2 85 5a cf cb 28 db 69  |..........Z..(.i|
-000001f0  ce 23 69 de d3 26 8e 18  88 39 30 75 06 03 55 1d  |.#i..&...90u..U.|
-00000200  23 04 6e 30 6c 80 14 b1  ad e2 85 5a cf cb 28 db  |#.n0l......Z..(.|
-00000210  69 ce 23 69 de d3 26 8e  18 88 39 a1 49 a4 47 30  |i.#i..&...9.I.G0|
-00000220  45 31 0b 30 09 06 03 55  04 06 13 02 41 55 31 13  |E1.0...U....AU1.|
-00000230  30 11 06 03 55 04 08 13  0a 53 6f 6d 65 2d 53 74  |0...U....Some-St|
-00000240  61 74 65 31 21 30 1f 06  03 55 04 0a 13 18 49 6e  |ate1!0...U....In|
-00000250  74 65 72 6e 65 74 20 57  69 64 67 69 74 73 20 50  |ternet Widgits P|
-00000260  74 79 20 4c 74 64 82 09  00 85 b0 bb a4 8a 7f b8  |ty Ltd..........|
-00000270  ca 30 0c 06 03 55 1d 13  04 05 30 03 01 01 ff 30  |.0...U....0....0|
-00000280  0d 06 09 2a 86 48 86 f7  0d 01 01 05 05 00 03 81  |...*.H..........|
-00000290  81 00 08 6c 45 24 c7 6b  b1 59 ab 0c 52 cc f2 b0  |...lE$.k.Y..R...|
-000002a0  14 d7 87 9d 7a 64 75 b5  5a 95 66 e4 c5 2b 8e ae  |....zdu.Z.f..+..|
-000002b0  12 66 1f eb 4f 38 b3 6e  60 d3 92 fd f7 41 08 b5  |.f..O8.n`....A..|
-000002c0  25 13 b1 18 7a 24 fb 30  1d ba ed 98 b9 17 ec e7  |%...z$.0........|
-000002d0  d7 31 59 db 95 d3 1d 78  ea 50 56 5c d5 82 5a 2d  |.1Y....x.PV\..Z-|
-000002e0  5a 5f 33 c4 b6 d8 c9 75  90 96 8c 0f 52 98 b5 cd  |Z_3....u....R...|
-000002f0  98 1f 89 20 5f f2 a0 1c  a3 1b 96 94 dd a9 fd 57  |... _..........W|
-00000300  e9 70 e8 26 6d 71 99 9b  26 6e 38 50 29 6c 90 a7  |.p.&mq..&n8P)l..|
-00000310  bd d9 16 03 01 00 04 0e  00 00 00                 |...........|
+00000000  16 03 01 00 51 02 00 00  4d 03 01 52 cc 57 58 d1  |....Q...M..R.WX.|
+00000010  c7 22 72 55 68 fb 69 12  2d 85 02 b7 66 93 40 d1  |."rUh.i.-...f.@.|
+00000020  2d 32 57 a8 f2 06 62 93  a0 39 b6 20 08 37 44 11  |-2W...b..9. .7D.|
+00000030  73 db 68 79 6d 98 30 f7  bf a2 9b a3 cb c0 03 cb  |s.hym.0.........|
+00000040  7f 79 e9 31 08 ce 93 17  25 6d c3 c4 00 05 00 00  |.y.1....%m......|
+00000050  05 ff 01 00 01 00 16 03  01 02 be 0b 00 02 ba 00  |................|
+00000060  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
+00000070  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
+00000080  09 2a 86 48 86 f7 0d 01  01 05 05 00 30 45 31 0b  |.*.H........0E1.|
+00000090  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
+000000a0  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
+000000b0  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
+000000c0  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
+000000d0  4c 74 64 30 1e 17 0d 31  30 30 34 32 34 30 39 30  |Ltd0...100424090|
+000000e0  39 33 38 5a 17 0d 31 31  30 34 32 34 30 39 30 39  |938Z..1104240909|
+000000f0  33 38 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |38Z0E1.0...U....|
+00000100  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
+00000110  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
+00000120  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
+00000130  74 73 20 50 74 79 20 4c  74 64 30 81 9f 30 0d 06  |ts Pty Ltd0..0..|
+00000140  09 2a 86 48 86 f7 0d 01  01 01 05 00 03 81 8d 00  |.*.H............|
+00000150  30 81 89 02 81 81 00 bb  79 d6 f5 17 b5 e5 bf 46  |0.......y......F|
+00000160  10 d0 dc 69 be e6 2b 07  43 5a d0 03 2d 8a 7a 43  |...i..+.CZ..-.zC|
+00000170  85 b7 14 52 e7 a5 65 4c  2c 78 b8 23 8c b5 b4 82  |...R..eL,x.#....|
+00000180  e5 de 1f 95 3b 7e 62 a5  2c a5 33 d6 fe 12 5c 7a  |....;~b.,.3...\z|
+00000190  56 fc f5 06 bf fa 58 7b  26 3f b5 cd 04 d3 d0 c9  |V.....X{&?......|
+000001a0  21 96 4a c7 f4 54 9f 5a  bf ef 42 71 00 fe 18 99  |!.J..T.Z..Bq....|
+000001b0  07 7f 7e 88 7d 7d f1 04  39 c4 a2 2e db 51 c9 7c  |..~.}}..9....Q.||
+000001c0  e3 c0 4c 3b 32 66 01 cf  af b1 1d b8 71 9a 1d db  |..L;2f......q...|
+000001d0  db 89 6b ae da 2d 79 02  03 01 00 01 a3 81 a7 30  |..k..-y........0|
+000001e0  81 a4 30 1d 06 03 55 1d  0e 04 16 04 14 b1 ad e2  |..0...U.........|
+000001f0  85 5a cf cb 28 db 69 ce  23 69 de d3 26 8e 18 88  |.Z..(.i.#i..&...|
+00000200  39 30 75 06 03 55 1d 23  04 6e 30 6c 80 14 b1 ad  |90u..U.#.n0l....|
+00000210  e2 85 5a cf cb 28 db 69  ce 23 69 de d3 26 8e 18  |..Z..(.i.#i..&..|
+00000220  88 39 a1 49 a4 47 30 45  31 0b 30 09 06 03 55 04  |.9.I.G0E1.0...U.|
+00000230  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
+00000240  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
+00000250  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
+00000260  64 67 69 74 73 20 50 74  79 20 4c 74 64 82 09 00  |dgits Pty Ltd...|
+00000270  85 b0 bb a4 8a 7f b8 ca  30 0c 06 03 55 1d 13 04  |........0...U...|
+00000280  05 30 03 01 01 ff 30 0d  06 09 2a 86 48 86 f7 0d  |.0....0...*.H...|
+00000290  01 01 05 05 00 03 81 81  00 08 6c 45 24 c7 6b b1  |..........lE$.k.|
+000002a0  59 ab 0c 52 cc f2 b0 14  d7 87 9d 7a 64 75 b5 5a  |Y..R.......zdu.Z|
+000002b0  95 66 e4 c5 2b 8e ae 12  66 1f eb 4f 38 b3 6e 60  |.f..+...f..O8.n`|
+000002c0  d3 92 fd f7 41 08 b5 25  13 b1 18 7a 24 fb 30 1d  |....A..%...z$.0.|
+000002d0  ba ed 98 b9 17 ec e7 d7  31 59 db 95 d3 1d 78 ea  |........1Y....x.|
+000002e0  50 56 5c d5 82 5a 2d 5a  5f 33 c4 b6 d8 c9 75 90  |PV\..Z-Z_3....u.|
+000002f0  96 8c 0f 52 98 b5 cd 98  1f 89 20 5f f2 a0 1c a3  |...R...... _....|
+00000300  1b 96 94 dd a9 fd 57 e9  70 e8 26 6d 71 99 9b 26  |......W.p.&mq..&|
+00000310  6e 38 50 29 6c 90 a7 bd  d9 16 03 01 00 04 0e 00  |n8P)l...........|
+00000320  00 00                                             |..|
 >>> Flow 3 (client to server)
 00000000  16 03 01 00 86 10 00 00  82 00 80 6d 51 f3 7f f9  |...........mQ...|
 00000010  3e fb 75 82 41 36 83 e8  6a ee 2a 2e 25 90 67 4c  |>.u.A6..j.*.%.gL|
 00000060  e6 bd 77 82 6f 23 b6 e0  bd a2 92 b7 3a ac e8 56  |..w.o#......:..V|
 00000070  f1 af 54 5e 46 87 e9 3b  33 e7 b8 28 b7 d6 c8 90  |..T^F..;3..(....|
 00000080  35 d4 1c 43 d1 30 6f 55  4e 0a 70 14 03 01 00 01  |5..C.0oUN.p.....|
-00000090  01 16 03 01 00 24 8f 42  2e 1a 6f 42 a2 d1 51 ae  |.....$.B..oB..Q.|
-000000a0  68 c4 3c 76 d0 df c3 41  3e 79 88 1a 43 28 bf 08  |h.<v...A>y..C(..|
-000000b0  ad 4e e2 1c f1 7f 87 3d  9d ba                    |.N.....=..|
+00000090  01 16 03 01 00 24 54 26  aa 7d 70 99 51 f1 bc d6  |.....$T&.}p.Q...|
+000000a0  e9 0b 4b c7 b2 02 8c ed  36 c9 7f b8 f7 82 29 3a  |..K.....6.....):|
+000000b0  0b 6a c0 b4 ef 38 3f e8  8a bf                    |.j...8?...|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 24 19 91 48 bb ae  |..........$..H..|
-00000010  63 9d 91 d8 2f 8b 97 00  b4 ae 79 06 88 a8 23 a0  |c.../.....y...#.|
-00000020  2d f4 dc 0f d9 6e c9 24  61 dd 3f 54 ec 9b 2f     |-....n.$a.?T../|
+00000000  14 03 01 00 01 01 16 03  01 00 24 9a 52 2f b1 3c  |..........$.R/.<|
+00000010  71 92 5c 81 68 a8 27 4c  b8 a9 4e 69 81 41 01 a2  |q.\.h.'L..Ni.A..|
+00000020  99 d4 0c dc 15 7b 52 b5  ee be a6 6f 70 88 91     |.....{R....op..|
 >>> Flow 5 (client to server)
-00000000  17 03 01 00 1a 80 15 48  e1 1a 02 3e 0f 11 0a 8b  |.......H...>....|
-00000010  ff 31 28 5f 7c 1e af fb  c7 c2 1f 8b fc 0f 12 15  |.1(_|...........|
-00000020  03 01 00 16 67 d2 c4 57  fd e1 55 9f 51 0d ff 89  |....g..W..U.Q...|
-00000030  09 17 87 2c 6c d4 96 9d  d9 86                    |...,l.....|
+00000000  17 03 01 00 1a b5 06 d1  18 a6 4b 26 21 47 be 14  |..........K&!G..|
+00000010  79 2e 63 49 84 1e 83 31  3b cb 97 14 94 5b 09 15  |y.cI...1;....[..|
+00000020  03 01 00 16 9d d6 d0 2a  65 f2 7e 31 20 e6 63 89  |.......*e.~1 .c.|
+00000030  b3 76 92 20 db b8 e6 25  54 1b                    |.v. ...%T.|
index 0c0474d470a0169c883aac1c9577eccd0c16f697..935aac14910dbe64a59d4bdfe777518da2fb7b78 100644 (file)
@@ -1,66 +1,67 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 70 01 00 00  6c 03 03 00 00 00 00 00  |....p...l.......|
+00000000  16 03 01 00 75 01 00 00  71 03 03 00 00 00 00 00  |....u...q.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
 00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
-00000040  00 2f 00 35 c0 12 00 0a  01 00 00 29 00 05 00 05  |./.5.......)....|
+00000040  00 2f 00 35 c0 12 00 0a  01 00 00 2e 00 05 00 05  |./.5............|
 00000050  01 00 00 00 00 00 0a 00  08 00 06 00 17 00 18 00  |................|
 00000060  19 00 0b 00 02 01 00 00  0d 00 0a 00 08 04 01 04  |................|
-00000070  03 02 01 02 03                                    |.....|
+00000070  03 02 01 02 03 ff 01 00  01 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 02 00 54 02 00 00  50 03 02 52 ac 77 f7 1a  |....T...P..R.w..|
-00000010  64 f7 56 af 0c d1 f7 5c  35 fb 48 6a b7 29 65 d6  |d.V....\5.Hj.)e.|
-00000020  3c b0 76 37 16 02 3c ed  25 24 d5 20 29 00 2f 99  |<.v7..<.%$. )./.|
-00000030  d5 2b 2e 59 f5 59 c6 ca  04 57 a9 5c ec ee f7 38  |.+.Y.Y...W.\...8|
-00000040  c9 0d 3b 6b e9 01 8b bd  5a e5 0d 68 c0 09 00 00  |..;k....Z..h....|
-00000050  08 00 0b 00 04 03 00 01  02 16 03 02 02 0e 0b 00  |................|
-00000060  02 0a 00 02 07 00 02 04  30 82 02 00 30 82 01 62  |........0...0..b|
-00000070  02 09 00 b8 bf 2d 47 a0  d2 eb f4 30 09 06 07 2a  |.....-G....0...*|
-00000080  86 48 ce 3d 04 01 30 45  31 0b 30 09 06 03 55 04  |.H.=..0E1.0...U.|
-00000090  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
-000000a0  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
-000000b0  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
-000000c0  64 67 69 74 73 20 50 74  79 20 4c 74 64 30 1e 17  |dgits Pty Ltd0..|
-000000d0  0d 31 32 31 31 32 32 31  35 30 36 33 32 5a 17 0d  |.121122150632Z..|
-000000e0  32 32 31 31 32 30 31 35  30 36 33 32 5a 30 45 31  |221120150632Z0E1|
-000000f0  0b 30 09 06 03 55 04 06  13 02 41 55 31 13 30 11  |.0...U....AU1.0.|
-00000100  06 03 55 04 08 13 0a 53  6f 6d 65 2d 53 74 61 74  |..U....Some-Stat|
-00000110  65 31 21 30 1f 06 03 55  04 0a 13 18 49 6e 74 65  |e1!0...U....Inte|
-00000120  72 6e 65 74 20 57 69 64  67 69 74 73 20 50 74 79  |rnet Widgits Pty|
-00000130  20 4c 74 64 30 81 9b 30  10 06 07 2a 86 48 ce 3d  | Ltd0..0...*.H.=|
-00000140  02 01 06 05 2b 81 04 00  23 03 81 86 00 04 00 c4  |....+...#.......|
-00000150  a1 ed be 98 f9 0b 48 73  36 7e c3 16 56 11 22 f2  |......Hs6~..V.".|
-00000160  3d 53 c3 3b 4d 21 3d cd  6b 75 e6 f6 b0 dc 9a df  |=S.;M!=.ku......|
-00000170  26 c1 bc b2 87 f0 72 32  7c b3 64 2f 1c 90 bc ea  |&.....r2|.d/....|
-00000180  68 23 10 7e fe e3 25 c0  48 3a 69 e0 28 6d d3 37  |h#.~..%.H:i.(m.7|
-00000190  00 ef 04 62 dd 0d a0 9c  70 62 83 d8 81 d3 64 31  |...b....pb....d1|
-000001a0  aa 9e 97 31 bd 96 b0 68  c0 9b 23 de 76 64 3f 1a  |...1...h..#.vd?.|
-000001b0  5c 7f e9 12 0e 58 58 b6  5f 70 dd 9b d8 ea d5 d7  |\....XX._p......|
-000001c0  f5 d5 cc b9 b6 9f 30 66  5b 66 9a 20 e2 27 e5 bf  |......0f[f. .'..|
-000001d0  fe 3b 30 09 06 07 2a 86  48 ce 3d 04 01 03 81 8c  |.;0...*.H.=.....|
-000001e0  00 30 81 88 02 42 01 88  a2 4f eb e2 45 c5 48 7d  |.0...B...O..E.H}|
-000001f0  1b ac f5 ed 98 9d ae 47  70 c0 5e 1b b6 2f bd f1  |.......Gp.^../..|
-00000200  b6 4d b7 61 40 d3 11 a2  ce ee 0b 7e 92 7e ff 76  |.M.a@......~.~.v|
-00000210  9d c3 3b 7e a5 3f ce fa  10 e2 59 ec 47 2d 7c ac  |..;~.?....Y.G-|.|
-00000220  da 4e 97 0e 15 a0 6f d0  02 42 01 4d fc be 67 13  |.N....o..B.M..g.|
-00000230  9c 2d 05 0e bd 3f a3 8c  25 c1 33 13 83 0d 94 06  |.-...?..%.3.....|
-00000240  bb d4 37 7a f6 ec 7a c9  86 2e dd d7 11 69 7f 85  |..7z..z......i..|
-00000250  7c 56 de fb 31 78 2b e4  c7 78 0d ae cb be 9e 4e  ||V..1x+..x.....N|
-00000260  36 24 31 7b 6a 0f 39 95  12 07 8f 2a 16 03 02 00  |6$1{j.9....*....|
-00000270  d5 0c 00 00 d1 03 00 17  41 04 6f c1 70 ca c9 46  |........A.o.p..F|
-00000280  2c 5e 69 58 33 1f 6f d6  aa 87 b7 bb d5 66 42 e9  |,^iX3.o......fB.|
-00000290  34 2e 37 d1 0b 04 11 14  ce 57 f4 00 6c ec 47 31  |4.7......W..l.G1|
-000002a0  e4 5a 38 25 50 51 f7 3a  22 b0 9f 7c 4d 81 f9 9a  |.Z8%PQ.:"..|M...|
-000002b0  b3 c9 fd 4e f4 20 62 0b  73 ce 00 8a 30 81 87 02  |...N. b.s...0...|
-000002c0  41 4d ee 15 33 7a 88 5f  20 15 e8 76 1f c9 0f 16  |AM..3z._ ..v....|
-000002d0  64 8c e1 d6 97 45 6a 56  1f 75 1b 41 6a ca de 86  |d....EjV.u.Aj...|
-000002e0  3e de 50 49 e7 21 ac f9  09 14 ca 96 c7 e6 23 ba  |>.PI.!........#.|
-000002f0  32 8d d4 22 b7 02 0b 40  77 cc 3f 19 50 9e a1 72  |2.."...@w.?.P..r|
-00000300  b8 8d 02 42 01 2c d4 47  4c 0b 20 3a 14 dd 11 ed  |...B.,.GL. :....|
-00000310  90 ed 83 ff 94 62 ec 88  d9 11 fd 2d 0c b0 01 b7  |.....b.....-....|
-00000320  0c 47 0b a2 1f 7f 73 5a  77 7d 76 27 8b 8c ca 29  |.G....sZw}v'...)|
-00000330  b5 b8 fb 22 79 25 4b dd  0a a1 39 c9 81 c7 2b 24  |..."y%K...9...+$|
-00000340  c9 5c b5 31 17 95 16 03  02 00 04 0e 00 00 00     |.\.1...........|
+00000000  16 03 02 00 59 02 00 00  55 03 02 52 cc 57 58 b6  |....Y...U..R.WX.|
+00000010  e0 47 f9 28 99 af 27 4c  21 20 d6 b1 ae 4e d4 62  |.G.(..'L! ...N.b|
+00000020  8a 24 f4 62 47 77 a5 78  4b d0 09 20 5b 17 6b 88  |.$.bGw.xK.. [.k.|
+00000030  8a ab 8c 0b 63 d9 c3 06  6d 13 e3 27 22 38 ee 69  |....c...m..'"8.i|
+00000040  88 7d e1 18 f8 ef 93 62  f4 06 1f ab c0 09 00 00  |.}.....b........|
+00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
+00000060  02 02 0e 0b 00 02 0a 00  02 07 00 02 04 30 82 02  |.............0..|
+00000070  00 30 82 01 62 02 09 00  b8 bf 2d 47 a0 d2 eb f4  |.0..b.....-G....|
+00000080  30 09 06 07 2a 86 48 ce  3d 04 01 30 45 31 0b 30  |0...*.H.=..0E1.0|
+00000090  09 06 03 55 04 06 13 02  41 55 31 13 30 11 06 03  |...U....AU1.0...|
+000000a0  55 04 08 13 0a 53 6f 6d  65 2d 53 74 61 74 65 31  |U....Some-State1|
+000000b0  21 30 1f 06 03 55 04 0a  13 18 49 6e 74 65 72 6e  |!0...U....Intern|
+000000c0  65 74 20 57 69 64 67 69  74 73 20 50 74 79 20 4c  |et Widgits Pty L|
+000000d0  74 64 30 1e 17 0d 31 32  31 31 32 32 31 35 30 36  |td0...1211221506|
+000000e0  33 32 5a 17 0d 32 32 31  31 32 30 31 35 30 36 33  |32Z..22112015063|
+000000f0  32 5a 30 45 31 0b 30 09  06 03 55 04 06 13 02 41  |2Z0E1.0...U....A|
+00000100  55 31 13 30 11 06 03 55  04 08 13 0a 53 6f 6d 65  |U1.0...U....Some|
+00000110  2d 53 74 61 74 65 31 21  30 1f 06 03 55 04 0a 13  |-State1!0...U...|
+00000120  18 49 6e 74 65 72 6e 65  74 20 57 69 64 67 69 74  |.Internet Widgit|
+00000130  73 20 50 74 79 20 4c 74  64 30 81 9b 30 10 06 07  |s Pty Ltd0..0...|
+00000140  2a 86 48 ce 3d 02 01 06  05 2b 81 04 00 23 03 81  |*.H.=....+...#..|
+00000150  86 00 04 00 c4 a1 ed be  98 f9 0b 48 73 36 7e c3  |...........Hs6~.|
+00000160  16 56 11 22 f2 3d 53 c3  3b 4d 21 3d cd 6b 75 e6  |.V.".=S.;M!=.ku.|
+00000170  f6 b0 dc 9a df 26 c1 bc  b2 87 f0 72 32 7c b3 64  |.....&.....r2|.d|
+00000180  2f 1c 90 bc ea 68 23 10  7e fe e3 25 c0 48 3a 69  |/....h#.~..%.H:i|
+00000190  e0 28 6d d3 37 00 ef 04  62 dd 0d a0 9c 70 62 83  |.(m.7...b....pb.|
+000001a0  d8 81 d3 64 31 aa 9e 97  31 bd 96 b0 68 c0 9b 23  |...d1...1...h..#|
+000001b0  de 76 64 3f 1a 5c 7f e9  12 0e 58 58 b6 5f 70 dd  |.vd?.\....XX._p.|
+000001c0  9b d8 ea d5 d7 f5 d5 cc  b9 b6 9f 30 66 5b 66 9a  |...........0f[f.|
+000001d0  20 e2 27 e5 bf fe 3b 30  09 06 07 2a 86 48 ce 3d  | .'...;0...*.H.=|
+000001e0  04 01 03 81 8c 00 30 81  88 02 42 01 88 a2 4f eb  |......0...B...O.|
+000001f0  e2 45 c5 48 7d 1b ac f5  ed 98 9d ae 47 70 c0 5e  |.E.H}.......Gp.^|
+00000200  1b b6 2f bd f1 b6 4d b7  61 40 d3 11 a2 ce ee 0b  |../...M.a@......|
+00000210  7e 92 7e ff 76 9d c3 3b  7e a5 3f ce fa 10 e2 59  |~.~.v..;~.?....Y|
+00000220  ec 47 2d 7c ac da 4e 97  0e 15 a0 6f d0 02 42 01  |.G-|..N....o..B.|
+00000230  4d fc be 67 13 9c 2d 05  0e bd 3f a3 8c 25 c1 33  |M..g..-...?..%.3|
+00000240  13 83 0d 94 06 bb d4 37  7a f6 ec 7a c9 86 2e dd  |.......7z..z....|
+00000250  d7 11 69 7f 85 7c 56 de  fb 31 78 2b e4 c7 78 0d  |..i..|V..1x+..x.|
+00000260  ae cb be 9e 4e 36 24 31  7b 6a 0f 39 95 12 07 8f  |....N6$1{j.9....|
+00000270  2a 16 03 02 00 d6 0c 00  00 d2 03 00 17 41 04 79  |*............A.y|
+00000280  48 bb 4c 30 4f 5c fe 5e  37 65 dc 65 90 d4 4a 7f  |H.L0O\.^7e.e..J.|
+00000290  8c fc 45 b6 4f fb 11 2b  7c 20 cf 94 83 79 f6 cc  |..E.O..+| ...y..|
+000002a0  c6 d6 44 0c ad ae 5c fc  fd 87 0f b9 51 03 dc 38  |..D...\.....Q..8|
+000002b0  d8 44 a8 75 18 7e d1 c6  3e 9e 0a 45 85 92 4b 00  |.D.u.~..>..E..K.|
+000002c0  8b 30 81 88 02 42 01 dd  a7 0b d6 69 3c b5 fc 06  |.0...B.....i<...|
+000002d0  8b c3 37 1d 12 be 0d 80  4a e4 d5 4e df c0 5c 7d  |..7.....J..N..\}|
+000002e0  ca 61 f2 3c 87 83 e0 de  22 0f 25 78 f0 21 ec ca  |.a.<....".%x.!..|
+000002f0  8e 62 28 24 10 3e d9 7d  30 d7 f1 bd dc c6 98 a9  |.b($.>.}0.......|
+00000300  c4 3f 85 8f 47 8c 8e b7  02 42 01 3c 61 1e ee e9  |.?..G....B.<a...|
+00000310  44 2d ae 57 d1 2f 04 59  16 f0 80 03 3e a1 fe 1f  |D-.W./.Y....>...|
+00000320  5f 54 b2 e1 b2 c0 07 3c  ad d9 9f 95 8d 79 7d 9b  |_T.....<.....y}.|
+00000330  8e 68 cc b9 7f 08 b3 c9  24 1f a9 37 18 60 52 54  |.h......$..7.`RT|
+00000340  5e 55 9c 36 1c 06 29 6b  7b 95 3e 73 16 03 02 00  |^U.6..)k{.>s....|
+00000350  04 0e 00 00 00                                    |.....|
 >>> Flow 3 (client to server)
 00000000  16 03 02 00 46 10 00 00  42 41 04 1e 18 37 ef 0d  |....F...BA...7..|
 00000010  19 51 88 35 75 71 b5 e5  54 5b 12 2e 8f 09 67 fd  |.Q.5uq..T[....g.|
 00000030  f1 07 9f 6c 4b 5b 83 56  e2 32 42 e9 58 b6 d7 49  |...lK[.V.2B.X..I|
 00000040  a6 b5 68 1a 41 03 56 6b  dc 5a 89 14 03 02 00 01  |..h.A.Vk.Z......|
 00000050  01 16 03 02 00 40 00 00  00 00 00 00 00 00 00 00  |.....@..........|
-00000060  00 00 00 00 00 00 8d 08  b9 eb b8 28 6a 9b b0 fb  |...........(j...|
-00000070  c3 79 06 07 ed b2 e5 56  5e 80 5d 0a 12 3b 50 b7  |.y.....V^.]..;P.|
-00000080  eb a0 6c eb aa d2 16 02  86 a8 76 13 23 65 ce ff  |..l.......v.#e..|
-00000090  57 52 7c 30 f2 a0                                 |WR|0..|
+00000060  00 00 00 00 00 00 42 9f  9d 29 fc 0e e3 9d 6d 89  |......B..)....m.|
+00000070  38 c3 6f d8 0f 0f 41 69  24 b8 44 a8 81 28 56 80  |8.o...Ai$.D..(V.|
+00000080  c2 a2 cd b8 27 84 4d f1  f0 5c dc df 94 a7 a4 05  |....'.M..\......|
+00000090  84 b9 f6 5c b4 50                                 |...\.P|
 >>> Flow 4 (server to client)
-00000000  14 03 02 00 01 01 16 03  02 00 40 8f b3 15 b3 54  |..........@....T|
-00000010  3b e9 7e c5 ec b7 df 4b  ae e4 d7 0f e5 4a d5 8e  |;.~....K.....J..|
-00000020  1c 94 f8 19 d9 a7 f3 5d  8b 18 6b 1f e8 a2 94 e4  |.......]..k.....|
-00000030  f9 31 ed ab 38 3b 25 22  12 61 d6 c9 c7 76 6d 82  |.1..8;%".a...vm.|
-00000040  ac 16 02 89 73 4f 02 98  e2 95 0f                 |....sO.....|
+00000000  14 03 02 00 01 01 16 03  02 00 40 5f 24 a7 68 9c  |..........@_$.h.|
+00000010  cc 93 4c fc a1 25 3d 71  43 88 d9 17 9b c9 99 6b  |..L..%=qC......k|
+00000020  01 00 24 a8 ca b3 52 3e  cf 2f f5 3e 80 16 c9 cb  |..$...R>./.>....|
+00000030  52 20 c3 f5 e0 8f a2 d9  f9 3d 86 c5 44 f6 52 31  |R .......=..D.R1|
+00000040  82 3a f9 fb d1 f6 43 5b  b8 28 bc                 |.:....C[.(.|
 >>> Flow 5 (client to server)
 00000000  17 03 02 00 30 00 00 00  00 00 00 00 00 00 00 00  |....0...........|
-00000010  00 00 00 00 00 f3 c1 b3  fb 58 f0 ce 01 e4 23 4f  |.........X....#O|
-00000020  de d9 81 9b d8 80 66 7a  fb 7b 45 1b a8 ac a0 f5  |......fz.{E.....|
-00000030  0b b4 92 74 e9 15 03 02  00 30 00 00 00 00 00 00  |...t.....0......|
-00000040  00 00 00 00 00 00 00 00  00 00 0b 89 72 90 d6 30  |............r..0|
-00000050  1c fb 6d ab 68 79 48 6d  2a 32 1a 4f b7 45 0b 08  |..m.hyHm*2.O.E..|
-00000060  11 dd 52 66 76 65 fc 02  e1 7e                    |..Rfve...~|
+00000010  00 00 00 00 00 18 60 dd  b8 15 76 04 ae 8c e9 09  |......`...v.....|
+00000020  84 8c c2 04 38 b2 45 3d  cb ea 9b cf 11 1a 38 67  |....8.E=......8g|
+00000030  cd ff 89 4c 8c 15 03 02  00 30 00 00 00 00 00 00  |...L.....0......|
+00000040  00 00 00 00 00 00 00 00  00 00 f3 b4 a0 68 1b 3b  |.............h.;|
+00000050  5c c7 e7 70 32 5f 19 4f  a4 bf 0a 57 bc a0 7d be  |\..p2_.O...W..}.|
+00000060  91 46 5a 8e 02 25 67 20  d0 c2                    |.FZ..%g ..|
index 9a6de9ffccf47787d80c33ee4e946c22a464677d..9bfaa75deb12541b105e9b647aa0d38b6a07312c 100644 (file)
@@ -1,77 +1,77 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 70 01 00 00  6c 03 03 00 00 00 00 00  |....p...l.......|
+00000000  16 03 01 00 75 01 00 00  71 03 03 00 00 00 00 00  |....u...q.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
 00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
-00000040  00 2f 00 35 c0 12 00 0a  01 00 00 29 00 05 00 05  |./.5.......)....|
+00000040  00 2f 00 35 c0 12 00 0a  01 00 00 2e 00 05 00 05  |./.5............|
 00000050  01 00 00 00 00 00 0a 00  08 00 06 00 17 00 18 00  |................|
 00000060  19 00 0b 00 02 01 00 00  0d 00 0a 00 08 04 01 04  |................|
-00000070  03 02 01 02 03                                    |.....|
+00000070  03 02 01 02 03 ff 01 00  01 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 02 00 54 02 00 00  50 03 02 52 ac 77 f7 e5  |....T...P..R.w..|
-00000010  29 8d 77 7e b2 af b8 50  dd 1f d4 2d 86 c1 bd c6  |).w~...P...-....|
-00000020  13 77 41 6c a1 2a 68 20  80 ce 0f 20 b4 52 61 8d  |.wAl.*h ... .Ra.|
-00000030  44 36 59 2b fa 58 be 5f  fa 69 f9 cd cf 4b 6f 9e  |D6Y+.X._.i...Ko.|
-00000040  dd 2f bf 58 e1 5f 11 5f  fa 24 75 38 c0 13 00 00  |./.X._._.$u8....|
-00000050  08 00 0b 00 04 03 00 01  02 16 03 02 02 be 0b 00  |................|
-00000060  02 ba 00 02 b7 00 02 b4  30 82 02 b0 30 82 02 19  |........0...0...|
-00000070  a0 03 02 01 02 02 09 00  85 b0 bb a4 8a 7f b8 ca  |................|
-00000080  30 0d 06 09 2a 86 48 86  f7 0d 01 01 05 05 00 30  |0...*.H........0|
-00000090  45 31 0b 30 09 06 03 55  04 06 13 02 41 55 31 13  |E1.0...U....AU1.|
-000000a0  30 11 06 03 55 04 08 13  0a 53 6f 6d 65 2d 53 74  |0...U....Some-St|
-000000b0  61 74 65 31 21 30 1f 06  03 55 04 0a 13 18 49 6e  |ate1!0...U....In|
-000000c0  74 65 72 6e 65 74 20 57  69 64 67 69 74 73 20 50  |ternet Widgits P|
-000000d0  74 79 20 4c 74 64 30 1e  17 0d 31 30 30 34 32 34  |ty Ltd0...100424|
-000000e0  30 39 30 39 33 38 5a 17  0d 31 31 30 34 32 34 30  |090938Z..1104240|
-000000f0  39 30 39 33 38 5a 30 45  31 0b 30 09 06 03 55 04  |90938Z0E1.0...U.|
-00000100  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
-00000110  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
-00000120  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
-00000130  64 67 69 74 73 20 50 74  79 20 4c 74 64 30 81 9f  |dgits Pty Ltd0..|
-00000140  30 0d 06 09 2a 86 48 86  f7 0d 01 01 01 05 00 03  |0...*.H.........|
-00000150  81 8d 00 30 81 89 02 81  81 00 bb 79 d6 f5 17 b5  |...0.......y....|
-00000160  e5 bf 46 10 d0 dc 69 be  e6 2b 07 43 5a d0 03 2d  |..F...i..+.CZ..-|
-00000170  8a 7a 43 85 b7 14 52 e7  a5 65 4c 2c 78 b8 23 8c  |.zC...R..eL,x.#.|
-00000180  b5 b4 82 e5 de 1f 95 3b  7e 62 a5 2c a5 33 d6 fe  |.......;~b.,.3..|
-00000190  12 5c 7a 56 fc f5 06 bf  fa 58 7b 26 3f b5 cd 04  |.\zV.....X{&?...|
-000001a0  d3 d0 c9 21 96 4a c7 f4  54 9f 5a bf ef 42 71 00  |...!.J..T.Z..Bq.|
-000001b0  fe 18 99 07 7f 7e 88 7d  7d f1 04 39 c4 a2 2e db  |.....~.}}..9....|
-000001c0  51 c9 7c e3 c0 4c 3b 32  66 01 cf af b1 1d b8 71  |Q.|..L;2f......q|
-000001d0  9a 1d db db 89 6b ae da  2d 79 02 03 01 00 01 a3  |.....k..-y......|
-000001e0  81 a7 30 81 a4 30 1d 06  03 55 1d 0e 04 16 04 14  |..0..0...U......|
-000001f0  b1 ad e2 85 5a cf cb 28  db 69 ce 23 69 de d3 26  |....Z..(.i.#i..&|
-00000200  8e 18 88 39 30 75 06 03  55 1d 23 04 6e 30 6c 80  |...90u..U.#.n0l.|
-00000210  14 b1 ad e2 85 5a cf cb  28 db 69 ce 23 69 de d3  |.....Z..(.i.#i..|
-00000220  26 8e 18 88 39 a1 49 a4  47 30 45 31 0b 30 09 06  |&...9.I.G0E1.0..|
-00000230  03 55 04 06 13 02 41 55  31 13 30 11 06 03 55 04  |.U....AU1.0...U.|
-00000240  08 13 0a 53 6f 6d 65 2d  53 74 61 74 65 31 21 30  |...Some-State1!0|
-00000250  1f 06 03 55 04 0a 13 18  49 6e 74 65 72 6e 65 74  |...U....Internet|
-00000260  20 57 69 64 67 69 74 73  20 50 74 79 20 4c 74 64  | Widgits Pty Ltd|
-00000270  82 09 00 85 b0 bb a4 8a  7f b8 ca 30 0c 06 03 55  |...........0...U|
-00000280  1d 13 04 05 30 03 01 01  ff 30 0d 06 09 2a 86 48  |....0....0...*.H|
-00000290  86 f7 0d 01 01 05 05 00  03 81 81 00 08 6c 45 24  |.............lE$|
-000002a0  c7 6b b1 59 ab 0c 52 cc  f2 b0 14 d7 87 9d 7a 64  |.k.Y..R.......zd|
-000002b0  75 b5 5a 95 66 e4 c5 2b  8e ae 12 66 1f eb 4f 38  |u.Z.f..+...f..O8|
-000002c0  b3 6e 60 d3 92 fd f7 41  08 b5 25 13 b1 18 7a 24  |.n`....A..%...z$|
-000002d0  fb 30 1d ba ed 98 b9 17  ec e7 d7 31 59 db 95 d3  |.0.........1Y...|
-000002e0  1d 78 ea 50 56 5c d5 82  5a 2d 5a 5f 33 c4 b6 d8  |.x.PV\..Z-Z_3...|
-000002f0  c9 75 90 96 8c 0f 52 98  b5 cd 98 1f 89 20 5f f2  |.u....R...... _.|
-00000300  a0 1c a3 1b 96 94 dd a9  fd 57 e9 70 e8 26 6d 71  |.........W.p.&mq|
-00000310  99 9b 26 6e 38 50 29 6c  90 a7 bd d9 16 03 02 00  |..&n8P)l........|
-00000320  cb 0c 00 00 c7 03 00 17  41 04 f2 1f af 58 08 d7  |........A....X..|
-00000330  4e ac d4 ee 2b 56 df 11  96 c8 01 d8 c8 0c 97 95  |N...+V..........|
-00000340  3c 34 1c 24 8b e9 a0 92  1a 74 71 9c ee 56 ec 0f  |<4.$.....tq..V..|
-00000350  b5 c6 3b 3c f1 a2 4d 52  11 f1 e3 3b 43 f8 fc 43  |..;<..MR...;C..C|
-00000360  83 67 7d 62 c7 56 0c 38  01 5c 00 80 83 5f df 3b  |.g}b.V.8.\..._.;|
-00000370  fe 4f 90 30 c6 c3 c7 16  df 7b 58 dc 5a c1 68 e6  |.O.0.....{X.Z.h.|
-00000380  18 7f 5e 4c 0f ae d2 f0  81 2c 48 a9 c4 7b 05 f6  |..^L.....,H..{..|
-00000390  e0 9e 17 95 dd fe a3 53  32 57 12 f4 96 55 94 ff  |.......S2W...U..|
-000003a0  0a ee cf 95 85 43 7c 75  fc f3 13 5e e0 cf c2 ff  |.....C|u...^....|
-000003b0  56 c6 2b 60 09 b3 32 b2  1a 93 49 2e f0 b6 5c 2f  |V.+`..2...I...\/|
-000003c0  5a 45 c9 da 8c ee 26 72  ca 9e b4 63 13 a8 7d 60  |ZE....&r...c..}`|
-000003d0  54 dd 17 70 40 60 15 e1  85 d5 64 02 83 e2 b3 e9  |T..p@`....d.....|
-000003e0  b3 de 84 6e 9d 62 18 48  99 66 cd 63 16 03 02 00  |...n.b.H.f.c....|
-000003f0  04 0e 00 00 00                                    |.....|
+00000000  16 03 02 00 59 02 00 00  55 03 02 52 cc 57 58 39  |....Y...U..R.WX9|
+00000010  f8 48 dc e0 ba ad e3 f6  6e bf 6b 9e e0 34 53 4f  |.H......n.k..4SO|
+00000020  cd 16 7a 31 ac 23 de 31  3c 4b 0d 20 41 92 79 b5  |..z1.#.1<K. A.y.|
+00000030  e0 f6 1c 25 da db 35 3b  58 61 04 52 7f ac da 64  |...%..5;Xa.R...d|
+00000040  0d 31 f0 52 55 5d ec 37  94 21 aa 6f c0 13 00 00  |.1.RU].7.!.o....|
+00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
+00000060  02 02 be 0b 00 02 ba 00  02 b7 00 02 b4 30 82 02  |.............0..|
+00000070  b0 30 82 02 19 a0 03 02  01 02 02 09 00 85 b0 bb  |.0..............|
+00000080  a4 8a 7f b8 ca 30 0d 06  09 2a 86 48 86 f7 0d 01  |.....0...*.H....|
+00000090  01 05 05 00 30 45 31 0b  30 09 06 03 55 04 06 13  |....0E1.0...U...|
+000000a0  02 41 55 31 13 30 11 06  03 55 04 08 13 0a 53 6f  |.AU1.0...U....So|
+000000b0  6d 65 2d 53 74 61 74 65  31 21 30 1f 06 03 55 04  |me-State1!0...U.|
+000000c0  0a 13 18 49 6e 74 65 72  6e 65 74 20 57 69 64 67  |...Internet Widg|
+000000d0  69 74 73 20 50 74 79 20  4c 74 64 30 1e 17 0d 31  |its Pty Ltd0...1|
+000000e0  30 30 34 32 34 30 39 30  39 33 38 5a 17 0d 31 31  |00424090938Z..11|
+000000f0  30 34 32 34 30 39 30 39  33 38 5a 30 45 31 0b 30  |0424090938Z0E1.0|
+00000100  09 06 03 55 04 06 13 02  41 55 31 13 30 11 06 03  |...U....AU1.0...|
+00000110  55 04 08 13 0a 53 6f 6d  65 2d 53 74 61 74 65 31  |U....Some-State1|
+00000120  21 30 1f 06 03 55 04 0a  13 18 49 6e 74 65 72 6e  |!0...U....Intern|
+00000130  65 74 20 57 69 64 67 69  74 73 20 50 74 79 20 4c  |et Widgits Pty L|
+00000140  74 64 30 81 9f 30 0d 06  09 2a 86 48 86 f7 0d 01  |td0..0...*.H....|
+00000150  01 01 05 00 03 81 8d 00  30 81 89 02 81 81 00 bb  |........0.......|
+00000160  79 d6 f5 17 b5 e5 bf 46  10 d0 dc 69 be e6 2b 07  |y......F...i..+.|
+00000170  43 5a d0 03 2d 8a 7a 43  85 b7 14 52 e7 a5 65 4c  |CZ..-.zC...R..eL|
+00000180  2c 78 b8 23 8c b5 b4 82  e5 de 1f 95 3b 7e 62 a5  |,x.#........;~b.|
+00000190  2c a5 33 d6 fe 12 5c 7a  56 fc f5 06 bf fa 58 7b  |,.3...\zV.....X{|
+000001a0  26 3f b5 cd 04 d3 d0 c9  21 96 4a c7 f4 54 9f 5a  |&?......!.J..T.Z|
+000001b0  bf ef 42 71 00 fe 18 99  07 7f 7e 88 7d 7d f1 04  |..Bq......~.}}..|
+000001c0  39 c4 a2 2e db 51 c9 7c  e3 c0 4c 3b 32 66 01 cf  |9....Q.|..L;2f..|
+000001d0  af b1 1d b8 71 9a 1d db  db 89 6b ae da 2d 79 02  |....q.....k..-y.|
+000001e0  03 01 00 01 a3 81 a7 30  81 a4 30 1d 06 03 55 1d  |.......0..0...U.|
+000001f0  0e 04 16 04 14 b1 ad e2  85 5a cf cb 28 db 69 ce  |.........Z..(.i.|
+00000200  23 69 de d3 26 8e 18 88  39 30 75 06 03 55 1d 23  |#i..&...90u..U.#|
+00000210  04 6e 30 6c 80 14 b1 ad  e2 85 5a cf cb 28 db 69  |.n0l......Z..(.i|
+00000220  ce 23 69 de d3 26 8e 18  88 39 a1 49 a4 47 30 45  |.#i..&...9.I.G0E|
+00000230  31 0b 30 09 06 03 55 04  06 13 02 41 55 31 13 30  |1.0...U....AU1.0|
+00000240  11 06 03 55 04 08 13 0a  53 6f 6d 65 2d 53 74 61  |...U....Some-Sta|
+00000250  74 65 31 21 30 1f 06 03  55 04 0a 13 18 49 6e 74  |te1!0...U....Int|
+00000260  65 72 6e 65 74 20 57 69  64 67 69 74 73 20 50 74  |ernet Widgits Pt|
+00000270  79 20 4c 74 64 82 09 00  85 b0 bb a4 8a 7f b8 ca  |y Ltd...........|
+00000280  30 0c 06 03 55 1d 13 04  05 30 03 01 01 ff 30 0d  |0...U....0....0.|
+00000290  06 09 2a 86 48 86 f7 0d  01 01 05 05 00 03 81 81  |..*.H...........|
+000002a0  00 08 6c 45 24 c7 6b b1  59 ab 0c 52 cc f2 b0 14  |..lE$.k.Y..R....|
+000002b0  d7 87 9d 7a 64 75 b5 5a  95 66 e4 c5 2b 8e ae 12  |...zdu.Z.f..+...|
+000002c0  66 1f eb 4f 38 b3 6e 60  d3 92 fd f7 41 08 b5 25  |f..O8.n`....A..%|
+000002d0  13 b1 18 7a 24 fb 30 1d  ba ed 98 b9 17 ec e7 d7  |...z$.0.........|
+000002e0  31 59 db 95 d3 1d 78 ea  50 56 5c d5 82 5a 2d 5a  |1Y....x.PV\..Z-Z|
+000002f0  5f 33 c4 b6 d8 c9 75 90  96 8c 0f 52 98 b5 cd 98  |_3....u....R....|
+00000300  1f 89 20 5f f2 a0 1c a3  1b 96 94 dd a9 fd 57 e9  |.. _..........W.|
+00000310  70 e8 26 6d 71 99 9b 26  6e 38 50 29 6c 90 a7 bd  |p.&mq..&n8P)l...|
+00000320  d9 16 03 02 00 cb 0c 00  00 c7 03 00 17 41 04 0a  |.............A..|
+00000330  be f8 00 24 e0 50 bf 90  12 25 b9 26 3b 7f 4a a2  |...$.P...%.&;.J.|
+00000340  b3 4b b1 76 db 53 0d 83  9b 35 57 2f 64 ad 03 d1  |.K.v.S...5W/d...|
+00000350  f9 1b ef cf 48 8a a8 a9  4c df d3 7b 7d e8 a0 68  |....H...L..{}..h|
+00000360  2b 20 b4 4f 1c e3 11 1d  bf a9 bd 58 e4 4a 3e 00  |+ .O.......X.J>.|
+00000370  80 2a 64 fb 5f 8f f5 bb  6d 48 2c 7d a6 c0 f6 b2  |.*d._...mH,}....|
+00000380  3d 2b 75 83 07 fd b8 9d  50 a1 ec 1c 09 85 69 4f  |=+u.....P.....iO|
+00000390  a3 39 8e 2f b4 94 76 b1  8d 03 3f 76 01 7e 22 90  |.9./..v...?v.~".|
+000003a0  08 58 40 0d d7 65 c1 49  d5 7e 0d 28 62 ec b6 58  |.X@..e.I.~.(b..X|
+000003b0  6f ff 83 21 65 e7 8b f5  51 32 5f 39 e8 9e 85 d4  |o..!e...Q2_9....|
+000003c0  65 1c a8 a8 70 82 5e db  d7 c6 4a 2d 2e ef c3 b3  |e...p.^...J-....|
+000003d0  73 ca 13 5b 99 19 e3 4d  cb 4a 9f 42 3c b7 79 fb  |s..[...M.J.B<.y.|
+000003e0  70 33 f7 a7 59 cb 76 a7  7c f3 8a 9a 5d fd 12 74  |p3..Y.v.|...]..t|
+000003f0  5a 16 03 02 00 04 0e 00  00 00                    |Z.........|
 >>> Flow 3 (client to server)
 00000000  16 03 02 00 46 10 00 00  42 41 04 1e 18 37 ef 0d  |....F...BA...7..|
 00000010  19 51 88 35 75 71 b5 e5  54 5b 12 2e 8f 09 67 fd  |.Q.5uq..T[....g.|
 00000030  f1 07 9f 6c 4b 5b 83 56  e2 32 42 e9 58 b6 d7 49  |...lK[.V.2B.X..I|
 00000040  a6 b5 68 1a 41 03 56 6b  dc 5a 89 14 03 02 00 01  |..h.A.Vk.Z......|
 00000050  01 16 03 02 00 40 00 00  00 00 00 00 00 00 00 00  |.....@..........|
-00000060  00 00 00 00 00 00 a4 c5  6a e0 d6 3d 47 a8 17 8f  |........j..=G...|
-00000070  5e 21 57 ac d5 0a 7c f7  fb df 33 e2 68 c4 46 82  |^!W...|...3.h.F.|
-00000080  b4 48 d2 d3 f5 79 14 0a  db f9 00 f2 59 ff c3 f4  |.H...y......Y...|
-00000090  11 a2 e9 90 49 d6                                 |....I.|
+00000060  00 00 00 00 00 00 9a 7d  f8 d5 af e5 5d 16 a2 39  |.......}....]..9|
+00000070  94 a5 de f6 ae 71 ba b7  b5 6e 9e a7 05 37 ed ff  |.....q...n...7..|
+00000080  b4 c3 d9 4e d5 d5 3c 84  7e 3f a4 68 23 3b 52 ab  |...N..<.~?.h#;R.|
+00000090  d7 30 3b 63 ed b1                                 |.0;c..|
 >>> Flow 4 (server to client)
-00000000  14 03 02 00 01 01 16 03  02 00 40 84 bb 5f a3 9a  |..........@.._..|
-00000010  07 af bf a2 3a 48 23 7c  a9 45 0c 07 ba ea bf 62  |....:H#|.E.....b|
-00000020  c0 4f f3 2f f1 70 0e b1  ee ec 90 4e ea b4 0f 50  |.O./.p.....N...P|
-00000030  47 e2 29 f3 ef ee 01 c7  eb db a4 56 d6 e8 d9 77  |G.)........V...w|
-00000040  9a 64 42 50 40 42 d9 4b  ef 04 48                 |.dBP@B.K..H|
+00000000  14 03 02 00 01 01 16 03  02 00 40 df 38 36 f9 ee  |..........@.86..|
+00000010  03 f3 92 e1 3b 81 21 60  3a 46 3a 2c fc 2f 6a 01  |....;.!`:F:,./j.|
+00000020  a4 04 a6 f4 09 f9 bf 1f  73 a6 c6 04 83 8a ae 39  |........s......9|
+00000030  43 d7 8d 88 8e 6c f2 da  0d a9 82 b5 4e b0 41 c9  |C....l......N.A.|
+00000040  5a 00 93 9b 8c 60 3c 08  fa aa 91                 |Z....`<....|
 >>> Flow 5 (client to server)
 00000000  17 03 02 00 30 00 00 00  00 00 00 00 00 00 00 00  |....0...........|
-00000010  00 00 00 00 00 d4 03 ec  a2 a8 1b 0a 4f 63 36 5e  |............Oc6^|
-00000020  df 85 45 e0 e7 1e 2d 48  be 2f 1a 09 5f 02 cb 91  |..E...-H./.._...|
-00000030  b2 76 35 39 a2 15 03 02  00 30 00 00 00 00 00 00  |.v59.....0......|
-00000040  00 00 00 00 00 00 00 00  00 00 b1 f1 a5 97 1d e5  |................|
-00000050  29 4c e4 d0 c7 43 3a 43  b1 15 fc 84 6e 54 ab 92  |)L...C:C....nT..|
-00000060  d4 c0 62 c9 fc 8b 73 83  62 a3                    |..b...s.b.|
+00000010  00 00 00 00 00 85 20 30  5e 6e e6 ab a0 2c 66 7a  |...... 0^n...,fz|
+00000020  f9 88 3b ee c9 5b 5c 0b  a3 7a 94 f0 8a ab 61 e0  |..;..[\..z....a.|
+00000030  7f 93 78 79 61 15 03 02  00 30 00 00 00 00 00 00  |..xya....0......|
+00000040  00 00 00 00 00 00 00 00  00 00 e0 de 16 23 01 0a  |.............#..|
+00000050  cf 90 1b 96 6a 14 f2 c9  af e2 20 49 ce b4 82 bf  |....j..... I....|
+00000060  bf ed 7a 28 e1 ed 8e e7  18 c6                    |..z(......|
index fb39b4a9db15f65d1568fe1071b7d25e5acaba9f..8483870fe8312786a7093ca8bb0bc0d9f3c688c6 100644 (file)
@@ -1,63 +1,64 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 70 01 00 00  6c 03 03 00 00 00 00 00  |....p...l.......|
+00000000  16 03 01 00 75 01 00 00  71 03 03 00 00 00 00 00  |....u...q.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
 00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
-00000040  00 2f 00 35 c0 12 00 0a  01 00 00 29 00 05 00 05  |./.5.......)....|
+00000040  00 2f 00 35 c0 12 00 0a  01 00 00 2e 00 05 00 05  |./.5............|
 00000050  01 00 00 00 00 00 0a 00  08 00 06 00 17 00 18 00  |................|
 00000060  19 00 0b 00 02 01 00 00  0d 00 0a 00 08 04 01 04  |................|
-00000070  03 02 01 02 03                                    |.....|
+00000070  03 02 01 02 03 ff 01 00  01 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 02 00 4a 02 00 00  46 03 02 52 ac 77 f7 01  |....J...F..R.w..|
-00000010  a9 ef 15 61 bf ac 76 b1  88 0d de 98 8c de f4 3e  |...a..v........>|
-00000020  52 04 64 33 6f ca b5 b4  19 5b 8f 20 1a d3 25 e1  |R.d3o....[. ..%.|
-00000030  d0 17 4c 71 8e ec 5b be  e6 99 f0 c0 07 76 8a be  |..Lq..[......v..|
-00000040  43 35 9b 98 71 e4 22 cc  88 48 fb c0 00 05 00 16  |C5..q."..H......|
-00000050  03 02 02 be 0b 00 02 ba  00 02 b7 00 02 b4 30 82  |..............0.|
-00000060  02 b0 30 82 02 19 a0 03  02 01 02 02 09 00 85 b0  |..0.............|
-00000070  bb a4 8a 7f b8 ca 30 0d  06 09 2a 86 48 86 f7 0d  |......0...*.H...|
-00000080  01 01 05 05 00 30 45 31  0b 30 09 06 03 55 04 06  |.....0E1.0...U..|
-00000090  13 02 41 55 31 13 30 11  06 03 55 04 08 13 0a 53  |..AU1.0...U....S|
-000000a0  6f 6d 65 2d 53 74 61 74  65 31 21 30 1f 06 03 55  |ome-State1!0...U|
-000000b0  04 0a 13 18 49 6e 74 65  72 6e 65 74 20 57 69 64  |....Internet Wid|
-000000c0  67 69 74 73 20 50 74 79  20 4c 74 64 30 1e 17 0d  |gits Pty Ltd0...|
-000000d0  31 30 30 34 32 34 30 39  30 39 33 38 5a 17 0d 31  |100424090938Z..1|
-000000e0  31 30 34 32 34 30 39 30  39 33 38 5a 30 45 31 0b  |10424090938Z0E1.|
-000000f0  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-00000100  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-00000110  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-00000120  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-00000130  4c 74 64 30 81 9f 30 0d  06 09 2a 86 48 86 f7 0d  |Ltd0..0...*.H...|
-00000140  01 01 01 05 00 03 81 8d  00 30 81 89 02 81 81 00  |.........0......|
-00000150  bb 79 d6 f5 17 b5 e5 bf  46 10 d0 dc 69 be e6 2b  |.y......F...i..+|
-00000160  07 43 5a d0 03 2d 8a 7a  43 85 b7 14 52 e7 a5 65  |.CZ..-.zC...R..e|
-00000170  4c 2c 78 b8 23 8c b5 b4  82 e5 de 1f 95 3b 7e 62  |L,x.#........;~b|
-00000180  a5 2c a5 33 d6 fe 12 5c  7a 56 fc f5 06 bf fa 58  |.,.3...\zV.....X|
-00000190  7b 26 3f b5 cd 04 d3 d0  c9 21 96 4a c7 f4 54 9f  |{&?......!.J..T.|
-000001a0  5a bf ef 42 71 00 fe 18  99 07 7f 7e 88 7d 7d f1  |Z..Bq......~.}}.|
-000001b0  04 39 c4 a2 2e db 51 c9  7c e3 c0 4c 3b 32 66 01  |.9....Q.|..L;2f.|
-000001c0  cf af b1 1d b8 71 9a 1d  db db 89 6b ae da 2d 79  |.....q.....k..-y|
-000001d0  02 03 01 00 01 a3 81 a7  30 81 a4 30 1d 06 03 55  |........0..0...U|
-000001e0  1d 0e 04 16 04 14 b1 ad  e2 85 5a cf cb 28 db 69  |..........Z..(.i|
-000001f0  ce 23 69 de d3 26 8e 18  88 39 30 75 06 03 55 1d  |.#i..&...90u..U.|
-00000200  23 04 6e 30 6c 80 14 b1  ad e2 85 5a cf cb 28 db  |#.n0l......Z..(.|
-00000210  69 ce 23 69 de d3 26 8e  18 88 39 a1 49 a4 47 30  |i.#i..&...9.I.G0|
-00000220  45 31 0b 30 09 06 03 55  04 06 13 02 41 55 31 13  |E1.0...U....AU1.|
-00000230  30 11 06 03 55 04 08 13  0a 53 6f 6d 65 2d 53 74  |0...U....Some-St|
-00000240  61 74 65 31 21 30 1f 06  03 55 04 0a 13 18 49 6e  |ate1!0...U....In|
-00000250  74 65 72 6e 65 74 20 57  69 64 67 69 74 73 20 50  |ternet Widgits P|
-00000260  74 79 20 4c 74 64 82 09  00 85 b0 bb a4 8a 7f b8  |ty Ltd..........|
-00000270  ca 30 0c 06 03 55 1d 13  04 05 30 03 01 01 ff 30  |.0...U....0....0|
-00000280  0d 06 09 2a 86 48 86 f7  0d 01 01 05 05 00 03 81  |...*.H..........|
-00000290  81 00 08 6c 45 24 c7 6b  b1 59 ab 0c 52 cc f2 b0  |...lE$.k.Y..R...|
-000002a0  14 d7 87 9d 7a 64 75 b5  5a 95 66 e4 c5 2b 8e ae  |....zdu.Z.f..+..|
-000002b0  12 66 1f eb 4f 38 b3 6e  60 d3 92 fd f7 41 08 b5  |.f..O8.n`....A..|
-000002c0  25 13 b1 18 7a 24 fb 30  1d ba ed 98 b9 17 ec e7  |%...z$.0........|
-000002d0  d7 31 59 db 95 d3 1d 78  ea 50 56 5c d5 82 5a 2d  |.1Y....x.PV\..Z-|
-000002e0  5a 5f 33 c4 b6 d8 c9 75  90 96 8c 0f 52 98 b5 cd  |Z_3....u....R...|
-000002f0  98 1f 89 20 5f f2 a0 1c  a3 1b 96 94 dd a9 fd 57  |... _..........W|
-00000300  e9 70 e8 26 6d 71 99 9b  26 6e 38 50 29 6c 90 a7  |.p.&mq..&n8P)l..|
-00000310  bd d9 16 03 02 00 04 0e  00 00 00                 |...........|
+00000000  16 03 02 00 51 02 00 00  4d 03 02 52 cc 57 58 d2  |....Q...M..R.WX.|
+00000010  3e 7a 93 49 2a f2 3f f8  fe 58 6b 88 d2 87 66 71  |>z.I*.?..Xk...fq|
+00000020  69 bd d2 98 03 4b 17 b1  5d 5b a5 20 c6 5d a6 c7  |i....K..][. .]..|
+00000030  40 53 b8 4f 68 74 12 70  64 58 4f 78 fa d1 a9 5c  |@S.Oht.pdXOx...\|
+00000040  f0 ce 5e 78 fd 66 30 98  8e ac 94 37 00 05 00 00  |..^x.f0....7....|
+00000050  05 ff 01 00 01 00 16 03  02 02 be 0b 00 02 ba 00  |................|
+00000060  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
+00000070  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
+00000080  09 2a 86 48 86 f7 0d 01  01 05 05 00 30 45 31 0b  |.*.H........0E1.|
+00000090  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
+000000a0  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
+000000b0  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
+000000c0  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
+000000d0  4c 74 64 30 1e 17 0d 31  30 30 34 32 34 30 39 30  |Ltd0...100424090|
+000000e0  39 33 38 5a 17 0d 31 31  30 34 32 34 30 39 30 39  |938Z..1104240909|
+000000f0  33 38 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |38Z0E1.0...U....|
+00000100  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
+00000110  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
+00000120  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
+00000130  74 73 20 50 74 79 20 4c  74 64 30 81 9f 30 0d 06  |ts Pty Ltd0..0..|
+00000140  09 2a 86 48 86 f7 0d 01  01 01 05 00 03 81 8d 00  |.*.H............|
+00000150  30 81 89 02 81 81 00 bb  79 d6 f5 17 b5 e5 bf 46  |0.......y......F|
+00000160  10 d0 dc 69 be e6 2b 07  43 5a d0 03 2d 8a 7a 43  |...i..+.CZ..-.zC|
+00000170  85 b7 14 52 e7 a5 65 4c  2c 78 b8 23 8c b5 b4 82  |...R..eL,x.#....|
+00000180  e5 de 1f 95 3b 7e 62 a5  2c a5 33 d6 fe 12 5c 7a  |....;~b.,.3...\z|
+00000190  56 fc f5 06 bf fa 58 7b  26 3f b5 cd 04 d3 d0 c9  |V.....X{&?......|
+000001a0  21 96 4a c7 f4 54 9f 5a  bf ef 42 71 00 fe 18 99  |!.J..T.Z..Bq....|
+000001b0  07 7f 7e 88 7d 7d f1 04  39 c4 a2 2e db 51 c9 7c  |..~.}}..9....Q.||
+000001c0  e3 c0 4c 3b 32 66 01 cf  af b1 1d b8 71 9a 1d db  |..L;2f......q...|
+000001d0  db 89 6b ae da 2d 79 02  03 01 00 01 a3 81 a7 30  |..k..-y........0|
+000001e0  81 a4 30 1d 06 03 55 1d  0e 04 16 04 14 b1 ad e2  |..0...U.........|
+000001f0  85 5a cf cb 28 db 69 ce  23 69 de d3 26 8e 18 88  |.Z..(.i.#i..&...|
+00000200  39 30 75 06 03 55 1d 23  04 6e 30 6c 80 14 b1 ad  |90u..U.#.n0l....|
+00000210  e2 85 5a cf cb 28 db 69  ce 23 69 de d3 26 8e 18  |..Z..(.i.#i..&..|
+00000220  88 39 a1 49 a4 47 30 45  31 0b 30 09 06 03 55 04  |.9.I.G0E1.0...U.|
+00000230  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
+00000240  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
+00000250  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
+00000260  64 67 69 74 73 20 50 74  79 20 4c 74 64 82 09 00  |dgits Pty Ltd...|
+00000270  85 b0 bb a4 8a 7f b8 ca  30 0c 06 03 55 1d 13 04  |........0...U...|
+00000280  05 30 03 01 01 ff 30 0d  06 09 2a 86 48 86 f7 0d  |.0....0...*.H...|
+00000290  01 01 05 05 00 03 81 81  00 08 6c 45 24 c7 6b b1  |..........lE$.k.|
+000002a0  59 ab 0c 52 cc f2 b0 14  d7 87 9d 7a 64 75 b5 5a  |Y..R.......zdu.Z|
+000002b0  95 66 e4 c5 2b 8e ae 12  66 1f eb 4f 38 b3 6e 60  |.f..+...f..O8.n`|
+000002c0  d3 92 fd f7 41 08 b5 25  13 b1 18 7a 24 fb 30 1d  |....A..%...z$.0.|
+000002d0  ba ed 98 b9 17 ec e7 d7  31 59 db 95 d3 1d 78 ea  |........1Y....x.|
+000002e0  50 56 5c d5 82 5a 2d 5a  5f 33 c4 b6 d8 c9 75 90  |PV\..Z-Z_3....u.|
+000002f0  96 8c 0f 52 98 b5 cd 98  1f 89 20 5f f2 a0 1c a3  |...R...... _....|
+00000300  1b 96 94 dd a9 fd 57 e9  70 e8 26 6d 71 99 9b 26  |......W.p.&mq..&|
+00000310  6e 38 50 29 6c 90 a7 bd  d9 16 03 02 00 04 0e 00  |n8P)l...........|
+00000320  00 00                                             |..|
 >>> Flow 3 (client to server)
 00000000  16 03 02 00 86 10 00 00  82 00 80 6d 51 f3 7f f9  |...........mQ...|
 00000010  3e fb 75 82 41 36 83 e8  6a ee 2a 2e 25 90 67 4c  |>.u.A6..j.*.%.gL|
 00000060  e6 bd 77 82 6f 23 b6 e0  bd a2 92 b7 3a ac e8 56  |..w.o#......:..V|
 00000070  f1 af 54 5e 46 87 e9 3b  33 e7 b8 28 b7 d6 c8 90  |..T^F..;3..(....|
 00000080  35 d4 1c 43 d1 30 6f 55  4e 0a 70 14 03 02 00 01  |5..C.0oUN.p.....|
-00000090  01 16 03 02 00 24 8e 02  46 f8 a6 27 03 86 ce 21  |.....$..F..'...!|
-000000a0  3e c1 64 75 2d fa db 7c  01 2f 89 43 9a 75 63 92  |>.du-..|./.C.uc.|
-000000b0  b0 03 5e a8 97 59 40 81  75 10                    |..^..Y@.u.|
+00000090  01 16 03 02 00 24 6c 69  1d 96 27 2b f5 0b 6e d5  |.....$li..'+..n.|
+000000a0  f7 97 96 c6 9f 5e 59 92  9f 3a 0e e5 d0 36 e4 af  |.....^Y..:...6..|
+000000b0  bc 17 bf 95 ab f7 0c 19  a6 86                    |..........|
 >>> Flow 4 (server to client)
-00000000  14 03 02 00 01 01 16 03  02 00 24 0f 50 8b d8 76  |..........$.P..v|
-00000010  1b 47 9d 1a 8f 8c 48 d1  1d 14 57 f5 54 6b f8 59  |.G....H...W.Tk.Y|
-00000020  cf 2c 6e ab f6 cb dd 43  0d f7 59 6d 41 cb 50     |.,n....C..YmA.P|
+00000000  14 03 02 00 01 01 16 03  02 00 24 dd 9f e5 d3 53  |..........$....S|
+00000010  ae af f2 41 bf eb 53 33  71 d0 f3 84 ac b0 88 72  |...A..S3q......r|
+00000020  2d de 14 5b 59 9d f3 4c  9f ab a1 aa f4 f3 af     |-..[Y..L.......|
 >>> Flow 5 (client to server)
-00000000  17 03 02 00 1a 3d 52 8b  ae aa b7 15 dd 68 bd b5  |.....=R......h..|
-00000010  bb 49 fb 5c ab eb aa cd  1e af 5b 3c 75 6f 51 15  |.I.\......[<uoQ.|
-00000020  03 02 00 16 ca fb 12 88  a0 47 f3 fa 9c d9 21 ee  |.........G....!.|
-00000030  20 35 0c 6d 37 04 2c 75  f8 c6                    | 5.m7.,u..|
+00000000  17 03 02 00 1a 24 4d 6b  23 8a 36 07 80 49 1a e5  |.....$Mk#.6..I..|
+00000010  da 85 7c a0 cb f3 82 e5  23 d7 b9 46 82 cb bc 15  |..|.....#..F....|
+00000020  03 02 00 16 f3 f1 5b f2  40 0f 3f 88 ea f2 4e 28  |......[.@.?...N(|
+00000030  52 aa c6 3a 6c 88 e3 30  21 0f                    |R..:l..0!.|
index 1cc6b3bdc134b1b3dfadd5729ffeb2eaf6fba858..0731ee2c35b31b3a4677ab319a18e56cff5b11bf 100644 (file)
@@ -1,69 +1,70 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 70 01 00 00  6c 03 03 00 00 00 00 00  |....p...l.......|
+00000000  16 03 01 00 75 01 00 00  71 03 03 00 00 00 00 00  |....u...q.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
 00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
-00000040  00 2f 00 35 c0 12 00 0a  01 00 00 29 00 05 00 05  |./.5.......)....|
+00000040  00 2f 00 35 c0 12 00 0a  01 00 00 2e 00 05 00 05  |./.5............|
 00000050  01 00 00 00 00 00 0a 00  08 00 06 00 17 00 18 00  |................|
 00000060  19 00 0b 00 02 01 00 00  0d 00 0a 00 08 04 01 04  |................|
-00000070  03 02 01 02 03                                    |.....|
+00000070  03 02 01 02 03 ff 01 00  01 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 54 02 00 00  50 03 03 52 ac 77 f8 c5  |....T...P..R.w..|
-00000010  96 12 04 26 41 58 b0 da  a3 63 a6 7c 30 17 a4 95  |...&AX...c.|0...|
-00000020  72 dc 9b 08 6b 5c cd f0  93 9e 64 20 b7 5d af c1  |r...k\....d .]..|
-00000030  b7 ca 6f 52 3b d8 51 da  34 4a 39 38 31 ed 69 01  |..oR;.Q.4J981.i.|
-00000040  bf e5 57 4c bb 90 07 f8  7b 59 e4 4c c0 09 00 00  |..WL....{Y.L....|
-00000050  08 00 0b 00 04 03 00 01  02 16 03 03 02 0e 0b 00  |................|
-00000060  02 0a 00 02 07 00 02 04  30 82 02 00 30 82 01 62  |........0...0..b|
-00000070  02 09 00 b8 bf 2d 47 a0  d2 eb f4 30 09 06 07 2a  |.....-G....0...*|
-00000080  86 48 ce 3d 04 01 30 45  31 0b 30 09 06 03 55 04  |.H.=..0E1.0...U.|
-00000090  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
-000000a0  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
-000000b0  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
-000000c0  64 67 69 74 73 20 50 74  79 20 4c 74 64 30 1e 17  |dgits Pty Ltd0..|
-000000d0  0d 31 32 31 31 32 32 31  35 30 36 33 32 5a 17 0d  |.121122150632Z..|
-000000e0  32 32 31 31 32 30 31 35  30 36 33 32 5a 30 45 31  |221120150632Z0E1|
-000000f0  0b 30 09 06 03 55 04 06  13 02 41 55 31 13 30 11  |.0...U....AU1.0.|
-00000100  06 03 55 04 08 13 0a 53  6f 6d 65 2d 53 74 61 74  |..U....Some-Stat|
-00000110  65 31 21 30 1f 06 03 55  04 0a 13 18 49 6e 74 65  |e1!0...U....Inte|
-00000120  72 6e 65 74 20 57 69 64  67 69 74 73 20 50 74 79  |rnet Widgits Pty|
-00000130  20 4c 74 64 30 81 9b 30  10 06 07 2a 86 48 ce 3d  | Ltd0..0...*.H.=|
-00000140  02 01 06 05 2b 81 04 00  23 03 81 86 00 04 00 c4  |....+...#.......|
-00000150  a1 ed be 98 f9 0b 48 73  36 7e c3 16 56 11 22 f2  |......Hs6~..V.".|
-00000160  3d 53 c3 3b 4d 21 3d cd  6b 75 e6 f6 b0 dc 9a df  |=S.;M!=.ku......|
-00000170  26 c1 bc b2 87 f0 72 32  7c b3 64 2f 1c 90 bc ea  |&.....r2|.d/....|
-00000180  68 23 10 7e fe e3 25 c0  48 3a 69 e0 28 6d d3 37  |h#.~..%.H:i.(m.7|
-00000190  00 ef 04 62 dd 0d a0 9c  70 62 83 d8 81 d3 64 31  |...b....pb....d1|
-000001a0  aa 9e 97 31 bd 96 b0 68  c0 9b 23 de 76 64 3f 1a  |...1...h..#.vd?.|
-000001b0  5c 7f e9 12 0e 58 58 b6  5f 70 dd 9b d8 ea d5 d7  |\....XX._p......|
-000001c0  f5 d5 cc b9 b6 9f 30 66  5b 66 9a 20 e2 27 e5 bf  |......0f[f. .'..|
-000001d0  fe 3b 30 09 06 07 2a 86  48 ce 3d 04 01 03 81 8c  |.;0...*.H.=.....|
-000001e0  00 30 81 88 02 42 01 88  a2 4f eb e2 45 c5 48 7d  |.0...B...O..E.H}|
-000001f0  1b ac f5 ed 98 9d ae 47  70 c0 5e 1b b6 2f bd f1  |.......Gp.^../..|
-00000200  b6 4d b7 61 40 d3 11 a2  ce ee 0b 7e 92 7e ff 76  |.M.a@......~.~.v|
-00000210  9d c3 3b 7e a5 3f ce fa  10 e2 59 ec 47 2d 7c ac  |..;~.?....Y.G-|.|
-00000220  da 4e 97 0e 15 a0 6f d0  02 42 01 4d fc be 67 13  |.N....o..B.M..g.|
-00000230  9c 2d 05 0e bd 3f a3 8c  25 c1 33 13 83 0d 94 06  |.-...?..%.3.....|
-00000240  bb d4 37 7a f6 ec 7a c9  86 2e dd d7 11 69 7f 85  |..7z..z......i..|
-00000250  7c 56 de fb 31 78 2b e4  c7 78 0d ae cb be 9e 4e  ||V..1x+..x.....N|
-00000260  36 24 31 7b 6a 0f 39 95  12 07 8f 2a 16 03 03 00  |6$1{j.9....*....|
-00000270  d7 0c 00 00 d3 03 00 17  41 04 d8 75 d0 64 77 b8  |........A..u.dw.|
-00000280  77 cf 62 09 56 22 8d 7c  c9 ad 95 b6 20 e1 22 53  |w.b.V".|.... ."S|
-00000290  04 a2 ff ef 55 98 32 a1  93 35 0d 75 21 cf f3 8b  |....U.2..5.u!...|
-000002a0  75 f1 8c da 6a d1 4d 3f  ee 45 bd 10 4c c3 cc 45  |u...j.M?.E..L..E|
-000002b0  ea 3c f7 6d 0f be 49 2c  f7 82 04 03 00 8a 30 81  |.<.m..I,......0.|
-000002c0  87 02 42 01 d5 04 fa a4  10 ff 0e 5f bb a3 ab ae  |..B........_....|
-000002d0  19 ee f0 cf 01 f1 c5 5a  ed b3 2c 08 21 e2 36 2f  |.......Z..,.!.6/|
-000002e0  ef ab 04 ab 03 2f 8c 3a  c6 1d 02 44 ca 91 dd 43  |...../.:...D...C|
-000002f0  a5 00 08 0c 5d ff d7 4e  31 5c 0c b3 da 7f 6d 6d  |....]..N1\....mm|
-00000300  0a ef 36 2e 55 02 41 2e  74 02 05 c1 4f 48 6e 3a  |..6.U.A.t...OHn:|
-00000310  59 fc 67 1d 31 b2 85 67  24 ea ed be 99 87 b3 03  |Y.g.1..g$.......|
-00000320  3c a5 bb fa f0 39 39 b6  a1 3a 3d b0 7e c4 c8 8f  |<....99..:=.~...|
-00000330  5b 74 9c bf df a0 84 f5  6c c5 c8 2a b5 65 f3 60  |[t......l..*.e.`|
-00000340  5f 38 10 c7 9b 71 64 a3  16 03 03 00 30 0d 00 00  |_8...qd.....0...|
-00000350  28 03 01 02 40 00 20 06  01 06 02 06 03 05 01 05  |(...@. .........|
-00000360  02 05 03 04 01 04 02 04  03 03 01 03 02 03 03 02  |................|
-00000370  01 02 02 02 03 01 01 00  00 0e 00 00 00           |.............|
+00000000  16 03 03 00 59 02 00 00  55 03 03 52 cc 57 59 76  |....Y...U..R.WYv|
+00000010  bc 07 88 2c 89 e3 aa 41  69 76 d1 0b 5f c0 7a b1  |...,...Aiv.._.z.|
+00000020  c3 c4 f8 12 6e 73 7f 5b  25 41 8e 20 b4 2d 8d a9  |....ns.[%A. .-..|
+00000030  80 95 44 d4 d7 47 8c a1  f1 de 36 57 cf 54 dd ee  |..D..G....6W.T..|
+00000040  a7 d8 ba cf ca b7 68 0e  9e b4 a3 7b c0 09 00 00  |......h....{....|
+00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
+00000060  03 02 0e 0b 00 02 0a 00  02 07 00 02 04 30 82 02  |.............0..|
+00000070  00 30 82 01 62 02 09 00  b8 bf 2d 47 a0 d2 eb f4  |.0..b.....-G....|
+00000080  30 09 06 07 2a 86 48 ce  3d 04 01 30 45 31 0b 30  |0...*.H.=..0E1.0|
+00000090  09 06 03 55 04 06 13 02  41 55 31 13 30 11 06 03  |...U....AU1.0...|
+000000a0  55 04 08 13 0a 53 6f 6d  65 2d 53 74 61 74 65 31  |U....Some-State1|
+000000b0  21 30 1f 06 03 55 04 0a  13 18 49 6e 74 65 72 6e  |!0...U....Intern|
+000000c0  65 74 20 57 69 64 67 69  74 73 20 50 74 79 20 4c  |et Widgits Pty L|
+000000d0  74 64 30 1e 17 0d 31 32  31 31 32 32 31 35 30 36  |td0...1211221506|
+000000e0  33 32 5a 17 0d 32 32 31  31 32 30 31 35 30 36 33  |32Z..22112015063|
+000000f0  32 5a 30 45 31 0b 30 09  06 03 55 04 06 13 02 41  |2Z0E1.0...U....A|
+00000100  55 31 13 30 11 06 03 55  04 08 13 0a 53 6f 6d 65  |U1.0...U....Some|
+00000110  2d 53 74 61 74 65 31 21  30 1f 06 03 55 04 0a 13  |-State1!0...U...|
+00000120  18 49 6e 74 65 72 6e 65  74 20 57 69 64 67 69 74  |.Internet Widgit|
+00000130  73 20 50 74 79 20 4c 74  64 30 81 9b 30 10 06 07  |s Pty Ltd0..0...|
+00000140  2a 86 48 ce 3d 02 01 06  05 2b 81 04 00 23 03 81  |*.H.=....+...#..|
+00000150  86 00 04 00 c4 a1 ed be  98 f9 0b 48 73 36 7e c3  |...........Hs6~.|
+00000160  16 56 11 22 f2 3d 53 c3  3b 4d 21 3d cd 6b 75 e6  |.V.".=S.;M!=.ku.|
+00000170  f6 b0 dc 9a df 26 c1 bc  b2 87 f0 72 32 7c b3 64  |.....&.....r2|.d|
+00000180  2f 1c 90 bc ea 68 23 10  7e fe e3 25 c0 48 3a 69  |/....h#.~..%.H:i|
+00000190  e0 28 6d d3 37 00 ef 04  62 dd 0d a0 9c 70 62 83  |.(m.7...b....pb.|
+000001a0  d8 81 d3 64 31 aa 9e 97  31 bd 96 b0 68 c0 9b 23  |...d1...1...h..#|
+000001b0  de 76 64 3f 1a 5c 7f e9  12 0e 58 58 b6 5f 70 dd  |.vd?.\....XX._p.|
+000001c0  9b d8 ea d5 d7 f5 d5 cc  b9 b6 9f 30 66 5b 66 9a  |...........0f[f.|
+000001d0  20 e2 27 e5 bf fe 3b 30  09 06 07 2a 86 48 ce 3d  | .'...;0...*.H.=|
+000001e0  04 01 03 81 8c 00 30 81  88 02 42 01 88 a2 4f eb  |......0...B...O.|
+000001f0  e2 45 c5 48 7d 1b ac f5  ed 98 9d ae 47 70 c0 5e  |.E.H}.......Gp.^|
+00000200  1b b6 2f bd f1 b6 4d b7  61 40 d3 11 a2 ce ee 0b  |../...M.a@......|
+00000210  7e 92 7e ff 76 9d c3 3b  7e a5 3f ce fa 10 e2 59  |~.~.v..;~.?....Y|
+00000220  ec 47 2d 7c ac da 4e 97  0e 15 a0 6f d0 02 42 01  |.G-|..N....o..B.|
+00000230  4d fc be 67 13 9c 2d 05  0e bd 3f a3 8c 25 c1 33  |M..g..-...?..%.3|
+00000240  13 83 0d 94 06 bb d4 37  7a f6 ec 7a c9 86 2e dd  |.......7z..z....|
+00000250  d7 11 69 7f 85 7c 56 de  fb 31 78 2b e4 c7 78 0d  |..i..|V..1x+..x.|
+00000260  ae cb be 9e 4e 36 24 31  7b 6a 0f 39 95 12 07 8f  |....N6$1{j.9....|
+00000270  2a 16 03 03 00 d8 0c 00  00 d4 03 00 17 41 04 3a  |*............A.:|
+00000280  16 95 9a af 75 ff 51 27  76 6e 82 c7 db a2 3d 62  |....u.Q'vn....=b|
+00000290  b4 65 d1 97 26 38 55 68  29 68 2c fc 4b 69 2c f9  |.e..&8Uh)h,.Ki,.|
+000002a0  01 00 4b 1e ee cf 88 54  a7 f3 49 a5 04 98 bd 12  |..K....T..I.....|
+000002b0  74 b1 cb 95 4c 49 c2 1a  31 e6 95 9f f5 0a f5 04  |t...LI..1.......|
+000002c0  03 00 8b 30 81 88 02 42  01 e7 72 2b 54 9e e0 97  |...0...B..r+T...|
+000002d0  79 e6 23 52 f7 2e 08 36  d5 dc 31 21 9d f2 13 ae  |y.#R...6..1!....|
+000002e0  30 86 1c df d2 be 52 e0  e7 8b f5 dd fa 09 f2 f3  |0.....R.........|
+000002f0  97 5d f7 48 37 83 9b aa  6c ef 87 95 de f4 50 19  |.].H7...l.....P.|
+00000300  b2 9b d6 27 4c 4d 67 6a  27 be 02 42 01 d8 86 63  |...'LMgj'..B...c|
+00000310  dc f1 9f 32 a3 25 6f 55  b3 67 7b 64 7e 24 38 25  |...2.%oU.g{d~$8%|
+00000320  96 bb 7b b1 9b ef 73 c3  6c d1 69 83 7d bc c5 30  |..{...s.l.i.}..0|
+00000330  fe 9a 21 0d 29 c4 d6 1a  51 a5 dd 6e a0 80 c8 9c  |..!.)...Q..n....|
+00000340  54 49 34 22 f7 5e cf 28  ae 2f cd 46 b1 71 16 03  |TI4".^.(./.F.q..|
+00000350  03 00 30 0d 00 00 28 03  01 02 40 00 20 06 01 06  |..0...(...@. ...|
+00000360  02 06 03 05 01 05 02 05  03 04 01 04 02 04 03 03  |................|
+00000370  01 03 02 03 03 02 01 02  02 02 03 01 01 00 00 0e  |................|
+00000380  00 00 00                                          |...|
 >>> Flow 3 (client to server)
 00000000  16 03 03 02 0a 0b 00 02  06 00 02 03 00 02 00 30  |...............0|
 00000010  82 01 fc 30 82 01 5e 02  09 00 9a 30 84 6c 26 35  |...0..^....0.l&5|
 000002a0  b3 c1 85 6a 42 9b f9 7e  7e 31 c2 e5 bd 66 02 41  |...jB..~~1...f.A|
 000002b0  4b 49 c6 cd 02 e3 83 f7  03 50 18 6d b4 c9 51 02  |KI.......P.m..Q.|
 000002c0  c0 ab 87 bc e0 3e 4b 89  53 3a e2 65 89 97 02 c1  |.....>K.S:.e....|
-000002d0  88 4a bb 6d c8 1f 2a 63  e4 a7 25 02 5c 95 a7 f1  |.J.m..*c..%.\...|
-000002e0  2c 8f bb f1 f6 95 31 b6  6b bc 29 61 b6 36 27 6e  |,.....1.k.)a.6'n|
-000002f0  ee 14 03 03 00 01 01 16  03 03 00 40 00 00 00 00  |...........@....|
-00000300  00 00 00 00 00 00 00 00  00 00 00 00 2b ec 49 d6  |............+.I.|
-00000310  bc 29 f0 dd ad 8f 56 56  1f e1 1e 8a 52 f1 ec d0  |.)....VV....R...|
-00000320  60 21 d9 6f e0 82 7b 5a  de 2d 9e e9 74 6d 7a e5  |`!.o..{Z.-..tmz.|
-00000330  c6 9f 6b da 1e 4c d6 2e  e8 57 cd 9f              |..k..L...W..|
+000002d0  88 a6 56 bf d0 53 0b a9  7e 82 7d 4d fc 66 78 8f  |..V..S..~.}M.fx.|
+000002e0  57 dc 5e 62 54 70 cc 32  0c 1c b5 62 fc 6a 76 7e  |W.^bTp.2...b.jv~|
+000002f0  3f 14 03 03 00 01 01 16  03 03 00 40 00 00 00 00  |?..........@....|
+00000300  00 00 00 00 00 00 00 00  00 00 00 00 62 a7 74 42  |............b.tB|
+00000310  ab 04 f8 f9 5a 86 3e 35  94 ce 4b 79 77 a1 a0 6a  |....Z.>5..Kyw..j|
+00000320  cf 2b 3a 62 fc 3b 50 2b  51 5e d7 6a d1 d0 65 b4  |.+:b.;P+Q^.j..e.|
+00000330  5d 15 99 11 10 d3 6b a3  97 d2 30 08              |].....k...0.|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 40 17 41 a0 69 d4  |..........@.A.i.|
-00000010  a0 9d aa dd 16 bf 06 ef  8d 63 e2 c8 d8 60 d9 a1  |.........c...`..|
-00000020  15 9e 28 76 6c 68 07 1a  e9 d6 68 f7 d2 51 5e b2  |..(vlh....h..Q^.|
-00000030  fb 5a 3c 39 5f d9 6a 1f  dd 23 06 63 47 b5 9e c1  |.Z<9_.j..#.cG...|
-00000040  7f 7a 3a e9 d9 fa 72 8a  44 e8 01                 |.z:...r.D..|
+00000000  14 03 03 00 01 01 16 03  03 00 40 fa 8c c0 6f 59  |..........@...oY|
+00000010  8f af a8 21 c8 aa 4c 00  db 6a a5 98 09 52 1a 27  |...!..L..j...R.'|
+00000020  77 af 6d 13 c2 54 f8 90  31 37 5c 86 3b 66 de d8  |w.m..T..17\.;f..|
+00000030  41 96 8b 84 d9 75 c0 00  b5 5f 99 3e a9 19 fa 6b  |A....u..._.>...k|
+00000040  be e2 78 43 30 41 94 39  ce 87 67                 |..xC0A.9..g|
 >>> Flow 5 (client to server)
 00000000  17 03 03 00 30 00 00 00  00 00 00 00 00 00 00 00  |....0...........|
-00000010  00 00 00 00 00 36 4a d2  bf e3 17 b8 b0 08 09 2e  |.....6J.........|
-00000020  75 9e 67 b6 86 09 6a f5  ed fa 75 3a 17 1e a8 9e  |u.g...j...u:....|
-00000030  50 e7 b5 79 75 15 03 03  00 30 00 00 00 00 00 00  |P..yu....0......|
-00000040  00 00 00 00 00 00 00 00  00 00 ee b2 c1 37 7d 4d  |.............7}M|
-00000050  9c 00 34 26 42 7f 3b d1  f2 f1 a9 7d 35 18 25 bb  |..4&B.;....}5.%.|
-00000060  a5 46 cc 2c 2b 90 02 a2  3b cc                    |.F.,+...;.|
+00000010  00 00 00 00 00 76 8b 21  f2 c9 fe b7 c4 60 e6 91  |.....v.!.....`..|
+00000020  00 ca 3e 54 25 5e f4 20  f8 df 58 41 03 b0 d0 fb  |..>T%^. ..XA....|
+00000030  e7 59 4d 6a 34 15 03 03  00 30 00 00 00 00 00 00  |.YMj4....0......|
+00000040  00 00 00 00 00 00 00 00  00 00 0f 0f e5 7a a2 86  |.............z..|
+00000050  8c 31 53 05 be 22 fb 53  51 e6 26 0a a5 c5 09 ca  |.1S..".SQ.&.....|
+00000060  f3 46 0f 67 50 d8 83 35  7b f3                    |.F.gP..5{.|
index 04368440ff8edeea2976401eb1d116a67a9cb31c..9edab394f70eb3fe1c5d5b93c3cd8d4806acacad 100644 (file)
@@ -1,66 +1,66 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 70 01 00 00  6c 03 03 00 00 00 00 00  |....p...l.......|
+00000000  16 03 01 00 75 01 00 00  71 03 03 00 00 00 00 00  |....u...q.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
 00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
-00000040  00 2f 00 35 c0 12 00 0a  01 00 00 29 00 05 00 05  |./.5.......)....|
+00000040  00 2f 00 35 c0 12 00 0a  01 00 00 2e 00 05 00 05  |./.5............|
 00000050  01 00 00 00 00 00 0a 00  08 00 06 00 17 00 18 00  |................|
 00000060  19 00 0b 00 02 01 00 00  0d 00 0a 00 08 04 01 04  |................|
-00000070  03 02 01 02 03                                    |.....|
+00000070  03 02 01 02 03 ff 01 00  01 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 4a 02 00 00  46 03 03 52 ac 77 f8 46  |....J...F..R.w.F|
-00000010  c2 25 41 4d f8 87 23 8f  4b f7 71 de cf 3b 78 df  |.%AM..#.K.q..;x.|
-00000020  77 c6 71 a2 6e f6 87 de  31 c6 89 20 23 7f ad 48  |w.q.n...1.. #..H|
-00000030  70 f7 2c 4f 87 c8 fb fd  0c 6f af a3 c1 a9 be 57  |p.,O.....o.....W|
-00000040  0f e0 d4 cc 2c f3 31 94  6f 60 b0 1e 00 05 00 16  |....,.1.o`......|
-00000050  03 03 02 be 0b 00 02 ba  00 02 b7 00 02 b4 30 82  |..............0.|
-00000060  02 b0 30 82 02 19 a0 03  02 01 02 02 09 00 85 b0  |..0.............|
-00000070  bb a4 8a 7f b8 ca 30 0d  06 09 2a 86 48 86 f7 0d  |......0...*.H...|
-00000080  01 01 05 05 00 30 45 31  0b 30 09 06 03 55 04 06  |.....0E1.0...U..|
-00000090  13 02 41 55 31 13 30 11  06 03 55 04 08 13 0a 53  |..AU1.0...U....S|
-000000a0  6f 6d 65 2d 53 74 61 74  65 31 21 30 1f 06 03 55  |ome-State1!0...U|
-000000b0  04 0a 13 18 49 6e 74 65  72 6e 65 74 20 57 69 64  |....Internet Wid|
-000000c0  67 69 74 73 20 50 74 79  20 4c 74 64 30 1e 17 0d  |gits Pty Ltd0...|
-000000d0  31 30 30 34 32 34 30 39  30 39 33 38 5a 17 0d 31  |100424090938Z..1|
-000000e0  31 30 34 32 34 30 39 30  39 33 38 5a 30 45 31 0b  |10424090938Z0E1.|
-000000f0  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-00000100  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-00000110  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-00000120  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-00000130  4c 74 64 30 81 9f 30 0d  06 09 2a 86 48 86 f7 0d  |Ltd0..0...*.H...|
-00000140  01 01 01 05 00 03 81 8d  00 30 81 89 02 81 81 00  |.........0......|
-00000150  bb 79 d6 f5 17 b5 e5 bf  46 10 d0 dc 69 be e6 2b  |.y......F...i..+|
-00000160  07 43 5a d0 03 2d 8a 7a  43 85 b7 14 52 e7 a5 65  |.CZ..-.zC...R..e|
-00000170  4c 2c 78 b8 23 8c b5 b4  82 e5 de 1f 95 3b 7e 62  |L,x.#........;~b|
-00000180  a5 2c a5 33 d6 fe 12 5c  7a 56 fc f5 06 bf fa 58  |.,.3...\zV.....X|
-00000190  7b 26 3f b5 cd 04 d3 d0  c9 21 96 4a c7 f4 54 9f  |{&?......!.J..T.|
-000001a0  5a bf ef 42 71 00 fe 18  99 07 7f 7e 88 7d 7d f1  |Z..Bq......~.}}.|
-000001b0  04 39 c4 a2 2e db 51 c9  7c e3 c0 4c 3b 32 66 01  |.9....Q.|..L;2f.|
-000001c0  cf af b1 1d b8 71 9a 1d  db db 89 6b ae da 2d 79  |.....q.....k..-y|
-000001d0  02 03 01 00 01 a3 81 a7  30 81 a4 30 1d 06 03 55  |........0..0...U|
-000001e0  1d 0e 04 16 04 14 b1 ad  e2 85 5a cf cb 28 db 69  |..........Z..(.i|
-000001f0  ce 23 69 de d3 26 8e 18  88 39 30 75 06 03 55 1d  |.#i..&...90u..U.|
-00000200  23 04 6e 30 6c 80 14 b1  ad e2 85 5a cf cb 28 db  |#.n0l......Z..(.|
-00000210  69 ce 23 69 de d3 26 8e  18 88 39 a1 49 a4 47 30  |i.#i..&...9.I.G0|
-00000220  45 31 0b 30 09 06 03 55  04 06 13 02 41 55 31 13  |E1.0...U....AU1.|
-00000230  30 11 06 03 55 04 08 13  0a 53 6f 6d 65 2d 53 74  |0...U....Some-St|
-00000240  61 74 65 31 21 30 1f 06  03 55 04 0a 13 18 49 6e  |ate1!0...U....In|
-00000250  74 65 72 6e 65 74 20 57  69 64 67 69 74 73 20 50  |ternet Widgits P|
-00000260  74 79 20 4c 74 64 82 09  00 85 b0 bb a4 8a 7f b8  |ty Ltd..........|
-00000270  ca 30 0c 06 03 55 1d 13  04 05 30 03 01 01 ff 30  |.0...U....0....0|
-00000280  0d 06 09 2a 86 48 86 f7  0d 01 01 05 05 00 03 81  |...*.H..........|
-00000290  81 00 08 6c 45 24 c7 6b  b1 59 ab 0c 52 cc f2 b0  |...lE$.k.Y..R...|
-000002a0  14 d7 87 9d 7a 64 75 b5  5a 95 66 e4 c5 2b 8e ae  |....zdu.Z.f..+..|
-000002b0  12 66 1f eb 4f 38 b3 6e  60 d3 92 fd f7 41 08 b5  |.f..O8.n`....A..|
-000002c0  25 13 b1 18 7a 24 fb 30  1d ba ed 98 b9 17 ec e7  |%...z$.0........|
-000002d0  d7 31 59 db 95 d3 1d 78  ea 50 56 5c d5 82 5a 2d  |.1Y....x.PV\..Z-|
-000002e0  5a 5f 33 c4 b6 d8 c9 75  90 96 8c 0f 52 98 b5 cd  |Z_3....u....R...|
-000002f0  98 1f 89 20 5f f2 a0 1c  a3 1b 96 94 dd a9 fd 57  |... _..........W|
-00000300  e9 70 e8 26 6d 71 99 9b  26 6e 38 50 29 6c 90 a7  |.p.&mq..&n8P)l..|
-00000310  bd d9 16 03 03 00 30 0d  00 00 28 03 01 02 40 00  |......0...(...@.|
-00000320  20 06 01 06 02 06 03 05  01 05 02 05 03 04 01 04  | ...............|
-00000330  02 04 03 03 01 03 02 03  03 02 01 02 02 02 03 01  |................|
-00000340  01 00 00 0e 00 00 00                              |.......|
+00000000  16 03 03 00 51 02 00 00  4d 03 03 52 cc 57 59 85  |....Q...M..R.WY.|
+00000010  0f 00 df b8 0d ef c4 98  ba e3 bd 71 4c 98 e5 80  |...........qL...|
+00000020  af 77 c7 d8 5f c1 36 62  1c ef 89 20 b6 01 c3 3b  |.w.._.6b... ...;|
+00000030  9e 93 27 04 05 7b 73 b3  02 7b c3 89 f5 ac 51 24  |..'..{s..{....Q$|
+00000040  7c e5 6d f3 34 d0 99 71  5e ae 30 ea 00 05 00 00  ||.m.4..q^.0.....|
+00000050  05 ff 01 00 01 00 16 03  03 02 be 0b 00 02 ba 00  |................|
+00000060  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
+00000070  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
+00000080  09 2a 86 48 86 f7 0d 01  01 05 05 00 30 45 31 0b  |.*.H........0E1.|
+00000090  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
+000000a0  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
+000000b0  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
+000000c0  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
+000000d0  4c 74 64 30 1e 17 0d 31  30 30 34 32 34 30 39 30  |Ltd0...100424090|
+000000e0  39 33 38 5a 17 0d 31 31  30 34 32 34 30 39 30 39  |938Z..1104240909|
+000000f0  33 38 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |38Z0E1.0...U....|
+00000100  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
+00000110  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
+00000120  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
+00000130  74 73 20 50 74 79 20 4c  74 64 30 81 9f 30 0d 06  |ts Pty Ltd0..0..|
+00000140  09 2a 86 48 86 f7 0d 01  01 01 05 00 03 81 8d 00  |.*.H............|
+00000150  30 81 89 02 81 81 00 bb  79 d6 f5 17 b5 e5 bf 46  |0.......y......F|
+00000160  10 d0 dc 69 be e6 2b 07  43 5a d0 03 2d 8a 7a 43  |...i..+.CZ..-.zC|
+00000170  85 b7 14 52 e7 a5 65 4c  2c 78 b8 23 8c b5 b4 82  |...R..eL,x.#....|
+00000180  e5 de 1f 95 3b 7e 62 a5  2c a5 33 d6 fe 12 5c 7a  |....;~b.,.3...\z|
+00000190  56 fc f5 06 bf fa 58 7b  26 3f b5 cd 04 d3 d0 c9  |V.....X{&?......|
+000001a0  21 96 4a c7 f4 54 9f 5a  bf ef 42 71 00 fe 18 99  |!.J..T.Z..Bq....|
+000001b0  07 7f 7e 88 7d 7d f1 04  39 c4 a2 2e db 51 c9 7c  |..~.}}..9....Q.||
+000001c0  e3 c0 4c 3b 32 66 01 cf  af b1 1d b8 71 9a 1d db  |..L;2f......q...|
+000001d0  db 89 6b ae da 2d 79 02  03 01 00 01 a3 81 a7 30  |..k..-y........0|
+000001e0  81 a4 30 1d 06 03 55 1d  0e 04 16 04 14 b1 ad e2  |..0...U.........|
+000001f0  85 5a cf cb 28 db 69 ce  23 69 de d3 26 8e 18 88  |.Z..(.i.#i..&...|
+00000200  39 30 75 06 03 55 1d 23  04 6e 30 6c 80 14 b1 ad  |90u..U.#.n0l....|
+00000210  e2 85 5a cf cb 28 db 69  ce 23 69 de d3 26 8e 18  |..Z..(.i.#i..&..|
+00000220  88 39 a1 49 a4 47 30 45  31 0b 30 09 06 03 55 04  |.9.I.G0E1.0...U.|
+00000230  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
+00000240  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
+00000250  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
+00000260  64 67 69 74 73 20 50 74  79 20 4c 74 64 82 09 00  |dgits Pty Ltd...|
+00000270  85 b0 bb a4 8a 7f b8 ca  30 0c 06 03 55 1d 13 04  |........0...U...|
+00000280  05 30 03 01 01 ff 30 0d  06 09 2a 86 48 86 f7 0d  |.0....0...*.H...|
+00000290  01 01 05 05 00 03 81 81  00 08 6c 45 24 c7 6b b1  |..........lE$.k.|
+000002a0  59 ab 0c 52 cc f2 b0 14  d7 87 9d 7a 64 75 b5 5a  |Y..R.......zdu.Z|
+000002b0  95 66 e4 c5 2b 8e ae 12  66 1f eb 4f 38 b3 6e 60  |.f..+...f..O8.n`|
+000002c0  d3 92 fd f7 41 08 b5 25  13 b1 18 7a 24 fb 30 1d  |....A..%...z$.0.|
+000002d0  ba ed 98 b9 17 ec e7 d7  31 59 db 95 d3 1d 78 ea  |........1Y....x.|
+000002e0  50 56 5c d5 82 5a 2d 5a  5f 33 c4 b6 d8 c9 75 90  |PV\..Z-Z_3....u.|
+000002f0  96 8c 0f 52 98 b5 cd 98  1f 89 20 5f f2 a0 1c a3  |...R...... _....|
+00000300  1b 96 94 dd a9 fd 57 e9  70 e8 26 6d 71 99 9b 26  |......W.p.&mq..&|
+00000310  6e 38 50 29 6c 90 a7 bd  d9 16 03 03 00 30 0d 00  |n8P)l........0..|
+00000320  00 28 03 01 02 40 00 20  06 01 06 02 06 03 05 01  |.(...@. ........|
+00000330  05 02 05 03 04 01 04 02  04 03 03 01 03 02 03 03  |................|
+00000340  02 01 02 02 02 03 01 01  00 00 0e 00 00 00        |..............|
 >>> Flow 3 (client to server)
 00000000  16 03 03 02 0a 0b 00 02  06 00 02 03 00 02 00 30  |...............0|
 00000010  82 01 fc 30 82 01 5e 02  09 00 9a 30 84 6c 26 35  |...0..^....0.l&5|
 000002e0  b3 c1 85 6a 42 9b f9 7e  7e 31 c2 e5 bd 66 02 41  |...jB..~~1...f.A|
 000002f0  4b 49 c6 cd 02 e3 83 f7  03 50 18 6d b4 c9 51 02  |KI.......P.m..Q.|
 00000300  c0 ab 87 bc e0 3e 4b 89  53 3a e2 65 89 97 02 c1  |.....>K.S:.e....|
-00000310  88 e9 ba 78 0b 19 d9 81  39 02 7e b5 9f ec 53 0d  |...x....9.~...S.|
-00000320  7e 92 80 e5 ca c5 4a 25  50 bf 85 3a 4c 0f 73 ca  |~.....J%P..:L.s.|
-00000330  ef 14 03 03 00 01 01 16  03 03 00 24 d0 33 06 ab  |...........$.3..|
-00000340  17 88 e1 65 44 18 3a 45  51 44 6f 0e 2e 85 61 33  |...eD.:EQDo...a3|
-00000350  1d 1b bb 5b 89 b5 da f0  7d df 01 90 67 0c 27 4e  |...[....}...g.'N|
+00000310  88 d6 42 09 8f e0 57 a7  e6 9e 65 3d fd 82 45 9d  |..B...W...e=..E.|
+00000320  3e 69 cc ad 17 72 c7 98  8d 3a ca f0 05 63 43 40  |>i...r...:...cC@|
+00000330  7a 14 03 03 00 01 01 16  03 03 00 24 a8 45 b8 6e  |z..........$.E.n|
+00000340  21 28 b3 6d 94 0d 7b c4  af 24 0e ca 51 ec 85 3c  |!(.m..{..$..Q..<|
+00000350  87 43 fd 36 e4 3d 1a f4  28 df 90 19 b6 05 d0 c9  |.C.6.=..(.......|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 24 4d ed 09 20 61  |..........$M.. a|
-00000010  30 03 09 eb cd d5 84 29  82 90 84 50 1e e7 9b 7b  |0......)...P...{|
-00000020  ec 8a 18 0c b5 6e 32 c7  65 fb 26 15 9e 79 41     |.....n2.e.&..yA|
+00000000  14 03 03 00 01 01 16 03  03 00 24 ae 0d d7 72 4f  |..........$...rO|
+00000010  70 d9 16 20 da 70 dd 04  d5 5a 96 32 80 8c 14 db  |p.. .p...Z.2....|
+00000020  4d 10 31 47 1e 26 78 f1  95 25 0c fe 24 2f 6f     |M.1G.&x..%..$/o|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 1a 85 47 11  25 35 d5 53 7f 3d 01 87  |......G.%5.S.=..|
-00000010  14 58 90 f7 25 1a 56 99  7b a2 b9 31 86 b3 45 15  |.X..%.V.{..1..E.|
-00000020  03 03 00 16 88 b2 fb 1c  f9 bb e6 7a a0 c0 d0 52  |...........z...R|
-00000030  f2 f9 b8 e4 5d e5 b7 a0  96 ca                    |....].....|
+00000000  17 03 03 00 1a d4 7d c7  83 f7 98 3b 77 91 4b e6  |......}....;w.K.|
+00000010  68 fa e2 22 37 24 93 20  fa e2 67 18 03 41 90 15  |h.."7$. ..g..A..|
+00000020  03 03 00 16 0b ff 73 1c  e5 81 5f 28 52 72 49 39  |......s..._(RrI9|
+00000030  ca 42 fb 57 8a 3a 80 75  2b ac                    |.B.W.:.u+.|
index 5c4b62321f1cb30e493cb1cb10f319baf33dc222..2b380a8119f6ef8632f4e3058d68b0faa1f1a6d7 100644 (file)
@@ -1,69 +1,70 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 70 01 00 00  6c 03 03 00 00 00 00 00  |....p...l.......|
+00000000  16 03 01 00 75 01 00 00  71 03 03 00 00 00 00 00  |....u...q.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
 00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
-00000040  00 2f 00 35 c0 12 00 0a  01 00 00 29 00 05 00 05  |./.5.......)....|
+00000040  00 2f 00 35 c0 12 00 0a  01 00 00 2e 00 05 00 05  |./.5............|
 00000050  01 00 00 00 00 00 0a 00  08 00 06 00 17 00 18 00  |................|
 00000060  19 00 0b 00 02 01 00 00  0d 00 0a 00 08 04 01 04  |................|
-00000070  03 02 01 02 03                                    |.....|
+00000070  03 02 01 02 03 ff 01 00  01 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 54 02 00 00  50 03 03 52 ac 77 f8 85  |....T...P..R.w..|
-00000010  40 fe 2e 6e 8e 8b 52 83  0e 17 63 15 6e a8 07 43  |@..n..R...c.n..C|
-00000020  de 66 78 c6 3b 54 c2 fe  a1 8e c8 20 d8 77 b3 a3  |.fx.;T..... .w..|
-00000030  2e bf c7 0f 1a 2f 0a 76  c7 e3 a6 62 ae 4b 57 0a  |...../.v...b.KW.|
-00000040  78 ed 7e ea 4f 4e ce 97  72 b1 04 78 c0 09 00 00  |x.~.ON..r..x....|
-00000050  08 00 0b 00 04 03 00 01  02 16 03 03 02 0e 0b 00  |................|
-00000060  02 0a 00 02 07 00 02 04  30 82 02 00 30 82 01 62  |........0...0..b|
-00000070  02 09 00 b8 bf 2d 47 a0  d2 eb f4 30 09 06 07 2a  |.....-G....0...*|
-00000080  86 48 ce 3d 04 01 30 45  31 0b 30 09 06 03 55 04  |.H.=..0E1.0...U.|
-00000090  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
-000000a0  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
-000000b0  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
-000000c0  64 67 69 74 73 20 50 74  79 20 4c 74 64 30 1e 17  |dgits Pty Ltd0..|
-000000d0  0d 31 32 31 31 32 32 31  35 30 36 33 32 5a 17 0d  |.121122150632Z..|
-000000e0  32 32 31 31 32 30 31 35  30 36 33 32 5a 30 45 31  |221120150632Z0E1|
-000000f0  0b 30 09 06 03 55 04 06  13 02 41 55 31 13 30 11  |.0...U....AU1.0.|
-00000100  06 03 55 04 08 13 0a 53  6f 6d 65 2d 53 74 61 74  |..U....Some-Stat|
-00000110  65 31 21 30 1f 06 03 55  04 0a 13 18 49 6e 74 65  |e1!0...U....Inte|
-00000120  72 6e 65 74 20 57 69 64  67 69 74 73 20 50 74 79  |rnet Widgits Pty|
-00000130  20 4c 74 64 30 81 9b 30  10 06 07 2a 86 48 ce 3d  | Ltd0..0...*.H.=|
-00000140  02 01 06 05 2b 81 04 00  23 03 81 86 00 04 00 c4  |....+...#.......|
-00000150  a1 ed be 98 f9 0b 48 73  36 7e c3 16 56 11 22 f2  |......Hs6~..V.".|
-00000160  3d 53 c3 3b 4d 21 3d cd  6b 75 e6 f6 b0 dc 9a df  |=S.;M!=.ku......|
-00000170  26 c1 bc b2 87 f0 72 32  7c b3 64 2f 1c 90 bc ea  |&.....r2|.d/....|
-00000180  68 23 10 7e fe e3 25 c0  48 3a 69 e0 28 6d d3 37  |h#.~..%.H:i.(m.7|
-00000190  00 ef 04 62 dd 0d a0 9c  70 62 83 d8 81 d3 64 31  |...b....pb....d1|
-000001a0  aa 9e 97 31 bd 96 b0 68  c0 9b 23 de 76 64 3f 1a  |...1...h..#.vd?.|
-000001b0  5c 7f e9 12 0e 58 58 b6  5f 70 dd 9b d8 ea d5 d7  |\....XX._p......|
-000001c0  f5 d5 cc b9 b6 9f 30 66  5b 66 9a 20 e2 27 e5 bf  |......0f[f. .'..|
-000001d0  fe 3b 30 09 06 07 2a 86  48 ce 3d 04 01 03 81 8c  |.;0...*.H.=.....|
-000001e0  00 30 81 88 02 42 01 88  a2 4f eb e2 45 c5 48 7d  |.0...B...O..E.H}|
-000001f0  1b ac f5 ed 98 9d ae 47  70 c0 5e 1b b6 2f bd f1  |.......Gp.^../..|
-00000200  b6 4d b7 61 40 d3 11 a2  ce ee 0b 7e 92 7e ff 76  |.M.a@......~.~.v|
-00000210  9d c3 3b 7e a5 3f ce fa  10 e2 59 ec 47 2d 7c ac  |..;~.?....Y.G-|.|
-00000220  da 4e 97 0e 15 a0 6f d0  02 42 01 4d fc be 67 13  |.N....o..B.M..g.|
-00000230  9c 2d 05 0e bd 3f a3 8c  25 c1 33 13 83 0d 94 06  |.-...?..%.3.....|
-00000240  bb d4 37 7a f6 ec 7a c9  86 2e dd d7 11 69 7f 85  |..7z..z......i..|
-00000250  7c 56 de fb 31 78 2b e4  c7 78 0d ae cb be 9e 4e  ||V..1x+..x.....N|
-00000260  36 24 31 7b 6a 0f 39 95  12 07 8f 2a 16 03 03 00  |6$1{j.9....*....|
-00000270  d8 0c 00 00 d4 03 00 17  41 04 d9 d2 72 4b ef c3  |........A...rK..|
-00000280  be a2 5b fc b3 75 52 c9  b4 5d 56 bf 23 2e e6 18  |..[..uR..]V.#...|
-00000290  96 df 4b 67 af 1c 11 c3  17 fa d5 43 81 d6 91 c3  |..Kg.......C....|
-000002a0  b2 0a d8 cc b9 24 36 1d  74 4e bf 1e 20 2f 77 cd  |.....$6.tN.. /w.|
-000002b0  6a 3b d7 07 b9 17 e8 ad  1d 5a 04 03 00 8b 30 81  |j;.......Z....0.|
-000002c0  88 02 42 01 9d ae 1a b6  0f 0a 0d 1b e1 d7 30 8c  |..B...........0.|
-000002d0  f1 63 1c 0a b9 9a 06 ef  23 59 4d c7 ba 86 ec 7e  |.c......#YM....~|
-000002e0  e4 5b 95 21 ea 7b 28 d2  a1 8c 9c fe 80 25 63 5f  |.[.!.{(......%c_|
-000002f0  42 e7 a2 59 db 76 de a2  66 cc 99 c7 96 a2 0a 54  |B..Y.v..f......T|
-00000300  15 62 cb d4 59 02 42 00  80 29 a2 cb a7 f4 ce 1d  |.b..Y.B..)......|
-00000310  4b 99 9b c1 36 70 a7 18  a4 94 8a 4b 02 6d 25 a6  |K...6p.....K.m%.|
-00000320  00 7c 84 09 21 db 31 0f  0d cc 4a 57 b6 44 5b cd  |.|..!.1...JW.D[.|
-00000330  1b be 16 ec d7 0c e4 27  bb 13 33 e9 d2 ae 13 c5  |.......'..3.....|
-00000340  05 c1 48 fd f3 c6 f9 a2  e0 16 03 03 00 30 0d 00  |..H..........0..|
-00000350  00 28 03 01 02 40 00 20  06 01 06 02 06 03 05 01  |.(...@. ........|
-00000360  05 02 05 03 04 01 04 02  04 03 03 01 03 02 03 03  |................|
-00000370  02 01 02 02 02 03 01 01  00 00 0e 00 00 00        |..............|
+00000000  16 03 03 00 59 02 00 00  55 03 03 52 cc 57 58 6a  |....Y...U..R.WXj|
+00000010  f6 51 de a7 6b b0 94 bb  98 24 ab e2 c0 02 e4 8c  |.Q..k....$......|
+00000020  ac a8 48 5d 41 82 eb c0  de 5a 1e 20 70 29 82 6c  |..H]A....Z. p).l|
+00000030  01 cf 4e 21 52 18 98 8c  0a 31 14 26 6c a4 44 11  |..N!R....1.&l.D.|
+00000040  6c 5b d6 5c cb a4 b1 91  52 13 b5 77 c0 09 00 00  |l[.\....R..w....|
+00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
+00000060  03 02 0e 0b 00 02 0a 00  02 07 00 02 04 30 82 02  |.............0..|
+00000070  00 30 82 01 62 02 09 00  b8 bf 2d 47 a0 d2 eb f4  |.0..b.....-G....|
+00000080  30 09 06 07 2a 86 48 ce  3d 04 01 30 45 31 0b 30  |0...*.H.=..0E1.0|
+00000090  09 06 03 55 04 06 13 02  41 55 31 13 30 11 06 03  |...U....AU1.0...|
+000000a0  55 04 08 13 0a 53 6f 6d  65 2d 53 74 61 74 65 31  |U....Some-State1|
+000000b0  21 30 1f 06 03 55 04 0a  13 18 49 6e 74 65 72 6e  |!0...U....Intern|
+000000c0  65 74 20 57 69 64 67 69  74 73 20 50 74 79 20 4c  |et Widgits Pty L|
+000000d0  74 64 30 1e 17 0d 31 32  31 31 32 32 31 35 30 36  |td0...1211221506|
+000000e0  33 32 5a 17 0d 32 32 31  31 32 30 31 35 30 36 33  |32Z..22112015063|
+000000f0  32 5a 30 45 31 0b 30 09  06 03 55 04 06 13 02 41  |2Z0E1.0...U....A|
+00000100  55 31 13 30 11 06 03 55  04 08 13 0a 53 6f 6d 65  |U1.0...U....Some|
+00000110  2d 53 74 61 74 65 31 21  30 1f 06 03 55 04 0a 13  |-State1!0...U...|
+00000120  18 49 6e 74 65 72 6e 65  74 20 57 69 64 67 69 74  |.Internet Widgit|
+00000130  73 20 50 74 79 20 4c 74  64 30 81 9b 30 10 06 07  |s Pty Ltd0..0...|
+00000140  2a 86 48 ce 3d 02 01 06  05 2b 81 04 00 23 03 81  |*.H.=....+...#..|
+00000150  86 00 04 00 c4 a1 ed be  98 f9 0b 48 73 36 7e c3  |...........Hs6~.|
+00000160  16 56 11 22 f2 3d 53 c3  3b 4d 21 3d cd 6b 75 e6  |.V.".=S.;M!=.ku.|
+00000170  f6 b0 dc 9a df 26 c1 bc  b2 87 f0 72 32 7c b3 64  |.....&.....r2|.d|
+00000180  2f 1c 90 bc ea 68 23 10  7e fe e3 25 c0 48 3a 69  |/....h#.~..%.H:i|
+00000190  e0 28 6d d3 37 00 ef 04  62 dd 0d a0 9c 70 62 83  |.(m.7...b....pb.|
+000001a0  d8 81 d3 64 31 aa 9e 97  31 bd 96 b0 68 c0 9b 23  |...d1...1...h..#|
+000001b0  de 76 64 3f 1a 5c 7f e9  12 0e 58 58 b6 5f 70 dd  |.vd?.\....XX._p.|
+000001c0  9b d8 ea d5 d7 f5 d5 cc  b9 b6 9f 30 66 5b 66 9a  |...........0f[f.|
+000001d0  20 e2 27 e5 bf fe 3b 30  09 06 07 2a 86 48 ce 3d  | .'...;0...*.H.=|
+000001e0  04 01 03 81 8c 00 30 81  88 02 42 01 88 a2 4f eb  |......0...B...O.|
+000001f0  e2 45 c5 48 7d 1b ac f5  ed 98 9d ae 47 70 c0 5e  |.E.H}.......Gp.^|
+00000200  1b b6 2f bd f1 b6 4d b7  61 40 d3 11 a2 ce ee 0b  |../...M.a@......|
+00000210  7e 92 7e ff 76 9d c3 3b  7e a5 3f ce fa 10 e2 59  |~.~.v..;~.?....Y|
+00000220  ec 47 2d 7c ac da 4e 97  0e 15 a0 6f d0 02 42 01  |.G-|..N....o..B.|
+00000230  4d fc be 67 13 9c 2d 05  0e bd 3f a3 8c 25 c1 33  |M..g..-...?..%.3|
+00000240  13 83 0d 94 06 bb d4 37  7a f6 ec 7a c9 86 2e dd  |.......7z..z....|
+00000250  d7 11 69 7f 85 7c 56 de  fb 31 78 2b e4 c7 78 0d  |..i..|V..1x+..x.|
+00000260  ae cb be 9e 4e 36 24 31  7b 6a 0f 39 95 12 07 8f  |....N6$1{j.9....|
+00000270  2a 16 03 03 00 d8 0c 00  00 d4 03 00 17 41 04 de  |*............A..|
+00000280  c7 75 51 96 25 63 8e c0  da 9c c0 8e d1 76 ca 08  |.uQ.%c.......v..|
+00000290  4c f5 a0 13 75 01 ab cf  12 09 ae cd 13 53 84 1e  |L...u........S..|
+000002a0  a4 f8 46 0f 15 08 18 48  65 d9 75 85 80 38 79 b7  |..F....He.u..8y.|
+000002b0  fc 51 a2 7c 7a ac ab b9  67 8a d7 16 af 75 df 04  |.Q.|z...g....u..|
+000002c0  03 00 8b 30 81 88 02 42  00 fe 19 74 a9 a1 27 05  |...0...B...t..'.|
+000002d0  92 78 a4 c8 9d c8 a5 de  67 cd 1f a3 1b c7 ba 7e  |.x......g......~|
+000002e0  75 68 15 29 16 e7 91 f9  b9 7b d7 e4 e9 c0 2a 7f  |uh.).....{....*.|
+000002f0  1a ce 71 5a b9 c1 64 dd  26 59 24 e8 34 21 24 8a  |..qZ..d.&Y$.4!$.|
+00000300  b0 19 06 d4 46 0c 05 46  dc 5f 02 42 00 a8 05 71  |....F..F._.B...q|
+00000310  59 ef 60 fa cf 06 ec 18  5f be 53 b7 95 07 05 5b  |Y.`....._.S....[|
+00000320  70 87 ac da f4 61 94 41  60 c8 ab 7b 26 5a 32 4d  |p....a.A`..{&Z2M|
+00000330  0d 53 00 0e 8e b3 b2 16  c7 4e 3a 15 14 76 bc dc  |.S.......N:..v..|
+00000340  ff b6 60 eb 62 b6 15 34  53 4f 2a 42 48 2c 16 03  |..`.b..4SO*BH,..|
+00000350  03 00 30 0d 00 00 28 03  01 02 40 00 20 06 01 06  |..0...(...@. ...|
+00000360  02 06 03 05 01 05 02 05  03 04 01 04 02 04 03 03  |................|
+00000370  01 03 02 03 03 02 01 02  02 02 03 01 01 00 00 0e  |................|
+00000380  00 00 00                                          |...|
 >>> Flow 3 (client to server)
 00000000  16 03 03 01 fb 0b 00 01  f7 00 01 f4 00 01 f1 30  |...............0|
 00000010  82 01 ed 30 82 01 58 a0  03 02 01 02 02 01 00 30  |...0..X........0|
 00000220  a7 24 20 3e b2 56 1c ce  97 28 5e f8 2b 2d 4f 9e  |.$ >.V...(^.+-O.|
 00000230  f1 07 9f 6c 4b 5b 83 56  e2 32 42 e9 58 b6 d7 49  |...lK[.V.2B.X..I|
 00000240  a6 b5 68 1a 41 03 56 6b  dc 5a 89 16 03 03 00 88  |..h.A.Vk.Z......|
-00000250  0f 00 00 84 04 01 00 80  3c 05 23 6b 47 37 6c de  |........<.#kG7l.|
-00000260  d9 21 fc c5 ba 63 15 5d  55 d0 1c 78 cc b7 76 6f  |.!...c.]U..x..vo|
-00000270  97 d7 ce cc 28 e4 cb 2c  b4 33 c4 7b 39 3a da b8  |....(..,.3.{9:..|
-00000280  0a 6d 79 be 30 86 21 2d  40 c9 7a 5e 44 98 b7 a2  |.my.0.!-@.z^D...|
-00000290  23 9d d2 af 3d d1 df 08  a0 b5 87 9f 57 06 1b ab  |#...=.......W...|
-000002a0  1e 8b e5 1f 09 71 cd df  7d 9b d3 bd a9 06 29 7f  |.....q..}.....).|
-000002b0  6a 84 b7 1b c5 a4 ee 11  e4 11 23 c1 1c 64 00 0b  |j.........#..d..|
-000002c0  07 49 ba 2b 40 95 57 0a  e5 02 ae a1 c1 e4 0b 31  |.I.+@.W........1|
-000002d0  9b bf ad eb aa 74 a9 fa  14 03 03 00 01 01 16 03  |.....t..........|
+00000250  0f 00 00 84 04 01 00 80  42 bd a6 a2 1f 49 ea 57  |........B....I.W|
+00000260  43 59 a0 b6 9f 1d b3 3c  35 a7 fa c7 57 02 fa f0  |CY.....<5...W...|
+00000270  9f 7d a2 77 1a a4 e1 13  c0 78 a3 9e 59 1a f2 c6  |.}.w.....x..Y...|
+00000280  2b dd 8d bc 5d f1 99 e8  db ac a2 9c 6e d8 b5 6a  |+...].......n..j|
+00000290  a5 04 aa 6c 48 b8 7a 06  55 81 1a e0 41 69 28 42  |...lH.z.U...Ai(B|
+000002a0  53 fa f0 63 a9 b5 c1 2f  69 60 cf 02 da d2 eb c8  |S..c.../i`......|
+000002b0  e8 a1 5c 7b b1 05 c3 b8  66 34 fe 21 8a 7a 84 10  |..\{....f4.!.z..|
+000002c0  f1 4d bd b1 68 97 85 11  10 bf be 96 cf 37 e9 68  |.M..h........7.h|
+000002d0  20 ab d2 f8 d2 20 65 90  14 03 03 00 01 01 16 03  | .... e.........|
 000002e0  03 00 40 00 00 00 00 00  00 00 00 00 00 00 00 00  |..@.............|
-000002f0  00 00 00 9b 04 da 20 1e  55 a7 d0 60 f3 7b 60 e2  |...... .U..`.{`.|
-00000300  3e 46 59 73 84 f7 1c 19  93 c5 53 95 bf 24 05 c9  |>FYs......S..$..|
-00000310  68 40 53 a9 b8 da 98 2b  08 9e 02 39 b0 a3 3f aa  |h@S....+...9..?.|
-00000320  eb ba 9c                                          |...|
+000002f0  00 00 00 a1 73 35 05 15  f3 87 00 58 06 54 f7 44  |....s5.....X.T.D|
+00000300  25 71 3f a6 16 3c e9 95  0a de 14 9d d0 78 73 35  |%q?..<.......xs5|
+00000310  a4 84 dc 9e bf 94 4e fe  07 89 33 d0 81 ef 9f 49  |......N...3....I|
+00000320  17 0a 64                                          |..d|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 40 23 ec df cd 12  |..........@#....|
-00000010  ca 13 f8 b5 75 10 af a0  27 a7 cf f5 d7 a7 46 68  |....u...'.....Fh|
-00000020  44 6b 7e cf 0b ce dc 86  5f b7 35 16 5f 01 ae c9  |Dk~....._.5._...|
-00000030  16 15 ae 4c 9e 7a ca 8e  ae dd cb ec 24 32 32 9c  |...L.z......$22.|
-00000040  b4 b7 61 78 18 0b ee 61  74 6d 0b                 |..ax...atm.|
+00000000  14 03 03 00 01 01 16 03  03 00 40 19 b8 9d de 48  |..........@....H|
+00000010  86 1e be b4 62 54 57 12  fc f0 ad fd 70 b7 69 48  |....bTW.....p.iH|
+00000020  58 66 8e 68 1c fd 73 62  da bd 6d 8f 83 8c 09 91  |Xf.h..sb..m.....|
+00000030  de 53 83 20 2b 81 f1 30  3f 0b 6b 7d c1 59 47 dc  |.S. +..0?.k}.YG.|
+00000040  e1 f4 95 85 d5 0b 09 45  4e a7 2f                 |.......EN./|
 >>> Flow 5 (client to server)
 00000000  17 03 03 00 30 00 00 00  00 00 00 00 00 00 00 00  |....0...........|
-00000010  00 00 00 00 00 d7 7d 87  ac 42 06 f2 4e d3 71 0c  |......}..B..N.q.|
-00000020  1b 62 8c 81 03 38 85 7e  6c 31 ae 8c b4 04 2f 19  |.b...8.~l1..../.|
-00000030  b1 c8 6c a2 6c 15 03 03  00 30 00 00 00 00 00 00  |..l.l....0......|
-00000040  00 00 00 00 00 00 00 00  00 00 99 e8 4b a9 33 ec  |............K.3.|
-00000050  f4 5e 60 5b c0 72 ef 61  6c e2 e0 5b 4d af f8 c6  |.^`[.r.al..[M...|
-00000060  b6 57 be 07 a3 c0 fe cd  29 65                    |.W......)e|
+00000010  00 00 00 00 00 69 73 64  71 d8 dc 9b a5 ce 9a 1e  |.....isdq.......|
+00000020  65 82 01 94 45 12 e7 13  4e 3e 59 7b 19 2b 41 a7  |e...E...N>Y{.+A.|
+00000030  49 aa 70 1d ce 15 03 03  00 30 00 00 00 00 00 00  |I.p......0......|
+00000040  00 00 00 00 00 00 00 00  00 00 5f 67 8d e3 77 5e  |.........._g..w^|
+00000050  32 c4 83 91 2b e6 37 76  18 11 8d 9f e5 c2 20 43  |2...+.7v...... C|
+00000060  c1 68 83 f9 e6 0b 07 95  ef b6                    |.h........|
index f8f121234d7c343e57ddb8d4b154b49269f6b839..dc56555cf1dc51308dcd3dbccfdbba6c94d9c79d 100644 (file)
@@ -1,66 +1,66 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 70 01 00 00  6c 03 03 00 00 00 00 00  |....p...l.......|
+00000000  16 03 01 00 75 01 00 00  71 03 03 00 00 00 00 00  |....u...q.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
 00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
-00000040  00 2f 00 35 c0 12 00 0a  01 00 00 29 00 05 00 05  |./.5.......)....|
+00000040  00 2f 00 35 c0 12 00 0a  01 00 00 2e 00 05 00 05  |./.5............|
 00000050  01 00 00 00 00 00 0a 00  08 00 06 00 17 00 18 00  |................|
 00000060  19 00 0b 00 02 01 00 00  0d 00 0a 00 08 04 01 04  |................|
-00000070  03 02 01 02 03                                    |.....|
+00000070  03 02 01 02 03 ff 01 00  01 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 4a 02 00 00  46 03 03 52 ac 77 f7 91  |....J...F..R.w..|
-00000010  73 b5 51 be 27 c7 ba 60  72 d9 ca 1f f6 7e a2 c2  |s.Q.'..`r....~..|
-00000020  ec 8a 16 39 9a 30 c8 46  3f 34 e8 20 90 e8 71 aa  |...9.0.F?4. ..q.|
-00000030  9f 0a fe 6f f1 9c 5c 8d  10 51 45 ea 90 ef f8 6e  |...o..\..QE....n|
-00000040  88 ba 7e 37 00 e8 66 b9  53 6f 89 dc 00 05 00 16  |..~7..f.So......|
-00000050  03 03 02 be 0b 00 02 ba  00 02 b7 00 02 b4 30 82  |..............0.|
-00000060  02 b0 30 82 02 19 a0 03  02 01 02 02 09 00 85 b0  |..0.............|
-00000070  bb a4 8a 7f b8 ca 30 0d  06 09 2a 86 48 86 f7 0d  |......0...*.H...|
-00000080  01 01 05 05 00 30 45 31  0b 30 09 06 03 55 04 06  |.....0E1.0...U..|
-00000090  13 02 41 55 31 13 30 11  06 03 55 04 08 13 0a 53  |..AU1.0...U....S|
-000000a0  6f 6d 65 2d 53 74 61 74  65 31 21 30 1f 06 03 55  |ome-State1!0...U|
-000000b0  04 0a 13 18 49 6e 74 65  72 6e 65 74 20 57 69 64  |....Internet Wid|
-000000c0  67 69 74 73 20 50 74 79  20 4c 74 64 30 1e 17 0d  |gits Pty Ltd0...|
-000000d0  31 30 30 34 32 34 30 39  30 39 33 38 5a 17 0d 31  |100424090938Z..1|
-000000e0  31 30 34 32 34 30 39 30  39 33 38 5a 30 45 31 0b  |10424090938Z0E1.|
-000000f0  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-00000100  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-00000110  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-00000120  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-00000130  4c 74 64 30 81 9f 30 0d  06 09 2a 86 48 86 f7 0d  |Ltd0..0...*.H...|
-00000140  01 01 01 05 00 03 81 8d  00 30 81 89 02 81 81 00  |.........0......|
-00000150  bb 79 d6 f5 17 b5 e5 bf  46 10 d0 dc 69 be e6 2b  |.y......F...i..+|
-00000160  07 43 5a d0 03 2d 8a 7a  43 85 b7 14 52 e7 a5 65  |.CZ..-.zC...R..e|
-00000170  4c 2c 78 b8 23 8c b5 b4  82 e5 de 1f 95 3b 7e 62  |L,x.#........;~b|
-00000180  a5 2c a5 33 d6 fe 12 5c  7a 56 fc f5 06 bf fa 58  |.,.3...\zV.....X|
-00000190  7b 26 3f b5 cd 04 d3 d0  c9 21 96 4a c7 f4 54 9f  |{&?......!.J..T.|
-000001a0  5a bf ef 42 71 00 fe 18  99 07 7f 7e 88 7d 7d f1  |Z..Bq......~.}}.|
-000001b0  04 39 c4 a2 2e db 51 c9  7c e3 c0 4c 3b 32 66 01  |.9....Q.|..L;2f.|
-000001c0  cf af b1 1d b8 71 9a 1d  db db 89 6b ae da 2d 79  |.....q.....k..-y|
-000001d0  02 03 01 00 01 a3 81 a7  30 81 a4 30 1d 06 03 55  |........0..0...U|
-000001e0  1d 0e 04 16 04 14 b1 ad  e2 85 5a cf cb 28 db 69  |..........Z..(.i|
-000001f0  ce 23 69 de d3 26 8e 18  88 39 30 75 06 03 55 1d  |.#i..&...90u..U.|
-00000200  23 04 6e 30 6c 80 14 b1  ad e2 85 5a cf cb 28 db  |#.n0l......Z..(.|
-00000210  69 ce 23 69 de d3 26 8e  18 88 39 a1 49 a4 47 30  |i.#i..&...9.I.G0|
-00000220  45 31 0b 30 09 06 03 55  04 06 13 02 41 55 31 13  |E1.0...U....AU1.|
-00000230  30 11 06 03 55 04 08 13  0a 53 6f 6d 65 2d 53 74  |0...U....Some-St|
-00000240  61 74 65 31 21 30 1f 06  03 55 04 0a 13 18 49 6e  |ate1!0...U....In|
-00000250  74 65 72 6e 65 74 20 57  69 64 67 69 74 73 20 50  |ternet Widgits P|
-00000260  74 79 20 4c 74 64 82 09  00 85 b0 bb a4 8a 7f b8  |ty Ltd..........|
-00000270  ca 30 0c 06 03 55 1d 13  04 05 30 03 01 01 ff 30  |.0...U....0....0|
-00000280  0d 06 09 2a 86 48 86 f7  0d 01 01 05 05 00 03 81  |...*.H..........|
-00000290  81 00 08 6c 45 24 c7 6b  b1 59 ab 0c 52 cc f2 b0  |...lE$.k.Y..R...|
-000002a0  14 d7 87 9d 7a 64 75 b5  5a 95 66 e4 c5 2b 8e ae  |....zdu.Z.f..+..|
-000002b0  12 66 1f eb 4f 38 b3 6e  60 d3 92 fd f7 41 08 b5  |.f..O8.n`....A..|
-000002c0  25 13 b1 18 7a 24 fb 30  1d ba ed 98 b9 17 ec e7  |%...z$.0........|
-000002d0  d7 31 59 db 95 d3 1d 78  ea 50 56 5c d5 82 5a 2d  |.1Y....x.PV\..Z-|
-000002e0  5a 5f 33 c4 b6 d8 c9 75  90 96 8c 0f 52 98 b5 cd  |Z_3....u....R...|
-000002f0  98 1f 89 20 5f f2 a0 1c  a3 1b 96 94 dd a9 fd 57  |... _..........W|
-00000300  e9 70 e8 26 6d 71 99 9b  26 6e 38 50 29 6c 90 a7  |.p.&mq..&n8P)l..|
-00000310  bd d9 16 03 03 00 30 0d  00 00 28 03 01 02 40 00  |......0...(...@.|
-00000320  20 06 01 06 02 06 03 05  01 05 02 05 03 04 01 04  | ...............|
-00000330  02 04 03 03 01 03 02 03  03 02 01 02 02 02 03 01  |................|
-00000340  01 00 00 0e 00 00 00                              |.......|
+00000000  16 03 03 00 51 02 00 00  4d 03 03 52 cc 57 58 8f  |....Q...M..R.WX.|
+00000010  4b 2e 8c 90 dd 88 33 43  44 02 90 c0 b5 ae b3 b2  |K.....3CD.......|
+00000020  c9 2c cd c4 53 8e 7e 5c  de 08 fe 20 ee 4e 7b b1  |.,..S.~\... .N{.|
+00000030  7e a2 eb b0 21 e3 b2 1e  b5 18 ff b3 43 c8 a7 a3  |~...!.......C...|
+00000040  2f ef 82 11 ae 66 be c5  64 5d 15 59 00 05 00 00  |/....f..d].Y....|
+00000050  05 ff 01 00 01 00 16 03  03 02 be 0b 00 02 ba 00  |................|
+00000060  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
+00000070  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
+00000080  09 2a 86 48 86 f7 0d 01  01 05 05 00 30 45 31 0b  |.*.H........0E1.|
+00000090  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
+000000a0  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
+000000b0  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
+000000c0  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
+000000d0  4c 74 64 30 1e 17 0d 31  30 30 34 32 34 30 39 30  |Ltd0...100424090|
+000000e0  39 33 38 5a 17 0d 31 31  30 34 32 34 30 39 30 39  |938Z..1104240909|
+000000f0  33 38 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |38Z0E1.0...U....|
+00000100  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
+00000110  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
+00000120  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
+00000130  74 73 20 50 74 79 20 4c  74 64 30 81 9f 30 0d 06  |ts Pty Ltd0..0..|
+00000140  09 2a 86 48 86 f7 0d 01  01 01 05 00 03 81 8d 00  |.*.H............|
+00000150  30 81 89 02 81 81 00 bb  79 d6 f5 17 b5 e5 bf 46  |0.......y......F|
+00000160  10 d0 dc 69 be e6 2b 07  43 5a d0 03 2d 8a 7a 43  |...i..+.CZ..-.zC|
+00000170  85 b7 14 52 e7 a5 65 4c  2c 78 b8 23 8c b5 b4 82  |...R..eL,x.#....|
+00000180  e5 de 1f 95 3b 7e 62 a5  2c a5 33 d6 fe 12 5c 7a  |....;~b.,.3...\z|
+00000190  56 fc f5 06 bf fa 58 7b  26 3f b5 cd 04 d3 d0 c9  |V.....X{&?......|
+000001a0  21 96 4a c7 f4 54 9f 5a  bf ef 42 71 00 fe 18 99  |!.J..T.Z..Bq....|
+000001b0  07 7f 7e 88 7d 7d f1 04  39 c4 a2 2e db 51 c9 7c  |..~.}}..9....Q.||
+000001c0  e3 c0 4c 3b 32 66 01 cf  af b1 1d b8 71 9a 1d db  |..L;2f......q...|
+000001d0  db 89 6b ae da 2d 79 02  03 01 00 01 a3 81 a7 30  |..k..-y........0|
+000001e0  81 a4 30 1d 06 03 55 1d  0e 04 16 04 14 b1 ad e2  |..0...U.........|
+000001f0  85 5a cf cb 28 db 69 ce  23 69 de d3 26 8e 18 88  |.Z..(.i.#i..&...|
+00000200  39 30 75 06 03 55 1d 23  04 6e 30 6c 80 14 b1 ad  |90u..U.#.n0l....|
+00000210  e2 85 5a cf cb 28 db 69  ce 23 69 de d3 26 8e 18  |..Z..(.i.#i..&..|
+00000220  88 39 a1 49 a4 47 30 45  31 0b 30 09 06 03 55 04  |.9.I.G0E1.0...U.|
+00000230  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
+00000240  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
+00000250  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
+00000260  64 67 69 74 73 20 50 74  79 20 4c 74 64 82 09 00  |dgits Pty Ltd...|
+00000270  85 b0 bb a4 8a 7f b8 ca  30 0c 06 03 55 1d 13 04  |........0...U...|
+00000280  05 30 03 01 01 ff 30 0d  06 09 2a 86 48 86 f7 0d  |.0....0...*.H...|
+00000290  01 01 05 05 00 03 81 81  00 08 6c 45 24 c7 6b b1  |..........lE$.k.|
+000002a0  59 ab 0c 52 cc f2 b0 14  d7 87 9d 7a 64 75 b5 5a  |Y..R.......zdu.Z|
+000002b0  95 66 e4 c5 2b 8e ae 12  66 1f eb 4f 38 b3 6e 60  |.f..+...f..O8.n`|
+000002c0  d3 92 fd f7 41 08 b5 25  13 b1 18 7a 24 fb 30 1d  |....A..%...z$.0.|
+000002d0  ba ed 98 b9 17 ec e7 d7  31 59 db 95 d3 1d 78 ea  |........1Y....x.|
+000002e0  50 56 5c d5 82 5a 2d 5a  5f 33 c4 b6 d8 c9 75 90  |PV\..Z-Z_3....u.|
+000002f0  96 8c 0f 52 98 b5 cd 98  1f 89 20 5f f2 a0 1c a3  |...R...... _....|
+00000300  1b 96 94 dd a9 fd 57 e9  70 e8 26 6d 71 99 9b 26  |......W.p.&mq..&|
+00000310  6e 38 50 29 6c 90 a7 bd  d9 16 03 03 00 30 0d 00  |n8P)l........0..|
+00000320  00 28 03 01 02 40 00 20  06 01 06 02 06 03 05 01  |.(...@. ........|
+00000330  05 02 05 03 04 01 04 02  04 03 03 01 03 02 03 03  |................|
+00000340  02 01 02 02 02 03 01 01  00 00 0e 00 00 00        |..............|
 >>> Flow 3 (client to server)
 00000000  16 03 03 01 fb 0b 00 01  f7 00 01 f4 00 01 f1 30  |...............0|
 00000010  82 01 ed 30 82 01 58 a0  03 02 01 02 02 01 00 30  |...0..X........0|
 00000260  e6 bd 77 82 6f 23 b6 e0  bd a2 92 b7 3a ac e8 56  |..w.o#......:..V|
 00000270  f1 af 54 5e 46 87 e9 3b  33 e7 b8 28 b7 d6 c8 90  |..T^F..;3..(....|
 00000280  35 d4 1c 43 d1 30 6f 55  4e 0a 70 16 03 03 00 88  |5..C.0oUN.p.....|
-00000290  0f 00 00 84 04 01 00 80  1d 50 f8 65 0a 2e e7 b8  |.........P.e....|
-000002a0  4e 52 51 05 bd 9f 4f 7a  31 67 dd 6c 34 ea 45 30  |NRQ...Oz1g.l4.E0|
-000002b0  57 0b ac a0 9c 41 f5 d7  82 1a fe 7d 3f 5d d4 b9  |W....A.....}?]..|
-000002c0  38 b0 3d 0c f3 57 ff 8e  e8 52 3d be 91 54 c5 49  |8.=..W...R=..T.I|
-000002d0  38 63 9e b8 8a 17 b5 36  29 e1 22 f5 a9 b8 f3 1a  |8c.....6).".....|
-000002e0  98 ab c3 32 3c 36 70 45  b0 25 e4 8c b7 e8 2c ea  |...2<6pE.%....,.|
-000002f0  cf 62 cd c0 69 6d 35 c4  3b 77 4d 90 5a ba 35 de  |.b..im5.;wM.Z.5.|
-00000300  6f 1d d3 ab bb e8 77 e7  83 6c b6 3c b3 ab b2 7e  |o.....w..l.<...~|
-00000310  f4 52 b4 e0 5f c9 9e 0d  14 03 03 00 01 01 16 03  |.R.._...........|
-00000320  03 00 24 8c 9a a2 e5 d5  9c af dc 73 d9 aa 86 a2  |..$........s....|
-00000330  f5 ff 2f 66 f1 5f 1e 65  4f ba 57 37 4f 6d 3b 47  |../f._.eO.W7Om;G|
-00000340  24 27 74 ca 91 3e e1                              |$'t..>.|
+00000290  0f 00 00 84 04 01 00 80  0a eb 78 3e 77 c5 9c 8e  |..........x>w...|
+000002a0  05 67 4e 06 bd ec c8 7c  b2 16 13 7d c5 5d e1 1a  |.gN....|...}.]..|
+000002b0  4d 2e f4 b1 78 2c 94 1b  47 e4 3e 2f 7e 74 cc 03  |M...x,..G.>/~t..|
+000002c0  1d eb e2 56 99 0e 92 27  79 e4 7e a7 12 86 88 91  |...V...'y.~.....|
+000002d0  a4 99 db 1d 50 62 88 41  cc a6 b7 90 d0 51 66 47  |....Pb.A.....QfG|
+000002e0  92 39 a0 2b 4c 8d 50 a6  af f4 72 2d 16 3b 6b b8  |.9.+L.P...r-.;k.|
+000002f0  82 d2 9a d8 cd 7b b9 aa  82 a5 31 12 9e bb 19 23  |.....{....1....#|
+00000300  15 5d ad a5 b1 65 c1 de  01 7d e3 d3 16 73 28 d6  |.]...e...}...s(.|
+00000310  75 02 32 68 5a e0 b1 bb  14 03 03 00 01 01 16 03  |u.2hZ...........|
+00000320  03 00 24 cd c6 25 df 1c  0b b3 a7 2a 46 99 b8 10  |..$..%.....*F...|
+00000330  37 78 40 2a aa 66 7a 3a  34 8e 87 bf 85 4c e2 de  |7x@*.fz:4....L..|
+00000340  36 62 4a 9e 7f e8 e8                              |6bJ....|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 24 a0 10 09 ea 2c  |..........$....,|
-00000010  f5 7c 55 41 84 35 47 d6  7d 75 09 fc 1a d7 b7 da  |.|UA.5G.}u......|
-00000020  8f e0 2d fb c8 a5 9e 71  12 1e eb 64 6b bb ae     |..-....q...dk..|
+00000000  14 03 03 00 01 01 16 03  03 00 24 20 68 ec 6b 11  |..........$ h.k.|
+00000010  e5 d6 eb c7 4f 7f e0 d0  c4 36 d4 c2 46 06 1d 92  |....O....6..F...|
+00000020  83 b4 77 e2 58 b6 cb 06  74 0a 5c f8 c6 06 83     |..w.X...t.\....|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 1a dd 2a cd  81 c7 ed c5 29 5f ef b2  |......*.....)_..|
-00000010  f2 34 9e bb cb 00 75 8b  d5 3e a6 3e b8 42 cd 15  |.4....u..>.>.B..|
-00000020  03 03 00 16 d5 4d e2 8f  8d f1 be 2d 85 fe 49 8a  |.....M.....-..I.|
-00000030  8d f8 df ca e4 ed d0 22  72 e0                    |......."r.|
+00000000  17 03 03 00 1a bb d6 71  f3 e0 2f c3 d6 0d 70 85  |.......q../...p.|
+00000010  25 df 6f ba b1 37 dd 49  42 79 5c b3 c1 85 7e 15  |%.o..7.IBy\...~.|
+00000020  03 03 00 16 8c 93 50 30  45 38 da e2 bf c6 df d8  |......P0E8......|
+00000030  41 e1 63 ca 28 82 d1 ae  30 76                    |A.c.(...0v|
index 5ca0bbff05d6f6508a8ab84a633fc1016066647e..47bbebfc45799a7db74a13a04fe399067c05c8b1 100644 (file)
@@ -1,67 +1,67 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 70 01 00 00  6c 03 03 00 00 00 00 00  |....p...l.......|
+00000000  16 03 01 00 75 01 00 00  71 03 03 00 00 00 00 00  |....u...q.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
 00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
-00000040  00 2f 00 35 c0 12 00 0a  01 00 00 29 00 05 00 05  |./.5.......)....|
+00000040  00 2f 00 35 c0 12 00 0a  01 00 00 2e 00 05 00 05  |./.5............|
 00000050  01 00 00 00 00 00 0a 00  08 00 06 00 17 00 18 00  |................|
 00000060  19 00 0b 00 02 01 00 00  0d 00 0a 00 08 04 01 04  |................|
-00000070  03 02 01 02 03                                    |.....|
+00000070  03 02 01 02 03 ff 01 00  01 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 54 02 00 00  50 03 03 52 ac 77 f7 5e  |....T...P..R.w.^|
-00000010  12 d1 1a fa 09 d7 e5 3c  eb 34 6f 79 3a 4f e8 7b  |.......<.4oy:O.{|
-00000020  92 d7 bd ff 22 37 21 58  c2 73 c2 20 7e 17 7f 83  |...."7!X.s. ~...|
-00000030  36 9e 12 f1 ce c0 3a b3  02 7f 3f 6d 58 7e 71 fe  |6.....:...?mX~q.|
-00000040  9c ce e2 7e f4 19 92 e3  45 57 69 5e c0 09 00 00  |...~....EWi^....|
-00000050  08 00 0b 00 04 03 00 01  02 16 03 03 02 0e 0b 00  |................|
-00000060  02 0a 00 02 07 00 02 04  30 82 02 00 30 82 01 62  |........0...0..b|
-00000070  02 09 00 b8 bf 2d 47 a0  d2 eb f4 30 09 06 07 2a  |.....-G....0...*|
-00000080  86 48 ce 3d 04 01 30 45  31 0b 30 09 06 03 55 04  |.H.=..0E1.0...U.|
-00000090  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
-000000a0  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
-000000b0  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
-000000c0  64 67 69 74 73 20 50 74  79 20 4c 74 64 30 1e 17  |dgits Pty Ltd0..|
-000000d0  0d 31 32 31 31 32 32 31  35 30 36 33 32 5a 17 0d  |.121122150632Z..|
-000000e0  32 32 31 31 32 30 31 35  30 36 33 32 5a 30 45 31  |221120150632Z0E1|
-000000f0  0b 30 09 06 03 55 04 06  13 02 41 55 31 13 30 11  |.0...U....AU1.0.|
-00000100  06 03 55 04 08 13 0a 53  6f 6d 65 2d 53 74 61 74  |..U....Some-Stat|
-00000110  65 31 21 30 1f 06 03 55  04 0a 13 18 49 6e 74 65  |e1!0...U....Inte|
-00000120  72 6e 65 74 20 57 69 64  67 69 74 73 20 50 74 79  |rnet Widgits Pty|
-00000130  20 4c 74 64 30 81 9b 30  10 06 07 2a 86 48 ce 3d  | Ltd0..0...*.H.=|
-00000140  02 01 06 05 2b 81 04 00  23 03 81 86 00 04 00 c4  |....+...#.......|
-00000150  a1 ed be 98 f9 0b 48 73  36 7e c3 16 56 11 22 f2  |......Hs6~..V.".|
-00000160  3d 53 c3 3b 4d 21 3d cd  6b 75 e6 f6 b0 dc 9a df  |=S.;M!=.ku......|
-00000170  26 c1 bc b2 87 f0 72 32  7c b3 64 2f 1c 90 bc ea  |&.....r2|.d/....|
-00000180  68 23 10 7e fe e3 25 c0  48 3a 69 e0 28 6d d3 37  |h#.~..%.H:i.(m.7|
-00000190  00 ef 04 62 dd 0d a0 9c  70 62 83 d8 81 d3 64 31  |...b....pb....d1|
-000001a0  aa 9e 97 31 bd 96 b0 68  c0 9b 23 de 76 64 3f 1a  |...1...h..#.vd?.|
-000001b0  5c 7f e9 12 0e 58 58 b6  5f 70 dd 9b d8 ea d5 d7  |\....XX._p......|
-000001c0  f5 d5 cc b9 b6 9f 30 66  5b 66 9a 20 e2 27 e5 bf  |......0f[f. .'..|
-000001d0  fe 3b 30 09 06 07 2a 86  48 ce 3d 04 01 03 81 8c  |.;0...*.H.=.....|
-000001e0  00 30 81 88 02 42 01 88  a2 4f eb e2 45 c5 48 7d  |.0...B...O..E.H}|
-000001f0  1b ac f5 ed 98 9d ae 47  70 c0 5e 1b b6 2f bd f1  |.......Gp.^../..|
-00000200  b6 4d b7 61 40 d3 11 a2  ce ee 0b 7e 92 7e ff 76  |.M.a@......~.~.v|
-00000210  9d c3 3b 7e a5 3f ce fa  10 e2 59 ec 47 2d 7c ac  |..;~.?....Y.G-|.|
-00000220  da 4e 97 0e 15 a0 6f d0  02 42 01 4d fc be 67 13  |.N....o..B.M..g.|
-00000230  9c 2d 05 0e bd 3f a3 8c  25 c1 33 13 83 0d 94 06  |.-...?..%.3.....|
-00000240  bb d4 37 7a f6 ec 7a c9  86 2e dd d7 11 69 7f 85  |..7z..z......i..|
-00000250  7c 56 de fb 31 78 2b e4  c7 78 0d ae cb be 9e 4e  ||V..1x+..x.....N|
-00000260  36 24 31 7b 6a 0f 39 95  12 07 8f 2a 16 03 03 00  |6$1{j.9....*....|
-00000270  d8 0c 00 00 d4 03 00 17  41 04 81 cc fd bd 41 23  |........A.....A#|
-00000280  dc cb a6 e5 8f 0b c9 bc  8a 0b 4a 26 e0 a6 5f 89  |..........J&.._.|
-00000290  a0 10 50 41 4b a9 80 f1  bf c1 a0 c0 e1 97 40 47  |..PAK.........@G|
-000002a0  f1 98 10 b2 73 a7 40 e6  8b 15 ed 83 37 4f 32 b9  |....s.@.....7O2.|
-000002b0  1f 0b 91 11 33 46 70 15  35 4d 04 03 00 8b 30 81  |....3Fp.5M....0.|
-000002c0  88 02 42 00 84 b5 7e 53  1d 32 a2 88 19 e6 bc a8  |..B...~S.2......|
-000002d0  8a b9 e8 13 af 63 8c a2  af 39 3b e0 dc d3 13 f9  |.....c...9;.....|
-000002e0  ec fe 4b 4a e1 7c 59 0a  ae 98 0c 5e ec 9b 33 d2  |..KJ.|Y....^..3.|
-000002f0  b4 ff 9a ed de 5a be 21  29 ad a6 e6 d5 c4 63 ae  |.....Z.!).....c.|
-00000300  b2 cd 8a dd 26 02 42 01  29 f0 0a 38 4d 14 ca 41  |....&.B.)..8M..A|
-00000310  89 02 31 2e 37 46 1f 60  f8 8d 4a 11 8e 86 a1 80  |..1.7F.`..J.....|
-00000320  10 be 13 79 a0 74 af 43  d8 b1 6e 52 33 3e eb bf  |...y.t.C..nR3>..|
-00000330  39 87 22 53 95 a4 15 1a  e6 d1 90 39 65 ec 75 c0  |9."S.......9e.u.|
-00000340  1c 58 fa 0b f1 83 04 f5  e7 16 03 03 00 04 0e 00  |.X..............|
-00000350  00 00                                             |..|
+00000000  16 03 03 00 59 02 00 00  55 03 03 52 cc 57 58 4e  |....Y...U..R.WXN|
+00000010  9d 88 aa 42 ea 19 04 55  fe e8 13 0c db 2d a9 70  |...B...U.....-.p|
+00000020  93 85 12 08 d2 15 f6 61  25 84 b7 20 55 a3 15 3b  |.......a%.. U..;|
+00000030  27 48 55 53 d1 23 c5 e8  f4 83 ce 44 db 2c 47 b8  |'HUS.#.....D.,G.|
+00000040  2b 4a 3e be 29 3d 73 76  dc 79 6b 75 c0 09 00 00  |+J>.)=sv.yku....|
+00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
+00000060  03 02 0e 0b 00 02 0a 00  02 07 00 02 04 30 82 02  |.............0..|
+00000070  00 30 82 01 62 02 09 00  b8 bf 2d 47 a0 d2 eb f4  |.0..b.....-G....|
+00000080  30 09 06 07 2a 86 48 ce  3d 04 01 30 45 31 0b 30  |0...*.H.=..0E1.0|
+00000090  09 06 03 55 04 06 13 02  41 55 31 13 30 11 06 03  |...U....AU1.0...|
+000000a0  55 04 08 13 0a 53 6f 6d  65 2d 53 74 61 74 65 31  |U....Some-State1|
+000000b0  21 30 1f 06 03 55 04 0a  13 18 49 6e 74 65 72 6e  |!0...U....Intern|
+000000c0  65 74 20 57 69 64 67 69  74 73 20 50 74 79 20 4c  |et Widgits Pty L|
+000000d0  74 64 30 1e 17 0d 31 32  31 31 32 32 31 35 30 36  |td0...1211221506|
+000000e0  33 32 5a 17 0d 32 32 31  31 32 30 31 35 30 36 33  |32Z..22112015063|
+000000f0  32 5a 30 45 31 0b 30 09  06 03 55 04 06 13 02 41  |2Z0E1.0...U....A|
+00000100  55 31 13 30 11 06 03 55  04 08 13 0a 53 6f 6d 65  |U1.0...U....Some|
+00000110  2d 53 74 61 74 65 31 21  30 1f 06 03 55 04 0a 13  |-State1!0...U...|
+00000120  18 49 6e 74 65 72 6e 65  74 20 57 69 64 67 69 74  |.Internet Widgit|
+00000130  73 20 50 74 79 20 4c 74  64 30 81 9b 30 10 06 07  |s Pty Ltd0..0...|
+00000140  2a 86 48 ce 3d 02 01 06  05 2b 81 04 00 23 03 81  |*.H.=....+...#..|
+00000150  86 00 04 00 c4 a1 ed be  98 f9 0b 48 73 36 7e c3  |...........Hs6~.|
+00000160  16 56 11 22 f2 3d 53 c3  3b 4d 21 3d cd 6b 75 e6  |.V.".=S.;M!=.ku.|
+00000170  f6 b0 dc 9a df 26 c1 bc  b2 87 f0 72 32 7c b3 64  |.....&.....r2|.d|
+00000180  2f 1c 90 bc ea 68 23 10  7e fe e3 25 c0 48 3a 69  |/....h#.~..%.H:i|
+00000190  e0 28 6d d3 37 00 ef 04  62 dd 0d a0 9c 70 62 83  |.(m.7...b....pb.|
+000001a0  d8 81 d3 64 31 aa 9e 97  31 bd 96 b0 68 c0 9b 23  |...d1...1...h..#|
+000001b0  de 76 64 3f 1a 5c 7f e9  12 0e 58 58 b6 5f 70 dd  |.vd?.\....XX._p.|
+000001c0  9b d8 ea d5 d7 f5 d5 cc  b9 b6 9f 30 66 5b 66 9a  |...........0f[f.|
+000001d0  20 e2 27 e5 bf fe 3b 30  09 06 07 2a 86 48 ce 3d  | .'...;0...*.H.=|
+000001e0  04 01 03 81 8c 00 30 81  88 02 42 01 88 a2 4f eb  |......0...B...O.|
+000001f0  e2 45 c5 48 7d 1b ac f5  ed 98 9d ae 47 70 c0 5e  |.E.H}.......Gp.^|
+00000200  1b b6 2f bd f1 b6 4d b7  61 40 d3 11 a2 ce ee 0b  |../...M.a@......|
+00000210  7e 92 7e ff 76 9d c3 3b  7e a5 3f ce fa 10 e2 59  |~.~.v..;~.?....Y|
+00000220  ec 47 2d 7c ac da 4e 97  0e 15 a0 6f d0 02 42 01  |.G-|..N....o..B.|
+00000230  4d fc be 67 13 9c 2d 05  0e bd 3f a3 8c 25 c1 33  |M..g..-...?..%.3|
+00000240  13 83 0d 94 06 bb d4 37  7a f6 ec 7a c9 86 2e dd  |.......7z..z....|
+00000250  d7 11 69 7f 85 7c 56 de  fb 31 78 2b e4 c7 78 0d  |..i..|V..1x+..x.|
+00000260  ae cb be 9e 4e 36 24 31  7b 6a 0f 39 95 12 07 8f  |....N6$1{j.9....|
+00000270  2a 16 03 03 00 d8 0c 00  00 d4 03 00 17 41 04 67  |*............A.g|
+00000280  9e b0 72 cf 69 da 56 8c  d2 8f fb 80 64 bb d2 ec  |..r.i.V.....d...|
+00000290  57 2d 8c 77 b7 5a b5 bc  ae bb 1f de db e7 64 5c  |W-.w.Z........d\|
+000002a0  36 2a 9b cb 92 a7 f1 db  93 76 8c 10 b5 74 ad b5  |6*.......v...t..|
+000002b0  8f c5 79 18 18 e7 92 6f  22 3b 92 47 dc 60 cf 04  |..y....o";.G.`..|
+000002c0  03 00 8b 30 81 88 02 42  01 c9 0b bf 07 18 e3 7d  |...0...B.......}|
+000002d0  26 b0 17 94 70 1d dc e8  6c 9e 45 4f d5 e0 79 00  |&...p...l.EO..y.|
+000002e0  2b 03 90 bb 7a aa 23 01  43 53 a1 d8 9f 81 1f 18  |+...z.#.CS......|
+000002f0  a2 5f 54 fa 7c c3 3a 15  d4 18 38 80 7e de f0 70  |._T.|.:...8.~..p|
+00000300  42 5d 2a 22 74 d1 6c 75  f5 18 02 42 00 a8 0a 3c  |B]*"t.lu...B...<|
+00000310  44 38 fa 3f b7 fc 00 1e  80 30 0d e5 55 87 99 53  |D8.?.....0..U..S|
+00000320  0a ab cd ad dd 1b 72 7f  49 bf 2f 89 74 72 11 3c  |......r.I./.tr.<|
+00000330  6e 49 5e 31 3c 6c f1 bc  90 fc e9 75 95 78 7b 95  |nI^1<l.....u.x{.|
+00000340  6a 8d 4d 51 0f e1 2f d1  9e 7b b7 c1 aa 62 16 03  |j.MQ../..{...b..|
+00000350  03 00 04 0e 00 00 00                              |.......|
 >>> Flow 3 (client to server)
 00000000  16 03 03 00 46 10 00 00  42 41 04 1e 18 37 ef 0d  |....F...BA...7..|
 00000010  19 51 88 35 75 71 b5 e5  54 5b 12 2e 8f 09 67 fd  |.Q.5uq..T[....g.|
 00000030  f1 07 9f 6c 4b 5b 83 56  e2 32 42 e9 58 b6 d7 49  |...lK[.V.2B.X..I|
 00000040  a6 b5 68 1a 41 03 56 6b  dc 5a 89 14 03 03 00 01  |..h.A.Vk.Z......|
 00000050  01 16 03 03 00 40 00 00  00 00 00 00 00 00 00 00  |.....@..........|
-00000060  00 00 00 00 00 00 dd af  5a 6c c7 fb 45 57 e9 0b  |........Zl..EW..|
-00000070  33 b6 a9 42 7e d0 33 79  dc ba d2 9f 07 b2 a5 16  |3..B~.3y........|
-00000080  31 30 5b 72 fb 27 10 ab  0b a9 cb 18 27 6f bd 75  |10[r.'......'o.u|
-00000090  65 a8 94 ba 2d 18                                 |e...-.|
+00000060  00 00 00 00 00 00 ea 9c  f3 e5 4d 7c 48 a5 48 9b  |..........M|H.H.|
+00000070  87 43 2a 6b 74 e4 8e ca  e4 1c c9 87 46 c2 d7 ef  |.C*kt.......F...|
+00000080  5e 8f c8 60 a9 1c 5f 68  c6 a9 7d 39 a5 8d 13 7c  |^..`.._h..}9...||
+00000090  bd 31 6e 19 8d 95                                 |.1n...|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 40 2a 60 dc bf a9  |..........@*`...|
-00000010  7e 5e a9 97 17 ee 1e 62  e8 0f c5 f2 72 1b 11 86  |~^.....b....r...|
-00000020  68 83 49 30 2e d4 08 32  80 16 1d 6a 4a 98 d2 e0  |h.I0...2...jJ...|
-00000030  0b 0c fa 5b 1c 74 b6 83  b8 ec 3d c6 7c f4 c5 f1  |...[.t....=.|...|
-00000040  d9 16 68 cf 32 1b 06 9b  18 fd f6                 |..h.2......|
+00000000  14 03 03 00 01 01 16 03  03 00 40 b1 d2 81 e7 2c  |..........@....,|
+00000010  ae 4a 72 98 91 5a 36 ae  8b 62 4b 58 55 f0 65 30  |.Jr..Z6..bKXU.e0|
+00000020  9a 8d ca 73 13 9f 90 c0  18 fb 10 07 c9 fa 9c aa  |...s............|
+00000030  67 2a 42 90 11 e5 38 7f  2f 35 ac d7 c7 75 cc 84  |g*B...8./5...u..|
+00000040  a4 73 dd 9c f5 0d 3e 5d  25 76 c6                 |.s....>]%v.|
 >>> Flow 5 (client to server)
 00000000  17 03 03 00 30 00 00 00  00 00 00 00 00 00 00 00  |....0...........|
-00000010  00 00 00 00 00 16 b5 36  aa c9 3d 27 04 cf 9f 37  |.......6..='...7|
-00000020  a0 6c 35 d1 d3 dd 5b cf  a1 df aa e0 54 0b 5d d4  |.l5...[.....T.].|
-00000030  b0 d3 44 18 5e 15 03 03  00 30 00 00 00 00 00 00  |..D.^....0......|
-00000040  00 00 00 00 00 00 00 00  00 00 ea de c9 15 ff e6  |................|
-00000050  28 f8 5d c4 2a de 64 64  98 22 1e ea 75 2e a7 72  |(.].*.dd."..u..r|
-00000060  65 95 98 0a e0 96 f4 de  ad 33                    |e........3|
+00000010  00 00 00 00 00 5c f6 d4  35 91 79 5d 47 e6 7d eb  |.....\..5.y]G.}.|
+00000020  a4 ba d8 94 ee 89 71 60  ba 67 e6 58 79 d7 52 38  |......q`.g.Xy.R8|
+00000030  35 07 0a 90 e4 15 03 03  00 30 00 00 00 00 00 00  |5........0......|
+00000040  00 00 00 00 00 00 00 00  00 00 73 92 bf 53 22 d7  |..........s..S".|
+00000050  80 54 7a 1c 77 d9 a5 16  05 68 c7 c7 5b ce 05 41  |.Tz.w....h..[..A|
+00000060  51 d2 a6 2b b9 ba 34 ef  93 5e                    |Q..+..4..^|
index 079ccfd328533cb62b3b5172448b90740293f973..155fab6b2ae30eac2cada2a4f6e7fbcafb84af7f 100644 (file)
@@ -1,84 +1,84 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 70 01 00 00  6c 03 03 00 00 00 00 00  |....p...l.......|
+00000000  16 03 01 00 75 01 00 00  71 03 03 00 00 00 00 00  |....u...q.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
 00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
-00000040  00 2f 00 35 c0 12 00 0a  01 00 00 29 00 05 00 05  |./.5.......)....|
+00000040  00 2f 00 35 c0 12 00 0a  01 00 00 2e 00 05 00 05  |./.5............|
 00000050  01 00 00 00 00 00 0a 00  08 00 06 00 17 00 18 00  |................|
 00000060  19 00 0b 00 02 01 00 00  0d 00 0a 00 08 04 01 04  |................|
-00000070  03 02 01 02 03                                    |.....|
+00000070  03 02 01 02 03 ff 01 00  01 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 54 02 00 00  50 03 03 52 ac 77 f7 a9  |....T...P..R.w..|
-00000010  e1 80 2b b8 c5 87 2e 11  81 69 a3 0c 25 83 bb 69  |..+......i..%..i|
-00000020  4c a0 c9 cf c0 b9 f4 be  7b 8b fc 20 d4 78 d2 91  |L.......{.. .x..|
-00000030  37 58 b2 d6 0a ee 11 5c  31 c6 d3 58 83 38 c3 6a  |7X.....\1..X.8.j|
-00000040  2a da 64 70 02 0f ce f5  65 27 21 76 c0 2b 00 00  |*.dp....e'!v.+..|
-00000050  08 00 0b 00 04 03 00 01  02 16 03 03 02 0e 0b 00  |................|
-00000060  02 0a 00 02 07 00 02 04  30 82 02 00 30 82 01 62  |........0...0..b|
-00000070  02 09 00 b8 bf 2d 47 a0  d2 eb f4 30 09 06 07 2a  |.....-G....0...*|
-00000080  86 48 ce 3d 04 01 30 45  31 0b 30 09 06 03 55 04  |.H.=..0E1.0...U.|
-00000090  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
-000000a0  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
-000000b0  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
-000000c0  64 67 69 74 73 20 50 74  79 20 4c 74 64 30 1e 17  |dgits Pty Ltd0..|
-000000d0  0d 31 32 31 31 32 32 31  35 30 36 33 32 5a 17 0d  |.121122150632Z..|
-000000e0  32 32 31 31 32 30 31 35  30 36 33 32 5a 30 45 31  |221120150632Z0E1|
-000000f0  0b 30 09 06 03 55 04 06  13 02 41 55 31 13 30 11  |.0...U....AU1.0.|
-00000100  06 03 55 04 08 13 0a 53  6f 6d 65 2d 53 74 61 74  |..U....Some-Stat|
-00000110  65 31 21 30 1f 06 03 55  04 0a 13 18 49 6e 74 65  |e1!0...U....Inte|
-00000120  72 6e 65 74 20 57 69 64  67 69 74 73 20 50 74 79  |rnet Widgits Pty|
-00000130  20 4c 74 64 30 81 9b 30  10 06 07 2a 86 48 ce 3d  | Ltd0..0...*.H.=|
-00000140  02 01 06 05 2b 81 04 00  23 03 81 86 00 04 00 c4  |....+...#.......|
-00000150  a1 ed be 98 f9 0b 48 73  36 7e c3 16 56 11 22 f2  |......Hs6~..V.".|
-00000160  3d 53 c3 3b 4d 21 3d cd  6b 75 e6 f6 b0 dc 9a df  |=S.;M!=.ku......|
-00000170  26 c1 bc b2 87 f0 72 32  7c b3 64 2f 1c 90 bc ea  |&.....r2|.d/....|
-00000180  68 23 10 7e fe e3 25 c0  48 3a 69 e0 28 6d d3 37  |h#.~..%.H:i.(m.7|
-00000190  00 ef 04 62 dd 0d a0 9c  70 62 83 d8 81 d3 64 31  |...b....pb....d1|
-000001a0  aa 9e 97 31 bd 96 b0 68  c0 9b 23 de 76 64 3f 1a  |...1...h..#.vd?.|
-000001b0  5c 7f e9 12 0e 58 58 b6  5f 70 dd 9b d8 ea d5 d7  |\....XX._p......|
-000001c0  f5 d5 cc b9 b6 9f 30 66  5b 66 9a 20 e2 27 e5 bf  |......0f[f. .'..|
-000001d0  fe 3b 30 09 06 07 2a 86  48 ce 3d 04 01 03 81 8c  |.;0...*.H.=.....|
-000001e0  00 30 81 88 02 42 01 88  a2 4f eb e2 45 c5 48 7d  |.0...B...O..E.H}|
-000001f0  1b ac f5 ed 98 9d ae 47  70 c0 5e 1b b6 2f bd f1  |.......Gp.^../..|
-00000200  b6 4d b7 61 40 d3 11 a2  ce ee 0b 7e 92 7e ff 76  |.M.a@......~.~.v|
-00000210  9d c3 3b 7e a5 3f ce fa  10 e2 59 ec 47 2d 7c ac  |..;~.?....Y.G-|.|
-00000220  da 4e 97 0e 15 a0 6f d0  02 42 01 4d fc be 67 13  |.N....o..B.M..g.|
-00000230  9c 2d 05 0e bd 3f a3 8c  25 c1 33 13 83 0d 94 06  |.-...?..%.3.....|
-00000240  bb d4 37 7a f6 ec 7a c9  86 2e dd d7 11 69 7f 85  |..7z..z......i..|
-00000250  7c 56 de fb 31 78 2b e4  c7 78 0d ae cb be 9e 4e  ||V..1x+..x.....N|
-00000260  36 24 31 7b 6a 0f 39 95  12 07 8f 2a 16 03 03 00  |6$1{j.9....*....|
-00000270  d7 0c 00 00 d3 03 00 17  41 04 b1 83 29 44 4d 61  |........A...)DMa|
-00000280  7f 14 4e 4f 54 fc 9f fb  01 e7 ab 16 fb 28 20 fc  |..NOT........( .|
-00000290  9a cb 75 50 b0 47 d5 3e  d3 41 0f 0f f7 dd c8 6f  |..uP.G.>.A.....o|
-000002a0  b3 65 e2 e4 c4 2b 74 fa  4e f0 6d 27 5a 1a 5a 69  |.e...+t.N.m'Z.Zi|
-000002b0  9d 44 78 f0 9b ec 4e cc  26 70 04 03 00 8a 30 81  |.Dx...N.&p....0.|
-000002c0  87 02 42 01 16 f4 f8 7a  52 8b 0f 83 75 d9 4f b2  |..B....zR...u.O.|
-000002d0  51 10 1c a6 30 6b ac 30  ab b9 00 38 b9 44 95 47  |Q...0k.0...8.D.G|
-000002e0  4b 80 29 ca 36 f4 b2 86  32 25 14 7b 4a 99 14 18  |K.).6...2%.{J...|
-000002f0  cd 3c 43 68 cb cf d8 cb  12 d8 1c 27 7b 4e de dd  |.<Ch.......'{N..|
-00000300  91 d8 7a 23 de 02 41 4b  33 2b 28 83 e4 47 e9 a7  |..z#..AK3+(..G..|
-00000310  fb aa 8a 3b ee 5e 96 3f  dd 2c c8 cf f4 1f 1d c7  |...;.^.?.,......|
-00000320  c3 41 b5 ba c9 22 d3 5b  7f 11 d9 e6 c5 f3 a7 df  |.A...".[........|
-00000330  bb dd 4f df a0 5f 53 0b  d0 bb 73 84 8a 5c 1c 8f  |..O.._S...s..\..|
-00000340  a7 4c 6e fd 4b fe d5 b1  16 03 03 00 04 0e 00 00  |.Ln.K...........|
-00000350  00                                                |.|
+00000000  16 03 03 00 59 02 00 00  55 03 03 52 cc 57 58 95  |....Y...U..R.WX.|
+00000010  a0 c0 f9 1d 34 16 31 f5  a5 08 dd 3d 6a 4c c9 96  |....4.1....=jL..|
+00000020  aa 8b 7f f3 1e 0c 59 4c  06 c1 2b 20 22 f5 fb 09  |......YL..+ "...|
+00000030  f2 7a c3 22 85 2f 16 b6  81 2d 2b d6 12 c2 4d 84  |.z."./...-+...M.|
+00000040  7e a9 3f 18 f2 1c f7 44  6c 66 3f 7f c0 2b 00 00  |~.?....Dlf?..+..|
+00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
+00000060  03 02 0e 0b 00 02 0a 00  02 07 00 02 04 30 82 02  |.............0..|
+00000070  00 30 82 01 62 02 09 00  b8 bf 2d 47 a0 d2 eb f4  |.0..b.....-G....|
+00000080  30 09 06 07 2a 86 48 ce  3d 04 01 30 45 31 0b 30  |0...*.H.=..0E1.0|
+00000090  09 06 03 55 04 06 13 02  41 55 31 13 30 11 06 03  |...U....AU1.0...|
+000000a0  55 04 08 13 0a 53 6f 6d  65 2d 53 74 61 74 65 31  |U....Some-State1|
+000000b0  21 30 1f 06 03 55 04 0a  13 18 49 6e 74 65 72 6e  |!0...U....Intern|
+000000c0  65 74 20 57 69 64 67 69  74 73 20 50 74 79 20 4c  |et Widgits Pty L|
+000000d0  74 64 30 1e 17 0d 31 32  31 31 32 32 31 35 30 36  |td0...1211221506|
+000000e0  33 32 5a 17 0d 32 32 31  31 32 30 31 35 30 36 33  |32Z..22112015063|
+000000f0  32 5a 30 45 31 0b 30 09  06 03 55 04 06 13 02 41  |2Z0E1.0...U....A|
+00000100  55 31 13 30 11 06 03 55  04 08 13 0a 53 6f 6d 65  |U1.0...U....Some|
+00000110  2d 53 74 61 74 65 31 21  30 1f 06 03 55 04 0a 13  |-State1!0...U...|
+00000120  18 49 6e 74 65 72 6e 65  74 20 57 69 64 67 69 74  |.Internet Widgit|
+00000130  73 20 50 74 79 20 4c 74  64 30 81 9b 30 10 06 07  |s Pty Ltd0..0...|
+00000140  2a 86 48 ce 3d 02 01 06  05 2b 81 04 00 23 03 81  |*.H.=....+...#..|
+00000150  86 00 04 00 c4 a1 ed be  98 f9 0b 48 73 36 7e c3  |...........Hs6~.|
+00000160  16 56 11 22 f2 3d 53 c3  3b 4d 21 3d cd 6b 75 e6  |.V.".=S.;M!=.ku.|
+00000170  f6 b0 dc 9a df 26 c1 bc  b2 87 f0 72 32 7c b3 64  |.....&.....r2|.d|
+00000180  2f 1c 90 bc ea 68 23 10  7e fe e3 25 c0 48 3a 69  |/....h#.~..%.H:i|
+00000190  e0 28 6d d3 37 00 ef 04  62 dd 0d a0 9c 70 62 83  |.(m.7...b....pb.|
+000001a0  d8 81 d3 64 31 aa 9e 97  31 bd 96 b0 68 c0 9b 23  |...d1...1...h..#|
+000001b0  de 76 64 3f 1a 5c 7f e9  12 0e 58 58 b6 5f 70 dd  |.vd?.\....XX._p.|
+000001c0  9b d8 ea d5 d7 f5 d5 cc  b9 b6 9f 30 66 5b 66 9a  |...........0f[f.|
+000001d0  20 e2 27 e5 bf fe 3b 30  09 06 07 2a 86 48 ce 3d  | .'...;0...*.H.=|
+000001e0  04 01 03 81 8c 00 30 81  88 02 42 01 88 a2 4f eb  |......0...B...O.|
+000001f0  e2 45 c5 48 7d 1b ac f5  ed 98 9d ae 47 70 c0 5e  |.E.H}.......Gp.^|
+00000200  1b b6 2f bd f1 b6 4d b7  61 40 d3 11 a2 ce ee 0b  |../...M.a@......|
+00000210  7e 92 7e ff 76 9d c3 3b  7e a5 3f ce fa 10 e2 59  |~.~.v..;~.?....Y|
+00000220  ec 47 2d 7c ac da 4e 97  0e 15 a0 6f d0 02 42 01  |.G-|..N....o..B.|
+00000230  4d fc be 67 13 9c 2d 05  0e bd 3f a3 8c 25 c1 33  |M..g..-...?..%.3|
+00000240  13 83 0d 94 06 bb d4 37  7a f6 ec 7a c9 86 2e dd  |.......7z..z....|
+00000250  d7 11 69 7f 85 7c 56 de  fb 31 78 2b e4 c7 78 0d  |..i..|V..1x+..x.|
+00000260  ae cb be 9e 4e 36 24 31  7b 6a 0f 39 95 12 07 8f  |....N6$1{j.9....|
+00000270  2a 16 03 03 00 d8 0c 00  00 d4 03 00 17 41 04 dd  |*............A..|
+00000280  b5 88 3a be 12 a5 fe 0e  19 f5 76 4f 71 90 93 ca  |..:.......vOq...|
+00000290  0e b3 62 a2 b0 c0 f2 78  95 90 cb 10 f9 e8 c8 8e  |..b....x........|
+000002a0  a6 5e 48 ae 8e 96 3d 60  3f 0a b0 73 e8 ea 42 42  |.^H...=`?..s..BB|
+000002b0  6e 19 fe e3 ab 30 ff 01  cc ae c1 90 3a 10 85 04  |n....0......:...|
+000002c0  03 00 8b 30 81 88 02 42  01 6e b2 79 a1 c1 45 7d  |...0...B.n.y..E}|
+000002d0  a3 44 45 75 e0 05 b6 68  ee e3 bb 80 2d 88 23 0c  |.DEu...h....-.#.|
+000002e0  40 ad 68 95 59 0f 49 5b  e5 67 2a 5a 9b 29 32 38  |@.h.Y.I[.g*Z.)28|
+000002f0  13 a0 f1 6c 11 3f 23 b9  1b 4b 0c 1f 2d 61 5e b3  |...l.?#..K..-a^.|
+00000300  de 14 b7 b8 a6 fb 7b 23  1f f3 02 42 01 30 39 22  |......{#...B.09"|
+00000310  01 6f d7 a2 83 2a fd 8a  6f f0 c2 d6 1b 0f b4 17  |.o...*..o.......|
+00000320  d3 50 f7 de 59 20 6a 5c  a1 93 65 ed aa fa 8f 6f  |.P..Y j\..e....o|
+00000330  75 3a b6 ab 33 b6 68 26  0b 8f d5 b2 ca eb 86 27  |u:..3.h&.......'|
+00000340  27 72 68 ed ee 42 37 1a  ff 8a 68 c3 32 91 16 03  |'rh..B7...h.2...|
+00000350  03 00 04 0e 00 00 00                              |.......|
 >>> Flow 3 (client to server)
 00000000  16 03 03 00 46 10 00 00  42 41 04 1e 18 37 ef 0d  |....F...BA...7..|
 00000010  19 51 88 35 75 71 b5 e5  54 5b 12 2e 8f 09 67 fd  |.Q.5uq..T[....g.|
 00000020  a7 24 20 3e b2 56 1c ce  97 28 5e f8 2b 2d 4f 9e  |.$ >.V...(^.+-O.|
 00000030  f1 07 9f 6c 4b 5b 83 56  e2 32 42 e9 58 b6 d7 49  |...lK[.V.2B.X..I|
 00000040  a6 b5 68 1a 41 03 56 6b  dc 5a 89 14 03 03 00 01  |..h.A.Vk.Z......|
-00000050  01 16 03 03 00 28 00 00  00 00 00 00 00 00 cd 30  |.....(.........0|
-00000060  fd 7f db 2c e9 5d df be  c1 6d ee 15 44 e3 04 f4  |...,.]...m..D...|
-00000070  4c 32 e8 05 65 65 8f 20  93 4b 7a b2 29 e6        |L2..ee. .Kz.).|
+00000050  01 16 03 03 00 28 00 00  00 00 00 00 00 00 8c c6  |.....(..........|
+00000060  b4 4f c9 4b f0 81 05 aa  aa 88 79 b0 76 fb 56 8a  |.O.K......y.v.V.|
+00000070  d3 8f 14 ff e2 9b a3 f6  92 77 aa cf f3 4e        |.........w...N|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 28 fb ad f8 e3 77  |..........(....w|
-00000010  e2 56 68 41 49 cb 4c 7b  1d 1e c4 2f 0b d2 3f 45  |.VhAI.L{.../..?E|
-00000020  e5 ec a0 72 bd 77 f7 c3  be 17 39 e2 ff 03 36 ee  |...r.w....9...6.|
-00000030  39 b0 9f                                          |9..|
+00000000  14 03 03 00 01 01 16 03  03 00 28 ca a5 27 78 fb  |..........(..'x.|
+00000010  e9 66 83 4d 71 62 d4 37  2f 01 5c 8b 67 52 98 5d  |.f.Mqb.7/.\.gR.]|
+00000020  0d a0 94 53 c1 b5 25 00  e2 42 ab 37 67 2e 12 eb  |...S..%..B.7g...|
+00000030  35 a3 9a                                          |5..|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 cc 1e ea  |................|
-00000010  a9 11 7d 34 9d 73 f0 5d  76 e6 3a bf 76 9b 71 45  |..}4.s.]v.:.v.qE|
-00000020  84 4b 37 15 03 03 00 1a  00 00 00 00 00 00 00 02  |.K7.............|
-00000030  a4 98 0c 9a 61 5f 58 48  98 b5 eb 9a 67 93 3e 6a  |....a_XH....g.>j|
-00000040  7d 49                                             |}I|
+00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 e0 be 1e  |................|
+00000010  a7 0f 73 a6 25 ca 9e d3  0a ad 6b e7 e9 db 21 a1  |..s.%.....k...!.|
+00000020  70 5f c1 15 03 03 00 1a  00 00 00 00 00 00 00 02  |p_..............|
+00000030  c3 af f9 8c 63 94 cb e4  99 6d b7 32 80 22 f7 1f  |....c....m.2."..|
+00000040  02 87                                             |..|
index 158c63a150ae2b1d592808a9d03f33f84f0a867f..ae137d878451ffdc296474d68b76dff95ede95ad 100644 (file)
@@ -1,77 +1,77 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 70 01 00 00  6c 03 03 00 00 00 00 00  |....p...l.......|
+00000000  16 03 01 00 75 01 00 00  71 03 03 00 00 00 00 00  |....u...q.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
 00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
-00000040  00 2f 00 35 c0 12 00 0a  01 00 00 29 00 05 00 05  |./.5.......)....|
+00000040  00 2f 00 35 c0 12 00 0a  01 00 00 2e 00 05 00 05  |./.5............|
 00000050  01 00 00 00 00 00 0a 00  08 00 06 00 17 00 18 00  |................|
 00000060  19 00 0b 00 02 01 00 00  0d 00 0a 00 08 04 01 04  |................|
-00000070  03 02 01 02 03                                    |.....|
+00000070  03 02 01 02 03 ff 01 00  01 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 54 02 00 00  50 03 03 52 ac 77 f7 63  |....T...P..R.w.c|
-00000010  0f 46 31 fc 9b 1f 13 19  98 13 0f dc f0 99 40 1c  |.F1...........@.|
-00000020  a4 72 1a 73 39 8e 49 d8  bc c6 60 20 80 ba 81 b5  |.r.s9.I...` ....|
-00000030  fb 17 2e 41 f4 e3 26 4b  2e ab 4f e0 10 d6 fd 46  |...A..&K..O....F|
-00000040  b6 1e 94 ef 5f 66 34 21  e0 27 71 b9 c0 13 00 00  |...._f4!.'q.....|
-00000050  08 00 0b 00 04 03 00 01  02 16 03 03 02 be 0b 00  |................|
-00000060  02 ba 00 02 b7 00 02 b4  30 82 02 b0 30 82 02 19  |........0...0...|
-00000070  a0 03 02 01 02 02 09 00  85 b0 bb a4 8a 7f b8 ca  |................|
-00000080  30 0d 06 09 2a 86 48 86  f7 0d 01 01 05 05 00 30  |0...*.H........0|
-00000090  45 31 0b 30 09 06 03 55  04 06 13 02 41 55 31 13  |E1.0...U....AU1.|
-000000a0  30 11 06 03 55 04 08 13  0a 53 6f 6d 65 2d 53 74  |0...U....Some-St|
-000000b0  61 74 65 31 21 30 1f 06  03 55 04 0a 13 18 49 6e  |ate1!0...U....In|
-000000c0  74 65 72 6e 65 74 20 57  69 64 67 69 74 73 20 50  |ternet Widgits P|
-000000d0  74 79 20 4c 74 64 30 1e  17 0d 31 30 30 34 32 34  |ty Ltd0...100424|
-000000e0  30 39 30 39 33 38 5a 17  0d 31 31 30 34 32 34 30  |090938Z..1104240|
-000000f0  39 30 39 33 38 5a 30 45  31 0b 30 09 06 03 55 04  |90938Z0E1.0...U.|
-00000100  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
-00000110  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
-00000120  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
-00000130  64 67 69 74 73 20 50 74  79 20 4c 74 64 30 81 9f  |dgits Pty Ltd0..|
-00000140  30 0d 06 09 2a 86 48 86  f7 0d 01 01 01 05 00 03  |0...*.H.........|
-00000150  81 8d 00 30 81 89 02 81  81 00 bb 79 d6 f5 17 b5  |...0.......y....|
-00000160  e5 bf 46 10 d0 dc 69 be  e6 2b 07 43 5a d0 03 2d  |..F...i..+.CZ..-|
-00000170  8a 7a 43 85 b7 14 52 e7  a5 65 4c 2c 78 b8 23 8c  |.zC...R..eL,x.#.|
-00000180  b5 b4 82 e5 de 1f 95 3b  7e 62 a5 2c a5 33 d6 fe  |.......;~b.,.3..|
-00000190  12 5c 7a 56 fc f5 06 bf  fa 58 7b 26 3f b5 cd 04  |.\zV.....X{&?...|
-000001a0  d3 d0 c9 21 96 4a c7 f4  54 9f 5a bf ef 42 71 00  |...!.J..T.Z..Bq.|
-000001b0  fe 18 99 07 7f 7e 88 7d  7d f1 04 39 c4 a2 2e db  |.....~.}}..9....|
-000001c0  51 c9 7c e3 c0 4c 3b 32  66 01 cf af b1 1d b8 71  |Q.|..L;2f......q|
-000001d0  9a 1d db db 89 6b ae da  2d 79 02 03 01 00 01 a3  |.....k..-y......|
-000001e0  81 a7 30 81 a4 30 1d 06  03 55 1d 0e 04 16 04 14  |..0..0...U......|
-000001f0  b1 ad e2 85 5a cf cb 28  db 69 ce 23 69 de d3 26  |....Z..(.i.#i..&|
-00000200  8e 18 88 39 30 75 06 03  55 1d 23 04 6e 30 6c 80  |...90u..U.#.n0l.|
-00000210  14 b1 ad e2 85 5a cf cb  28 db 69 ce 23 69 de d3  |.....Z..(.i.#i..|
-00000220  26 8e 18 88 39 a1 49 a4  47 30 45 31 0b 30 09 06  |&...9.I.G0E1.0..|
-00000230  03 55 04 06 13 02 41 55  31 13 30 11 06 03 55 04  |.U....AU1.0...U.|
-00000240  08 13 0a 53 6f 6d 65 2d  53 74 61 74 65 31 21 30  |...Some-State1!0|
-00000250  1f 06 03 55 04 0a 13 18  49 6e 74 65 72 6e 65 74  |...U....Internet|
-00000260  20 57 69 64 67 69 74 73  20 50 74 79 20 4c 74 64  | Widgits Pty Ltd|
-00000270  82 09 00 85 b0 bb a4 8a  7f b8 ca 30 0c 06 03 55  |...........0...U|
-00000280  1d 13 04 05 30 03 01 01  ff 30 0d 06 09 2a 86 48  |....0....0...*.H|
-00000290  86 f7 0d 01 01 05 05 00  03 81 81 00 08 6c 45 24  |.............lE$|
-000002a0  c7 6b b1 59 ab 0c 52 cc  f2 b0 14 d7 87 9d 7a 64  |.k.Y..R.......zd|
-000002b0  75 b5 5a 95 66 e4 c5 2b  8e ae 12 66 1f eb 4f 38  |u.Z.f..+...f..O8|
-000002c0  b3 6e 60 d3 92 fd f7 41  08 b5 25 13 b1 18 7a 24  |.n`....A..%...z$|
-000002d0  fb 30 1d ba ed 98 b9 17  ec e7 d7 31 59 db 95 d3  |.0.........1Y...|
-000002e0  1d 78 ea 50 56 5c d5 82  5a 2d 5a 5f 33 c4 b6 d8  |.x.PV\..Z-Z_3...|
-000002f0  c9 75 90 96 8c 0f 52 98  b5 cd 98 1f 89 20 5f f2  |.u....R...... _.|
-00000300  a0 1c a3 1b 96 94 dd a9  fd 57 e9 70 e8 26 6d 71  |.........W.p.&mq|
-00000310  99 9b 26 6e 38 50 29 6c  90 a7 bd d9 16 03 03 00  |..&n8P)l........|
-00000320  cd 0c 00 00 c9 03 00 17  41 04 07 bc 8a ca 81 0b  |........A.......|
-00000330  56 ef fa 13 da 6f 4b 90  77 d7 bc e0 4b b5 50 31  |V....oK.w...K.P1|
-00000340  f4 a4 bf c8 e3 28 32 42  22 ec a3 2e c6 65 21 93  |.....(2B"....e!.|
-00000350  75 26 cf b0 83 68 c4 22  ce 02 7d 9a 5a a4 2a 76  |u&...h."..}.Z.*v|
-00000360  f4 63 d1 97 48 6e 5a 5d  55 af 04 01 00 80 2f 5a  |.c..HnZ]U...../Z|
-00000370  0e 8e a3 98 6c 5d fe 45  c0 a1 80 56 9b a7 cd 3f  |....l].E...V...?|
-00000380  62 5c 65 94 4a b4 00 e1  85 6a 08 9f 21 c7 de f5  |b\e.J....j..!...|
-00000390  32 96 3a e1 24 4c a2 1a  f4 42 eb 26 34 32 98 1f  |2.:.$L...B.&42..|
-000003a0  00 1f 0c 54 ed cd d5 90  32 ac 63 7a 6b 8b 81 22  |...T....2.czk.."|
-000003b0  a0 9a 1b 72 cc b1 ea aa  a8 e5 92 dd 1b 47 59 9f  |...r.........GY.|
-000003c0  2c 0e f4 96 44 ae 40 4b  d2 12 8d 66 f3 13 a2 fe  |,...D.@K...f....|
-000003d0  e8 ec d7 69 5b fe 6b 1b  57 2a b0 e4 4c 9c d8 01  |...i[.k.W*..L...|
-000003e0  fc b6 b1 b6 b5 06 49 2f  a7 65 6c da ac a1 16 03  |......I/.el.....|
-000003f0  03 00 04 0e 00 00 00                              |.......|
+00000000  16 03 03 00 59 02 00 00  55 03 03 52 cc 57 58 64  |....Y...U..R.WXd|
+00000010  28 c0 0d 0a be 3a aa 96  4e 92 8d 9d f2 19 ab de  |(....:..N.......|
+00000020  b2 05 3a 61 13 78 60 7e  96 24 b2 20 a3 06 80 14  |..:a.x`~.$. ....|
+00000030  15 52 89 1b d4 84 94 8b  ed 66 8d 75 63 8f dc 5a  |.R.......f.uc..Z|
+00000040  a8 20 14 65 5d ce 7e 2f  4b 3e 1e 09 c0 13 00 00  |. .e].~/K>......|
+00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
+00000060  03 02 be 0b 00 02 ba 00  02 b7 00 02 b4 30 82 02  |.............0..|
+00000070  b0 30 82 02 19 a0 03 02  01 02 02 09 00 85 b0 bb  |.0..............|
+00000080  a4 8a 7f b8 ca 30 0d 06  09 2a 86 48 86 f7 0d 01  |.....0...*.H....|
+00000090  01 05 05 00 30 45 31 0b  30 09 06 03 55 04 06 13  |....0E1.0...U...|
+000000a0  02 41 55 31 13 30 11 06  03 55 04 08 13 0a 53 6f  |.AU1.0...U....So|
+000000b0  6d 65 2d 53 74 61 74 65  31 21 30 1f 06 03 55 04  |me-State1!0...U.|
+000000c0  0a 13 18 49 6e 74 65 72  6e 65 74 20 57 69 64 67  |...Internet Widg|
+000000d0  69 74 73 20 50 74 79 20  4c 74 64 30 1e 17 0d 31  |its Pty Ltd0...1|
+000000e0  30 30 34 32 34 30 39 30  39 33 38 5a 17 0d 31 31  |00424090938Z..11|
+000000f0  30 34 32 34 30 39 30 39  33 38 5a 30 45 31 0b 30  |0424090938Z0E1.0|
+00000100  09 06 03 55 04 06 13 02  41 55 31 13 30 11 06 03  |...U....AU1.0...|
+00000110  55 04 08 13 0a 53 6f 6d  65 2d 53 74 61 74 65 31  |U....Some-State1|
+00000120  21 30 1f 06 03 55 04 0a  13 18 49 6e 74 65 72 6e  |!0...U....Intern|
+00000130  65 74 20 57 69 64 67 69  74 73 20 50 74 79 20 4c  |et Widgits Pty L|
+00000140  74 64 30 81 9f 30 0d 06  09 2a 86 48 86 f7 0d 01  |td0..0...*.H....|
+00000150  01 01 05 00 03 81 8d 00  30 81 89 02 81 81 00 bb  |........0.......|
+00000160  79 d6 f5 17 b5 e5 bf 46  10 d0 dc 69 be e6 2b 07  |y......F...i..+.|
+00000170  43 5a d0 03 2d 8a 7a 43  85 b7 14 52 e7 a5 65 4c  |CZ..-.zC...R..eL|
+00000180  2c 78 b8 23 8c b5 b4 82  e5 de 1f 95 3b 7e 62 a5  |,x.#........;~b.|
+00000190  2c a5 33 d6 fe 12 5c 7a  56 fc f5 06 bf fa 58 7b  |,.3...\zV.....X{|
+000001a0  26 3f b5 cd 04 d3 d0 c9  21 96 4a c7 f4 54 9f 5a  |&?......!.J..T.Z|
+000001b0  bf ef 42 71 00 fe 18 99  07 7f 7e 88 7d 7d f1 04  |..Bq......~.}}..|
+000001c0  39 c4 a2 2e db 51 c9 7c  e3 c0 4c 3b 32 66 01 cf  |9....Q.|..L;2f..|
+000001d0  af b1 1d b8 71 9a 1d db  db 89 6b ae da 2d 79 02  |....q.....k..-y.|
+000001e0  03 01 00 01 a3 81 a7 30  81 a4 30 1d 06 03 55 1d  |.......0..0...U.|
+000001f0  0e 04 16 04 14 b1 ad e2  85 5a cf cb 28 db 69 ce  |.........Z..(.i.|
+00000200  23 69 de d3 26 8e 18 88  39 30 75 06 03 55 1d 23  |#i..&...90u..U.#|
+00000210  04 6e 30 6c 80 14 b1 ad  e2 85 5a cf cb 28 db 69  |.n0l......Z..(.i|
+00000220  ce 23 69 de d3 26 8e 18  88 39 a1 49 a4 47 30 45  |.#i..&...9.I.G0E|
+00000230  31 0b 30 09 06 03 55 04  06 13 02 41 55 31 13 30  |1.0...U....AU1.0|
+00000240  11 06 03 55 04 08 13 0a  53 6f 6d 65 2d 53 74 61  |...U....Some-Sta|
+00000250  74 65 31 21 30 1f 06 03  55 04 0a 13 18 49 6e 74  |te1!0...U....Int|
+00000260  65 72 6e 65 74 20 57 69  64 67 69 74 73 20 50 74  |ernet Widgits Pt|
+00000270  79 20 4c 74 64 82 09 00  85 b0 bb a4 8a 7f b8 ca  |y Ltd...........|
+00000280  30 0c 06 03 55 1d 13 04  05 30 03 01 01 ff 30 0d  |0...U....0....0.|
+00000290  06 09 2a 86 48 86 f7 0d  01 01 05 05 00 03 81 81  |..*.H...........|
+000002a0  00 08 6c 45 24 c7 6b b1  59 ab 0c 52 cc f2 b0 14  |..lE$.k.Y..R....|
+000002b0  d7 87 9d 7a 64 75 b5 5a  95 66 e4 c5 2b 8e ae 12  |...zdu.Z.f..+...|
+000002c0  66 1f eb 4f 38 b3 6e 60  d3 92 fd f7 41 08 b5 25  |f..O8.n`....A..%|
+000002d0  13 b1 18 7a 24 fb 30 1d  ba ed 98 b9 17 ec e7 d7  |...z$.0.........|
+000002e0  31 59 db 95 d3 1d 78 ea  50 56 5c d5 82 5a 2d 5a  |1Y....x.PV\..Z-Z|
+000002f0  5f 33 c4 b6 d8 c9 75 90  96 8c 0f 52 98 b5 cd 98  |_3....u....R....|
+00000300  1f 89 20 5f f2 a0 1c a3  1b 96 94 dd a9 fd 57 e9  |.. _..........W.|
+00000310  70 e8 26 6d 71 99 9b 26  6e 38 50 29 6c 90 a7 bd  |p.&mq..&n8P)l...|
+00000320  d9 16 03 03 00 cd 0c 00  00 c9 03 00 17 41 04 33  |.............A.3|
+00000330  96 55 c1 5e 9d c4 a1 23  86 5b e8 df f9 7d d4 d0  |.U.^...#.[...}..|
+00000340  5f 61 9a c6 24 be a6 4b  ce 08 6e 9f 8f ef 08 66  |_a..$..K..n....f|
+00000350  9f a5 2e e7 04 c9 f2 d9  ab ef fa 62 28 a0 01 7a  |...........b(..z|
+00000360  d9 d6 44 9b c3 25 dc 5e  a9 75 ea 8d 2f e8 63 04  |..D..%.^.u../.c.|
+00000370  01 00 80 ba b3 36 74 0f  2c 3a c2 a3 2c ae 74 dc  |.....6t.,:..,.t.|
+00000380  f8 90 ba 91 10 a3 c1 8e  2b bf 2c b4 05 78 12 ff  |........+.,..x..|
+00000390  ec 62 b3 db f2 27 3d d0  0f bb 7d 1e f6 8f fd ee  |.b...'=...}.....|
+000003a0  53 37 be 6a 9e d9 21 42  ea 20 1e d8 fc eb 3c 79  |S7.j..!B. ....<y|
+000003b0  98 85 ab fe 9b 2d 63 77  cb 13 32 32 81 94 3e 53  |.....-cw..22..>S|
+000003c0  4f a7 63 c4 78 2d a2 48  08 ea f6 2a 50 24 33 f4  |O.c.x-.H...*P$3.|
+000003d0  9f 10 63 13 80 4e ec 5e  68 e3 18 f0 7b a4 2f 16  |..c..N.^h...{./.|
+000003e0  db c0 aa 8c a0 ee 47 65  a9 57 f3 a5 ef 6a 45 f5  |......Ge.W...jE.|
+000003f0  e2 54 cd 16 03 03 00 04  0e 00 00 00              |.T..........|
 >>> Flow 3 (client to server)
 00000000  16 03 03 00 46 10 00 00  42 41 04 1e 18 37 ef 0d  |....F...BA...7..|
 00000010  19 51 88 35 75 71 b5 e5  54 5b 12 2e 8f 09 67 fd  |.Q.5uq..T[....g.|
 00000030  f1 07 9f 6c 4b 5b 83 56  e2 32 42 e9 58 b6 d7 49  |...lK[.V.2B.X..I|
 00000040  a6 b5 68 1a 41 03 56 6b  dc 5a 89 14 03 03 00 01  |..h.A.Vk.Z......|
 00000050  01 16 03 03 00 40 00 00  00 00 00 00 00 00 00 00  |.....@..........|
-00000060  00 00 00 00 00 00 40 b3  ad 72 14 89 dc 2f e5 ac  |......@..r.../..|
-00000070  21 94 09 2f a4 99 ea f1  6e 09 57 20 05 51 2b 0b  |!../....n.W .Q+.|
-00000080  db 16 2d d8 ab 58 71 d9  da be 75 10 69 2d ef 03  |..-..Xq...u.i-..|
-00000090  e3 68 0e ab da 21                                 |.h...!|
+00000060  00 00 00 00 00 00 73 06  31 ab 8e cc e0 db 1a fe  |......s.1.......|
+00000070  7e d1 5b 2b 96 93 ee 2d  76 54 17 f9 c2 73 e8 62  |~.[+...-vT...s.b|
+00000080  f0 39 31 02 72 e9 ae 08  75 2d f1 f3 82 06 17 57  |.91.r...u-.....W|
+00000090  b7 aa c2 79 9f 8e                                 |...y..|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 40 c3 bb ef 26 e3  |..........@...&.|
-00000010  77 8d ca 38 15 ee e3 ce  2e b4 63 41 5a 07 fe b7  |w..8......cAZ...|
-00000020  9e 68 48 40 fc 09 17 f7  44 0d 04 7c af 2a 72 08  |.hH@....D..|.*r.|
-00000030  26 a0 65 13 02 04 c5 c7  63 80 86 76 cb da 67 4b  |&.e.....c..v..gK|
-00000040  6b 77 6b 69 f7 38 81 9b  22 42 36                 |kwki.8.."B6|
+00000000  14 03 03 00 01 01 16 03  03 00 40 dc c3 03 17 76  |..........@....v|
+00000010  d0 a5 61 9e 47 6a 1a 01  d0 21 92 c5 d5 f9 69 ba  |..a.Gj...!....i.|
+00000020  5e 82 2e d3 fc 4b a4 af  78 9d 47 6e b8 33 dc 8b  |^....K..x.Gn.3..|
+00000030  a0 94 b5 72 ea 4a 7d fc  ea f5 6e b6 c9 00 73 d1  |...r.J}...n...s.|
+00000040  3e cb 44 ef 0c fc fc ff  1e 87 8e                 |>.D........|
 >>> Flow 5 (client to server)
 00000000  17 03 03 00 30 00 00 00  00 00 00 00 00 00 00 00  |....0...........|
-00000010  00 00 00 00 00 4a b4 4a  af 44 80 31 87 26 b3 a8  |.....J.J.D.1.&..|
-00000020  1e f7 2a 4c 0c 8f 29 ac  52 55 75 e7 fe de b9 66  |..*L..).RUu....f|
-00000030  aa 16 e7 18 02 15 03 03  00 30 00 00 00 00 00 00  |.........0......|
-00000040  00 00 00 00 00 00 00 00  00 00 54 7f 4b c7 d7 93  |..........T.K...|
-00000050  90 30 ff 8f 96 4d 71 b7  ed db 65 7c af a2 00 f9  |.0...Mq...e|....|
-00000060  cb b4 77 a6 c4 5e 23 a7  77 4a                    |..w..^#.wJ|
+00000010  00 00 00 00 00 de 2e e3  8e d3 a5 e5 64 8e 22 f7  |............d.".|
+00000020  09 00 15 06 cb e9 d3 c5  3c 17 41 2f 5b a8 ce 09  |........<.A/[...|
+00000030  70 59 47 24 22 15 03 03  00 30 00 00 00 00 00 00  |pYG$"....0......|
+00000040  00 00 00 00 00 00 00 00  00 00 6a af 3f c1 54 6b  |..........j.?.Tk|
+00000050  14 64 23 c4 94 79 82 fd  78 84 ef 04 6f 64 fd 3e  |.d#..y..x...od.>|
+00000060  20 ff a0 11 ed fb d1 fb  ff 07                    | .........|
index ac1d9a407fa4cbd734aff4f481780dae9315ccfc..2c6e776848eab1118db9755bc638d9f125011332 100644 (file)
@@ -1,63 +1,64 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 70 01 00 00  6c 03 03 00 00 00 00 00  |....p...l.......|
+00000000  16 03 01 00 75 01 00 00  71 03 03 00 00 00 00 00  |....u...q.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
 00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
-00000040  00 2f 00 35 c0 12 00 0a  01 00 00 29 00 05 00 05  |./.5.......)....|
+00000040  00 2f 00 35 c0 12 00 0a  01 00 00 2e 00 05 00 05  |./.5............|
 00000050  01 00 00 00 00 00 0a 00  08 00 06 00 17 00 18 00  |................|
 00000060  19 00 0b 00 02 01 00 00  0d 00 0a 00 08 04 01 04  |................|
-00000070  03 02 01 02 03                                    |.....|
+00000070  03 02 01 02 03 ff 01 00  01 00                    |..........|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 4a 02 00 00  46 03 03 52 ac 77 f7 35  |....J...F..R.w.5|
-00000010  a6 0a 57 0a 43 25 69 29  e7 14 d6 27 f3 21 ec c7  |..W.C%i)...'.!..|
-00000020  be 69 65 eb f4 ed 96 4c  9e 0a fa 20 5d 7d 71 3b  |.ie....L... ]}q;|
-00000030  c1 7d 2d 56 a9 60 2f 58  f2 05 29 36 8f 59 a6 0f  |.}-V.`/X..)6.Y..|
-00000040  13 f8 31 dc 8e b5 ca 4d  38 c4 28 19 00 05 00 16  |..1....M8.(.....|
-00000050  03 03 02 be 0b 00 02 ba  00 02 b7 00 02 b4 30 82  |..............0.|
-00000060  02 b0 30 82 02 19 a0 03  02 01 02 02 09 00 85 b0  |..0.............|
-00000070  bb a4 8a 7f b8 ca 30 0d  06 09 2a 86 48 86 f7 0d  |......0...*.H...|
-00000080  01 01 05 05 00 30 45 31  0b 30 09 06 03 55 04 06  |.....0E1.0...U..|
-00000090  13 02 41 55 31 13 30 11  06 03 55 04 08 13 0a 53  |..AU1.0...U....S|
-000000a0  6f 6d 65 2d 53 74 61 74  65 31 21 30 1f 06 03 55  |ome-State1!0...U|
-000000b0  04 0a 13 18 49 6e 74 65  72 6e 65 74 20 57 69 64  |....Internet Wid|
-000000c0  67 69 74 73 20 50 74 79  20 4c 74 64 30 1e 17 0d  |gits Pty Ltd0...|
-000000d0  31 30 30 34 32 34 30 39  30 39 33 38 5a 17 0d 31  |100424090938Z..1|
-000000e0  31 30 34 32 34 30 39 30  39 33 38 5a 30 45 31 0b  |10424090938Z0E1.|
-000000f0  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-00000100  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-00000110  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-00000120  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-00000130  4c 74 64 30 81 9f 30 0d  06 09 2a 86 48 86 f7 0d  |Ltd0..0...*.H...|
-00000140  01 01 01 05 00 03 81 8d  00 30 81 89 02 81 81 00  |.........0......|
-00000150  bb 79 d6 f5 17 b5 e5 bf  46 10 d0 dc 69 be e6 2b  |.y......F...i..+|
-00000160  07 43 5a d0 03 2d 8a 7a  43 85 b7 14 52 e7 a5 65  |.CZ..-.zC...R..e|
-00000170  4c 2c 78 b8 23 8c b5 b4  82 e5 de 1f 95 3b 7e 62  |L,x.#........;~b|
-00000180  a5 2c a5 33 d6 fe 12 5c  7a 56 fc f5 06 bf fa 58  |.,.3...\zV.....X|
-00000190  7b 26 3f b5 cd 04 d3 d0  c9 21 96 4a c7 f4 54 9f  |{&?......!.J..T.|
-000001a0  5a bf ef 42 71 00 fe 18  99 07 7f 7e 88 7d 7d f1  |Z..Bq......~.}}.|
-000001b0  04 39 c4 a2 2e db 51 c9  7c e3 c0 4c 3b 32 66 01  |.9....Q.|..L;2f.|
-000001c0  cf af b1 1d b8 71 9a 1d  db db 89 6b ae da 2d 79  |.....q.....k..-y|
-000001d0  02 03 01 00 01 a3 81 a7  30 81 a4 30 1d 06 03 55  |........0..0...U|
-000001e0  1d 0e 04 16 04 14 b1 ad  e2 85 5a cf cb 28 db 69  |..........Z..(.i|
-000001f0  ce 23 69 de d3 26 8e 18  88 39 30 75 06 03 55 1d  |.#i..&...90u..U.|
-00000200  23 04 6e 30 6c 80 14 b1  ad e2 85 5a cf cb 28 db  |#.n0l......Z..(.|
-00000210  69 ce 23 69 de d3 26 8e  18 88 39 a1 49 a4 47 30  |i.#i..&...9.I.G0|
-00000220  45 31 0b 30 09 06 03 55  04 06 13 02 41 55 31 13  |E1.0...U....AU1.|
-00000230  30 11 06 03 55 04 08 13  0a 53 6f 6d 65 2d 53 74  |0...U....Some-St|
-00000240  61 74 65 31 21 30 1f 06  03 55 04 0a 13 18 49 6e  |ate1!0...U....In|
-00000250  74 65 72 6e 65 74 20 57  69 64 67 69 74 73 20 50  |ternet Widgits P|
-00000260  74 79 20 4c 74 64 82 09  00 85 b0 bb a4 8a 7f b8  |ty Ltd..........|
-00000270  ca 30 0c 06 03 55 1d 13  04 05 30 03 01 01 ff 30  |.0...U....0....0|
-00000280  0d 06 09 2a 86 48 86 f7  0d 01 01 05 05 00 03 81  |...*.H..........|
-00000290  81 00 08 6c 45 24 c7 6b  b1 59 ab 0c 52 cc f2 b0  |...lE$.k.Y..R...|
-000002a0  14 d7 87 9d 7a 64 75 b5  5a 95 66 e4 c5 2b 8e ae  |....zdu.Z.f..+..|
-000002b0  12 66 1f eb 4f 38 b3 6e  60 d3 92 fd f7 41 08 b5  |.f..O8.n`....A..|
-000002c0  25 13 b1 18 7a 24 fb 30  1d ba ed 98 b9 17 ec e7  |%...z$.0........|
-000002d0  d7 31 59 db 95 d3 1d 78  ea 50 56 5c d5 82 5a 2d  |.1Y....x.PV\..Z-|
-000002e0  5a 5f 33 c4 b6 d8 c9 75  90 96 8c 0f 52 98 b5 cd  |Z_3....u....R...|
-000002f0  98 1f 89 20 5f f2 a0 1c  a3 1b 96 94 dd a9 fd 57  |... _..........W|
-00000300  e9 70 e8 26 6d 71 99 9b  26 6e 38 50 29 6c 90 a7  |.p.&mq..&n8P)l..|
-00000310  bd d9 16 03 03 00 04 0e  00 00 00                 |...........|
+00000000  16 03 03 00 51 02 00 00  4d 03 03 52 cc 57 58 70  |....Q...M..R.WXp|
+00000010  03 50 58 32 ec de bc ae  18 e7 24 15 2b 4d cc d5  |.PX2......$.+M..|
+00000020  1f 40 db 80 5b 19 d9 3f  48 4b 06 20 87 fe d3 d4  |.@..[..?HK. ....|
+00000030  51 42 74 9c cf 9d fd 31  c3 53 28 f1 a4 21 16 d6  |QBt....1.S(..!..|
+00000040  4f 5a 22 09 9d 99 89 7c  f9 e7 5b 49 00 05 00 00  |OZ"....|..[I....|
+00000050  05 ff 01 00 01 00 16 03  03 02 be 0b 00 02 ba 00  |................|
+00000060  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
+00000070  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
+00000080  09 2a 86 48 86 f7 0d 01  01 05 05 00 30 45 31 0b  |.*.H........0E1.|
+00000090  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
+000000a0  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
+000000b0  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
+000000c0  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
+000000d0  4c 74 64 30 1e 17 0d 31  30 30 34 32 34 30 39 30  |Ltd0...100424090|
+000000e0  39 33 38 5a 17 0d 31 31  30 34 32 34 30 39 30 39  |938Z..1104240909|
+000000f0  33 38 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |38Z0E1.0...U....|
+00000100  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
+00000110  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
+00000120  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
+00000130  74 73 20 50 74 79 20 4c  74 64 30 81 9f 30 0d 06  |ts Pty Ltd0..0..|
+00000140  09 2a 86 48 86 f7 0d 01  01 01 05 00 03 81 8d 00  |.*.H............|
+00000150  30 81 89 02 81 81 00 bb  79 d6 f5 17 b5 e5 bf 46  |0.......y......F|
+00000160  10 d0 dc 69 be e6 2b 07  43 5a d0 03 2d 8a 7a 43  |...i..+.CZ..-.zC|
+00000170  85 b7 14 52 e7 a5 65 4c  2c 78 b8 23 8c b5 b4 82  |...R..eL,x.#....|
+00000180  e5 de 1f 95 3b 7e 62 a5  2c a5 33 d6 fe 12 5c 7a  |....;~b.,.3...\z|
+00000190  56 fc f5 06 bf fa 58 7b  26 3f b5 cd 04 d3 d0 c9  |V.....X{&?......|
+000001a0  21 96 4a c7 f4 54 9f 5a  bf ef 42 71 00 fe 18 99  |!.J..T.Z..Bq....|
+000001b0  07 7f 7e 88 7d 7d f1 04  39 c4 a2 2e db 51 c9 7c  |..~.}}..9....Q.||
+000001c0  e3 c0 4c 3b 32 66 01 cf  af b1 1d b8 71 9a 1d db  |..L;2f......q...|
+000001d0  db 89 6b ae da 2d 79 02  03 01 00 01 a3 81 a7 30  |..k..-y........0|
+000001e0  81 a4 30 1d 06 03 55 1d  0e 04 16 04 14 b1 ad e2  |..0...U.........|
+000001f0  85 5a cf cb 28 db 69 ce  23 69 de d3 26 8e 18 88  |.Z..(.i.#i..&...|
+00000200  39 30 75 06 03 55 1d 23  04 6e 30 6c 80 14 b1 ad  |90u..U.#.n0l....|
+00000210  e2 85 5a cf cb 28 db 69  ce 23 69 de d3 26 8e 18  |..Z..(.i.#i..&..|
+00000220  88 39 a1 49 a4 47 30 45  31 0b 30 09 06 03 55 04  |.9.I.G0E1.0...U.|
+00000230  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
+00000240  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
+00000250  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
+00000260  64 67 69 74 73 20 50 74  79 20 4c 74 64 82 09 00  |dgits Pty Ltd...|
+00000270  85 b0 bb a4 8a 7f b8 ca  30 0c 06 03 55 1d 13 04  |........0...U...|
+00000280  05 30 03 01 01 ff 30 0d  06 09 2a 86 48 86 f7 0d  |.0....0...*.H...|
+00000290  01 01 05 05 00 03 81 81  00 08 6c 45 24 c7 6b b1  |..........lE$.k.|
+000002a0  59 ab 0c 52 cc f2 b0 14  d7 87 9d 7a 64 75 b5 5a  |Y..R.......zdu.Z|
+000002b0  95 66 e4 c5 2b 8e ae 12  66 1f eb 4f 38 b3 6e 60  |.f..+...f..O8.n`|
+000002c0  d3 92 fd f7 41 08 b5 25  13 b1 18 7a 24 fb 30 1d  |....A..%...z$.0.|
+000002d0  ba ed 98 b9 17 ec e7 d7  31 59 db 95 d3 1d 78 ea  |........1Y....x.|
+000002e0  50 56 5c d5 82 5a 2d 5a  5f 33 c4 b6 d8 c9 75 90  |PV\..Z-Z_3....u.|
+000002f0  96 8c 0f 52 98 b5 cd 98  1f 89 20 5f f2 a0 1c a3  |...R...... _....|
+00000300  1b 96 94 dd a9 fd 57 e9  70 e8 26 6d 71 99 9b 26  |......W.p.&mq..&|
+00000310  6e 38 50 29 6c 90 a7 bd  d9 16 03 03 00 04 0e 00  |n8P)l...........|
+00000320  00 00                                             |..|
 >>> Flow 3 (client to server)
 00000000  16 03 03 00 86 10 00 00  82 00 80 6d 51 f3 7f f9  |...........mQ...|
 00000010  3e fb 75 82 41 36 83 e8  6a ee 2a 2e 25 90 67 4c  |>.u.A6..j.*.%.gL|
 00000060  e6 bd 77 82 6f 23 b6 e0  bd a2 92 b7 3a ac e8 56  |..w.o#......:..V|
 00000070  f1 af 54 5e 46 87 e9 3b  33 e7 b8 28 b7 d6 c8 90  |..T^F..;3..(....|
 00000080  35 d4 1c 43 d1 30 6f 55  4e 0a 70 14 03 03 00 01  |5..C.0oUN.p.....|
-00000090  01 16 03 03 00 24 6e bd  04 e6 9f 42 97 d8 e5 c8  |.....$n....B....|
-000000a0  53 80 41 35 a7 f3 a3 9e  88 13 37 ac 51 25 c2 87  |S.A5......7.Q%..|
-000000b0  29 4a e1 e4 eb 2b 31 a3  8b 0b                    |)J...+1...|
+00000090  01 16 03 03 00 24 fb 2b  2f c5 19 90 a6 bc 81 c0  |.....$.+/.......|
+000000a0  ac 6b e6 1f e2 af be 10  b4 a0 c7 31 aa d8 cc a2  |.k.........1....|
+000000b0  ce 51 1e 8e d6 00 76 27  72 53                    |.Q....v'rS|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 24 60 22 7f 1b 4d  |..........$`"..M|
-00000010  75 6a c3 d3 d6 7c 18 f5  94 b1 4b 80 b8 7c a5 1b  |uj...|....K..|..|
-00000020  8c 45 f0 b6 e7 8a 65 82  69 0f c0 0f 9b 71 ea     |.E....e.i....q.|
+00000000  14 03 03 00 01 01 16 03  03 00 24 d4 c8 b3 8a 87  |..........$.....|
+00000010  b5 0d 01 80 fc 2c df 18  ca 17 fd 06 ad 31 29 13  |.....,.......1).|
+00000020  5f f9 b4 75 ad 49 c8 de  ec 1a ee 57 6b 1a 81     |_..u.I.....Wk..|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 1a 3a 50 9f  29 c9 86 ec 81 79 f0 86  |.....:P.)....y..|
-00000010  25 03 5b 0c dd a6 f7 d6  e0 ad dc bc eb 37 c7 15  |%.[..........7..|
-00000020  03 03 00 16 89 31 da 0a  95 7a 42 54 81 85 de 9f  |.....1...zBT....|
-00000030  ff 9f 7e 13 28 3a f6 84  40 24                    |..~.(:..@$|
+00000000  17 03 03 00 1a 8b ce be  7d c7 06 42 d0 9b 65 6c  |........}..B..el|
+00000010  23 0e 84 ef e0 a3 ec 42  4e 70 14 65 78 ad 52 15  |#......BNp.ex.R.|
+00000020  03 03 00 16 49 5f f2 e2  e0 8f d3 54 68 2a d6 ab  |....I_.....Th*..|
+00000030  28 be 50 3d 62 8b 1a b3  5b e5                    |(.P=b...[.|
index 28bb242216eef0a6ee61c21519afd39fb827fc5e..a6c7a4196c7b4d4502938d491aef02997cb3bdec 100644 (file)
@@ -1,82 +1,83 @@
 >>> Flow 1 (client to server)
-00000000  16 03 00 00 30 01 00 00  2c 03 00 52 ac 77 f8 ba  |....0...,..R.w..|
-00000010  20 7c b1 a6 c2 a5 5e 1b  b6 76 26 88 79 9b 52 56  | |....^..v&.y.RV|
-00000020  f4 f5 83 1e 23 be 66 6c  47 70 ed 00 00 04 00 0a  |....#.flGp......|
-00000030  00 ff 02 01 00                                    |.....|
+00000000  16 03 00 00 2f 01 00 00  2b 03 00 52 cc 57 59 d8  |..../...+..R.WY.|
+00000010  86 d6 07 ae e0 8d 63 b7  1e cb aa c6 67 32 c8 dd  |......c.....g2..|
+00000020  68 03 d8 3d 37 18 72 c3  c0 f1 9d 00 00 04 00 0a  |h..=7.r.........|
+00000030  00 ff 01 00                                       |....|
 >>> Flow 2 (server to client)
-00000000  16 03 00 00 2a 02 00 00  26 03 00 00 00 00 00 00  |....*...&.......|
+00000000  16 03 00 00 31 02 00 00  2d 03 00 00 00 00 00 00  |....1...-.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 0a 00 16  |................|
-00000030  03 00 02 be 0b 00 02 ba  00 02 b7 00 02 b4 30 82  |..............0.|
-00000040  02 b0 30 82 02 19 a0 03  02 01 02 02 09 00 85 b0  |..0.............|
-00000050  bb a4 8a 7f b8 ca 30 0d  06 09 2a 86 48 86 f7 0d  |......0...*.H...|
-00000060  01 01 05 05 00 30 45 31  0b 30 09 06 03 55 04 06  |.....0E1.0...U..|
-00000070  13 02 41 55 31 13 30 11  06 03 55 04 08 13 0a 53  |..AU1.0...U....S|
-00000080  6f 6d 65 2d 53 74 61 74  65 31 21 30 1f 06 03 55  |ome-State1!0...U|
-00000090  04 0a 13 18 49 6e 74 65  72 6e 65 74 20 57 69 64  |....Internet Wid|
-000000a0  67 69 74 73 20 50 74 79  20 4c 74 64 30 1e 17 0d  |gits Pty Ltd0...|
-000000b0  31 30 30 34 32 34 30 39  30 39 33 38 5a 17 0d 31  |100424090938Z..1|
-000000c0  31 30 34 32 34 30 39 30  39 33 38 5a 30 45 31 0b  |10424090938Z0E1.|
-000000d0  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-000000e0  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-000000f0  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-00000100  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-00000110  4c 74 64 30 81 9f 30 0d  06 09 2a 86 48 86 f7 0d  |Ltd0..0...*.H...|
-00000120  01 01 01 05 00 03 81 8d  00 30 81 89 02 81 81 00  |.........0......|
-00000130  bb 79 d6 f5 17 b5 e5 bf  46 10 d0 dc 69 be e6 2b  |.y......F...i..+|
-00000140  07 43 5a d0 03 2d 8a 7a  43 85 b7 14 52 e7 a5 65  |.CZ..-.zC...R..e|
-00000150  4c 2c 78 b8 23 8c b5 b4  82 e5 de 1f 95 3b 7e 62  |L,x.#........;~b|
-00000160  a5 2c a5 33 d6 fe 12 5c  7a 56 fc f5 06 bf fa 58  |.,.3...\zV.....X|
-00000170  7b 26 3f b5 cd 04 d3 d0  c9 21 96 4a c7 f4 54 9f  |{&?......!.J..T.|
-00000180  5a bf ef 42 71 00 fe 18  99 07 7f 7e 88 7d 7d f1  |Z..Bq......~.}}.|
-00000190  04 39 c4 a2 2e db 51 c9  7c e3 c0 4c 3b 32 66 01  |.9....Q.|..L;2f.|
-000001a0  cf af b1 1d b8 71 9a 1d  db db 89 6b ae da 2d 79  |.....q.....k..-y|
-000001b0  02 03 01 00 01 a3 81 a7  30 81 a4 30 1d 06 03 55  |........0..0...U|
-000001c0  1d 0e 04 16 04 14 b1 ad  e2 85 5a cf cb 28 db 69  |..........Z..(.i|
-000001d0  ce 23 69 de d3 26 8e 18  88 39 30 75 06 03 55 1d  |.#i..&...90u..U.|
-000001e0  23 04 6e 30 6c 80 14 b1  ad e2 85 5a cf cb 28 db  |#.n0l......Z..(.|
-000001f0  69 ce 23 69 de d3 26 8e  18 88 39 a1 49 a4 47 30  |i.#i..&...9.I.G0|
-00000200  45 31 0b 30 09 06 03 55  04 06 13 02 41 55 31 13  |E1.0...U....AU1.|
-00000210  30 11 06 03 55 04 08 13  0a 53 6f 6d 65 2d 53 74  |0...U....Some-St|
-00000220  61 74 65 31 21 30 1f 06  03 55 04 0a 13 18 49 6e  |ate1!0...U....In|
-00000230  74 65 72 6e 65 74 20 57  69 64 67 69 74 73 20 50  |ternet Widgits P|
-00000240  74 79 20 4c 74 64 82 09  00 85 b0 bb a4 8a 7f b8  |ty Ltd..........|
-00000250  ca 30 0c 06 03 55 1d 13  04 05 30 03 01 01 ff 30  |.0...U....0....0|
-00000260  0d 06 09 2a 86 48 86 f7  0d 01 01 05 05 00 03 81  |...*.H..........|
-00000270  81 00 08 6c 45 24 c7 6b  b1 59 ab 0c 52 cc f2 b0  |...lE$.k.Y..R...|
-00000280  14 d7 87 9d 7a 64 75 b5  5a 95 66 e4 c5 2b 8e ae  |....zdu.Z.f..+..|
-00000290  12 66 1f eb 4f 38 b3 6e  60 d3 92 fd f7 41 08 b5  |.f..O8.n`....A..|
-000002a0  25 13 b1 18 7a 24 fb 30  1d ba ed 98 b9 17 ec e7  |%...z$.0........|
-000002b0  d7 31 59 db 95 d3 1d 78  ea 50 56 5c d5 82 5a 2d  |.1Y....x.PV\..Z-|
-000002c0  5a 5f 33 c4 b6 d8 c9 75  90 96 8c 0f 52 98 b5 cd  |Z_3....u....R...|
-000002d0  98 1f 89 20 5f f2 a0 1c  a3 1b 96 94 dd a9 fd 57  |... _..........W|
-000002e0  e9 70 e8 26 6d 71 99 9b  26 6e 38 50 29 6c 90 a7  |.p.&mq..&n8P)l..|
-000002f0  bd d9 16 03 00 00 04 0e  00 00 00                 |...........|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 0a 00 00  |................|
+00000030  05 ff 01 00 01 00 16 03  00 02 be 0b 00 02 ba 00  |................|
+00000040  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
+00000050  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
+00000060  09 2a 86 48 86 f7 0d 01  01 05 05 00 30 45 31 0b  |.*.H........0E1.|
+00000070  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
+00000080  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
+00000090  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
+000000a0  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
+000000b0  4c 74 64 30 1e 17 0d 31  30 30 34 32 34 30 39 30  |Ltd0...100424090|
+000000c0  39 33 38 5a 17 0d 31 31  30 34 32 34 30 39 30 39  |938Z..1104240909|
+000000d0  33 38 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |38Z0E1.0...U....|
+000000e0  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
+000000f0  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
+00000100  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
+00000110  74 73 20 50 74 79 20 4c  74 64 30 81 9f 30 0d 06  |ts Pty Ltd0..0..|
+00000120  09 2a 86 48 86 f7 0d 01  01 01 05 00 03 81 8d 00  |.*.H............|
+00000130  30 81 89 02 81 81 00 bb  79 d6 f5 17 b5 e5 bf 46  |0.......y......F|
+00000140  10 d0 dc 69 be e6 2b 07  43 5a d0 03 2d 8a 7a 43  |...i..+.CZ..-.zC|
+00000150  85 b7 14 52 e7 a5 65 4c  2c 78 b8 23 8c b5 b4 82  |...R..eL,x.#....|
+00000160  e5 de 1f 95 3b 7e 62 a5  2c a5 33 d6 fe 12 5c 7a  |....;~b.,.3...\z|
+00000170  56 fc f5 06 bf fa 58 7b  26 3f b5 cd 04 d3 d0 c9  |V.....X{&?......|
+00000180  21 96 4a c7 f4 54 9f 5a  bf ef 42 71 00 fe 18 99  |!.J..T.Z..Bq....|
+00000190  07 7f 7e 88 7d 7d f1 04  39 c4 a2 2e db 51 c9 7c  |..~.}}..9....Q.||
+000001a0  e3 c0 4c 3b 32 66 01 cf  af b1 1d b8 71 9a 1d db  |..L;2f......q...|
+000001b0  db 89 6b ae da 2d 79 02  03 01 00 01 a3 81 a7 30  |..k..-y........0|
+000001c0  81 a4 30 1d 06 03 55 1d  0e 04 16 04 14 b1 ad e2  |..0...U.........|
+000001d0  85 5a cf cb 28 db 69 ce  23 69 de d3 26 8e 18 88  |.Z..(.i.#i..&...|
+000001e0  39 30 75 06 03 55 1d 23  04 6e 30 6c 80 14 b1 ad  |90u..U.#.n0l....|
+000001f0  e2 85 5a cf cb 28 db 69  ce 23 69 de d3 26 8e 18  |..Z..(.i.#i..&..|
+00000200  88 39 a1 49 a4 47 30 45  31 0b 30 09 06 03 55 04  |.9.I.G0E1.0...U.|
+00000210  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
+00000220  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
+00000230  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
+00000240  64 67 69 74 73 20 50 74  79 20 4c 74 64 82 09 00  |dgits Pty Ltd...|
+00000250  85 b0 bb a4 8a 7f b8 ca  30 0c 06 03 55 1d 13 04  |........0...U...|
+00000260  05 30 03 01 01 ff 30 0d  06 09 2a 86 48 86 f7 0d  |.0....0...*.H...|
+00000270  01 01 05 05 00 03 81 81  00 08 6c 45 24 c7 6b b1  |..........lE$.k.|
+00000280  59 ab 0c 52 cc f2 b0 14  d7 87 9d 7a 64 75 b5 5a  |Y..R.......zdu.Z|
+00000290  95 66 e4 c5 2b 8e ae 12  66 1f eb 4f 38 b3 6e 60  |.f..+...f..O8.n`|
+000002a0  d3 92 fd f7 41 08 b5 25  13 b1 18 7a 24 fb 30 1d  |....A..%...z$.0.|
+000002b0  ba ed 98 b9 17 ec e7 d7  31 59 db 95 d3 1d 78 ea  |........1Y....x.|
+000002c0  50 56 5c d5 82 5a 2d 5a  5f 33 c4 b6 d8 c9 75 90  |PV\..Z-Z_3....u.|
+000002d0  96 8c 0f 52 98 b5 cd 98  1f 89 20 5f f2 a0 1c a3  |...R...... _....|
+000002e0  1b 96 94 dd a9 fd 57 e9  70 e8 26 6d 71 99 9b 26  |......W.p.&mq..&|
+000002f0  6e 38 50 29 6c 90 a7 bd  d9 16 03 00 00 04 0e 00  |n8P)l...........|
+00000300  00 00                                             |..|
 >>> Flow 3 (client to server)
-00000000  16 03 00 00 84 10 00 00  80 b6 25 91 8f 12 fc a2  |..........%.....|
-00000010  b9 f1 31 3a b5 a8 b6 cf  aa f1 b4 83 3d aa f1 1d  |..1:........=...|
-00000020  de 33 e4 25 6a 49 25 71  e9 9d 51 97 3b 9d 2a 68  |.3.%jI%q..Q.;.*h|
-00000030  84 13 3a e7 2c 97 67 36  ee 23 a9 97 6d c2 3a e5  |..:.,.g6.#..m.:.|
-00000040  33 24 37 ce 76 ed a1 8f  f8 49 e4 b8 77 2a ef 9a  |3$7.v....I..w*..|
-00000050  38 3c 4f d1 88 7b 28 1b  3a 90 4b 6b 67 8f 04 f0  |8<O..{(.:.Kkg...|
-00000060  cd d4 b7 ab a2 42 86 e9  45 38 dd 78 4c 9f fb 10  |.....B..E8.xL...|
-00000070  3c 65 35 8e f5 bc 3a 28  e1 cb 86 44 e8 bc 29 26  |<e5...:(...D..)&|
-00000080  fc 43 be 15 f2 5b e7 07  82 14 03 00 00 01 01 16  |.C...[..........|
-00000090  03 00 00 40 3d db ec d5  66 0d 92 2f 23 36 3e e6  |...@=...f../#6>.|
-000000a0  ac ee 10 8d db 11 ce dc  65 e7 cb ba 14 4d 81 34  |........e....M.4|
-000000b0  46 eb 6e fd 5e 36 20 32  bd 59 05 b6 39 a1 86 31  |F.n.^6 2.Y..9..1|
-000000c0  24 ef 53 64 0a 7a 91 95  c1 e3 aa bb 48 08 ac 22  |$.Sd.z......H.."|
-000000d0  6e 1c df e1                                       |n...|
+00000000  16 03 00 00 84 10 00 00  80 75 e0 c9 76 d6 e9 34  |.........u..v..4|
+00000010  1d e3 31 9e db 3b 03 41  93 e8 db 73 7c e9 3f 6a  |..1..;.A...s|.?j|
+00000020  d8 2a 7b 25 83 4f 45 de  3f 78 3f b6 53 a7 b4 6c  |.*{%.OE.?x?.S..l|
+00000030  e3 87 c4 c3 70 55 71 79  55 dc 74 98 84 21 19 13  |....pUqyU.t..!..|
+00000040  be d5 8e 0a ff 2f 9f 7a  6b d4 6c ef 78 d1 cb 65  |...../.zk.l.x..e|
+00000050  32 4c 0c c5 29 b9 60 94  c6 79 56 a2 aa 2d d9 ad  |2L..).`..yV..-..|
+00000060  51 2c 54 1b 28 23 33 54  cd 48 cb 80 13 45 3d 4a  |Q,T.(#3T.H...E=J|
+00000070  8e 2f f2 da bd 68 3e 1b  eb 73 f9 2d 35 6b b1 40  |./...h>..s.-5k.@|
+00000080  2e 6d 9d 1c e9 c1 02 80  37 14 03 00 00 01 01 16  |.m......7.......|
+00000090  03 00 00 40 f7 c3 dd a4  64 3d 81 24 de a2 81 7d  |...@....d=.$...}|
+000000a0  e4 df 78 46 e7 ba 93 6c  36 43 05 96 fc 75 ef ec  |..xF...l6C...u..|
+000000b0  a5 46 6d 47 a5 be 74 ad  15 93 d9 87 4f 1d e2 b3  |.FmG..t.....O...|
+000000c0  03 ff 2e 89 6e 50 f4 d6  a6 e2 b3 54 cb 74 07 f7  |....nP.....T.t..|
+000000d0  ca 1b 8c 0a                                       |....|
 >>> Flow 4 (server to client)
-00000000  14 03 00 00 01 01 16 03  00 00 40 c1 e3 a0 4d 7d  |..........@...M}|
-00000010  02 0b dc 0a 12 8c 2c 5c  c4 d4 b9 76 b8 a3 dc 9a  |......,\...v....|
-00000020  7d 3a 08 a6 b6 c9 00 8b  ee b7 e6 8e 72 3c e0 07  |}:..........r<..|
-00000030  28 07 20 a7 7a 93 1a de  63 af bd 80 2b 66 74 d9  |(. .z...c...+ft.|
-00000040  d8 ef 7c 56 cd 0f c4 bf  b4 7d cc 17 03 00 00 18  |..|V.....}......|
-00000050  18 d2 23 27 f9 89 7c 47  8a a8 92 32 26 4e 7d c6  |..#'..|G...2&N}.|
-00000060  59 44 71 b3 c9 ca 31 63  17 03 00 00 28 24 09 c1  |YDq...1c....($..|
-00000070  98 2e 4c 4b 80 66 b5 cb  20 01 0f 23 06 44 be 23  |..LK.f.. ..#.D.#|
-00000080  32 0e bc e4 c1 b5 b4 f0  e3 53 5a 69 fb ae 3b 92  |2........SZi..;.|
-00000090  29 c9 b6 cf 5d 15 03 00  00 18 ec 3e e9 e6 4e 7e  |)...]......>..N~|
-000000a0  4d 8f b7 74 93 61 f4 85  28 5f e6 37 2d 9f 01 54  |M..t.a..(_.7-..T|
-000000b0  bd 24                                             |.$|
+00000000  14 03 00 00 01 01 16 03  00 00 40 6d 3d d8 d5 cf  |..........@m=...|
+00000010  05 7d 98 8c 28 28 e2 43  ab ad 4a fa ae bf ec c3  |.}..((.C..J.....|
+00000020  9c 0a 13 4d 28 a4 45 c4  b9 f2 bc c5 12 a2 68 91  |...M(.E.......h.|
+00000030  77 fa 72 f8 9e 4e b7 1f  b4 02 02 e3 5d 57 b0 8b  |w.r..N......]W..|
+00000040  d8 90 0c 9d e6 df 5b 90  92 a1 0d 17 03 00 00 18  |......[.........|
+00000050  91 48 8a e1 d6 bf 79 1c  d5 0a 70 d5 94 20 25 78  |.H....y...p.. %x|
+00000060  d8 84 c8 6e 54 f0 99 01  17 03 00 00 28 74 19 90  |...nT.......(t..|
+00000070  41 44 53 27 bb fb 1f fd  71 34 20 61 a0 eb a4 7c  |ADS'....q4 a...||
+00000080  fe 36 f8 4b d7 b0 27 d3  b9 36 e1 67 af 2d 0e 23  |.6.K..'..6.g.-.#|
+00000090  2b 76 a7 2f c3 15 03 00  00 18 db fc e9 fd 87 5f  |+v./..........._|
+000000a0  92 a8 3d 4b 35 f5 c6 48  2c b4 42 50 c3 81 28 f0  |..=K5..H,.BP..(.|
+000000b0  2b 41                                             |+A|
index 515ebac23ad93964c9c4d5378d88d8054dbb8976..4885b267da7e2df32d83988681ff8712d1e3f908 100644 (file)
@@ -1,83 +1,84 @@
 >>> Flow 1 (client to server)
-00000000  16 03 00 00 30 01 00 00  2c 03 00 52 ac 77 f8 f2  |....0...,..R.w..|
-00000010  8a e8 25 e4 df f9 db 01  25 d2 14 4b 10 25 b8 f7  |..%.....%..K.%..|
-00000020  86 b3 83 32 96 e8 af 50  93 78 8d 00 00 04 00 2f  |...2...P.x...../|
-00000030  00 ff 02 01 00                                    |.....|
+00000000  16 03 00 00 2f 01 00 00  2b 03 00 52 cc 57 59 30  |..../...+..R.WY0|
+00000010  e1 ee 8c 60 5b 40 dd 95  bd b4 84 87 2f 01 15 e7  |...`[@....../...|
+00000020  50 88 4c 82 6b 6d 93 8a  57 d0 27 00 00 04 00 2f  |P.L.km..W.'..../|
+00000030  00 ff 01 00                                       |....|
 >>> Flow 2 (server to client)
-00000000  16 03 00 00 2a 02 00 00  26 03 00 00 00 00 00 00  |....*...&.......|
+00000000  16 03 00 00 31 02 00 00  2d 03 00 00 00 00 00 00  |....1...-.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 2f 00 16  |............./..|
-00000030  03 00 02 be 0b 00 02 ba  00 02 b7 00 02 b4 30 82  |..............0.|
-00000040  02 b0 30 82 02 19 a0 03  02 01 02 02 09 00 85 b0  |..0.............|
-00000050  bb a4 8a 7f b8 ca 30 0d  06 09 2a 86 48 86 f7 0d  |......0...*.H...|
-00000060  01 01 05 05 00 30 45 31  0b 30 09 06 03 55 04 06  |.....0E1.0...U..|
-00000070  13 02 41 55 31 13 30 11  06 03 55 04 08 13 0a 53  |..AU1.0...U....S|
-00000080  6f 6d 65 2d 53 74 61 74  65 31 21 30 1f 06 03 55  |ome-State1!0...U|
-00000090  04 0a 13 18 49 6e 74 65  72 6e 65 74 20 57 69 64  |....Internet Wid|
-000000a0  67 69 74 73 20 50 74 79  20 4c 74 64 30 1e 17 0d  |gits Pty Ltd0...|
-000000b0  31 30 30 34 32 34 30 39  30 39 33 38 5a 17 0d 31  |100424090938Z..1|
-000000c0  31 30 34 32 34 30 39 30  39 33 38 5a 30 45 31 0b  |10424090938Z0E1.|
-000000d0  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-000000e0  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-000000f0  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-00000100  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-00000110  4c 74 64 30 81 9f 30 0d  06 09 2a 86 48 86 f7 0d  |Ltd0..0...*.H...|
-00000120  01 01 01 05 00 03 81 8d  00 30 81 89 02 81 81 00  |.........0......|
-00000130  bb 79 d6 f5 17 b5 e5 bf  46 10 d0 dc 69 be e6 2b  |.y......F...i..+|
-00000140  07 43 5a d0 03 2d 8a 7a  43 85 b7 14 52 e7 a5 65  |.CZ..-.zC...R..e|
-00000150  4c 2c 78 b8 23 8c b5 b4  82 e5 de 1f 95 3b 7e 62  |L,x.#........;~b|
-00000160  a5 2c a5 33 d6 fe 12 5c  7a 56 fc f5 06 bf fa 58  |.,.3...\zV.....X|
-00000170  7b 26 3f b5 cd 04 d3 d0  c9 21 96 4a c7 f4 54 9f  |{&?......!.J..T.|
-00000180  5a bf ef 42 71 00 fe 18  99 07 7f 7e 88 7d 7d f1  |Z..Bq......~.}}.|
-00000190  04 39 c4 a2 2e db 51 c9  7c e3 c0 4c 3b 32 66 01  |.9....Q.|..L;2f.|
-000001a0  cf af b1 1d b8 71 9a 1d  db db 89 6b ae da 2d 79  |.....q.....k..-y|
-000001b0  02 03 01 00 01 a3 81 a7  30 81 a4 30 1d 06 03 55  |........0..0...U|
-000001c0  1d 0e 04 16 04 14 b1 ad  e2 85 5a cf cb 28 db 69  |..........Z..(.i|
-000001d0  ce 23 69 de d3 26 8e 18  88 39 30 75 06 03 55 1d  |.#i..&...90u..U.|
-000001e0  23 04 6e 30 6c 80 14 b1  ad e2 85 5a cf cb 28 db  |#.n0l......Z..(.|
-000001f0  69 ce 23 69 de d3 26 8e  18 88 39 a1 49 a4 47 30  |i.#i..&...9.I.G0|
-00000200  45 31 0b 30 09 06 03 55  04 06 13 02 41 55 31 13  |E1.0...U....AU1.|
-00000210  30 11 06 03 55 04 08 13  0a 53 6f 6d 65 2d 53 74  |0...U....Some-St|
-00000220  61 74 65 31 21 30 1f 06  03 55 04 0a 13 18 49 6e  |ate1!0...U....In|
-00000230  74 65 72 6e 65 74 20 57  69 64 67 69 74 73 20 50  |ternet Widgits P|
-00000240  74 79 20 4c 74 64 82 09  00 85 b0 bb a4 8a 7f b8  |ty Ltd..........|
-00000250  ca 30 0c 06 03 55 1d 13  04 05 30 03 01 01 ff 30  |.0...U....0....0|
-00000260  0d 06 09 2a 86 48 86 f7  0d 01 01 05 05 00 03 81  |...*.H..........|
-00000270  81 00 08 6c 45 24 c7 6b  b1 59 ab 0c 52 cc f2 b0  |...lE$.k.Y..R...|
-00000280  14 d7 87 9d 7a 64 75 b5  5a 95 66 e4 c5 2b 8e ae  |....zdu.Z.f..+..|
-00000290  12 66 1f eb 4f 38 b3 6e  60 d3 92 fd f7 41 08 b5  |.f..O8.n`....A..|
-000002a0  25 13 b1 18 7a 24 fb 30  1d ba ed 98 b9 17 ec e7  |%...z$.0........|
-000002b0  d7 31 59 db 95 d3 1d 78  ea 50 56 5c d5 82 5a 2d  |.1Y....x.PV\..Z-|
-000002c0  5a 5f 33 c4 b6 d8 c9 75  90 96 8c 0f 52 98 b5 cd  |Z_3....u....R...|
-000002d0  98 1f 89 20 5f f2 a0 1c  a3 1b 96 94 dd a9 fd 57  |... _..........W|
-000002e0  e9 70 e8 26 6d 71 99 9b  26 6e 38 50 29 6c 90 a7  |.p.&mq..&n8P)l..|
-000002f0  bd d9 16 03 00 00 04 0e  00 00 00                 |...........|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 2f 00 00  |............./..|
+00000030  05 ff 01 00 01 00 16 03  00 02 be 0b 00 02 ba 00  |................|
+00000040  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
+00000050  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
+00000060  09 2a 86 48 86 f7 0d 01  01 05 05 00 30 45 31 0b  |.*.H........0E1.|
+00000070  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
+00000080  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
+00000090  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
+000000a0  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
+000000b0  4c 74 64 30 1e 17 0d 31  30 30 34 32 34 30 39 30  |Ltd0...100424090|
+000000c0  39 33 38 5a 17 0d 31 31  30 34 32 34 30 39 30 39  |938Z..1104240909|
+000000d0  33 38 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |38Z0E1.0...U....|
+000000e0  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
+000000f0  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
+00000100  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
+00000110  74 73 20 50 74 79 20 4c  74 64 30 81 9f 30 0d 06  |ts Pty Ltd0..0..|
+00000120  09 2a 86 48 86 f7 0d 01  01 01 05 00 03 81 8d 00  |.*.H............|
+00000130  30 81 89 02 81 81 00 bb  79 d6 f5 17 b5 e5 bf 46  |0.......y......F|
+00000140  10 d0 dc 69 be e6 2b 07  43 5a d0 03 2d 8a 7a 43  |...i..+.CZ..-.zC|
+00000150  85 b7 14 52 e7 a5 65 4c  2c 78 b8 23 8c b5 b4 82  |...R..eL,x.#....|
+00000160  e5 de 1f 95 3b 7e 62 a5  2c a5 33 d6 fe 12 5c 7a  |....;~b.,.3...\z|
+00000170  56 fc f5 06 bf fa 58 7b  26 3f b5 cd 04 d3 d0 c9  |V.....X{&?......|
+00000180  21 96 4a c7 f4 54 9f 5a  bf ef 42 71 00 fe 18 99  |!.J..T.Z..Bq....|
+00000190  07 7f 7e 88 7d 7d f1 04  39 c4 a2 2e db 51 c9 7c  |..~.}}..9....Q.||
+000001a0  e3 c0 4c 3b 32 66 01 cf  af b1 1d b8 71 9a 1d db  |..L;2f......q...|
+000001b0  db 89 6b ae da 2d 79 02  03 01 00 01 a3 81 a7 30  |..k..-y........0|
+000001c0  81 a4 30 1d 06 03 55 1d  0e 04 16 04 14 b1 ad e2  |..0...U.........|
+000001d0  85 5a cf cb 28 db 69 ce  23 69 de d3 26 8e 18 88  |.Z..(.i.#i..&...|
+000001e0  39 30 75 06 03 55 1d 23  04 6e 30 6c 80 14 b1 ad  |90u..U.#.n0l....|
+000001f0  e2 85 5a cf cb 28 db 69  ce 23 69 de d3 26 8e 18  |..Z..(.i.#i..&..|
+00000200  88 39 a1 49 a4 47 30 45  31 0b 30 09 06 03 55 04  |.9.I.G0E1.0...U.|
+00000210  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
+00000220  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
+00000230  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
+00000240  64 67 69 74 73 20 50 74  79 20 4c 74 64 82 09 00  |dgits Pty Ltd...|
+00000250  85 b0 bb a4 8a 7f b8 ca  30 0c 06 03 55 1d 13 04  |........0...U...|
+00000260  05 30 03 01 01 ff 30 0d  06 09 2a 86 48 86 f7 0d  |.0....0...*.H...|
+00000270  01 01 05 05 00 03 81 81  00 08 6c 45 24 c7 6b b1  |..........lE$.k.|
+00000280  59 ab 0c 52 cc f2 b0 14  d7 87 9d 7a 64 75 b5 5a  |Y..R.......zdu.Z|
+00000290  95 66 e4 c5 2b 8e ae 12  66 1f eb 4f 38 b3 6e 60  |.f..+...f..O8.n`|
+000002a0  d3 92 fd f7 41 08 b5 25  13 b1 18 7a 24 fb 30 1d  |....A..%...z$.0.|
+000002b0  ba ed 98 b9 17 ec e7 d7  31 59 db 95 d3 1d 78 ea  |........1Y....x.|
+000002c0  50 56 5c d5 82 5a 2d 5a  5f 33 c4 b6 d8 c9 75 90  |PV\..Z-Z_3....u.|
+000002d0  96 8c 0f 52 98 b5 cd 98  1f 89 20 5f f2 a0 1c a3  |...R...... _....|
+000002e0  1b 96 94 dd a9 fd 57 e9  70 e8 26 6d 71 99 9b 26  |......W.p.&mq..&|
+000002f0  6e 38 50 29 6c 90 a7 bd  d9 16 03 00 00 04 0e 00  |n8P)l...........|
+00000300  00 00                                             |..|
 >>> Flow 3 (client to server)
-00000000  16 03 00 00 84 10 00 00  80 00 0a a1 56 18 df ac  |............V...|
-00000010  c2 e2 64 41 17 df 7f 05  29 0a 72 65 46 ea c9 ff  |..dA....).reF...|
-00000020  c6 67 75 62 9a e8 46 05  e3 08 1a 14 ea e7 ff 35  |.gub..F........5|
-00000030  a8 d1 fa 96 cc e2 d8 d9  7a a3 40 64 37 96 54 29  |........z.@d7.T)|
-00000040  ad 72 7c 98 13 de c3 a8  fb c6 4a 6e 2a 8b e7 5f  |.r|.......Jn*.._|
-00000050  ef f3 c5 76 7f fb b3 24  ed 80 57 b6 ce 0e 53 65  |...v...$..W...Se|
-00000060  2b db da fd a5 6a ee 46  b4 2e 26 8c 53 d5 67 d4  |+....j.F..&.S.g.|
-00000070  8a 4c 56 58 40 68 7d b5  d7 51 f3 05 1f 68 b5 54  |.LVX@h}..Q...h.T|
-00000080  f5 91 86 71 cd 3c 6d 0a  d6 14 03 00 00 01 01 16  |...q.<m.........|
-00000090  03 00 00 40 1c 55 bc ea  55 12 63 36 f2 1a f4 ae  |...@.U..U.c6....|
-000000a0  34 51 d6 d0 63 e1 13 4c  d9 a0 a9 ac 3b cb 1e e4  |4Q..c..L....;...|
-000000b0  de 21 f7 bf ae 7f 27 31  cb 01 58 e4 b1 57 00 39  |.!....'1..X..W.9|
-000000c0  13 e0 e3 be 2b b1 24 cc  41 55 69 c4 f0 a6 cc 38  |....+.$.AUi....8|
-000000d0  e8 a8 ba c1                                       |....|
+00000000  16 03 00 00 84 10 00 00  80 74 50 05 6f f5 83 c9  |.........tP.o...|
+00000010  f5 0c 5a 65 c7 4e c6 f3  87 96 d7 5d 3e 88 27 32  |..Ze.N.....]>.'2|
+00000020  89 12 ba ec db ef c0 85  70 84 ed b6 83 03 8f 44  |........p......D|
+00000030  f5 6f fa fa d0 1f 95 30  d1 ae a7 71 cf ee e9 b1  |.o.....0...q....|
+00000040  80 7b 34 a9 ea 1b 5e e5  71 40 3f e8 7d 30 d1 8b  |.{4...^.q@?.}0..|
+00000050  11 f1 68 1f c8 25 f0 77  c5 af b3 92 6e d9 81 cc  |..h..%.w....n...|
+00000060  f8 fd 82 95 cc 1f 4a b1  05 15 7a b3 a1 22 33 09  |......J...z.."3.|
+00000070  e7 a5 c2 89 7f 03 e0 91  b6 61 a3 a0 4e 17 0d 7a  |.........a..N..z|
+00000080  13 01 c4 b6 50 c7 d9 81  15 14 03 00 00 01 01 16  |....P...........|
+00000090  03 00 00 40 56 da 56 ab  e6 26 98 58 53 1f 36 b5  |...@V.V..&.XS.6.|
+000000a0  03 14 bd 42 29 ee 9c 7c  e4 48 26 82 68 ae fd fe  |...B)..|.H&.h...|
+000000b0  5e a4 43 22 75 95 7b c8  77 88 fd d6 d4 9b c9 b5  |^.C"u.{.w.......|
+000000c0  ee 3e a6 e8 c5 04 90 63  3f ac be 56 67 da 30 d4  |.>.....c?..Vg.0.|
+000000d0  64 fb a8 a0                                       |d...|
 >>> Flow 4 (server to client)
-00000000  14 03 00 00 01 01 16 03  00 00 40 68 cb f5 14 f0  |..........@h....|
-00000010  42 7a 8c d6 69 09 37 24  92 82 ef 78 bb 4f f9 86  |Bz..i.7$...x.O..|
-00000020  9f f1 db 3c da 97 f1 02  ab f0 9d c9 8a 71 8e b4  |...<.........q..|
-00000030  ac 6f 83 1a 44 90 80 a3  3b 97 a2 7f 64 b9 63 b1  |.o..D...;...d.c.|
-00000040  6b 80 2a a5 5f 2d c3 14  b6 d5 0c 17 03 00 00 20  |k.*._-......... |
-00000050  b1 d5 04 a3 c4 05 f9 8d  96 84 78 a6 cb 8e 0a 04  |..........x.....|
-00000060  a9 e3 97 f9 dc f0 7a 7d  f5 44 0e e5 eb 80 83 9a  |......z}.D......|
-00000070  17 03 00 00 30 8d c7 b7  e4 ac 13 79 cc fb f8 74  |....0......y...t|
-00000080  00 cb 89 5c b0 fb bd 3c  f6 9f e0 72 02 34 4f d2  |...\...<...r.4O.|
-00000090  f5 6e 29 da 14 d2 11 45  85 dd ae 72 8e b6 4e eb  |.n)....E...r..N.|
-000000a0  56 cb a9 33 fd 15 03 00  00 20 10 46 5e 81 a1 29  |V..3..... .F^..)|
-000000b0  69 2b 66 52 6c d9 4b 8f  79 c0 7f d9 13 8a 67 99  |i+fRl.K.y.....g.|
-000000c0  14 b2 eb a8 2a 2e 2d b0  0f 5a                    |....*.-..Z|
+00000000  14 03 00 00 01 01 16 03  00 00 40 96 af fb 79 96  |..........@...y.|
+00000010  92 97 2d d0 67 46 1e 08  b5 35 65 ef dc bc 8e 57  |..-.gF...5e....W|
+00000020  53 b7 36 58 74 d7 88 b1  55 fc eb fa 2e f3 17 b7  |S.6Xt...U.......|
+00000030  62 58 a0 9d 99 e1 85 d4  33 e0 b4 1f 1d 94 f2 88  |bX......3.......|
+00000040  d5 9a 34 5b 74 cd d2 ff  87 bd 52 17 03 00 00 20  |..4[t.....R.... |
+00000050  c6 61 c2 28 ac d2 0c 08  7f f1 c2 62 af 37 7e 78  |.a.(.......b.7~x|
+00000060  e8 e2 a1 54 f2 3a 80 97  f8 47 64 f2 cd 94 dd 0b  |...T.:...Gd.....|
+00000070  17 03 00 00 30 b8 40 8f  a3 18 ff 03 84 d4 1c 28  |....0.@........(|
+00000080  82 ce d8 9a 81 3a dd 23  7c 65 d8 ca f7 f1 46 1b  |.....:.#|e....F.|
+00000090  70 f0 d7 d9 54 a7 71 e6  4d d4 25 61 5a e4 30 d3  |p...T.q.M.%aZ.0.|
+000000a0  4a 42 ae 26 a5 15 03 00  00 20 c4 e8 ed 40 57 00  |JB.&..... ...@W.|
+000000b0  dc a5 0e 82 90 47 92 08  dd 7e 50 6b 30 66 5e 90  |.....G...~Pk0f^.|
+000000c0  73 7c 81 93 8d 24 b1 06  e7 39                    |s|...$...9|
index 15c0e2213260e0dd8825515463f57a04640be08e..1314b659bf0b01a8fc4de19eacfe6c18b6d29699 100644 (file)
@@ -1,78 +1,79 @@
 >>> Flow 1 (client to server)
-00000000  16 03 00 00 30 01 00 00  2c 03 00 52 ac 77 f8 34  |....0...,..R.w.4|
-00000010  e1 b1 2e 93 67 6d 6e 49  b5 9d 74 06 e1 1b 73 92  |....gmnI..t...s.|
-00000020  0f c3 39 5f 4b 17 88 45  84 28 fd 00 00 04 00 05  |..9_K..E.(......|
-00000030  00 ff 02 01 00                                    |.....|
+00000000  16 03 00 00 2f 01 00 00  2b 03 00 52 cc 57 59 79  |..../...+..R.WYy|
+00000010  b9 3b ef df 53 fb 09 f6  01 e5 18 0a fc 3d 65 bb  |.;..S........=e.|
+00000020  cf 9c 4c 77 b1 e8 6b 4f  5f c7 94 00 00 04 00 05  |..Lw..kO_.......|
+00000030  00 ff 01 00                                       |....|
 >>> Flow 2 (server to client)
-00000000  16 03 00 00 2a 02 00 00  26 03 00 00 00 00 00 00  |....*...&.......|
+00000000  16 03 00 00 31 02 00 00  2d 03 00 00 00 00 00 00  |....1...-.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 05 00 16  |................|
-00000030  03 00 02 be 0b 00 02 ba  00 02 b7 00 02 b4 30 82  |..............0.|
-00000040  02 b0 30 82 02 19 a0 03  02 01 02 02 09 00 85 b0  |..0.............|
-00000050  bb a4 8a 7f b8 ca 30 0d  06 09 2a 86 48 86 f7 0d  |......0...*.H...|
-00000060  01 01 05 05 00 30 45 31  0b 30 09 06 03 55 04 06  |.....0E1.0...U..|
-00000070  13 02 41 55 31 13 30 11  06 03 55 04 08 13 0a 53  |..AU1.0...U....S|
-00000080  6f 6d 65 2d 53 74 61 74  65 31 21 30 1f 06 03 55  |ome-State1!0...U|
-00000090  04 0a 13 18 49 6e 74 65  72 6e 65 74 20 57 69 64  |....Internet Wid|
-000000a0  67 69 74 73 20 50 74 79  20 4c 74 64 30 1e 17 0d  |gits Pty Ltd0...|
-000000b0  31 30 30 34 32 34 30 39  30 39 33 38 5a 17 0d 31  |100424090938Z..1|
-000000c0  31 30 34 32 34 30 39 30  39 33 38 5a 30 45 31 0b  |10424090938Z0E1.|
-000000d0  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-000000e0  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-000000f0  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-00000100  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-00000110  4c 74 64 30 81 9f 30 0d  06 09 2a 86 48 86 f7 0d  |Ltd0..0...*.H...|
-00000120  01 01 01 05 00 03 81 8d  00 30 81 89 02 81 81 00  |.........0......|
-00000130  bb 79 d6 f5 17 b5 e5 bf  46 10 d0 dc 69 be e6 2b  |.y......F...i..+|
-00000140  07 43 5a d0 03 2d 8a 7a  43 85 b7 14 52 e7 a5 65  |.CZ..-.zC...R..e|
-00000150  4c 2c 78 b8 23 8c b5 b4  82 e5 de 1f 95 3b 7e 62  |L,x.#........;~b|
-00000160  a5 2c a5 33 d6 fe 12 5c  7a 56 fc f5 06 bf fa 58  |.,.3...\zV.....X|
-00000170  7b 26 3f b5 cd 04 d3 d0  c9 21 96 4a c7 f4 54 9f  |{&?......!.J..T.|
-00000180  5a bf ef 42 71 00 fe 18  99 07 7f 7e 88 7d 7d f1  |Z..Bq......~.}}.|
-00000190  04 39 c4 a2 2e db 51 c9  7c e3 c0 4c 3b 32 66 01  |.9....Q.|..L;2f.|
-000001a0  cf af b1 1d b8 71 9a 1d  db db 89 6b ae da 2d 79  |.....q.....k..-y|
-000001b0  02 03 01 00 01 a3 81 a7  30 81 a4 30 1d 06 03 55  |........0..0...U|
-000001c0  1d 0e 04 16 04 14 b1 ad  e2 85 5a cf cb 28 db 69  |..........Z..(.i|
-000001d0  ce 23 69 de d3 26 8e 18  88 39 30 75 06 03 55 1d  |.#i..&...90u..U.|
-000001e0  23 04 6e 30 6c 80 14 b1  ad e2 85 5a cf cb 28 db  |#.n0l......Z..(.|
-000001f0  69 ce 23 69 de d3 26 8e  18 88 39 a1 49 a4 47 30  |i.#i..&...9.I.G0|
-00000200  45 31 0b 30 09 06 03 55  04 06 13 02 41 55 31 13  |E1.0...U....AU1.|
-00000210  30 11 06 03 55 04 08 13  0a 53 6f 6d 65 2d 53 74  |0...U....Some-St|
-00000220  61 74 65 31 21 30 1f 06  03 55 04 0a 13 18 49 6e  |ate1!0...U....In|
-00000230  74 65 72 6e 65 74 20 57  69 64 67 69 74 73 20 50  |ternet Widgits P|
-00000240  74 79 20 4c 74 64 82 09  00 85 b0 bb a4 8a 7f b8  |ty Ltd..........|
-00000250  ca 30 0c 06 03 55 1d 13  04 05 30 03 01 01 ff 30  |.0...U....0....0|
-00000260  0d 06 09 2a 86 48 86 f7  0d 01 01 05 05 00 03 81  |...*.H..........|
-00000270  81 00 08 6c 45 24 c7 6b  b1 59 ab 0c 52 cc f2 b0  |...lE$.k.Y..R...|
-00000280  14 d7 87 9d 7a 64 75 b5  5a 95 66 e4 c5 2b 8e ae  |....zdu.Z.f..+..|
-00000290  12 66 1f eb 4f 38 b3 6e  60 d3 92 fd f7 41 08 b5  |.f..O8.n`....A..|
-000002a0  25 13 b1 18 7a 24 fb 30  1d ba ed 98 b9 17 ec e7  |%...z$.0........|
-000002b0  d7 31 59 db 95 d3 1d 78  ea 50 56 5c d5 82 5a 2d  |.1Y....x.PV\..Z-|
-000002c0  5a 5f 33 c4 b6 d8 c9 75  90 96 8c 0f 52 98 b5 cd  |Z_3....u....R...|
-000002d0  98 1f 89 20 5f f2 a0 1c  a3 1b 96 94 dd a9 fd 57  |... _..........W|
-000002e0  e9 70 e8 26 6d 71 99 9b  26 6e 38 50 29 6c 90 a7  |.p.&mq..&n8P)l..|
-000002f0  bd d9 16 03 00 00 04 0e  00 00 00                 |...........|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 05 00 00  |................|
+00000030  05 ff 01 00 01 00 16 03  00 02 be 0b 00 02 ba 00  |................|
+00000040  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
+00000050  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
+00000060  09 2a 86 48 86 f7 0d 01  01 05 05 00 30 45 31 0b  |.*.H........0E1.|
+00000070  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
+00000080  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
+00000090  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
+000000a0  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
+000000b0  4c 74 64 30 1e 17 0d 31  30 30 34 32 34 30 39 30  |Ltd0...100424090|
+000000c0  39 33 38 5a 17 0d 31 31  30 34 32 34 30 39 30 39  |938Z..1104240909|
+000000d0  33 38 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |38Z0E1.0...U....|
+000000e0  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
+000000f0  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
+00000100  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
+00000110  74 73 20 50 74 79 20 4c  74 64 30 81 9f 30 0d 06  |ts Pty Ltd0..0..|
+00000120  09 2a 86 48 86 f7 0d 01  01 01 05 00 03 81 8d 00  |.*.H............|
+00000130  30 81 89 02 81 81 00 bb  79 d6 f5 17 b5 e5 bf 46  |0.......y......F|
+00000140  10 d0 dc 69 be e6 2b 07  43 5a d0 03 2d 8a 7a 43  |...i..+.CZ..-.zC|
+00000150  85 b7 14 52 e7 a5 65 4c  2c 78 b8 23 8c b5 b4 82  |...R..eL,x.#....|
+00000160  e5 de 1f 95 3b 7e 62 a5  2c a5 33 d6 fe 12 5c 7a  |....;~b.,.3...\z|
+00000170  56 fc f5 06 bf fa 58 7b  26 3f b5 cd 04 d3 d0 c9  |V.....X{&?......|
+00000180  21 96 4a c7 f4 54 9f 5a  bf ef 42 71 00 fe 18 99  |!.J..T.Z..Bq....|
+00000190  07 7f 7e 88 7d 7d f1 04  39 c4 a2 2e db 51 c9 7c  |..~.}}..9....Q.||
+000001a0  e3 c0 4c 3b 32 66 01 cf  af b1 1d b8 71 9a 1d db  |..L;2f......q...|
+000001b0  db 89 6b ae da 2d 79 02  03 01 00 01 a3 81 a7 30  |..k..-y........0|
+000001c0  81 a4 30 1d 06 03 55 1d  0e 04 16 04 14 b1 ad e2  |..0...U.........|
+000001d0  85 5a cf cb 28 db 69 ce  23 69 de d3 26 8e 18 88  |.Z..(.i.#i..&...|
+000001e0  39 30 75 06 03 55 1d 23  04 6e 30 6c 80 14 b1 ad  |90u..U.#.n0l....|
+000001f0  e2 85 5a cf cb 28 db 69  ce 23 69 de d3 26 8e 18  |..Z..(.i.#i..&..|
+00000200  88 39 a1 49 a4 47 30 45  31 0b 30 09 06 03 55 04  |.9.I.G0E1.0...U.|
+00000210  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
+00000220  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
+00000230  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
+00000240  64 67 69 74 73 20 50 74  79 20 4c 74 64 82 09 00  |dgits Pty Ltd...|
+00000250  85 b0 bb a4 8a 7f b8 ca  30 0c 06 03 55 1d 13 04  |........0...U...|
+00000260  05 30 03 01 01 ff 30 0d  06 09 2a 86 48 86 f7 0d  |.0....0...*.H...|
+00000270  01 01 05 05 00 03 81 81  00 08 6c 45 24 c7 6b b1  |..........lE$.k.|
+00000280  59 ab 0c 52 cc f2 b0 14  d7 87 9d 7a 64 75 b5 5a  |Y..R.......zdu.Z|
+00000290  95 66 e4 c5 2b 8e ae 12  66 1f eb 4f 38 b3 6e 60  |.f..+...f..O8.n`|
+000002a0  d3 92 fd f7 41 08 b5 25  13 b1 18 7a 24 fb 30 1d  |....A..%...z$.0.|
+000002b0  ba ed 98 b9 17 ec e7 d7  31 59 db 95 d3 1d 78 ea  |........1Y....x.|
+000002c0  50 56 5c d5 82 5a 2d 5a  5f 33 c4 b6 d8 c9 75 90  |PV\..Z-Z_3....u.|
+000002d0  96 8c 0f 52 98 b5 cd 98  1f 89 20 5f f2 a0 1c a3  |...R...... _....|
+000002e0  1b 96 94 dd a9 fd 57 e9  70 e8 26 6d 71 99 9b 26  |......W.p.&mq..&|
+000002f0  6e 38 50 29 6c 90 a7 bd  d9 16 03 00 00 04 0e 00  |n8P)l...........|
+00000300  00 00                                             |..|
 >>> Flow 3 (client to server)
-00000000  16 03 00 00 84 10 00 00  80 a0 f8 7e 56 69 88 3a  |...........~Vi.:|
-00000010  75 b6 bc 7f 3f a5 15 0c  7a 33 7c 3d c9 84 ce 06  |u...?...z3|=....|
-00000020  52 a4 c3 47 8d 91 c1 0d  27 b6 56 a8 92 b8 b5 2c  |R..G....'.V....,|
-00000030  6b 19 54 3f 14 e2 d8 b5  39 6a 53 0a ba 3d 7f bc  |k.T?....9jS..=..|
-00000040  69 e5 fd 93 88 15 84 27  ea e0 ef f3 6b 17 5c 07  |i......'....k.\.|
-00000050  76 5f 71 0f 3e 94 d3 7b  2f 63 88 03 5e 79 28 d9  |v_q.>..{/c..^y(.|
-00000060  e8 c7 fc 65 b1 5a a3 91  1c fe cc a3 f6 13 d3 a2  |...e.Z..........|
-00000070  7c e0 5f 51 97 a3 a7 32  14 c5 d4 fa 09 5d de 04  ||._Q...2.....]..|
-00000080  59 7d 78 af 1e e5 d9 99  68 14 03 00 00 01 01 16  |Y}x.....h.......|
-00000090  03 00 00 3c de c0 8f 60  be 89 4f 61 5e 88 72 50  |...<...`..Oa^.rP|
-000000a0  b4 c8 e0 ff 9d 91 2e c4  ba 11 3e fb 92 ba dd ab  |..........>.....|
-000000b0  96 ba 56 91 78 70 f6 fe  73 fb a3 85 47 28 9e 57  |..V.xp..s...G(.W|
-000000c0  80 18 f0 e7 44 d6 0c a6  6e 5a 03 9e c1 7a f3 a4  |....D...nZ...z..|
+00000000  16 03 00 00 84 10 00 00  80 4d 66 7a f3 f8 ab 86  |.........Mfz....|
+00000010  43 4c 5f 7c 52 ca e7 3f  ba 62 b3 82 88 16 7d ca  |CL_|R..?.b....}.|
+00000020  3a 66 15 c0 36 55 2c ab  bf 30 6b cd 9c d8 b9 48  |:f..6U,..0k....H|
+00000030  03 c9 d0 98 ab 0b a6 5b  39 c8 fe 82 8e bb f0 16  |.......[9.......|
+00000040  6f 96 62 81 f2 dc 52 02  c9 de e4 47 73 21 6e 1e  |o.b...R....Gs!n.|
+00000050  3a 11 89 7a e2 6b 9e 04  64 72 15 ba 2d 10 a2 69  |:..z.k..dr..-..i|
+00000060  07 e6 ba 17 cf 54 d6 4e  5f 99 e8 59 8b 54 ce 8e  |.....T.N_..Y.T..|
+00000070  6b 58 ba 83 68 46 4a 5f  43 3e 9b e1 32 a2 19 42  |kX..hFJ_C>..2..B|
+00000080  46 0f e4 47 1a 3b 16 5f  e1 14 03 00 00 01 01 16  |F..G.;._........|
+00000090  03 00 00 3c 78 7e ee da  0d 38 0b 1a d6 d4 8e d5  |...<x~...8......|
+000000a0  6a c5 3a 0f 85 e7 37 a6  3c 8d 1e 4b da 02 94 bf  |j.:...7.<..K....|
+000000b0  ae 2c 50 3b 4e 1c 0c 3c  4f cc d5 1c da 33 13 43  |.,P;N..<O....3.C|
+000000c0  37 64 44 ac 26 43 28 0b  d0 c2 04 09 b5 0f 23 1d  |7dD.&C(.......#.|
 >>> Flow 4 (server to client)
-00000000  14 03 00 00 01 01 16 03  00 00 3c 8e ae 6b 37 56  |..........<..k7V|
-00000010  42 96 37 76 e9 48 a0 4d  67 5e e9 e0 48 4e 75 4d  |B.7v.H.Mg^..HNuM|
-00000020  a8 58 01 a5 e5 c2 0c ec  43 ae a1 86 8d 0f be fc  |.X......C.......|
-00000030  de c3 5c 15 c3 84 fc ed  6a 48 6f dd 22 94 4f 54  |..\.....jHo.".OT|
-00000040  83 ab 76 ab 38 ea a1 17  03 00 00 21 64 56 94 f9  |..v.8......!dV..|
-00000050  ba 22 a3 af 63 30 16 b0  23 54 e2 22 92 4e 67 5d  |."..c0..#T.".Ng]|
-00000060  a2 37 92 83 1f 28 78 bb  02 6b fe 4d de 15 03 00  |.7...(x..k.M....|
-00000070  00 16 c3 1b bb 58 03 ce  44 9b 3c 6e e9 75 ba 66  |.....X..D.<n.u.f|
-00000080  1c 03 08 19 75 64 9c 98                           |....ud..|
+00000000  14 03 00 00 01 01 16 03  00 00 3c 23 29 64 62 23  |..........<#)db#|
+00000010  19 20 f8 2e 15 07 ee c8  f4 ab f0 3e 66 c3 ed 7b  |. .........>f..{|
+00000020  7c a7 c2 7e c3 25 3c 8f  f3 04 dc 37 e8 fc 0a 1d  ||..~.%<....7....|
+00000030  fa 7a 09 d4 21 11 e3 24  21 4b 37 d1 85 cc 40 bf  |.z..!..$!K7...@.|
+00000040  bd bd f8 59 6b cd 73 17  03 00 00 21 47 1d ac 54  |...Yk.s....!G..T|
+00000050  bd 58 a6 c0 04 e2 0c 6b  66 64 5a 85 09 0e 47 fc  |.X.....kfdZ...G.|
+00000060  0b 57 ee f1 24 b6 89 57  46 be 6b 0d f2 15 03 00  |.W..$..WF.k.....|
+00000070  00 16 b4 f7 34 99 19 43  b6 b3 5a 8b c3 d2 67 2f  |....4..C..Z...g/|
+00000080  3b 19 1c 31 d4 f9 bd 96                           |;..1....|
index e824b152fe3aa0840aabf3120c0ce29bb330247d..d90f02bd3556017ea03d33566dc6adac1b9d4039 100644 (file)
@@ -1,92 +1,93 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 77 01 00 00  73 03 01 52 ac 77 f8 0f  |....w...s..R.w..|
-00000010  da f5 85 29 f9 40 1c fd  b5 88 59 30 92 9d 24 66  |...).@....Y0..$f|
-00000020  d5 14 a0 f2 f3 31 5f 55  a2 6e 49 00 00 04 c0 0a  |.....1_U.nI.....|
-00000030  00 ff 02 01 00 00 45 00  0b 00 04 03 00 01 02 00  |......E.........|
-00000040  0a 00 34 00 32 00 0e 00  0d 00 19 00 0b 00 0c 00  |..4.2...........|
-00000050  18 00 09 00 0a 00 16 00  17 00 08 00 06 00 07 00  |................|
-00000060  14 00 15 00 04 00 05 00  12 00 13 00 01 00 02 00  |................|
-00000070  03 00 0f 00 10 00 11 00  0f 00 01 01              |............|
+00000000  16 03 01 00 76 01 00 00  72 03 01 52 cc 57 59 19  |....v...r..R.WY.|
+00000010  3d b7 7c 4b 54 8d ca 3a  b1 4c 4e a9 78 86 d9 74  |=.|KT..:.LN.x..t|
+00000020  87 2f f3 86 bf ac cc f4  11 75 b7 00 00 04 c0 0a  |./.......u......|
+00000030  00 ff 01 00 00 45 00 0b  00 04 03 00 01 02 00 0a  |.....E..........|
+00000040  00 34 00 32 00 0e 00 0d  00 19 00 0b 00 0c 00 18  |.4.2............|
+00000050  00 09 00 0a 00 16 00 17  00 08 00 06 00 07 00 14  |................|
+00000060  00 15 00 04 00 05 00 12  00 13 00 01 00 02 00 03  |................|
+00000070  00 0f 00 10 00 11 00 0f  00 01 01                 |...........|
 >>> Flow 2 (server to client)
-00000000  16 03 01 00 2a 02 00 00  26 03 01 00 00 00 00 00  |....*...&.......|
+00000000  16 03 01 00 31 02 00 00  2d 03 01 00 00 00 00 00  |....1...-.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 c0 0a 00 16  |................|
-00000030  03 01 02 0e 0b 00 02 0a  00 02 07 00 02 04 30 82  |..............0.|
-00000040  02 00 30 82 01 62 02 09  00 b8 bf 2d 47 a0 d2 eb  |..0..b.....-G...|
-00000050  f4 30 09 06 07 2a 86 48  ce 3d 04 01 30 45 31 0b  |.0...*.H.=..0E1.|
-00000060  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-00000070  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-00000080  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-00000090  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-000000a0  4c 74 64 30 1e 17 0d 31  32 31 31 32 32 31 35 30  |Ltd0...121122150|
-000000b0  36 33 32 5a 17 0d 32 32  31 31 32 30 31 35 30 36  |632Z..2211201506|
-000000c0  33 32 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |32Z0E1.0...U....|
-000000d0  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
-000000e0  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
-000000f0  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
-00000100  74 73 20 50 74 79 20 4c  74 64 30 81 9b 30 10 06  |ts Pty Ltd0..0..|
-00000110  07 2a 86 48 ce 3d 02 01  06 05 2b 81 04 00 23 03  |.*.H.=....+...#.|
-00000120  81 86 00 04 00 c4 a1 ed  be 98 f9 0b 48 73 36 7e  |............Hs6~|
-00000130  c3 16 56 11 22 f2 3d 53  c3 3b 4d 21 3d cd 6b 75  |..V.".=S.;M!=.ku|
-00000140  e6 f6 b0 dc 9a df 26 c1  bc b2 87 f0 72 32 7c b3  |......&.....r2|.|
-00000150  64 2f 1c 90 bc ea 68 23  10 7e fe e3 25 c0 48 3a  |d/....h#.~..%.H:|
-00000160  69 e0 28 6d d3 37 00 ef  04 62 dd 0d a0 9c 70 62  |i.(m.7...b....pb|
-00000170  83 d8 81 d3 64 31 aa 9e  97 31 bd 96 b0 68 c0 9b  |....d1...1...h..|
-00000180  23 de 76 64 3f 1a 5c 7f  e9 12 0e 58 58 b6 5f 70  |#.vd?.\....XX._p|
-00000190  dd 9b d8 ea d5 d7 f5 d5  cc b9 b6 9f 30 66 5b 66  |............0f[f|
-000001a0  9a 20 e2 27 e5 bf fe 3b  30 09 06 07 2a 86 48 ce  |. .'...;0...*.H.|
-000001b0  3d 04 01 03 81 8c 00 30  81 88 02 42 01 88 a2 4f  |=......0...B...O|
-000001c0  eb e2 45 c5 48 7d 1b ac  f5 ed 98 9d ae 47 70 c0  |..E.H}.......Gp.|
-000001d0  5e 1b b6 2f bd f1 b6 4d  b7 61 40 d3 11 a2 ce ee  |^../...M.a@.....|
-000001e0  0b 7e 92 7e ff 76 9d c3  3b 7e a5 3f ce fa 10 e2  |.~.~.v..;~.?....|
-000001f0  59 ec 47 2d 7c ac da 4e  97 0e 15 a0 6f d0 02 42  |Y.G-|..N....o..B|
-00000200  01 4d fc be 67 13 9c 2d  05 0e bd 3f a3 8c 25 c1  |.M..g..-...?..%.|
-00000210  33 13 83 0d 94 06 bb d4  37 7a f6 ec 7a c9 86 2e  |3.......7z..z...|
-00000220  dd d7 11 69 7f 85 7c 56  de fb 31 78 2b e4 c7 78  |...i..|V..1x+..x|
-00000230  0d ae cb be 9e 4e 36 24  31 7b 6a 0f 39 95 12 07  |.....N6$1{j.9...|
-00000240  8f 2a 16 03 01 01 1a 0c  00 01 16 03 00 19 85 04  |.*..............|
-00000250  01 39 dc ee 44 17 5e db  d7 27 af b6 56 d9 b4 43  |.9..D.^..'..V..C|
-00000260  5a 99 cf aa 31 37 0c 6f  3a a0 f8 53 c4 74 d1 91  |Z...17.o:..S.t..|
-00000270  0a 46 f5 38 3b 5c 09 d8  97 dc 4b aa 70 26 48 f2  |.F.8;\....K.p&H.|
-00000280  d6 0b 31 c9 f8 d4 98 43  e1 6c d5 c7 b2 8e 0b 01  |..1....C.l......|
-00000290  e6 b6 00 28 80 7b fc 96  8f 0d a2 4f b0 79 af dc  |...(.{.....O.y..|
-000002a0  61 28 63 33 78 f6 31 39  fd 8a f4 15 18 11 fe db  |a(c3x.19........|
-000002b0  d5 07 da 2c ed 49 a0 23  bf d0 3a 38 1d 54 ae 1c  |...,.I.#..:8.T..|
-000002c0  7b ea 29 ee d0 38 c1 76  a7 7f 2a f4 ce 1e ac cc  |{.)..8.v..*.....|
-000002d0  94 79 90 33 00 8b 30 81  88 02 42 00 c6 85 8e 06  |.y.3..0...B.....|
-000002e0  b7 04 04 e9 cd 9e 3e cb  66 23 95 b4 42 9c 64 81  |......>.f#..B.d.|
-000002f0  39 05 3f b5 21 f8 28 af  60 6b 4d 3d ba a1 4b 5e  |9.?.!.(.`kM=..K^|
-00000300  77 ef e7 59 28 fe 1d c1  27 a2 ff a8 de 33 48 b3  |w..Y(...'....3H.|
-00000310  c1 85 6a 42 9b f9 7e 7e  31 c2 e5 bd 66 02 42 00  |..jB..~~1...f.B.|
-00000320  ad 7d 06 35 ab ec 8d ac  d4 ba 1b 49 5e 05 5f f0  |.}.5.......I^._.|
-00000330  97 93 82 b8 2b 8d 91 98  63 8e b4 14 62 db 1e c9  |....+...c...b...|
-00000340  2b 30 f8 41 9b a6 e6 bc  de 0e 68 30 21 d7 c5 13  |+0.A......h0!...|
-00000350  c5 0d 59 07 a1 c7 28 ca  0c e3 9b 45 fa d3 04 fb  |..Y...(....E....|
-00000360  31 16 03 01 00 04 0e 00  00 00                    |1.........|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 c0 0a 00 00  |................|
+00000030  05 ff 01 00 01 00 16 03  01 02 0e 0b 00 02 0a 00  |................|
+00000040  02 07 00 02 04 30 82 02  00 30 82 01 62 02 09 00  |.....0...0..b...|
+00000050  b8 bf 2d 47 a0 d2 eb f4  30 09 06 07 2a 86 48 ce  |..-G....0...*.H.|
+00000060  3d 04 01 30 45 31 0b 30  09 06 03 55 04 06 13 02  |=..0E1.0...U....|
+00000070  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
+00000080  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
+00000090  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
+000000a0  74 73 20 50 74 79 20 4c  74 64 30 1e 17 0d 31 32  |ts Pty Ltd0...12|
+000000b0  31 31 32 32 31 35 30 36  33 32 5a 17 0d 32 32 31  |1122150632Z..221|
+000000c0  31 32 30 31 35 30 36 33  32 5a 30 45 31 0b 30 09  |120150632Z0E1.0.|
+000000d0  06 03 55 04 06 13 02 41  55 31 13 30 11 06 03 55  |..U....AU1.0...U|
+000000e0  04 08 13 0a 53 6f 6d 65  2d 53 74 61 74 65 31 21  |....Some-State1!|
+000000f0  30 1f 06 03 55 04 0a 13  18 49 6e 74 65 72 6e 65  |0...U....Interne|
+00000100  74 20 57 69 64 67 69 74  73 20 50 74 79 20 4c 74  |t Widgits Pty Lt|
+00000110  64 30 81 9b 30 10 06 07  2a 86 48 ce 3d 02 01 06  |d0..0...*.H.=...|
+00000120  05 2b 81 04 00 23 03 81  86 00 04 00 c4 a1 ed be  |.+...#..........|
+00000130  98 f9 0b 48 73 36 7e c3  16 56 11 22 f2 3d 53 c3  |...Hs6~..V.".=S.|
+00000140  3b 4d 21 3d cd 6b 75 e6  f6 b0 dc 9a df 26 c1 bc  |;M!=.ku......&..|
+00000150  b2 87 f0 72 32 7c b3 64  2f 1c 90 bc ea 68 23 10  |...r2|.d/....h#.|
+00000160  7e fe e3 25 c0 48 3a 69  e0 28 6d d3 37 00 ef 04  |~..%.H:i.(m.7...|
+00000170  62 dd 0d a0 9c 70 62 83  d8 81 d3 64 31 aa 9e 97  |b....pb....d1...|
+00000180  31 bd 96 b0 68 c0 9b 23  de 76 64 3f 1a 5c 7f e9  |1...h..#.vd?.\..|
+00000190  12 0e 58 58 b6 5f 70 dd  9b d8 ea d5 d7 f5 d5 cc  |..XX._p.........|
+000001a0  b9 b6 9f 30 66 5b 66 9a  20 e2 27 e5 bf fe 3b 30  |...0f[f. .'...;0|
+000001b0  09 06 07 2a 86 48 ce 3d  04 01 03 81 8c 00 30 81  |...*.H.=......0.|
+000001c0  88 02 42 01 88 a2 4f eb  e2 45 c5 48 7d 1b ac f5  |..B...O..E.H}...|
+000001d0  ed 98 9d ae 47 70 c0 5e  1b b6 2f bd f1 b6 4d b7  |....Gp.^../...M.|
+000001e0  61 40 d3 11 a2 ce ee 0b  7e 92 7e ff 76 9d c3 3b  |a@......~.~.v..;|
+000001f0  7e a5 3f ce fa 10 e2 59  ec 47 2d 7c ac da 4e 97  |~.?....Y.G-|..N.|
+00000200  0e 15 a0 6f d0 02 42 01  4d fc be 67 13 9c 2d 05  |...o..B.M..g..-.|
+00000210  0e bd 3f a3 8c 25 c1 33  13 83 0d 94 06 bb d4 37  |..?..%.3.......7|
+00000220  7a f6 ec 7a c9 86 2e dd  d7 11 69 7f 85 7c 56 de  |z..z......i..|V.|
+00000230  fb 31 78 2b e4 c7 78 0d  ae cb be 9e 4e 36 24 31  |.1x+..x.....N6$1|
+00000240  7b 6a 0f 39 95 12 07 8f  2a 16 03 01 01 1a 0c 00  |{j.9....*.......|
+00000250  01 16 03 00 19 85 04 01  39 dc ee 44 17 5e db d7  |........9..D.^..|
+00000260  27 af b6 56 d9 b4 43 5a  99 cf aa 31 37 0c 6f 3a  |'..V..CZ...17.o:|
+00000270  a0 f8 53 c4 74 d1 91 0a  46 f5 38 3b 5c 09 d8 97  |..S.t...F.8;\...|
+00000280  dc 4b aa 70 26 48 f2 d6  0b 31 c9 f8 d4 98 43 e1  |.K.p&H...1....C.|
+00000290  6c d5 c7 b2 8e 0b 01 e6  b6 00 28 80 7b fc 96 8f  |l.........(.{...|
+000002a0  0d a2 4f b0 79 af dc 61  28 63 33 78 f6 31 39 fd  |..O.y..a(c3x.19.|
+000002b0  8a f4 15 18 11 fe db d5  07 da 2c ed 49 a0 23 bf  |..........,.I.#.|
+000002c0  d0 3a 38 1d 54 ae 1c 7b  ea 29 ee d0 38 c1 76 a7  |.:8.T..{.)..8.v.|
+000002d0  7f 2a f4 ce 1e ac cc 94  79 90 33 00 8b 30 81 88  |.*......y.3..0..|
+000002e0  02 42 00 c6 85 8e 06 b7  04 04 e9 cd 9e 3e cb 66  |.B...........>.f|
+000002f0  23 95 b4 42 9c 64 81 39  05 3f b5 21 f8 28 af 60  |#..B.d.9.?.!.(.`|
+00000300  6b 4d 3d ba a1 4b 5e 77  ef e7 59 28 fe 1d c1 27  |kM=..K^w..Y(...'|
+00000310  a2 ff a8 de 33 48 b3 c1  85 6a 42 9b f9 7e 7e 31  |....3H...jB..~~1|
+00000320  c2 e5 bd 66 02 42 00 ad  7d 06 35 ab ec 8d ac d4  |...f.B..}.5.....|
+00000330  ba 1b 49 5e 05 5f f0 97  93 82 b8 2b 8d 91 98 63  |..I^._.....+...c|
+00000340  8e b4 14 62 db 1e c9 2b  30 f8 41 9b a6 e6 bc de  |...b...+0.A.....|
+00000350  0e 68 30 21 e4 33 62 b4  3c 00 12 33 3c d2 bb 9e  |.h0!.3b.<..3<...|
+00000360  a9 db ef 22 41 ed 2b 1a  16 03 01 00 04 0e 00 00  |..."A.+.........|
+00000370  00                                                |.|
 >>> Flow 3 (client to server)
-00000000  16 03 01 00 8a 10 00 00  86 85 04 00 dc a9 a1 fb  |................|
-00000010  01 f0 3c 35 4f f0 67 6c  7b de 7d dc 6e bb 59 6f  |..<5O.gl{.}.n.Yo|
-00000020  5b 42 57 b1 55 c6 78 28  69 cb c5 c0 c1 e3 b5 89  |[BW.U.x(i.......|
-00000030  dd 03 20 6b d2 08 17 50  68 11 64 ad 0c 2f aa 4f  |.. k...Ph.d../.O|
-00000040  df ea e1 b9 1a 3c 92 ec  e7 78 f4 19 f8 01 77 e0  |.....<...x....w.|
-00000050  e2 c5 a2 d1 39 e3 e4 6b  78 0c 70 ae d4 2b 9f e4  |....9..kx.p..+..|
-00000060  79 a2 ab 23 82 9e ec 3c  7c 62 f1 66 b9 9a 06 4f  |y..#...<|b.f...O|
-00000070  49 a0 39 79 b4 32 7a 38  0e 6c ec e0 aa fc e2 d9  |I.9y.2z8.l......|
-00000080  fe 2a c0 88 bc 9c 29 8c  78 06 bb bc 5d 0f 01 14  |.*....).x...]...|
-00000090  03 01 00 01 01 16 03 01  00 30 76 33 00 79 15 52  |.........0v3.y.R|
-000000a0  12 d8 c0 34 74 b3 50 76  98 e3 29 db 30 9c 82 1f  |...4t.Pv..).0...|
-000000b0  89 47 b7 ab 26 bc 19 d8  b1 49 7b f8 d2 71 88 b0  |.G..&....I{..q..|
-000000c0  05 c4 0d 96 54 d2 61 c4  ad b8                    |....T.a...|
+00000000  16 03 01 00 8a 10 00 00  86 85 04 00 be 44 15 9d  |.............D..|
+00000010  89 bc 13 e7 55 cf 7a f9  b1 dc 2b 22 f2 7b a6 33  |....U.z...+".{.3|
+00000020  b6 46 de 7d c2 08 a6 67  15 7d 3e c2 02 d4 30 dc  |.F.}...g.}>...0.|
+00000030  35 37 7e ee fb 12 8c 74  c0 bf ea db 72 06 cd 52  |57~....t....r..R|
+00000040  1a e9 36 2e c5 5d 22 9e  56 e5 8d 9f a5 01 e2 e6  |..6..]".V.......|
+00000050  f5 77 64 05 80 c0 e3 54  9a 89 76 f9 73 64 7d 0e  |.wd....T..v.sd}.|
+00000060  bf d7 b3 57 a2 6c 4a 34  80 53 96 90 61 56 34 ad  |...W.lJ4.S..aV4.|
+00000070  75 44 54 79 dd 71 16 fe  4f 27 4f d0 0c d0 1e b6  |uDTy.q..O'O.....|
+00000080  82 c4 b2 e9 a1 87 fd a7  2a 6a 5d 79 b8 f1 4e 14  |........*j]y..N.|
+00000090  03 01 00 01 01 16 03 01  00 30 db c5 5f 9b 03 77  |.........0.._..w|
+000000a0  c9 aa 5e 74 fd 0c f7 28  fe 40 8b 0e 2d 85 1e 25  |..^t...(.@..-..%|
+000000b0  96 23 79 48 2c 3f 5d 9b  57 f0 34 8d 87 81 13 d9  |.#yH,?].W.4.....|
+000000c0  ed 72 f6 51 bf d7 6e 8b  61 3d                    |.r.Q..n.a=|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 30 7a 2a 1b a8 08  |..........0z*...|
-00000010  56 fa a3 93 04 45 31 8d  8b 9b 55 36 bb 5b 18 53  |V....E1...U6.[.S|
-00000020  b5 da d6 9f 51 89 a5 b5  ff 8d 26 24 df 05 1e 09  |....Q.....&$....|
-00000030  ee 7d 59 d3 e0 8b 9b d7  10 93 ce 17 03 01 00 20  |.}Y............ |
-00000040  b0 68 94 01 e0 38 37 6d  5c 4e ec 9d 77 f7 e6 a8  |.h...87m\N..w...|
-00000050  1a 06 bd ec 9f a2 63 ce  25 10 d2 ad 48 00 30 8f  |......c.%...H.0.|
-00000060  17 03 01 00 30 6f c4 67  87 d4 b2 1e 32 31 44 23  |....0o.g....21D#|
-00000070  54 45 95 99 16 7a 83 32  86 75 5d 14 d1 ae 65 3c  |TE...z.2.u]...e<|
-00000080  71 2c c7 ca 84 4a ea 1d  6a 54 33 6f d6 38 21 4d  |q,...J..jT3o.8!M|
-00000090  e0 6c 64 a9 58 15 03 01  00 20 8f 9e 96 b1 74 b0  |.ld.X.... ....t.|
-000000a0  93 1e 6b ba c3 ce 53 f5  0a 11 ae cb 08 ac 1d 2c  |..k...S........,|
-000000b0  e4 79 9a 6b bf fb db 0b  29 a1                    |.y.k....).|
+00000000  14 03 01 00 01 01 16 03  01 00 30 95 b6 20 60 88  |..........0.. `.|
+00000010  5f 23 11 06 83 f5 20 2d  42 77 36 c2 84 1b 70 90  |_#.... -Bw6...p.|
+00000020  12 af d3 5e fa b0 59 6b  1e 91 0a c3 e0 37 40 94  |...^..Yk.....7@.|
+00000030  07 c0 2b 84 74 41 fa fd  7c 41 59 17 03 01 00 20  |..+.tA..|AY.... |
+00000040  de a7 ea 4e f8 88 22 6d  cb 3d d5 ed 60 7c b9 a0  |...N.."m.=..`|..|
+00000050  ba c5 19 14 86 3a 98 ea  d3 73 68 1e d4 f8 0e 12  |.....:...sh.....|
+00000060  17 03 01 00 30 30 50 48  84 2e b0 15 0a 5f 64 3c  |....00PH....._d<|
+00000070  fc 19 aa 89 7d 6e ba 84  56 56 66 15 6e d4 b9 35  |....}n..VVf.n..5|
+00000080  20 ac 98 0d 8d 09 e1 80  8d 32 c8 99 d2 70 41 3a  | ........2...pA:|
+00000090  9b 62 d6 48 b1 15 03 01  00 20 9a 16 01 aa d0 6f  |.b.H..... .....o|
+000000a0  d4 d3 bb 5d 57 c0 7c d1  a8 d4 67 5d 5e 1d be 7d  |...]W.|...g]^..}|
+000000b0  d2 78 4a 33 93 ae 53 cc  fb a0                    |.xJ3..S...|
index a93c2dbcc4e69b076be2af3e8362e21d1be17249..c0e6241c07ea0b9a60b07f5dce7a7f216a296483 100644 (file)
@@ -1,78 +1,79 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 37 01 00 00  33 03 01 52 ac 77 f8 13  |....7...3..R.w..|
-00000010  46 58 6c 7e 9a 3d 5b 13  de 27 23 60 5a a9 8e 0b  |FXl~.=[..'#`Z...|
-00000020  b9 f0 f8 f9 ad d5 fc f9  c2 50 10 00 00 04 00 0a  |.........P......|
-00000030  00 ff 02 01 00 00 05 00  0f 00 01 01              |............|
+00000000  16 03 01 00 36 01 00 00  32 03 01 52 cc 57 59 13  |....6...2..R.WY.|
+00000010  8b e6 5b a3 1d cb 94 ef  48 e4 59 7e 20 6d 07 67  |..[.....H.Y~ m.g|
+00000020  1e 28 6d 31 a2 e7 96 b3  7d 32 cc 00 00 04 00 0a  |.(m1....}2......|
+00000030  00 ff 01 00 00 05 00 0f  00 01 01                 |...........|
 >>> Flow 2 (server to client)
-00000000  16 03 01 00 2a 02 00 00  26 03 01 00 00 00 00 00  |....*...&.......|
+00000000  16 03 01 00 31 02 00 00  2d 03 01 00 00 00 00 00  |....1...-.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 0a 00 16  |................|
-00000030  03 01 02 be 0b 00 02 ba  00 02 b7 00 02 b4 30 82  |..............0.|
-00000040  02 b0 30 82 02 19 a0 03  02 01 02 02 09 00 85 b0  |..0.............|
-00000050  bb a4 8a 7f b8 ca 30 0d  06 09 2a 86 48 86 f7 0d  |......0...*.H...|
-00000060  01 01 05 05 00 30 45 31  0b 30 09 06 03 55 04 06  |.....0E1.0...U..|
-00000070  13 02 41 55 31 13 30 11  06 03 55 04 08 13 0a 53  |..AU1.0...U....S|
-00000080  6f 6d 65 2d 53 74 61 74  65 31 21 30 1f 06 03 55  |ome-State1!0...U|
-00000090  04 0a 13 18 49 6e 74 65  72 6e 65 74 20 57 69 64  |....Internet Wid|
-000000a0  67 69 74 73 20 50 74 79  20 4c 74 64 30 1e 17 0d  |gits Pty Ltd0...|
-000000b0  31 30 30 34 32 34 30 39  30 39 33 38 5a 17 0d 31  |100424090938Z..1|
-000000c0  31 30 34 32 34 30 39 30  39 33 38 5a 30 45 31 0b  |10424090938Z0E1.|
-000000d0  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-000000e0  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-000000f0  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-00000100  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-00000110  4c 74 64 30 81 9f 30 0d  06 09 2a 86 48 86 f7 0d  |Ltd0..0...*.H...|
-00000120  01 01 01 05 00 03 81 8d  00 30 81 89 02 81 81 00  |.........0......|
-00000130  bb 79 d6 f5 17 b5 e5 bf  46 10 d0 dc 69 be e6 2b  |.y......F...i..+|
-00000140  07 43 5a d0 03 2d 8a 7a  43 85 b7 14 52 e7 a5 65  |.CZ..-.zC...R..e|
-00000150  4c 2c 78 b8 23 8c b5 b4  82 e5 de 1f 95 3b 7e 62  |L,x.#........;~b|
-00000160  a5 2c a5 33 d6 fe 12 5c  7a 56 fc f5 06 bf fa 58  |.,.3...\zV.....X|
-00000170  7b 26 3f b5 cd 04 d3 d0  c9 21 96 4a c7 f4 54 9f  |{&?......!.J..T.|
-00000180  5a bf ef 42 71 00 fe 18  99 07 7f 7e 88 7d 7d f1  |Z..Bq......~.}}.|
-00000190  04 39 c4 a2 2e db 51 c9  7c e3 c0 4c 3b 32 66 01  |.9....Q.|..L;2f.|
-000001a0  cf af b1 1d b8 71 9a 1d  db db 89 6b ae da 2d 79  |.....q.....k..-y|
-000001b0  02 03 01 00 01 a3 81 a7  30 81 a4 30 1d 06 03 55  |........0..0...U|
-000001c0  1d 0e 04 16 04 14 b1 ad  e2 85 5a cf cb 28 db 69  |..........Z..(.i|
-000001d0  ce 23 69 de d3 26 8e 18  88 39 30 75 06 03 55 1d  |.#i..&...90u..U.|
-000001e0  23 04 6e 30 6c 80 14 b1  ad e2 85 5a cf cb 28 db  |#.n0l......Z..(.|
-000001f0  69 ce 23 69 de d3 26 8e  18 88 39 a1 49 a4 47 30  |i.#i..&...9.I.G0|
-00000200  45 31 0b 30 09 06 03 55  04 06 13 02 41 55 31 13  |E1.0...U....AU1.|
-00000210  30 11 06 03 55 04 08 13  0a 53 6f 6d 65 2d 53 74  |0...U....Some-St|
-00000220  61 74 65 31 21 30 1f 06  03 55 04 0a 13 18 49 6e  |ate1!0...U....In|
-00000230  74 65 72 6e 65 74 20 57  69 64 67 69 74 73 20 50  |ternet Widgits P|
-00000240  74 79 20 4c 74 64 82 09  00 85 b0 bb a4 8a 7f b8  |ty Ltd..........|
-00000250  ca 30 0c 06 03 55 1d 13  04 05 30 03 01 01 ff 30  |.0...U....0....0|
-00000260  0d 06 09 2a 86 48 86 f7  0d 01 01 05 05 00 03 81  |...*.H..........|
-00000270  81 00 08 6c 45 24 c7 6b  b1 59 ab 0c 52 cc f2 b0  |...lE$.k.Y..R...|
-00000280  14 d7 87 9d 7a 64 75 b5  5a 95 66 e4 c5 2b 8e ae  |....zdu.Z.f..+..|
-00000290  12 66 1f eb 4f 38 b3 6e  60 d3 92 fd f7 41 08 b5  |.f..O8.n`....A..|
-000002a0  25 13 b1 18 7a 24 fb 30  1d ba ed 98 b9 17 ec e7  |%...z$.0........|
-000002b0  d7 31 59 db 95 d3 1d 78  ea 50 56 5c d5 82 5a 2d  |.1Y....x.PV\..Z-|
-000002c0  5a 5f 33 c4 b6 d8 c9 75  90 96 8c 0f 52 98 b5 cd  |Z_3....u....R...|
-000002d0  98 1f 89 20 5f f2 a0 1c  a3 1b 96 94 dd a9 fd 57  |... _..........W|
-000002e0  e9 70 e8 26 6d 71 99 9b  26 6e 38 50 29 6c 90 a7  |.p.&mq..&n8P)l..|
-000002f0  bd d9 16 03 01 00 04 0e  00 00 00                 |...........|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 0a 00 00  |................|
+00000030  05 ff 01 00 01 00 16 03  01 02 be 0b 00 02 ba 00  |................|
+00000040  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
+00000050  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
+00000060  09 2a 86 48 86 f7 0d 01  01 05 05 00 30 45 31 0b  |.*.H........0E1.|
+00000070  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
+00000080  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
+00000090  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
+000000a0  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
+000000b0  4c 74 64 30 1e 17 0d 31  30 30 34 32 34 30 39 30  |Ltd0...100424090|
+000000c0  39 33 38 5a 17 0d 31 31  30 34 32 34 30 39 30 39  |938Z..1104240909|
+000000d0  33 38 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |38Z0E1.0...U....|
+000000e0  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
+000000f0  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
+00000100  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
+00000110  74 73 20 50 74 79 20 4c  74 64 30 81 9f 30 0d 06  |ts Pty Ltd0..0..|
+00000120  09 2a 86 48 86 f7 0d 01  01 01 05 00 03 81 8d 00  |.*.H............|
+00000130  30 81 89 02 81 81 00 bb  79 d6 f5 17 b5 e5 bf 46  |0.......y......F|
+00000140  10 d0 dc 69 be e6 2b 07  43 5a d0 03 2d 8a 7a 43  |...i..+.CZ..-.zC|
+00000150  85 b7 14 52 e7 a5 65 4c  2c 78 b8 23 8c b5 b4 82  |...R..eL,x.#....|
+00000160  e5 de 1f 95 3b 7e 62 a5  2c a5 33 d6 fe 12 5c 7a  |....;~b.,.3...\z|
+00000170  56 fc f5 06 bf fa 58 7b  26 3f b5 cd 04 d3 d0 c9  |V.....X{&?......|
+00000180  21 96 4a c7 f4 54 9f 5a  bf ef 42 71 00 fe 18 99  |!.J..T.Z..Bq....|
+00000190  07 7f 7e 88 7d 7d f1 04  39 c4 a2 2e db 51 c9 7c  |..~.}}..9....Q.||
+000001a0  e3 c0 4c 3b 32 66 01 cf  af b1 1d b8 71 9a 1d db  |..L;2f......q...|
+000001b0  db 89 6b ae da 2d 79 02  03 01 00 01 a3 81 a7 30  |..k..-y........0|
+000001c0  81 a4 30 1d 06 03 55 1d  0e 04 16 04 14 b1 ad e2  |..0...U.........|
+000001d0  85 5a cf cb 28 db 69 ce  23 69 de d3 26 8e 18 88  |.Z..(.i.#i..&...|
+000001e0  39 30 75 06 03 55 1d 23  04 6e 30 6c 80 14 b1 ad  |90u..U.#.n0l....|
+000001f0  e2 85 5a cf cb 28 db 69  ce 23 69 de d3 26 8e 18  |..Z..(.i.#i..&..|
+00000200  88 39 a1 49 a4 47 30 45  31 0b 30 09 06 03 55 04  |.9.I.G0E1.0...U.|
+00000210  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
+00000220  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
+00000230  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
+00000240  64 67 69 74 73 20 50 74  79 20 4c 74 64 82 09 00  |dgits Pty Ltd...|
+00000250  85 b0 bb a4 8a 7f b8 ca  30 0c 06 03 55 1d 13 04  |........0...U...|
+00000260  05 30 03 01 01 ff 30 0d  06 09 2a 86 48 86 f7 0d  |.0....0...*.H...|
+00000270  01 01 05 05 00 03 81 81  00 08 6c 45 24 c7 6b b1  |..........lE$.k.|
+00000280  59 ab 0c 52 cc f2 b0 14  d7 87 9d 7a 64 75 b5 5a  |Y..R.......zdu.Z|
+00000290  95 66 e4 c5 2b 8e ae 12  66 1f eb 4f 38 b3 6e 60  |.f..+...f..O8.n`|
+000002a0  d3 92 fd f7 41 08 b5 25  13 b1 18 7a 24 fb 30 1d  |....A..%...z$.0.|
+000002b0  ba ed 98 b9 17 ec e7 d7  31 59 db 95 d3 1d 78 ea  |........1Y....x.|
+000002c0  50 56 5c d5 82 5a 2d 5a  5f 33 c4 b6 d8 c9 75 90  |PV\..Z-Z_3....u.|
+000002d0  96 8c 0f 52 98 b5 cd 98  1f 89 20 5f f2 a0 1c a3  |...R...... _....|
+000002e0  1b 96 94 dd a9 fd 57 e9  70 e8 26 6d 71 99 9b 26  |......W.p.&mq..&|
+000002f0  6e 38 50 29 6c 90 a7 bd  d9 16 03 01 00 04 0e 00  |n8P)l...........|
+00000300  00 00                                             |..|
 >>> Flow 3 (client to server)
-00000000  16 03 01 00 86 10 00 00  82 00 80 17 30 df 06 a4  |............0...|
-00000010  8d 51 21 4a 76 9f 8b d2  2d 5d 0b 5e b1 72 63 7f  |.Q!Jv...-].^.rc.|
-00000020  f6 66 50 76 7a e0 90 de  3a 30 3f c3 66 1e 06 e4  |.fPvz...:0?.f...|
-00000030  ae fa 2f e5 a9 e9 9e fe  a6 b8 78 44 73 72 31 91  |../.......xDsr1.|
-00000040  78 76 7e e3 86 58 2f 62  79 5c 04 08 63 24 bd 29  |xv~..X/by\..c$.)|
-00000050  42 af fc c7 40 8b b0 26  1b a7 e1 a6 00 be e7 3a  |B...@..&.......:|
-00000060  60 bd a9 ff de 21 7f 87  55 7f d5 5f 5c 0f dc 5e  |`....!..U.._\..^|
-00000070  af b1 be 7f f6 5a fc e1  fc 81 2a 5d 5a 57 17 4c  |.....Z....*]ZW.L|
-00000080  76 b7 33 9a a2 89 46 66  b8 70 86 14 03 01 00 01  |v.3...Ff.p......|
-00000090  01 16 03 01 00 28 02 28  ba 24 9f 8c aa d8 e6 ce  |.....(.(.$......|
-000000a0  48 cf d5 6a 38 8b d4 d3  68 7a ce 6e a6 92 c7 47  |H..j8...hz.n...G|
-000000b0  85 72 c5 06 2f f1 5b b7  be 89 04 f3 b6 af        |.r../.[.......|
+00000000  16 03 01 00 86 10 00 00  82 00 80 2e af d2 61 f6  |..............a.|
+00000010  e2 b8 24 da 28 17 55 99  fd 11 bd 7a ab 98 dd f2  |..$.(.U....z....|
+00000020  f6 5f e0 11 6b 12 61 6f  86 48 b2 6e db f0 dd d5  |._..k.ao.H.n....|
+00000030  07 88 e5 95 f4 2d 6b 0c  d0 09 1a 5e 5f 50 1f dc  |.....-k....^_P..|
+00000040  f2 e7 02 7d 5e a0 70 29  80 ef 87 aa cc 95 3f 2e  |...}^.p)......?.|
+00000050  24 d1 40 b6 62 53 1d 25  31 87 1e 2f 77 d3 e1 1c  |$.@.bS.%1../w...|
+00000060  c4 99 89 bc 99 09 e9 ad  1f ce 09 e6 36 1c 3e 97  |............6.>.|
+00000070  be 62 69 a0 4e 14 20 9c  82 2a 3e fc 7e 9b c4 7a  |.bi.N. ..*>.~..z|
+00000080  5a f7 ad 1a 03 17 2a f8  7a 5f 44 14 03 01 00 01  |Z.....*.z_D.....|
+00000090  01 16 03 01 00 28 49 6b  da 73 07 ad 85 9a 0e fb  |.....(Ik.s......|
+000000a0  dd e0 69 ef c9 22 2d 86  91 51 26 63 d0 24 7d 16  |..i.."-..Q&c.$}.|
+000000b0  3c db 9b 00 c9 7e 64 e2  69 02 85 7d f7 47        |<....~d.i..}.G|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 28 d8 7a 71 41 9f  |..........(.zqA.|
-00000010  63 7a a8 5e ad 34 83 75  6a 15 29 d0 87 43 9b 3f  |cz.^.4.uj.)..C.?|
-00000020  b6 79 b1 44 92 f6 fd 9c  9b cc ec fc 05 8e 55 e9  |.y.D..........U.|
-00000030  7b 6a fe 17 03 01 00 18  52 2c 2b 19 63 fa 1f f0  |{j......R,+.c...|
-00000040  3a c2 1a 7e ba 3a 90 aa  25 46 f9 a4 f6 57 0e 32  |:..~.:..%F...W.2|
-00000050  17 03 01 00 28 49 ad 51  5e 27 fe e7 e4 1b bc 79  |....(I.Q^'.....y|
-00000060  34 51 f2 ea 3f cb 16 51  c5 d1 01 9a 65 7b e1 97  |4Q..?..Q....e{..|
-00000070  d4 28 f1 e6 ab cd 19 86  d3 01 79 9c 53 15 03 01  |.(........y.S...|
-00000080  00 18 ee 5b 0a 3c c5 0f  6f 85 2b 24 de 93 55 31  |...[.<..o.+$..U1|
-00000090  d8 17 a5 77 3c d4 10 48  cf af                    |...w<..H..|
+00000000  14 03 01 00 01 01 16 03  01 00 28 dc 60 83 43 6c  |..........(.`.Cl|
+00000010  37 79 ab 6e 92 1f 66 d0  b1 12 ce c1 64 9d 2b 68  |7y.n..f.....d.+h|
+00000020  c7 1a e5 1f 8c 80 08 d2  86 3e a1 2c e3 7e f4 64  |.........>.,.~.d|
+00000030  e7 96 b2 17 03 01 00 18  8d b5 7c 03 78 cf dc 09  |..........|.x...|
+00000040  95 06 4b a6 82 f9 30 d2  6b 26 cb 0a 9a 9d 47 9f  |..K...0.k&....G.|
+00000050  17 03 01 00 28 30 a9 55  dd b9 4d 6a 76 00 39 96  |....(0.U..Mjv.9.|
+00000060  a3 94 6a df e5 af 1e a2  eb bb e4 ac 95 2c f7 93  |..j..........,..|
+00000070  ef d1 b5 13 d8 e2 06 1a  ad 5c 00 dd 0c 15 03 01  |.........\......|
+00000080  00 18 a5 62 e4 8b 51 1d  28 46 bc 8a c8 50 a3 32  |...b..Q.(F...P.2|
+00000090  6b 7b f1 b6 19 43 63 1f  7d 38                    |k{...Cc.}8|
index 40cd947565dd435de50a22e4ad9c60d8971be8f1..1670997b0d0cbebdfc4c06467b62b06224ad32f1 100644 (file)
@@ -1,81 +1,82 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 37 01 00 00  33 03 01 52 ac 77 f8 da  |....7...3..R.w..|
-00000010  b3 ba 8c d1 0a a2 3b 35  7c db 1b ff cc e0 c4 f1  |......;5|.......|
-00000020  aa a3 40 fe 92 15 5b ed  29 3d 07 00 00 04 00 2f  |..@...[.)=...../|
-00000030  00 ff 02 01 00 00 05 00  0f 00 01 01              |............|
+00000000  16 03 01 00 36 01 00 00  32 03 01 52 cc 57 59 5d  |....6...2..R.WY]|
+00000010  0d 77 24 3e b3 32 3d ba  0f b0 aa 1d e3 13 06 f6  |.w$>.2=.........|
+00000020  0f be 3c 92 ba 93 bd a6  6d 69 53 00 00 04 00 2f  |..<.....miS..../|
+00000030  00 ff 01 00 00 05 00 0f  00 01 01                 |...........|
 >>> Flow 2 (server to client)
-00000000  16 03 01 00 2a 02 00 00  26 03 01 00 00 00 00 00  |....*...&.......|
+00000000  16 03 01 00 31 02 00 00  2d 03 01 00 00 00 00 00  |....1...-.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 2f 00 16  |............./..|
-00000030  03 01 02 be 0b 00 02 ba  00 02 b7 00 02 b4 30 82  |..............0.|
-00000040  02 b0 30 82 02 19 a0 03  02 01 02 02 09 00 85 b0  |..0.............|
-00000050  bb a4 8a 7f b8 ca 30 0d  06 09 2a 86 48 86 f7 0d  |......0...*.H...|
-00000060  01 01 05 05 00 30 45 31  0b 30 09 06 03 55 04 06  |.....0E1.0...U..|
-00000070  13 02 41 55 31 13 30 11  06 03 55 04 08 13 0a 53  |..AU1.0...U....S|
-00000080  6f 6d 65 2d 53 74 61 74  65 31 21 30 1f 06 03 55  |ome-State1!0...U|
-00000090  04 0a 13 18 49 6e 74 65  72 6e 65 74 20 57 69 64  |....Internet Wid|
-000000a0  67 69 74 73 20 50 74 79  20 4c 74 64 30 1e 17 0d  |gits Pty Ltd0...|
-000000b0  31 30 30 34 32 34 30 39  30 39 33 38 5a 17 0d 31  |100424090938Z..1|
-000000c0  31 30 34 32 34 30 39 30  39 33 38 5a 30 45 31 0b  |10424090938Z0E1.|
-000000d0  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-000000e0  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-000000f0  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-00000100  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-00000110  4c 74 64 30 81 9f 30 0d  06 09 2a 86 48 86 f7 0d  |Ltd0..0...*.H...|
-00000120  01 01 01 05 00 03 81 8d  00 30 81 89 02 81 81 00  |.........0......|
-00000130  bb 79 d6 f5 17 b5 e5 bf  46 10 d0 dc 69 be e6 2b  |.y......F...i..+|
-00000140  07 43 5a d0 03 2d 8a 7a  43 85 b7 14 52 e7 a5 65  |.CZ..-.zC...R..e|
-00000150  4c 2c 78 b8 23 8c b5 b4  82 e5 de 1f 95 3b 7e 62  |L,x.#........;~b|
-00000160  a5 2c a5 33 d6 fe 12 5c  7a 56 fc f5 06 bf fa 58  |.,.3...\zV.....X|
-00000170  7b 26 3f b5 cd 04 d3 d0  c9 21 96 4a c7 f4 54 9f  |{&?......!.J..T.|
-00000180  5a bf ef 42 71 00 fe 18  99 07 7f 7e 88 7d 7d f1  |Z..Bq......~.}}.|
-00000190  04 39 c4 a2 2e db 51 c9  7c e3 c0 4c 3b 32 66 01  |.9....Q.|..L;2f.|
-000001a0  cf af b1 1d b8 71 9a 1d  db db 89 6b ae da 2d 79  |.....q.....k..-y|
-000001b0  02 03 01 00 01 a3 81 a7  30 81 a4 30 1d 06 03 55  |........0..0...U|
-000001c0  1d 0e 04 16 04 14 b1 ad  e2 85 5a cf cb 28 db 69  |..........Z..(.i|
-000001d0  ce 23 69 de d3 26 8e 18  88 39 30 75 06 03 55 1d  |.#i..&...90u..U.|
-000001e0  23 04 6e 30 6c 80 14 b1  ad e2 85 5a cf cb 28 db  |#.n0l......Z..(.|
-000001f0  69 ce 23 69 de d3 26 8e  18 88 39 a1 49 a4 47 30  |i.#i..&...9.I.G0|
-00000200  45 31 0b 30 09 06 03 55  04 06 13 02 41 55 31 13  |E1.0...U....AU1.|
-00000210  30 11 06 03 55 04 08 13  0a 53 6f 6d 65 2d 53 74  |0...U....Some-St|
-00000220  61 74 65 31 21 30 1f 06  03 55 04 0a 13 18 49 6e  |ate1!0...U....In|
-00000230  74 65 72 6e 65 74 20 57  69 64 67 69 74 73 20 50  |ternet Widgits P|
-00000240  74 79 20 4c 74 64 82 09  00 85 b0 bb a4 8a 7f b8  |ty Ltd..........|
-00000250  ca 30 0c 06 03 55 1d 13  04 05 30 03 01 01 ff 30  |.0...U....0....0|
-00000260  0d 06 09 2a 86 48 86 f7  0d 01 01 05 05 00 03 81  |...*.H..........|
-00000270  81 00 08 6c 45 24 c7 6b  b1 59 ab 0c 52 cc f2 b0  |...lE$.k.Y..R...|
-00000280  14 d7 87 9d 7a 64 75 b5  5a 95 66 e4 c5 2b 8e ae  |....zdu.Z.f..+..|
-00000290  12 66 1f eb 4f 38 b3 6e  60 d3 92 fd f7 41 08 b5  |.f..O8.n`....A..|
-000002a0  25 13 b1 18 7a 24 fb 30  1d ba ed 98 b9 17 ec e7  |%...z$.0........|
-000002b0  d7 31 59 db 95 d3 1d 78  ea 50 56 5c d5 82 5a 2d  |.1Y....x.PV\..Z-|
-000002c0  5a 5f 33 c4 b6 d8 c9 75  90 96 8c 0f 52 98 b5 cd  |Z_3....u....R...|
-000002d0  98 1f 89 20 5f f2 a0 1c  a3 1b 96 94 dd a9 fd 57  |... _..........W|
-000002e0  e9 70 e8 26 6d 71 99 9b  26 6e 38 50 29 6c 90 a7  |.p.&mq..&n8P)l..|
-000002f0  bd d9 16 03 01 00 04 0e  00 00 00                 |...........|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 2f 00 00  |............./..|
+00000030  05 ff 01 00 01 00 16 03  01 02 be 0b 00 02 ba 00  |................|
+00000040  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
+00000050  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
+00000060  09 2a 86 48 86 f7 0d 01  01 05 05 00 30 45 31 0b  |.*.H........0E1.|
+00000070  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
+00000080  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
+00000090  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
+000000a0  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
+000000b0  4c 74 64 30 1e 17 0d 31  30 30 34 32 34 30 39 30  |Ltd0...100424090|
+000000c0  39 33 38 5a 17 0d 31 31  30 34 32 34 30 39 30 39  |938Z..1104240909|
+000000d0  33 38 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |38Z0E1.0...U....|
+000000e0  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
+000000f0  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
+00000100  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
+00000110  74 73 20 50 74 79 20 4c  74 64 30 81 9f 30 0d 06  |ts Pty Ltd0..0..|
+00000120  09 2a 86 48 86 f7 0d 01  01 01 05 00 03 81 8d 00  |.*.H............|
+00000130  30 81 89 02 81 81 00 bb  79 d6 f5 17 b5 e5 bf 46  |0.......y......F|
+00000140  10 d0 dc 69 be e6 2b 07  43 5a d0 03 2d 8a 7a 43  |...i..+.CZ..-.zC|
+00000150  85 b7 14 52 e7 a5 65 4c  2c 78 b8 23 8c b5 b4 82  |...R..eL,x.#....|
+00000160  e5 de 1f 95 3b 7e 62 a5  2c a5 33 d6 fe 12 5c 7a  |....;~b.,.3...\z|
+00000170  56 fc f5 06 bf fa 58 7b  26 3f b5 cd 04 d3 d0 c9  |V.....X{&?......|
+00000180  21 96 4a c7 f4 54 9f 5a  bf ef 42 71 00 fe 18 99  |!.J..T.Z..Bq....|
+00000190  07 7f 7e 88 7d 7d f1 04  39 c4 a2 2e db 51 c9 7c  |..~.}}..9....Q.||
+000001a0  e3 c0 4c 3b 32 66 01 cf  af b1 1d b8 71 9a 1d db  |..L;2f......q...|
+000001b0  db 89 6b ae da 2d 79 02  03 01 00 01 a3 81 a7 30  |..k..-y........0|
+000001c0  81 a4 30 1d 06 03 55 1d  0e 04 16 04 14 b1 ad e2  |..0...U.........|
+000001d0  85 5a cf cb 28 db 69 ce  23 69 de d3 26 8e 18 88  |.Z..(.i.#i..&...|
+000001e0  39 30 75 06 03 55 1d 23  04 6e 30 6c 80 14 b1 ad  |90u..U.#.n0l....|
+000001f0  e2 85 5a cf cb 28 db 69  ce 23 69 de d3 26 8e 18  |..Z..(.i.#i..&..|
+00000200  88 39 a1 49 a4 47 30 45  31 0b 30 09 06 03 55 04  |.9.I.G0E1.0...U.|
+00000210  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
+00000220  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
+00000230  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
+00000240  64 67 69 74 73 20 50 74  79 20 4c 74 64 82 09 00  |dgits Pty Ltd...|
+00000250  85 b0 bb a4 8a 7f b8 ca  30 0c 06 03 55 1d 13 04  |........0...U...|
+00000260  05 30 03 01 01 ff 30 0d  06 09 2a 86 48 86 f7 0d  |.0....0...*.H...|
+00000270  01 01 05 05 00 03 81 81  00 08 6c 45 24 c7 6b b1  |..........lE$.k.|
+00000280  59 ab 0c 52 cc f2 b0 14  d7 87 9d 7a 64 75 b5 5a  |Y..R.......zdu.Z|
+00000290  95 66 e4 c5 2b 8e ae 12  66 1f eb 4f 38 b3 6e 60  |.f..+...f..O8.n`|
+000002a0  d3 92 fd f7 41 08 b5 25  13 b1 18 7a 24 fb 30 1d  |....A..%...z$.0.|
+000002b0  ba ed 98 b9 17 ec e7 d7  31 59 db 95 d3 1d 78 ea  |........1Y....x.|
+000002c0  50 56 5c d5 82 5a 2d 5a  5f 33 c4 b6 d8 c9 75 90  |PV\..Z-Z_3....u.|
+000002d0  96 8c 0f 52 98 b5 cd 98  1f 89 20 5f f2 a0 1c a3  |...R...... _....|
+000002e0  1b 96 94 dd a9 fd 57 e9  70 e8 26 6d 71 99 9b 26  |......W.p.&mq..&|
+000002f0  6e 38 50 29 6c 90 a7 bd  d9 16 03 01 00 04 0e 00  |n8P)l...........|
+00000300  00 00                                             |..|
 >>> Flow 3 (client to server)
-00000000  16 03 01 00 86 10 00 00  82 00 80 ae 53 cd ef fb  |............S...|
-00000010  31 07 cb 0b 1b a6 da c6  b6 b6 49 1b fb 5c f9 2f  |1.........I..\./|
-00000020  6b fe c9 5c 46 0c 2b 01  a2 4b 2e df 65 6d d9 61  |k..\F.+..K..em.a|
-00000030  59 93 72 89 d1 38 72 49  a7 28 e8 7a 70 7d 96 6e  |Y.r..8rI.(.zp}.n|
-00000040  72 0b 4d d4 f8 59 46 32  49 8b e4 97 35 de 77 19  |r.M..YF2I...5.w.|
-00000050  e9 30 12 ff d9 3d 32 07  4b 26 f7 d3 1a 32 dc 36  |.0...=2.K&...2.6|
-00000060  d9 f3 f9 33 fb 34 73 a4  35 15 f1 a9 cc 1a 30 55  |...3.4s.5.....0U|
-00000070  f3 25 20 8a 9e 25 87 13  58 ec e7 07 87 5d a7 84  |.% ..%..X....]..|
-00000080  e9 f8 83 c3 9e 08 0a 01  fa c2 8f 14 03 01 00 01  |................|
-00000090  01 16 03 01 00 30 dd 53  57 25 a0 e3 91 a1 0b fd  |.....0.SW%......|
-000000a0  16 91 90 59 4a 12 fe 96  a2 4b ca c9 85 a2 91 ef  |...YJ....K......|
-000000b0  ac 1f aa dc ff c3 9a 6d  79 5a 56 36 8d 48 fd e4  |.......myZV6.H..|
-000000c0  9a d2 4d 47 8e d0                                 |..MG..|
+00000000  16 03 01 00 86 10 00 00  82 00 80 20 e6 80 f7 48  |........... ...H|
+00000010  7e 7d 08 08 54 e1 b4 e3  98 27 5f 90 9d 3b e3 c2  |~}..T....'_..;..|
+00000020  c8 8b dc 9e ff 75 fa fc  60 e1 9e 67 7c c4 08 27  |.....u..`..g|..'|
+00000030  cc 6f 15 6c bc 7c 96 de  83 8f 98 6d 4a c7 b7 20  |.o.l.|.....mJ.. |
+00000040  8c 19 47 5a ff 76 92 0a  df df 66 d2 b6 9d 2d 06  |..GZ.v....f...-.|
+00000050  fb ac 07 cf 38 08 f1 fd  0d fe 07 d7 69 3e 8a 79  |....8.......i>.y|
+00000060  dc 2d ab bb f7 18 3c 51  14 6e c6 70 95 a2 59 b1  |.-....<Q.n.p..Y.|
+00000070  39 04 9f ae f3 5f fb a7  2b d3 5a c0 96 d9 4d 2a  |9...._..+.Z...M*|
+00000080  2a 6c 6d 39 ee fc ce 76  1a 92 1b 14 03 01 00 01  |*lm9...v........|
+00000090  01 16 03 01 00 30 10 20  90 7b 0e e6 c2 05 81 c3  |.....0. .{......|
+000000a0  bc da 84 67 dd 5f 97 e2  74 c4 35 4e bf d2 1b 90  |...g._..t.5N....|
+000000b0  2f e0 af dd 6b f5 52 db  36 cd 3e e1 e6 bd 99 30  |/...k.R.6.>....0|
+000000c0  ed c6 bc c2 38 b6                                 |....8.|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 30 12 3f 15 b4 79  |..........0.?..y|
-00000010  a8 f7 48 a3 f5 fa 0b 8e  58 f2 f0 cb dc 56 54 95  |..H.....X....VT.|
-00000020  8d fa 83 3a 09 da 97 28  bd 01 7f 0d 88 1d 46 33  |...:...(......F3|
-00000030  42 58 b3 d5 31 45 c2 4c  cb 0b fc 17 03 01 00 20  |BX..1E.L....... |
-00000040  9c 90 ff 54 aa 89 5a f7  70 0a 1e 99 47 94 1e b6  |...T..Z.p...G...|
-00000050  b7 66 14 4a 25 4f b8 b1  cc 60 65 5d 0b 5a c1 c2  |.f.J%O...`e].Z..|
-00000060  17 03 01 00 30 b6 f0 49  f3 b1 2e 3a b5 d8 9e 35  |....0..I...:...5|
-00000070  fc 2a 77 6e d3 d8 5a 17  dc d8 8a ac 29 d3 90 28  |.*wn..Z.....)..(|
-00000080  8b bf 3c 8a b0 59 05 15  e6 ac 53 5b 59 ae 61 30  |..<..Y....S[Y.a0|
-00000090  f8 1c b4 40 62 15 03 01  00 20 1f bb db f5 0e a8  |...@b.... ......|
-000000a0  8d ed 68 b1 aa 3d c7 15  3e 7f 00 24 41 c6 4e b8  |..h..=..>..$A.N.|
-000000b0  91 24 46 5e f1 23 b2 4d  7e 47                    |.$F^.#.M~G|
+00000000  14 03 01 00 01 01 16 03  01 00 30 5d 0c a2 18 13  |..........0]....|
+00000010  40 a1 84 ce c5 d8 4e fc  a4 8a 14 b5 94 18 b1 86  |@.....N.........|
+00000020  da 6a 7d 26 08 d6 a0 f8  78 5b 42 7e f8 83 54 56  |.j}&....x[B~..TV|
+00000030  36 a4 91 37 67 5a d7 68  37 c4 4f 17 03 01 00 20  |6..7gZ.h7.O.... |
+00000040  fd aa 5e cf 4b 12 c5 be  a4 a2 65 5d 6e 65 46 5f  |..^.K.....e]neF_|
+00000050  d2 fe 46 e7 77 2d 9c 1e  0b 39 40 48 c2 2f be 21  |..F.w-...9@H./.!|
+00000060  17 03 01 00 30 03 af 9e  6b d6 76 ed 9e 1d 8b 8b  |....0...k.v.....|
+00000070  2e 2a 5d da c4 73 95 ac  0e 6f 69 cb 63 df 50 27  |.*]..s...oi.c.P'|
+00000080  30 de 2e 55 86 85 ad 3e  33 22 49 72 f2 e2 9f 8f  |0..U...>3"Ir....|
+00000090  ba cf 4e 30 34 15 03 01  00 20 4c 4c 97 61 70 ea  |..N04.... LL.ap.|
+000000a0  ae fc a2 e9 c6 c2 b6 2e  4d 85 f6 ae 2b 56 46 82  |........M...+VF.|
+000000b0  9d d8 a5 82 17 fa 3e 62  67 7e                    |......>bg~|
index 7dc32b53a8abf95531106bd725d42bffbd4f61c5..d653561f9d42339af390451ceba6db40b456d862 100644 (file)
@@ -1,75 +1,76 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 37 01 00 00  33 03 01 52 ac 77 f8 61  |....7...3..R.w.a|
-00000010  5d ea e5 06 b5 5e 74 c9  65 dd 4b f3 12 10 82 90  |]....^t.e.K.....|
-00000020  3a 4f 56 50 1a 96 fa a1  6e 41 12 00 00 04 00 05  |:OVP....nA......|
-00000030  00 ff 02 01 00 00 05 00  0f 00 01 01              |............|
+00000000  16 03 01 00 36 01 00 00  32 03 01 52 cc 57 59 cf  |....6...2..R.WY.|
+00000010  00 a1 49 a4 37 69 74 d8  a7 93 ea 8d e7 50 b7 b3  |..I.7it......P..|
+00000020  8c ec e5 56 fb dc 5f 1a  2e ab 18 00 00 04 00 05  |...V.._.........|
+00000030  00 ff 01 00 00 05 00 0f  00 01 01                 |...........|
 >>> Flow 2 (server to client)
-00000000  16 03 01 00 2a 02 00 00  26 03 01 00 00 00 00 00  |....*...&.......|
+00000000  16 03 01 00 31 02 00 00  2d 03 01 00 00 00 00 00  |....1...-.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 05 00 16  |................|
-00000030  03 01 02 be 0b 00 02 ba  00 02 b7 00 02 b4 30 82  |..............0.|
-00000040  02 b0 30 82 02 19 a0 03  02 01 02 02 09 00 85 b0  |..0.............|
-00000050  bb a4 8a 7f b8 ca 30 0d  06 09 2a 86 48 86 f7 0d  |......0...*.H...|
-00000060  01 01 05 05 00 30 45 31  0b 30 09 06 03 55 04 06  |.....0E1.0...U..|
-00000070  13 02 41 55 31 13 30 11  06 03 55 04 08 13 0a 53  |..AU1.0...U....S|
-00000080  6f 6d 65 2d 53 74 61 74  65 31 21 30 1f 06 03 55  |ome-State1!0...U|
-00000090  04 0a 13 18 49 6e 74 65  72 6e 65 74 20 57 69 64  |....Internet Wid|
-000000a0  67 69 74 73 20 50 74 79  20 4c 74 64 30 1e 17 0d  |gits Pty Ltd0...|
-000000b0  31 30 30 34 32 34 30 39  30 39 33 38 5a 17 0d 31  |100424090938Z..1|
-000000c0  31 30 34 32 34 30 39 30  39 33 38 5a 30 45 31 0b  |10424090938Z0E1.|
-000000d0  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-000000e0  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-000000f0  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-00000100  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-00000110  4c 74 64 30 81 9f 30 0d  06 09 2a 86 48 86 f7 0d  |Ltd0..0...*.H...|
-00000120  01 01 01 05 00 03 81 8d  00 30 81 89 02 81 81 00  |.........0......|
-00000130  bb 79 d6 f5 17 b5 e5 bf  46 10 d0 dc 69 be e6 2b  |.y......F...i..+|
-00000140  07 43 5a d0 03 2d 8a 7a  43 85 b7 14 52 e7 a5 65  |.CZ..-.zC...R..e|
-00000150  4c 2c 78 b8 23 8c b5 b4  82 e5 de 1f 95 3b 7e 62  |L,x.#........;~b|
-00000160  a5 2c a5 33 d6 fe 12 5c  7a 56 fc f5 06 bf fa 58  |.,.3...\zV.....X|
-00000170  7b 26 3f b5 cd 04 d3 d0  c9 21 96 4a c7 f4 54 9f  |{&?......!.J..T.|
-00000180  5a bf ef 42 71 00 fe 18  99 07 7f 7e 88 7d 7d f1  |Z..Bq......~.}}.|
-00000190  04 39 c4 a2 2e db 51 c9  7c e3 c0 4c 3b 32 66 01  |.9....Q.|..L;2f.|
-000001a0  cf af b1 1d b8 71 9a 1d  db db 89 6b ae da 2d 79  |.....q.....k..-y|
-000001b0  02 03 01 00 01 a3 81 a7  30 81 a4 30 1d 06 03 55  |........0..0...U|
-000001c0  1d 0e 04 16 04 14 b1 ad  e2 85 5a cf cb 28 db 69  |..........Z..(.i|
-000001d0  ce 23 69 de d3 26 8e 18  88 39 30 75 06 03 55 1d  |.#i..&...90u..U.|
-000001e0  23 04 6e 30 6c 80 14 b1  ad e2 85 5a cf cb 28 db  |#.n0l......Z..(.|
-000001f0  69 ce 23 69 de d3 26 8e  18 88 39 a1 49 a4 47 30  |i.#i..&...9.I.G0|
-00000200  45 31 0b 30 09 06 03 55  04 06 13 02 41 55 31 13  |E1.0...U....AU1.|
-00000210  30 11 06 03 55 04 08 13  0a 53 6f 6d 65 2d 53 74  |0...U....Some-St|
-00000220  61 74 65 31 21 30 1f 06  03 55 04 0a 13 18 49 6e  |ate1!0...U....In|
-00000230  74 65 72 6e 65 74 20 57  69 64 67 69 74 73 20 50  |ternet Widgits P|
-00000240  74 79 20 4c 74 64 82 09  00 85 b0 bb a4 8a 7f b8  |ty Ltd..........|
-00000250  ca 30 0c 06 03 55 1d 13  04 05 30 03 01 01 ff 30  |.0...U....0....0|
-00000260  0d 06 09 2a 86 48 86 f7  0d 01 01 05 05 00 03 81  |...*.H..........|
-00000270  81 00 08 6c 45 24 c7 6b  b1 59 ab 0c 52 cc f2 b0  |...lE$.k.Y..R...|
-00000280  14 d7 87 9d 7a 64 75 b5  5a 95 66 e4 c5 2b 8e ae  |....zdu.Z.f..+..|
-00000290  12 66 1f eb 4f 38 b3 6e  60 d3 92 fd f7 41 08 b5  |.f..O8.n`....A..|
-000002a0  25 13 b1 18 7a 24 fb 30  1d ba ed 98 b9 17 ec e7  |%...z$.0........|
-000002b0  d7 31 59 db 95 d3 1d 78  ea 50 56 5c d5 82 5a 2d  |.1Y....x.PV\..Z-|
-000002c0  5a 5f 33 c4 b6 d8 c9 75  90 96 8c 0f 52 98 b5 cd  |Z_3....u....R...|
-000002d0  98 1f 89 20 5f f2 a0 1c  a3 1b 96 94 dd a9 fd 57  |... _..........W|
-000002e0  e9 70 e8 26 6d 71 99 9b  26 6e 38 50 29 6c 90 a7  |.p.&mq..&n8P)l..|
-000002f0  bd d9 16 03 01 00 04 0e  00 00 00                 |...........|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 05 00 00  |................|
+00000030  05 ff 01 00 01 00 16 03  01 02 be 0b 00 02 ba 00  |................|
+00000040  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
+00000050  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
+00000060  09 2a 86 48 86 f7 0d 01  01 05 05 00 30 45 31 0b  |.*.H........0E1.|
+00000070  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
+00000080  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
+00000090  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
+000000a0  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
+000000b0  4c 74 64 30 1e 17 0d 31  30 30 34 32 34 30 39 30  |Ltd0...100424090|
+000000c0  39 33 38 5a 17 0d 31 31  30 34 32 34 30 39 30 39  |938Z..1104240909|
+000000d0  33 38 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |38Z0E1.0...U....|
+000000e0  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
+000000f0  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
+00000100  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
+00000110  74 73 20 50 74 79 20 4c  74 64 30 81 9f 30 0d 06  |ts Pty Ltd0..0..|
+00000120  09 2a 86 48 86 f7 0d 01  01 01 05 00 03 81 8d 00  |.*.H............|
+00000130  30 81 89 02 81 81 00 bb  79 d6 f5 17 b5 e5 bf 46  |0.......y......F|
+00000140  10 d0 dc 69 be e6 2b 07  43 5a d0 03 2d 8a 7a 43  |...i..+.CZ..-.zC|
+00000150  85 b7 14 52 e7 a5 65 4c  2c 78 b8 23 8c b5 b4 82  |...R..eL,x.#....|
+00000160  e5 de 1f 95 3b 7e 62 a5  2c a5 33 d6 fe 12 5c 7a  |....;~b.,.3...\z|
+00000170  56 fc f5 06 bf fa 58 7b  26 3f b5 cd 04 d3 d0 c9  |V.....X{&?......|
+00000180  21 96 4a c7 f4 54 9f 5a  bf ef 42 71 00 fe 18 99  |!.J..T.Z..Bq....|
+00000190  07 7f 7e 88 7d 7d f1 04  39 c4 a2 2e db 51 c9 7c  |..~.}}..9....Q.||
+000001a0  e3 c0 4c 3b 32 66 01 cf  af b1 1d b8 71 9a 1d db  |..L;2f......q...|
+000001b0  db 89 6b ae da 2d 79 02  03 01 00 01 a3 81 a7 30  |..k..-y........0|
+000001c0  81 a4 30 1d 06 03 55 1d  0e 04 16 04 14 b1 ad e2  |..0...U.........|
+000001d0  85 5a cf cb 28 db 69 ce  23 69 de d3 26 8e 18 88  |.Z..(.i.#i..&...|
+000001e0  39 30 75 06 03 55 1d 23  04 6e 30 6c 80 14 b1 ad  |90u..U.#.n0l....|
+000001f0  e2 85 5a cf cb 28 db 69  ce 23 69 de d3 26 8e 18  |..Z..(.i.#i..&..|
+00000200  88 39 a1 49 a4 47 30 45  31 0b 30 09 06 03 55 04  |.9.I.G0E1.0...U.|
+00000210  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
+00000220  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
+00000230  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
+00000240  64 67 69 74 73 20 50 74  79 20 4c 74 64 82 09 00  |dgits Pty Ltd...|
+00000250  85 b0 bb a4 8a 7f b8 ca  30 0c 06 03 55 1d 13 04  |........0...U...|
+00000260  05 30 03 01 01 ff 30 0d  06 09 2a 86 48 86 f7 0d  |.0....0...*.H...|
+00000270  01 01 05 05 00 03 81 81  00 08 6c 45 24 c7 6b b1  |..........lE$.k.|
+00000280  59 ab 0c 52 cc f2 b0 14  d7 87 9d 7a 64 75 b5 5a  |Y..R.......zdu.Z|
+00000290  95 66 e4 c5 2b 8e ae 12  66 1f eb 4f 38 b3 6e 60  |.f..+...f..O8.n`|
+000002a0  d3 92 fd f7 41 08 b5 25  13 b1 18 7a 24 fb 30 1d  |....A..%...z$.0.|
+000002b0  ba ed 98 b9 17 ec e7 d7  31 59 db 95 d3 1d 78 ea  |........1Y....x.|
+000002c0  50 56 5c d5 82 5a 2d 5a  5f 33 c4 b6 d8 c9 75 90  |PV\..Z-Z_3....u.|
+000002d0  96 8c 0f 52 98 b5 cd 98  1f 89 20 5f f2 a0 1c a3  |...R...... _....|
+000002e0  1b 96 94 dd a9 fd 57 e9  70 e8 26 6d 71 99 9b 26  |......W.p.&mq..&|
+000002f0  6e 38 50 29 6c 90 a7 bd  d9 16 03 01 00 04 0e 00  |n8P)l...........|
+00000300  00 00                                             |..|
 >>> Flow 3 (client to server)
-00000000  16 03 01 00 86 10 00 00  82 00 80 9a 45 b5 b4 9d  |............E...|
-00000010  1c 49 c5 52 aa 0b 43 45  45 10 ab a0 21 04 f1 ca  |.I.R..CEE...!...|
-00000020  41 d8 b3 70 10 fc c5 7c  a1 d2 d7 15 04 1e 8f ae  |A..p...|........|
-00000030  39 a4 d2 0d b9 e3 cf d4  40 9a b4 ee 8e 57 c4 41  |9.......@....W.A|
-00000040  74 d4 94 a4 7b 36 70 e9  af 43 e3 7b 02 52 7d 99  |t...{6p..C.{.R}.|
-00000050  52 65 03 b7 e3 05 72 36  7c f7 c0 07 49 27 f8 5d  |Re....r6|...I'.]|
-00000060  cb e0 00 5b 84 b1 bd b7  7f e5 6b a8 ad e3 df 9e  |...[......k.....|
-00000070  b8 7c 19 aa 6e 22 c7 0b  43 61 6d 0b d3 b9 72 10  |.|..n"..Cam...r.|
-00000080  b1 a3 ac e4 12 de 32 b5  e0 89 a0 14 03 01 00 01  |......2.........|
-00000090  01 16 03 01 00 24 ba 96  18 34 84 cc 60 cd 33 33  |.....$...4..`.33|
-000000a0  c2 24 88 ec 0d 46 93 d3  d5 42 82 a5 8b f0 a5 c6  |.$...F...B......|
-000000b0  c5 73 9a d5 85 fb 79 5e  90 09                    |.s....y^..|
+00000000  16 03 01 00 86 10 00 00  82 00 80 b1 96 7b 6f f5  |.............{o.|
+00000010  a0 cb 0d 60 9b 64 d3 f5  17 76 47 7b bc a5 0e 96  |...`.d...vG{....|
+00000020  53 af 68 0c 96 22 f7 28  0c 24 37 9c 51 69 ed b2  |S.h..".(.$7.Qi..|
+00000030  47 14 ba 33 c5 79 6b 96  f2 ab 3c 02 5c 37 a4 97  |G..3.yk...<.\7..|
+00000040  23 fc 7f d3 95 2d 85 99  1a 10 1b 38 e5 f1 83 55  |#....-.....8...U|
+00000050  4a ab 60 f8 89 0a 6a c4  eb 45 f5 b0 f4 f8 09 31  |J.`...j..E.....1|
+00000060  6e f0 25 30 fd 5e 68 61  bc cb 0d 9e 05 73 0a f4  |n.%0.^ha.....s..|
+00000070  a5 2e d9 d5 4e 08 f6 3b  8d 2d 21 f5 79 b6 97 55  |....N..;.-!.y..U|
+00000080  b9 99 03 49 ea 96 36 49  21 56 bf 14 03 01 00 01  |...I..6I!V......|
+00000090  01 16 03 01 00 24 f0 4f  30 06 c3 25 01 93 34 ab  |.....$.O0..%..4.|
+000000a0  93 8f 59 26 83 6e 8a fd  5a a6 cf af ad b1 a2 83  |..Y&.n..Z.......|
+000000b0  28 ff c2 66 5f ac e5 a5  a5 03                    |(..f_.....|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 24 88 79 b1 70 0e  |..........$.y.p.|
-00000010  86 2a ec 3e a3 8b 2f 78  70 d0 92 4e ae 8e 17 78  |.*.>../xp..N...x|
-00000020  cc 91 a9 3d 5c f2 2c 36  45 12 62 e4 8d 15 0a 17  |...=\.,6E.b.....|
-00000030  03 01 00 21 f7 3b 4e 00  2b 54 e8 86 6f 84 bd 92  |...!.;N.+T..o...|
-00000040  ca 87 5f a7 4e 62 ad 84  a8 3d be 8d 61 5f e2 e8  |.._.Nb...=..a_..|
-00000050  74 83 e3 1e 1f 15 03 01  00 16 fd 57 d8 6c 17 47  |t..........W.l.G|
-00000060  af 7b 6e c6 5e 68 26 db  bc 5b 47 51 92 ac 11 b5  |.{n.^h&..[GQ....|
+00000000  14 03 01 00 01 01 16 03  01 00 24 9d b4 ea d8 be  |..........$.....|
+00000010  b5 9f 00 fd b5 99 04 12  6b 7a 3f b8 52 d7 52 a9  |........kz?.R.R.|
+00000020  e9 bd 5b 63 ad b0 53 ac  46 80 be 48 6e dd ee 17  |..[c..S.F..Hn...|
+00000030  03 01 00 21 07 ac c4 fb  21 e4 b8 6b 64 3b b5 27  |...!....!..kd;.'|
+00000040  29 67 a1 10 2e d2 71 d5  59 5e fc 1d 84 31 15 6e  |)g....q.Y^...1.n|
+00000050  4d 4b dc a9 3a 15 03 01  00 16 25 22 a5 78 23 5a  |MK..:.....%".x#Z|
+00000060  69 6f 99 a1 b3 1c 8d bf  f3 bd 1b c8 1c 57 15 75  |io...........W.u|
index b03742eca4bf5fea8d3be0cdc419d4baaea16faf..9237db0786366112e36990c7f70014a8ee50f0e4 100644 (file)
@@ -1,75 +1,76 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 37 01 00 00  33 03 02 52 ac 77 f8 ec  |....7...3..R.w..|
-00000010  6b 58 37 4d 43 de 2f 43  32 93 a4 d2 a1 10 21 6e  |kX7MC./C2.....!n|
-00000020  55 aa f2 0d 14 70 6d 37  cb 0e e7 00 00 04 00 05  |U....pm7........|
-00000030  00 ff 02 01 00 00 05 00  0f 00 01 01              |............|
+00000000  16 03 01 00 36 01 00 00  32 03 02 52 cc 57 59 bd  |....6...2..R.WY.|
+00000010  cd 9d 1e 17 38 43 a5 e3  e7 30 e4 2b 2a ef f7 5b  |....8C...0.+*..[|
+00000020  81 91 0c 0b 52 f8 2d 2c  61 d3 13 00 00 04 00 05  |....R.-,a.......|
+00000030  00 ff 01 00 00 05 00 0f  00 01 01                 |...........|
 >>> Flow 2 (server to client)
-00000000  16 03 02 00 2a 02 00 00  26 03 02 00 00 00 00 00  |....*...&.......|
+00000000  16 03 02 00 31 02 00 00  2d 03 02 00 00 00 00 00  |....1...-.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 05 00 16  |................|
-00000030  03 02 02 be 0b 00 02 ba  00 02 b7 00 02 b4 30 82  |..............0.|
-00000040  02 b0 30 82 02 19 a0 03  02 01 02 02 09 00 85 b0  |..0.............|
-00000050  bb a4 8a 7f b8 ca 30 0d  06 09 2a 86 48 86 f7 0d  |......0...*.H...|
-00000060  01 01 05 05 00 30 45 31  0b 30 09 06 03 55 04 06  |.....0E1.0...U..|
-00000070  13 02 41 55 31 13 30 11  06 03 55 04 08 13 0a 53  |..AU1.0...U....S|
-00000080  6f 6d 65 2d 53 74 61 74  65 31 21 30 1f 06 03 55  |ome-State1!0...U|
-00000090  04 0a 13 18 49 6e 74 65  72 6e 65 74 20 57 69 64  |....Internet Wid|
-000000a0  67 69 74 73 20 50 74 79  20 4c 74 64 30 1e 17 0d  |gits Pty Ltd0...|
-000000b0  31 30 30 34 32 34 30 39  30 39 33 38 5a 17 0d 31  |100424090938Z..1|
-000000c0  31 30 34 32 34 30 39 30  39 33 38 5a 30 45 31 0b  |10424090938Z0E1.|
-000000d0  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-000000e0  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-000000f0  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-00000100  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-00000110  4c 74 64 30 81 9f 30 0d  06 09 2a 86 48 86 f7 0d  |Ltd0..0...*.H...|
-00000120  01 01 01 05 00 03 81 8d  00 30 81 89 02 81 81 00  |.........0......|
-00000130  bb 79 d6 f5 17 b5 e5 bf  46 10 d0 dc 69 be e6 2b  |.y......F...i..+|
-00000140  07 43 5a d0 03 2d 8a 7a  43 85 b7 14 52 e7 a5 65  |.CZ..-.zC...R..e|
-00000150  4c 2c 78 b8 23 8c b5 b4  82 e5 de 1f 95 3b 7e 62  |L,x.#........;~b|
-00000160  a5 2c a5 33 d6 fe 12 5c  7a 56 fc f5 06 bf fa 58  |.,.3...\zV.....X|
-00000170  7b 26 3f b5 cd 04 d3 d0  c9 21 96 4a c7 f4 54 9f  |{&?......!.J..T.|
-00000180  5a bf ef 42 71 00 fe 18  99 07 7f 7e 88 7d 7d f1  |Z..Bq......~.}}.|
-00000190  04 39 c4 a2 2e db 51 c9  7c e3 c0 4c 3b 32 66 01  |.9....Q.|..L;2f.|
-000001a0  cf af b1 1d b8 71 9a 1d  db db 89 6b ae da 2d 79  |.....q.....k..-y|
-000001b0  02 03 01 00 01 a3 81 a7  30 81 a4 30 1d 06 03 55  |........0..0...U|
-000001c0  1d 0e 04 16 04 14 b1 ad  e2 85 5a cf cb 28 db 69  |..........Z..(.i|
-000001d0  ce 23 69 de d3 26 8e 18  88 39 30 75 06 03 55 1d  |.#i..&...90u..U.|
-000001e0  23 04 6e 30 6c 80 14 b1  ad e2 85 5a cf cb 28 db  |#.n0l......Z..(.|
-000001f0  69 ce 23 69 de d3 26 8e  18 88 39 a1 49 a4 47 30  |i.#i..&...9.I.G0|
-00000200  45 31 0b 30 09 06 03 55  04 06 13 02 41 55 31 13  |E1.0...U....AU1.|
-00000210  30 11 06 03 55 04 08 13  0a 53 6f 6d 65 2d 53 74  |0...U....Some-St|
-00000220  61 74 65 31 21 30 1f 06  03 55 04 0a 13 18 49 6e  |ate1!0...U....In|
-00000230  74 65 72 6e 65 74 20 57  69 64 67 69 74 73 20 50  |ternet Widgits P|
-00000240  74 79 20 4c 74 64 82 09  00 85 b0 bb a4 8a 7f b8  |ty Ltd..........|
-00000250  ca 30 0c 06 03 55 1d 13  04 05 30 03 01 01 ff 30  |.0...U....0....0|
-00000260  0d 06 09 2a 86 48 86 f7  0d 01 01 05 05 00 03 81  |...*.H..........|
-00000270  81 00 08 6c 45 24 c7 6b  b1 59 ab 0c 52 cc f2 b0  |...lE$.k.Y..R...|
-00000280  14 d7 87 9d 7a 64 75 b5  5a 95 66 e4 c5 2b 8e ae  |....zdu.Z.f..+..|
-00000290  12 66 1f eb 4f 38 b3 6e  60 d3 92 fd f7 41 08 b5  |.f..O8.n`....A..|
-000002a0  25 13 b1 18 7a 24 fb 30  1d ba ed 98 b9 17 ec e7  |%...z$.0........|
-000002b0  d7 31 59 db 95 d3 1d 78  ea 50 56 5c d5 82 5a 2d  |.1Y....x.PV\..Z-|
-000002c0  5a 5f 33 c4 b6 d8 c9 75  90 96 8c 0f 52 98 b5 cd  |Z_3....u....R...|
-000002d0  98 1f 89 20 5f f2 a0 1c  a3 1b 96 94 dd a9 fd 57  |... _..........W|
-000002e0  e9 70 e8 26 6d 71 99 9b  26 6e 38 50 29 6c 90 a7  |.p.&mq..&n8P)l..|
-000002f0  bd d9 16 03 02 00 04 0e  00 00 00                 |...........|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 05 00 00  |................|
+00000030  05 ff 01 00 01 00 16 03  02 02 be 0b 00 02 ba 00  |................|
+00000040  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
+00000050  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
+00000060  09 2a 86 48 86 f7 0d 01  01 05 05 00 30 45 31 0b  |.*.H........0E1.|
+00000070  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
+00000080  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
+00000090  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
+000000a0  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
+000000b0  4c 74 64 30 1e 17 0d 31  30 30 34 32 34 30 39 30  |Ltd0...100424090|
+000000c0  39 33 38 5a 17 0d 31 31  30 34 32 34 30 39 30 39  |938Z..1104240909|
+000000d0  33 38 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |38Z0E1.0...U....|
+000000e0  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
+000000f0  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
+00000100  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
+00000110  74 73 20 50 74 79 20 4c  74 64 30 81 9f 30 0d 06  |ts Pty Ltd0..0..|
+00000120  09 2a 86 48 86 f7 0d 01  01 01 05 00 03 81 8d 00  |.*.H............|
+00000130  30 81 89 02 81 81 00 bb  79 d6 f5 17 b5 e5 bf 46  |0.......y......F|
+00000140  10 d0 dc 69 be e6 2b 07  43 5a d0 03 2d 8a 7a 43  |...i..+.CZ..-.zC|
+00000150  85 b7 14 52 e7 a5 65 4c  2c 78 b8 23 8c b5 b4 82  |...R..eL,x.#....|
+00000160  e5 de 1f 95 3b 7e 62 a5  2c a5 33 d6 fe 12 5c 7a  |....;~b.,.3...\z|
+00000170  56 fc f5 06 bf fa 58 7b  26 3f b5 cd 04 d3 d0 c9  |V.....X{&?......|
+00000180  21 96 4a c7 f4 54 9f 5a  bf ef 42 71 00 fe 18 99  |!.J..T.Z..Bq....|
+00000190  07 7f 7e 88 7d 7d f1 04  39 c4 a2 2e db 51 c9 7c  |..~.}}..9....Q.||
+000001a0  e3 c0 4c 3b 32 66 01 cf  af b1 1d b8 71 9a 1d db  |..L;2f......q...|
+000001b0  db 89 6b ae da 2d 79 02  03 01 00 01 a3 81 a7 30  |..k..-y........0|
+000001c0  81 a4 30 1d 06 03 55 1d  0e 04 16 04 14 b1 ad e2  |..0...U.........|
+000001d0  85 5a cf cb 28 db 69 ce  23 69 de d3 26 8e 18 88  |.Z..(.i.#i..&...|
+000001e0  39 30 75 06 03 55 1d 23  04 6e 30 6c 80 14 b1 ad  |90u..U.#.n0l....|
+000001f0  e2 85 5a cf cb 28 db 69  ce 23 69 de d3 26 8e 18  |..Z..(.i.#i..&..|
+00000200  88 39 a1 49 a4 47 30 45  31 0b 30 09 06 03 55 04  |.9.I.G0E1.0...U.|
+00000210  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
+00000220  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
+00000230  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
+00000240  64 67 69 74 73 20 50 74  79 20 4c 74 64 82 09 00  |dgits Pty Ltd...|
+00000250  85 b0 bb a4 8a 7f b8 ca  30 0c 06 03 55 1d 13 04  |........0...U...|
+00000260  05 30 03 01 01 ff 30 0d  06 09 2a 86 48 86 f7 0d  |.0....0...*.H...|
+00000270  01 01 05 05 00 03 81 81  00 08 6c 45 24 c7 6b b1  |..........lE$.k.|
+00000280  59 ab 0c 52 cc f2 b0 14  d7 87 9d 7a 64 75 b5 5a  |Y..R.......zdu.Z|
+00000290  95 66 e4 c5 2b 8e ae 12  66 1f eb 4f 38 b3 6e 60  |.f..+...f..O8.n`|
+000002a0  d3 92 fd f7 41 08 b5 25  13 b1 18 7a 24 fb 30 1d  |....A..%...z$.0.|
+000002b0  ba ed 98 b9 17 ec e7 d7  31 59 db 95 d3 1d 78 ea  |........1Y....x.|
+000002c0  50 56 5c d5 82 5a 2d 5a  5f 33 c4 b6 d8 c9 75 90  |PV\..Z-Z_3....u.|
+000002d0  96 8c 0f 52 98 b5 cd 98  1f 89 20 5f f2 a0 1c a3  |...R...... _....|
+000002e0  1b 96 94 dd a9 fd 57 e9  70 e8 26 6d 71 99 9b 26  |......W.p.&mq..&|
+000002f0  6e 38 50 29 6c 90 a7 bd  d9 16 03 02 00 04 0e 00  |n8P)l...........|
+00000300  00 00                                             |..|
 >>> Flow 3 (client to server)
-00000000  16 03 02 00 86 10 00 00  82 00 80 04 ed f2 fd 60  |...............`|
-00000010  fe 22 e4 ed 2a d2 f4 e2  7c 50 f7 a5 20 7f aa 06  |."..*...|P.. ...|
-00000020  ab fa 73 e7 fa 52 da 1e  ee a2 27 2c 90 21 35 0e  |..s..R....',.!5.|
-00000030  b4 c7 ca 3e 94 bc 65 e0  64 cb a0 c3 80 15 6e 40  |...>..e.d.....n@|
-00000040  53 6c 02 ec e8 b9 51 29  ae b8 bc 1e fa 18 61 50  |Sl....Q)......aP|
-00000050  79 f4 31 d3 13 0d e1 36  a4 2b c1 7d 3f 88 90 a5  |y.1....6.+.}?...|
-00000060  3d bd 09 2a e8 f9 56 a5  4b 59 63 90 0a fd 79 26  |=..*..V.KYc...y&|
-00000070  2b 80 8c 40 68 ee 85 41  c1 b7 9c 6d d5 fc 2f 96  |+..@h..A...m../.|
-00000080  d3 20 7b 34 7b 8c 94 5f  fc 27 80 14 03 02 00 01  |. {4{.._.'......|
-00000090  01 16 03 02 00 24 ae b1  15 28 25 1b e0 a1 d1 6e  |.....$...(%....n|
-000000a0  6f 01 b9 ff 19 09 2e 01  c1 15 b8 04 cc ad e7 63  |o..............c|
-000000b0  29 0a fd 3e eb ea 56 f3  68 ac                    |)..>..V.h.|
+00000000  16 03 02 00 86 10 00 00  82 00 80 71 2b 19 25 86  |...........q+.%.|
+00000010  a0 ff ba d5 1c a6 0c 8b  6b 0a b8 e9 42 93 2f 55  |........k...B./U|
+00000020  a8 ee 62 fa ed bc 6d e2  9d e3 76 a6 73 d7 99 58  |..b...m...v.s..X|
+00000030  cc 0b 14 42 96 7c b6 c7  8f 21 16 cf 71 9b 2b b9  |...B.|...!..q.+.|
+00000040  e0 34 57 76 22 d5 87 8a  ce 1f ea 26 6e 1e e6 ca  |.4Wv"......&n...|
+00000050  55 3b 20 cd cf 42 26 b1  51 3e 8c 1d a2 ae c4 63  |U; ..B&.Q>.....c|
+00000060  f5 ce 27 3c 1e c3 e0 e3  b1 16 c1 8a 62 bd 21 7f  |..'<........b.!.|
+00000070  38 b5 b7 3a 3c bb 03 37  e1 a5 ff f1 29 e2 21 0a  |8..:<..7....).!.|
+00000080  8c 20 02 e0 c0 82 97 9d  18 6d f8 14 03 02 00 01  |. .......m......|
+00000090  01 16 03 02 00 24 bc 19  16 6e fd 0b db 9e d5 1d  |.....$...n......|
+000000a0  65 b6 57 1c 58 b5 6a ac  f7 4f f0 cd a1 a9 0c c0  |e.W.X.j..O......|
+000000b0  df e6 eb d5 00 f7 fd 43  bb 27                    |.......C.'|
 >>> Flow 4 (server to client)
-00000000  14 03 02 00 01 01 16 03  02 00 24 99 ca 80 4d cf  |..........$...M.|
-00000010  dd de 83 29 63 8c 16 36  5f e0 6b ed c4 ed 6c 03  |...)c..6_.k...l.|
-00000020  9a 56 8b 78 e1 cc 68 a5  83 ae 25 23 4d 31 0a 17  |.V.x..h...%#M1..|
-00000030  03 02 00 21 66 36 75 ae  62 17 85 e8 2e b0 3d c6  |...!f6u.b.....=.|
-00000040  c7 71 44 a5 6b 50 ea c3  8b 46 b8 b6 d0 9d 04 36  |.qD.kP...F.....6|
-00000050  cd f1 69 cf 8f 15 03 02  00 16 47 61 e8 e2 4c bb  |..i.......Ga..L.|
-00000060  10 a3 31 38 5a a1 33 61  c2 09 cf a9 95 1c df 72  |..18Z.3a.......r|
+00000000  14 03 02 00 01 01 16 03  02 00 24 cf 4f e4 27 b0  |..........$.O.'.|
+00000010  3d 17 34 b1 3c 37 6e c5  2b 3d 4a c3 46 50 44 b4  |=.4.<7n.+=J.FPD.|
+00000020  de 77 18 10 4f 60 b3 4e  dc 06 fd 25 ec 05 15 17  |.w..O`.N...%....|
+00000030  03 02 00 21 a5 c9 32 f2  21 fb 94 7e 0d 15 65 fd  |...!..2.!..~..e.|
+00000040  3e fe e4 c1 a5 e9 88 72  b2 f1 26 39 a6 48 59 97  |>......r..&9.HY.|
+00000050  65 e3 f0 cb 46 15 03 02  00 16 4b 02 ec cd ca 30  |e...F.....K....0|
+00000060  42 cf 3d a0 4a fa 8e 79  bb ed b0 59 40 9b 2c 1a  |B.=.J..y...Y@.,.|
index cd91d7f50a97c358e38fb0e9ecf3753b99d22761..c170408e48099b5d9eea6faa16eea0d9bfd7d954 100644 (file)
@@ -1,24 +1,17 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 01 39 01 00 01  35 03 03 52 ac 77 f8 cf  |....9...5..R.w..|
-00000010  8e 29 75 5c 1e a8 0c ef  df a1 2b c5 c0 ca fe bc  |.)u\......+.....|
-00000020  63 b1 df 9a 17 e3 5f a4  e1 1c c4 00 00 a0 c0 30  |c....._........0|
+00000000  16 03 01 00 ca 01 00 00  c6 03 03 52 cc 5e 7f 49  |...........R.^.I|
+00000010  8a 7a 88 c0 85 24 6b 3d  95 ff 0f 9e 91 32 c2 a4  |.z...$k=.....2..|
+00000020  6b 4c 53 e4 b4 4c 40 72  e4 54 27 00 00 32 c0 30  |kLS..L@r.T'..2.0|
 00000030  c0 2c c0 28 c0 24 c0 14  c0 0a c0 22 c0 21 00 a3  |.,.(.$.....".!..|
 00000040  00 9f 00 6b 00 6a 00 39  00 38 00 88 00 87 c0 32  |...k.j.9.8.....2|
 00000050  c0 2e c0 2a c0 26 c0 0f  c0 05 00 9d 00 3d 00 35  |...*.&.......=.5|
-00000060  00 84 c0 12 c0 08 c0 1c  c0 1b 00 16 00 13 c0 0d  |................|
-00000070  c0 03 00 0a c0 2f c0 2b  c0 27 c0 23 c0 13 c0 09  |...../.+.'.#....|
-00000080  c0 1f c0 1e 00 a2 00 9e  00 67 00 40 00 33 00 32  |.........g.@.3.2|
-00000090  00 9a 00 99 00 45 00 44  c0 31 c0 2d c0 29 c0 25  |.....E.D.1.-.).%|
-000000a0  c0 0e c0 04 00 9c 00 3c  00 2f 00 96 00 41 00 07  |.......<./...A..|
-000000b0  c0 11 c0 07 c0 0c c0 02  00 05 00 04 00 15 00 12  |................|
-000000c0  00 09 00 14 00 11 00 08  00 06 00 03 00 ff 02 01  |................|
-000000d0  00 00 6b 00 0b 00 04 03  00 01 02 00 0a 00 34 00  |..k...........4.|
-000000e0  32 00 0e 00 0d 00 19 00  0b 00 0c 00 18 00 09 00  |2...............|
-000000f0  0a 00 16 00 17 00 08 00  06 00 07 00 14 00 15 00  |................|
-00000100  04 00 05 00 12 00 13 00  01 00 02 00 03 00 0f 00  |................|
-00000110  10 00 11 00 0d 00 22 00  20 06 01 06 02 06 03 05  |......". .......|
-00000120  01 05 02 05 03 04 01 04  02 04 03 03 01 03 02 03  |................|
-00000130  03 02 01 02 02 02 03 01  01 00 0f 00 01 01        |..............|
+00000060  01 00 00 6b 00 0b 00 04  03 00 01 02 00 0a 00 34  |...k...........4|
+00000070  00 32 00 0e 00 0d 00 19  00 0b 00 0c 00 18 00 09  |.2..............|
+00000080  00 0a 00 16 00 17 00 08  00 06 00 07 00 14 00 15  |................|
+00000090  00 04 00 05 00 12 00 13  00 01 00 02 00 03 00 0f  |................|
+000000a0  00 10 00 11 00 0d 00 22  00 20 06 01 06 02 06 03  |.......". ......|
+000000b0  05 01 05 02 05 03 04 01  04 02 04 03 03 01 03 02  |................|
+000000c0  03 03 02 01 02 02 02 03  01 01 00 0f 00 01 01     |...............|
 >>> Flow 2 (server to client)
 00000000  16 03 03 00 2a 02 00 00  26 03 03 00 00 00 00 00  |....*...&.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000310  48 b3 c1 85 6a 42 9b f9  7e 7e 31 c2 e5 bd 66 02  |H...jB..~~1...f.|
 00000320  42 00 ad 7d 06 35 ab ec  8d ac d4 ba 1b 49 5e 05  |B..}.5.......I^.|
 00000330  5f f0 97 93 82 b8 2b 8d  91 98 63 8e b4 14 62 db  |_.....+...c...b.|
-00000340  1e c9 2b b9 8d 7b bf 37  1c f3 94 74 60 d6 7d a5  |..+..{.7...t`.}.|
-00000350  28 0a 74 d1 59 87 c3 42  31 9a 0e f7 85 ce ec eb  |(.t.Y..B1.......|
-00000360  fa 4a 14 16 03 03 00 04  0e 00 00 00              |.J..........|
+00000340  1e c9 2b ca fe c9 88 b7  3d 46 d2 5b 55 de bc 9a  |..+.....=F.[U...|
+00000350  66 c9 cf b7 3d e8 c8 62  24 93 d8 db 12 77 2a 6c  |f...=..b$....w*l|
+00000360  08 66 48 16 03 03 00 04  0e 00 00 00              |.fH.........|
 >>> Flow 3 (client to server)
-00000000  16 03 03 00 8a 10 00 00  86 85 04 01 31 b5 19 44  |............1..D|
-00000010  f5 d4 29 20 77 2e cc a9  bb ab 5d 3b f6 0e 5c dd  |..) w.....];..\.|
-00000020  c2 cd 42 a4 b1 ce 1f 69  0f 09 c7 ef 5a 99 96 03  |..B....i....Z...|
-00000030  5b 57 86 02 c0 d0 9a a6  5f 59 b0 5b 45 c2 ae ec  |[W......_Y.[E...|
-00000040  cf 3d 3d 60 b5 5f 7d c9  82 5a 54 0b 74 00 c2 8b  |.==`._}..ZT.t...|
-00000050  67 2f f9 dd c9 bd 2c 63  12 5b 55 61 09 8b fe 75  |g/....,c.[Ua...u|
-00000060  23 2c a2 c1 bd 6e 71 23  07 e3 c2 64 5e 13 f1 d1  |#,...nq#...d^...|
-00000070  cc db 17 dc 8b e6 4f d4  72 46 0a 1e 26 63 cb e0  |......O.rF..&c..|
-00000080  da f3 f7 f6 d3 64 f5 44  ce 01 7b 21 4e cb 23 14  |.....d.D..{!N.#.|
-00000090  03 03 00 01 01 16 03 03  00 40 5d 5b 3c 90 6b e1  |.........@][<.k.|
-000000a0  33 90 6a a3 6a 9e f8 a6  9b 2d ca 8b ea 26 10 92  |3.j.j....-...&..|
-000000b0  ca 60 7b 4b fb 8a df 5d  1d 4b 23 41 7e 4f f7 c2  |.`{K...].K#A~O..|
-000000c0  98 64 11 84 56 bc 9c ba  11 1c 19 7f a9 04 43 d3  |.d..V.........C.|
-000000d0  a0 80 47 11 09 a5 dc 08  fc a0                    |..G.......|
+00000000  16 03 03 00 8a 10 00 00  86 85 04 01 fd 02 a1 b1  |................|
+00000010  56 3c 37 37 da 78 37 d9  07 ee 09 35 4f ff 3e db  |V<77.x7....5O.>.|
+00000020  da da 23 12 2c 40 12 dd  73 e7 2c c5 2e fb 37 24  |..#.,@..s.,...7$|
+00000030  2f 97 95 b4 6c 1e 56 6c  4e 49 d5 89 21 8b ca 74  |/...l.VlNI..!..t|
+00000040  85 1b 24 96 fb 28 cc 64  70 59 fc be 18 00 00 98  |..$..(.dpY......|
+00000050  9a f6 c9 26 26 6d ce 48  7b 3b 62 ea dd da 73 8b  |...&&m.H{;b...s.|
+00000060  71 48 18 71 52 2d 22 1d  7c 67 55 1b 6b fa 44 40  |qH.qR-".|gU.k.D@|
+00000070  be 87 0f 52 21 4b 86 b4  f0 6d 1b dd e7 0f f8 ef  |...R!K...m......|
+00000080  1a 09 8b 66 b9 60 38 da  6f 9d 9d 74 58 d9 35 14  |...f.`8.o..tX.5.|
+00000090  03 03 00 01 01 16 03 03  00 40 5b 98 11 9d d4 83  |.........@[.....|
+000000a0  13 b6 28 4b 85 61 0b e1  bf 36 3f 43 c0 95 3d 7e  |..(K.a...6?C..=~|
+000000b0  95 ea 84 14 e6 6d 1a e0  20 50 b4 02 d0 b2 e9 5f  |.....m.. P....._|
+000000c0  07 82 a8 6a 1e 7c 1e f7  6c b5 be 1b 20 2e 98 4e  |...j.|..l... ..N|
+000000d0  ab 8d 1e f2 56 88 ed ef  aa 39                    |....V....9|
 >>> Flow 4 (server to client)
 00000000  14 03 03 00 01 01 16 03  03 00 40 00 00 00 00 00  |..........@.....|
-00000010  00 00 00 00 00 00 00 00  00 00 00 2e 6a 39 7e ab  |............j9~.|
-00000020  da af a7 27 4f 60 4e e4  d6 6e 75 3a 03 20 af 45  |...'O`N..nu:. .E|
-00000030  a2 ad 58 2e 8b 4b e6 5f  22 41 87 79 21 eb 5c 71  |..X..K._"A.y!.\q|
-00000040  d8 63 ba 42 8b 32 8a 61  e2 6f 43 17 03 03 00 40  |.c.B.2.a.oC....@|
+00000010  00 00 00 00 00 00 00 00  00 00 00 7e f1 fc 1d 0c  |...........~....|
+00000020  f5 a2 c6 35 de 78 97 62  72 3f 05 6c a3 a8 0e cb  |...5.x.br?.l....|
+00000030  10 7e c0 3d 28 c7 d9 4e  71 f4 18 d7 14 42 09 5c  |.~.=(..Nq....B.\|
+00000040  22 26 04 1f 04 12 9f 88  3d 4a 4a 17 03 03 00 40  |"&......=JJ....@|
 00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000060  2e e2 39 2b 6c 28 9e 3a  59 f6 31 04 8b 95 be bd  |..9+l(.:Y.1.....|
-00000070  73 e6 12 77 ab 3a 30 30  1b f2 5f 7e 42 f9 53 1c  |s..w.:00.._~B.S.|
-00000080  bf 3c 58 8f e0 b6 c7 f2  c5 5d 0f d0 37 3f 37 96  |.<X......]..7?7.|
+00000060  0f 35 50 38 be 3a c7 4e  c4 de 36 63 85 c1 7a 78  |.5P8.:.N..6c..zx|
+00000070  c6 7f 65 8c d1 44 c5 7e  45 32 60 88 93 bf 10 82  |..e..D.~E2`.....|
+00000080  4b 1a 46 9a 60 54 c5 ee  2a c1 86 02 a7 b6 d5 ea  |K.F.`T..*.......|
 00000090  15 03 03 00 30 00 00 00  00 00 00 00 00 00 00 00  |....0...........|
-000000a0  00 00 00 00 00 a5 fa 6a  4d 33 1a 0d 83 5e 26 39  |.......jM3...^&9|
-000000b0  a1 07 3c 00 02 7e 2b 1b  c0 95 4a 16 85 83 c4 af  |..<..~+...J.....|
-000000c0  79 0e 43 c6 c8                                    |y.C..|
+000000a0  00 00 00 00 00 78 6c 41  05 2f 6f c2 d7 70 54 24  |.....xlA./o..pT$|
+000000b0  66 01 2c 1e 71 43 05 3a  1b 9e 86 ff b4 c5 65 b2  |f.,.qC.:......e.|
+000000c0  f0 f8 ef 6b 25                                    |...k%|
index 637c8aa98f78cca1796cc30ef2e2835bb272ef1f..de2f0aba8b31c64f6eac846722e42b6badaefae4 100644 (file)
@@ -1,28 +1,21 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 01 39 01 00 01  35 03 03 52 ac 77 f8 37  |....9...5..R.w.7|
-00000010  29 0d 02 21 92 09 b5 f1  91 cd bc a7 7d 84 2b 9b  |)..!........}.+.|
-00000020  f5 4f bf b6 c6 f3 a0 60  62 df cf 00 00 a0 c0 30  |.O.....`b......0|
+00000000  16 03 01 00 ca 01 00 00  c6 03 03 52 cc 5e 7f ec  |...........R.^..|
+00000010  d7 b4 0c ac 92 e8 d1 6e  df c1 e6 ee f5 84 5e 1a  |.......n......^.|
+00000020  1d 05 bf 2d 3f 71 91 d1  cc b7 f8 00 00 32 c0 30  |...-?q.......2.0|
 00000030  c0 2c c0 28 c0 24 c0 14  c0 0a c0 22 c0 21 00 a3  |.,.(.$.....".!..|
 00000040  00 9f 00 6b 00 6a 00 39  00 38 00 88 00 87 c0 32  |...k.j.9.8.....2|
 00000050  c0 2e c0 2a c0 26 c0 0f  c0 05 00 9d 00 3d 00 35  |...*.&.......=.5|
-00000060  00 84 c0 12 c0 08 c0 1c  c0 1b 00 16 00 13 c0 0d  |................|
-00000070  c0 03 00 0a c0 2f c0 2b  c0 27 c0 23 c0 13 c0 09  |...../.+.'.#....|
-00000080  c0 1f c0 1e 00 a2 00 9e  00 67 00 40 00 33 00 32  |.........g.@.3.2|
-00000090  00 9a 00 99 00 45 00 44  c0 31 c0 2d c0 29 c0 25  |.....E.D.1.-.).%|
-000000a0  c0 0e c0 04 00 9c 00 3c  00 2f 00 96 00 41 00 07  |.......<./...A..|
-000000b0  c0 11 c0 07 c0 0c c0 02  00 05 00 04 00 15 00 12  |................|
-000000c0  00 09 00 14 00 11 00 08  00 06 00 03 00 ff 02 01  |................|
-000000d0  00 00 6b 00 0b 00 04 03  00 01 02 00 0a 00 34 00  |..k...........4.|
-000000e0  32 00 0e 00 0d 00 19 00  0b 00 0c 00 18 00 09 00  |2...............|
-000000f0  0a 00 16 00 17 00 08 00  06 00 07 00 14 00 15 00  |................|
-00000100  04 00 05 00 12 00 13 00  01 00 02 00 03 00 0f 00  |................|
-00000110  10 00 11 00 0d 00 22 00  20 06 01 06 02 06 03 05  |......". .......|
-00000120  01 05 02 05 03 04 01 04  02 04 03 03 01 03 02 03  |................|
-00000130  03 02 01 02 02 02 03 01  01 00 0f 00 01 01        |..............|
+00000060  01 00 00 6b 00 0b 00 04  03 00 01 02 00 0a 00 34  |...k...........4|
+00000070  00 32 00 0e 00 0d 00 19  00 0b 00 0c 00 18 00 09  |.2..............|
+00000080  00 0a 00 16 00 17 00 08  00 06 00 07 00 14 00 15  |................|
+00000090  00 04 00 05 00 12 00 13  00 01 00 02 00 03 00 0f  |................|
+000000a0  00 10 00 11 00 0d 00 22  00 20 06 01 06 02 06 03  |.......". ......|
+000000b0  05 01 05 02 05 03 04 01  04 02 04 03 03 01 03 02  |................|
+000000c0  03 03 02 01 02 02 02 03  01 01 00 0f 00 01 01     |...............|
 >>> Flow 2 (server to client)
 00000000  16 03 03 00 2a 02 00 00  26 03 03 00 00 00 00 00  |....*...&.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 c0 13 00 16  |................|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 c0 14 00 16  |................|
 00000030  03 03 02 be 0b 00 02 ba  00 02 b7 00 02 b4 30 82  |..............0.|
 00000040  02 b0 30 82 02 19 a0 03  02 01 02 02 09 00 85 b0  |..0.............|
 00000050  bb a4 8a 7f b8 ca 30 0d  06 09 2a 86 48 86 f7 0d  |......0...*.H...|
 00000350  61 28 63 33 78 f6 31 39  fd 8a f4 15 18 11 fe db  |a(c3x.19........|
 00000360  d5 07 da 2c ed 49 a0 23  bf d0 3a 38 1d 54 ae 1c  |...,.I.#..:8.T..|
 00000370  7b ea 29 ee d0 38 c1 76  a7 7f 2a f4 ce 1e ac cc  |{.)..8.v..*.....|
-00000380  94 79 90 33 04 01 00 80  8f 6a 76 5c 33 9a 1e 46  |.y.3.....jv\3..F|
-00000390  e6 c4 91 f6 69 23 05 38  bf c0 fd 9e dc 32 49 a6  |....i#.8.....2I.|
-000003a0  9a 80 43 a0 47 d4 37 f5  98 06 2f 77 cb 30 8a 95  |..C.G.7.../w.0..|
-000003b0  04 02 76 f1 2a ee 7c a6  79 df 7f 63 1e 1a 64 75  |..v.*.|.y..c..du|
-000003c0  f5 a9 1e a9 32 49 65 8b  5b 1b 02 68 7b 6c 39 e8  |....2Ie.[..h{l9.|
-000003d0  06 99 10 08 77 f7 a2 b3  22 14 14 d6 83 b8 a2 3e  |....w..."......>|
-000003e0  e3 a6 4d dd da 99 c4 d7  5c 4c d1 2f 0e 0e 21 2e  |..M.....\L./..!.|
-000003f0  e0 9d dc bf 51 f3 da 1d  7a df 8e dc 41 77 b3 18  |....Q...z...Aw..|
-00000400  38 75 ba b6 a3 75 0f fd  16 03 03 00 04 0e 00 00  |8u...u..........|
+00000380  94 79 90 33 04 01 00 80  ad 89 a5 bf 16 74 a1 14  |.y.3.........t..|
+00000390  c4 a1 09 31 95 69 e4 b4  e3 8d df 99 73 cd e6 94  |...1.i......s...|
+000003a0  eb ca 07 7f f4 36 ca 31  1c 29 f0 f0 d8 40 6b 19  |.....6.1.)...@k.|
+000003b0  f2 15 be f1 76 22 b3 82  f7 bf 2b 09 0f cd 31 c8  |....v"....+...1.|
+000003c0  69 7b 7b 1a ed a1 f7 85  6e 04 5c fa a5 20 c0 ef  |i{{.....n.\.. ..|
+000003d0  c6 45 6d 05 25 37 ec f6  94 91 32 f3 c8 d1 f0 13  |.Em.%7....2.....|
+000003e0  81 1e 26 bb 4c 47 91 79  ad cf 7e 61 85 54 eb 13  |..&.LG.y..~a.T..|
+000003f0  6b b1 15 36 72 bf d1 ad  07 3e 6d bd 44 1a 30 ac  |k..6r....>m.D.0.|
+00000400  41 39 ad 75 14 bb 11 dc  16 03 03 00 04 0e 00 00  |A9.u............|
 00000410  00                                                |.|
 >>> Flow 3 (client to server)
-00000000  16 03 03 00 8a 10 00 00  86 85 04 01 e0 a2 f2 1d  |................|
-00000010  d1 f5 e7 49 09 07 df 43  5f 45 f7 fc 42 9a 81 7d  |...I...C_E..B..}|
-00000020  39 fa bf 1c 74 df 68 de  93 49 62 3e 72 e7 78 47  |9...t.h..Ib>r.xG|
-00000030  71 71 fd d0 3d 89 d3 38  aa f0 54 4a ad 1e 87 e9  |qq..=..8..TJ....|
-00000040  f7 89 90 b0 25 5b a0 81  a0 20 1a 99 5e 01 7f 05  |....%[... ..^...|
-00000050  95 78 f7 f4 4a ec 85 a9  aa cc 56 bc f7 15 37 ab  |.x..J.....V...7.|
-00000060  31 41 62 d3 ea 46 ce 94  bf 6c 00 83 a6 f0 ee dc  |1Ab..F...l......|
-00000070  0b 2a e0 5a fb f0 db 70  cd 9f 48 92 49 c9 9d 20  |.*.Z...p..H.I.. |
-00000080  7b 8c de af 9d cd 5e 20  94 4e 95 c7 32 50 94 14  |{.....^ .N..2P..|
-00000090  03 03 00 01 01 16 03 03  00 40 6a 6c 92 ef b5 d0  |.........@jl....|
-000000a0  8f 4d c7 23 5b 31 65 71  24 50 be 5a e7 95 fc 14  |.M.#[1eq$P.Z....|
-000000b0  e7 4f 33 c8 ae e0 e7 5f  63 76 3a 7b 51 cd 18 7a  |.O3...._cv:{Q..z|
-000000c0  15 15 0c aa cc 76 be fc  1e 55 a1 3a df 05 4c 84  |.....v...U.:..L.|
-000000d0  75 6e c2 2b 3d 93 76 53  41 13                    |un.+=.vSA.|
+00000000  16 03 03 00 8a 10 00 00  86 85 04 01 fb 77 96 9a  |.............w..|
+00000010  82 26 4f 44 b5 2f 32 28  0a dd 51 f5 a4 84 46 a1  |.&OD./2(..Q...F.|
+00000020  ba 58 e6 9a 96 1b 85 9f  ae 3a 8b db a8 93 81 00  |.X.......:......|
+00000030  17 be 24 26 17 fd b8 7c  fe 93 7f af 5f 4d c6 47  |..$&...|...._M.G|
+00000040  8b 72 5b 23 89 03 d5 a6  fb 6f de 59 15 00 bb 36  |.r[#.....o.Y...6|
+00000050  6d 72 03 47 61 b7 7e d4  46 43 b3 e9 9d 2f 61 6a  |mr.Ga.~.FC.../aj|
+00000060  08 1b 04 70 ac 95 ad bf  18 e5 09 b6 b3 0d 6a bb  |...p..........j.|
+00000070  e8 77 09 fa 81 2e 8a e1  61 7e 9f 38 d0 67 f5 11  |.w......a~.8.g..|
+00000080  f1 62 7f a4 69 4a 42 7a  f8 9e 05 26 66 34 6e 14  |.b..iJBz...&f4n.|
+00000090  03 03 00 01 01 16 03 03  00 40 2c a1 a8 3a 34 18  |.........@,..:4.|
+000000a0  ea a1 d4 28 0b 1a ac ab  51 b1 c5 48 f2 56 8d c7  |...(....Q..H.V..|
+000000b0  83 7b 70 44 40 7d 15 1c  00 19 ed 53 21 fe 9d c1  |.{pD@}.....S!...|
+000000c0  a2 13 8f a0 0c 51 f5 13  67 1f bf 07 da bc 2d ca  |.....Q..g.....-.|
+000000d0  7c 0f 53 4b 4a 02 bb 0f  72 c6                    ||.SKJ...r.|
 >>> Flow 4 (server to client)
 00000000  14 03 03 00 01 01 16 03  03 00 40 00 00 00 00 00  |..........@.....|
-00000010  00 00 00 00 00 00 00 00  00 00 00 e8 4b a0 ea c7  |............K...|
-00000020  e8 9e 4a c7 c5 65 84 eb  3f 4e a5 bd 97 11 b4 0b  |..J..e..?N......|
-00000030  26 b8 6d 28 16 38 c4 92  d9 45 48 7f 7f e0 74 dd  |&.m(.8...EH...t.|
-00000040  85 b7 13 5b f8 4e 5b 3f  00 95 0a 17 03 03 00 40  |...[.N[?.......@|
+00000010  00 00 00 00 00 00 00 00  00 00 00 82 f6 03 51 7f  |..............Q.|
+00000020  37 19 ec 26 20 db e2 5b  8e 5e 22 29 1a 88 ca f1  |7..& ..[.^")....|
+00000030  ad 55 1c 3c 07 1d 05 b6  c4 88 58 84 a0 5d 33 41  |.U.<......X..]3A|
+00000040  7a 65 bc ba a1 71 a4 71  df 6c 9d 17 03 03 00 40  |ze...q.q.l.....@|
 00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000060  c6 52 ac 75 32 b3 86 f4  cb cf 18 66 02 40 a3 b1  |.R.u2......f.@..|
-00000070  cb 1b 25 2e ac 91 a7 91  2b 73 37 72 c1 1f 2c 2f  |..%.....+s7r..,/|
-00000080  55 59 12 bd f0 df b4 07  fa b1 13 cc 58 f3 66 54  |UY..........X.fT|
+00000060  8d ca 51 a1 4a b1 23 dc  e3 ef 63 5f b0 e8 7a c6  |..Q.J.#...c_..z.|
+00000070  97 d7 18 6a 4b 80 3e 5c  7b 79 86 93 60 2c 8b f1  |...jK.>\{y..`,..|
+00000080  4e 46 c5 5e 64 0c 98 81  10 6d c5 08 22 f1 02 1d  |NF.^d....m.."...|
 00000090  15 03 03 00 30 00 00 00  00 00 00 00 00 00 00 00  |....0...........|
-000000a0  00 00 00 00 00 14 49 94  f4 07 cb 98 d2 6f a5 b3  |......I......o..|
-000000b0  37 bb 55 71 04 43 f9 3c  53 1c 00 31 c9 3b 8a 5c  |7.Uq.C.<S..1.;.\|
-000000c0  53 75 90 5d 59                                    |Su.]Y|
+000000a0  00 00 00 00 00 51 19 c4  67 b7 14 6b 5c 49 ac 1d  |.....Q..g..k\I..|
+000000b0  b3 97 88 42 29 cb f5 06  54 f4 c6 38 9a 47 41 78  |...B)...T..8.GAx|
+000000c0  0f 33 21 ac c5                                    |.3!..|
index fb4edae9c9169bbcbbe4410b091f212eff1751eb..547f79834d965eeeb6fd765103b14ee9a509d1d7 100644 (file)
@@ -1,61 +1,62 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 5d 01 00 00  59 03 03 52 ac 77 f8 7c  |....]...Y..R.w.||
-00000010  ec cd d0 9c df d2 a6 8b  74 43 ed af 58 14 00 1f  |........tC..X...|
-00000020  3f 85 68 1d c9 3d 20 0a  61 87 33 00 00 04 00 05  |?.h..= .a.3.....|
-00000030  00 ff 02 01 00 00 2b 00  0d 00 22 00 20 06 01 06  |......+...". ...|
-00000040  02 06 03 05 01 05 02 05  03 04 01 04 02 04 03 03  |................|
-00000050  01 03 02 03 03 02 01 02  02 02 03 01 01 00 0f 00  |................|
-00000060  01 01                                             |..|
+00000000  16 03 01 00 5c 01 00 00  58 03 03 52 cc 57 59 65  |....\...X..R.WYe|
+00000010  ae b3 ec a4 7a 05 f7 ec  39 22 7d 8c 91 96 6b e0  |....z...9"}...k.|
+00000020  69 81 ff 88 28 17 60 ac  94 19 ff 00 00 04 00 05  |i...(.`.........|
+00000030  00 ff 01 00 00 2b 00 0d  00 22 00 20 06 01 06 02  |.....+...". ....|
+00000040  06 03 05 01 05 02 05 03  04 01 04 02 04 03 03 01  |................|
+00000050  03 02 03 03 02 01 02 02  02 03 01 01 00 0f 00 01  |................|
+00000060  01                                                |.|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 2a 02 00 00  26 03 03 00 00 00 00 00  |....*...&.......|
+00000000  16 03 03 00 31 02 00 00  2d 03 03 00 00 00 00 00  |....1...-.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 05 00 16  |................|
-00000030  03 03 02 be 0b 00 02 ba  00 02 b7 00 02 b4 30 82  |..............0.|
-00000040  02 b0 30 82 02 19 a0 03  02 01 02 02 09 00 85 b0  |..0.............|
-00000050  bb a4 8a 7f b8 ca 30 0d  06 09 2a 86 48 86 f7 0d  |......0...*.H...|
-00000060  01 01 05 05 00 30 45 31  0b 30 09 06 03 55 04 06  |.....0E1.0...U..|
-00000070  13 02 41 55 31 13 30 11  06 03 55 04 08 13 0a 53  |..AU1.0...U....S|
-00000080  6f 6d 65 2d 53 74 61 74  65 31 21 30 1f 06 03 55  |ome-State1!0...U|
-00000090  04 0a 13 18 49 6e 74 65  72 6e 65 74 20 57 69 64  |....Internet Wid|
-000000a0  67 69 74 73 20 50 74 79  20 4c 74 64 30 1e 17 0d  |gits Pty Ltd0...|
-000000b0  31 30 30 34 32 34 30 39  30 39 33 38 5a 17 0d 31  |100424090938Z..1|
-000000c0  31 30 34 32 34 30 39 30  39 33 38 5a 30 45 31 0b  |10424090938Z0E1.|
-000000d0  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-000000e0  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-000000f0  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-00000100  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-00000110  4c 74 64 30 81 9f 30 0d  06 09 2a 86 48 86 f7 0d  |Ltd0..0...*.H...|
-00000120  01 01 01 05 00 03 81 8d  00 30 81 89 02 81 81 00  |.........0......|
-00000130  bb 79 d6 f5 17 b5 e5 bf  46 10 d0 dc 69 be e6 2b  |.y......F...i..+|
-00000140  07 43 5a d0 03 2d 8a 7a  43 85 b7 14 52 e7 a5 65  |.CZ..-.zC...R..e|
-00000150  4c 2c 78 b8 23 8c b5 b4  82 e5 de 1f 95 3b 7e 62  |L,x.#........;~b|
-00000160  a5 2c a5 33 d6 fe 12 5c  7a 56 fc f5 06 bf fa 58  |.,.3...\zV.....X|
-00000170  7b 26 3f b5 cd 04 d3 d0  c9 21 96 4a c7 f4 54 9f  |{&?......!.J..T.|
-00000180  5a bf ef 42 71 00 fe 18  99 07 7f 7e 88 7d 7d f1  |Z..Bq......~.}}.|
-00000190  04 39 c4 a2 2e db 51 c9  7c e3 c0 4c 3b 32 66 01  |.9....Q.|..L;2f.|
-000001a0  cf af b1 1d b8 71 9a 1d  db db 89 6b ae da 2d 79  |.....q.....k..-y|
-000001b0  02 03 01 00 01 a3 81 a7  30 81 a4 30 1d 06 03 55  |........0..0...U|
-000001c0  1d 0e 04 16 04 14 b1 ad  e2 85 5a cf cb 28 db 69  |..........Z..(.i|
-000001d0  ce 23 69 de d3 26 8e 18  88 39 30 75 06 03 55 1d  |.#i..&...90u..U.|
-000001e0  23 04 6e 30 6c 80 14 b1  ad e2 85 5a cf cb 28 db  |#.n0l......Z..(.|
-000001f0  69 ce 23 69 de d3 26 8e  18 88 39 a1 49 a4 47 30  |i.#i..&...9.I.G0|
-00000200  45 31 0b 30 09 06 03 55  04 06 13 02 41 55 31 13  |E1.0...U....AU1.|
-00000210  30 11 06 03 55 04 08 13  0a 53 6f 6d 65 2d 53 74  |0...U....Some-St|
-00000220  61 74 65 31 21 30 1f 06  03 55 04 0a 13 18 49 6e  |ate1!0...U....In|
-00000230  74 65 72 6e 65 74 20 57  69 64 67 69 74 73 20 50  |ternet Widgits P|
-00000240  74 79 20 4c 74 64 82 09  00 85 b0 bb a4 8a 7f b8  |ty Ltd..........|
-00000250  ca 30 0c 06 03 55 1d 13  04 05 30 03 01 01 ff 30  |.0...U....0....0|
-00000260  0d 06 09 2a 86 48 86 f7  0d 01 01 05 05 00 03 81  |...*.H..........|
-00000270  81 00 08 6c 45 24 c7 6b  b1 59 ab 0c 52 cc f2 b0  |...lE$.k.Y..R...|
-00000280  14 d7 87 9d 7a 64 75 b5  5a 95 66 e4 c5 2b 8e ae  |....zdu.Z.f..+..|
-00000290  12 66 1f eb 4f 38 b3 6e  60 d3 92 fd f7 41 08 b5  |.f..O8.n`....A..|
-000002a0  25 13 b1 18 7a 24 fb 30  1d ba ed 98 b9 17 ec e7  |%...z$.0........|
-000002b0  d7 31 59 db 95 d3 1d 78  ea 50 56 5c d5 82 5a 2d  |.1Y....x.PV\..Z-|
-000002c0  5a 5f 33 c4 b6 d8 c9 75  90 96 8c 0f 52 98 b5 cd  |Z_3....u....R...|
-000002d0  98 1f 89 20 5f f2 a0 1c  a3 1b 96 94 dd a9 fd 57  |... _..........W|
-000002e0  e9 70 e8 26 6d 71 99 9b  26 6e 38 50 29 6c 90 a7  |.p.&mq..&n8P)l..|
-000002f0  bd d9 16 03 03 00 0f 0d  00 00 0b 02 01 40 00 04  |.............@..|
-00000300  04 01 04 03 00 00 16 03  03 00 04 0e 00 00 00     |...............|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 05 00 00  |................|
+00000030  05 ff 01 00 01 00 16 03  03 02 be 0b 00 02 ba 00  |................|
+00000040  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
+00000050  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
+00000060  09 2a 86 48 86 f7 0d 01  01 05 05 00 30 45 31 0b  |.*.H........0E1.|
+00000070  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
+00000080  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
+00000090  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
+000000a0  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
+000000b0  4c 74 64 30 1e 17 0d 31  30 30 34 32 34 30 39 30  |Ltd0...100424090|
+000000c0  39 33 38 5a 17 0d 31 31  30 34 32 34 30 39 30 39  |938Z..1104240909|
+000000d0  33 38 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |38Z0E1.0...U....|
+000000e0  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
+000000f0  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
+00000100  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
+00000110  74 73 20 50 74 79 20 4c  74 64 30 81 9f 30 0d 06  |ts Pty Ltd0..0..|
+00000120  09 2a 86 48 86 f7 0d 01  01 01 05 00 03 81 8d 00  |.*.H............|
+00000130  30 81 89 02 81 81 00 bb  79 d6 f5 17 b5 e5 bf 46  |0.......y......F|
+00000140  10 d0 dc 69 be e6 2b 07  43 5a d0 03 2d 8a 7a 43  |...i..+.CZ..-.zC|
+00000150  85 b7 14 52 e7 a5 65 4c  2c 78 b8 23 8c b5 b4 82  |...R..eL,x.#....|
+00000160  e5 de 1f 95 3b 7e 62 a5  2c a5 33 d6 fe 12 5c 7a  |....;~b.,.3...\z|
+00000170  56 fc f5 06 bf fa 58 7b  26 3f b5 cd 04 d3 d0 c9  |V.....X{&?......|
+00000180  21 96 4a c7 f4 54 9f 5a  bf ef 42 71 00 fe 18 99  |!.J..T.Z..Bq....|
+00000190  07 7f 7e 88 7d 7d f1 04  39 c4 a2 2e db 51 c9 7c  |..~.}}..9....Q.||
+000001a0  e3 c0 4c 3b 32 66 01 cf  af b1 1d b8 71 9a 1d db  |..L;2f......q...|
+000001b0  db 89 6b ae da 2d 79 02  03 01 00 01 a3 81 a7 30  |..k..-y........0|
+000001c0  81 a4 30 1d 06 03 55 1d  0e 04 16 04 14 b1 ad e2  |..0...U.........|
+000001d0  85 5a cf cb 28 db 69 ce  23 69 de d3 26 8e 18 88  |.Z..(.i.#i..&...|
+000001e0  39 30 75 06 03 55 1d 23  04 6e 30 6c 80 14 b1 ad  |90u..U.#.n0l....|
+000001f0  e2 85 5a cf cb 28 db 69  ce 23 69 de d3 26 8e 18  |..Z..(.i.#i..&..|
+00000200  88 39 a1 49 a4 47 30 45  31 0b 30 09 06 03 55 04  |.9.I.G0E1.0...U.|
+00000210  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
+00000220  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
+00000230  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
+00000240  64 67 69 74 73 20 50 74  79 20 4c 74 64 82 09 00  |dgits Pty Ltd...|
+00000250  85 b0 bb a4 8a 7f b8 ca  30 0c 06 03 55 1d 13 04  |........0...U...|
+00000260  05 30 03 01 01 ff 30 0d  06 09 2a 86 48 86 f7 0d  |.0....0...*.H...|
+00000270  01 01 05 05 00 03 81 81  00 08 6c 45 24 c7 6b b1  |..........lE$.k.|
+00000280  59 ab 0c 52 cc f2 b0 14  d7 87 9d 7a 64 75 b5 5a  |Y..R.......zdu.Z|
+00000290  95 66 e4 c5 2b 8e ae 12  66 1f eb 4f 38 b3 6e 60  |.f..+...f..O8.n`|
+000002a0  d3 92 fd f7 41 08 b5 25  13 b1 18 7a 24 fb 30 1d  |....A..%...z$.0.|
+000002b0  ba ed 98 b9 17 ec e7 d7  31 59 db 95 d3 1d 78 ea  |........1Y....x.|
+000002c0  50 56 5c d5 82 5a 2d 5a  5f 33 c4 b6 d8 c9 75 90  |PV\..Z-Z_3....u.|
+000002d0  96 8c 0f 52 98 b5 cd 98  1f 89 20 5f f2 a0 1c a3  |...R...... _....|
+000002e0  1b 96 94 dd a9 fd 57 e9  70 e8 26 6d 71 99 9b 26  |......W.p.&mq..&|
+000002f0  6e 38 50 29 6c 90 a7 bd  d9 16 03 03 00 0f 0d 00  |n8P)l...........|
+00000300  00 0b 02 01 40 00 04 04  01 04 03 00 00 16 03 03  |....@...........|
+00000310  00 04 0e 00 00 00                                 |......|
 >>> Flow 3 (client to server)
 00000000  16 03 03 02 0a 0b 00 02  06 00 02 03 00 02 00 30  |...............0|
 00000010  82 01 fc 30 82 01 5e 02  09 00 9a 30 84 6c 26 35  |...0..^....0.l&5|
 000001e0  be e8 91 b3 da 1a f5 5d  a3 23 f5 26 8b 45 70 8d  |.......].#.&.Ep.|
 000001f0  65 62 9b 7e 01 99 3d 18  f6 10 9a 38 61 9b 2e 57  |eb.~..=....8a..W|
 00000200  e4 fa cc b1 8a ce e2 23  a0 87 f0 e1 67 51 eb 16  |.......#....gQ..|
-00000210  03 03 00 86 10 00 00 82  00 80 b9 28 1c 08 59 6e  |...........(..Yn|
-00000220  04 5f dd 1d a2 c0 04 d9  ef 2e 9c be ae a4 ce cb  |._..............|
-00000230  a3 5e 25 da ec a7 70 95  bb 78 1f 68 37 cc 76 25  |.^%...p..x.h7.v%|
-00000240  14 64 b1 23 35 7e af 93  07 56 41 f2 f7 6b 65 03  |.d.#5~...VA..ke.|
-00000250  98 08 0d dd 0b b3 57 3c  63 09 14 3e 38 7a e8 f6  |......W<c..>8z..|
-00000260  7a 92 3d f4 cc 91 78 a0  90 19 94 a8 1b 60 e5 aa  |z.=...x......`..|
-00000270  93 48 44 6c 89 e1 d7 5c  22 20 67 8e 3c 56 ef 7d  |.HDl...\" g.<V.}|
-00000280  1b 43 7d c5 d1 06 19 d4  6d 59 d7 36 59 63 e5 08  |.C}.....mY.6Yc..|
-00000290  84 53 51 1e cf a0 d7 fc  ec 2a 16 03 03 00 93 0f  |.SQ......*......|
-000002a0  00 00 8f 04 03 00 8b 30  81 88 02 42 01 99 ca f5  |.......0...B....|
-000002b0  1d 5f 49 9c 9e 98 df 42  65 dd 3c 6a 50 95 34 94  |._I....Be.<jP.4.|
-000002c0  ff 90 c1 91 89 19 4f 8c  7a a0 f6 9a 30 6d 69 25  |......O.z...0mi%|
-000002d0  d6 73 ce 37 6f 59 cc 84  62 de 48 d9 93 41 1c cb  |.s.7oY..b.H..A..|
-000002e0  93 b0 35 c9 01 f2 2b 23  68 62 97 ab 10 4c 02 42  |..5...+#hb...L.B|
-000002f0  00 ba e9 5f ba 91 96 5d  7f d3 a3 f0 c0 29 45 0d  |..._...].....)E.|
-00000300  47 64 93 92 96 6f 3a ea  a8 48 71 68 0e 67 62 b5  |Gd...o:..Hqh.gb.|
-00000310  61 09 b3 d0 6e 28 8d 43  c8 bc 6e 15 59 91 6c 74  |a...n(.C..n.Y.lt|
-00000320  6c 63 2c 02 dd 3d 40 ce  d9 2c 7e 4c f5 92 8c aa  |lc,..=@..,~L....|
-00000330  3a b7 14 03 03 00 01 01  16 03 03 00 24 46 dd 87  |:...........$F..|
-00000340  c7 50 96 64 41 11 ad b6  68 cc 90 04 85 21 48 aa  |.P.dA...h....!H.|
-00000350  43 da 06 a6 7e ec 73 71  be 37 9a a5 10 1b c7 5c  |C...~.sq.7.....\|
-00000360  a7                                                |.|
+00000210  03 03 00 86 10 00 00 82  00 80 47 5a 2f b8 78 46  |..........GZ/.xF|
+00000220  9f 3c fc ab 8b 35 c9 77  da c3 96 78 31 7c 2b 4f  |.<...5.w...x1|+O|
+00000230  56 be 0f 33 bd 17 bc 1c  86 5a ae b3 0f 8b 18 2f  |V..3.....Z...../|
+00000240  48 0d e0 0a 20 d3 53 96  88 d2 8a 7d b6 58 13 44  |H... .S....}.X.D|
+00000250  a5 e8 19 6d 02 df a6 1b  79 c5 54 c2 ef 4d 41 4f  |...m....y.T..MAO|
+00000260  04 1c eb 37 55 b7 2b f4  7c 6d 37 9c f1 89 a0 2c  |...7U.+.|m7....,|
+00000270  0f ba 10 09 e4 a1 ee 0a  7e 9a fd 2c 32 63 1c 55  |........~..,2c.U|
+00000280  85 38 de d0 7b 5f 46 03  1f cc 4d 69 51 97 d8 d7  |.8..{_F...MiQ...|
+00000290  88 6f ba 43 04 b0 42 09  61 5e 16 03 03 00 92 0f  |.o.C..B.a^......|
+000002a0  00 00 8e 04 03 00 8a 30  81 87 02 41 14 3d 4c 71  |.......0...A.=Lq|
+000002b0  c2 32 4a 20 ee b7 69 17  55 e8 99 55 11 76 51 7a  |.2J ..i.U..U.vQz|
+000002c0  74 55 e7 e8 c3 3b b3 70  db 1c 8e f6 8a d4 99 40  |tU...;.p.......@|
+000002d0  6e da 04 fd 7a 47 41 d6  ae c0 63 ad fd 91 a8 58  |n...zGA...c....X|
+000002e0  24 b9 ac 2f 7a 4c bf 5b  24 12 cb 3a f3 02 42 00  |$../zL.[$..:..B.|
+000002f0  90 f9 48 97 0e d4 33 99  09 9f 1d a8 97 16 60 82  |..H...3.......`.|
+00000300  85 cc 5a 5d 79 f7 2f 03  2a c0 b8 12 61 ac 9f 88  |..Z]y./.*...a...|
+00000310  1d 0d 9e 0a ee 28 a8 5a  e2 42 b7 94 e2 e6 0e 13  |.....(.Z.B......|
+00000320  c8 64 dc 4e d3 6b 10 d6  83 41 9c dc d4 53 c3 08  |.d.N.k...A...S..|
+00000330  19 14 03 03 00 01 01 16  03 03 00 24 ef bd e3 23  |...........$...#|
+00000340  10 23 ae 6e b5 12 eb 9c  21 78 db 36 fd bf 7f ee  |.#.n....!x.6....|
+00000350  6f c8 00 2d b6 35 cc 2f  38 73 ae a4 34 cf 0d df  |o..-.5./8s..4...|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 24 49 19 94 44 b4  |..........$I..D.|
-00000010  e7 50 8a 4f 7a 4f 05 28  e3 bc ae fc e5 ed 1c e0  |.P.OzO.(........|
-00000020  34 0e a7 99 99 08 44 fc  95 5a 91 c9 f4 29 4a 17  |4.....D..Z...)J.|
-00000030  03 03 00 21 5f 7b 31 75  5f 5c 84 a9 c6 5b cf e5  |...!_{1u_\...[..|
-00000040  90 11 a9 64 62 5d cf 54  f2 40 4f fa 1d 52 85 d1  |...db].T.@O..R..|
-00000050  52 5a 2d 7a 18 15 03 03  00 16 4c 68 39 b1 4b 18  |RZ-z......Lh9.K.|
-00000060  9e 67 77 5e 89 1d ae f9  17 fd 16 03 76 12 a6 73  |.gw^........v..s|
+00000000  14 03 03 00 01 01 16 03  03 00 24 a7 50 0f 50 b4  |..........$.P.P.|
+00000010  1c c3 4d f3 7a 64 df 65  ac 35 22 13 46 cc ec 36  |..M.zd.e.5".F..6|
+00000020  e6 d2 f3 67 94 6a 18 85  9f 4a 3c 44 a3 58 b0 17  |...g.j...J<D.X..|
+00000030  03 03 00 21 51 0a 41 8c  fd 50 e3 54 8b 6a 1f 83  |...!Q.A..P.T.j..|
+00000040  a5 37 98 e1 5b 1e ec 03  1d c7 0e 28 6d 79 3f 34  |.7..[......(my?4|
+00000050  de 1c 38 6d 7e 15 03 03  00 16 06 fc b1 7d ad 70  |..8m~........}.p|
+00000060  1a de d4 b7 b5 e7 a2 6d  1b 9a b0 31 0c cc 7b 70  |.......m...1..{p|
index 051155028732602177197e8cf43b080f371ec3d8..04a5b117cd6d380deb02183610a66873eef9b7ec 100644 (file)
@@ -1,61 +1,62 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 5d 01 00 00  59 03 03 52 ac 77 f8 5a  |....]...Y..R.w.Z|
-00000010  89 61 73 8e 24 3b 48 6d  30 b4 36 ee 17 10 58 76  |.as.$;Hm0.6...Xv|
-00000020  d0 48 1d 93 eb 78 c9 ad  c0 53 ed 00 00 04 00 05  |.H...x...S......|
-00000030  00 ff 02 01 00 00 2b 00  0d 00 22 00 20 06 01 06  |......+...". ...|
-00000040  02 06 03 05 01 05 02 05  03 04 01 04 02 04 03 03  |................|
-00000050  01 03 02 03 03 02 01 02  02 02 03 01 01 00 0f 00  |................|
-00000060  01 01                                             |..|
+00000000  16 03 01 00 5c 01 00 00  58 03 03 52 cc 57 59 6b  |....\...X..R.WYk|
+00000010  11 07 04 39 77 20 c2 b4  3f cb 0a c9 53 fe 5b 3e  |...9w ..?...S.[>|
+00000020  5f 58 2c 7e 30 69 e1 8e  6c 9d c8 00 00 04 00 05  |_X,~0i..l.......|
+00000030  00 ff 01 00 00 2b 00 0d  00 22 00 20 06 01 06 02  |.....+...". ....|
+00000040  06 03 05 01 05 02 05 03  04 01 04 02 04 03 03 01  |................|
+00000050  03 02 03 03 02 01 02 02  02 03 01 01 00 0f 00 01  |................|
+00000060  01                                                |.|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 2a 02 00 00  26 03 03 00 00 00 00 00  |....*...&.......|
+00000000  16 03 03 00 31 02 00 00  2d 03 03 00 00 00 00 00  |....1...-.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 05 00 16  |................|
-00000030  03 03 02 be 0b 00 02 ba  00 02 b7 00 02 b4 30 82  |..............0.|
-00000040  02 b0 30 82 02 19 a0 03  02 01 02 02 09 00 85 b0  |..0.............|
-00000050  bb a4 8a 7f b8 ca 30 0d  06 09 2a 86 48 86 f7 0d  |......0...*.H...|
-00000060  01 01 05 05 00 30 45 31  0b 30 09 06 03 55 04 06  |.....0E1.0...U..|
-00000070  13 02 41 55 31 13 30 11  06 03 55 04 08 13 0a 53  |..AU1.0...U....S|
-00000080  6f 6d 65 2d 53 74 61 74  65 31 21 30 1f 06 03 55  |ome-State1!0...U|
-00000090  04 0a 13 18 49 6e 74 65  72 6e 65 74 20 57 69 64  |....Internet Wid|
-000000a0  67 69 74 73 20 50 74 79  20 4c 74 64 30 1e 17 0d  |gits Pty Ltd0...|
-000000b0  31 30 30 34 32 34 30 39  30 39 33 38 5a 17 0d 31  |100424090938Z..1|
-000000c0  31 30 34 32 34 30 39 30  39 33 38 5a 30 45 31 0b  |10424090938Z0E1.|
-000000d0  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-000000e0  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-000000f0  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-00000100  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-00000110  4c 74 64 30 81 9f 30 0d  06 09 2a 86 48 86 f7 0d  |Ltd0..0...*.H...|
-00000120  01 01 01 05 00 03 81 8d  00 30 81 89 02 81 81 00  |.........0......|
-00000130  bb 79 d6 f5 17 b5 e5 bf  46 10 d0 dc 69 be e6 2b  |.y......F...i..+|
-00000140  07 43 5a d0 03 2d 8a 7a  43 85 b7 14 52 e7 a5 65  |.CZ..-.zC...R..e|
-00000150  4c 2c 78 b8 23 8c b5 b4  82 e5 de 1f 95 3b 7e 62  |L,x.#........;~b|
-00000160  a5 2c a5 33 d6 fe 12 5c  7a 56 fc f5 06 bf fa 58  |.,.3...\zV.....X|
-00000170  7b 26 3f b5 cd 04 d3 d0  c9 21 96 4a c7 f4 54 9f  |{&?......!.J..T.|
-00000180  5a bf ef 42 71 00 fe 18  99 07 7f 7e 88 7d 7d f1  |Z..Bq......~.}}.|
-00000190  04 39 c4 a2 2e db 51 c9  7c e3 c0 4c 3b 32 66 01  |.9....Q.|..L;2f.|
-000001a0  cf af b1 1d b8 71 9a 1d  db db 89 6b ae da 2d 79  |.....q.....k..-y|
-000001b0  02 03 01 00 01 a3 81 a7  30 81 a4 30 1d 06 03 55  |........0..0...U|
-000001c0  1d 0e 04 16 04 14 b1 ad  e2 85 5a cf cb 28 db 69  |..........Z..(.i|
-000001d0  ce 23 69 de d3 26 8e 18  88 39 30 75 06 03 55 1d  |.#i..&...90u..U.|
-000001e0  23 04 6e 30 6c 80 14 b1  ad e2 85 5a cf cb 28 db  |#.n0l......Z..(.|
-000001f0  69 ce 23 69 de d3 26 8e  18 88 39 a1 49 a4 47 30  |i.#i..&...9.I.G0|
-00000200  45 31 0b 30 09 06 03 55  04 06 13 02 41 55 31 13  |E1.0...U....AU1.|
-00000210  30 11 06 03 55 04 08 13  0a 53 6f 6d 65 2d 53 74  |0...U....Some-St|
-00000220  61 74 65 31 21 30 1f 06  03 55 04 0a 13 18 49 6e  |ate1!0...U....In|
-00000230  74 65 72 6e 65 74 20 57  69 64 67 69 74 73 20 50  |ternet Widgits P|
-00000240  74 79 20 4c 74 64 82 09  00 85 b0 bb a4 8a 7f b8  |ty Ltd..........|
-00000250  ca 30 0c 06 03 55 1d 13  04 05 30 03 01 01 ff 30  |.0...U....0....0|
-00000260  0d 06 09 2a 86 48 86 f7  0d 01 01 05 05 00 03 81  |...*.H..........|
-00000270  81 00 08 6c 45 24 c7 6b  b1 59 ab 0c 52 cc f2 b0  |...lE$.k.Y..R...|
-00000280  14 d7 87 9d 7a 64 75 b5  5a 95 66 e4 c5 2b 8e ae  |....zdu.Z.f..+..|
-00000290  12 66 1f eb 4f 38 b3 6e  60 d3 92 fd f7 41 08 b5  |.f..O8.n`....A..|
-000002a0  25 13 b1 18 7a 24 fb 30  1d ba ed 98 b9 17 ec e7  |%...z$.0........|
-000002b0  d7 31 59 db 95 d3 1d 78  ea 50 56 5c d5 82 5a 2d  |.1Y....x.PV\..Z-|
-000002c0  5a 5f 33 c4 b6 d8 c9 75  90 96 8c 0f 52 98 b5 cd  |Z_3....u....R...|
-000002d0  98 1f 89 20 5f f2 a0 1c  a3 1b 96 94 dd a9 fd 57  |... _..........W|
-000002e0  e9 70 e8 26 6d 71 99 9b  26 6e 38 50 29 6c 90 a7  |.p.&mq..&n8P)l..|
-000002f0  bd d9 16 03 03 00 0f 0d  00 00 0b 02 01 40 00 04  |.............@..|
-00000300  04 01 04 03 00 00 16 03  03 00 04 0e 00 00 00     |...............|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 05 00 00  |................|
+00000030  05 ff 01 00 01 00 16 03  03 02 be 0b 00 02 ba 00  |................|
+00000040  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
+00000050  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
+00000060  09 2a 86 48 86 f7 0d 01  01 05 05 00 30 45 31 0b  |.*.H........0E1.|
+00000070  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
+00000080  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
+00000090  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
+000000a0  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
+000000b0  4c 74 64 30 1e 17 0d 31  30 30 34 32 34 30 39 30  |Ltd0...100424090|
+000000c0  39 33 38 5a 17 0d 31 31  30 34 32 34 30 39 30 39  |938Z..1104240909|
+000000d0  33 38 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |38Z0E1.0...U....|
+000000e0  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
+000000f0  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
+00000100  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
+00000110  74 73 20 50 74 79 20 4c  74 64 30 81 9f 30 0d 06  |ts Pty Ltd0..0..|
+00000120  09 2a 86 48 86 f7 0d 01  01 01 05 00 03 81 8d 00  |.*.H............|
+00000130  30 81 89 02 81 81 00 bb  79 d6 f5 17 b5 e5 bf 46  |0.......y......F|
+00000140  10 d0 dc 69 be e6 2b 07  43 5a d0 03 2d 8a 7a 43  |...i..+.CZ..-.zC|
+00000150  85 b7 14 52 e7 a5 65 4c  2c 78 b8 23 8c b5 b4 82  |...R..eL,x.#....|
+00000160  e5 de 1f 95 3b 7e 62 a5  2c a5 33 d6 fe 12 5c 7a  |....;~b.,.3...\z|
+00000170  56 fc f5 06 bf fa 58 7b  26 3f b5 cd 04 d3 d0 c9  |V.....X{&?......|
+00000180  21 96 4a c7 f4 54 9f 5a  bf ef 42 71 00 fe 18 99  |!.J..T.Z..Bq....|
+00000190  07 7f 7e 88 7d 7d f1 04  39 c4 a2 2e db 51 c9 7c  |..~.}}..9....Q.||
+000001a0  e3 c0 4c 3b 32 66 01 cf  af b1 1d b8 71 9a 1d db  |..L;2f......q...|
+000001b0  db 89 6b ae da 2d 79 02  03 01 00 01 a3 81 a7 30  |..k..-y........0|
+000001c0  81 a4 30 1d 06 03 55 1d  0e 04 16 04 14 b1 ad e2  |..0...U.........|
+000001d0  85 5a cf cb 28 db 69 ce  23 69 de d3 26 8e 18 88  |.Z..(.i.#i..&...|
+000001e0  39 30 75 06 03 55 1d 23  04 6e 30 6c 80 14 b1 ad  |90u..U.#.n0l....|
+000001f0  e2 85 5a cf cb 28 db 69  ce 23 69 de d3 26 8e 18  |..Z..(.i.#i..&..|
+00000200  88 39 a1 49 a4 47 30 45  31 0b 30 09 06 03 55 04  |.9.I.G0E1.0...U.|
+00000210  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
+00000220  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
+00000230  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
+00000240  64 67 69 74 73 20 50 74  79 20 4c 74 64 82 09 00  |dgits Pty Ltd...|
+00000250  85 b0 bb a4 8a 7f b8 ca  30 0c 06 03 55 1d 13 04  |........0...U...|
+00000260  05 30 03 01 01 ff 30 0d  06 09 2a 86 48 86 f7 0d  |.0....0...*.H...|
+00000270  01 01 05 05 00 03 81 81  00 08 6c 45 24 c7 6b b1  |..........lE$.k.|
+00000280  59 ab 0c 52 cc f2 b0 14  d7 87 9d 7a 64 75 b5 5a  |Y..R.......zdu.Z|
+00000290  95 66 e4 c5 2b 8e ae 12  66 1f eb 4f 38 b3 6e 60  |.f..+...f..O8.n`|
+000002a0  d3 92 fd f7 41 08 b5 25  13 b1 18 7a 24 fb 30 1d  |....A..%...z$.0.|
+000002b0  ba ed 98 b9 17 ec e7 d7  31 59 db 95 d3 1d 78 ea  |........1Y....x.|
+000002c0  50 56 5c d5 82 5a 2d 5a  5f 33 c4 b6 d8 c9 75 90  |PV\..Z-Z_3....u.|
+000002d0  96 8c 0f 52 98 b5 cd 98  1f 89 20 5f f2 a0 1c a3  |...R...... _....|
+000002e0  1b 96 94 dd a9 fd 57 e9  70 e8 26 6d 71 99 9b 26  |......W.p.&mq..&|
+000002f0  6e 38 50 29 6c 90 a7 bd  d9 16 03 03 00 0f 0d 00  |n8P)l...........|
+00000300  00 0b 02 01 40 00 04 04  01 04 03 00 00 16 03 03  |....@...........|
+00000310  00 04 0e 00 00 00                                 |......|
 >>> Flow 3 (client to server)
 00000000  16 03 03 01 fb 0b 00 01  f7 00 01 f4 00 01 f1 30  |...............0|
 00000010  82 01 ed 30 82 01 58 a0  03 02 01 02 02 01 00 30  |...0..X........0|
 000001d0  8b ec ab 67 be c8 64 b0  11 50 46 58 17 6b 99 1c  |...g..d..PFX.k..|
 000001e0  d3 1d fc 06 f1 0e e5 96  a8 0c f9 78 20 b7 44 18  |...........x .D.|
 000001f0  51 8d 10 7e 4f 94 67 df  a3 4e 70 73 8e 90 91 85  |Q..~O.g..Nps....|
-00000200  16 03 03 00 86 10 00 00  82 00 80 05 f0 5b e7 ee  |.............[..|
-00000210  1a a0 9d 54 85 3c c9 1d  e0 fd d7 21 ed d2 34 0a  |...T.<.....!..4.|
-00000220  91 da db 03 b4 c8 b5 50  d9 5f 8e 31 9e 56 ec 62  |.......P._.1.V.b|
-00000230  ff df 79 37 6e 22 c1 11  00 a2 e3 ed 63 29 9e 26  |..y7n"......c).&|
-00000240  4c d1 7a 6a d4 b6 06 cc  06 da 72 a8 4b 08 0b fc  |L.zj......r.K...|
-00000250  f4 23 e8 43 9b 9f 55 cc  dc 4a e3 45 be b5 be d7  |.#.C..U..J.E....|
-00000260  e5 34 e5 86 ca 45 b4 15  9d 8c bc 0c 66 f2 e5 24  |.4...E......f..$|
-00000270  2c af d8 1a c0 9e dc f7  cc 30 43 d1 1e 8e 4c c0  |,........0C...L.|
-00000280  e8 7b 8e a5 21 37 35 ae  b9 c4 aa 16 03 03 00 88  |.{..!75.........|
-00000290  0f 00 00 84 04 01 00 80  2f db 55 56 9a 38 36 98  |......../.UV.86.|
-000002a0  b3 46 cf 9f 91 37 92 98  97 d6 7e 7b 5e b8 cc ef  |.F...7....~{^...|
-000002b0  b9 f8 69 91 e4 f5 4a bf  2c 6d f5 b2 d0 61 b3 79  |..i...J.,m...a.y|
-000002c0  f0 6a 22 3c 32 bf 72 c3  7d 4c 30 68 dd d6 cd 53  |.j"<2.r.}L0h...S|
-000002d0  c1 88 84 11 90 7f 75 e2  5b ca 80 a9 c9 8e 6e ef  |......u.[.....n.|
-000002e0  87 8b 80 06 c5 ce 95 a5  b5 20 d6 75 04 66 87 29  |......... .u.f.)|
-000002f0  06 1d 59 0b b5 d2 b1 07  5e 09 c3 1d 9e 47 0e 07  |..Y.....^....G..|
-00000300  d9 83 dd 56 e5 93 b6 1e  e7 61 5c f8 2b 8a e7 83  |...V.....a\.+...|
-00000310  52 15 2f bd 9c 91 3b a3  14 03 03 00 01 01 16 03  |R./...;.........|
-00000320  03 00 24 64 d6 db a5 d4  0c 9f 03 be c9 f1 20 5c  |..$d.......... \|
-00000330  5f 5a 41 1e 5e c9 c6 04  e7 f5 7f 68 db 38 a6 8c  |_ZA.^......h.8..|
-00000340  cb 5e b9 99 5e b3 69                              |.^..^.i|
+00000200  16 03 03 00 86 10 00 00  82 00 80 44 89 7d aa 26  |...........D.}.&|
+00000210  30 ce 6b db 25 70 b0 1e  16 fa 5b 3a dd 4a 4b bd  |0.k.%p....[:.JK.|
+00000220  ec ee 50 9d 21 ba 52 b5  51 4f a8 65 d8 2e 41 e2  |..P.!.R.QO.e..A.|
+00000230  e1 dc f3 1a df 58 4f 87  7a d3 e1 e1 1c 13 b2 0b  |.....XO.z.......|
+00000240  b7 43 b7 92 f2 df 19 bb  79 71 e0 71 44 ab 19 2f  |.C......yq.qD../|
+00000250  37 11 ac 62 50 b6 f1 53  fe aa b4 bc 29 8e 0b 4c  |7..bP..S....)..L|
+00000260  0b 12 8d d5 84 a9 fa a9  ea 16 aa c3 0d da 32 c8  |..............2.|
+00000270  e0 4c 9f 99 f8 69 cd a8  c3 b1 76 42 67 f3 ff 15  |.L...i....vBg...|
+00000280  52 95 43 66 da 49 43 25  9d e5 eb 16 03 03 00 88  |R.Cf.IC%........|
+00000290  0f 00 00 84 04 01 00 80  01 d5 0e 1c 75 97 89 52  |............u..R|
+000002a0  1a f0 cc ef 93 6e 71 b2  b1 38 8c 50 11 f7 a3 02  |.....nq..8.P....|
+000002b0  71 c4 d5 6f 8d 01 83 06  2e ea 5a 10 8a 0d d0 fc  |q..o......Z.....|
+000002c0  b6 a2 63 af 4f 99 b5 eb  ab fd 01 c2 fb 26 fc fd  |..c.O........&..|
+000002d0  ad 2c b3 63 b3 87 a6 f5  14 ea 7d e7 fe a8 e7 7e  |.,.c......}....~|
+000002e0  20 ab b9 f6 c3 58 bd c0  f3 96 eb 83 dc 42 6c 0d  | ....X.......Bl.|
+000002f0  5e e8 09 55 c7 b8 24 05  dd e1 7c af 9f 2c 22 6c  |^..U..$...|..,"l|
+00000300  fa b8 94 13 3b f1 09 e1  38 59 fc a1 8c cb aa ca  |....;...8Y......|
+00000310  f8 e0 2a 9c 36 f9 c3 2b  14 03 03 00 01 01 16 03  |..*.6..+........|
+00000320  03 00 24 d0 12 7c cc d2  3e 37 1f f4 7d b4 c0 fc  |..$..|..>7..}...|
+00000330  19 f6 c8 ea 62 12 e0 0d  af 62 d4 69 f7 96 5a c0  |....b....b.i..Z.|
+00000340  97 d3 bb b0 a3 f7 3f                              |......?|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 24 5a 42 72 e0 fc  |..........$ZBr..|
-00000010  c7 ca 9c 74 da 0a 85 df  d5 32 f4 24 aa e1 45 39  |...t.....2.$..E9|
-00000020  5c 86 29 99 85 c8 1b cb  bc ba 1d 27 68 1a a7 17  |\.)........'h...|
-00000030  03 03 00 21 95 56 9f 44  51 a4 51 67 3f ee 8b e4  |...!.V.DQ.Qg?...|
-00000040  19 03 e4 5f 15 aa b7 ce  7f db 15 a0 15 65 e7 cc  |..._.........e..|
-00000050  c5 25 72 ae 0c 15 03 03  00 16 e5 97 49 3d f1 5e  |.%r.........I=.^|
-00000060  53 4e d9 40 cf 81 de 3b  5f 5e b2 2a 78 51 ab 66  |SN.@...;_^.*xQ.f|
+00000000  14 03 03 00 01 01 16 03  03 00 24 cd 20 85 1e 74  |..........$. ..t|
+00000010  18 b2 71 48 d5 10 61 c6  b0 18 26 83 c2 7f f1 b1  |..qH..a...&.....|
+00000020  2f b5 35 d0 47 a8 99 9a  9a a5 62 64 fb f9 29 17  |/.5.G.....bd..).|
+00000030  03 03 00 21 22 7b ed 61  e3 9b 6d 98 b9 23 98 e3  |...!"{.a..m..#..|
+00000040  55 11 b8 0f 7e 2b e1 c1  d4 f1 83 79 c3 f8 03 f0  |U...~+.....y....|
+00000050  02 5c 61 24 d7 15 03 03  00 16 14 2b a3 5a 56 f0  |.\a$.......+.ZV.|
+00000060  92 da d0 e6 32 91 d8 30  7a b4 d0 a2 93 f5 01 ea  |....2..0z.......|
index 1543e83c7865bcba41e9baede7fdb031ab9a1ecd..562fe1aaa0a463452e744e8cb52e7ab4f143cdfc 100644 (file)
@@ -1,80 +1,81 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 5d 01 00 00  59 03 03 52 ac 77 f8 c7  |....]...Y..R.w..|
-00000010  e6 0f 80 12 13 8e 2d a8  61 1f 31 ba 94 f9 0e f8  |......-.a.1.....|
-00000020  43 a5 2b c8 95 c5 f7 47  b4 f9 b5 00 00 04 00 05  |C.+....G........|
-00000030  00 ff 02 01 00 00 2b 00  0d 00 22 00 20 06 01 06  |......+...". ...|
-00000040  02 06 03 05 01 05 02 05  03 04 01 04 02 04 03 03  |................|
-00000050  01 03 02 03 03 02 01 02  02 02 03 01 01 00 0f 00  |................|
-00000060  01 01                                             |..|
+00000000  16 03 01 00 5c 01 00 00  58 03 03 52 cc 57 59 1b  |....\...X..R.WY.|
+00000010  08 fe f7 8a bf 07 84 2b  60 a6 13 2d 15 13 f8 b6  |.......+`..-....|
+00000020  d4 b6 3b f2 7a 98 ff 32  a0 68 7c 00 00 04 00 05  |..;.z..2.h|.....|
+00000030  00 ff 01 00 00 2b 00 0d  00 22 00 20 06 01 06 02  |.....+...". ....|
+00000040  06 03 05 01 05 02 05 03  04 01 04 02 04 03 03 01  |................|
+00000050  03 02 03 03 02 01 02 02  02 03 01 01 00 0f 00 01  |................|
+00000060  01                                                |.|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 2a 02 00 00  26 03 03 00 00 00 00 00  |....*...&.......|
+00000000  16 03 03 00 31 02 00 00  2d 03 03 00 00 00 00 00  |....1...-.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 05 00 16  |................|
-00000030  03 03 02 be 0b 00 02 ba  00 02 b7 00 02 b4 30 82  |..............0.|
-00000040  02 b0 30 82 02 19 a0 03  02 01 02 02 09 00 85 b0  |..0.............|
-00000050  bb a4 8a 7f b8 ca 30 0d  06 09 2a 86 48 86 f7 0d  |......0...*.H...|
-00000060  01 01 05 05 00 30 45 31  0b 30 09 06 03 55 04 06  |.....0E1.0...U..|
-00000070  13 02 41 55 31 13 30 11  06 03 55 04 08 13 0a 53  |..AU1.0...U....S|
-00000080  6f 6d 65 2d 53 74 61 74  65 31 21 30 1f 06 03 55  |ome-State1!0...U|
-00000090  04 0a 13 18 49 6e 74 65  72 6e 65 74 20 57 69 64  |....Internet Wid|
-000000a0  67 69 74 73 20 50 74 79  20 4c 74 64 30 1e 17 0d  |gits Pty Ltd0...|
-000000b0  31 30 30 34 32 34 30 39  30 39 33 38 5a 17 0d 31  |100424090938Z..1|
-000000c0  31 30 34 32 34 30 39 30  39 33 38 5a 30 45 31 0b  |10424090938Z0E1.|
-000000d0  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-000000e0  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-000000f0  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-00000100  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-00000110  4c 74 64 30 81 9f 30 0d  06 09 2a 86 48 86 f7 0d  |Ltd0..0...*.H...|
-00000120  01 01 01 05 00 03 81 8d  00 30 81 89 02 81 81 00  |.........0......|
-00000130  bb 79 d6 f5 17 b5 e5 bf  46 10 d0 dc 69 be e6 2b  |.y......F...i..+|
-00000140  07 43 5a d0 03 2d 8a 7a  43 85 b7 14 52 e7 a5 65  |.CZ..-.zC...R..e|
-00000150  4c 2c 78 b8 23 8c b5 b4  82 e5 de 1f 95 3b 7e 62  |L,x.#........;~b|
-00000160  a5 2c a5 33 d6 fe 12 5c  7a 56 fc f5 06 bf fa 58  |.,.3...\zV.....X|
-00000170  7b 26 3f b5 cd 04 d3 d0  c9 21 96 4a c7 f4 54 9f  |{&?......!.J..T.|
-00000180  5a bf ef 42 71 00 fe 18  99 07 7f 7e 88 7d 7d f1  |Z..Bq......~.}}.|
-00000190  04 39 c4 a2 2e db 51 c9  7c e3 c0 4c 3b 32 66 01  |.9....Q.|..L;2f.|
-000001a0  cf af b1 1d b8 71 9a 1d  db db 89 6b ae da 2d 79  |.....q.....k..-y|
-000001b0  02 03 01 00 01 a3 81 a7  30 81 a4 30 1d 06 03 55  |........0..0...U|
-000001c0  1d 0e 04 16 04 14 b1 ad  e2 85 5a cf cb 28 db 69  |..........Z..(.i|
-000001d0  ce 23 69 de d3 26 8e 18  88 39 30 75 06 03 55 1d  |.#i..&...90u..U.|
-000001e0  23 04 6e 30 6c 80 14 b1  ad e2 85 5a cf cb 28 db  |#.n0l......Z..(.|
-000001f0  69 ce 23 69 de d3 26 8e  18 88 39 a1 49 a4 47 30  |i.#i..&...9.I.G0|
-00000200  45 31 0b 30 09 06 03 55  04 06 13 02 41 55 31 13  |E1.0...U....AU1.|
-00000210  30 11 06 03 55 04 08 13  0a 53 6f 6d 65 2d 53 74  |0...U....Some-St|
-00000220  61 74 65 31 21 30 1f 06  03 55 04 0a 13 18 49 6e  |ate1!0...U....In|
-00000230  74 65 72 6e 65 74 20 57  69 64 67 69 74 73 20 50  |ternet Widgits P|
-00000240  74 79 20 4c 74 64 82 09  00 85 b0 bb a4 8a 7f b8  |ty Ltd..........|
-00000250  ca 30 0c 06 03 55 1d 13  04 05 30 03 01 01 ff 30  |.0...U....0....0|
-00000260  0d 06 09 2a 86 48 86 f7  0d 01 01 05 05 00 03 81  |...*.H..........|
-00000270  81 00 08 6c 45 24 c7 6b  b1 59 ab 0c 52 cc f2 b0  |...lE$.k.Y..R...|
-00000280  14 d7 87 9d 7a 64 75 b5  5a 95 66 e4 c5 2b 8e ae  |....zdu.Z.f..+..|
-00000290  12 66 1f eb 4f 38 b3 6e  60 d3 92 fd f7 41 08 b5  |.f..O8.n`....A..|
-000002a0  25 13 b1 18 7a 24 fb 30  1d ba ed 98 b9 17 ec e7  |%...z$.0........|
-000002b0  d7 31 59 db 95 d3 1d 78  ea 50 56 5c d5 82 5a 2d  |.1Y....x.PV\..Z-|
-000002c0  5a 5f 33 c4 b6 d8 c9 75  90 96 8c 0f 52 98 b5 cd  |Z_3....u....R...|
-000002d0  98 1f 89 20 5f f2 a0 1c  a3 1b 96 94 dd a9 fd 57  |... _..........W|
-000002e0  e9 70 e8 26 6d 71 99 9b  26 6e 38 50 29 6c 90 a7  |.p.&mq..&n8P)l..|
-000002f0  bd d9 16 03 03 00 0f 0d  00 00 0b 02 01 40 00 04  |.............@..|
-00000300  04 01 04 03 00 00 16 03  03 00 04 0e 00 00 00     |...............|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 05 00 00  |................|
+00000030  05 ff 01 00 01 00 16 03  03 02 be 0b 00 02 ba 00  |................|
+00000040  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
+00000050  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
+00000060  09 2a 86 48 86 f7 0d 01  01 05 05 00 30 45 31 0b  |.*.H........0E1.|
+00000070  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
+00000080  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
+00000090  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
+000000a0  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
+000000b0  4c 74 64 30 1e 17 0d 31  30 30 34 32 34 30 39 30  |Ltd0...100424090|
+000000c0  39 33 38 5a 17 0d 31 31  30 34 32 34 30 39 30 39  |938Z..1104240909|
+000000d0  33 38 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |38Z0E1.0...U....|
+000000e0  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
+000000f0  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
+00000100  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
+00000110  74 73 20 50 74 79 20 4c  74 64 30 81 9f 30 0d 06  |ts Pty Ltd0..0..|
+00000120  09 2a 86 48 86 f7 0d 01  01 01 05 00 03 81 8d 00  |.*.H............|
+00000130  30 81 89 02 81 81 00 bb  79 d6 f5 17 b5 e5 bf 46  |0.......y......F|
+00000140  10 d0 dc 69 be e6 2b 07  43 5a d0 03 2d 8a 7a 43  |...i..+.CZ..-.zC|
+00000150  85 b7 14 52 e7 a5 65 4c  2c 78 b8 23 8c b5 b4 82  |...R..eL,x.#....|
+00000160  e5 de 1f 95 3b 7e 62 a5  2c a5 33 d6 fe 12 5c 7a  |....;~b.,.3...\z|
+00000170  56 fc f5 06 bf fa 58 7b  26 3f b5 cd 04 d3 d0 c9  |V.....X{&?......|
+00000180  21 96 4a c7 f4 54 9f 5a  bf ef 42 71 00 fe 18 99  |!.J..T.Z..Bq....|
+00000190  07 7f 7e 88 7d 7d f1 04  39 c4 a2 2e db 51 c9 7c  |..~.}}..9....Q.||
+000001a0  e3 c0 4c 3b 32 66 01 cf  af b1 1d b8 71 9a 1d db  |..L;2f......q...|
+000001b0  db 89 6b ae da 2d 79 02  03 01 00 01 a3 81 a7 30  |..k..-y........0|
+000001c0  81 a4 30 1d 06 03 55 1d  0e 04 16 04 14 b1 ad e2  |..0...U.........|
+000001d0  85 5a cf cb 28 db 69 ce  23 69 de d3 26 8e 18 88  |.Z..(.i.#i..&...|
+000001e0  39 30 75 06 03 55 1d 23  04 6e 30 6c 80 14 b1 ad  |90u..U.#.n0l....|
+000001f0  e2 85 5a cf cb 28 db 69  ce 23 69 de d3 26 8e 18  |..Z..(.i.#i..&..|
+00000200  88 39 a1 49 a4 47 30 45  31 0b 30 09 06 03 55 04  |.9.I.G0E1.0...U.|
+00000210  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
+00000220  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
+00000230  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
+00000240  64 67 69 74 73 20 50 74  79 20 4c 74 64 82 09 00  |dgits Pty Ltd...|
+00000250  85 b0 bb a4 8a 7f b8 ca  30 0c 06 03 55 1d 13 04  |........0...U...|
+00000260  05 30 03 01 01 ff 30 0d  06 09 2a 86 48 86 f7 0d  |.0....0...*.H...|
+00000270  01 01 05 05 00 03 81 81  00 08 6c 45 24 c7 6b b1  |..........lE$.k.|
+00000280  59 ab 0c 52 cc f2 b0 14  d7 87 9d 7a 64 75 b5 5a  |Y..R.......zdu.Z|
+00000290  95 66 e4 c5 2b 8e ae 12  66 1f eb 4f 38 b3 6e 60  |.f..+...f..O8.n`|
+000002a0  d3 92 fd f7 41 08 b5 25  13 b1 18 7a 24 fb 30 1d  |....A..%...z$.0.|
+000002b0  ba ed 98 b9 17 ec e7 d7  31 59 db 95 d3 1d 78 ea  |........1Y....x.|
+000002c0  50 56 5c d5 82 5a 2d 5a  5f 33 c4 b6 d8 c9 75 90  |PV\..Z-Z_3....u.|
+000002d0  96 8c 0f 52 98 b5 cd 98  1f 89 20 5f f2 a0 1c a3  |...R...... _....|
+000002e0  1b 96 94 dd a9 fd 57 e9  70 e8 26 6d 71 99 9b 26  |......W.p.&mq..&|
+000002f0  6e 38 50 29 6c 90 a7 bd  d9 16 03 03 00 0f 0d 00  |n8P)l...........|
+00000300  00 0b 02 01 40 00 04 04  01 04 03 00 00 16 03 03  |....@...........|
+00000310  00 04 0e 00 00 00                                 |......|
 >>> Flow 3 (client to server)
 00000000  16 03 03 00 07 0b 00 00  03 00 00 00 16 03 03 00  |................|
-00000010  86 10 00 00 82 00 80 8c  f3 9d ed 36 34 11 9b 89  |...........64...|
-00000020  22 b2 0e 20 0c be c6 91  f5 2e 7f 35 e9 14 b1 b9  |".. .......5....|
-00000030  c6 02 cf da d2 3a 81 a4  18 1b 32 0c 21 fe cd a5  |.....:....2.!...|
-00000040  c2 74 0c db 29 9c 73 e4  de 7c c4 8d f6 2d b0 0e  |.t..).s..|...-..|
-00000050  f5 b4 48 b5 24 94 be 3f  c2 da 2a fe 82 b9 66 1f  |..H.$..?..*...f.|
-00000060  45 12 e9 50 a9 e4 09 2d  6e 67 e2 63 21 a8 e7 23  |E..P...-ng.c!..#|
-00000070  2e ec e3 e3 39 dc f9 54  c4 5a 5c 3e e8 a1 fc 6a  |....9..T.Z\>...j|
-00000080  98 38 23 85 a2 a4 f4 26  4c 8e 00 fa 99 f9 53 3f  |.8#....&L.....S?|
-00000090  ce f7 34 4e a3 1b 2e 14  03 03 00 01 01 16 03 03  |..4N............|
-000000a0  00 24 e2 c8 25 81 12 b8  b1 28 f9 a3 8c 94 9e 7c  |.$..%....(.....||
-000000b0  63 78 f0 04 74 53 31 50  40 29 2f 6c 0a 09 05 6a  |cx..tS1P@)/l...j|
-000000c0  32 5d 92 1a 0c 2e                                 |2]....|
+00000010  86 10 00 00 82 00 80 6b  51 48 d3 18 7d 30 e0 0c  |.......kQH..}0..|
+00000020  20 8d f3 e4 39 47 30 0e  a5 85 79 f9 8b 11 50 9e  | ...9G0...y...P.|
+00000030  81 71 5c 26 c6 bb cb aa  d5 00 d1 89 79 b1 77 2d  |.q\&........y.w-|
+00000040  eb 9b 86 7c 52 c6 f7 b7  10 b0 b6 94 22 51 b8 12  |...|R......."Q..|
+00000050  3c 09 35 8e 1b cc f4 3b  b7 b8 78 ab 89 59 41 49  |<.5....;..x..YAI|
+00000060  21 31 eb f0 f8 94 63 3d  e6 96 8f b6 63 95 05 dd  |!1....c=....c...|
+00000070  46 b3 00 8a d6 83 75 99  1b 5a 48 0a 23 b5 10 c1  |F.....u..ZH.#...|
+00000080  95 b5 bc 15 72 b5 f5 a0  62 e2 1d c0 ff d2 87 a5  |....r...b.......|
+00000090  97 5c 33 49 a7 26 35 14  03 03 00 01 01 16 03 03  |.\3I.&5.........|
+000000a0  00 24 61 38 1f 9d fb d9  65 2e 02 07 fb be f9 85  |.$a8....e.......|
+000000b0  8d 15 34 c0 d1 0e 4e 10  3c 25 60 2f ac 04 21 66  |..4...N.<%`/..!f|
+000000c0  04 9d 9a 60 31 72                                 |...`1r|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 24 fb 18 af ff 1b  |..........$.....|
-00000010  72 08 c5 e1 1f c6 8b 43  18 0b 54 65 bd 6e d8 f4  |r......C..Te.n..|
-00000020  7e 3e e4 b0 bb 73 39 bf  24 ab d4 cd 4a 88 b2 17  |~>...s9.$...J...|
-00000030  03 03 00 21 ee 69 69 7c  70 70 d7 63 b7 cf 3c 50  |...!.ii|pp.c..<P|
-00000040  30 96 0a f8 1b ed c8 3a  c7 a4 8e d5 35 5d e1 8d  |0......:....5]..|
-00000050  bd 26 6e 1e 33 15 03 03  00 16 bc 99 f6 0b 44 7e  |.&n.3.........D~|
-00000060  6a 5b 65 51 8d 2d b9 e0  bf 47 fa 46 f7 0a f0 9f  |j[eQ.-...G.F....|
+00000000  14 03 03 00 01 01 16 03  03 00 24 fe 0e 3e 84 af  |..........$..>..|
+00000010  e5 6b 10 ed 41 9c 2b e0  ba e0 2b 53 61 36 1b 40  |.k..A.+...+Sa6.@|
+00000020  35 de 3a c7 c3 5c df 74  67 f7 05 74 84 f5 e1 17  |5.:..\.tg..t....|
+00000030  03 03 00 21 d3 8d 81 85  b7 1f 30 bd 89 33 f9 81  |...!......0..3..|
+00000040  89 f7 af d1 be b0 c1 46  e3 df 32 f6 dc 2f 4d 82  |.......F..2../M.|
+00000050  0a 84 9f 5b 03 15 03 03  00 16 13 af 37 91 82 67  |...[........7..g|
+00000060  b0 7c 5e 0e ec 8e cc 31  a0 ea a5 72 a4 2b 0b 73  |.|^....1...r.+.s|
index 1ba6bc8388a963e6dcbb115e2c77e668d316c02c..fa6cb080c90544c8a8035ff9275851926b3b40bc 100644 (file)
@@ -1,97 +1,98 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 9d 01 00 00  99 03 03 52 ac 77 f8 5b  |...........R.w.[|
-00000010  57 5f 06 3b 30 36 42 66  99 e9 c9 8c 57 1c cf 14  |W_.;06Bf....W...|
-00000020  c9 a8 20 ee da a6 55 d4  d9 ff 1c 00 00 04 c0 0a  |.. ...U.........|
-00000030  00 ff 02 01 00 00 6b 00  0b 00 04 03 00 01 02 00  |......k.........|
-00000040  0a 00 34 00 32 00 0e 00  0d 00 19 00 0b 00 0c 00  |..4.2...........|
-00000050  18 00 09 00 0a 00 16 00  17 00 08 00 06 00 07 00  |................|
-00000060  14 00 15 00 04 00 05 00  12 00 13 00 01 00 02 00  |................|
-00000070  03 00 0f 00 10 00 11 00  0d 00 22 00 20 06 01 06  |..........". ...|
-00000080  02 06 03 05 01 05 02 05  03 04 01 04 02 04 03 03  |................|
-00000090  01 03 02 03 03 02 01 02  02 02 03 01 01 00 0f 00  |................|
-000000a0  01 01                                             |..|
+00000000  16 03 01 00 9c 01 00 00  98 03 03 52 cc 57 59 54  |...........R.WYT|
+00000010  0b ba f3 ec 2c 33 3e 3e  ac b8 c1 d5 d5 ff e3 d3  |....,3>>........|
+00000020  63 d0 29 16 aa 5d 96 37  89 90 c4 00 00 04 c0 0a  |c.)..].7........|
+00000030  00 ff 01 00 00 6b 00 0b  00 04 03 00 01 02 00 0a  |.....k..........|
+00000040  00 34 00 32 00 0e 00 0d  00 19 00 0b 00 0c 00 18  |.4.2............|
+00000050  00 09 00 0a 00 16 00 17  00 08 00 06 00 07 00 14  |................|
+00000060  00 15 00 04 00 05 00 12  00 13 00 01 00 02 00 03  |................|
+00000070  00 0f 00 10 00 11 00 0d  00 22 00 20 06 01 06 02  |.........". ....|
+00000080  06 03 05 01 05 02 05 03  04 01 04 02 04 03 03 01  |................|
+00000090  03 02 03 03 02 01 02 02  02 03 01 01 00 0f 00 01  |................|
+000000a0  01                                                |.|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 2a 02 00 00  26 03 03 00 00 00 00 00  |....*...&.......|
+00000000  16 03 03 00 31 02 00 00  2d 03 03 00 00 00 00 00  |....1...-.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 c0 0a 00 16  |................|
-00000030  03 03 02 0e 0b 00 02 0a  00 02 07 00 02 04 30 82  |..............0.|
-00000040  02 00 30 82 01 62 02 09  00 b8 bf 2d 47 a0 d2 eb  |..0..b.....-G...|
-00000050  f4 30 09 06 07 2a 86 48  ce 3d 04 01 30 45 31 0b  |.0...*.H.=..0E1.|
-00000060  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-00000070  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-00000080  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-00000090  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-000000a0  4c 74 64 30 1e 17 0d 31  32 31 31 32 32 31 35 30  |Ltd0...121122150|
-000000b0  36 33 32 5a 17 0d 32 32  31 31 32 30 31 35 30 36  |632Z..2211201506|
-000000c0  33 32 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |32Z0E1.0...U....|
-000000d0  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
-000000e0  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
-000000f0  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
-00000100  74 73 20 50 74 79 20 4c  74 64 30 81 9b 30 10 06  |ts Pty Ltd0..0..|
-00000110  07 2a 86 48 ce 3d 02 01  06 05 2b 81 04 00 23 03  |.*.H.=....+...#.|
-00000120  81 86 00 04 00 c4 a1 ed  be 98 f9 0b 48 73 36 7e  |............Hs6~|
-00000130  c3 16 56 11 22 f2 3d 53  c3 3b 4d 21 3d cd 6b 75  |..V.".=S.;M!=.ku|
-00000140  e6 f6 b0 dc 9a df 26 c1  bc b2 87 f0 72 32 7c b3  |......&.....r2|.|
-00000150  64 2f 1c 90 bc ea 68 23  10 7e fe e3 25 c0 48 3a  |d/....h#.~..%.H:|
-00000160  69 e0 28 6d d3 37 00 ef  04 62 dd 0d a0 9c 70 62  |i.(m.7...b....pb|
-00000170  83 d8 81 d3 64 31 aa 9e  97 31 bd 96 b0 68 c0 9b  |....d1...1...h..|
-00000180  23 de 76 64 3f 1a 5c 7f  e9 12 0e 58 58 b6 5f 70  |#.vd?.\....XX._p|
-00000190  dd 9b d8 ea d5 d7 f5 d5  cc b9 b6 9f 30 66 5b 66  |............0f[f|
-000001a0  9a 20 e2 27 e5 bf fe 3b  30 09 06 07 2a 86 48 ce  |. .'...;0...*.H.|
-000001b0  3d 04 01 03 81 8c 00 30  81 88 02 42 01 88 a2 4f  |=......0...B...O|
-000001c0  eb e2 45 c5 48 7d 1b ac  f5 ed 98 9d ae 47 70 c0  |..E.H}.......Gp.|
-000001d0  5e 1b b6 2f bd f1 b6 4d  b7 61 40 d3 11 a2 ce ee  |^../...M.a@.....|
-000001e0  0b 7e 92 7e ff 76 9d c3  3b 7e a5 3f ce fa 10 e2  |.~.~.v..;~.?....|
-000001f0  59 ec 47 2d 7c ac da 4e  97 0e 15 a0 6f d0 02 42  |Y.G-|..N....o..B|
-00000200  01 4d fc be 67 13 9c 2d  05 0e bd 3f a3 8c 25 c1  |.M..g..-...?..%.|
-00000210  33 13 83 0d 94 06 bb d4  37 7a f6 ec 7a c9 86 2e  |3.......7z..z...|
-00000220  dd d7 11 69 7f 85 7c 56  de fb 31 78 2b e4 c7 78  |...i..|V..1x+..x|
-00000230  0d ae cb be 9e 4e 36 24  31 7b 6a 0f 39 95 12 07  |.....N6$1{j.9...|
-00000240  8f 2a 16 03 03 01 1c 0c  00 01 18 03 00 19 85 04  |.*..............|
-00000250  01 39 dc ee 44 17 5e db  d7 27 af b6 56 d9 b4 43  |.9..D.^..'..V..C|
-00000260  5a 99 cf aa 31 37 0c 6f  3a a0 f8 53 c4 74 d1 91  |Z...17.o:..S.t..|
-00000270  0a 46 f5 38 3b 5c 09 d8  97 dc 4b aa 70 26 48 f2  |.F.8;\....K.p&H.|
-00000280  d6 0b 31 c9 f8 d4 98 43  e1 6c d5 c7 b2 8e 0b 01  |..1....C.l......|
-00000290  e6 b6 00 28 80 7b fc 96  8f 0d a2 4f b0 79 af dc  |...(.{.....O.y..|
-000002a0  61 28 63 33 78 f6 31 39  fd 8a f4 15 18 11 fe db  |a(c3x.19........|
-000002b0  d5 07 da 2c ed 49 a0 23  bf d0 3a 38 1d 54 ae 1c  |...,.I.#..:8.T..|
-000002c0  7b ea 29 ee d0 38 c1 76  a7 7f 2a f4 ce 1e ac cc  |{.)..8.v..*.....|
-000002d0  94 79 90 33 04 03 00 8b  30 81 88 02 42 00 c6 85  |.y.3....0...B...|
-000002e0  8e 06 b7 04 04 e9 cd 9e  3e cb 66 23 95 b4 42 9c  |........>.f#..B.|
-000002f0  64 81 39 05 3f b5 21 f8  28 af 60 6b 4d 3d ba a1  |d.9.?.!.(.`kM=..|
-00000300  4b 5e 77 ef e7 59 28 fe  1d c1 27 a2 ff a8 de 33  |K^w..Y(...'....3|
-00000310  48 b3 c1 85 6a 42 9b f9  7e 7e 31 c2 e5 bd 66 02  |H...jB..~~1...f.|
-00000320  42 00 ad 7d 06 35 ab ec  8d ac d4 ba 1b 49 5e 05  |B..}.5.......I^.|
-00000330  5f f0 97 93 82 b8 2b 8d  91 98 63 8e b4 14 62 db  |_.....+...c...b.|
-00000340  1e c9 2c 13 30 dc 4e 5e  b7 d5 65 00 16 6c 30 04  |..,.0.N^..e..l0.|
-00000350  cb 66 02 97 ea 7f 7a 16  90 97 16 51 4e de 88 c8  |.f....z....QN...|
-00000360  63 95 8f 16 03 03 00 04  0e 00 00 00              |c...........|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 c0 0a 00 00  |................|
+00000030  05 ff 01 00 01 00 16 03  03 02 0e 0b 00 02 0a 00  |................|
+00000040  02 07 00 02 04 30 82 02  00 30 82 01 62 02 09 00  |.....0...0..b...|
+00000050  b8 bf 2d 47 a0 d2 eb f4  30 09 06 07 2a 86 48 ce  |..-G....0...*.H.|
+00000060  3d 04 01 30 45 31 0b 30  09 06 03 55 04 06 13 02  |=..0E1.0...U....|
+00000070  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
+00000080  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
+00000090  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
+000000a0  74 73 20 50 74 79 20 4c  74 64 30 1e 17 0d 31 32  |ts Pty Ltd0...12|
+000000b0  31 31 32 32 31 35 30 36  33 32 5a 17 0d 32 32 31  |1122150632Z..221|
+000000c0  31 32 30 31 35 30 36 33  32 5a 30 45 31 0b 30 09  |120150632Z0E1.0.|
+000000d0  06 03 55 04 06 13 02 41  55 31 13 30 11 06 03 55  |..U....AU1.0...U|
+000000e0  04 08 13 0a 53 6f 6d 65  2d 53 74 61 74 65 31 21  |....Some-State1!|
+000000f0  30 1f 06 03 55 04 0a 13  18 49 6e 74 65 72 6e 65  |0...U....Interne|
+00000100  74 20 57 69 64 67 69 74  73 20 50 74 79 20 4c 74  |t Widgits Pty Lt|
+00000110  64 30 81 9b 30 10 06 07  2a 86 48 ce 3d 02 01 06  |d0..0...*.H.=...|
+00000120  05 2b 81 04 00 23 03 81  86 00 04 00 c4 a1 ed be  |.+...#..........|
+00000130  98 f9 0b 48 73 36 7e c3  16 56 11 22 f2 3d 53 c3  |...Hs6~..V.".=S.|
+00000140  3b 4d 21 3d cd 6b 75 e6  f6 b0 dc 9a df 26 c1 bc  |;M!=.ku......&..|
+00000150  b2 87 f0 72 32 7c b3 64  2f 1c 90 bc ea 68 23 10  |...r2|.d/....h#.|
+00000160  7e fe e3 25 c0 48 3a 69  e0 28 6d d3 37 00 ef 04  |~..%.H:i.(m.7...|
+00000170  62 dd 0d a0 9c 70 62 83  d8 81 d3 64 31 aa 9e 97  |b....pb....d1...|
+00000180  31 bd 96 b0 68 c0 9b 23  de 76 64 3f 1a 5c 7f e9  |1...h..#.vd?.\..|
+00000190  12 0e 58 58 b6 5f 70 dd  9b d8 ea d5 d7 f5 d5 cc  |..XX._p.........|
+000001a0  b9 b6 9f 30 66 5b 66 9a  20 e2 27 e5 bf fe 3b 30  |...0f[f. .'...;0|
+000001b0  09 06 07 2a 86 48 ce 3d  04 01 03 81 8c 00 30 81  |...*.H.=......0.|
+000001c0  88 02 42 01 88 a2 4f eb  e2 45 c5 48 7d 1b ac f5  |..B...O..E.H}...|
+000001d0  ed 98 9d ae 47 70 c0 5e  1b b6 2f bd f1 b6 4d b7  |....Gp.^../...M.|
+000001e0  61 40 d3 11 a2 ce ee 0b  7e 92 7e ff 76 9d c3 3b  |a@......~.~.v..;|
+000001f0  7e a5 3f ce fa 10 e2 59  ec 47 2d 7c ac da 4e 97  |~.?....Y.G-|..N.|
+00000200  0e 15 a0 6f d0 02 42 01  4d fc be 67 13 9c 2d 05  |...o..B.M..g..-.|
+00000210  0e bd 3f a3 8c 25 c1 33  13 83 0d 94 06 bb d4 37  |..?..%.3.......7|
+00000220  7a f6 ec 7a c9 86 2e dd  d7 11 69 7f 85 7c 56 de  |z..z......i..|V.|
+00000230  fb 31 78 2b e4 c7 78 0d  ae cb be 9e 4e 36 24 31  |.1x+..x.....N6$1|
+00000240  7b 6a 0f 39 95 12 07 8f  2a 16 03 03 01 1c 0c 00  |{j.9....*.......|
+00000250  01 18 03 00 19 85 04 01  39 dc ee 44 17 5e db d7  |........9..D.^..|
+00000260  27 af b6 56 d9 b4 43 5a  99 cf aa 31 37 0c 6f 3a  |'..V..CZ...17.o:|
+00000270  a0 f8 53 c4 74 d1 91 0a  46 f5 38 3b 5c 09 d8 97  |..S.t...F.8;\...|
+00000280  dc 4b aa 70 26 48 f2 d6  0b 31 c9 f8 d4 98 43 e1  |.K.p&H...1....C.|
+00000290  6c d5 c7 b2 8e 0b 01 e6  b6 00 28 80 7b fc 96 8f  |l.........(.{...|
+000002a0  0d a2 4f b0 79 af dc 61  28 63 33 78 f6 31 39 fd  |..O.y..a(c3x.19.|
+000002b0  8a f4 15 18 11 fe db d5  07 da 2c ed 49 a0 23 bf  |..........,.I.#.|
+000002c0  d0 3a 38 1d 54 ae 1c 7b  ea 29 ee d0 38 c1 76 a7  |.:8.T..{.)..8.v.|
+000002d0  7f 2a f4 ce 1e ac cc 94  79 90 33 04 03 00 8b 30  |.*......y.3....0|
+000002e0  81 88 02 42 00 c6 85 8e  06 b7 04 04 e9 cd 9e 3e  |...B...........>|
+000002f0  cb 66 23 95 b4 42 9c 64  81 39 05 3f b5 21 f8 28  |.f#..B.d.9.?.!.(|
+00000300  af 60 6b 4d 3d ba a1 4b  5e 77 ef e7 59 28 fe 1d  |.`kM=..K^w..Y(..|
+00000310  c1 27 a2 ff a8 de 33 48  b3 c1 85 6a 42 9b f9 7e  |.'....3H...jB..~|
+00000320  7e 31 c2 e5 bd 66 02 42  00 ad 7d 06 35 ab ec 8d  |~1...f.B..}.5...|
+00000330  ac d4 ba 1b 49 5e 05 5f  f0 97 93 82 b8 2b 8d 91  |....I^._.....+..|
+00000340  98 63 8e b4 14 62 db 1e  c9 2b eb 95 36 9b 44 c6  |.c...b...+..6.D.|
+00000350  a6 89 58 50 f9 30 94 89  ef 0f 71 ed c0 42 59 11  |..XP.0....q..BY.|
+00000360  68 e7 ac 52 2c 1e ed 70  b1 f8 16 03 03 00 04 0e  |h..R,..p........|
+00000370  00 00 00                                          |...|
 >>> Flow 3 (client to server)
-00000000  16 03 03 00 8a 10 00 00  86 85 04 00 c6 26 3b 69  |.............&;i|
-00000010  8e 54 b7 33 1f be ba 55  54 2d 37 79 d2 69 b9 ff  |.T.3...UT-7y.i..|
-00000020  2f 18 4f e4 64 94 84 37  d3 34 5b 51 cd cd 62 45  |/.O.d..7.4[Q..bE|
-00000030  6f b6 78 46 ed 2e 7d 75  93 d7 b9 e3 18 d2 80 1e  |o.xF..}u........|
-00000040  55 09 57 13 6d 74 04 c6  f2 18 85 d2 44 01 7e 0a  |U.W.mt......D.~.|
-00000050  d7 31 93 51 45 47 74 11  a9 db b1 1b 93 d0 64 75  |.1.QEGt.......du|
-00000060  e1 be 61 88 5c 26 c3 a6  82 b0 04 ad b2 39 26 c7  |..a.\&.......9&.|
-00000070  75 fe ac 50 cd f4 87 8d  02 3a b4 06 9d 93 d5 09  |u..P.....:......|
-00000080  2c 8a fd 20 1c 34 73 8f  47 96 85 ce 80 fc b1 14  |,.. .4s.G.......|
-00000090  03 03 00 01 01 16 03 03  00 40 f2 63 f6 c1 21 89  |.........@.c..!.|
-000000a0  34 a9 cc a3 ff 71 a0 c5  9e b7 f9 32 80 8f 60 cc  |4....q.....2..`.|
-000000b0  bf 58 43 7c 5e d5 52 f1  d4 ea a3 50 ac 0d b5 ce  |.XC|^.R....P....|
-000000c0  80 82 f7 91 9b 07 f6 38  a8 90 b2 15 77 f5 b6 7c  |.......8....w..||
-000000d0  f9 df 62 f1 dc 15 21 04  dc 89                    |..b...!...|
+00000000  16 03 03 00 8a 10 00 00  86 85 04 01 7d 90 e6 a1  |............}...|
+00000010  06 d6 a9 32 e9 ba 42 d5  05 11 e7 69 7c 5e 6e b6  |...2..B....i|^n.|
+00000020  ad 51 bc 25 12 89 93 e0  bf 3c 2f ce a8 83 29 0e  |.Q.%.....</...).|
+00000030  eb 06 89 10 f4 de ce d9  16 6c 95 dc 61 66 84 87  |.........l..af..|
+00000040  84 6b 47 77 01 55 79 a2  0d e0 e8 d0 bd 00 7e d7  |.kGw.Uy.......~.|
+00000050  34 a4 75 e4 c8 ac e4 a3  4b df 27 52 7a f7 1b 0f  |4.u.....K.'Rz...|
+00000060  73 af 26 66 2c c9 29 56  b9 e2 1b b8 02 21 80 74  |s.&f,.)V.....!.t|
+00000070  db c8 d4 99 31 8f 6c 41  a6 b2 ac 60 82 13 85 08  |....1.lA...`....|
+00000080  4d 34 f2 77 ba 22 ec 05  92 9c 9b ca 2d 8e dc 14  |M4.w."......-...|
+00000090  03 03 00 01 01 16 03 03  00 40 19 4c 60 51 51 ed  |.........@.L`QQ.|
+000000a0  03 16 fe 05 a4 88 17 91  f0 0a 50 0d e4 a8 82 9a  |..........P.....|
+000000b0  4d 4b ef 2a 3d 57 29 60  e7 36 70 9c 41 e2 93 89  |MK.*=W)`.6p.A...|
+000000c0  b7 b0 f6 76 fc 19 93 7b  ac 8e 39 d1 7c 90 73 62  |...v...{..9.|.sb|
+000000d0  88 bf 0b 20 f9 fd 49 b4  d9 3c                    |... ..I..<|
 >>> Flow 4 (server to client)
 00000000  14 03 03 00 01 01 16 03  03 00 40 00 00 00 00 00  |..........@.....|
-00000010  00 00 00 00 00 00 00 00  00 00 00 3c d0 01 76 c9  |...........<..v.|
-00000020  0a 55 3f 92 47 ec 04 22  d8 79 3e 0c 7d f9 fe 12  |.U?.G..".y>.}...|
-00000030  c1 21 ce 50 d9 f1 2d 21  38 1a 74 44 e2 0d d0 e6  |.!.P..-!8.tD....|
-00000040  e5 e1 e2 a0 0e 20 59 7b  2c 62 57 17 03 03 00 40  |..... Y{,bW....@|
+00000010  00 00 00 00 00 00 00 00  00 00 00 f1 df 07 dd 3f  |...............?|
+00000020  92 27 96 9a 5c 98 4a 3b  39 0b 5d 2e 5f 12 55 11  |.'..\.J;9.]._.U.|
+00000030  32 4d 14 39 31 02 1b 02  ee b0 ae 2c 19 8d c2 31  |2M.91......,...1|
+00000040  52 cc e9 c3 d6 34 ac 4d  7f e6 6e 17 03 03 00 40  |R....4.M..n....@|
 00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000060  c7 92 46 7e 19 ca ca a3  39 e5 11 de 06 bd a8 ab  |..F~....9.......|
-00000070  68 75 b7 32 0b 8c a9 80  42 9c a2 ae a4 98 f1 5b  |hu.2....B......[|
-00000080  35 7b 05 63 2d a0 58 ae  01 9f b1 24 12 06 00 c5  |5{.c-.X....$....|
+00000060  6b 1e 9a b5 a8 89 3c d0  05 08 cf 81 a7 02 b4 ed  |k.....<.........|
+00000070  fa 21 e2 15 87 d0 78 ac  4b 8e fc d0 c5 0e b2 5c  |.!....x.K......\|
+00000080  bb c6 49 2a 80 00 67 93  37 4c a6 38 a7 24 f3 05  |..I*..g.7L.8.$..|
 00000090  15 03 03 00 30 00 00 00  00 00 00 00 00 00 00 00  |....0...........|
-000000a0  00 00 00 00 00 74 9c 20  9a ab fb 26 4b cd da 86  |.....t. ...&K...|
-000000b0  ad 35 0a ff 33 2f 49 59  47 f0 bd ac cf 77 b3 2e  |.5..3/IYG....w..|
-000000c0  0f 20 91 6b ed                                    |. .k.|
+000000a0  00 00 00 00 00 50 ea de  de b1 ba e4 da b1 d2 3e  |.....P.........>|
+000000b0  b3 ed 03 2f 8e 30 d5 20  f8 2a 65 d4 4c 1c b9 7f  |.../.0. .*e.L...|
+000000c0  4c 0c 8f cf 5a                                    |L...Z|
index 6350fe15dd1a66c8190ea96dcf27ad234b247bdb..e3e62f224230e339870153e8ecbbdc5f976dfb31 100644 (file)
@@ -1,87 +1,87 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 61 01 00 00  5d 03 03 52 ac 77 f8 de  |....a...]..R.w..|
-00000010  80 6f ff 1d 84 ca 82 41  2c 64 aa 9f a8 d3 85 c0  |.o.....A,d......|
-00000020  11 58 e0 72 b1 e7 98 03  00 cc 89 00 00 04 00 05  |.X.r............|
-00000030  00 ff 02 01 00 00 2f 00  23 00 00 00 0d 00 22 00  |....../.#.....".|
-00000040  20 06 01 06 02 06 03 05  01 05 02 05 03 04 01 04  | ...............|
-00000050  02 04 03 03 01 03 02 03  03 02 01 02 02 02 03 01  |................|
-00000060  01 00 0f 00 01 01                                 |......|
+00000000  16 03 01 00 60 01 00 00  5c 03 03 52 cc 57 59 7e  |....`...\..R.WY~|
+00000010  43 5c 3b fd 50 ab 61 3f  64 a4 f9 bd ba 8c 28 e1  |C\;.P.a?d.....(.|
+00000020  f9 a1 45 7e 48 9e 62 af  25 de 0e 00 00 04 00 05  |..E~H.b.%.......|
+00000030  00 ff 01 00 00 2f 00 23  00 00 00 0d 00 22 00 20  |...../.#.....". |
+00000040  06 01 06 02 06 03 05 01  05 02 05 03 04 01 04 02  |................|
+00000050  04 03 03 01 03 02 03 03  02 01 02 02 02 03 01 01  |................|
+00000060  00 0f 00 01 01                                    |.....|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 30 02 00 00  2c 03 03 00 00 00 00 00  |....0...,.......|
+00000000  16 03 03 00 35 02 00 00  31 03 03 00 00 00 00 00  |....5...1.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 05 00 00  |................|
-00000030  04 00 23 00 00 16 03 03  02 be 0b 00 02 ba 00 02  |..#.............|
-00000040  b7 00 02 b4 30 82 02 b0  30 82 02 19 a0 03 02 01  |....0...0.......|
-00000050  02 02 09 00 85 b0 bb a4  8a 7f b8 ca 30 0d 06 09  |............0...|
-00000060  2a 86 48 86 f7 0d 01 01  05 05 00 30 45 31 0b 30  |*.H........0E1.0|
-00000070  09 06 03 55 04 06 13 02  41 55 31 13 30 11 06 03  |...U....AU1.0...|
-00000080  55 04 08 13 0a 53 6f 6d  65 2d 53 74 61 74 65 31  |U....Some-State1|
-00000090  21 30 1f 06 03 55 04 0a  13 18 49 6e 74 65 72 6e  |!0...U....Intern|
-000000a0  65 74 20 57 69 64 67 69  74 73 20 50 74 79 20 4c  |et Widgits Pty L|
-000000b0  74 64 30 1e 17 0d 31 30  30 34 32 34 30 39 30 39  |td0...1004240909|
-000000c0  33 38 5a 17 0d 31 31 30  34 32 34 30 39 30 39 33  |38Z..11042409093|
-000000d0  38 5a 30 45 31 0b 30 09  06 03 55 04 06 13 02 41  |8Z0E1.0...U....A|
-000000e0  55 31 13 30 11 06 03 55  04 08 13 0a 53 6f 6d 65  |U1.0...U....Some|
-000000f0  2d 53 74 61 74 65 31 21  30 1f 06 03 55 04 0a 13  |-State1!0...U...|
-00000100  18 49 6e 74 65 72 6e 65  74 20 57 69 64 67 69 74  |.Internet Widgit|
-00000110  73 20 50 74 79 20 4c 74  64 30 81 9f 30 0d 06 09  |s Pty Ltd0..0...|
-00000120  2a 86 48 86 f7 0d 01 01  01 05 00 03 81 8d 00 30  |*.H............0|
-00000130  81 89 02 81 81 00 bb 79  d6 f5 17 b5 e5 bf 46 10  |.......y......F.|
-00000140  d0 dc 69 be e6 2b 07 43  5a d0 03 2d 8a 7a 43 85  |..i..+.CZ..-.zC.|
-00000150  b7 14 52 e7 a5 65 4c 2c  78 b8 23 8c b5 b4 82 e5  |..R..eL,x.#.....|
-00000160  de 1f 95 3b 7e 62 a5 2c  a5 33 d6 fe 12 5c 7a 56  |...;~b.,.3...\zV|
-00000170  fc f5 06 bf fa 58 7b 26  3f b5 cd 04 d3 d0 c9 21  |.....X{&?......!|
-00000180  96 4a c7 f4 54 9f 5a bf  ef 42 71 00 fe 18 99 07  |.J..T.Z..Bq.....|
-00000190  7f 7e 88 7d 7d f1 04 39  c4 a2 2e db 51 c9 7c e3  |.~.}}..9....Q.|.|
-000001a0  c0 4c 3b 32 66 01 cf af  b1 1d b8 71 9a 1d db db  |.L;2f......q....|
-000001b0  89 6b ae da 2d 79 02 03  01 00 01 a3 81 a7 30 81  |.k..-y........0.|
-000001c0  a4 30 1d 06 03 55 1d 0e  04 16 04 14 b1 ad e2 85  |.0...U..........|
-000001d0  5a cf cb 28 db 69 ce 23  69 de d3 26 8e 18 88 39  |Z..(.i.#i..&...9|
-000001e0  30 75 06 03 55 1d 23 04  6e 30 6c 80 14 b1 ad e2  |0u..U.#.n0l.....|
-000001f0  85 5a cf cb 28 db 69 ce  23 69 de d3 26 8e 18 88  |.Z..(.i.#i..&...|
-00000200  39 a1 49 a4 47 30 45 31  0b 30 09 06 03 55 04 06  |9.I.G0E1.0...U..|
-00000210  13 02 41 55 31 13 30 11  06 03 55 04 08 13 0a 53  |..AU1.0...U....S|
-00000220  6f 6d 65 2d 53 74 61 74  65 31 21 30 1f 06 03 55  |ome-State1!0...U|
-00000230  04 0a 13 18 49 6e 74 65  72 6e 65 74 20 57 69 64  |....Internet Wid|
-00000240  67 69 74 73 20 50 74 79  20 4c 74 64 82 09 00 85  |gits Pty Ltd....|
-00000250  b0 bb a4 8a 7f b8 ca 30  0c 06 03 55 1d 13 04 05  |.......0...U....|
-00000260  30 03 01 01 ff 30 0d 06  09 2a 86 48 86 f7 0d 01  |0....0...*.H....|
-00000270  01 05 05 00 03 81 81 00  08 6c 45 24 c7 6b b1 59  |.........lE$.k.Y|
-00000280  ab 0c 52 cc f2 b0 14 d7  87 9d 7a 64 75 b5 5a 95  |..R.......zdu.Z.|
-00000290  66 e4 c5 2b 8e ae 12 66  1f eb 4f 38 b3 6e 60 d3  |f..+...f..O8.n`.|
-000002a0  92 fd f7 41 08 b5 25 13  b1 18 7a 24 fb 30 1d ba  |...A..%...z$.0..|
-000002b0  ed 98 b9 17 ec e7 d7 31  59 db 95 d3 1d 78 ea 50  |.......1Y....x.P|
-000002c0  56 5c d5 82 5a 2d 5a 5f  33 c4 b6 d8 c9 75 90 96  |V\..Z-Z_3....u..|
-000002d0  8c 0f 52 98 b5 cd 98 1f  89 20 5f f2 a0 1c a3 1b  |..R...... _.....|
-000002e0  96 94 dd a9 fd 57 e9 70  e8 26 6d 71 99 9b 26 6e  |.....W.p.&mq..&n|
-000002f0  38 50 29 6c 90 a7 bd d9  16 03 03 00 04 0e 00 00  |8P)l............|
-00000300  00                                                |.|
+00000030  09 00 23 00 00 ff 01 00  01 00 16 03 03 02 be 0b  |..#.............|
+00000040  00 02 ba 00 02 b7 00 02  b4 30 82 02 b0 30 82 02  |.........0...0..|
+00000050  19 a0 03 02 01 02 02 09  00 85 b0 bb a4 8a 7f b8  |................|
+00000060  ca 30 0d 06 09 2a 86 48  86 f7 0d 01 01 05 05 00  |.0...*.H........|
+00000070  30 45 31 0b 30 09 06 03  55 04 06 13 02 41 55 31  |0E1.0...U....AU1|
+00000080  13 30 11 06 03 55 04 08  13 0a 53 6f 6d 65 2d 53  |.0...U....Some-S|
+00000090  74 61 74 65 31 21 30 1f  06 03 55 04 0a 13 18 49  |tate1!0...U....I|
+000000a0  6e 74 65 72 6e 65 74 20  57 69 64 67 69 74 73 20  |nternet Widgits |
+000000b0  50 74 79 20 4c 74 64 30  1e 17 0d 31 30 30 34 32  |Pty Ltd0...10042|
+000000c0  34 30 39 30 39 33 38 5a  17 0d 31 31 30 34 32 34  |4090938Z..110424|
+000000d0  30 39 30 39 33 38 5a 30  45 31 0b 30 09 06 03 55  |090938Z0E1.0...U|
+000000e0  04 06 13 02 41 55 31 13  30 11 06 03 55 04 08 13  |....AU1.0...U...|
+000000f0  0a 53 6f 6d 65 2d 53 74  61 74 65 31 21 30 1f 06  |.Some-State1!0..|
+00000100  03 55 04 0a 13 18 49 6e  74 65 72 6e 65 74 20 57  |.U....Internet W|
+00000110  69 64 67 69 74 73 20 50  74 79 20 4c 74 64 30 81  |idgits Pty Ltd0.|
+00000120  9f 30 0d 06 09 2a 86 48  86 f7 0d 01 01 01 05 00  |.0...*.H........|
+00000130  03 81 8d 00 30 81 89 02  81 81 00 bb 79 d6 f5 17  |....0.......y...|
+00000140  b5 e5 bf 46 10 d0 dc 69  be e6 2b 07 43 5a d0 03  |...F...i..+.CZ..|
+00000150  2d 8a 7a 43 85 b7 14 52  e7 a5 65 4c 2c 78 b8 23  |-.zC...R..eL,x.#|
+00000160  8c b5 b4 82 e5 de 1f 95  3b 7e 62 a5 2c a5 33 d6  |........;~b.,.3.|
+00000170  fe 12 5c 7a 56 fc f5 06  bf fa 58 7b 26 3f b5 cd  |..\zV.....X{&?..|
+00000180  04 d3 d0 c9 21 96 4a c7  f4 54 9f 5a bf ef 42 71  |....!.J..T.Z..Bq|
+00000190  00 fe 18 99 07 7f 7e 88  7d 7d f1 04 39 c4 a2 2e  |......~.}}..9...|
+000001a0  db 51 c9 7c e3 c0 4c 3b  32 66 01 cf af b1 1d b8  |.Q.|..L;2f......|
+000001b0  71 9a 1d db db 89 6b ae  da 2d 79 02 03 01 00 01  |q.....k..-y.....|
+000001c0  a3 81 a7 30 81 a4 30 1d  06 03 55 1d 0e 04 16 04  |...0..0...U.....|
+000001d0  14 b1 ad e2 85 5a cf cb  28 db 69 ce 23 69 de d3  |.....Z..(.i.#i..|
+000001e0  26 8e 18 88 39 30 75 06  03 55 1d 23 04 6e 30 6c  |&...90u..U.#.n0l|
+000001f0  80 14 b1 ad e2 85 5a cf  cb 28 db 69 ce 23 69 de  |......Z..(.i.#i.|
+00000200  d3 26 8e 18 88 39 a1 49  a4 47 30 45 31 0b 30 09  |.&...9.I.G0E1.0.|
+00000210  06 03 55 04 06 13 02 41  55 31 13 30 11 06 03 55  |..U....AU1.0...U|
+00000220  04 08 13 0a 53 6f 6d 65  2d 53 74 61 74 65 31 21  |....Some-State1!|
+00000230  30 1f 06 03 55 04 0a 13  18 49 6e 74 65 72 6e 65  |0...U....Interne|
+00000240  74 20 57 69 64 67 69 74  73 20 50 74 79 20 4c 74  |t Widgits Pty Lt|
+00000250  64 82 09 00 85 b0 bb a4  8a 7f b8 ca 30 0c 06 03  |d...........0...|
+00000260  55 1d 13 04 05 30 03 01  01 ff 30 0d 06 09 2a 86  |U....0....0...*.|
+00000270  48 86 f7 0d 01 01 05 05  00 03 81 81 00 08 6c 45  |H.............lE|
+00000280  24 c7 6b b1 59 ab 0c 52  cc f2 b0 14 d7 87 9d 7a  |$.k.Y..R.......z|
+00000290  64 75 b5 5a 95 66 e4 c5  2b 8e ae 12 66 1f eb 4f  |du.Z.f..+...f..O|
+000002a0  38 b3 6e 60 d3 92 fd f7  41 08 b5 25 13 b1 18 7a  |8.n`....A..%...z|
+000002b0  24 fb 30 1d ba ed 98 b9  17 ec e7 d7 31 59 db 95  |$.0.........1Y..|
+000002c0  d3 1d 78 ea 50 56 5c d5  82 5a 2d 5a 5f 33 c4 b6  |..x.PV\..Z-Z_3..|
+000002d0  d8 c9 75 90 96 8c 0f 52  98 b5 cd 98 1f 89 20 5f  |..u....R...... _|
+000002e0  f2 a0 1c a3 1b 96 94 dd  a9 fd 57 e9 70 e8 26 6d  |..........W.p.&m|
+000002f0  71 99 9b 26 6e 38 50 29  6c 90 a7 bd d9 16 03 03  |q..&n8P)l.......|
+00000300  00 04 0e 00 00 00                                 |......|
 >>> Flow 3 (client to server)
-00000000  16 03 03 00 86 10 00 00  82 00 80 01 0a 69 54 c5  |.............iT.|
-00000010  b8 a7 ab 91 53 42 ff c9  2b 27 49 12 df 7d 4d 65  |....SB..+'I..}Me|
-00000020  d1 5a 36 a0 47 ad f6 42  59 36 99 d0 d6 92 9e 16  |.Z6.G..BY6......|
-00000030  9d 8c 0c ad ee f9 7b b1  96 91 01 1e b1 b5 04 a9  |......{.........|
-00000040  0d fe 0b 88 b8 25 4f 70  f8 51 7e 6f c9 cd 7a 60  |.....%Op.Q~o..z`|
-00000050  2c 58 b4 50 36 28 01 e8  71 86 08 7e 75 b3 76 31  |,X.P6(..q..~u.v1|
-00000060  69 50 3a bb 21 95 f8 75  64 7f 0b 78 29 da 82 6b  |iP:.!..ud..x)..k|
-00000070  e1 b9 cd ca 2c f0 57 f9  e3 d0 09 df fd 51 bc fa  |....,.W......Q..|
-00000080  ef f1 68 07 4b 21 6e 52  7a 5f dc 14 03 03 00 01  |..h.K!nRz_......|
-00000090  01 16 03 03 00 24 ca a5  ab ab 2f 12 1e a8 3c 33  |.....$..../...<3|
-000000a0  24 e8 ef c9 b2 bb 58 61  c0 eb 97 66 fb e0 72 4a  |$.....Xa...f..rJ|
-000000b0  82 9e e7 d1 0f fa be aa  d0 d3                    |..........|
+00000000  16 03 03 00 86 10 00 00  82 00 80 6e 2e 79 82 3a  |...........n.y.:|
+00000010  c4 68 72 f5 a2 42 3d 71  f9 ec 22 8c 0b fa f0 82  |.hr..B=q..".....|
+00000020  82 c0 cb fc 52 0a 51 03  04 8c eb 4a 4e 4f b6 49  |....R.Q....JNO.I|
+00000030  ef 94 65 21 3c f7 9d 46  85 6e 35 d5 17 6b ff a3  |..e!<..F.n5..k..|
+00000040  5e 4d c1 36 1a 2f 68 f5  06 d4 2d 73 4f 1c 3b 7b  |^M.6./h...-sO.;{|
+00000050  c1 fa 4e 7e 7c f9 6c 13  a6 f4 3a 43 e9 aa be 22  |..N~|.l...:C..."|
+00000060  85 6f 2f 7c 5b b0 08 e2  86 b2 ae cb a9 12 d8 32  |.o/|[..........2|
+00000070  80 1d e4 2e 5d c3 66 d1  19 e5 89 33 2a 88 24 40  |....].f....3*.$@|
+00000080  2a 6d 6b b5 f1 92 4b 66  06 b8 49 14 03 03 00 01  |*mk...Kf..I.....|
+00000090  01 16 03 03 00 24 16 49  e2 a0 67 31 cf 0d 72 cb  |.....$.I..g1..r.|
+000000a0  ac 16 2c 80 37 71 69 f7  5f c4 d3 00 19 b7 4b fb  |..,.7qi._.....K.|
+000000b0  e5 e9 74 8e 30 b3 1c c5  ae e6                    |..t.0.....|
 >>> Flow 4 (server to client)
 00000000  16 03 03 00 72 04 00 00  6e 00 00 00 00 00 68 00  |....r...n.....h.|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 65  |...............e|
-00000020  ea 4b d1 ef ba 11 a0 88  48 34 0d 3b 22 38 1e 62  |.K......H4.;"8.b|
-00000030  c5 0a 33 b3 f0 65 ff fa  c4 f3 a8 2d 24 75 55 e4  |..3..e.....-$uU.|
-00000040  47 cc d2 6b 8d 26 c6 d1  10 cc a2 48 29 c0 a1 a5  |G..k.&.....H)...|
-00000050  52 66 dc ec 0b 59 23 02  5b 66 c3 af 88 27 f0 65  |Rf...Y#.[f...'.e|
-00000060  c0 72 de 1a db cf 9b 5f  e7 fe e8 2d 27 6f 67 fb  |.r....._...-'og.|
-00000070  91 a1 46 70 b1 ce 29 14  03 03 00 01 01 16 03 03  |..Fp..).........|
-00000080  00 24 de 3d 06 39 fa fe  ad 47 50 1e 3d 38 ff 1d  |.$.=.9...GP.=8..|
-00000090  15 7f 11 4a 90 52 de 7d  0b d3 8b f4 f8 60 a9 78  |...J.R.}.....`.x|
-000000a0  6a db e2 a7 5b b7 17 03  03 00 21 66 6f 29 59 68  |j...[.....!fo)Yh|
-000000b0  e0 64 a1 87 c8 f2 63 86  c6 5c c8 dc 05 de 6f d2  |.d....c..\....o.|
-000000c0  db 53 72 f1 ae 22 61 4e  a1 b8 c9 25 15 03 03 00  |.Sr.."aN...%....|
-000000d0  16 70 ad 3d dc 66 ab 57  2e 75 ab 1f 07 9e 70 77  |.p.=.f.W.u....pw|
-000000e0  c2 2b 88 05 34 cf da                              |.+..4..|
+00000020  ea 4b d1 ef ba 06 38 1e  e1 88 82 3a cd 03 ac 3b  |.K....8....:...;|
+00000030  39 0a e0 19 fd af 6c 57  30 df 31 6e f7 92 38 4b  |9.....lW0.1n..8K|
+00000040  5d 77 90 39 ff 32 51 f5  ed 12 d7 b0 7c 4d 6c c5  |]w.9.2Q.....|Ml.|
+00000050  76 e4 72 48 3e 59 23 fe  0d 15 df f4 ba ea b9 67  |v.rH>Y#........g|
+00000060  16 23 8f 7d 15 b6 11 f1  ab d7 d4 cd a3 21 82 92  |.#.}.........!..|
+00000070  2a 12 cf 95 f3 60 b2 14  03 03 00 01 01 16 03 03  |*....`..........|
+00000080  00 24 89 ad 87 04 4f 08  dc 2a 71 37 fb f1 95 d1  |.$....O..*q7....|
+00000090  2e 3c c2 6e 0f 38 5d e4  0e c3 f7 27 d0 46 a3 c1  |.<.n.8]....'.F..|
+000000a0  a8 3b 06 ed 96 ec 17 03  03 00 21 30 d4 9f 0b 49  |.;........!0...I|
+000000b0  9f a2 a8 a1 2c 0a 79 93  56 2d 8a ee 85 ed 62 42  |....,.y.V-....bB|
+000000c0  8c 18 fe 7a 09 3a 24 c4  5e ed 7d 2a 15 03 03 00  |...z.:$.^.}*....|
+000000d0  16 a0 24 0a 8b 90 4c fc  99 ba 67 bb 04 1e 59 69  |..$...L...g...Yi|
+000000e0  c2 98 49 b5 00 0b e0                              |..I....|
index fe0a0bd3f0af1bc437c8c4f6c75ba1301e07fa58..5995b3314c420da8ede5b73791b2d487498a5b60 100644 (file)
@@ -1,82 +1,83 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 5d 01 00 00  59 03 03 52 ac 77 f8 94  |....]...Y..R.w..|
-00000010  1b 92 d4 0b 16 00 df 59  3d 0e 9b 20 4a 9a 37 b5  |.......Y=.. J.7.|
-00000020  8c 96 96 f9 a0 d4 4f b2  20 9e 22 00 00 04 00 0a  |......O. .".....|
-00000030  00 ff 02 01 00 00 2b 00  0d 00 22 00 20 06 01 06  |......+...". ...|
-00000040  02 06 03 05 01 05 02 05  03 04 01 04 02 04 03 03  |................|
-00000050  01 03 02 03 03 02 01 02  02 02 03 01 01 00 0f 00  |................|
-00000060  01 01                                             |..|
+00000000  16 03 01 00 5c 01 00 00  58 03 03 52 cc 57 59 68  |....\...X..R.WYh|
+00000010  11 72 a6 ec 6b 0a 47 1d  10 06 ec 75 af 07 38 a0  |.r..k.G....u..8.|
+00000020  30 9e 91 12 e1 9b 19 46  0d d4 45 00 00 04 00 0a  |0......F..E.....|
+00000030  00 ff 01 00 00 2b 00 0d  00 22 00 20 06 01 06 02  |.....+...". ....|
+00000040  06 03 05 01 05 02 05 03  04 01 04 02 04 03 03 01  |................|
+00000050  03 02 03 03 02 01 02 02  02 03 01 01 00 0f 00 01  |................|
+00000060  01                                                |.|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 2a 02 00 00  26 03 03 00 00 00 00 00  |....*...&.......|
+00000000  16 03 03 00 31 02 00 00  2d 03 03 00 00 00 00 00  |....1...-.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 0a 00 16  |................|
-00000030  03 03 02 be 0b 00 02 ba  00 02 b7 00 02 b4 30 82  |..............0.|
-00000040  02 b0 30 82 02 19 a0 03  02 01 02 02 09 00 85 b0  |..0.............|
-00000050  bb a4 8a 7f b8 ca 30 0d  06 09 2a 86 48 86 f7 0d  |......0...*.H...|
-00000060  01 01 05 05 00 30 45 31  0b 30 09 06 03 55 04 06  |.....0E1.0...U..|
-00000070  13 02 41 55 31 13 30 11  06 03 55 04 08 13 0a 53  |..AU1.0...U....S|
-00000080  6f 6d 65 2d 53 74 61 74  65 31 21 30 1f 06 03 55  |ome-State1!0...U|
-00000090  04 0a 13 18 49 6e 74 65  72 6e 65 74 20 57 69 64  |....Internet Wid|
-000000a0  67 69 74 73 20 50 74 79  20 4c 74 64 30 1e 17 0d  |gits Pty Ltd0...|
-000000b0  31 30 30 34 32 34 30 39  30 39 33 38 5a 17 0d 31  |100424090938Z..1|
-000000c0  31 30 34 32 34 30 39 30  39 33 38 5a 30 45 31 0b  |10424090938Z0E1.|
-000000d0  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-000000e0  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-000000f0  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-00000100  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-00000110  4c 74 64 30 81 9f 30 0d  06 09 2a 86 48 86 f7 0d  |Ltd0..0...*.H...|
-00000120  01 01 01 05 00 03 81 8d  00 30 81 89 02 81 81 00  |.........0......|
-00000130  bb 79 d6 f5 17 b5 e5 bf  46 10 d0 dc 69 be e6 2b  |.y......F...i..+|
-00000140  07 43 5a d0 03 2d 8a 7a  43 85 b7 14 52 e7 a5 65  |.CZ..-.zC...R..e|
-00000150  4c 2c 78 b8 23 8c b5 b4  82 e5 de 1f 95 3b 7e 62  |L,x.#........;~b|
-00000160  a5 2c a5 33 d6 fe 12 5c  7a 56 fc f5 06 bf fa 58  |.,.3...\zV.....X|
-00000170  7b 26 3f b5 cd 04 d3 d0  c9 21 96 4a c7 f4 54 9f  |{&?......!.J..T.|
-00000180  5a bf ef 42 71 00 fe 18  99 07 7f 7e 88 7d 7d f1  |Z..Bq......~.}}.|
-00000190  04 39 c4 a2 2e db 51 c9  7c e3 c0 4c 3b 32 66 01  |.9....Q.|..L;2f.|
-000001a0  cf af b1 1d b8 71 9a 1d  db db 89 6b ae da 2d 79  |.....q.....k..-y|
-000001b0  02 03 01 00 01 a3 81 a7  30 81 a4 30 1d 06 03 55  |........0..0...U|
-000001c0  1d 0e 04 16 04 14 b1 ad  e2 85 5a cf cb 28 db 69  |..........Z..(.i|
-000001d0  ce 23 69 de d3 26 8e 18  88 39 30 75 06 03 55 1d  |.#i..&...90u..U.|
-000001e0  23 04 6e 30 6c 80 14 b1  ad e2 85 5a cf cb 28 db  |#.n0l......Z..(.|
-000001f0  69 ce 23 69 de d3 26 8e  18 88 39 a1 49 a4 47 30  |i.#i..&...9.I.G0|
-00000200  45 31 0b 30 09 06 03 55  04 06 13 02 41 55 31 13  |E1.0...U....AU1.|
-00000210  30 11 06 03 55 04 08 13  0a 53 6f 6d 65 2d 53 74  |0...U....Some-St|
-00000220  61 74 65 31 21 30 1f 06  03 55 04 0a 13 18 49 6e  |ate1!0...U....In|
-00000230  74 65 72 6e 65 74 20 57  69 64 67 69 74 73 20 50  |ternet Widgits P|
-00000240  74 79 20 4c 74 64 82 09  00 85 b0 bb a4 8a 7f b8  |ty Ltd..........|
-00000250  ca 30 0c 06 03 55 1d 13  04 05 30 03 01 01 ff 30  |.0...U....0....0|
-00000260  0d 06 09 2a 86 48 86 f7  0d 01 01 05 05 00 03 81  |...*.H..........|
-00000270  81 00 08 6c 45 24 c7 6b  b1 59 ab 0c 52 cc f2 b0  |...lE$.k.Y..R...|
-00000280  14 d7 87 9d 7a 64 75 b5  5a 95 66 e4 c5 2b 8e ae  |....zdu.Z.f..+..|
-00000290  12 66 1f eb 4f 38 b3 6e  60 d3 92 fd f7 41 08 b5  |.f..O8.n`....A..|
-000002a0  25 13 b1 18 7a 24 fb 30  1d ba ed 98 b9 17 ec e7  |%...z$.0........|
-000002b0  d7 31 59 db 95 d3 1d 78  ea 50 56 5c d5 82 5a 2d  |.1Y....x.PV\..Z-|
-000002c0  5a 5f 33 c4 b6 d8 c9 75  90 96 8c 0f 52 98 b5 cd  |Z_3....u....R...|
-000002d0  98 1f 89 20 5f f2 a0 1c  a3 1b 96 94 dd a9 fd 57  |... _..........W|
-000002e0  e9 70 e8 26 6d 71 99 9b  26 6e 38 50 29 6c 90 a7  |.p.&mq..&n8P)l..|
-000002f0  bd d9 16 03 03 00 04 0e  00 00 00                 |...........|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 0a 00 00  |................|
+00000030  05 ff 01 00 01 00 16 03  03 02 be 0b 00 02 ba 00  |................|
+00000040  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
+00000050  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
+00000060  09 2a 86 48 86 f7 0d 01  01 05 05 00 30 45 31 0b  |.*.H........0E1.|
+00000070  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
+00000080  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
+00000090  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
+000000a0  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
+000000b0  4c 74 64 30 1e 17 0d 31  30 30 34 32 34 30 39 30  |Ltd0...100424090|
+000000c0  39 33 38 5a 17 0d 31 31  30 34 32 34 30 39 30 39  |938Z..1104240909|
+000000d0  33 38 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |38Z0E1.0...U....|
+000000e0  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
+000000f0  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
+00000100  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
+00000110  74 73 20 50 74 79 20 4c  74 64 30 81 9f 30 0d 06  |ts Pty Ltd0..0..|
+00000120  09 2a 86 48 86 f7 0d 01  01 01 05 00 03 81 8d 00  |.*.H............|
+00000130  30 81 89 02 81 81 00 bb  79 d6 f5 17 b5 e5 bf 46  |0.......y......F|
+00000140  10 d0 dc 69 be e6 2b 07  43 5a d0 03 2d 8a 7a 43  |...i..+.CZ..-.zC|
+00000150  85 b7 14 52 e7 a5 65 4c  2c 78 b8 23 8c b5 b4 82  |...R..eL,x.#....|
+00000160  e5 de 1f 95 3b 7e 62 a5  2c a5 33 d6 fe 12 5c 7a  |....;~b.,.3...\z|
+00000170  56 fc f5 06 bf fa 58 7b  26 3f b5 cd 04 d3 d0 c9  |V.....X{&?......|
+00000180  21 96 4a c7 f4 54 9f 5a  bf ef 42 71 00 fe 18 99  |!.J..T.Z..Bq....|
+00000190  07 7f 7e 88 7d 7d f1 04  39 c4 a2 2e db 51 c9 7c  |..~.}}..9....Q.||
+000001a0  e3 c0 4c 3b 32 66 01 cf  af b1 1d b8 71 9a 1d db  |..L;2f......q...|
+000001b0  db 89 6b ae da 2d 79 02  03 01 00 01 a3 81 a7 30  |..k..-y........0|
+000001c0  81 a4 30 1d 06 03 55 1d  0e 04 16 04 14 b1 ad e2  |..0...U.........|
+000001d0  85 5a cf cb 28 db 69 ce  23 69 de d3 26 8e 18 88  |.Z..(.i.#i..&...|
+000001e0  39 30 75 06 03 55 1d 23  04 6e 30 6c 80 14 b1 ad  |90u..U.#.n0l....|
+000001f0  e2 85 5a cf cb 28 db 69  ce 23 69 de d3 26 8e 18  |..Z..(.i.#i..&..|
+00000200  88 39 a1 49 a4 47 30 45  31 0b 30 09 06 03 55 04  |.9.I.G0E1.0...U.|
+00000210  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
+00000220  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
+00000230  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
+00000240  64 67 69 74 73 20 50 74  79 20 4c 74 64 82 09 00  |dgits Pty Ltd...|
+00000250  85 b0 bb a4 8a 7f b8 ca  30 0c 06 03 55 1d 13 04  |........0...U...|
+00000260  05 30 03 01 01 ff 30 0d  06 09 2a 86 48 86 f7 0d  |.0....0...*.H...|
+00000270  01 01 05 05 00 03 81 81  00 08 6c 45 24 c7 6b b1  |..........lE$.k.|
+00000280  59 ab 0c 52 cc f2 b0 14  d7 87 9d 7a 64 75 b5 5a  |Y..R.......zdu.Z|
+00000290  95 66 e4 c5 2b 8e ae 12  66 1f eb 4f 38 b3 6e 60  |.f..+...f..O8.n`|
+000002a0  d3 92 fd f7 41 08 b5 25  13 b1 18 7a 24 fb 30 1d  |....A..%...z$.0.|
+000002b0  ba ed 98 b9 17 ec e7 d7  31 59 db 95 d3 1d 78 ea  |........1Y....x.|
+000002c0  50 56 5c d5 82 5a 2d 5a  5f 33 c4 b6 d8 c9 75 90  |PV\..Z-Z_3....u.|
+000002d0  96 8c 0f 52 98 b5 cd 98  1f 89 20 5f f2 a0 1c a3  |...R...... _....|
+000002e0  1b 96 94 dd a9 fd 57 e9  70 e8 26 6d 71 99 9b 26  |......W.p.&mq..&|
+000002f0  6e 38 50 29 6c 90 a7 bd  d9 16 03 03 00 04 0e 00  |n8P)l...........|
+00000300  00 00                                             |..|
 >>> Flow 3 (client to server)
-00000000  16 03 03 00 86 10 00 00  82 00 80 49 e0 e1 1c 2f  |...........I.../|
-00000010  7a 73 f4 a2 af 83 23 1d  4a 49 2b 6d d8 95 c7 48  |zs....#.JI+m...H|
-00000020  ea 32 03 0d f8 72 06 73  92 90 67 10 d7 c5 12 b3  |.2...r.s..g.....|
-00000030  52 56 1e e9 14 d5 1b 67  68 93 9f 9f 0c 53 bf 73  |RV.....gh....S.s|
-00000040  80 09 0f 67 05 d6 de 59  4b 76 0e 8f 8d a2 6e 09  |...g...YKv....n.|
-00000050  3d 86 a4 d8 f9 af a0 89  73 5a 1a 58 9b 80 a6 28  |=.......sZ.X...(|
-00000060  4b 6b 79 af de 02 56 1e  2b d3 ec 3f 67 43 1e 45  |Kky...V.+..?gC.E|
-00000070  cd d0 69 db 88 f3 6b d8  cd cd 89 82 7a cf 5a 76  |..i...k.....z.Zv|
-00000080  5f 1e b3 ae 01 34 7c 2b  3c fa 82 14 03 03 00 01  |_....4|+<.......|
-00000090  01 16 03 03 00 30 ce 2c  83 c5 74 8b ab 3c 6b 54  |.....0.,..t..<kT|
-000000a0  73 7a d2 5e e6 db 7c c7  c1 c0 8e da 13 d3 a3 d8  |sz.^..|.........|
-000000b0  de 53 be b9 0b 45 cf 40  35 fa 77 6a 95 83 4f 26  |.S...E.@5.wj..O&|
-000000c0  74 33 5b a3 5d f8                                 |t3[.].|
+00000000  16 03 03 00 86 10 00 00  82 00 80 7a c0 73 ec cb  |...........z.s..|
+00000010  cf c2 a8 86 c0 7e 03 63  57 a1 ce 42 37 6d 78 54  |.....~.cW..B7mxT|
+00000020  29 f5 3e cc 57 c7 0d d9  69 e1 52 5c 3b 6b c4 c7  |).>.W...i.R\;k..|
+00000030  20 6d 59 ee c0 07 81 74  74 9f 62 41 64 f0 4d c8  | mY....tt.bAd.M.|
+00000040  9b aa 1a b9 da 56 07 f5  6c 1c 59 8c d3 f9 08 d9  |.....V..l.Y.....|
+00000050  08 f4 16 93 5d 9a e5 6f  fb 9f ba 3d 3c d6 81 ad  |....]..o...=<...|
+00000060  02 12 a7 28 b6 81 6a 77  c3 e9 d7 c7 54 d6 77 83  |...(..jw....T.w.|
+00000070  77 de 71 fb b3 f3 2d c4  a5 b1 e5 de aa 0e 21 bd  |w.q...-.......!.|
+00000080  91 a2 dc 7f f7 6f 90 82  54 b1 e7 14 03 03 00 01  |.....o..T.......|
+00000090  01 16 03 03 00 30 8f ee  bf fb c8 5c 54 f5 29 23  |.....0.....\T.)#|
+000000a0  d4 55 f6 98 a1 6e d5 43  e7 81 b2 36 f2 98 d8 1b  |.U...n.C...6....|
+000000b0  0d 76 cb 14 ba 32 d7 36  30 e6 ab 42 80 95 f6 8a  |.v...2.60..B....|
+000000c0  60 64 a0 6b 90 81                                 |`d.k..|
 >>> Flow 4 (server to client)
 00000000  14 03 03 00 01 01 16 03  03 00 30 00 00 00 00 00  |..........0.....|
-00000010  00 00 00 fa 71 b5 6e 06  4f ba 9e 8d 44 85 b1 58  |....q.n.O...D..X|
-00000020  dc 6e 13 a7 f4 26 96 cd  9d 58 41 c3 d7 14 7c 20  |.n...&...XA...| |
-00000030  0d 77 83 e0 8c 43 a7 74  8b 7d 60 17 03 03 00 30  |.w...C.t.}`....0|
-00000040  00 00 00 00 00 00 00 00  55 f4 03 c0 00 95 bb 6d  |........U......m|
-00000050  52 29 35 7b ba 5d d5 e4  4d 8b 2a 5a 21 25 af 43  |R)5{.]..M.*Z!%.C|
-00000060  0d e5 ad 97 ba 70 4d b2  79 78 58 1d c4 d3 c9 8b  |.....pM.yxX.....|
-00000070  15 03 03 00 20 00 00 00  00 00 00 00 00 d4 54 36  |.... .........T6|
-00000080  41 07 5d e0 de 65 80 ad  b8 0f 61 22 a8 0f 87 2f  |A.]..e....a".../|
-00000090  59 91 0a de 60                                    |Y...`|
+00000010  00 00 00 2c 21 52 34 63  ac e3 a3 66 45 00 41 0c  |...,!R4c...fE.A.|
+00000020  93 5d 6a 74 5a 25 dc 69  1d 76 73 0c f4 42 6a 18  |.]jtZ%.i.vs..Bj.|
+00000030  5b 62 23 e7 fe 41 cf d4  9b 86 35 17 03 03 00 30  |[b#..A....5....0|
+00000040  00 00 00 00 00 00 00 00  7d 5d ce 43 85 5c 6b 89  |........}].C.\k.|
+00000050  c9 a5 0e 22 69 8e b9 4a  77 4c c0 4e cc 79 d9 7e  |..."i..JwL.N.y.~|
+00000060  a3 c8 d3 db 5c 53 f8 92  4d c4 5a 88 72 58 05 11  |....\S..M.Z.rX..|
+00000070  15 03 03 00 20 00 00 00  00 00 00 00 00 1d 63 8b  |.... .........c.|
+00000080  a7 74 fb 76 1d 47 31 93  1f ec 8c e2 18 8e 21 dd  |.t.v.G1.......!.|
+00000090  87 97 9f 1c ca                                    |.....|
index c19d37fa4eb5786c9df97e68ae27fa54d581f5b9..a152a96a849adf550c46f7d838faae3cf9f96501 100644 (file)
@@ -1,86 +1,87 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 5d 01 00 00  59 03 03 52 ac 77 f8 f2  |....]...Y..R.w..|
-00000010  28 d7 4f 30 1c 37 0e be  ff 22 60 a4 4a b4 14 11  |(.O0.7..."`.J...|
-00000020  47 2d 7b 91 55 d6 c3 58  51 c3 f1 00 00 04 00 2f  |G-{.U..XQ....../|
-00000030  00 ff 02 01 00 00 2b 00  0d 00 22 00 20 06 01 06  |......+...". ...|
-00000040  02 06 03 05 01 05 02 05  03 04 01 04 02 04 03 03  |................|
-00000050  01 03 02 03 03 02 01 02  02 02 03 01 01 00 0f 00  |................|
-00000060  01 01                                             |..|
+00000000  16 03 01 00 5c 01 00 00  58 03 03 52 cc 57 59 d0  |....\...X..R.WY.|
+00000010  38 05 36 7e e3 1e 93 2a  5a bf dc c2 f8 0a 03 6f  |8.6~...*Z......o|
+00000020  1a fc 21 74 e5 8b 2a c3  9e 2c 26 00 00 04 00 2f  |..!t..*..,&..../|
+00000030  00 ff 01 00 00 2b 00 0d  00 22 00 20 06 01 06 02  |.....+...". ....|
+00000040  06 03 05 01 05 02 05 03  04 01 04 02 04 03 03 01  |................|
+00000050  03 02 03 03 02 01 02 02  02 03 01 01 00 0f 00 01  |................|
+00000060  01                                                |.|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 2a 02 00 00  26 03 03 00 00 00 00 00  |....*...&.......|
+00000000  16 03 03 00 31 02 00 00  2d 03 03 00 00 00 00 00  |....1...-.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 2f 00 16  |............./..|
-00000030  03 03 02 be 0b 00 02 ba  00 02 b7 00 02 b4 30 82  |..............0.|
-00000040  02 b0 30 82 02 19 a0 03  02 01 02 02 09 00 85 b0  |..0.............|
-00000050  bb a4 8a 7f b8 ca 30 0d  06 09 2a 86 48 86 f7 0d  |......0...*.H...|
-00000060  01 01 05 05 00 30 45 31  0b 30 09 06 03 55 04 06  |.....0E1.0...U..|
-00000070  13 02 41 55 31 13 30 11  06 03 55 04 08 13 0a 53  |..AU1.0...U....S|
-00000080  6f 6d 65 2d 53 74 61 74  65 31 21 30 1f 06 03 55  |ome-State1!0...U|
-00000090  04 0a 13 18 49 6e 74 65  72 6e 65 74 20 57 69 64  |....Internet Wid|
-000000a0  67 69 74 73 20 50 74 79  20 4c 74 64 30 1e 17 0d  |gits Pty Ltd0...|
-000000b0  31 30 30 34 32 34 30 39  30 39 33 38 5a 17 0d 31  |100424090938Z..1|
-000000c0  31 30 34 32 34 30 39 30  39 33 38 5a 30 45 31 0b  |10424090938Z0E1.|
-000000d0  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-000000e0  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-000000f0  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-00000100  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-00000110  4c 74 64 30 81 9f 30 0d  06 09 2a 86 48 86 f7 0d  |Ltd0..0...*.H...|
-00000120  01 01 01 05 00 03 81 8d  00 30 81 89 02 81 81 00  |.........0......|
-00000130  bb 79 d6 f5 17 b5 e5 bf  46 10 d0 dc 69 be e6 2b  |.y......F...i..+|
-00000140  07 43 5a d0 03 2d 8a 7a  43 85 b7 14 52 e7 a5 65  |.CZ..-.zC...R..e|
-00000150  4c 2c 78 b8 23 8c b5 b4  82 e5 de 1f 95 3b 7e 62  |L,x.#........;~b|
-00000160  a5 2c a5 33 d6 fe 12 5c  7a 56 fc f5 06 bf fa 58  |.,.3...\zV.....X|
-00000170  7b 26 3f b5 cd 04 d3 d0  c9 21 96 4a c7 f4 54 9f  |{&?......!.J..T.|
-00000180  5a bf ef 42 71 00 fe 18  99 07 7f 7e 88 7d 7d f1  |Z..Bq......~.}}.|
-00000190  04 39 c4 a2 2e db 51 c9  7c e3 c0 4c 3b 32 66 01  |.9....Q.|..L;2f.|
-000001a0  cf af b1 1d b8 71 9a 1d  db db 89 6b ae da 2d 79  |.....q.....k..-y|
-000001b0  02 03 01 00 01 a3 81 a7  30 81 a4 30 1d 06 03 55  |........0..0...U|
-000001c0  1d 0e 04 16 04 14 b1 ad  e2 85 5a cf cb 28 db 69  |..........Z..(.i|
-000001d0  ce 23 69 de d3 26 8e 18  88 39 30 75 06 03 55 1d  |.#i..&...90u..U.|
-000001e0  23 04 6e 30 6c 80 14 b1  ad e2 85 5a cf cb 28 db  |#.n0l......Z..(.|
-000001f0  69 ce 23 69 de d3 26 8e  18 88 39 a1 49 a4 47 30  |i.#i..&...9.I.G0|
-00000200  45 31 0b 30 09 06 03 55  04 06 13 02 41 55 31 13  |E1.0...U....AU1.|
-00000210  30 11 06 03 55 04 08 13  0a 53 6f 6d 65 2d 53 74  |0...U....Some-St|
-00000220  61 74 65 31 21 30 1f 06  03 55 04 0a 13 18 49 6e  |ate1!0...U....In|
-00000230  74 65 72 6e 65 74 20 57  69 64 67 69 74 73 20 50  |ternet Widgits P|
-00000240  74 79 20 4c 74 64 82 09  00 85 b0 bb a4 8a 7f b8  |ty Ltd..........|
-00000250  ca 30 0c 06 03 55 1d 13  04 05 30 03 01 01 ff 30  |.0...U....0....0|
-00000260  0d 06 09 2a 86 48 86 f7  0d 01 01 05 05 00 03 81  |...*.H..........|
-00000270  81 00 08 6c 45 24 c7 6b  b1 59 ab 0c 52 cc f2 b0  |...lE$.k.Y..R...|
-00000280  14 d7 87 9d 7a 64 75 b5  5a 95 66 e4 c5 2b 8e ae  |....zdu.Z.f..+..|
-00000290  12 66 1f eb 4f 38 b3 6e  60 d3 92 fd f7 41 08 b5  |.f..O8.n`....A..|
-000002a0  25 13 b1 18 7a 24 fb 30  1d ba ed 98 b9 17 ec e7  |%...z$.0........|
-000002b0  d7 31 59 db 95 d3 1d 78  ea 50 56 5c d5 82 5a 2d  |.1Y....x.PV\..Z-|
-000002c0  5a 5f 33 c4 b6 d8 c9 75  90 96 8c 0f 52 98 b5 cd  |Z_3....u....R...|
-000002d0  98 1f 89 20 5f f2 a0 1c  a3 1b 96 94 dd a9 fd 57  |... _..........W|
-000002e0  e9 70 e8 26 6d 71 99 9b  26 6e 38 50 29 6c 90 a7  |.p.&mq..&n8P)l..|
-000002f0  bd d9 16 03 03 00 04 0e  00 00 00                 |...........|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 2f 00 00  |............./..|
+00000030  05 ff 01 00 01 00 16 03  03 02 be 0b 00 02 ba 00  |................|
+00000040  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
+00000050  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
+00000060  09 2a 86 48 86 f7 0d 01  01 05 05 00 30 45 31 0b  |.*.H........0E1.|
+00000070  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
+00000080  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
+00000090  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
+000000a0  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
+000000b0  4c 74 64 30 1e 17 0d 31  30 30 34 32 34 30 39 30  |Ltd0...100424090|
+000000c0  39 33 38 5a 17 0d 31 31  30 34 32 34 30 39 30 39  |938Z..1104240909|
+000000d0  33 38 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |38Z0E1.0...U....|
+000000e0  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
+000000f0  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
+00000100  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
+00000110  74 73 20 50 74 79 20 4c  74 64 30 81 9f 30 0d 06  |ts Pty Ltd0..0..|
+00000120  09 2a 86 48 86 f7 0d 01  01 01 05 00 03 81 8d 00  |.*.H............|
+00000130  30 81 89 02 81 81 00 bb  79 d6 f5 17 b5 e5 bf 46  |0.......y......F|
+00000140  10 d0 dc 69 be e6 2b 07  43 5a d0 03 2d 8a 7a 43  |...i..+.CZ..-.zC|
+00000150  85 b7 14 52 e7 a5 65 4c  2c 78 b8 23 8c b5 b4 82  |...R..eL,x.#....|
+00000160  e5 de 1f 95 3b 7e 62 a5  2c a5 33 d6 fe 12 5c 7a  |....;~b.,.3...\z|
+00000170  56 fc f5 06 bf fa 58 7b  26 3f b5 cd 04 d3 d0 c9  |V.....X{&?......|
+00000180  21 96 4a c7 f4 54 9f 5a  bf ef 42 71 00 fe 18 99  |!.J..T.Z..Bq....|
+00000190  07 7f 7e 88 7d 7d f1 04  39 c4 a2 2e db 51 c9 7c  |..~.}}..9....Q.||
+000001a0  e3 c0 4c 3b 32 66 01 cf  af b1 1d b8 71 9a 1d db  |..L;2f......q...|
+000001b0  db 89 6b ae da 2d 79 02  03 01 00 01 a3 81 a7 30  |..k..-y........0|
+000001c0  81 a4 30 1d 06 03 55 1d  0e 04 16 04 14 b1 ad e2  |..0...U.........|
+000001d0  85 5a cf cb 28 db 69 ce  23 69 de d3 26 8e 18 88  |.Z..(.i.#i..&...|
+000001e0  39 30 75 06 03 55 1d 23  04 6e 30 6c 80 14 b1 ad  |90u..U.#.n0l....|
+000001f0  e2 85 5a cf cb 28 db 69  ce 23 69 de d3 26 8e 18  |..Z..(.i.#i..&..|
+00000200  88 39 a1 49 a4 47 30 45  31 0b 30 09 06 03 55 04  |.9.I.G0E1.0...U.|
+00000210  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
+00000220  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
+00000230  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
+00000240  64 67 69 74 73 20 50 74  79 20 4c 74 64 82 09 00  |dgits Pty Ltd...|
+00000250  85 b0 bb a4 8a 7f b8 ca  30 0c 06 03 55 1d 13 04  |........0...U...|
+00000260  05 30 03 01 01 ff 30 0d  06 09 2a 86 48 86 f7 0d  |.0....0...*.H...|
+00000270  01 01 05 05 00 03 81 81  00 08 6c 45 24 c7 6b b1  |..........lE$.k.|
+00000280  59 ab 0c 52 cc f2 b0 14  d7 87 9d 7a 64 75 b5 5a  |Y..R.......zdu.Z|
+00000290  95 66 e4 c5 2b 8e ae 12  66 1f eb 4f 38 b3 6e 60  |.f..+...f..O8.n`|
+000002a0  d3 92 fd f7 41 08 b5 25  13 b1 18 7a 24 fb 30 1d  |....A..%...z$.0.|
+000002b0  ba ed 98 b9 17 ec e7 d7  31 59 db 95 d3 1d 78 ea  |........1Y....x.|
+000002c0  50 56 5c d5 82 5a 2d 5a  5f 33 c4 b6 d8 c9 75 90  |PV\..Z-Z_3....u.|
+000002d0  96 8c 0f 52 98 b5 cd 98  1f 89 20 5f f2 a0 1c a3  |...R...... _....|
+000002e0  1b 96 94 dd a9 fd 57 e9  70 e8 26 6d 71 99 9b 26  |......W.p.&mq..&|
+000002f0  6e 38 50 29 6c 90 a7 bd  d9 16 03 03 00 04 0e 00  |n8P)l...........|
+00000300  00 00                                             |..|
 >>> Flow 3 (client to server)
-00000000  16 03 03 00 86 10 00 00  82 00 80 67 83 ea ad 9c  |...........g....|
-00000010  e6 e0 e6 39 39 8a f4 1d  b0 da 2e a0 de 44 b1 92  |...99........D..|
-00000020  2a ca 64 cb e5 d2 d4 40  f9 a6 ec 12 fc 00 97 8a  |*.d....@........|
-00000030  9c bb b6 e3 55 06 93 af  3f 70 53 2a c8 93 fe 08  |....U...?pS*....|
-00000040  1a bf 92 a9 64 71 36 55  f4 7b a3 08 59 05 8d 69  |....dq6U.{..Y..i|
-00000050  e2 6d 1a d8 97 2e b9 f1  f4 16 63 6e c4 28 59 44  |.m........cn.(YD|
-00000060  5b 53 84 11 2b f6 bd 41  21 9e cc 3e c3 9a 17 8e  |[S..+..A!..>....|
-00000070  53 92 b7 cf 45 dc f3 0c  2d f2 dd 0b a2 6c 34 ab  |S...E...-....l4.|
-00000080  05 e2 48 1a 83 60 dc 8e  f7 bc 3a 14 03 03 00 01  |..H..`....:.....|
-00000090  01 16 03 03 00 40 c8 19  88 56 0b fd 75 d9 e9 7a  |.....@...V..u..z|
-000000a0  38 04 37 e3 74 fc af 7b  b6 2b d8 93 da 25 ba 14  |8.7.t..{.+...%..|
-000000b0  3b 5e ef 19 c5 45 fd cf  b4 f5 ce a5 ee 8a 9b cc  |;^...E..........|
-000000c0  52 17 87 3c c7 9f 56 72  f3 e1 03 e4 db d5 24 6a  |R..<..Vr......$j|
-000000d0  08 de 9b fd a5 2c                                 |.....,|
+00000000  16 03 03 00 86 10 00 00  82 00 80 4b b4 28 bc 78  |...........K.(.x|
+00000010  41 34 f3 49 e8 74 07 74  42 ae 2e 55 9e 9a ce e5  |A4.I.t.tB..U....|
+00000020  4a 1b e7 55 c7 64 c4 9c  b3 dd 20 d6 f8 8e 67 b3  |J..U.d.... ...g.|
+00000030  7a 5c 3b 34 e4 1a f6 bd  65 fc 21 cd 9a de 64 77  |z\;4....e.!...dw|
+00000040  09 a5 92 e5 a4 f5 18 7b  23 5b 8b c1 95 23 97 6f  |.......{#[...#.o|
+00000050  76 55 04 34 22 7d 43 71  db cd eb f8 36 36 44 4b  |vU.4"}Cq....66DK|
+00000060  ae e3 cc ec 64 88 7b e1  ea d6 ab 49 35 94 a5 04  |....d.{....I5...|
+00000070  1e 83 c5 cf 21 bb ca 33  5f d4 bf 1d d3 4d 07 59  |....!..3_....M.Y|
+00000080  b4 39 b2 4b 7b 05 43 70  0d ba 7a 14 03 03 00 01  |.9.K{.Cp..z.....|
+00000090  01 16 03 03 00 40 74 4b  7d b2 53 49 ea 86 90 c3  |.....@tK}.SI....|
+000000a0  64 6b 64 31 1a 2a 3f 1a  37 1e 56 b8 dd 12 6d 56  |dkd1.*?.7.V...mV|
+000000b0  2a 61 92 5b 39 e7 e1 be  71 70 4b 9b b3 f0 71 e7  |*a.[9...qpK...q.|
+000000c0  47 2e 2e 17 c3 0a 66 9f  69 74 30 2d f0 a0 7f 84  |G.....f.it0-....|
+000000d0  25 db c1 81 ee cf                                 |%.....|
 >>> Flow 4 (server to client)
 00000000  14 03 03 00 01 01 16 03  03 00 40 00 00 00 00 00  |..........@.....|
-00000010  00 00 00 00 00 00 00 00  00 00 00 c9 7d ec 45 ce  |............}.E.|
-00000020  b9 e1 3b 11 02 44 56 cf  86 61 44 64 0c 00 5a 9e  |..;..DV..aDd..Z.|
-00000030  f0 37 cc 56 6a 13 f7 81  67 f3 78 a2 53 a6 5c b5  |.7.Vj...g.x.S.\.|
-00000040  0f cc 5b f0 c3 6c 2d cb  48 e1 e4 17 03 03 00 40  |..[..l-.H......@|
+00000010  00 00 00 00 00 00 00 00  00 00 00 f3 4d 5a fc 21  |............MZ.!|
+00000020  30 b5 a1 86 9d e2 ea 38  ac 54 57 fa 5a 54 97 b8  |0......8.TW.ZT..|
+00000030  bb 4d 64 09 ef ce a1 75  0c 50 8d ff 5c c2 e9 47  |.Md....u.P..\..G|
+00000040  95 93 53 c0 bd dc c5 9c  e0 59 17 17 03 03 00 40  |..S......Y.....@|
 00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000060  6d 27 67 8e 44 ed c2 6b  e7 a8 f5 ab c9 5d a5 a6  |m'g.D..k.....]..|
-00000070  da f0 ae 72 2c 95 75 00  fb e3 94 6e b7 8f e7 44  |...r,.u....n...D|
-00000080  69 37 8c aa 7f 8d 63 5b  03 1d 8e 64 1a 75 72 cb  |i7....c[...d.ur.|
+00000060  69 c5 48 6e 45 cf 98 1b  2c 23 40 d1 ab a3 c2 e2  |i.HnE...,#@.....|
+00000070  10 7b b1 c8 21 3c f0 eb  96 bd 4f 78 b2 4a 7b 18  |.{..!<....Ox.J{.|
+00000080  4c b1 a6 67 bf 06 40 01  d0 8d 91 be 17 d8 0c 71  |L..g..@........q|
 00000090  15 03 03 00 30 00 00 00  00 00 00 00 00 00 00 00  |....0...........|
-000000a0  00 00 00 00 00 5e f4 e5  ae 1f f9 37 b7 14 26 cc  |.....^.....7..&.|
-000000b0  b0 07 f4 61 60 03 2d e3  ff f2 85 bf 1c 74 74 e2  |...a`.-......tt.|
-000000c0  db 0b e3 5f 62                                    |..._b|
+000000a0  00 00 00 00 00 20 84 80  3d 70 fe ae ee d7 2f e9  |..... ..=p..../.|
+000000b0  bf 65 30 bf 0b dd 98 ea  bb ba 12 14 98 53 7f d5  |.e0..........S..|
+000000c0  56 ce 06 3c d0                                    |V..<.|
index 54ad7474120b100b23be27b6c1db35c8542916c6..6f7e0e40ab1c1b68c8789cc22bfb0da53abbb5f9 100644 (file)
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 9d 01 00 00  99 03 03 52 ac 77 f8 7a  |...........R.w.z|
-00000010  f5 85 72 ff ef a8 58 b7  be 86 38 82 c7 dd 79 f7  |..r...X...8...y.|
-00000020  78 20 05 9d cf 1b 44 71  92 ab b8 00 00 04 c0 2f  |x ....Dq......./|
-00000030  00 ff 02 01 00 00 6b 00  0b 00 04 03 00 01 02 00  |......k.........|
-00000040  0a 00 34 00 32 00 0e 00  0d 00 19 00 0b 00 0c 00  |..4.2...........|
-00000050  18 00 09 00 0a 00 16 00  17 00 08 00 06 00 07 00  |................|
-00000060  14 00 15 00 04 00 05 00  12 00 13 00 01 00 02 00  |................|
-00000070  03 00 0f 00 10 00 11 00  0d 00 22 00 20 06 01 06  |..........". ...|
-00000080  02 06 03 05 01 05 02 05  03 04 01 04 02 04 03 03  |................|
-00000090  01 03 02 03 03 02 01 02  02 02 03 01 01 00 0f 00  |................|
-000000a0  01 01                                             |..|
+00000000  16 03 01 00 9c 01 00 00  98 03 03 52 cc 57 59 d3  |...........R.WY.|
+00000010  91 67 1b de 52 be 25 1d  61 3b 45 29 43 aa 8a e9  |.g..R.%.a;E)C...|
+00000020  fc 29 19 d5 59 aa 48 0d  21 8a eb 00 00 04 c0 2f  |.)..Y.H.!....../|
+00000030  00 ff 01 00 00 6b 00 0b  00 04 03 00 01 02 00 0a  |.....k..........|
+00000040  00 34 00 32 00 0e 00 0d  00 19 00 0b 00 0c 00 18  |.4.2............|
+00000050  00 09 00 0a 00 16 00 17  00 08 00 06 00 07 00 14  |................|
+00000060  00 15 00 04 00 05 00 12  00 13 00 01 00 02 00 03  |................|
+00000070  00 0f 00 10 00 11 00 0d  00 22 00 20 06 01 06 02  |.........". ....|
+00000080  06 03 05 01 05 02 05 03  04 01 04 02 04 03 03 01  |................|
+00000090  03 02 03 03 02 01 02 02  02 03 01 01 00 0f 00 01  |................|
+000000a0  01                                                |.|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 2a 02 00 00  26 03 03 00 00 00 00 00  |....*...&.......|
+00000000  16 03 03 00 31 02 00 00  2d 03 03 00 00 00 00 00  |....1...-.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 c0 2f 00 16  |............./..|
-00000030  03 03 02 be 0b 00 02 ba  00 02 b7 00 02 b4 30 82  |..............0.|
-00000040  02 b0 30 82 02 19 a0 03  02 01 02 02 09 00 85 b0  |..0.............|
-00000050  bb a4 8a 7f b8 ca 30 0d  06 09 2a 86 48 86 f7 0d  |......0...*.H...|
-00000060  01 01 05 05 00 30 45 31  0b 30 09 06 03 55 04 06  |.....0E1.0...U..|
-00000070  13 02 41 55 31 13 30 11  06 03 55 04 08 13 0a 53  |..AU1.0...U....S|
-00000080  6f 6d 65 2d 53 74 61 74  65 31 21 30 1f 06 03 55  |ome-State1!0...U|
-00000090  04 0a 13 18 49 6e 74 65  72 6e 65 74 20 57 69 64  |....Internet Wid|
-000000a0  67 69 74 73 20 50 74 79  20 4c 74 64 30 1e 17 0d  |gits Pty Ltd0...|
-000000b0  31 30 30 34 32 34 30 39  30 39 33 38 5a 17 0d 31  |100424090938Z..1|
-000000c0  31 30 34 32 34 30 39 30  39 33 38 5a 30 45 31 0b  |10424090938Z0E1.|
-000000d0  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-000000e0  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-000000f0  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-00000100  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-00000110  4c 74 64 30 81 9f 30 0d  06 09 2a 86 48 86 f7 0d  |Ltd0..0...*.H...|
-00000120  01 01 01 05 00 03 81 8d  00 30 81 89 02 81 81 00  |.........0......|
-00000130  bb 79 d6 f5 17 b5 e5 bf  46 10 d0 dc 69 be e6 2b  |.y......F...i..+|
-00000140  07 43 5a d0 03 2d 8a 7a  43 85 b7 14 52 e7 a5 65  |.CZ..-.zC...R..e|
-00000150  4c 2c 78 b8 23 8c b5 b4  82 e5 de 1f 95 3b 7e 62  |L,x.#........;~b|
-00000160  a5 2c a5 33 d6 fe 12 5c  7a 56 fc f5 06 bf fa 58  |.,.3...\zV.....X|
-00000170  7b 26 3f b5 cd 04 d3 d0  c9 21 96 4a c7 f4 54 9f  |{&?......!.J..T.|
-00000180  5a bf ef 42 71 00 fe 18  99 07 7f 7e 88 7d 7d f1  |Z..Bq......~.}}.|
-00000190  04 39 c4 a2 2e db 51 c9  7c e3 c0 4c 3b 32 66 01  |.9....Q.|..L;2f.|
-000001a0  cf af b1 1d b8 71 9a 1d  db db 89 6b ae da 2d 79  |.....q.....k..-y|
-000001b0  02 03 01 00 01 a3 81 a7  30 81 a4 30 1d 06 03 55  |........0..0...U|
-000001c0  1d 0e 04 16 04 14 b1 ad  e2 85 5a cf cb 28 db 69  |..........Z..(.i|
-000001d0  ce 23 69 de d3 26 8e 18  88 39 30 75 06 03 55 1d  |.#i..&...90u..U.|
-000001e0  23 04 6e 30 6c 80 14 b1  ad e2 85 5a cf cb 28 db  |#.n0l......Z..(.|
-000001f0  69 ce 23 69 de d3 26 8e  18 88 39 a1 49 a4 47 30  |i.#i..&...9.I.G0|
-00000200  45 31 0b 30 09 06 03 55  04 06 13 02 41 55 31 13  |E1.0...U....AU1.|
-00000210  30 11 06 03 55 04 08 13  0a 53 6f 6d 65 2d 53 74  |0...U....Some-St|
-00000220  61 74 65 31 21 30 1f 06  03 55 04 0a 13 18 49 6e  |ate1!0...U....In|
-00000230  74 65 72 6e 65 74 20 57  69 64 67 69 74 73 20 50  |ternet Widgits P|
-00000240  74 79 20 4c 74 64 82 09  00 85 b0 bb a4 8a 7f b8  |ty Ltd..........|
-00000250  ca 30 0c 06 03 55 1d 13  04 05 30 03 01 01 ff 30  |.0...U....0....0|
-00000260  0d 06 09 2a 86 48 86 f7  0d 01 01 05 05 00 03 81  |...*.H..........|
-00000270  81 00 08 6c 45 24 c7 6b  b1 59 ab 0c 52 cc f2 b0  |...lE$.k.Y..R...|
-00000280  14 d7 87 9d 7a 64 75 b5  5a 95 66 e4 c5 2b 8e ae  |....zdu.Z.f..+..|
-00000290  12 66 1f eb 4f 38 b3 6e  60 d3 92 fd f7 41 08 b5  |.f..O8.n`....A..|
-000002a0  25 13 b1 18 7a 24 fb 30  1d ba ed 98 b9 17 ec e7  |%...z$.0........|
-000002b0  d7 31 59 db 95 d3 1d 78  ea 50 56 5c d5 82 5a 2d  |.1Y....x.PV\..Z-|
-000002c0  5a 5f 33 c4 b6 d8 c9 75  90 96 8c 0f 52 98 b5 cd  |Z_3....u....R...|
-000002d0  98 1f 89 20 5f f2 a0 1c  a3 1b 96 94 dd a9 fd 57  |... _..........W|
-000002e0  e9 70 e8 26 6d 71 99 9b  26 6e 38 50 29 6c 90 a7  |.p.&mq..&n8P)l..|
-000002f0  bd d9 16 03 03 01 11 0c  00 01 0d 03 00 19 85 04  |................|
-00000300  01 39 dc ee 44 17 5e db  d7 27 af b6 56 d9 b4 43  |.9..D.^..'..V..C|
-00000310  5a 99 cf aa 31 37 0c 6f  3a a0 f8 53 c4 74 d1 91  |Z...17.o:..S.t..|
-00000320  0a 46 f5 38 3b 5c 09 d8  97 dc 4b aa 70 26 48 f2  |.F.8;\....K.p&H.|
-00000330  d6 0b 31 c9 f8 d4 98 43  e1 6c d5 c7 b2 8e 0b 01  |..1....C.l......|
-00000340  e6 b6 00 28 80 7b fc 96  8f 0d a2 4f b0 79 af dc  |...(.{.....O.y..|
-00000350  61 28 63 33 78 f6 31 39  fd 8a f4 15 18 11 fe db  |a(c3x.19........|
-00000360  d5 07 da 2c ed 49 a0 23  bf d0 3a 38 1d 54 ae 1c  |...,.I.#..:8.T..|
-00000370  7b ea 29 ee d0 38 c1 76  a7 7f 2a f4 ce 1e ac cc  |{.)..8.v..*.....|
-00000380  94 79 90 33 04 01 00 80  11 d6 f6 f9 49 4c ad d6  |.y.3........IL..|
-00000390  c6 50 3f 8d 28 d2 9b 32  8c c8 14 b4 75 22 81 8f  |.P?.(..2....u"..|
-000003a0  b9 dc 0b 5e 71 7a eb 15  1a 8e 50 fb 03 f0 42 de  |...^qz....P...B.|
-000003b0  06 bb d7 28 c7 b3 c5 23  2d 29 11 01 5e 03 3b 2f  |...(...#-)..^.;/|
-000003c0  3c e0 5c 26 b2 15 95 e3  30 35 1f 79 9b de a5 ee  |<.\&....05.y....|
-000003d0  01 35 14 22 c3 7f 0f 30  75 9d ec 94 bd 17 08 1a  |.5."...0u.......|
-000003e0  96 b5 7a 16 39 58 ce 96  aa 90 06 19 1b d5 64 13  |..z.9X........d.|
-000003f0  49 9f c6 84 e8 22 5c 5c  cc f9 90 75 75 ef 33 94  |I...."\\...uu.3.|
-00000400  6b 76 8a b7 c0 9a 34 aa  16 03 03 00 04 0e 00 00  |kv....4.........|
-00000410  00                                                |.|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 c0 2f 00 00  |............./..|
+00000030  05 ff 01 00 01 00 16 03  03 02 be 0b 00 02 ba 00  |................|
+00000040  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
+00000050  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
+00000060  09 2a 86 48 86 f7 0d 01  01 05 05 00 30 45 31 0b  |.*.H........0E1.|
+00000070  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
+00000080  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
+00000090  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
+000000a0  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
+000000b0  4c 74 64 30 1e 17 0d 31  30 30 34 32 34 30 39 30  |Ltd0...100424090|
+000000c0  39 33 38 5a 17 0d 31 31  30 34 32 34 30 39 30 39  |938Z..1104240909|
+000000d0  33 38 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |38Z0E1.0...U....|
+000000e0  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
+000000f0  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
+00000100  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
+00000110  74 73 20 50 74 79 20 4c  74 64 30 81 9f 30 0d 06  |ts Pty Ltd0..0..|
+00000120  09 2a 86 48 86 f7 0d 01  01 01 05 00 03 81 8d 00  |.*.H............|
+00000130  30 81 89 02 81 81 00 bb  79 d6 f5 17 b5 e5 bf 46  |0.......y......F|
+00000140  10 d0 dc 69 be e6 2b 07  43 5a d0 03 2d 8a 7a 43  |...i..+.CZ..-.zC|
+00000150  85 b7 14 52 e7 a5 65 4c  2c 78 b8 23 8c b5 b4 82  |...R..eL,x.#....|
+00000160  e5 de 1f 95 3b 7e 62 a5  2c a5 33 d6 fe 12 5c 7a  |....;~b.,.3...\z|
+00000170  56 fc f5 06 bf fa 58 7b  26 3f b5 cd 04 d3 d0 c9  |V.....X{&?......|
+00000180  21 96 4a c7 f4 54 9f 5a  bf ef 42 71 00 fe 18 99  |!.J..T.Z..Bq....|
+00000190  07 7f 7e 88 7d 7d f1 04  39 c4 a2 2e db 51 c9 7c  |..~.}}..9....Q.||
+000001a0  e3 c0 4c 3b 32 66 01 cf  af b1 1d b8 71 9a 1d db  |..L;2f......q...|
+000001b0  db 89 6b ae da 2d 79 02  03 01 00 01 a3 81 a7 30  |..k..-y........0|
+000001c0  81 a4 30 1d 06 03 55 1d  0e 04 16 04 14 b1 ad e2  |..0...U.........|
+000001d0  85 5a cf cb 28 db 69 ce  23 69 de d3 26 8e 18 88  |.Z..(.i.#i..&...|
+000001e0  39 30 75 06 03 55 1d 23  04 6e 30 6c 80 14 b1 ad  |90u..U.#.n0l....|
+000001f0  e2 85 5a cf cb 28 db 69  ce 23 69 de d3 26 8e 18  |..Z..(.i.#i..&..|
+00000200  88 39 a1 49 a4 47 30 45  31 0b 30 09 06 03 55 04  |.9.I.G0E1.0...U.|
+00000210  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
+00000220  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
+00000230  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
+00000240  64 67 69 74 73 20 50 74  79 20 4c 74 64 82 09 00  |dgits Pty Ltd...|
+00000250  85 b0 bb a4 8a 7f b8 ca  30 0c 06 03 55 1d 13 04  |........0...U...|
+00000260  05 30 03 01 01 ff 30 0d  06 09 2a 86 48 86 f7 0d  |.0....0...*.H...|
+00000270  01 01 05 05 00 03 81 81  00 08 6c 45 24 c7 6b b1  |..........lE$.k.|
+00000280  59 ab 0c 52 cc f2 b0 14  d7 87 9d 7a 64 75 b5 5a  |Y..R.......zdu.Z|
+00000290  95 66 e4 c5 2b 8e ae 12  66 1f eb 4f 38 b3 6e 60  |.f..+...f..O8.n`|
+000002a0  d3 92 fd f7 41 08 b5 25  13 b1 18 7a 24 fb 30 1d  |....A..%...z$.0.|
+000002b0  ba ed 98 b9 17 ec e7 d7  31 59 db 95 d3 1d 78 ea  |........1Y....x.|
+000002c0  50 56 5c d5 82 5a 2d 5a  5f 33 c4 b6 d8 c9 75 90  |PV\..Z-Z_3....u.|
+000002d0  96 8c 0f 52 98 b5 cd 98  1f 89 20 5f f2 a0 1c a3  |...R...... _....|
+000002e0  1b 96 94 dd a9 fd 57 e9  70 e8 26 6d 71 99 9b 26  |......W.p.&mq..&|
+000002f0  6e 38 50 29 6c 90 a7 bd  d9 16 03 03 01 11 0c 00  |n8P)l...........|
+00000300  01 0d 03 00 19 85 04 01  39 dc ee 44 17 5e db d7  |........9..D.^..|
+00000310  27 af b6 56 d9 b4 43 5a  99 cf aa 31 37 0c 6f 3a  |'..V..CZ...17.o:|
+00000320  a0 f8 53 c4 74 d1 91 0a  46 f5 38 3b 5c 09 d8 97  |..S.t...F.8;\...|
+00000330  dc 4b aa 70 26 48 f2 d6  0b 31 c9 f8 d4 98 43 e1  |.K.p&H...1....C.|
+00000340  6c d5 c7 b2 8e 0b 01 e6  b6 00 28 80 7b fc 96 8f  |l.........(.{...|
+00000350  0d a2 4f b0 79 af dc 61  28 63 33 78 f6 31 39 fd  |..O.y..a(c3x.19.|
+00000360  8a f4 15 18 11 fe db d5  07 da 2c ed 49 a0 23 bf  |..........,.I.#.|
+00000370  d0 3a 38 1d 54 ae 1c 7b  ea 29 ee d0 38 c1 76 a7  |.:8.T..{.)..8.v.|
+00000380  7f 2a f4 ce 1e ac cc 94  79 90 33 04 01 00 80 5f  |.*......y.3...._|
+00000390  c6 9e 6d 87 97 04 b5 c2  12 73 75 ff a5 40 d0 0f  |..m......su..@..|
+000003a0  39 74 98 e5 1f 62 4c e8  9a af a0 d4 08 61 d4 53  |9t...bL......a.S|
+000003b0  67 ee f6 27 45 1a ee 52  35 7a 5f 5b 54 4a de 9b  |g..'E..R5z_[TJ..|
+000003c0  fb 9a a2 61 e1 db be b0  08 5d 4f fc b5 5d d3 bc  |...a.....]O..]..|
+000003d0  c9 49 e2 b9 d8 52 52 79  d1 a3 8e da 7d 35 12 19  |.I...RRy....}5..|
+000003e0  45 30 fb fd e7 e2 f4 00  43 78 64 ca 2b 6c 65 28  |E0......Cxd.+le(|
+000003f0  8a 8d 83 4f cf 44 9a 19  89 4d 08 d8 85 b3 65 95  |...O.D...M....e.|
+00000400  e8 47 4d 86 25 48 09 5c  77 7d 73 0c 6b 22 22 16  |.GM.%H.\w}s.k"".|
+00000410  03 03 00 04 0e 00 00 00                           |........|
 >>> Flow 3 (client to server)
-00000000  16 03 03 00 8a 10 00 00  86 85 04 01 bf 6a c6 3e  |.............j.>|
-00000010  39 bb 08 d0 2a 07 fd d9  9a 61 5d 0f ca e5 26 80  |9...*....a]...&.|
-00000020  09 45 b9 34 2d e8 1b 8f  9c 6f b3 c0 2b a3 48 46  |.E.4-....o..+.HF|
-00000030  ce a5 6c b9 16 0f 26 ca  65 00 11 e3 6d ff 18 89  |..l...&.e...m...|
-00000040  5d 0d 4a 94 1b a5 c7 35  59 72 a8 2d 08 01 e2 5e  |].J....5Yr.-...^|
-00000050  d8 12 2d f6 6c d2 0a b1  df d2 5a 13 5c 29 fb 59  |..-.l.....Z.\).Y|
-00000060  fc 2a 77 81 73 dd 86 4a  00 8c 61 a0 e4 b3 ae 6e  |.*w.s..J..a....n|
-00000070  7a 59 bf a2 61 7d 10 ca  4b a0 b3 70 b0 0b 77 09  |zY..a}..K..p..w.|
-00000080  6c 6c 3c b5 b0 65 4a 35  de c5 88 f0 17 b1 4a 14  |ll<..eJ5......J.|
-00000090  03 03 00 01 01 16 03 03  00 28 4a d7 fe 68 74 b5  |.........(J..ht.|
-000000a0  3d 9d 40 33 2a 96 4e 60  d6 d0 ae 2a c5 c8 51 f5  |=.@3*.N`...*..Q.|
-000000b0  aa 54 9b b4 99 56 a4 fe  06 5b 94 6a be 9b aa fa  |.T...V...[.j....|
-000000c0  15 83                                             |..|
+00000000  16 03 03 00 8a 10 00 00  86 85 04 01 4e f2 1d 1f  |............N...|
+00000010  c0 23 cf 00 58 0b 25 ee  6b e1 5f 50 7b c9 15 9d  |.#..X.%.k._P{...|
+00000020  d9 2f 8a f1 b8 7b 62 d2  6d d0 46 b8 6f 3f 2d 6f  |./...{b.m.F.o?-o|
+00000030  ba 68 74 7e a3 b5 12 1c  93 d1 0a 13 e1 50 d7 82  |.ht~.........P..|
+00000040  1b 4c 54 b5 73 a9 9e 72  80 4e bc 75 17 00 e1 f3  |.LT.s..r.N.u....|
+00000050  70 03 80 1f d3 1f 2a 53  52 6a ee 4e 93 f4 10 1c  |p.....*SRj.N....|
+00000060  2d ff 5f 6c a4 3b fa a1  7f 87 93 5d 76 b3 35 62  |-._l.;.....]v.5b|
+00000070  0b 48 41 42 f9 57 65 4a  42 9e 53 7d 2c 09 37 02  |.HAB.WeJB.S},.7.|
+00000080  55 bd 6f 0e 4d 05 17 8d  c5 df ff 54 da 94 d6 14  |U.o.M......T....|
+00000090  03 03 00 01 01 16 03 03  00 28 38 e3 ad 08 8e e3  |.........(8.....|
+000000a0  b8 bc 6d a2 15 35 b1 b2  28 47 82 63 30 9e b6 5c  |..m..5..(G.c0..\|
+000000b0  26 47 38 20 a0 77 e3 b2  38 8f 8b c4 96 ac f4 5c  |&G8 .w..8......\|
+000000c0  10 9f                                             |..|
 >>> Flow 4 (server to client)
 00000000  14 03 03 00 01 01 16 03  03 00 28 00 00 00 00 00  |..........(.....|
-00000010  00 00 00 dc 64 82 fd 0e  fc b5 a4 e0 7b 8d 62 69  |....d.......{.bi|
-00000020  6e 03 35 a6 6b 0e 19 53  7e 87 e5 fe 7b 78 e6 27  |n.5.k..S~...{x.'|
-00000030  fa 31 7d 17 03 03 00 25  00 00 00 00 00 00 00 01  |.1}....%........|
-00000040  8e 5d 8d 1c a1 07 a4 ed  d1 e2 35 28 d3 8d 47 ec  |.]........5(..G.|
-00000050  d2 67 31 c2 88 5c 23 f8  6b d1 bd a9 0b 15 03 03  |.g1..\#.k.......|
-00000060  00 1a 00 00 00 00 00 00  00 02 3e 14 30 85 89 e0  |..........>.0...|
-00000070  19 3c 0a dc 80 3f c1 28  65 12 f7 38              |.<...?.(e..8|
+00000010  00 00 00 30 ae 4d 36 49  d1 d6 4d 1a 71 87 eb ed  |...0.M6I..M.q...|
+00000020  d2 6f 66 3f 25 03 a5 69  04 5d ca e6 71 eb c2 06  |.of?%..i.]..q...|
+00000030  b4 15 b7 17 03 03 00 25  00 00 00 00 00 00 00 01  |.......%........|
+00000040  8d a6 27 08 34 77 a2 a7  f5 e6 c3 ca 49 25 db 9a  |..'.4w......I%..|
+00000050  19 44 42 d1 0b c1 3a d6  73 b2 11 df 52 15 03 03  |.DB...:.s...R...|
+00000060  00 1a 00 00 00 00 00 00  00 02 42 63 43 f7 98 69  |..........BcC..i|
+00000070  d9 2b 38 6b 88 9d bf a2  8a 31 5d 54              |.+8k.....1]T|
index d5cf4e4232b47548d619b3061f19d2579308431f..b703a8f766c28ebc11b8d4a563b439206eba2eee 100644 (file)
@@ -1,78 +1,79 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 5d 01 00 00  59 03 03 52 ac 77 f8 36  |....]...Y..R.w.6|
-00000010  6c 14 4d a5 96 7f 9f 63  56 81 2f ef 2b e8 4c 9d  |l.M....cV./.+.L.|
-00000020  04 92 ba 6c 99 29 47 f3  b5 22 46 00 00 04 00 05  |...l.)G.."F.....|
-00000030  00 ff 02 01 00 00 2b 00  0d 00 22 00 20 06 01 06  |......+...". ...|
-00000040  02 06 03 05 01 05 02 05  03 04 01 04 02 04 03 03  |................|
-00000050  01 03 02 03 03 02 01 02  02 02 03 01 01 00 0f 00  |................|
-00000060  01 01                                             |..|
+00000000  16 03 01 00 5c 01 00 00  58 03 03 52 cc 57 59 c9  |....\...X..R.WY.|
+00000010  c3 13 fc 18 8a ee c2 0e  88 ff fb 4a 16 f2 eb eb  |...........J....|
+00000020  d4 f8 b3 5b cd bb 25 0e  0b cb 48 00 00 04 00 05  |...[..%...H.....|
+00000030  00 ff 01 00 00 2b 00 0d  00 22 00 20 06 01 06 02  |.....+...". ....|
+00000040  06 03 05 01 05 02 05 03  04 01 04 02 04 03 03 01  |................|
+00000050  03 02 03 03 02 01 02 02  02 03 01 01 00 0f 00 01  |................|
+00000060  01                                                |.|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 2a 02 00 00  26 03 03 00 00 00 00 00  |....*...&.......|
+00000000  16 03 03 00 31 02 00 00  2d 03 03 00 00 00 00 00  |....1...-.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 05 00 16  |................|
-00000030  03 03 02 be 0b 00 02 ba  00 02 b7 00 02 b4 30 82  |..............0.|
-00000040  02 b0 30 82 02 19 a0 03  02 01 02 02 09 00 85 b0  |..0.............|
-00000050  bb a4 8a 7f b8 ca 30 0d  06 09 2a 86 48 86 f7 0d  |......0...*.H...|
-00000060  01 01 05 05 00 30 45 31  0b 30 09 06 03 55 04 06  |.....0E1.0...U..|
-00000070  13 02 41 55 31 13 30 11  06 03 55 04 08 13 0a 53  |..AU1.0...U....S|
-00000080  6f 6d 65 2d 53 74 61 74  65 31 21 30 1f 06 03 55  |ome-State1!0...U|
-00000090  04 0a 13 18 49 6e 74 65  72 6e 65 74 20 57 69 64  |....Internet Wid|
-000000a0  67 69 74 73 20 50 74 79  20 4c 74 64 30 1e 17 0d  |gits Pty Ltd0...|
-000000b0  31 30 30 34 32 34 30 39  30 39 33 38 5a 17 0d 31  |100424090938Z..1|
-000000c0  31 30 34 32 34 30 39 30  39 33 38 5a 30 45 31 0b  |10424090938Z0E1.|
-000000d0  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
-000000e0  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
-000000f0  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
-00000100  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
-00000110  4c 74 64 30 81 9f 30 0d  06 09 2a 86 48 86 f7 0d  |Ltd0..0...*.H...|
-00000120  01 01 01 05 00 03 81 8d  00 30 81 89 02 81 81 00  |.........0......|
-00000130  bb 79 d6 f5 17 b5 e5 bf  46 10 d0 dc 69 be e6 2b  |.y......F...i..+|
-00000140  07 43 5a d0 03 2d 8a 7a  43 85 b7 14 52 e7 a5 65  |.CZ..-.zC...R..e|
-00000150  4c 2c 78 b8 23 8c b5 b4  82 e5 de 1f 95 3b 7e 62  |L,x.#........;~b|
-00000160  a5 2c a5 33 d6 fe 12 5c  7a 56 fc f5 06 bf fa 58  |.,.3...\zV.....X|
-00000170  7b 26 3f b5 cd 04 d3 d0  c9 21 96 4a c7 f4 54 9f  |{&?......!.J..T.|
-00000180  5a bf ef 42 71 00 fe 18  99 07 7f 7e 88 7d 7d f1  |Z..Bq......~.}}.|
-00000190  04 39 c4 a2 2e db 51 c9  7c e3 c0 4c 3b 32 66 01  |.9....Q.|..L;2f.|
-000001a0  cf af b1 1d b8 71 9a 1d  db db 89 6b ae da 2d 79  |.....q.....k..-y|
-000001b0  02 03 01 00 01 a3 81 a7  30 81 a4 30 1d 06 03 55  |........0..0...U|
-000001c0  1d 0e 04 16 04 14 b1 ad  e2 85 5a cf cb 28 db 69  |..........Z..(.i|
-000001d0  ce 23 69 de d3 26 8e 18  88 39 30 75 06 03 55 1d  |.#i..&...90u..U.|
-000001e0  23 04 6e 30 6c 80 14 b1  ad e2 85 5a cf cb 28 db  |#.n0l......Z..(.|
-000001f0  69 ce 23 69 de d3 26 8e  18 88 39 a1 49 a4 47 30  |i.#i..&...9.I.G0|
-00000200  45 31 0b 30 09 06 03 55  04 06 13 02 41 55 31 13  |E1.0...U....AU1.|
-00000210  30 11 06 03 55 04 08 13  0a 53 6f 6d 65 2d 53 74  |0...U....Some-St|
-00000220  61 74 65 31 21 30 1f 06  03 55 04 0a 13 18 49 6e  |ate1!0...U....In|
-00000230  74 65 72 6e 65 74 20 57  69 64 67 69 74 73 20 50  |ternet Widgits P|
-00000240  74 79 20 4c 74 64 82 09  00 85 b0 bb a4 8a 7f b8  |ty Ltd..........|
-00000250  ca 30 0c 06 03 55 1d 13  04 05 30 03 01 01 ff 30  |.0...U....0....0|
-00000260  0d 06 09 2a 86 48 86 f7  0d 01 01 05 05 00 03 81  |...*.H..........|
-00000270  81 00 08 6c 45 24 c7 6b  b1 59 ab 0c 52 cc f2 b0  |...lE$.k.Y..R...|
-00000280  14 d7 87 9d 7a 64 75 b5  5a 95 66 e4 c5 2b 8e ae  |....zdu.Z.f..+..|
-00000290  12 66 1f eb 4f 38 b3 6e  60 d3 92 fd f7 41 08 b5  |.f..O8.n`....A..|
-000002a0  25 13 b1 18 7a 24 fb 30  1d ba ed 98 b9 17 ec e7  |%...z$.0........|
-000002b0  d7 31 59 db 95 d3 1d 78  ea 50 56 5c d5 82 5a 2d  |.1Y....x.PV\..Z-|
-000002c0  5a 5f 33 c4 b6 d8 c9 75  90 96 8c 0f 52 98 b5 cd  |Z_3....u....R...|
-000002d0  98 1f 89 20 5f f2 a0 1c  a3 1b 96 94 dd a9 fd 57  |... _..........W|
-000002e0  e9 70 e8 26 6d 71 99 9b  26 6e 38 50 29 6c 90 a7  |.p.&mq..&n8P)l..|
-000002f0  bd d9 16 03 03 00 04 0e  00 00 00                 |...........|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 05 00 00  |................|
+00000030  05 ff 01 00 01 00 16 03  03 02 be 0b 00 02 ba 00  |................|
+00000040  02 b7 00 02 b4 30 82 02  b0 30 82 02 19 a0 03 02  |.....0...0......|
+00000050  01 02 02 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0d 06  |.............0..|
+00000060  09 2a 86 48 86 f7 0d 01  01 05 05 00 30 45 31 0b  |.*.H........0E1.|
+00000070  30 09 06 03 55 04 06 13  02 41 55 31 13 30 11 06  |0...U....AU1.0..|
+00000080  03 55 04 08 13 0a 53 6f  6d 65 2d 53 74 61 74 65  |.U....Some-State|
+00000090  31 21 30 1f 06 03 55 04  0a 13 18 49 6e 74 65 72  |1!0...U....Inter|
+000000a0  6e 65 74 20 57 69 64 67  69 74 73 20 50 74 79 20  |net Widgits Pty |
+000000b0  4c 74 64 30 1e 17 0d 31  30 30 34 32 34 30 39 30  |Ltd0...100424090|
+000000c0  39 33 38 5a 17 0d 31 31  30 34 32 34 30 39 30 39  |938Z..1104240909|
+000000d0  33 38 5a 30 45 31 0b 30  09 06 03 55 04 06 13 02  |38Z0E1.0...U....|
+000000e0  41 55 31 13 30 11 06 03  55 04 08 13 0a 53 6f 6d  |AU1.0...U....Som|
+000000f0  65 2d 53 74 61 74 65 31  21 30 1f 06 03 55 04 0a  |e-State1!0...U..|
+00000100  13 18 49 6e 74 65 72 6e  65 74 20 57 69 64 67 69  |..Internet Widgi|
+00000110  74 73 20 50 74 79 20 4c  74 64 30 81 9f 30 0d 06  |ts Pty Ltd0..0..|
+00000120  09 2a 86 48 86 f7 0d 01  01 01 05 00 03 81 8d 00  |.*.H............|
+00000130  30 81 89 02 81 81 00 bb  79 d6 f5 17 b5 e5 bf 46  |0.......y......F|
+00000140  10 d0 dc 69 be e6 2b 07  43 5a d0 03 2d 8a 7a 43  |...i..+.CZ..-.zC|
+00000150  85 b7 14 52 e7 a5 65 4c  2c 78 b8 23 8c b5 b4 82  |...R..eL,x.#....|
+00000160  e5 de 1f 95 3b 7e 62 a5  2c a5 33 d6 fe 12 5c 7a  |....;~b.,.3...\z|
+00000170  56 fc f5 06 bf fa 58 7b  26 3f b5 cd 04 d3 d0 c9  |V.....X{&?......|
+00000180  21 96 4a c7 f4 54 9f 5a  bf ef 42 71 00 fe 18 99  |!.J..T.Z..Bq....|
+00000190  07 7f 7e 88 7d 7d f1 04  39 c4 a2 2e db 51 c9 7c  |..~.}}..9....Q.||
+000001a0  e3 c0 4c 3b 32 66 01 cf  af b1 1d b8 71 9a 1d db  |..L;2f......q...|
+000001b0  db 89 6b ae da 2d 79 02  03 01 00 01 a3 81 a7 30  |..k..-y........0|
+000001c0  81 a4 30 1d 06 03 55 1d  0e 04 16 04 14 b1 ad e2  |..0...U.........|
+000001d0  85 5a cf cb 28 db 69 ce  23 69 de d3 26 8e 18 88  |.Z..(.i.#i..&...|
+000001e0  39 30 75 06 03 55 1d 23  04 6e 30 6c 80 14 b1 ad  |90u..U.#.n0l....|
+000001f0  e2 85 5a cf cb 28 db 69  ce 23 69 de d3 26 8e 18  |..Z..(.i.#i..&..|
+00000200  88 39 a1 49 a4 47 30 45  31 0b 30 09 06 03 55 04  |.9.I.G0E1.0...U.|
+00000210  06 13 02 41 55 31 13 30  11 06 03 55 04 08 13 0a  |...AU1.0...U....|
+00000220  53 6f 6d 65 2d 53 74 61  74 65 31 21 30 1f 06 03  |Some-State1!0...|
+00000230  55 04 0a 13 18 49 6e 74  65 72 6e 65 74 20 57 69  |U....Internet Wi|
+00000240  64 67 69 74 73 20 50 74  79 20 4c 74 64 82 09 00  |dgits Pty Ltd...|
+00000250  85 b0 bb a4 8a 7f b8 ca  30 0c 06 03 55 1d 13 04  |........0...U...|
+00000260  05 30 03 01 01 ff 30 0d  06 09 2a 86 48 86 f7 0d  |.0....0...*.H...|
+00000270  01 01 05 05 00 03 81 81  00 08 6c 45 24 c7 6b b1  |..........lE$.k.|
+00000280  59 ab 0c 52 cc f2 b0 14  d7 87 9d 7a 64 75 b5 5a  |Y..R.......zdu.Z|
+00000290  95 66 e4 c5 2b 8e ae 12  66 1f eb 4f 38 b3 6e 60  |.f..+...f..O8.n`|
+000002a0  d3 92 fd f7 41 08 b5 25  13 b1 18 7a 24 fb 30 1d  |....A..%...z$.0.|
+000002b0  ba ed 98 b9 17 ec e7 d7  31 59 db 95 d3 1d 78 ea  |........1Y....x.|
+000002c0  50 56 5c d5 82 5a 2d 5a  5f 33 c4 b6 d8 c9 75 90  |PV\..Z-Z_3....u.|
+000002d0  96 8c 0f 52 98 b5 cd 98  1f 89 20 5f f2 a0 1c a3  |...R...... _....|
+000002e0  1b 96 94 dd a9 fd 57 e9  70 e8 26 6d 71 99 9b 26  |......W.p.&mq..&|
+000002f0  6e 38 50 29 6c 90 a7 bd  d9 16 03 03 00 04 0e 00  |n8P)l...........|
+00000300  00 00                                             |..|
 >>> Flow 3 (client to server)
-00000000  16 03 03 00 86 10 00 00  82 00 80 91 75 8a cc 25  |............u..%|
-00000010  6e 5e c5 ce 1b a8 1d fc  ed 80 08 1a e2 fb 04 12  |n^..............|
-00000020  00 fb 52 d2 92 b0 0b 42  8a f2 66 11 fc 31 91 1c  |..R....B..f..1..|
-00000030  28 5a 9a 62 12 84 f8 fb  8b 08 18 03 58 ec 5a 5c  |(Z.b........X.Z\|
-00000040  aa 71 69 e5 c2 a9 5d c3  06 d4 cb e5 58 01 be 6e  |.qi...].....X..n|
-00000050  41 22 02 b2 71 52 d5 67  a2 fc 7c f2 f6 38 67 a3  |A"..qR.g..|..8g.|
-00000060  23 e0 21 7f b8 59 2c ca  7b 3f 8a ee 47 b2 ed 51  |#.!..Y,.{?..G..Q|
-00000070  63 cd 04 8e 19 ac ca 97  13 fb c0 b8 30 82 58 22  |c...........0.X"|
-00000080  a8 30 31 7a ed 64 8e fc  10 53 f1 14 03 03 00 01  |.01z.d...S......|
-00000090  01 16 03 03 00 24 7c 40  76 86 a1 2d 7a 0d 6a e0  |.....$|@v..-z.j.|
-000000a0  be 52 1e a4 5c 8a 8a 41  b7 65 b8 98 09 fd 84 28  |.R..\..A.e.....(|
-000000b0  31 2c b2 5f 25 dc fd 72  df 26                    |1,._%..r.&|
+00000000  16 03 03 00 86 10 00 00  82 00 80 35 b3 60 ba 14  |...........5.`..|
+00000010  5f 19 24 a0 24 de 4e 85  a9 64 78 3a 51 24 64 70  |_.$.$.N..dx:Q$dp|
+00000020  88 55 6d c3 11 b8 d3 9f  bc 7a 33 f8 3c 48 93 2f  |.Um......z3.<H./|
+00000030  66 69 11 33 39 37 7a 36  a3 1c ef b0 81 71 7d 25  |fi.397z6.....q}%|
+00000040  35 da 2c 42 e2 ab d3 b7  07 8b 4a 0d 6d 77 bd ae  |5.,B......J.mw..|
+00000050  02 51 7c a5 0d a6 03 4c  3c d0 ce 89 2c 83 6c de  |.Q|....L<...,.l.|
+00000060  40 15 cc 72 c7 95 c8 6d  ee 05 86 da 3e c6 7c d4  |@..r...m....>.|.|
+00000070  44 82 f4 24 03 22 40 00  64 27 53 15 41 8c 01 e9  |D..$."@.d'S.A...|
+00000080  39 32 fa 8e 2d f9 b4 89  34 15 d6 14 03 03 00 01  |92..-...4.......|
+00000090  01 16 03 03 00 24 f5 61  8b 24 bf b4 82 3a cf 49  |.....$.a.$...:.I|
+000000a0  99 a0 b1 1b a7 a7 a3 92  7c 84 85 e0 64 a3 3d bd  |........|...d.=.|
+000000b0  38 98 7d 97 a8 b9 2a 35  a9 09                    |8.}...*5..|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 24 6c 98 e2 1b ad  |..........$l....|
-00000010  22 8b 5a 5a b7 95 5c be  2f 29 97 7f 05 54 59 6f  |".ZZ..\./)...TYo|
-00000020  c6 91 98 ed 7a 81 eb 7f  5c 34 b8 f8 6d a4 da 17  |....z...\4..m...|
-00000030  03 03 00 21 4f d9 55 62  2a 4e fa 4e 28 8f 92 e2  |...!O.Ub*N.N(...|
-00000040  22 50 14 21 ca 48 ba 71  2c 36 77 b6 92 eb 67 e2  |"P.!.H.q,6w...g.|
-00000050  ba 31 f4 4c 00 15 03 03  00 16 3f a2 64 b0 a9 ed  |.1.L......?.d...|
-00000060  cf 5e b3 25 07 97 d9 1b  a5 04 e7 ff 8a 08 4f ff  |.^.%..........O.|
+00000000  14 03 03 00 01 01 16 03  03 00 24 c9 0b 84 e6 39  |..........$....9|
+00000010  f2 e0 f3 ac 9f 0f 17 92  5f 6d de 94 18 c4 60 d9  |........_m....`.|
+00000020  66 c3 0d 1a ae c2 8f 46  8f 7f f0 58 0e 4a 9b 17  |f......F...X.J..|
+00000030  03 03 00 21 8b 73 a1 6a  7e d9 7e 4f 1d cc b2 7d  |...!.s.j~.~O...}|
+00000040  3c 83 3f 52 f8 08 77 01  4c 65 11 6d 50 25 9a cc  |<.?R..w.Le.mP%..|
+00000050  e3 54 27 72 59 15 03 03  00 16 3d c8 ab 14 51 fa  |.T'rY.....=...Q.|
+00000060  97 f1 ef 5f b4 4f 44 58  d4 93 3b ae e5 61 1f a3  |..._.ODX..;..a..|
index 944289029d3207e63d93b503f460e711477c7021..c495d4adc60f8bfd13103c6436dddd8498fee9d9 100644 (file)
@@ -1,35 +1,36 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 e9 01 00 00  e5 03 03 52 ac 77 f8 65  |...........R.w.e|
-00000010  60 65 1c ac 85 b1 4c d1  e0 5f 02 b0 22 80 c9 98  |`e....L.._.."...|
-00000020  af d9 43 87 0a e8 26 a3  d9 59 cc 20 76 ef 21 5d  |..C...&..Y. v.!]|
-00000030  53 6c 8b 2e 11 a0 43 a8  af 74 8a 58 40 a5 95 ee  |Sl....C..t.X@...|
-00000040  6d a9 ff e8 e4 d8 ba d2  88 ca 7f 0a 00 04 00 05  |m...............|
-00000050  00 ff 02 01 00 00 97 00  23 00 68 00 00 00 00 00  |........#.h.....|
-00000060  00 00 00 00 00 00 00 00  00 00 00 65 ea 4b d1 ef  |...........e.K..|
-00000070  ba 11 a0 88 48 34 0d 3b  22 38 1e 62 c5 0a 33 b3  |....H4.;"8.b..3.|
-00000080  f0 65 ff fa c4 f3 a8 2d  24 75 55 e4 47 cc d2 6b  |.e.....-$uU.G..k|
-00000090  8d 26 c6 d1 10 cc a2 48  29 c0 a1 a5 52 66 dc ec  |.&.....H)...Rf..|
-000000a0  0b 59 23 02 5b 66 c3 af  88 27 f0 65 c0 72 de 1a  |.Y#.[f...'.e.r..|
-000000b0  db cf 9b 5f e7 fe e8 2d  27 6f 67 fb 91 a1 46 70  |..._...-'og...Fp|
-000000c0  b1 ce 29 00 0d 00 22 00  20 06 01 06 02 06 03 05  |..)...". .......|
-000000d0  01 05 02 05 03 04 01 04  02 04 03 03 01 03 02 03  |................|
-000000e0  03 02 01 02 02 02 03 01  01 00 0f 00 01 01        |..............|
+00000000  16 03 01 00 e8 01 00 00  e4 03 03 52 cc 57 59 c3  |...........R.WY.|
+00000010  8b df 97 05 d8 5f 16 22  b4 b1 e7 cb 7d 2f 9b 58  |....._."....}/.X|
+00000020  a3 f4 d7 2c a4 c1 9d 49  ed 4b ba 20 90 da 90 3e  |...,...I.K. ...>|
+00000030  36 19 7a db 56 43 26 f7  dc 42 57 33 22 ed 9d a4  |6.z.VC&..BW3"...|
+00000040  9d 53 da f8 9d 4e 60 66  71 a0 2e 2e 00 04 00 05  |.S...N`fq.......|
+00000050  00 ff 01 00 00 97 00 23  00 68 00 00 00 00 00 00  |.......#.h......|
+00000060  00 00 00 00 00 00 00 00  00 00 65 ea 4b d1 ef ba  |..........e.K...|
+00000070  06 38 1e e1 88 82 3a cd  03 ac 3b 39 0a e0 19 fd  |.8....:...;9....|
+00000080  af 6c 57 30 df 31 6e f7  92 38 4b 5d 77 90 39 ff  |.lW0.1n..8K]w.9.|
+00000090  32 51 f5 ed 12 d7 b0 7c  4d 6c c5 76 e4 72 48 3e  |2Q.....|Ml.v.rH>|
+000000a0  59 23 fe 0d 15 df f4 ba  ea b9 67 16 23 8f 7d 15  |Y#........g.#.}.|
+000000b0  b6 11 f1 ab d7 d4 cd a3  21 82 92 2a 12 cf 95 f3  |........!..*....|
+000000c0  60 b2 00 0d 00 22 00 20  06 01 06 02 06 03 05 01  |`....". ........|
+000000d0  05 02 05 03 04 01 04 02  04 03 03 01 03 02 03 03  |................|
+000000e0  02 01 02 02 02 03 01 01  00 0f 00 01 01           |.............|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 4a 02 00 00  46 03 03 00 00 00 00 00  |....J...F.......|
+00000000  16 03 03 00 51 02 00 00  4d 03 03 00 00 00 00 00  |....Q...M.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 20 76 ef 21 5d  |........... v.!]|
-00000030  53 6c 8b 2e 11 a0 43 a8  af 74 8a 58 40 a5 95 ee  |Sl....C..t.X@...|
-00000040  6d a9 ff e8 e4 d8 ba d2  88 ca 7f 0a 00 05 00 14  |m...............|
-00000050  03 03 00 01 01 16 03 03  00 24 37 d8 ed 9b cc 6d  |.........$7....m|
-00000060  5f ce c0 40 68 4b 1f 45  ff 94 3a 98 ec c7 69 1c  |_..@hK.E..:...i.|
-00000070  26 50 9e 3c 54 e6 da b6  5c 2e 48 66 1d 65        |&P.<T...\.Hf.e|
+00000020  00 00 00 00 00 00 00 00  00 00 00 20 90 da 90 3e  |........... ...>|
+00000030  36 19 7a db 56 43 26 f7  dc 42 57 33 22 ed 9d a4  |6.z.VC&..BW3"...|
+00000040  9d 53 da f8 9d 4e 60 66  71 a0 2e 2e 00 05 00 00  |.S...N`fq.......|
+00000050  05 ff 01 00 01 00 14 03  03 00 01 01 16 03 03 00  |................|
+00000060  24 11 12 ff 28 10 14 4c  e5 0e ad a7 fa f3 92 fb  |$...(..L........|
+00000070  13 7d ae f2 b2 4a 6b a1  9e 67 cf a8 f7 8c 6f a0  |.}...Jk..g....o.|
+00000080  6c 30 0e 18 55                                    |l0..U|
 >>> Flow 3 (client to server)
-00000000  14 03 03 00 01 01 16 03  03 00 24 de 72 a3 15 54  |..........$.r..T|
-00000010  7e 6d a0 ce 5c 38 5c f3  6f 49 00 ba fb c0 c2 cc  |~m..\8\.oI......|
-00000020  6f 29 00 39 f9 bf 77 07  57 f1 e4 cf 6e 0c a3     |o).9..w.W...n..|
+00000000  14 03 03 00 01 01 16 03  03 00 24 0d 46 41 8b 24  |..........$.FA.$|
+00000010  36 01 a9 fd 8b ec fc e6  b1 83 96 df 0d 3e 53 54  |6............>ST|
+00000020  58 b8 43 f2 a6 25 5e 1a  ae 19 9e d2 28 44 92     |X.C..%^.....(D.|
 >>> Flow 4 (server to client)
-00000000  17 03 03 00 21 b0 e7 1c  af 33 cd 5e ad 24 cf a4  |....!....3.^.$..|
-00000010  51 99 1a f6 65 1e f3 28  ec 83 93 25 3d 8f f9 57  |Q...e..(...%=..W|
-00000020  cb ec 1f 4a 47 77 15 03  03 00 16 2b 87 cb 08 f7  |...JGw.....+....|
-00000030  51 08 3b c9 73 f4 1f 22  ac 8c 7c 1a 2e 43 84 d7  |Q.;.s.."..|..C..|
-00000040  ef                                                |.|
+00000000  17 03 03 00 21 c4 fb f6  53 bb 3e 04 cc 0b a0 03  |....!...S.>.....|
+00000010  fa 49 96 da b5 8d b2 f2  e5 d8 f3 5c 27 57 4f 9c  |.I.........\'WO.|
+00000020  30 00 34 fc 52 92 15 03  03 00 16 a3 02 7a 50 d2  |0.4.R........zP.|
+00000030  c6 b3 fc 69 8f e4 94 ae  ab 22 ad 05 1d 15 69 b9  |...i....."....i.|
+00000040  a5                                                |.|
index 667adb3aaa221c8db2cf764a3f87ab57466b32a4..61b17a11da2b2e63f8e83b4e628134001b57d9e3 100644 (file)
@@ -1,75 +1,76 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 71 01 00 00  6d 03 03 52 ac 77 f8 8f  |....q...m..R.w..|
-00000010  99 4f 1f b2 b1 8e c1 fe  52 04 d7 2f 45 db 34 55  |.O......R../E.4U|
-00000020  ca d1 ae 94 68 05 5d ae  7f 34 ae 00 00 04 00 2f  |....h.]..4...../|
-00000030  00 ff 02 01 00 00 3f 00  00 00 10 00 0e 00 00 0b  |......?.........|
-00000040  73 6e 69 74 65 73 74 2e  63 6f 6d 00 0d 00 22 00  |snitest.com...".|
-00000050  20 06 01 06 02 06 03 05  01 05 02 05 03 04 01 04  | ...............|
-00000060  02 04 03 03 01 03 02 03  03 02 01 02 02 02 03 01  |................|
-00000070  01 00 0f 00 01 01                                 |......|
+00000000  16 03 01 00 70 01 00 00  6c 03 03 52 cc 57 59 2d  |....p...l..R.WY-|
+00000010  77 aa 75 35 fa ff 2a a2  bf 91 5e e3 7f 38 7d 7a  |w.u5..*...^..8}z|
+00000020  e3 93 d3 e8 8b 09 bb 06  c8 6d 91 00 00 04 00 2f  |.........m...../|
+00000030  00 ff 01 00 00 3f 00 00  00 10 00 0e 00 00 0b 73  |.....?.........s|
+00000040  6e 69 74 65 73 74 2e 63  6f 6d 00 0d 00 22 00 20  |nitest.com...". |
+00000050  06 01 06 02 06 03 05 01  05 02 05 03 04 01 04 02  |................|
+00000060  04 03 03 01 03 02 03 03  02 01 02 02 02 03 01 01  |................|
+00000070  00 0f 00 01 01                                    |.....|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 2a 02 00 00  26 03 03 00 00 00 00 00  |....*...&.......|
+00000000  16 03 03 00 31 02 00 00  2d 03 03 00 00 00 00 00  |....1...-.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 2f 00 16  |............./..|
-00000030  03 03 02 00 0b 00 01 fc  00 01 f9 00 01 f6 30 82  |..............0.|
-00000040  01 f2 30 82 01 5d a0 03  02 01 02 02 01 00 30 0b  |..0..]........0.|
-00000050  06 09 2a 86 48 86 f7 0d  01 01 05 30 28 31 10 30  |..*.H......0(1.0|
-00000060  0e 06 03 55 04 0a 13 07  41 63 6d 65 20 43 6f 31  |...U....Acme Co1|
-00000070  14 30 12 06 03 55 04 03  13 0b 73 6e 69 74 65 73  |.0...U....snites|
-00000080  74 2e 63 6f 6d 30 1e 17  0d 31 32 30 34 31 31 31  |t.com0...1204111|
-00000090  37 34 30 33 35 5a 17 0d  31 33 30 34 31 31 31 37  |74035Z..13041117|
-000000a0  34 35 33 35 5a 30 28 31  10 30 0e 06 03 55 04 0a  |4535Z0(1.0...U..|
-000000b0  13 07 41 63 6d 65 20 43  6f 31 14 30 12 06 03 55  |..Acme Co1.0...U|
-000000c0  04 03 13 0b 73 6e 69 74  65 73 74 2e 63 6f 6d 30  |....snitest.com0|
-000000d0  81 9d 30 0b 06 09 2a 86  48 86 f7 0d 01 01 01 03  |..0...*.H.......|
-000000e0  81 8d 00 30 81 89 02 81  81 00 bb 79 d6 f5 17 b5  |...0.......y....|
-000000f0  e5 bf 46 10 d0 dc 69 be  e6 2b 07 43 5a d0 03 2d  |..F...i..+.CZ..-|
-00000100  8a 7a 43 85 b7 14 52 e7  a5 65 4c 2c 78 b8 23 8c  |.zC...R..eL,x.#.|
-00000110  b5 b4 82 e5 de 1f 95 3b  7e 62 a5 2c a5 33 d6 fe  |.......;~b.,.3..|
-00000120  12 5c 7a 56 fc f5 06 bf  fa 58 7b 26 3f b5 cd 04  |.\zV.....X{&?...|
-00000130  d3 d0 c9 21 96 4a c7 f4  54 9f 5a bf ef 42 71 00  |...!.J..T.Z..Bq.|
-00000140  fe 18 99 07 7f 7e 88 7d  7d f1 04 39 c4 a2 2e db  |.....~.}}..9....|
-00000150  51 c9 7c e3 c0 4c 3b 32  66 01 cf af b1 1d b8 71  |Q.|..L;2f......q|
-00000160  9a 1d db db 89 6b ae da  2d 79 02 03 01 00 01 a3  |.....k..-y......|
-00000170  32 30 30 30 0e 06 03 55  1d 0f 01 01 ff 04 04 03  |2000...U........|
-00000180  02 00 a0 30 0d 06 03 55  1d 0e 04 06 04 04 01 02  |...0...U........|
-00000190  03 04 30 0f 06 03 55 1d  23 04 08 30 06 80 04 01  |..0...U.#..0....|
-000001a0  02 03 04 30 0b 06 09 2a  86 48 86 f7 0d 01 01 05  |...0...*.H......|
-000001b0  03 81 81 00 89 c6 45 5f  1c 1f 5e f8 eb 1a b1 74  |......E_..^....t|
-000001c0  ee 24 39 05 9f 5c 42 59  bb 1a 8d 86 cd b1 d0 56  |.$9..\BY.......V|
-000001d0  f5 6a 71 7d a4 0e 95 ab  90 f5 9e 8d ea f6 27 c1  |.jq}..........'.|
-000001e0  57 99 50 94 db 08 02 26  6e b3 4f c6 84 2d ea 8a  |W.P....&n.O..-..|
-000001f0  4b 68 d9 c1 38 91 03 ab  84 fb 9e 1f 85 d9 b5 d2  |Kh..8...........|
-00000200  3f f2 31 2c 86 70 fb b5  40 14 82 45 a4 eb af e2  |?.1,.p..@..E....|
-00000210  64 d9 0c 8a 4c f4 f8 5b  0f ac 12 ac 2f c4 a3 15  |d...L..[..../...|
-00000220  4b ad 52 46 28 68 af 96  c6 2c 65 25 d6 52 b6 e3  |K.RF(h...,e%.R..|
-00000230  18 45 bd cc 16 03 03 00  04 0e 00 00 00           |.E...........|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 2f 00 00  |............./..|
+00000030  05 ff 01 00 01 00 16 03  03 02 00 0b 00 01 fc 00  |................|
+00000040  01 f9 00 01 f6 30 82 01  f2 30 82 01 5d a0 03 02  |.....0...0..]...|
+00000050  01 02 02 01 00 30 0b 06  09 2a 86 48 86 f7 0d 01  |.....0...*.H....|
+00000060  01 05 30 28 31 10 30 0e  06 03 55 04 0a 13 07 41  |..0(1.0...U....A|
+00000070  63 6d 65 20 43 6f 31 14  30 12 06 03 55 04 03 13  |cme Co1.0...U...|
+00000080  0b 73 6e 69 74 65 73 74  2e 63 6f 6d 30 1e 17 0d  |.snitest.com0...|
+00000090  31 32 30 34 31 31 31 37  34 30 33 35 5a 17 0d 31  |120411174035Z..1|
+000000a0  33 30 34 31 31 31 37 34  35 33 35 5a 30 28 31 10  |30411174535Z0(1.|
+000000b0  30 0e 06 03 55 04 0a 13  07 41 63 6d 65 20 43 6f  |0...U....Acme Co|
+000000c0  31 14 30 12 06 03 55 04  03 13 0b 73 6e 69 74 65  |1.0...U....snite|
+000000d0  73 74 2e 63 6f 6d 30 81  9d 30 0b 06 09 2a 86 48  |st.com0..0...*.H|
+000000e0  86 f7 0d 01 01 01 03 81  8d 00 30 81 89 02 81 81  |..........0.....|
+000000f0  00 bb 79 d6 f5 17 b5 e5  bf 46 10 d0 dc 69 be e6  |..y......F...i..|
+00000100  2b 07 43 5a d0 03 2d 8a  7a 43 85 b7 14 52 e7 a5  |+.CZ..-.zC...R..|
+00000110  65 4c 2c 78 b8 23 8c b5  b4 82 e5 de 1f 95 3b 7e  |eL,x.#........;~|
+00000120  62 a5 2c a5 33 d6 fe 12  5c 7a 56 fc f5 06 bf fa  |b.,.3...\zV.....|
+00000130  58 7b 26 3f b5 cd 04 d3  d0 c9 21 96 4a c7 f4 54  |X{&?......!.J..T|
+00000140  9f 5a bf ef 42 71 00 fe  18 99 07 7f 7e 88 7d 7d  |.Z..Bq......~.}}|
+00000150  f1 04 39 c4 a2 2e db 51  c9 7c e3 c0 4c 3b 32 66  |..9....Q.|..L;2f|
+00000160  01 cf af b1 1d b8 71 9a  1d db db 89 6b ae da 2d  |......q.....k..-|
+00000170  79 02 03 01 00 01 a3 32  30 30 30 0e 06 03 55 1d  |y......2000...U.|
+00000180  0f 01 01 ff 04 04 03 02  00 a0 30 0d 06 03 55 1d  |..........0...U.|
+00000190  0e 04 06 04 04 01 02 03  04 30 0f 06 03 55 1d 23  |.........0...U.#|
+000001a0  04 08 30 06 80 04 01 02  03 04 30 0b 06 09 2a 86  |..0.......0...*.|
+000001b0  48 86 f7 0d 01 01 05 03  81 81 00 89 c6 45 5f 1c  |H............E_.|
+000001c0  1f 5e f8 eb 1a b1 74 ee  24 39 05 9f 5c 42 59 bb  |.^....t.$9..\BY.|
+000001d0  1a 8d 86 cd b1 d0 56 f5  6a 71 7d a4 0e 95 ab 90  |......V.jq}.....|
+000001e0  f5 9e 8d ea f6 27 c1 57  99 50 94 db 08 02 26 6e  |.....'.W.P....&n|
+000001f0  b3 4f c6 84 2d ea 8a 4b  68 d9 c1 38 91 03 ab 84  |.O..-..Kh..8....|
+00000200  fb 9e 1f 85 d9 b5 d2 3f  f2 31 2c 86 70 fb b5 40  |.......?.1,.p..@|
+00000210  14 82 45 a4 eb af e2 64  d9 0c 8a 4c f4 f8 5b 0f  |..E....d...L..[.|
+00000220  ac 12 ac 2f c4 a3 15 4b  ad 52 46 28 68 af 96 c6  |.../...K.RF(h...|
+00000230  2c 65 25 d6 52 b6 e3 18  45 bd cc 16 03 03 00 04  |,e%.R...E.......|
+00000240  0e 00 00 00                                       |....|
 >>> Flow 3 (client to server)
-00000000  16 03 03 00 86 10 00 00  82 00 80 53 d9 f6 6b 66  |...........S..kf|
-00000010  c8 ef e0 90 72 b4 57 ab  a0 21 1f 2b d1 da 50 6d  |....r.W..!.+..Pm|
-00000020  fc 0b bb 45 1b 5c f3 44  d3 a3 45 7f 2f ef 5c 46  |...E.\.D..E./.\F|
-00000030  d5 39 eb 28 1d bb 25 af  34 f3 f8 d3 0d c3 6f a2  |.9.(..%.4.....o.|
-00000040  c9 fc 2c 87 9e 9e 1e 73  6f 9f f2 bc 9d 03 c3 80  |..,....so.......|
-00000050  fa c5 52 70 5a 5e 64 89  bb 90 ba c3 e5 93 bc 65  |..RpZ^d........e|
-00000060  47 f6 7e f2 9c 0e 4c 8d  a7 b9 d0 51 09 b3 51 53  |G.~...L....Q..QS|
-00000070  39 12 4e f4 ed a0 39 27  d5 5f a3 cc f2 d3 05 73  |9.N...9'._.....s|
-00000080  49 d8 09 c3 1d 03 c8 1f  13 12 75 14 03 03 00 01  |I.........u.....|
-00000090  01 16 03 03 00 40 c4 16  cc fe ae db 1c dd eb 8e  |.....@..........|
-000000a0  97 ca ce 6d 88 de 64 81  91 4f 92 fe 77 50 03 77  |...m..d..O..wP.w|
-000000b0  86 31 4c b7 e7 ed 10 7a  61 b3 b0 06 7b 01 70 e4  |.1L....za...{.p.|
-000000c0  7f 04 37 f1 24 14 4f b3  32 0c 04 0d e0 90 aa ec  |..7.$.O.2.......|
-000000d0  47 8f 2d 3e cf c8                                 |G.->..|
+00000000  16 03 03 00 86 10 00 00  82 00 80 0d f2 bf 75 a9  |..............u.|
+00000010  aa db f3 25 55 d4 20 59  63 54 d1 70 82 f9 61 c5  |...%U. YcT.p..a.|
+00000020  b7 ae 3f 75 71 75 9d c5  01 a1 ed b1 07 66 9f 3f  |..?uqu.......f.?|
+00000030  cf c6 e6 ad 44 03 fd 18  6f 53 24 ce 76 01 bd fe  |....D...oS$.v...|
+00000040  e2 51 f7 df 8a 23 3a 21  c4 00 15 ff d0 e0 ff c8  |.Q...#:!........|
+00000050  8b 89 33 c6 8e e0 ce 97  ef b4 c6 f9 b0 ea 38 89  |..3...........8.|
+00000060  79 98 34 9e f7 bc c6 fd  d2 5d 56 84 5c d2 9a ce  |y.4......]V.\...|
+00000070  ae de 09 bc 24 25 fc 09  0c bc 0e 91 0d 6b 36 ae  |....$%.......k6.|
+00000080  ce 6b cd 14 ec b6 3c fa  d6 df fc 14 03 03 00 01  |.k....<.........|
+00000090  01 16 03 03 00 40 ad 21  13 2b 33 7a 4a 0d fb 0f  |.....@.!.+3zJ...|
+000000a0  eb d2 b6 85 29 1f 59 79  ba 86 53 5c 68 b4 c7 e3  |....).Yy..S\h...|
+000000b0  8a 6c 5c 18 04 4d e4 76  19 30 ba 92 b4 79 8c 64  |.l\..M.v.0...y.d|
+000000c0  00 a0 2e 13 96 45 9f e7  a9 e4 23 9e 9f 89 23 26  |.....E....#...#&|
+000000d0  36 20 82 fc 75 fe                                 |6 ..u.|
 >>> Flow 4 (server to client)
 00000000  14 03 03 00 01 01 16 03  03 00 40 00 00 00 00 00  |..........@.....|
-00000010  00 00 00 00 00 00 00 00  00 00 00 f7 24 2c f6 09  |............$,..|
-00000020  46 72 c8 41 83 e4 1b fe  6b 6e 5d b1 a0 40 07 9f  |Fr.A....kn]..@..|
-00000030  f5 45 a2 bc 12 1c cd 0c  da ac 13 c0 3d 72 fb 02  |.E..........=r..|
-00000040  70 d6 cd 6e 5b 43 16 c4  c4 cd 6b 17 03 03 00 40  |p..n[C....k....@|
+00000010  00 00 00 00 00 00 00 00  00 00 00 b7 87 61 10 03  |.............a..|
+00000020  b8 a4 42 d4 8b 49 bc 40  80 70 92 c8 25 b0 c6 7f  |..B..I.@.p..%...|
+00000030  b3 87 76 50 5a 59 b3 3c  d8 3e 23 24 aa 1a f3 36  |..vPZY.<.>#$...6|
+00000040  c9 2c 87 c1 22 d2 94 f8  2c fd ef 17 03 03 00 40  |.,.."...,......@|
 00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000060  73 ec e3 ba 42 c5 3f 17  9a 04 98 78 23 3e 8a d2  |s...B.?....x#>..|
-00000070  5c b2 6a 0b 4a 1d 6a db  4d 98 89 ba 99 36 51 bc  |\.j.J.j.M....6Q.|
-00000080  7b 12 83 28 62 c7 26 dc  04 d4 79 49 f3 08 2a 1d  |{..(b.&...yI..*.|
+00000060  e5 7f bd 3e ff 9f d4 1b  91 02 f8 69 6f 70 9d 51  |...>.......iop.Q|
+00000070  a5 ec ef 5b 10 3f 4e 3f  44 e5 9a 39 68 7c 3a b9  |...[.?N?D..9h|:.|
+00000080  69 38 31 ec 9c 45 bf 19  d1 5c 5e 2e 06 00 ca 19  |i81..E...\^.....|
 00000090  15 03 03 00 30 00 00 00  00 00 00 00 00 00 00 00  |....0...........|
-000000a0  00 00 00 00 00 72 b0 8e  3b 7d 3f 74 fd 65 7a 32  |.....r..;}?t.ez2|
-000000b0  6a 3b 7f e9 75 84 a9 87  81 2f f6 08 ea 42 31 55  |j;..u..../...B1U|
-000000c0  78 82 f0 cc 89                                    |x....|
+000000a0  00 00 00 00 00 63 5e 79  2c f2 05 dc 2b d7 5b ac  |.....c^y,...+.[.|
+000000b0  9d fc 75 94 03 16 ca 1f  b2 75 58 2d f1 2f f1 1e  |..u......uX-./..|
+000000c0  d2 f6 84 8f 2e                                    |.....|
index 6c67506fc3610aee314b138e7ccad5666684c46b..40156a0013bc9fb982d2cd143d57c2759232f6e7 100644 (file)
@@ -27,9 +27,8 @@ func Server(conn net.Conn, config *Config) *Conn {
 
 // Client returns a new TLS client side connection
 // using conn as the underlying transport.
-// Client interprets a nil configuration as equivalent to
-// the zero configuration; see the documentation of Config
-// for the defaults.
+// The config cannot be nil: users must set either ServerHostname or
+// InsecureSkipVerify in the config.
 func Client(conn net.Conn, config *Config) *Conn {
        return &Conn{conn: conn, config: config, isClient: true}
 }
index 5034946f7103d38af2d6ba3d57ab1c47fbf5f7b2..58c1e54d1004cc5b6a1ee40d1e2c1c45cb76d93c 100644 (file)
@@ -30,6 +30,13 @@ type AttributeTypeAndValue struct {
        Value interface{}
 }
 
+// AttributeTypeAndValueSET represents a set of ASN.1 sequences of
+// AttributeTypeAndValue sequences from RFC 2986 (PKCS #10).
+type AttributeTypeAndValueSET struct {
+       Type  asn1.ObjectIdentifier
+       Value [][]AttributeTypeAndValue `asn1:"set"`
+}
+
 // Extension represents the ASN.1 structure of the same name. See RFC
 // 5280, section 4.2.
 type Extension struct {
index 324f855b135c67bf69b11b0b32c4e47dd6085f1b..a5bd19e821695d6352a00f2ecf2d428b6f6a129b 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build dragonfly freebsd linux openbsd netbsd
+// +build dragonfly freebsd linux openbsd netbsd solaris
 
 package x509
 
index 2a55fb1e5581c30c2e59dba2d0a3690be9233ead..3570e02359e804bce6b3c77350e467ef749b4dff 100644 (file)
@@ -790,6 +790,58 @@ func parsePublicKey(algo PublicKeyAlgorithm, keyData *publicKeyInfo) (interface{
        }
 }
 
+func parseSANExtension(value []byte) (dnsNames, emailAddresses []string, ipAddresses []net.IP, err error) {
+       // RFC 5280, 4.2.1.6
+
+       // SubjectAltName ::= GeneralNames
+       //
+       // GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
+       //
+       // GeneralName ::= CHOICE {
+       //      otherName                       [0]     OtherName,
+       //      rfc822Name                      [1]     IA5String,
+       //      dNSName                         [2]     IA5String,
+       //      x400Address                     [3]     ORAddress,
+       //      directoryName                   [4]     Name,
+       //      ediPartyName                    [5]     EDIPartyName,
+       //      uniformResourceIdentifier       [6]     IA5String,
+       //      iPAddress                       [7]     OCTET STRING,
+       //      registeredID                    [8]     OBJECT IDENTIFIER }
+       var seq asn1.RawValue
+       if _, err = asn1.Unmarshal(value, &seq); err != nil {
+               return
+       }
+       if !seq.IsCompound || seq.Tag != 16 || seq.Class != 0 {
+               err = asn1.StructuralError{Msg: "bad SAN sequence"}
+               return
+       }
+
+       rest := seq.Bytes
+       for len(rest) > 0 {
+               var v asn1.RawValue
+               rest, err = asn1.Unmarshal(rest, &v)
+               if err != nil {
+                       return
+               }
+               switch v.Tag {
+               case 1:
+                       emailAddresses = append(emailAddresses, string(v.Bytes))
+               case 2:
+                       dnsNames = append(dnsNames, string(v.Bytes))
+               case 7:
+                       switch len(v.Bytes) {
+                       case net.IPv4len, net.IPv6len:
+                               ipAddresses = append(ipAddresses, v.Bytes)
+                       default:
+                               err = errors.New("x509: certificate contained IP address of length " + strconv.Itoa(len(v.Bytes)))
+                               return
+                       }
+               }
+       }
+
+       return
+}
+
 func parseCertificate(in *certificate) (*Certificate, error) {
        out := new(Certificate)
        out.Raw = in.Raw
@@ -863,58 +915,12 @@ func parseCertificate(in *certificate) (*Certificate, error) {
                                        continue
                                }
                        case 17:
-                               // RFC 5280, 4.2.1.6
-
-                               // SubjectAltName ::= GeneralNames
-                               //
-                               // GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
-                               //
-                               // GeneralName ::= CHOICE {
-                               //      otherName                       [0]     OtherName,
-                               //      rfc822Name                      [1]     IA5String,
-                               //      dNSName                         [2]     IA5String,
-                               //      x400Address                     [3]     ORAddress,
-                               //      directoryName                   [4]     Name,
-                               //      ediPartyName                    [5]     EDIPartyName,
-                               //      uniformResourceIdentifier       [6]     IA5String,
-                               //      iPAddress                       [7]     OCTET STRING,
-                               //      registeredID                    [8]     OBJECT IDENTIFIER }
-                               var seq asn1.RawValue
-                               _, err := asn1.Unmarshal(e.Value, &seq)
+                               out.DNSNames, out.EmailAddresses, out.IPAddresses, err = parseSANExtension(e.Value)
                                if err != nil {
                                        return nil, err
                                }
-                               if !seq.IsCompound || seq.Tag != 16 || seq.Class != 0 {
-                                       return nil, asn1.StructuralError{Msg: "bad SAN sequence"}
-                               }
-
-                               parsedName := false
 
-                               rest := seq.Bytes
-                               for len(rest) > 0 {
-                                       var v asn1.RawValue
-                                       rest, err = asn1.Unmarshal(rest, &v)
-                                       if err != nil {
-                                               return nil, err
-                                       }
-                                       switch v.Tag {
-                                       case 1:
-                                               out.EmailAddresses = append(out.EmailAddresses, string(v.Bytes))
-                                               parsedName = true
-                                       case 2:
-                                               out.DNSNames = append(out.DNSNames, string(v.Bytes))
-                                               parsedName = true
-                                       case 7:
-                                               switch len(v.Bytes) {
-                                               case net.IPv4len, net.IPv6len:
-                                                       out.IPAddresses = append(out.IPAddresses, v.Bytes)
-                                               default:
-                                                       return nil, errors.New("x509: certificate contained IP address of length " + strconv.Itoa(len(v.Bytes)))
-                                               }
-                                       }
-                               }
-
-                               if parsedName {
+                               if len(out.DNSNames) > 0 || len(out.EmailAddresses) > 0 || len(out.IPAddresses) > 0 {
                                        continue
                                }
                                // If we didn't parse any of the names then we
@@ -1151,6 +1157,27 @@ func oidInExtensions(oid asn1.ObjectIdentifier, extensions []pkix.Extension) boo
        return false
 }
 
+// marshalSANs marshals a list of addresses into a the contents of an X.509
+// SubjectAlternativeName extension.
+func marshalSANs(dnsNames, emailAddresses []string, ipAddresses []net.IP) (derBytes []byte, err error) {
+       var rawValues []asn1.RawValue
+       for _, name := range dnsNames {
+               rawValues = append(rawValues, asn1.RawValue{Tag: 2, Class: 2, Bytes: []byte(name)})
+       }
+       for _, email := range emailAddresses {
+               rawValues = append(rawValues, asn1.RawValue{Tag: 1, Class: 2, Bytes: []byte(email)})
+       }
+       for _, rawIP := range ipAddresses {
+               // If possible, we always want to encode IPv4 addresses in 4 bytes.
+               ip := rawIP.To4()
+               if ip == nil {
+                       ip = rawIP
+               }
+               rawValues = append(rawValues, asn1.RawValue{Tag: 7, Class: 2, Bytes: ip})
+       }
+       return asn1.Marshal(rawValues)
+}
+
 func buildExtensions(template *Certificate) (ret []pkix.Extension, err error) {
        ret = make([]pkix.Extension, 10 /* maximum number of elements. */)
        n := 0
@@ -1252,22 +1279,7 @@ func buildExtensions(template *Certificate) (ret []pkix.Extension, err error) {
        if (len(template.DNSNames) > 0 || len(template.EmailAddresses) > 0 || len(template.IPAddresses) > 0) &&
                !oidInExtensions(oidExtensionSubjectAltName, template.ExtraExtensions) {
                ret[n].Id = oidExtensionSubjectAltName
-               var rawValues []asn1.RawValue
-               for _, name := range template.DNSNames {
-                       rawValues = append(rawValues, asn1.RawValue{Tag: 2, Class: 2, Bytes: []byte(name)})
-               }
-               for _, email := range template.EmailAddresses {
-                       rawValues = append(rawValues, asn1.RawValue{Tag: 1, Class: 2, Bytes: []byte(email)})
-               }
-               for _, rawIP := range template.IPAddresses {
-                       // If possible, we always want to encode IPv4 addresses in 4 bytes.
-                       ip := rawIP.To4()
-                       if ip == nil {
-                               ip = rawIP
-                       }
-                       rawValues = append(rawValues, asn1.RawValue{Tag: 7, Class: 2, Bytes: ip})
-               }
-               ret[n].Value, err = asn1.Marshal(rawValues)
+               ret[n].Value, err = marshalSANs(template.DNSNames, template.EmailAddresses, template.IPAddresses)
                if err != nil {
                        return
                }
@@ -1342,75 +1354,94 @@ func subjectBytes(cert *Certificate) ([]byte, error) {
        return asn1.Marshal(cert.Subject.ToRDNSequence())
 }
 
-// CreateCertificate creates a new certificate based on a template. The
-// following members of template are used: SerialNumber, Subject, NotBefore,
-// NotAfter, KeyUsage, ExtKeyUsage, UnknownExtKeyUsage, BasicConstraintsValid,
-// IsCA, MaxPathLen, SubjectKeyId, DNSNames, PermittedDNSDomainsCritical,
-// PermittedDNSDomains, SignatureAlgorithm.
-//
-// The certificate is signed by parent. If parent is equal to template then the
-// certificate is self-signed. The parameter pub is the public key of the
-// signee and priv is the private key of the signer.
-//
-// The returned slice is the certificate in DER encoding.
-//
-// The only supported key types are RSA and ECDSA (*rsa.PublicKey or
-// *ecdsa.PublicKey for pub, *rsa.PrivateKey or *ecdsa.PrivateKey for priv).
-func CreateCertificate(rand io.Reader, template, parent *Certificate, pub interface{}, priv interface{}) (cert []byte, err error) {
-       var publicKeyBytes []byte
-       var publicKeyAlgorithm pkix.AlgorithmIdentifier
-
-       if publicKeyBytes, publicKeyAlgorithm, err = marshalPublicKey(pub); err != nil {
-               return nil, err
-       }
-
-       var signatureAlgorithm pkix.AlgorithmIdentifier
-       var hashFunc crypto.Hash
-       var privType PublicKeyAlgorithm
+// signingParamsForPrivateKey returns the parameters to use for signing with
+// priv. If requestedSigAlgo is not zero then it overrides the default
+// signature algorithm.
+func signingParamsForPrivateKey(priv interface{}, requestedSigAlgo SignatureAlgorithm) (hashFunc crypto.Hash, sigAlgo pkix.AlgorithmIdentifier, err error) {
+       var pubType PublicKeyAlgorithm
 
        switch priv := priv.(type) {
        case *rsa.PrivateKey:
-               privType = RSA
-               signatureAlgorithm.Algorithm = oidSignatureSHA256WithRSA
+               pubType = RSA
+               sigAlgo.Algorithm = oidSignatureSHA256WithRSA
                hashFunc = crypto.SHA256
+
        case *ecdsa.PrivateKey:
-               privType = ECDSA
+               pubType = ECDSA
 
                switch priv.Curve {
                case elliptic.P224(), elliptic.P256():
                        hashFunc = crypto.SHA256
-                       signatureAlgorithm.Algorithm = oidSignatureECDSAWithSHA256
+                       sigAlgo.Algorithm = oidSignatureECDSAWithSHA256
                case elliptic.P384():
                        hashFunc = crypto.SHA384
-                       signatureAlgorithm.Algorithm = oidSignatureECDSAWithSHA384
+                       sigAlgo.Algorithm = oidSignatureECDSAWithSHA384
                case elliptic.P521():
                        hashFunc = crypto.SHA512
-                       signatureAlgorithm.Algorithm = oidSignatureECDSAWithSHA512
+                       sigAlgo.Algorithm = oidSignatureECDSAWithSHA512
                default:
-                       return nil, errors.New("x509: unknown elliptic curve")
+                       err = errors.New("x509: unknown elliptic curve")
                }
+
        default:
-               return nil, errors.New("x509: only RSA and ECDSA private keys supported")
+               err = errors.New("x509: only RSA and ECDSA private keys supported")
        }
 
-       if template.SignatureAlgorithm != 0 {
-               found := false
-               for _, details := range signatureAlgorithmDetails {
-                       if details.algo == template.SignatureAlgorithm {
-                               if details.pubKeyAlgo != privType {
-                                       return nil, errors.New("x509: requested SignatureAlgorithm does not match private key type")
-                               }
-                               signatureAlgorithm.Algorithm, hashFunc = details.oid, details.hash
-                               if hashFunc == 0 {
-                                       return nil, errors.New("x509: cannot sign with hash function requested")
-                               }
-                               found = true
-                               break
+       if err != nil {
+               return
+       }
+
+       if requestedSigAlgo == 0 {
+               return
+       }
+
+       found := false
+       for _, details := range signatureAlgorithmDetails {
+               if details.algo == requestedSigAlgo {
+                       if details.pubKeyAlgo != pubType {
+                               err = errors.New("x509: requested SignatureAlgorithm does not match private key type")
+                               return
                        }
+                       sigAlgo.Algorithm, hashFunc = details.oid, details.hash
+                       if hashFunc == 0 {
+                               err = errors.New("x509: cannot sign with hash function requested")
+                               return
+                       }
+                       found = true
+                       break
                }
-               if !found {
-                       return nil, errors.New("x509: unknown SignatureAlgorithm")
-               }
+       }
+
+       if !found {
+               err = errors.New("x509: unknown SignatureAlgorithm")
+       }
+
+       return
+}
+
+// CreateCertificate creates a new certificate based on a template. The
+// following members of template are used: SerialNumber, Subject, NotBefore,
+// NotAfter, KeyUsage, ExtKeyUsage, UnknownExtKeyUsage, BasicConstraintsValid,
+// IsCA, MaxPathLen, SubjectKeyId, DNSNames, PermittedDNSDomainsCritical,
+// PermittedDNSDomains, SignatureAlgorithm.
+//
+// The certificate is signed by parent. If parent is equal to template then the
+// certificate is self-signed. The parameter pub is the public key of the
+// signee and priv is the private key of the signer.
+//
+// The returned slice is the certificate in DER encoding.
+//
+// The only supported key types are RSA and ECDSA (*rsa.PublicKey or
+// *ecdsa.PublicKey for pub, *rsa.PrivateKey or *ecdsa.PrivateKey for priv).
+func CreateCertificate(rand io.Reader, template, parent *Certificate, pub interface{}, priv interface{}) (cert []byte, err error) {
+       hashFunc, signatureAlgorithm, err := signingParamsForPrivateKey(priv, template.SignatureAlgorithm)
+       if err != nil {
+               return nil, err
+       }
+
+       publicKeyBytes, publicKeyAlgorithm, err := marshalPublicKey(pub)
+       if err != nil {
+               return nil, err
        }
 
        if err != nil {
@@ -1559,3 +1590,313 @@ func (c *Certificate) CreateCRL(rand io.Reader, priv interface{}, revokedCerts [
                SignatureValue: asn1.BitString{Bytes: signature, BitLength: len(signature) * 8},
        })
 }
+
+// CertificateRequest represents a PKCS #10, certificate signature request.
+type CertificateRequest struct {
+       Raw                      []byte // Complete ASN.1 DER content (CSR, signature algorithm and signature).
+       RawTBSCertificateRequest []byte // Certificate request info part of raw ASN.1 DER content.
+       RawSubjectPublicKeyInfo  []byte // DER encoded SubjectPublicKeyInfo.
+       RawSubject               []byte // DER encoded Subject.
+
+       Version            int
+       Signature          []byte
+       SignatureAlgorithm SignatureAlgorithm
+
+       PublicKeyAlgorithm PublicKeyAlgorithm
+       PublicKey          interface{}
+
+       Subject pkix.Name
+
+       // Attributes is a collection of attributes providing
+       // additional information about the subject of the certificate.
+       // See RFC 2986 section 4.1.
+       Attributes []pkix.AttributeTypeAndValueSET
+
+       // Extensions contains raw X.509 extensions. When parsing CSRs, this
+       // can be used to extract extensions that are not parsed by this
+       // package.
+       Extensions []pkix.Extension
+
+       // ExtraExtensions contains extensions to be copied, raw, into any
+       // marshaled CSR. Values override any extensions that would otherwise
+       // be produced based on the other fields but are overridden by any
+       // extensions specified in Attributes.
+       //
+       // The ExtraExtensions field is not populated when parsing CSRs, see
+       // Extensions.
+       ExtraExtensions []pkix.Extension
+
+       // Subject Alternate Name values.
+       DNSNames       []string
+       EmailAddresses []string
+       IPAddresses    []net.IP
+}
+
+// These structures reflect the ASN.1 structure of X.509 certificate
+// signature requests (see RFC 2986):
+
+type tbsCertificateRequest struct {
+       Raw        asn1.RawContent
+       Version    int
+       Subject    asn1.RawValue
+       PublicKey  publicKeyInfo
+       Attributes []pkix.AttributeTypeAndValueSET `asn1:"tag:0"`
+}
+
+type certificateRequest struct {
+       Raw                asn1.RawContent
+       TBSCSR             tbsCertificateRequest
+       SignatureAlgorithm pkix.AlgorithmIdentifier
+       SignatureValue     asn1.BitString
+}
+
+// oidExtensionRequest is a PKCS#9 OBJECT IDENTIFIER that indicates requested
+// extensions in a CSR.
+var oidExtensionRequest = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 14}
+
+// CreateCertificateRequest creates a new certificate based on a template. The
+// following members of template are used: Subject, Attributes,
+// SignatureAlgorithm, Extension, DNSNames, EmailAddresses, and IPAddresses.
+// The private key is the private key of the signer.
+//
+// The returned slice is the certificate request in DER encoding.
+//
+// The only supported key types are RSA (*rsa.PrivateKey) and ECDSA
+// (*ecdsa.PrivateKey).
+func CreateCertificateRequest(rand io.Reader, template *CertificateRequest, priv interface{}) (csr []byte, err error) {
+       hashFunc, sigAlgo, err := signingParamsForPrivateKey(priv, template.SignatureAlgorithm)
+       if err != nil {
+               return nil, err
+       }
+
+       var publicKeyBytes []byte
+       var publicKeyAlgorithm pkix.AlgorithmIdentifier
+
+       switch priv := priv.(type) {
+       case *rsa.PrivateKey:
+               publicKeyBytes, publicKeyAlgorithm, err = marshalPublicKey(&priv.PublicKey)
+       case *ecdsa.PrivateKey:
+               publicKeyBytes, publicKeyAlgorithm, err = marshalPublicKey(&priv.PublicKey)
+       default:
+               panic("internal error")
+       }
+
+       if err != nil {
+               return nil, err
+       }
+
+       var extensions []pkix.Extension
+
+       if (len(template.DNSNames) > 0 || len(template.EmailAddresses) > 0 || len(template.IPAddresses) > 0) &&
+               !oidInExtensions(oidExtensionSubjectAltName, template.ExtraExtensions) {
+               sanBytes, err := marshalSANs(template.DNSNames, template.EmailAddresses, template.IPAddresses)
+               if err != nil {
+                       return nil, err
+               }
+
+               extensions = append(extensions, pkix.Extension{
+                       Id:    oidExtensionSubjectAltName,
+                       Value: sanBytes,
+               })
+       }
+
+       extensions = append(extensions, template.ExtraExtensions...)
+
+       var attributes []pkix.AttributeTypeAndValueSET
+       attributes = append(attributes, template.Attributes...)
+
+       if len(extensions) > 0 {
+               // specifiedExtensions contains all the extensions that we
+               // found specified via template.Attributes.
+               specifiedExtensions := make(map[string]bool)
+
+               for _, atvSet := range template.Attributes {
+                       if !atvSet.Type.Equal(oidExtensionRequest) {
+                               continue
+                       }
+
+                       for _, atvs := range atvSet.Value {
+                               for _, atv := range atvs {
+                                       specifiedExtensions[atv.Type.String()] = true
+                               }
+                       }
+               }
+
+               atvs := make([]pkix.AttributeTypeAndValue, 0, len(extensions))
+               for _, e := range extensions {
+                       if specifiedExtensions[e.Id.String()] {
+                               // Attributes already contained a value for
+                               // this extension and it takes priority.
+                               continue
+                       }
+
+                       atvs = append(atvs, pkix.AttributeTypeAndValue{
+                               // There is no place for the critical flag in a CSR.
+                               Type:  e.Id,
+                               Value: e.Value,
+                       })
+               }
+
+               // Append the extensions to an existing attribute if possible.
+               appended := false
+               for _, atvSet := range attributes {
+                       if !atvSet.Type.Equal(oidExtensionRequest) || len(atvSet.Value) == 0 {
+                               continue
+                       }
+
+                       atvSet.Value[0] = append(atvSet.Value[0], atvs...)
+                       appended = true
+                       break
+               }
+
+               // Otherwise, add a new attribute for the extensions.
+               if !appended {
+                       attributes = append(attributes, pkix.AttributeTypeAndValueSET{
+                               Type: oidExtensionRequest,
+                               Value: [][]pkix.AttributeTypeAndValue{
+                                       atvs,
+                               },
+                       })
+               }
+       }
+
+       asn1Subject := template.RawSubject
+       if len(asn1Subject) == 0 {
+               asn1Subject, err = asn1.Marshal(template.Subject.ToRDNSequence())
+               if err != nil {
+                       return
+               }
+       }
+
+       tbsCSR := tbsCertificateRequest{
+               Version: 0, // PKCS #10, RFC 2986
+               Subject: asn1.RawValue{FullBytes: asn1Subject},
+               PublicKey: publicKeyInfo{
+                       Algorithm: publicKeyAlgorithm,
+                       PublicKey: asn1.BitString{
+                               Bytes:     publicKeyBytes,
+                               BitLength: len(publicKeyBytes) * 8,
+                       },
+               },
+               Attributes: attributes,
+       }
+
+       tbsCSRContents, err := asn1.Marshal(tbsCSR)
+       if err != nil {
+               return
+       }
+       tbsCSR.Raw = tbsCSRContents
+
+       h := hashFunc.New()
+       h.Write(tbsCSRContents)
+       digest := h.Sum(nil)
+
+       var signature []byte
+       switch priv := priv.(type) {
+       case *rsa.PrivateKey:
+               signature, err = rsa.SignPKCS1v15(rand, priv, hashFunc, digest)
+       case *ecdsa.PrivateKey:
+               var r, s *big.Int
+               if r, s, err = ecdsa.Sign(rand, priv, digest); err == nil {
+                       signature, err = asn1.Marshal(ecdsaSignature{r, s})
+               }
+       default:
+               panic("internal error")
+       }
+
+       if err != nil {
+               return
+       }
+
+       return asn1.Marshal(certificateRequest{
+               TBSCSR:             tbsCSR,
+               SignatureAlgorithm: sigAlgo,
+               SignatureValue: asn1.BitString{
+                       Bytes:     signature,
+                       BitLength: len(signature) * 8,
+               },
+       })
+}
+
+// ParseCertificateRequest parses a single certificate request from the
+// given ASN.1 DER data.
+func ParseCertificateRequest(asn1Data []byte) (*CertificateRequest, error) {
+       var csr certificateRequest
+
+       rest, err := asn1.Unmarshal(asn1Data, &csr)
+       if err != nil {
+               return nil, err
+       } else if len(rest) != 0 {
+               return nil, asn1.SyntaxError{Msg: "trailing data"}
+       }
+
+       return parseCertificateRequest(&csr)
+}
+
+func parseCertificateRequest(in *certificateRequest) (*CertificateRequest, error) {
+       out := &CertificateRequest{
+               Raw: in.Raw,
+               RawTBSCertificateRequest: in.TBSCSR.Raw,
+               RawSubjectPublicKeyInfo:  in.TBSCSR.PublicKey.Raw,
+               RawSubject:               in.TBSCSR.Subject.FullBytes,
+
+               Signature:          in.SignatureValue.RightAlign(),
+               SignatureAlgorithm: getSignatureAlgorithmFromOID(in.SignatureAlgorithm.Algorithm),
+
+               PublicKeyAlgorithm: getPublicKeyAlgorithmFromOID(in.TBSCSR.PublicKey.Algorithm.Algorithm),
+
+               Version:    in.TBSCSR.Version,
+               Attributes: in.TBSCSR.Attributes,
+       }
+
+       var err error
+       out.PublicKey, err = parsePublicKey(out.PublicKeyAlgorithm, &in.TBSCSR.PublicKey)
+       if err != nil {
+               return nil, err
+       }
+
+       var subject pkix.RDNSequence
+       if _, err := asn1.Unmarshal(in.TBSCSR.Subject.FullBytes, &subject); err != nil {
+               return nil, err
+       }
+
+       out.Subject.FillFromRDNSequence(&subject)
+
+       var extensions []pkix.AttributeTypeAndValue
+
+       for _, atvSet := range in.TBSCSR.Attributes {
+               if !atvSet.Type.Equal(oidExtensionRequest) {
+                       continue
+               }
+
+               for _, atvs := range atvSet.Value {
+                       extensions = append(extensions, atvs...)
+               }
+       }
+
+       out.Extensions = make([]pkix.Extension, 0, len(extensions))
+
+       for _, e := range extensions {
+               value, ok := e.Value.([]byte)
+               if !ok {
+                       return nil, errors.New("x509: extension attribute contained non-OCTET STRING data")
+               }
+
+               out.Extensions = append(out.Extensions, pkix.Extension{
+                       Id:    e.Type,
+                       Value: value,
+               })
+
+               if len(e.Type) == 4 && e.Type[0] == 2 && e.Type[1] == 5 && e.Type[2] == 29 {
+                       switch e.Type[3] {
+                       case 17:
+                               out.DNSNames, out.EmailAddresses, out.IPAddresses, err = parseSANExtension(value)
+                               if err != nil {
+                                       return nil, err
+                               }
+                       }
+               }
+       }
+
+       return out, nil
+}
index 9d727f0fa7c94bad2ce4c2ac0c6e0ec91a6982c2..d158a9d86310871fcf8eadf92153acdab1bf42fe 100644 (file)
@@ -679,11 +679,11 @@ func TestCRLCreation(t *testing.T) {
 
 func fromBase64(in string) []byte {
        out := make([]byte, base64.StdEncoding.DecodedLen(len(in)))
-       _, err := base64.StdEncoding.Decode(out, []byte(in))
+       n, err := base64.StdEncoding.Decode(out, []byte(in))
        if err != nil {
                panic("failed to base64 decode")
        }
-       return out
+       return out[:n]
 }
 
 func TestParseDERCRL(t *testing.T) {
@@ -727,6 +727,7 @@ func TestParsePEMCRL(t *testing.T) {
 }
 
 func TestImports(t *testing.T) {
+       t.Skip("gccgo does not have a go command")
        if err := exec.Command("go", "run", "x509_test_import.go").Run(); err != nil {
                t.Errorf("failed to run x509_test_import.go: %s", err)
        }
@@ -735,3 +736,213 @@ func TestImports(t *testing.T) {
 const derCRLBase64 = "MIINqzCCDJMCAQEwDQYJKoZIhvcNAQEFBQAwVjEZMBcGA1UEAxMQUEtJIEZJTk1FQ0NBTklDQTEVMBMGA1UEChMMRklOTUVDQ0FOSUNBMRUwEwYDVQQLEwxGSU5NRUNDQU5JQ0ExCzAJBgNVBAYTAklUFw0xMTA1MDQxNjU3NDJaFw0xMTA1MDQyMDU3NDJaMIIMBzAhAg4Ze1od49Lt1qIXBydAzhcNMDkwNzE2MDg0MzIyWjAAMCECDl0HSL9bcZ1Ci/UHJ0DPFw0wOTA3MTYwODQzMTNaMAAwIQIOESB9tVAmX3cY7QcnQNAXDTA5MDcxNjA4NDUyMlowADAhAg4S1tGAQ3mHt8uVBydA1RcNMDkwODA0MTUyNTIyWjAAMCECDlQ249Y7vtC25ScHJ0DWFw0wOTA4MDQxNTI1MzdaMAAwIQIOISMop3NkA4PfYwcnQNkXDTA5MDgwNDExMDAzNFowADAhAg56/BMoS29KEShTBydA2hcNMDkwODA0MTEwMTAzWjAAMCECDnBp/22HPH5CSWoHJ0DbFw0wOTA4MDQxMDU0NDlaMAAwIQIOV9IP+8CD8bK+XAcnQNwXDTA5MDgwNDEwNTcxN1owADAhAg4v5aRz0IxWqYiXBydA3RcNMDkwODA0MTA1NzQ1WjAAMCECDlOU34VzvZAybQwHJ0DeFw0wOTA4MDQxMDU4MjFaMAAwIAINO4CD9lluIxcwBydBAxcNMDkwNzIyMTUzMTU5WjAAMCECDgOllfO8Y1QA7/wHJ0ExFw0wOTA3MjQxMTQxNDNaMAAwIQIOJBX7jbiCdRdyjgcnQUQXDTA5MDkxNjA5MzAwOFowADAhAg5iYSAgmDrlH/RZBydBRRcNMDkwOTE2MDkzMDE3WjAAMCECDmu6k6srP3jcMaQHJ0FRFw0wOTA4MDQxMDU2NDBaMAAwIQIOX8aHlO0V+WVH4QcnQVMXDTA5MDgwNDEwNTcyOVowADAhAg5flK2rg3NnsRgDBydBzhcNMTEwMjAxMTUzMzQ2WjAAMCECDg35yJDL1jOPTgoHJ0HPFw0xMTAyMDExNTM0MjZaMAAwIQIOMyFJ6+e9iiGVBQcnQdAXDTA5MDkxODEzMjAwNVowADAhAg5Emb/Oykucmn8fBydB1xcNMDkwOTIxMTAxMDQ3WjAAMCECDjQKCncV+MnUavMHJ0HaFw0wOTA5MjIwODE1MjZaMAAwIQIOaxiFUt3dpd+tPwcnQfQXDTEwMDYxODA4NDI1MVowADAhAg5G7P8nO0tkrMt7BydB9RcNMTAwNjE4MDg0MjMwWjAAMCECDmTCC3SXhmDRst4HJ0H2Fw0wOTA5MjgxMjA3MjBaMAAwIQIOHoGhUr/pRwzTKgcnQfcXDTA5MDkyODEyMDcyNFowADAhAg50wrcrCiw8mQmPBydCBBcNMTAwMjE2MTMwMTA2WjAAMCECDifWmkvwyhEqwEcHJ0IFFw0xMDAyMTYxMzAxMjBaMAAwIQIOfgPmlW9fg+osNgcnQhwXDTEwMDQxMzA5NTIwMFowADAhAg4YHAGuA6LgCk7tBydCHRcNMTAwNDEzMDk1MTM4WjAAMCECDi1zH1bxkNJhokAHJ0IsFw0xMDA0MTMwOTU5MzBaMAAwIQIOMipNccsb/wo2fwcnQi0XDTEwMDQxMzA5NTkwMFowADAhAg46lCmvPl4GpP6ABydCShcNMTAwMTE5MDk1MjE3WjAAMCECDjaTcaj+wBpcGAsHJ0JLFw0xMDAxMTkwOTUyMzRaMAAwIQIOOMC13EOrBuxIOQcnQloXDTEwMDIwMTA5NDcwNVowADAhAg5KmZl+krz4RsmrBydCWxcNMTAwMjAxMDk0NjQwWjAAMCECDmLG3zQJ/fzdSsUHJ0JiFw0xMDAzMDEwOTUxNDBaMAAwIQIOP39ksgHdojf4owcnQmMXDTEwMDMwMTA5NTExN1owADAhAg4LDQzvWNRlD6v9BydCZBcNMTAwMzAxMDk0NjIyWjAAMCECDkmNfeclaFhIaaUHJ0JlFw0xMDAzMDEwOTQ2MDVaMAAwIQIOT/qWWfpH/m8NTwcnQpQXDTEwMDUxMTA5MTgyMVowADAhAg5m/ksYxvCEgJSvBydClRcNMTAwNTExMDkxODAxWjAAMCECDgvf3Ohq6JOPU9AHJ0KWFw0xMDA1MTEwOTIxMjNaMAAwIQIOKSPas10z4jNVIQcnQpcXDTEwMDUxMTA5MjEwMlowADAhAg4mCWmhoZ3lyKCDBydCohcNMTEwNDI4MTEwMjI1WjAAMCECDkeiyRsBMK0Gvr4HJ0KjFw0xMTA0MjgxMTAyMDdaMAAwIQIOa09b/nH2+55SSwcnQq4XDTExMDQwMTA4Mjk0NlowADAhAg5O7M7iq7gGplr1BydCrxcNMTEwNDAxMDgzMDE3WjAAMCECDjlT6mJxUjTvyogHJ0K1Fw0xMTAxMjcxNTQ4NTJaMAAwIQIODS/l4UUFLe21NAcnQrYXDTExMDEyNzE1NDgyOFowADAhAg5lPRA0XdOUF6lSBydDHhcNMTEwMTI4MTQzNTA1WjAAMCECDixKX4fFGGpENwgHJ0MfFw0xMTAxMjgxNDM1MzBaMAAwIQIORNBkqsPnpKTtbAcnQ08XDTEwMDkwOTA4NDg0MlowADAhAg5QL+EMM3lohedEBydDUBcNMTAwOTA5MDg0ODE5WjAAMCECDlhDnHK+HiTRAXcHJ0NUFw0xMDEwMTkxNjIxNDBaMAAwIQIOdBFqAzq/INz53gcnQ1UXDTEwMTAxOTE2MjA0NFowADAhAg4OjR7s8MgKles1BydDWhcNMTEwMTI3MTY1MzM2WjAAMCECDmfR/elHee+d0SoHJ0NbFw0xMTAxMjcxNjUzNTZaMAAwIQIOBTKv2ui+KFMI+wcnQ5YXDTEwMDkxNTEwMjE1N1owADAhAg49F3c/GSah+oRUBydDmxcNMTEwMTI3MTczMjMzWjAAMCECDggv4I61WwpKFMMHJ0OcFw0xMTAxMjcxNzMyNTVaMAAwIQIOXx/Y8sEvwS10LAcnQ6UXDTExMDEyODExMjkzN1owADAhAg5LSLbnVrSKaw/9BydDphcNMTEwMTI4MTEyOTIwWjAAMCECDmFFoCuhKUeACQQHJ0PfFw0xMTAxMTExMDE3MzdaMAAwIQIOQTDdFh2fSPF6AAcnQ+AXDTExMDExMTEwMTcxMFowADAhAg5B8AOXX61FpvbbBydD5RcNMTAxMDA2MTAxNDM2WjAAMCECDh41P2Gmi7PkwI4HJ0PmFw0xMDEwMDYxMDE2MjVaMAAwIQIOWUHGLQCd+Ale9gcnQ/0XDTExMDUwMjA3NTYxMFowADAhAg5Z2c9AYkikmgWOBydD/hcNMTEwNTAyMDc1NjM0WjAAMCECDmf/UD+/h8nf+74HJ0QVFw0xMTA0MTUwNzI4MzNaMAAwIQIOICvj4epy3MrqfwcnRBYXDTExMDQxNTA3Mjg1NlowADAhAg4bouRMfOYqgv4xBydEHxcNMTEwMzA4MTYyNDI1WjAAMCECDhebWHGoKiTp7pEHJ0QgFw0xMTAzMDgxNjI0NDhaMAAwIQIOX+qnxxAqJ8LtawcnRDcXDTExMDEzMTE1MTIyOFowADAhAg4j0fICqZ+wkOdqBydEOBcNMTEwMTMxMTUxMTQxWjAAMCECDhmXjsV4SUpWtAMHJ0RLFw0xMTAxMjgxMTI0MTJaMAAwIQIODno/w+zG43kkTwcnREwXDTExMDEyODExMjM1MlowADAhAg4b1gc88767Fr+LBydETxcNMTEwMTI4MTEwMjA4WjAAMCECDn+M3Pa1w2nyFeUHJ0RQFw0xMTAxMjgxMDU4NDVaMAAwIQIOaduoyIH61tqybAcnRJUXDTEwMTIxNTA5NDMyMlowADAhAg4nLqQPkyi3ESAKBydElhcNMTAxMjE1MDk0MzM2WjAAMCECDi504NIMH8578gQHJ0SbFw0xMTAyMTQxNDA1NDFaMAAwIQIOGuaM8PDaC5u1egcnRJwXDTExMDIxNDE0MDYwNFowADAhAg4ehYq/BXGnB5PWBydEnxcNMTEwMjA0MDgwOTUxWjAAMCECDkSD4eS4FxW5H20HJ0SgFw0xMTAyMDQwODA5MjVaMAAwIQIOOCcb6ilYObt1egcnRKEXDTExMDEyNjEwNDEyOVowADAhAg58tISWCCwFnKGnBydEohcNMTEwMjA0MDgxMzQyWjAAMCECDn5rjtabY/L/WL0HJ0TJFw0xMTAyMDQxMTAzNDFaMAAwDQYJKoZIhvcNAQEFBQADggEBAGnF2Gs0+LNiYCW1Ipm83OXQYP/bd5tFFRzyz3iepFqNfYs4D68/QihjFoRHQoXEB0OEe1tvaVnnPGnEOpi6krwekquMxo4H88B5SlyiFIqemCOIss0SxlCFs69LmfRYvPPvPEhoXtQ3ZThe0UvKG83GOklhvGl6OaiRf4Mt+m8zOT4Wox/j6aOBK6cw6qKCdmD+Yj1rrNqFGg1CnSWMoD6S6mwNgkzwdBUJZ22BwrzAAo4RHa2Uy3ef1FjwD0XtU5N3uDSxGGBEDvOe5z82rps3E22FpAA8eYl8kaXtmWqyvYU0epp4brGuTxCuBMCAsxt/OjIjeNNQbBGkwxgfYA0="
 
 const pemCRLBase64 = "LS0tLS1CRUdJTiBYNTA5IENSTC0tLS0tDQpNSUlCOWpDQ0FWOENBUUV3RFFZSktvWklodmNOQVFFRkJRQXdiREVhTUJnR0ExVUVDaE1SVWxOQklGTmxZM1Z5DQphWFI1SUVsdVl5NHhIakFjQmdOVkJBTVRGVkpUUVNCUWRXSnNhV01nVW05dmRDQkRRU0IyTVRFdU1Dd0dDU3FHDQpTSWIzRFFFSkFSWWZjbk5oYTJWdmJuSnZiM1J6YVdkdVFISnpZWE5sWTNWeWFYUjVMbU52YlJjTk1URXdNakl6DQpNVGt5T0RNd1doY05NVEV3T0RJeU1Ua3lPRE13V2pDQmpEQktBaEVBckRxb2g5RkhKSFhUN09QZ3V1bjQrQmNODQpNRGt4TVRBeU1UUXlOekE1V2pBbU1Bb0dBMVVkRlFRRENnRUpNQmdHQTFVZEdBUVJHQTh5TURBNU1URXdNakUwDQpNalExTlZvd1BnSVJBTEd6blowOTVQQjVhQU9MUGc1N2ZNTVhEVEF5TVRBeU16RTBOVEF4TkZvd0dqQVlCZ05WDQpIUmdFRVJnUE1qQXdNakV3TWpNeE5EVXdNVFJhb0RBd0xqQWZCZ05WSFNNRUdEQVdnQlQxVERGNlVRTS9MTmVMDQpsNWx2cUhHUXEzZzltekFMQmdOVkhSUUVCQUlDQUlRd0RRWUpLb1pJaHZjTkFRRUZCUUFEZ1lFQUZVNUFzNk16DQpxNVBSc2lmYW9iUVBHaDFhSkx5QytNczVBZ2MwYld5QTNHQWR4dXI1U3BQWmVSV0NCamlQL01FSEJXSkNsQkhQDQpHUmNxNXlJZDNFakRrYUV5eFJhK2k2N0x6dmhJNmMyOUVlNks5cFNZd2ppLzdSVWhtbW5Qclh0VHhsTDBsckxyDQptUVFKNnhoRFJhNUczUUE0Q21VZHNITnZicnpnbUNZcHZWRT0NCi0tLS0tRU5EIFg1MDkgQ1JMLS0tLS0NCg0K"
+
+func TestCreateCertificateRequest(t *testing.T) {
+       random := rand.Reader
+
+       block, _ := pem.Decode([]byte(pemPrivateKey))
+       rsaPriv, err := ParsePKCS1PrivateKey(block.Bytes)
+       if err != nil {
+               t.Fatalf("Failed to parse private key: %s", err)
+       }
+
+       ecdsa256Priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+       if err != nil {
+               t.Fatalf("Failed to generate ECDSA key: %s", err)
+       }
+
+       ecdsa384Priv, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
+       if err != nil {
+               t.Fatalf("Failed to generate ECDSA key: %s", err)
+       }
+
+       ecdsa521Priv, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
+       if err != nil {
+               t.Fatalf("Failed to generate ECDSA key: %s", err)
+       }
+
+       tests := []struct {
+               name    string
+               priv    interface{}
+               sigAlgo SignatureAlgorithm
+       }{
+               {"RSA", rsaPriv, SHA1WithRSA},
+               {"ECDSA-256", ecdsa256Priv, ECDSAWithSHA1},
+               {"ECDSA-384", ecdsa384Priv, ECDSAWithSHA1},
+               {"ECDSA-521", ecdsa521Priv, ECDSAWithSHA1},
+       }
+
+       for _, test := range tests {
+               template := CertificateRequest{
+                       Subject: pkix.Name{
+                               CommonName:   "test.example.com",
+                               Organization: []string{"Σ Acme Co"},
+                       },
+                       SignatureAlgorithm: test.sigAlgo,
+                       DNSNames:           []string{"test.example.com"},
+                       EmailAddresses:     []string{"gopher@golang.org"},
+                       IPAddresses:        []net.IP{net.IPv4(127, 0, 0, 1).To4(), net.ParseIP("2001:4860:0:2001::68")},
+               }
+
+               derBytes, err := CreateCertificateRequest(random, &template, test.priv)
+               if err != nil {
+                       t.Errorf("%s: failed to create certificate request: %s", test.name, err)
+                       continue
+               }
+
+               out, err := ParseCertificateRequest(derBytes)
+               if err != nil {
+                       t.Errorf("%s: failed to create certificate request: %s", test.name, err)
+                       continue
+               }
+
+               if out.Subject.CommonName != template.Subject.CommonName {
+                       t.Errorf("%s: output subject common name and template subject common name don't match", test.name)
+               } else if len(out.Subject.Organization) != len(template.Subject.Organization) {
+                       t.Errorf("%s: output subject organisation and template subject organisation don't match", test.name)
+               } else if len(out.DNSNames) != len(template.DNSNames) {
+                       t.Errorf("%s: output DNS names and template DNS names don't match", test.name)
+               } else if len(out.EmailAddresses) != len(template.EmailAddresses) {
+                       t.Errorf("%s: output email addresses and template email addresses don't match", test.name)
+               } else if len(out.IPAddresses) != len(template.IPAddresses) {
+                       t.Errorf("%s: output IP addresses and template IP addresses names don't match", test.name)
+               }
+       }
+}
+
+func marshalAndParseCSR(t *testing.T, template *CertificateRequest) *CertificateRequest {
+       block, _ := pem.Decode([]byte(pemPrivateKey))
+       rsaPriv, err := ParsePKCS1PrivateKey(block.Bytes)
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       derBytes, err := CreateCertificateRequest(rand.Reader, template, rsaPriv)
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       csr, err := ParseCertificateRequest(derBytes)
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       return csr
+}
+
+func TestCertificateRequestOverrides(t *testing.T) {
+       sanContents, err := marshalSANs([]string{"foo.example.com"}, nil, nil)
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       template := CertificateRequest{
+               Subject: pkix.Name{
+                       CommonName:   "test.example.com",
+                       Organization: []string{"Σ Acme Co"},
+               },
+               DNSNames: []string{"test.example.com"},
+
+               // An explicit extension should override the DNSNames from the
+               // template.
+               ExtraExtensions: []pkix.Extension{
+                       pkix.Extension{
+                               Id:    oidExtensionSubjectAltName,
+                               Value: sanContents,
+                       },
+               },
+       }
+
+       csr := marshalAndParseCSR(t, &template)
+
+       if len(csr.DNSNames) != 1 || csr.DNSNames[0] != "foo.example.com" {
+               t.Errorf("Extension did not override template. Got %v\n", csr.DNSNames)
+       }
+
+       // If there is already an attribute with X.509 extensions then the
+       // extra extensions should be added to it rather than creating a CSR
+       // with two extension attributes.
+
+       template.Attributes = []pkix.AttributeTypeAndValueSET{
+               pkix.AttributeTypeAndValueSET{
+                       Type: oidExtensionRequest,
+                       Value: [][]pkix.AttributeTypeAndValue{
+                               []pkix.AttributeTypeAndValue{
+                                       pkix.AttributeTypeAndValue{
+                                               Type:  oidExtensionAuthorityInfoAccess,
+                                               Value: []byte("foo"),
+                                       },
+                               },
+                       },
+               },
+       }
+
+       csr = marshalAndParseCSR(t, &template)
+       if l := len(csr.Attributes); l != 1 {
+               t.Errorf("incorrect number of attributes: %d\n", l)
+       }
+
+       if !csr.Attributes[0].Type.Equal(oidExtensionRequest) ||
+               len(csr.Attributes[0].Value) != 1 ||
+               len(csr.Attributes[0].Value[0]) != 2 {
+               t.Errorf("bad attributes: %#v\n", csr.Attributes)
+       }
+
+       sanContents2, err := marshalSANs([]string{"foo2.example.com"}, nil, nil)
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       // Extensions in Attributes should override those in ExtraExtensions.
+       template.Attributes[0].Value[0] = append(template.Attributes[0].Value[0], pkix.AttributeTypeAndValue{
+               Type:  oidExtensionSubjectAltName,
+               Value: sanContents2,
+       })
+
+       csr = marshalAndParseCSR(t, &template)
+
+       if len(csr.DNSNames) != 1 || csr.DNSNames[0] != "foo2.example.com" {
+               t.Errorf("Attributes did not override ExtraExtensions. Got %v\n", csr.DNSNames)
+       }
+}
+
+func TestParseCertificateRequest(t *testing.T) {
+       csrBytes := fromBase64(csrBase64)
+       csr, err := ParseCertificateRequest(csrBytes)
+       if err != nil {
+               t.Fatalf("failed to parse CSR: %s", err)
+       }
+
+       if len(csr.EmailAddresses) != 1 || csr.EmailAddresses[0] != "gopher@golang.org" {
+               t.Errorf("incorrect email addresses found: %v", csr.EmailAddresses)
+       }
+
+       if len(csr.DNSNames) != 1 || csr.DNSNames[0] != "test.example.com" {
+               t.Errorf("incorrect DNS names found: %v", csr.DNSNames)
+       }
+
+       if len(csr.Subject.Country) != 1 || csr.Subject.Country[0] != "AU" {
+               t.Errorf("incorrect Subject name: %v", csr.Subject)
+       }
+
+       found := false
+       for _, e := range csr.Extensions {
+               if e.Id.Equal(oidExtensionBasicConstraints) {
+                       found = true
+                       break
+               }
+       }
+       if !found {
+               t.Errorf("basic constraints extension not found in CSR")
+       }
+}
+
+// This CSR was generated with OpenSSL:
+//  openssl req -out CSR.csr -new -newkey rsa:2048 -nodes -keyout privateKey.key -config openssl.cnf
+//
+// The openssl.cnf needs to include this section:
+//   [ v3_req ]
+//   basicConstraints = CA:FALSE
+//   keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+//   subjectAltName = email:gopher@golang.org,DNS:test.example.com
+const csrBase64 = "MIIC4zCCAcsCAQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOY+MVedRg2JEnyeLcSzcsMv2VcsTfkB5+Etd6hihAh6MrGezNyASMMKuQN6YhCX1icQDiQtGsDLTtheNnSXK06tAhHjAP/hGlszRJp+5+rP2M58fDBAkUBEhskbCUWwpY14jFtVuGNJ8vF8h8IeczdolvQhX9lVai9G0EUXJMliMKdjA899H0mRs9PzHyidyrXFNiZlQXfD8Kg7gETn2Ny965iyI6ujAIYSCvam6TnxRHYH2MBKyVGvsYGbPYUQJCsgdgyajEg6ekihvQY3SzO1HSAlZAd7d1QYO4VeWJ2mY6Wu3Jpmh+AmG19S9CcHqGjd0bhuAX9cpPOKgnEmqn0CAwEAAaBZMFcGCSqGSIb3DQEJDjFKMEgwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwLgYDVR0RBCcwJYERZ29waGVyQGdvbGFuZy5vcmeCEHRlc3QuZXhhbXBsZS5jb20wDQYJKoZIhvcNAQEFBQADggEBAC9+QpKfdabxwCWwf4IEe1cKjdXLS1ScSuw27a3kZzQiPV78WJMa6dB8dqhdH5BRwGZ/qsgLrO6ZHlNeIv2Ib41Ccq71ecHW/nXc94A1BzJ/bVdI9LZcmTUvR1/m1jCpN7UqQ0ml1u9VihK7Pe762hEYxuWDQzYEU0l15S/bXmqeq3eF1A59XT/2jwe5+NV0Wwf4UQlkTXsAQMsJ+KzrQafd8Qv2A49o048uRvmjeJDrXLawGVianZ7D5A6Fpd1rZh6XcjqBpmgLw41DRQWENOdzhy+HyphKRv1MlY8OLkNqpGMhu8DdgJVGoT16DGiickoEa7Z3UCPVNgdTkT9jq7U="
index c04adde1fc1603dafc35d4cd04696223555b6aa8..c0b38a24940fcade4452df0b5cdae6369420d3df 100644 (file)
@@ -160,27 +160,19 @@ func convertAssign(dest, src interface{}) error {
                        reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
                        reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
                        reflect.Float32, reflect.Float64:
-                       *d = fmt.Sprintf("%v", src)
+                       *d = asString(src)
                        return nil
                }
        case *[]byte:
                sv = reflect.ValueOf(src)
-               switch sv.Kind() {
-               case reflect.Bool,
-                       reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
-                       reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
-                       reflect.Float32, reflect.Float64:
-                       *d = []byte(fmt.Sprintf("%v", src))
+               if b, ok := asBytes(nil, sv); ok {
+                       *d = b
                        return nil
                }
        case *RawBytes:
                sv = reflect.ValueOf(src)
-               switch sv.Kind() {
-               case reflect.Bool,
-                       reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
-                       reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
-                       reflect.Float32, reflect.Float64:
-                       *d = RawBytes(fmt.Sprintf("%v", src))
+               if b, ok := asBytes([]byte(*d)[:0], sv); ok {
+                       *d = RawBytes(b)
                        return nil
                }
        case *bool:
@@ -271,5 +263,37 @@ func asString(src interface{}) string {
        case []byte:
                return string(v)
        }
+       rv := reflect.ValueOf(src)
+       switch rv.Kind() {
+       case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+               return strconv.FormatInt(rv.Int(), 10)
+       case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+               return strconv.FormatUint(rv.Uint(), 10)
+       case reflect.Float64:
+               return strconv.FormatFloat(rv.Float(), 'g', -1, 64)
+       case reflect.Float32:
+               return strconv.FormatFloat(rv.Float(), 'g', -1, 32)
+       case reflect.Bool:
+               return strconv.FormatBool(rv.Bool())
+       }
        return fmt.Sprintf("%v", src)
 }
+
+func asBytes(buf []byte, rv reflect.Value) (b []byte, ok bool) {
+       switch rv.Kind() {
+       case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+               return strconv.AppendInt(buf, rv.Int(), 10), true
+       case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+               return strconv.AppendUint(buf, rv.Uint(), 10), true
+       case reflect.Float32:
+               return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 32), true
+       case reflect.Float64:
+               return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 64), true
+       case reflect.Bool:
+               return strconv.AppendBool(buf, rv.Bool()), true
+       case reflect.String:
+               s := rv.String()
+               return append(buf, s...), true
+       }
+       return
+}
index a39c2c54fba68599c2e87ba76ce9345e9608c1b0..6e248301283f9613afc43db8e7f6a8316d1e52de 100644 (file)
@@ -8,6 +8,7 @@ import (
        "database/sql/driver"
        "fmt"
        "reflect"
+       "runtime"
        "testing"
        "time"
 )
@@ -279,3 +280,58 @@ func TestValueConverters(t *testing.T) {
                }
        }
 }
+
+// Tests that assigning to RawBytes doesn't allocate (and also works).
+func TestRawBytesAllocs(t *testing.T) {
+       buf := make(RawBytes, 10)
+       test := func(name string, in interface{}, want string) {
+               if err := convertAssign(&buf, in); err != nil {
+                       t.Fatalf("%s: convertAssign = %v", name, err)
+               }
+               match := len(buf) == len(want)
+               if match {
+                       for i, b := range buf {
+                               if want[i] != b {
+                                       match = false
+                                       break
+                               }
+                       }
+               }
+               if !match {
+                       t.Fatalf("%s: got %q (len %d); want %q (len %d)", name, buf, len(buf), want, len(want))
+               }
+       }
+       n := testing.AllocsPerRun(100, func() {
+               test("uint64", uint64(12345678), "12345678")
+               test("uint32", uint32(1234), "1234")
+               test("uint16", uint16(12), "12")
+               test("uint8", uint8(1), "1")
+               test("uint", uint(123), "123")
+               test("int", int(123), "123")
+               test("int8", int8(1), "1")
+               test("int16", int16(12), "12")
+               test("int32", int32(1234), "1234")
+               test("int64", int64(12345678), "12345678")
+               test("float32", float32(1.5), "1.5")
+               test("float64", float64(64), "64")
+               test("bool", false, "false")
+       })
+
+       // The numbers below are only valid for 64-bit interface word sizes,
+       // and gc. With 32-bit words there are more convT2E allocs, and
+       // with gccgo, only pointers currently go in interface data.
+       // So only care on amd64 gc for now.
+       measureAllocs := runtime.GOARCH == "amd64" && runtime.Compiler == "gc"
+
+       if n > 0.5 && measureAllocs {
+               t.Fatalf("allocs = %v; want 0", n)
+       }
+
+       // This one involves a convT2E allocation, string -> interface{}
+       n = testing.AllocsPerRun(100, func() {
+               test("string", "foo", "foo")
+       })
+       if n > 1.5 && measureAllocs {
+               t.Fatalf("allocs = %v; want max 1", n)
+       }
+}
index 68503c742f6e2900e1ce99aeca7235cdb43ac0ac..2aa0c270ff2509b67954fd101df039166a1fb963 100644 (file)
@@ -207,6 +207,7 @@ const (
        formRef8        format = 0x14
        formRefUdata    format = 0x15
        formIndirect    format = 0x16
+       // The following are new in DWARF 4.
        formSecOffset   format = 0x17
        formExprloc     format = 0x18
        formFlagPresent format = 0x19
@@ -264,15 +265,22 @@ const (
        TagVariantPart            Tag = 0x33
        TagVariable               Tag = 0x34
        TagVolatileType           Tag = 0x35
-       TagDwarfProcedure         Tag = 0x36
-       TagRestrictType           Tag = 0x37
-       TagInterfaceType          Tag = 0x38
-       TagNamespace              Tag = 0x39
-       TagImportedModule         Tag = 0x3A
-       TagUnspecifiedType        Tag = 0x3B
-       TagPartialUnit            Tag = 0x3C
-       TagImportedUnit           Tag = 0x3D
-       TagMutableType            Tag = 0x3E
+       // The following are new in DWARF 3.
+       TagDwarfProcedure  Tag = 0x36
+       TagRestrictType    Tag = 0x37
+       TagInterfaceType   Tag = 0x38
+       TagNamespace       Tag = 0x39
+       TagImportedModule  Tag = 0x3A
+       TagUnspecifiedType Tag = 0x3B
+       TagPartialUnit     Tag = 0x3C
+       TagImportedUnit    Tag = 0x3D
+       TagMutableType     Tag = 0x3E // Later removed from DWARF.
+       TagCondition       Tag = 0x3F
+       TagSharedType      Tag = 0x40
+       // The following are new in DWARF 4.
+       TagTypeUnit            Tag = 0x41
+       TagRvalueReferenceType Tag = 0x42
+       TagTemplateAlias       Tag = 0x43
 )
 
 var tagNames = [...]string{
@@ -332,6 +340,11 @@ var tagNames = [...]string{
        TagPartialUnit:            "PartialUnit",
        TagImportedUnit:           "ImportedUnit",
        TagMutableType:            "MutableType",
+       TagCondition:              "Condition",
+       TagSharedType:             "SharedType",
+       TagTypeUnit:               "TypeUnit",
+       TagRvalueReferenceType:    "RvalueReferenceType",
+       TagTemplateAlias:          "TemplateAlias",
 }
 
 func (t Tag) String() string {
index e0d3229fb4942f2ab38338ead4fa258880bb49c9..1772221633f11d963e5e1731603689879aa68fd3 100644 (file)
@@ -396,3 +396,15 @@ func (r *Reader) SkipChildren() {
                }
        }
 }
+
+// clone returns a copy of the reader.  This is used by the typeReader
+// interface.
+func (r *Reader) clone() typeReader {
+       return r.d.Reader()
+}
+
+// offset returns the current buffer offset.  This is used by the
+// typeReader interface.
+func (r *Reader) offset() Offset {
+       return r.b.off
+}
index 75798925296cff7375db930854e61f24ee67ae6c..c1b3f37aca9618ebbf5aa1f07eb691abeba9cfaa 100644 (file)
@@ -26,6 +26,7 @@ type Data struct {
        abbrevCache map[uint32]abbrevTable
        order       binary.ByteOrder
        typeCache   map[Offset]Type
+       typeSigs    map[uint64]*typeUnit
        unit        []unit
 }
 
@@ -49,6 +50,7 @@ func New(abbrev, aranges, frame, info, line, pubnames, ranges, str []byte) (*Dat
                str:         str,
                abbrevCache: make(map[uint32]abbrevTable),
                typeCache:   make(map[Offset]Type),
+               typeSigs:    make(map[uint64]*typeUnit),
        }
 
        // Sniff .debug_info to figure out byte order.
@@ -75,3 +77,11 @@ func New(abbrev, aranges, frame, info, line, pubnames, ranges, str []byte) (*Dat
        d.unit = u
        return d, nil
 }
+
+// AddTypes will add one .debug_types section to the DWARF data.  A
+// typical object with DWARF version 4 debug info will have multiple
+// .debug_types sections.  The name is used for error reporting only,
+// and serves to distinguish one .debug_types section from another.
+func (d *Data) AddTypes(name string, types []byte) error {
+       return d.parseTypes(name, types)
+}
diff --git a/libgo/go/debug/dwarf/testdata/typedef.elf4 b/libgo/go/debug/dwarf/testdata/typedef.elf4
new file mode 100644 (file)
index 0000000..3d5a5a1
Binary files /dev/null and b/libgo/go/debug/dwarf/testdata/typedef.elf4 differ
index 1fbae6c144ea53d609dc547dc3f76a4c9182ff72..68866d0b7bfbbf4cd3e44aa1431f6bd01ea07c90 100644 (file)
@@ -251,23 +251,37 @@ func (t *TypedefType) String() string { return t.Name }
 
 func (t *TypedefType) Size() int64 { return t.Type.Size() }
 
+// typeReader is used to read from either the info section or the
+// types section.
+type typeReader interface {
+       Seek(Offset)
+       Next() (*Entry, error)
+       clone() typeReader
+       offset() Offset
+}
+
+// Type reads the type at off in the DWARF ``info'' section.
 func (d *Data) Type(off Offset) (Type, error) {
-       if t, ok := d.typeCache[off]; ok {
+       return d.readType("info", d.Reader(), off, d.typeCache)
+}
+
+// readType reads a type from r at off of name using and updating a
+// type cache.
+func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Offset]Type) (Type, error) {
+       if t, ok := typeCache[off]; ok {
                return t, nil
        }
-
-       r := d.Reader()
        r.Seek(off)
        e, err := r.Next()
        if err != nil {
                return nil, err
        }
        if e == nil || e.Offset != off {
-               return nil, DecodeError{"info", off, "no type at offset"}
+               return nil, DecodeError{name, off, "no type at offset"}
        }
 
        // Parse type from Entry.
-       // Must always set d.typeCache[off] before calling
+       // Must always set typeCache[off] before calling
        // d.Type recursively, to handle circular types correctly.
        var typ Type
 
@@ -290,7 +304,7 @@ func (d *Data) Type(off Offset) (Type, error) {
                                return nil
                        }
                        if kid == nil {
-                               err = DecodeError{"info", r.b.off, "unexpected end of DWARF entries"}
+                               err = DecodeError{name, r.offset(), "unexpected end of DWARF entries"}
                                return nil
                        }
                        if kid.Tag == 0 {
@@ -313,15 +327,21 @@ func (d *Data) Type(off Offset) (Type, error) {
        // Get Type referred to by Entry's AttrType field.
        // Set err if error happens.  Not having a type is an error.
        typeOf := func(e *Entry) Type {
-               toff, ok := e.Val(AttrType).(Offset)
-               if !ok {
+               tval := e.Val(AttrType)
+               var t Type
+               switch toff := tval.(type) {
+               case Offset:
+                       if t, err = d.readType(name, r.clone(), toff, typeCache); err != nil {
+                               return nil
+                       }
+               case uint64:
+                       if t, err = d.sigToType(toff); err != nil {
+                               return nil
+                       }
+               default:
                        // It appears that no Type means "void".
                        return new(VoidType)
                }
-               var t Type
-               if t, err = d.Type(toff); err != nil {
-                       return nil
-               }
                return t
        }
 
@@ -337,7 +357,7 @@ func (d *Data) Type(off Offset) (Type, error) {
                //      dimensions are in left to right order.
                t := new(ArrayType)
                typ = t
-               d.typeCache[off] = t
+               typeCache[off] = t
                if t.Type = typeOf(e); err != nil {
                        goto Error
                }
@@ -363,7 +383,7 @@ func (d *Data) Type(off Offset) (Type, error) {
                                }
                                ndim++
                        case TagEnumerationType:
-                               err = DecodeError{"info", kid.Offset, "cannot handle enumeration type as array bound"}
+                               err = DecodeError{name, kid.Offset, "cannot handle enumeration type as array bound"}
                                goto Error
                        }
                }
@@ -383,12 +403,12 @@ func (d *Data) Type(off Offset) (Type, error) {
                name, _ := e.Val(AttrName).(string)
                enc, ok := e.Val(AttrEncoding).(int64)
                if !ok {
-                       err = DecodeError{"info", e.Offset, "missing encoding attribute for " + name}
+                       err = DecodeError{name, e.Offset, "missing encoding attribute for " + name}
                        goto Error
                }
                switch enc {
                default:
-                       err = DecodeError{"info", e.Offset, "unrecognized encoding attribute value"}
+                       err = DecodeError{name, e.Offset, "unrecognized encoding attribute value"}
                        goto Error
 
                case encAddress:
@@ -408,7 +428,7 @@ func (d *Data) Type(off Offset) (Type, error) {
                case encUnsignedChar:
                        typ = new(UcharType)
                }
-               d.typeCache[off] = typ
+               typeCache[off] = typ
                t := typ.(interface {
                        Basic() *BasicType
                }).Basic()
@@ -433,7 +453,7 @@ func (d *Data) Type(off Offset) (Type, error) {
                // There is much more to handle C++, all ignored for now.
                t := new(StructType)
                typ = t
-               d.typeCache[off] = t
+               typeCache[off] = t
                switch e.Tag {
                case TagClassType:
                        t.Kind = "class"
@@ -453,12 +473,13 @@ func (d *Data) Type(off Offset) (Type, error) {
                                if f.Type = typeOf(kid); err != nil {
                                        goto Error
                                }
-                               if loc, ok := kid.Val(AttrDataMemberLoc).([]byte); ok {
+                               switch loc := kid.Val(AttrDataMemberLoc).(type) {
+                               case []byte:
                                        // TODO: Should have original compilation
                                        // unit here, not unknownFormat.
                                        b := makeBuf(d, unknownFormat{}, "location", 0, loc)
                                        if b.uint8() != opPlusUconst {
-                                               err = DecodeError{"info", kid.Offset, "unexpected opcode"}
+                                               err = DecodeError{name, kid.Offset, "unexpected opcode"}
                                                goto Error
                                        }
                                        f.ByteOffset = int64(b.uint())
@@ -466,6 +487,8 @@ func (d *Data) Type(off Offset) (Type, error) {
                                                err = b.err
                                                goto Error
                                        }
+                               case int64:
+                                       f.ByteOffset = loc
                                }
 
                                haveBitOffset := false
@@ -502,7 +525,7 @@ func (d *Data) Type(off Offset) (Type, error) {
                //      AttrType: subtype
                t := new(QualType)
                typ = t
-               d.typeCache[off] = t
+               typeCache[off] = t
                if t.Type = typeOf(e); err != nil {
                        goto Error
                }
@@ -526,7 +549,7 @@ func (d *Data) Type(off Offset) (Type, error) {
                //              AttrConstValue: value of constant
                t := new(EnumType)
                typ = t
-               d.typeCache[off] = t
+               typeCache[off] = t
                t.EnumName, _ = e.Val(AttrName).(string)
                t.Val = make([]*EnumValue, 0, 8)
                for kid := next(); kid != nil; kid = next() {
@@ -552,7 +575,7 @@ func (d *Data) Type(off Offset) (Type, error) {
                //      AttrAddrClass: address class [ignored]
                t := new(PtrType)
                typ = t
-               d.typeCache[off] = t
+               typeCache[off] = t
                if e.Val(AttrType) == nil {
                        t.Type = &VoidType{}
                        break
@@ -571,7 +594,7 @@ func (d *Data) Type(off Offset) (Type, error) {
                //      TagUnspecifiedParameter: final ...
                t := new(FuncType)
                typ = t
-               d.typeCache[off] = t
+               typeCache[off] = t
                if t.ReturnType = typeOf(e); err != nil {
                        goto Error
                }
@@ -598,7 +621,7 @@ func (d *Data) Type(off Offset) (Type, error) {
                //      AttrType: type definition [required]
                t := new(TypedefType)
                typ = t
-               d.typeCache[off] = t
+               typeCache[off] = t
                t.Name, _ = e.Val(AttrName).(string)
                t.Type = typeOf(e)
        }
@@ -620,7 +643,7 @@ Error:
        // If the parse fails, take the type out of the cache
        // so that the next call with this offset doesn't hit
        // the cache and return success.
-       delete(d.typeCache, off)
+       delete(typeCache, off)
        return nil, err
 }
 
index b5b255f6f4a600846b0e44c2ff452982df544fb3..2cb85e74bb23a76a81817f6bdafd0b327a838c43 100644 (file)
@@ -73,6 +73,8 @@ func TestTypedefsMachO(t *testing.T) {
        testTypedefs(t, machoData(t, "testdata/typedef.macho"), "macho")
 }
 
+func TestTypedefsELFDwarf4(t *testing.T) { testTypedefs(t, elfData(t, "testdata/typedef.elf4"), "elf") }
+
 func testTypedefs(t *testing.T, d *Data, kind string) {
        r := d.Reader()
        seen := make(map[string]bool)
diff --git a/libgo/go/debug/dwarf/typeunit.go b/libgo/go/debug/dwarf/typeunit.go
new file mode 100644 (file)
index 0000000..3fd1c99
--- /dev/null
@@ -0,0 +1,166 @@
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package dwarf
+
+import (
+       "fmt"
+       "strconv"
+)
+
+// Parse the type units stored in a DWARF4 .debug_types section.  Each
+// type unit defines a single primary type and an 8-byte signature.
+// Other sections may then use formRefSig8 to refer to the type.
+
+// The typeUnit format is a single type with a signature.  It holds
+// the same data as a compilation unit.
+type typeUnit struct {
+       unit
+       toff  Offset // Offset to signature type within data.
+       name  string // Name of .debug_type section.
+       cache Type   // Cache the type, nil to start.
+}
+
+// Parse a .debug_types section.
+func (d *Data) parseTypes(name string, types []byte) error {
+       b := makeBuf(d, unknownFormat{}, name, 0, types)
+       for len(b.data) > 0 {
+               base := b.off
+               dwarf64 := false
+               n := b.uint32()
+               if n == 0xffffffff {
+                       n64 := b.uint64()
+                       if n64 != uint64(uint32(n64)) {
+                               b.error("type unit length overflow")
+                               return b.err
+                       }
+                       n = uint32(n64)
+                       dwarf64 = true
+               }
+               hdroff := b.off
+               vers := b.uint16()
+               if vers != 4 {
+                       b.error("unsupported DWARF version " + strconv.Itoa(int(vers)))
+                       return b.err
+               }
+               var ao uint32
+               if !dwarf64 {
+                       ao = b.uint32()
+               } else {
+                       ao64 := b.uint64()
+                       if ao64 != uint64(uint32(ao64)) {
+                               b.error("type unit abbrev offset overflow")
+                               return b.err
+                       }
+                       ao = uint32(ao64)
+               }
+               atable, err := d.parseAbbrev(ao)
+               if err != nil {
+                       return err
+               }
+               asize := b.uint8()
+               sig := b.uint64()
+
+               var toff uint32
+               if !dwarf64 {
+                       toff = b.uint32()
+               } else {
+                       to64 := b.uint64()
+                       if to64 != uint64(uint32(to64)) {
+                               b.error("type unit type offset overflow")
+                               return b.err
+                       }
+                       toff = uint32(to64)
+               }
+
+               boff := b.off
+               d.typeSigs[sig] = &typeUnit{
+                       unit: unit{
+                               base:   base,
+                               off:    boff,
+                               data:   b.bytes(int(Offset(n) - (b.off - hdroff))),
+                               atable: atable,
+                               asize:  int(asize),
+                               vers:   int(vers),
+                               is64:   dwarf64,
+                       },
+                       toff: Offset(toff),
+                       name: name,
+               }
+               if b.err != nil {
+                       return b.err
+               }
+       }
+       return nil
+}
+
+// Return the type for a type signature.
+func (d *Data) sigToType(sig uint64) (Type, error) {
+       tu := d.typeSigs[sig]
+       if tu == nil {
+               return nil, fmt.Errorf("no type unit with signature %v", sig)
+       }
+       if tu.cache != nil {
+               return tu.cache, nil
+       }
+
+       b := makeBuf(d, tu, tu.name, tu.off, tu.data)
+       r := &typeUnitReader{d: d, tu: tu, b: b}
+       t, err := d.readType(tu.name, r, Offset(tu.toff), make(map[Offset]Type))
+       if err != nil {
+               return nil, err
+       }
+
+       tu.cache = t
+       return t, nil
+}
+
+// typeUnitReader is a typeReader for a tagTypeUnit.
+type typeUnitReader struct {
+       d   *Data
+       tu  *typeUnit
+       b   buf
+       err error
+}
+
+// Seek to a new position in the type unit.
+func (tur *typeUnitReader) Seek(off Offset) {
+       tur.err = nil
+       doff := off - tur.tu.off
+       if doff < 0 || doff >= Offset(len(tur.tu.data)) {
+               tur.err = fmt.Errorf("%s: offset %d out of range; max %d", tur.tu.name, doff, len(tur.tu.data))
+               return
+       }
+       tur.b = makeBuf(tur.d, tur.tu, tur.tu.name, off, tur.tu.data[doff:])
+}
+
+// Next reads the next Entry from the type unit.
+func (tur *typeUnitReader) Next() (*Entry, error) {
+       if tur.err != nil {
+               return nil, tur.err
+       }
+       if len(tur.tu.data) == 0 {
+               return nil, nil
+       }
+       e := tur.b.entry(tur.tu.atable, tur.tu.base)
+       if tur.b.err != nil {
+               tur.err = tur.b.err
+               return nil, tur.err
+       }
+       return e, nil
+}
+
+// clone returns a new reader for the type unit.
+func (tur *typeUnitReader) clone() typeReader {
+       return &typeUnitReader{
+               d:  tur.d,
+               tu: tur.tu,
+               b:  makeBuf(tur.d, tur.tu, tur.tu.name, tur.tu.off, tur.tu.data),
+       }
+}
+
+// offset returns the current offset.
+func (tur *typeUnitReader) offset() Offset {
+       return tur.b.off
+}
index 8e09298a8b43ea061cab5bd9111c9aca39bac363..be6093519d5efaa49e8ccafd42a896cca1fc8235 100644 (file)
@@ -76,7 +76,7 @@ func (d *Data) parseUnits() ([]unit, error) {
                        n = uint32(b.uint64())
                }
                vers := b.uint16()
-               if vers < 2 || vers > 4 {
+               if vers != 2 && vers != 3 && vers != 4 {
                        b.error("unsupported DWARF version " + strconv.Itoa(int(vers)))
                        break
                }
index 67b961b5c6c20acfaa134d5ae6247d4e14eeb7a7..e3c51bb717b20661cc69e7b77fc1f7892e79b980 100644 (file)
@@ -43,7 +43,7 @@ func TestNames(t *testing.T) {
        for i, tt := range nameTests {
                s := fmt.Sprint(tt.val)
                if s != tt.str {
-                       t.Errorf("#%d: want %q have %q", i, s, tt.str)
+                       t.Errorf("#%d: Sprint(%d) = %q, want %q", i, tt.val, s, tt.str)
                }
        }
 }
index 8023eb0a0b75508019ded5977d7fcc58146481af..a98b469b33036ae97c7bdee6399f98ae13bf6953 100644 (file)
@@ -76,6 +76,9 @@ type Section struct {
 func (s *Section) Data() ([]byte, error) {
        dat := make([]byte, s.sr.Size())
        n, err := s.sr.ReadAt(dat, 0)
+       if n == len(dat) {
+               err = nil
+       }
        return dat[0:n], err
 }
 
@@ -412,7 +415,7 @@ func (f *File) getSymbols32(typ SectionType) ([]Symbol, []byte, error) {
        if err != nil {
                return nil, nil, errors.New("cannot load symbol section")
        }
-       symtab := bytes.NewBuffer(data)
+       symtab := bytes.NewReader(data)
        if symtab.Len()%Sym32Size != 0 {
                return nil, nil, errors.New("length of symbol section is not a multiple of SymSize")
        }
@@ -455,7 +458,7 @@ func (f *File) getSymbols64(typ SectionType) ([]Symbol, []byte, error) {
        if err != nil {
                return nil, nil, errors.New("cannot load symbol section")
        }
-       symtab := bytes.NewBuffer(data)
+       symtab := bytes.NewReader(data)
        if symtab.Len()%Sym64Size != 0 {
                return nil, nil, errors.New("length of symbol section is not a multiple of Sym64Size")
        }
@@ -533,7 +536,7 @@ func (f *File) applyRelocationsAMD64(dst []byte, rels []byte) error {
                return err
        }
 
-       b := bytes.NewBuffer(rels)
+       b := bytes.NewReader(rels)
        var rela Rela64
 
        for b.Len() > 0 {
@@ -601,7 +604,44 @@ func (f *File) DWARF() (*dwarf.Data, error) {
        }
 
        abbrev, info, line, ranges, str := dat[0], dat[1], dat[2], dat[3], dat[4]
-       return dwarf.New(abbrev, nil, nil, info, line, nil, ranges, str)
+       d, err := dwarf.New(abbrev, nil, nil, info, line, nil, ranges, str)
+       if err != nil {
+               return nil, err
+       }
+
+       // Look for DWARF4 .debug_types sections.
+       for i, s := range f.Sections {
+               if s.Name == ".debug_types" {
+                       b, err := s.Data()
+                       if err != nil && uint64(len(b)) < s.Size {
+                               return nil, err
+                       }
+
+                       for _, r := range f.Sections {
+                               if r.Type != SHT_RELA && r.Type != SHT_REL {
+                                       continue
+                               }
+                               if int(r.Info) != i {
+                                       continue
+                               }
+                               rd, err := r.Data()
+                               if err != nil {
+                                       return nil, err
+                               }
+                               err = f.applyRelocations(b, rd)
+                               if err != nil {
+                                       return nil, err
+                               }
+                       }
+
+                       err = d.AddTypes(fmt.Sprintf("types-%d", i), b)
+                       if err != nil {
+                               return nil, err
+                       }
+               }
+       }
+
+       return d, nil
 }
 
 // Symbols returns the symbol table for f.
diff --git a/libgo/go/debug/elf/testdata/hello.c b/libgo/go/debug/elf/testdata/hello.c
new file mode 100644 (file)
index 0000000..34d9ee7
--- /dev/null
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+void
+main(int argc, char *argv[])
+{
+       printf("hello, world\n");
+}
index 3338c411dc3f8ea59e600aa0481bcc418cdd2fd0..f65abb6c27399e253c0612dd16c80c6a9a9a9b14 100644 (file)
@@ -72,6 +72,49 @@ const (
        SHOSTOBJ
 )
 
+var symKindStrings = []string{
+       SBSS:              "SBSS",
+       SCONST:            "SCONST",
+       SDATA:             "SDATA",
+       SDYNIMPORT:        "SDYNIMPORT",
+       SELFROSECT:        "SELFROSECT",
+       SELFRXSECT:        "SELFRXSECT",
+       SELFSECT:          "SELFSECT",
+       SFILE:             "SFILE",
+       SFILEPATH:         "SFILEPATH",
+       SFUNCTAB:          "SFUNCTAB",
+       SGOFUNC:           "SGOFUNC",
+       SGOSTRING:         "SGOSTRING",
+       SHOSTOBJ:          "SHOSTOBJ",
+       SINITARR:          "SINITARR",
+       SMACHO:            "SMACHO",
+       SMACHOGOT:         "SMACHOGOT",
+       SMACHOINDIRECTGOT: "SMACHOINDIRECTGOT",
+       SMACHOINDIRECTPLT: "SMACHOINDIRECTPLT",
+       SMACHOPLT:         "SMACHOPLT",
+       SMACHOSYMSTR:      "SMACHOSYMSTR",
+       SMACHOSYMTAB:      "SMACHOSYMTAB",
+       SNOPTRBSS:         "SNOPTRBSS",
+       SNOPTRDATA:        "SNOPTRDATA",
+       SPCLNTAB:          "SPCLNTAB",
+       SRODATA:           "SRODATA",
+       SSTRING:           "SSTRING",
+       SSYMTAB:           "SSYMTAB",
+       STEXT:             "STEXT",
+       STLSBSS:           "STLSBSS",
+       STYPE:             "STYPE",
+       STYPELINK:         "STYPELINK",
+       SWINDOWS:          "SWINDOWS",
+       SXREF:             "SXREF",
+}
+
+func (k SymKind) String() string {
+       if k < 0 || int(k) >= len(symKindStrings) {
+               return fmt.Sprintf("SymKind(%d)", k)
+       }
+       return symKindStrings[k]
+}
+
 // A Sym is a named symbol in an object file.
 type Sym struct {
        SymID         // symbol identifier (name and version)
@@ -98,6 +141,13 @@ type SymID struct {
        Version int
 }
 
+func (s SymID) String() string {
+       if s.Version == 0 {
+               return s.Name
+       }
+       return fmt.Sprintf("%s<%d>", s.Name, s.Version)
+}
+
 // A Data is a reference to data stored in an object file.
 // It records the offset and size of the data, so that a client can
 // read the data only if necessary.
index 3e6a8046b3e35e45beb591b747532ba92a6673d8..6620aefb053ceab0bb20b4a8cd5900adab4e091c 100644 (file)
@@ -196,6 +196,33 @@ func (t *LineTable) go12Init() {
        t.go12 = 1 // so far so good
 }
 
+// go12Funcs returns a slice of Funcs derived from the Go 1.2 pcln table.
+func (t *LineTable) go12Funcs() []Func {
+       // Assume it is malformed and return nil on error.
+       defer func() {
+               recover()
+       }()
+
+       n := len(t.functab) / int(t.ptrsize) / 2
+       funcs := make([]Func, n)
+       for i := range funcs {
+               f := &funcs[i]
+               f.Entry = uint64(t.uintptr(t.functab[2*i*int(t.ptrsize):]))
+               f.End = uint64(t.uintptr(t.functab[(2*i+2)*int(t.ptrsize):]))
+               info := t.Data[t.uintptr(t.functab[(2*i+1)*int(t.ptrsize):]):]
+               f.LineTable = t
+               f.FrameSize = int(t.binary.Uint32(info[t.ptrsize+2*4:]))
+               f.Sym = &Sym{
+                       Value:  f.Entry,
+                       Type:   'T',
+                       Name:   t.string(t.binary.Uint32(info[t.ptrsize:])),
+                       GoType: 0,
+                       Func:   f,
+               }
+       }
+       return funcs
+}
+
 // findFunc returns the func corresponding to the given program counter.
 func (t *LineTable) findFunc(pc uint64) []byte {
        if pc < t.uintptr(t.functab) || pc >= t.uintptr(t.functab[len(t.functab)-int(t.ptrsize):]) {
index 9ab05bac2f70af17e9edb7417956eb56e196f8df..3864e3cb4fa8ff81060e470a5bf4fb11af067f65 100644 (file)
@@ -129,6 +129,9 @@ var (
 )
 
 func walksymtab(data []byte, fn func(sym) error) error {
+       if len(data) == 0 { // missing symtab is okay
+               return nil
+       }
        var order binary.ByteOrder = binary.BigEndian
        newTable := false
        switch {
@@ -455,6 +458,10 @@ func NewTable(symtab []byte, pcln *LineTable) (*Table, error) {
                        i = end - 1 // loop will i++
                }
        }
+
+       if t.go12line != nil && nf == 0 {
+               t.Funcs = t.go12line.go12Funcs()
+       }
        if obj != nil {
                obj.Funcs = t.Funcs[lastf:]
        }
diff --git a/libgo/go/debug/macho/fat.go b/libgo/go/debug/macho/fat.go
new file mode 100644 (file)
index 0000000..93b8315
--- /dev/null
@@ -0,0 +1,146 @@
+// Copyright 2014 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package macho
+
+import (
+       "encoding/binary"
+       "fmt"
+       "io"
+       "os"
+)
+
+// A FatFile is a Mach-O universal binary that contains at least one architecture.
+type FatFile struct {
+       Magic  uint32
+       Arches []FatArch
+       closer io.Closer
+}
+
+// A FatArchHeader represents a fat header for a specific image architecture.
+type FatArchHeader struct {
+       Cpu    Cpu
+       SubCpu uint32
+       Offset uint32
+       Size   uint32
+       Align  uint32
+}
+
+const fatArchHeaderSize = 5 * 4
+
+// A FatArch is a Mach-O File inside a FatFile.
+type FatArch struct {
+       FatArchHeader
+       *File
+}
+
+// ErrNotFat is returned from NewFatFile or OpenFat when the file is not a
+// universal binary but may be a thin binary, based on its magic number.
+var ErrNotFat = &FormatError{0, "not a fat Mach-O file", nil}
+
+// NewFatFile creates a new FatFile for accessing all the Mach-O images in a
+// universal binary. The Mach-O binary is expected to start at position 0 in
+// the ReaderAt.
+func NewFatFile(r io.ReaderAt) (*FatFile, error) {
+       var ff FatFile
+       sr := io.NewSectionReader(r, 0, 1<<63-1)
+
+       // Read the fat_header struct, which is always in big endian.
+       // Start with the magic number.
+       err := binary.Read(sr, binary.BigEndian, &ff.Magic)
+       if err != nil {
+               return nil, &FormatError{0, "error reading magic number", nil}
+       } else if ff.Magic != MagicFat {
+               // See if this is a Mach-O file via its magic number. The magic
+               // must be converted to little endian first though.
+               var buf [4]byte
+               binary.BigEndian.PutUint32(buf[:], ff.Magic)
+               leMagic := binary.LittleEndian.Uint32(buf[:])
+               if leMagic == Magic32 || leMagic == Magic64 {
+                       return nil, ErrNotFat
+               } else {
+                       return nil, &FormatError{0, "invalid magic number", nil}
+               }
+       }
+       offset := int64(4)
+
+       // Read the number of FatArchHeaders that come after the fat_header.
+       var narch uint32
+       err = binary.Read(sr, binary.BigEndian, &narch)
+       if err != nil {
+               return nil, &FormatError{offset, "invalid fat_header", nil}
+       }
+       offset += 4
+
+       if narch < 1 {
+               return nil, &FormatError{offset, "file contains no images", nil}
+       }
+
+       // Combine the Cpu and SubCpu (both uint32) into a uint64 to make sure
+       // there are not duplicate architectures.
+       seenArches := make(map[uint64]bool, narch)
+       // Make sure that all images are for the same MH_ type.
+       var machoType Type
+
+       // Following the fat_header comes narch fat_arch structs that index
+       // Mach-O images further in the file.
+       ff.Arches = make([]FatArch, narch)
+       for i := uint32(0); i < narch; i++ {
+               fa := &ff.Arches[i]
+               err = binary.Read(sr, binary.BigEndian, &fa.FatArchHeader)
+               if err != nil {
+                       return nil, &FormatError{offset, "invalid fat_arch header", nil}
+               }
+               offset += fatArchHeaderSize
+
+               fr := io.NewSectionReader(r, int64(fa.Offset), int64(fa.Size))
+               fa.File, err = NewFile(fr)
+               if err != nil {
+                       return nil, err
+               }
+
+               // Make sure the architecture for this image is not duplicate.
+               seenArch := (uint64(fa.Cpu) << 32) | uint64(fa.SubCpu)
+               if o, k := seenArches[seenArch]; o || k {
+                       return nil, &FormatError{offset, fmt.Sprintf("duplicate architecture cpu=%v, subcpu=%#x", fa.Cpu, fa.SubCpu), nil}
+               }
+               seenArches[seenArch] = true
+
+               // Make sure the Mach-O type matches that of the first image.
+               if i == 0 {
+                       machoType = fa.Type
+               } else {
+                       if fa.Type != machoType {
+                               return nil, &FormatError{offset, fmt.Sprintf("Mach-O type for architecture #%d (type=%#x) does not match first (type=%#x)", i, fa.Type, machoType), nil}
+                       }
+               }
+       }
+
+       return &ff, nil
+}
+
+// OpenFat opens the named file using os.Open and prepares it for use as a Mach-O
+// universal binary.
+func OpenFat(name string) (ff *FatFile, err error) {
+       f, err := os.Open(name)
+       if err != nil {
+               return nil, err
+       }
+       ff, err = NewFatFile(f)
+       if err != nil {
+               f.Close()
+               return nil, err
+       }
+       ff.closer = f
+       return
+}
+
+func (ff *FatFile) Close() error {
+       var err error
+       if ff.closer != nil {
+               err = ff.closer.Close()
+               ff.closer = nil
+       }
+       return err
+}
index 9d912e7a08734ac36dabe517e041e090f1a308b0..ed9b2a6912017d0842036ced34fbc66a327e283c 100644 (file)
@@ -74,6 +74,9 @@ type Segment struct {
 func (s *Segment) Data() ([]byte, error) {
        dat := make([]byte, s.sr.Size())
        n, err := s.sr.ReadAt(dat, 0)
+       if n == len(dat) {
+               err = nil
+       }
        return dat[0:n], err
 }
 
@@ -109,6 +112,9 @@ type Section struct {
 func (s *Section) Data() ([]byte, error) {
        dat := make([]byte, s.sr.Size())
        n, err := s.sr.ReadAt(dat, 0)
+       if n == len(dat) {
+               err = nil
+       }
        return dat[0:n], err
 }
 
@@ -246,7 +252,7 @@ func NewFile(r io.ReaderAt) (*File, error) {
 
                case LoadCmdDylib:
                        var hdr DylibCmd
-                       b := bytes.NewBuffer(cmddat)
+                       b := bytes.NewReader(cmddat)
                        if err := binary.Read(b, bo, &hdr); err != nil {
                                return nil, err
                        }
@@ -263,7 +269,7 @@ func NewFile(r io.ReaderAt) (*File, error) {
 
                case LoadCmdSymtab:
                        var hdr SymtabCmd
-                       b := bytes.NewBuffer(cmddat)
+                       b := bytes.NewReader(cmddat)
                        if err := binary.Read(b, bo, &hdr); err != nil {
                                return nil, err
                        }
@@ -290,7 +296,7 @@ func NewFile(r io.ReaderAt) (*File, error) {
 
                case LoadCmdDysymtab:
                        var hdr DysymtabCmd
-                       b := bytes.NewBuffer(cmddat)
+                       b := bytes.NewReader(cmddat)
                        if err := binary.Read(b, bo, &hdr); err != nil {
                                return nil, err
                        }
@@ -299,7 +305,7 @@ func NewFile(r io.ReaderAt) (*File, error) {
                                return nil, err
                        }
                        x := make([]uint32, hdr.Nindirectsyms)
-                       if err := binary.Read(bytes.NewBuffer(dat), bo, x); err != nil {
+                       if err := binary.Read(bytes.NewReader(dat), bo, x); err != nil {
                                return nil, err
                        }
                        st := new(Dysymtab)
@@ -311,7 +317,7 @@ func NewFile(r io.ReaderAt) (*File, error) {
 
                case LoadCmdSegment:
                        var seg32 Segment32
-                       b := bytes.NewBuffer(cmddat)
+                       b := bytes.NewReader(cmddat)
                        if err := binary.Read(b, bo, &seg32); err != nil {
                                return nil, err
                        }
@@ -349,7 +355,7 @@ func NewFile(r io.ReaderAt) (*File, error) {
 
                case LoadCmdSegment64:
                        var seg64 Segment64
-                       b := bytes.NewBuffer(cmddat)
+                       b := bytes.NewReader(cmddat)
                        if err := binary.Read(b, bo, &seg64); err != nil {
                                return nil, err
                        }
@@ -396,7 +402,7 @@ func NewFile(r io.ReaderAt) (*File, error) {
 func (f *File) parseSymtab(symdat, strtab, cmddat []byte, hdr *SymtabCmd, offset int64) (*Symtab, error) {
        bo := f.ByteOrder
        symtab := make([]Symbol, hdr.Nsyms)
-       b := bytes.NewBuffer(symdat)
+       b := bytes.NewReader(symdat)
        for i := range symtab {
                var n Nlist64
                if f.Magic == Magic64 {
index 640225b3291b138c6462107d5b62adf3024c98f1..0de9184c22746a22d4e1eb05f8b08b8ec7041b8b 100644 (file)
@@ -165,3 +165,46 @@ func TestOpenFailure(t *testing.T) {
                t.Errorf("open %s: succeeded unexpectedly", filename)
        }
 }
+
+func TestOpenFat(t *testing.T) {
+       ff, err := OpenFat("testdata/fat-gcc-386-amd64-darwin-exec")
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       if ff.Magic != MagicFat {
+               t.Errorf("OpenFat: got magic number %#x, want %#x", ff.Magic, MagicFat)
+       }
+       if len(ff.Arches) != 2 {
+               t.Errorf("OpenFat: got %d architectures, want 2", len(ff.Arches))
+       }
+
+       for i := range ff.Arches {
+               arch := &ff.Arches[i]
+               ftArch := &fileTests[i]
+
+               if arch.Cpu != ftArch.hdr.Cpu || arch.SubCpu != ftArch.hdr.SubCpu {
+                       t.Error("OpenFat: architecture #%d got cpu=%#x subtype=%#x, expected cpu=%#x, subtype=%#x", i, arch.Cpu, arch.SubCpu, ftArch.hdr.Cpu, ftArch.hdr.SubCpu)
+               }
+
+               if !reflect.DeepEqual(arch.FileHeader, ftArch.hdr) {
+                       t.Errorf("OpenFat header:\n\tgot %#v\n\twant %#v\n", arch.FileHeader, ftArch.hdr)
+               }
+       }
+}
+
+func TestOpenFatFailure(t *testing.T) {
+       filename := "file.go" // not a Mach-O file
+       if _, err := OpenFat(filename); err == nil {
+               t.Errorf("OpenFat %s: succeeded unexpectedly", filename)
+       }
+
+       filename = "testdata/gcc-386-darwin-exec" // not a fat Mach-O
+       ff, err := OpenFat(filename)
+       if err != ErrNotFat {
+               t.Errorf("OpenFat %s: got %v, want ErrNotFat", err)
+       }
+       if ff != nil {
+               t.Errorf("OpenFat %s: got %v, want nil", ff)
+       }
+}
index bc14226c565a0c8045d8dcd68f95a4f5dd21b55a..09f4d0ec91c63b7fcf2c8931929aa8aa75847aff 100644 (file)
@@ -26,16 +26,19 @@ const (
 )
 
 const (
-       Magic32 uint32 = 0xfeedface
-       Magic64 uint32 = 0xfeedfacf
+       Magic32  uint32 = 0xfeedface
+       Magic64  uint32 = 0xfeedfacf
+       MagicFat uint32 = 0xcafebabe
 )
 
-// A Type is a Mach-O file type, either an object or an executable.
+// A Type is the Mach-O file type, e.g. an object file, executable, or dynamic library.
 type Type uint32
 
 const (
-       TypeObj  Type = 1
-       TypeExec Type = 2
+       TypeObj    Type = 1
+       TypeExec   Type = 2
+       TypeDylib  Type = 6
+       TypeBundle Type = 8
 )
 
 // A Cpu is a Mach-O cpu type.
diff --git a/libgo/go/debug/macho/testdata/fat-gcc-386-amd64-darwin-exec b/libgo/go/debug/macho/testdata/fat-gcc-386-amd64-darwin-exec
new file mode 100644 (file)
index 0000000..7efd193
Binary files /dev/null and b/libgo/go/debug/macho/testdata/fat-gcc-386-amd64-darwin-exec differ
index f521566efa7abb5a8c33e172f89afb2618af0b3f..d0005bacf383ee9e6ff4107092ba07e3827eb184 100644 (file)
@@ -72,6 +72,9 @@ type ImportDirectory struct {
 func (s *Section) Data() ([]byte, error) {
        dat := make([]byte, s.sr.Size())
        n, err := s.sr.ReadAt(dat, 0)
+       if n == len(dat) {
+               err = nil
+       }
        return dat[0:n], err
 }
 
@@ -213,15 +216,15 @@ func NewFile(r io.ReaderAt) (*File, error) {
                s := new(Section)
                s.SectionHeader = SectionHeader{
                        Name:                 name,
-                       VirtualSize:          uint32(sh.VirtualSize),
-                       VirtualAddress:       uint32(sh.VirtualAddress),
-                       Size:                 uint32(sh.SizeOfRawData),
-                       Offset:               uint32(sh.PointerToRawData),
-                       PointerToRelocations: uint32(sh.PointerToRelocations),
-                       PointerToLineNumbers: uint32(sh.PointerToLineNumbers),
-                       NumberOfRelocations:  uint16(sh.NumberOfRelocations),
-                       NumberOfLineNumbers:  uint16(sh.NumberOfLineNumbers),
-                       Characteristics:      uint32(sh.Characteristics),
+                       VirtualSize:          sh.VirtualSize,
+                       VirtualAddress:       sh.VirtualAddress,
+                       Size:                 sh.SizeOfRawData,
+                       Offset:               sh.PointerToRawData,
+                       PointerToRelocations: sh.PointerToRelocations,
+                       PointerToLineNumbers: sh.PointerToLineNumbers,
+                       NumberOfRelocations:  sh.NumberOfRelocations,
+                       NumberOfLineNumbers:  sh.NumberOfLineNumbers,
+                       Characteristics:      sh.Characteristics,
                }
                s.sr = io.NewSectionReader(r, int64(s.SectionHeader.Offset), int64(s.SectionHeader.Size))
                s.ReaderAt = s.sr
diff --git a/libgo/go/debug/plan9obj/file.go b/libgo/go/debug/plan9obj/file.go
new file mode 100644 (file)
index 0000000..a4c95a9
--- /dev/null
@@ -0,0 +1,346 @@
+// Copyright 2014 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package plan9obj implements access to Plan 9 a.out object files.
+package plan9obj
+
+import (
+       "encoding/binary"
+       "errors"
+       "fmt"
+       "io"
+       "os"
+)
+
+// A FileHeader represents an Plan 9 a.out file header.
+type FileHeader struct {
+       Ptrsz int
+}
+
+// A File represents an open Plan 9 a.out file.
+type File struct {
+       FileHeader
+       Sections []*Section
+       closer   io.Closer
+}
+
+type SectionHeader struct {
+       Name   string
+       Size   uint32
+       Offset uint32
+}
+
+// A Section represents a single section in an Plan 9 a.out file.
+type Section struct {
+       SectionHeader
+
+       // Embed ReaderAt for ReadAt method.
+       // Do not embed SectionReader directly
+       // to avoid having Read and Seek.
+       // If a client wants Read and Seek it must use
+       // Open() to avoid fighting over the seek offset
+       // with other clients.
+       io.ReaderAt
+       sr *io.SectionReader
+}
+
+// Data reads and returns the contents of the Plan 9 a.out section.
+func (s *Section) Data() ([]byte, error) {
+       dat := make([]byte, s.sr.Size())
+       n, err := s.sr.ReadAt(dat, 0)
+       return dat[0:n], err
+}
+
+// Open returns a new ReadSeeker reading the Plan 9 a.out section.
+func (s *Section) Open() io.ReadSeeker { return io.NewSectionReader(s.sr, 0, 1<<63-1) }
+
+// A ProgHeader represents a single Plan 9 a.out program header.
+type ProgHeader struct {
+       Magic uint32
+       Text  uint32
+       Data  uint32
+       Bss   uint32
+       Syms  uint32
+       Entry uint64
+       Spsz  uint32
+       Pcsz  uint32
+}
+
+// A Prog represents the program header in an Plan 9 a.out binary.
+type Prog struct {
+       ProgHeader
+
+       // Embed ReaderAt for ReadAt method.
+       // Do not embed SectionReader directly
+       // to avoid having Read and Seek.
+       // If a client wants Read and Seek it must use
+       // Open() to avoid fighting over the seek offset
+       // with other clients.
+       io.ReaderAt
+       sr *io.SectionReader
+}
+
+// Open returns a new ReadSeeker reading the Plan 9 a.out program body.
+func (p *Prog) Open() io.ReadSeeker { return io.NewSectionReader(p.sr, 0, 1<<63-1) }
+
+// A Symbol represents an entry in a Plan 9 a.out symbol table section.
+type Sym struct {
+       Value uint64
+       Type  rune
+       Name  string
+}
+
+/*
+ * Plan 9 a.out reader
+ */
+
+type FormatError struct {
+       off int
+       msg string
+       val interface{}
+}
+
+func (e *FormatError) Error() string {
+       msg := e.msg
+       if e.val != nil {
+               msg += fmt.Sprintf(" '%v'", e.val)
+       }
+       msg += fmt.Sprintf(" in record at byte %#x", e.off)
+       return msg
+}
+
+// Open opens the named file using os.Open and prepares it for use as an Plan 9 a.out binary.
+func Open(name string) (*File, error) {
+       f, err := os.Open(name)
+       if err != nil {
+               return nil, err
+       }
+       ff, err := NewFile(f)
+       if err != nil {
+               f.Close()
+               return nil, err
+       }
+       ff.closer = f
+       return ff, nil
+}
+
+// Close closes the File.
+// If the File was created using NewFile directly instead of Open,
+// Close has no effect.
+func (f *File) Close() error {
+       var err error
+       if f.closer != nil {
+               err = f.closer.Close()
+               f.closer = nil
+       }
+       return err
+}
+
+func parseMagic(magic [4]byte) (*ExecTable, error) {
+       for _, e := range exectab {
+               if string(magic[:]) == e.Magic {
+                       return &e, nil
+               }
+       }
+       return nil, &FormatError{0, "bad magic number", magic[:]}
+}
+
+// NewFile creates a new File for accessing an Plan 9 binary in an underlying reader.
+// The Plan 9 binary is expected to start at position 0 in the ReaderAt.
+func NewFile(r io.ReaderAt) (*File, error) {
+       sr := io.NewSectionReader(r, 0, 1<<63-1)
+       // Read and decode Plan 9 magic
+       var magic [4]byte
+       if _, err := r.ReadAt(magic[:], 0); err != nil {
+               return nil, err
+       }
+       mp, err := parseMagic(magic)
+       if err != nil {
+               return nil, err
+       }
+
+       f := &File{FileHeader{mp.Ptrsz}, nil, nil}
+
+       ph := new(prog)
+       if err := binary.Read(sr, binary.BigEndian, ph); err != nil {
+               return nil, err
+       }
+
+       p := new(Prog)
+       p.ProgHeader = ProgHeader{
+               Magic: ph.Magic,
+               Text:  ph.Text,
+               Data:  ph.Data,
+               Bss:   ph.Bss,
+               Syms:  ph.Syms,
+               Entry: uint64(ph.Entry),
+               Spsz:  ph.Spsz,
+               Pcsz:  ph.Pcsz,
+       }
+
+       if mp.Ptrsz == 8 {
+               if err := binary.Read(sr, binary.BigEndian, &p.Entry); err != nil {
+                       return nil, err
+               }
+       }
+
+       var sects = []struct {
+               name string
+               size uint32
+       }{
+               {"text", ph.Text},
+               {"data", ph.Data},
+               {"syms", ph.Syms},
+               {"spsz", ph.Spsz},
+               {"pcsz", ph.Pcsz},
+       }
+
+       f.Sections = make([]*Section, 5)
+
+       off := mp.Hsize
+
+       for i, sect := range sects {
+               s := new(Section)
+               s.SectionHeader = SectionHeader{
+                       Name:   sect.name,
+                       Size:   sect.size,
+                       Offset: off,
+               }
+               off += sect.size
+               s.sr = io.NewSectionReader(r, int64(s.SectionHeader.Offset), int64(s.SectionHeader.Size))
+               s.ReaderAt = s.sr
+               f.Sections[i] = s
+       }
+
+       return f, nil
+}
+
+func walksymtab(data []byte, ptrsz int, fn func(sym) error) error {
+       var order binary.ByteOrder = binary.BigEndian
+       var s sym
+       p := data
+       for len(p) >= 4 {
+               // Symbol type, value.
+               if len(p) < ptrsz {
+                       return &FormatError{len(data), "unexpected EOF", nil}
+               }
+               // fixed-width value
+               if ptrsz == 8 {
+                       s.value = order.Uint64(p[0:8])
+                       p = p[8:]
+               } else {
+                       s.value = uint64(order.Uint32(p[0:4]))
+                       p = p[4:]
+               }
+
+               var typ byte
+               typ = p[0] & 0x7F
+               s.typ = typ
+               p = p[1:]
+
+               // Name.
+               var i int
+               var nnul int
+               for i = 0; i < len(p); i++ {
+                       if p[i] == 0 {
+                               nnul = 1
+                               break
+                       }
+               }
+               switch typ {
+               case 'z', 'Z':
+                       p = p[i+nnul:]
+                       for i = 0; i+2 <= len(p); i += 2 {
+                               if p[i] == 0 && p[i+1] == 0 {
+                                       nnul = 2
+                                       break
+                               }
+                       }
+               }
+               if len(p) < i+nnul {
+                       return &FormatError{len(data), "unexpected EOF", nil}
+               }
+               s.name = p[0:i]
+               i += nnul
+               p = p[i:]
+
+               fn(s)
+       }
+       return nil
+}
+
+// NewTable decodes the Go symbol table in data,
+// returning an in-memory representation.
+func newTable(symtab []byte, ptrsz int) ([]Sym, error) {
+       var n int
+       err := walksymtab(symtab, ptrsz, func(s sym) error {
+               n++
+               return nil
+       })
+       if err != nil {
+               return nil, err
+       }
+
+       fname := make(map[uint16]string)
+       syms := make([]Sym, 0, n)
+       err = walksymtab(symtab, ptrsz, func(s sym) error {
+               n := len(syms)
+               syms = syms[0 : n+1]
+               ts := &syms[n]
+               ts.Type = rune(s.typ)
+               ts.Value = s.value
+               switch s.typ {
+               default:
+                       ts.Name = string(s.name[:])
+               case 'z', 'Z':
+                       for i := 0; i < len(s.name); i += 2 {
+                               eltIdx := binary.BigEndian.Uint16(s.name[i : i+2])
+                               elt, ok := fname[eltIdx]
+                               if !ok {
+                                       return &FormatError{-1, "bad filename code", eltIdx}
+                               }
+                               if n := len(ts.Name); n > 0 && ts.Name[n-1] != '/' {
+                                       ts.Name += "/"
+                               }
+                               ts.Name += elt
+                       }
+               }
+               switch s.typ {
+               case 'f':
+                       fname[uint16(s.value)] = ts.Name
+               }
+               return nil
+       })
+       if err != nil {
+               return nil, err
+       }
+
+       return syms, nil
+}
+
+// Symbols returns the symbol table for f.
+func (f *File) Symbols() ([]Sym, error) {
+       symtabSection := f.Section("syms")
+       if symtabSection == nil {
+               return nil, errors.New("no symbol section")
+       }
+
+       symtab, err := symtabSection.Data()
+       if err != nil {
+               return nil, errors.New("cannot load symbol section")
+       }
+
+       return newTable(symtab, f.Ptrsz)
+}
+
+// Section returns a section with the given name, or nil if no such
+// section exists.
+func (f *File) Section(name string) *Section {
+       for _, s := range f.Sections {
+               if s.Name == name {
+                       return s
+               }
+       }
+       return nil
+}
diff --git a/libgo/go/debug/plan9obj/file_test.go b/libgo/go/debug/plan9obj/file_test.go
new file mode 100644 (file)
index 0000000..cc1db40
--- /dev/null
@@ -0,0 +1,81 @@
+// Copyright 2014 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package plan9obj
+
+import (
+       "reflect"
+       "testing"
+)
+
+type fileTest struct {
+       file     string
+       hdr      FileHeader
+       sections []*SectionHeader
+}
+
+var fileTests = []fileTest{
+       {
+               "testdata/386-plan9-exec",
+               FileHeader{4},
+               []*SectionHeader{
+                       {"text", 0x4c5f, 0x20},
+                       {"data", 0x94c, 0x4c7f},
+                       {"syms", 0x2c2b, 0x55cb},
+                       {"spsz", 0x0, 0x81f6},
+                       {"pcsz", 0xf7a, 0x81f6},
+               },
+       },
+       {
+               "testdata/amd64-plan9-exec",
+               FileHeader{8},
+               []*SectionHeader{
+                       {"text", 0x4213, 0x28},
+                       {"data", 0xa80, 0x423b},
+                       {"syms", 0x2c8c, 0x4cbb},
+                       {"spsz", 0x0, 0x7947},
+                       {"pcsz", 0xca0, 0x7947},
+               },
+       },
+}
+
+func TestOpen(t *testing.T) {
+       for i := range fileTests {
+               tt := &fileTests[i]
+
+               f, err := Open(tt.file)
+               if err != nil {
+                       t.Error(err)
+                       continue
+               }
+               if !reflect.DeepEqual(f.FileHeader, tt.hdr) {
+                       t.Errorf("open %s:\n\thave %#v\n\twant %#v\n", tt.file, f.FileHeader, tt.hdr)
+                       continue
+               }
+
+               for i, sh := range f.Sections {
+                       if i >= len(tt.sections) {
+                               break
+                       }
+                       have := &sh.SectionHeader
+                       want := tt.sections[i]
+                       if !reflect.DeepEqual(have, want) {
+                               t.Errorf("open %s, section %d:\n\thave %#v\n\twant %#v\n", tt.file, i, have, want)
+                       }
+               }
+               tn := len(tt.sections)
+               fn := len(f.Sections)
+               if tn != fn {
+                       t.Errorf("open %s: len(Sections) = %d, want %d", tt.file, fn, tn)
+               }
+       }
+}
+
+func TestOpenFailure(t *testing.T) {
+       filename := "file.go"    // not a Plan 9 a.out file
+       _, err := Open(filename) // don't crash
+       if err == nil {
+               t.Errorf("open %s: succeeded unexpectedly", filename)
+       }
+}
diff --git a/libgo/go/debug/plan9obj/plan9obj.go b/libgo/go/debug/plan9obj/plan9obj.go
new file mode 100644 (file)
index 0000000..4e3b08f
--- /dev/null
@@ -0,0 +1,91 @@
+// Copyright 2014 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+ * Plan 9 a.out constants and data structures
+ */
+
+package plan9obj
+
+import (
+       "bytes"
+       "encoding/binary"
+)
+
+// Plan 9 Program header.
+type prog struct {
+       Magic uint32 /* magic number */
+       Text  uint32 /* size of text segment */
+       Data  uint32 /* size of initialized data */
+       Bss   uint32 /* size of uninitialized data */
+       Syms  uint32 /* size of symbol table */
+       Entry uint32 /* entry point */
+       Spsz  uint32 /* size of pc/sp offset table */
+       Pcsz  uint32 /* size of pc/line number table */
+}
+
+// Plan 9 symbol table entries.
+type sym struct {
+       value uint64
+       typ   byte
+       name  []byte
+}
+
+const (
+       hsize      = 4 * 8
+       _HDR_MAGIC = 0x00008000 /* header expansion */
+)
+
+func magic(f, b int) string {
+       buf := new(bytes.Buffer)
+       var i uint32 = uint32((f) | ((((4 * (b)) + 0) * (b)) + 7))
+       binary.Write(buf, binary.BigEndian, i)
+       return string(buf.Bytes())
+}
+
+var (
+       _A_MAGIC = magic(0, 8)           /* 68020 (retired) */
+       _I_MAGIC = magic(0, 11)          /* intel 386 */
+       _J_MAGIC = magic(0, 12)          /* intel 960 (retired) */
+       _K_MAGIC = magic(0, 13)          /* sparc */
+       _V_MAGIC = magic(0, 16)          /* mips 3000 BE */
+       _X_MAGIC = magic(0, 17)          /* att dsp 3210 (retired) */
+       _M_MAGIC = magic(0, 18)          /* mips 4000 BE */
+       _D_MAGIC = magic(0, 19)          /* amd 29000 (retired) */
+       _E_MAGIC = magic(0, 20)          /* arm */
+       _Q_MAGIC = magic(0, 21)          /* powerpc */
+       _N_MAGIC = magic(0, 22)          /* mips 4000 LE */
+       _L_MAGIC = magic(0, 23)          /* dec alpha (retired) */
+       _P_MAGIC = magic(0, 24)          /* mips 3000 LE */
+       _U_MAGIC = magic(0, 25)          /* sparc64 (retired) */
+       _S_MAGIC = magic(_HDR_MAGIC, 26) /* amd64 */
+       _T_MAGIC = magic(_HDR_MAGIC, 27) /* powerpc64 */
+       _R_MAGIC = magic(_HDR_MAGIC, 28) /* arm64 */
+)
+
+type ExecTable struct {
+       Magic string
+       Ptrsz int
+       Hsize uint32
+}
+
+var exectab = []ExecTable{
+       {_A_MAGIC, 4, hsize},
+       {_I_MAGIC, 4, hsize},
+       {_J_MAGIC, 4, hsize},
+       {_K_MAGIC, 4, hsize},
+       {_V_MAGIC, 4, hsize},
+       {_X_MAGIC, 4, hsize},
+       {_M_MAGIC, 4, hsize},
+       {_D_MAGIC, 4, hsize},
+       {_E_MAGIC, 4, hsize},
+       {_Q_MAGIC, 4, hsize},
+       {_N_MAGIC, 4, hsize},
+       {_L_MAGIC, 4, hsize},
+       {_P_MAGIC, 4, hsize},
+       {_U_MAGIC, 4, hsize},
+       {_S_MAGIC, 8, hsize + 8},
+       {_T_MAGIC, 8, hsize + 8},
+       {_R_MAGIC, 8, hsize + 8},
+}
diff --git a/libgo/go/debug/plan9obj/testdata/386-plan9-exec b/libgo/go/debug/plan9obj/testdata/386-plan9-exec
new file mode 100644 (file)
index 0000000..748e83f
Binary files /dev/null and b/libgo/go/debug/plan9obj/testdata/386-plan9-exec differ
diff --git a/libgo/go/debug/plan9obj/testdata/amd64-plan9-exec b/libgo/go/debug/plan9obj/testdata/amd64-plan9-exec
new file mode 100644 (file)
index 0000000..3e257dd
Binary files /dev/null and b/libgo/go/debug/plan9obj/testdata/amd64-plan9-exec differ
diff --git a/libgo/go/debug/plan9obj/testdata/hello.c b/libgo/go/debug/plan9obj/testdata/hello.c
new file mode 100644 (file)
index 0000000..c0d633e
--- /dev/null
@@ -0,0 +1,8 @@
+#include <u.h>
+#include <libc.h>
+
+void
+main(void)
+{
+       print("hello, world\n");
+}
index dc1134dccd63713c88633370e4361b306edd076a..77bc465d5949c916df1c6a75c8d244fb53e25aa4 100644 (file)
@@ -8,6 +8,7 @@ import (
        "bytes"
        "io"
        "io/ioutil"
+       "strings"
        "testing"
 )
 
@@ -115,7 +116,7 @@ func TestDecode(t *testing.T) {
 
 func TestDecoder(t *testing.T) {
        for _, p := range pairs {
-               decoder := NewDecoder(bytes.NewBufferString(p.encoded))
+               decoder := NewDecoder(strings.NewReader(p.encoded))
                dbuf, err := ioutil.ReadAll(decoder)
                if err != nil {
                        t.Fatal("Read failed", err)
@@ -130,7 +131,7 @@ func TestDecoder(t *testing.T) {
 
 func TestDecoderBuffering(t *testing.T) {
        for bs := 1; bs <= 12; bs++ {
-               decoder := NewDecoder(bytes.NewBufferString(bigtest.encoded))
+               decoder := NewDecoder(strings.NewReader(bigtest.encoded))
                buf := make([]byte, len(bigtest.decoded)+12)
                var total int
                for total = 0; total < len(bigtest.decoded); {
index dfcbf920d0afcd34783582fb4be4b9326552e81d..7a3c3797c8bb8240455c133c208f912073315dc5 100644 (file)
@@ -23,6 +23,7 @@ import (
        "fmt"
        "math/big"
        "reflect"
+       "strconv"
        "time"
 )
 
@@ -197,6 +198,19 @@ func (oi ObjectIdentifier) Equal(other ObjectIdentifier) bool {
        return true
 }
 
+func (oi ObjectIdentifier) String() string {
+       var s string
+
+       for i, v := range oi {
+               if i > 0 {
+                       s += "."
+               }
+               s += strconv.Itoa(v)
+       }
+
+       return s
+}
+
 // parseObjectIdentifier parses an OBJECT IDENTIFIER from the given bytes and
 // returns it. An object identifier is a sequence of variable length integers
 // that are assigned in a hierarchy.
@@ -634,6 +648,10 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam
                universalTag = tagGeneralizedTime
        }
 
+       if params.set {
+               universalTag = tagSet
+       }
+
        expectedClass := classUniversal
        expectedTag := universalTag
 
@@ -854,13 +872,20 @@ func setDefaultValue(v reflect.Value, params fieldParameters) (ok bool) {
 //
 // The following tags on struct fields have special meaning to Unmarshal:
 //
-//     optional                marks the field as ASN.1 OPTIONAL
-//     [explicit] tag:x        specifies the ASN.1 tag number; implies ASN.1 CONTEXT SPECIFIC
-//     default:x               sets the default value for optional integer fields
+//     application     specifies that a APPLICATION tag is used
+//     default:x       sets the default value for optional integer fields
+//     explicit        specifies that an additional, explicit tag wraps the implicit one
+//     optional        marks the field as ASN.1 OPTIONAL
+//     set             causes a SET, rather than a SEQUENCE type to be expected
+//     tag:x           specifies the ASN.1 tag number; implies ASN.1 CONTEXT SPECIFIC
 //
 // If the type of the first field of a structure is RawContent then the raw
 // ASN1 contents of the struct will be stored in it.
 //
+// If the type name of a slice element ends with "SET" then it's treated as if
+// the "set" tag was set on it. This can be used with nested slices where a
+// struct tag cannot be given.
+//
 // Other ASN.1 types are not supported; if it encounters them,
 // Unmarshal returns a parse error.
 func Unmarshal(b []byte, val interface{}) (rest []byte, err error) {
index ea98e023faf20badfec5caa5f0cc2f8411f5957d..b553f78e0a6fe659b0f77a541694895976e8c7cd 100644 (file)
@@ -232,6 +232,10 @@ func TestObjectIdentifier(t *testing.T) {
                        }
                }
        }
+
+       if s := ObjectIdentifier([]int{1, 2, 3, 4}).String(); s != "1.2.3.4" {
+               t.Errorf("bad ObjectIdentifier.String(). Got %s, want 1.2.3.4", s)
+       }
 }
 
 type timeTest struct {
@@ -397,6 +401,10 @@ type TestBigInt struct {
        X *big.Int
 }
 
+type TestSet struct {
+       Ints []int `asn1:"set"`
+}
+
 var unmarshalTestData = []struct {
        in  []byte
        out interface{}
@@ -416,6 +424,7 @@ var unmarshalTestData = []struct {
        {[]byte{0x01, 0x01, 0xff}, newBool(true)},
        {[]byte{0x30, 0x0b, 0x13, 0x03, 0x66, 0x6f, 0x6f, 0x02, 0x01, 0x22, 0x02, 0x01, 0x33}, &TestElementsAfterString{"foo", 0x22, 0x33}},
        {[]byte{0x30, 0x05, 0x02, 0x03, 0x12, 0x34, 0x56}, &TestBigInt{big.NewInt(0x123456)}},
+       {[]byte{0x30, 0x0b, 0x31, 0x09, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, 0x01, 0x03}, &TestSet{Ints: []int{1, 2, 3}}},
 }
 
 func TestUnmarshal(t *testing.T) {
index ed17e41a55cfd9f5d1e6ac9f703520eecb597db1..da50cf25e83a7ab5c38a3ed2d3dc6005bf9d780c 100644 (file)
@@ -568,6 +568,14 @@ func marshalField(out *forkableWriter, v reflect.Value, params fieldParameters)
 }
 
 // Marshal returns the ASN.1 encoding of val.
+//
+// In addition to the struct tags recognised by Unmarshal, the following can be
+// used:
+//
+//     ia5:            causes strings to be marshaled as ASN.1, IA5 strings
+//     omitempty:      causes empty slices to be skipped
+//     printable:      causes strings to be marshaled as ASN.1, PrintableString strings.
+//     utf8:           causes strings to be marshaled as ASN.1, UTF8 strings
 func Marshal(val interface{}) ([]byte, error) {
        var out bytes.Buffer
        v := reflect.ValueOf(val)
index 63298d1c94c180d34797b797768b80e7976f4229..f56b996faafa9347467def50ad30855e251ce838 100644 (file)
@@ -108,7 +108,7 @@ func TestDecode(t *testing.T) {
 
 func TestDecoder(t *testing.T) {
        for _, p := range pairs {
-               decoder := NewDecoder(StdEncoding, bytes.NewBufferString(p.encoded))
+               decoder := NewDecoder(StdEncoding, strings.NewReader(p.encoded))
                dbuf := make([]byte, StdEncoding.DecodedLen(len(p.encoded)))
                count, err := decoder.Read(dbuf)
                if err != nil && err != io.EOF {
@@ -125,7 +125,7 @@ func TestDecoder(t *testing.T) {
 
 func TestDecoderBuffering(t *testing.T) {
        for bs := 1; bs <= 12; bs++ {
-               decoder := NewDecoder(StdEncoding, bytes.NewBufferString(bigtest.encoded))
+               decoder := NewDecoder(StdEncoding, strings.NewReader(bigtest.encoded))
                buf := make([]byte, len(bigtest.decoded)+12)
                var total int
                for total = 0; total < len(bigtest.decoded); {
@@ -267,13 +267,13 @@ LNEBUWIIDFON2CA3DBMJXXE5LNFY==
 ====`
        encodedShort := strings.Replace(encoded, "\n", "", -1)
 
-       dec := NewDecoder(StdEncoding, bytes.NewBufferString(encoded))
+       dec := NewDecoder(StdEncoding, strings.NewReader(encoded))
        res1, err := ioutil.ReadAll(dec)
        if err != nil {
                t.Errorf("ReadAll failed: %v", err)
        }
 
-       dec = NewDecoder(StdEncoding, bytes.NewBufferString(encodedShort))
+       dec = NewDecoder(StdEncoding, strings.NewReader(encodedShort))
        var res2 []byte
        res2, err = ioutil.ReadAll(dec)
        if err != nil {
index 579591a88d7a0b44f33eef97c1beb53f7eba34fe..6bcc724d9b5702fc4d42e67bd5df2d9a1cef5cb1 100644 (file)
@@ -113,7 +113,7 @@ func TestDecode(t *testing.T) {
 
 func TestDecoder(t *testing.T) {
        for _, p := range pairs {
-               decoder := NewDecoder(StdEncoding, bytes.NewBufferString(p.encoded))
+               decoder := NewDecoder(StdEncoding, strings.NewReader(p.encoded))
                dbuf := make([]byte, StdEncoding.DecodedLen(len(p.encoded)))
                count, err := decoder.Read(dbuf)
                if err != nil && err != io.EOF {
@@ -130,7 +130,7 @@ func TestDecoder(t *testing.T) {
 
 func TestDecoderBuffering(t *testing.T) {
        for bs := 1; bs <= 12; bs++ {
-               decoder := NewDecoder(StdEncoding, bytes.NewBufferString(bigtest.encoded))
+               decoder := NewDecoder(StdEncoding, strings.NewReader(bigtest.encoded))
                buf := make([]byte, len(bigtest.decoded)+12)
                var total int
                for total = 0; total < len(bigtest.decoded); {
@@ -308,13 +308,13 @@ bqbPb06551Y4
 `
        encodedShort := strings.Replace(encoded, "\n", "", -1)
 
-       dec := NewDecoder(StdEncoding, bytes.NewBufferString(encoded))
+       dec := NewDecoder(StdEncoding, strings.NewReader(encoded))
        res1, err := ioutil.ReadAll(dec)
        if err != nil {
                t.Errorf("ReadAll failed: %v", err)
        }
 
-       dec = NewDecoder(StdEncoding, bytes.NewBufferString(encodedShort))
+       dec = NewDecoder(StdEncoding, strings.NewReader(encodedShort))
        var res2 []byte
        res2, err = ioutil.ReadAll(dec)
        if err != nil {
index fdfee7d871148e5f00132d8322c5a2b38015afdd..1aa6ecd2486ba007cd565209e49bbd05928bff70 100644 (file)
@@ -111,7 +111,7 @@ func checkResult(t *testing.T, dir string, order ByteOrder, err error, have, wan
 
 func testRead(t *testing.T, order ByteOrder, b []byte, s1 interface{}) {
        var s2 Struct
-       err := Read(bytes.NewBuffer(b), order, &s2)
+       err := Read(bytes.NewReader(b), order, &s2)
        checkResult(t, "Read", order, err, s2, s1)
 }
 
@@ -131,7 +131,7 @@ func TestBigEndianPtrWrite(t *testing.T) { testWrite(t, BigEndian, big, &s) }
 
 func TestReadSlice(t *testing.T) {
        slice := make([]int32, 2)
-       err := Read(bytes.NewBuffer(src), BigEndian, slice)
+       err := Read(bytes.NewReader(src), BigEndian, slice)
        checkResult(t, "ReadSlice", BigEndian, err, slice, res)
 }
 
index 9476bd5fb7a6d7ac69d905895a3fbaec81a02895..ca411ecbd65e8180d2bfcb0c819a561328d66f06 100644 (file)
@@ -35,7 +35,7 @@ func testVarint(t *testing.T, x int64) {
                t.Errorf("Varint(%d): got n = %d; want %d", x, m, n)
        }
 
-       y, err := ReadVarint(bytes.NewBuffer(buf))
+       y, err := ReadVarint(bytes.NewReader(buf))
        if err != nil {
                t.Errorf("ReadVarint(%d): %s", x, err)
        }
@@ -55,7 +55,7 @@ func testUvarint(t *testing.T, x uint64) {
                t.Errorf("Uvarint(%d): got n = %d; want %d", x, m, n)
        }
 
-       y, err := ReadUvarint(bytes.NewBuffer(buf))
+       y, err := ReadUvarint(bytes.NewReader(buf))
        if err != nil {
                t.Errorf("ReadUvarint(%d): %s", x, err)
        }
@@ -114,7 +114,7 @@ func TestBufferTooSmall(t *testing.T) {
                        t.Errorf("Uvarint(%v): got x = %d, n = %d", buf, x, n)
                }
 
-               x, err := ReadUvarint(bytes.NewBuffer(buf))
+               x, err := ReadUvarint(bytes.NewReader(buf))
                if x != 0 || err != io.EOF {
                        t.Errorf("ReadUvarint(%v): got x = %d, err = %s", buf, x, err)
                }
@@ -127,7 +127,7 @@ func testOverflow(t *testing.T, buf []byte, n0 int, err0 error) {
                t.Errorf("Uvarint(%v): got x = %d, n = %d; want 0, %d", buf, x, n, n0)
        }
 
-       x, err := ReadUvarint(bytes.NewBuffer(buf))
+       x, err := ReadUvarint(bytes.NewReader(buf))
        if x != 0 || err != err0 {
                t.Errorf("ReadUvarint(%v): got x = %d, err = %s; want 0, %s", buf, x, err, err0)
        }
index b40f78360c235b59eb476c95e551c4cfc150ed67..fa57f3761d0d3b9d21a1f607cfcf774b0d64b4f9 100644 (file)
@@ -1364,11 +1364,7 @@ type DT struct {
        S     []string
 }
 
-func TestDebugStruct(t *testing.T) {
-       if debugFunc == nil {
-               return
-       }
-       Register(OnTheFly{})
+func newDT() DT {
        var dt DT
        dt.A = 17
        dt.B = "hello"
@@ -1379,6 +1375,15 @@ func TestDebugStruct(t *testing.T) {
        dt.M = map[string]int{"one": 1, "two": 2}
        dt.T = [3]int{11, 22, 33}
        dt.S = []string{"hi", "joe"}
+       return dt
+}
+
+func TestDebugStruct(t *testing.T) {
+       if debugFunc == nil {
+               return
+       }
+       Register(OnTheFly{})
+       dt := newDT()
        b := new(bytes.Buffer)
        err := NewEncoder(b).Encode(dt)
        if err != nil {
@@ -1458,3 +1463,44 @@ func testFuzz(t *testing.T, seed int64, n int, input ...interface{}) {
                }
        }
 }
+
+// TestFuzzOneByte tries to decode corrupted input sequences
+// and checks that no panic occurs.
+func TestFuzzOneByte(t *testing.T) {
+       buf := new(bytes.Buffer)
+       Register(OnTheFly{})
+       dt := newDT()
+       if err := NewEncoder(buf).Encode(dt); err != nil {
+               t.Fatal(err)
+       }
+       s := buf.String()
+
+       indices := make([]int, 0, len(s))
+       for i := 0; i < len(s); i++ {
+               switch i {
+               case 14, 167, 231, 265: // a slice length, corruptions are not handled yet.
+                       continue
+               }
+               indices = append(indices, i)
+       }
+       if testing.Short() {
+               indices = []int{1, 111, 178} // known fixed panics
+       }
+       for _, i := range indices {
+               for j := 0; j < 256; j += 3 {
+                       b := []byte(s)
+                       b[i] ^= byte(j)
+                       var e DT
+                       func() {
+                               defer func() {
+                                       if p := recover(); p != nil {
+                                               t.Errorf("crash for b[%d] ^= 0x%x", i, j)
+                                               panic(p)
+                                       }
+                               }()
+                               err := NewDecoder(bytes.NewReader(b)).Decode(&e)
+                               _ = err
+                       }()
+               }
+       }
+}
index 3037a581b3a001ab7c46b5b07374fd965a9254fc..aa186a582e87a906f6101cb294e32c246b244203 100644 (file)
@@ -701,6 +701,9 @@ func (dec *Decoder) decodeInterface(ityp reflect.Type, state *decoderState, p un
        if nr < 0 || nr > 1<<31 { // zero is permissible for anonymous types
                errorf("invalid type name length %d", nr)
        }
+       if nr > uint64(state.b.Len()) {
+               errorf("invalid type name length %d: exceeds input size", nr)
+       }
        b := make([]byte, nr)
        state.b.Read(b)
        name := string(b)
@@ -1237,7 +1240,8 @@ func (dec *Decoder) decodeValue(wireId typeId, val reflect.Value) {
        }
        engine := *enginePtr
        if st := base; st.Kind() == reflect.Struct && ut.externalDec == 0 {
-               if engine.numInstr == 0 && st.NumField() > 0 && len(dec.wireType[wireId].StructT.Field) > 0 {
+               if engine.numInstr == 0 && st.NumField() > 0 &&
+                       dec.wireType[wireId] != nil && len(dec.wireType[wireId].StructT.Field) > 0 {
                        name := base.Name()
                        errorf("type mismatch: no fields matched compiling decoder for %s", name)
                }
index 4ecf51d122b755939f51690a100f7efcace27eda..6445ce10026f0b32dde3d89358cc970497e65b29 100644 (file)
@@ -129,6 +129,8 @@ func TestBadData(t *testing.T) {
        corruptDataCheck("", io.EOF, t)
        corruptDataCheck("\x7Fhi", io.ErrUnexpectedEOF, t)
        corruptDataCheck("\x03now is the time for all good men", errBadType, t)
+       // issue 6323.
+       corruptDataCheck("\x04\x24foo", errRange, t)
 }
 
 // Types not supported at top level by the Encoder.
@@ -630,7 +632,7 @@ func TestSliceReusesMemory(t *testing.T) {
 // Used to crash: negative count in recvMessage.
 func TestBadCount(t *testing.T) {
        b := []byte{0xfb, 0xa5, 0x82, 0x2f, 0xca, 0x1}
-       if err := NewDecoder(bytes.NewBuffer(b)).Decode(nil); err == nil {
+       if err := NewDecoder(bytes.NewReader(b)).Decode(nil); err == nil {
                t.Error("expected error from bad count")
        } else if err.Error() != errBadCount.Error() {
                t.Error("expected bad count error; got", err)
index 4a77ba1cd256e1f47709979c06325d64ddca8b88..741ddd89cbe7ca617e334669b4d776963c6006f3 100644 (file)
@@ -44,6 +44,7 @@ import (
 // if an invalid UTF-8 sequence is encountered.
 // The angle brackets "<" and ">" are escaped to "\u003c" and "\u003e"
 // to keep some browsers from misinterpreting JSON output as HTML.
+// Ampersand "&" is also escaped to "\u0026" for the same reason.
 //
 // Array and slice values encode as JSON arrays, except that
 // []byte encodes as a base64-encoded string, and a nil slice
@@ -804,7 +805,7 @@ func (e *encodeState) string(s string) (int, error) {
                                e.WriteByte('r')
                        default:
                                // This encodes bytes < 0x20 except for \n and \r,
-                               // as well as < and >. The latter are escaped because they
+                               // as well as <, > and &. The latter are escaped because they
                                // can lead to security holes when user-controlled strings
                                // are rendered into JSON and served to some browsers.
                                e.WriteString(`\u00`)
index 265a237e448761eb96123b5c328aecf9632b8c3a..2e89a78eb9fd01d75631f1b9a7cc1e6002e38009 100644 (file)
@@ -93,7 +93,7 @@ func TestStringTag(t *testing.T) {
 
        // Verify that it round-trips.
        var s2 StringTag
-       err = NewDecoder(bytes.NewBuffer(got)).Decode(&s2)
+       err = NewDecoder(bytes.NewReader(got)).Decode(&s2)
        if err != nil {
                t.Fatalf("Decode: %v", err)
        }
index 90e45ff0369081d2f97618cb228c21bcefdd797e..78803429029357322a253ec135c4da90e0170300 100644 (file)
@@ -239,23 +239,16 @@ func trim(b []byte) []byte {
 
 var jsonBig []byte
 
-const (
-       big   = 10000
-       small = 100
-)
-
 func initBig() {
-       n := big
+       n := 10000
        if testing.Short() {
-               n = small
+               n = 100
        }
-       if len(jsonBig) != n {
-               b, err := Marshal(genValue(n))
-               if err != nil {
-                       panic(err)
-               }
-               jsonBig = b
+       b, err := Marshal(genValue(n))
+       if err != nil {
+               panic(err)
        }
+       jsonBig = b
 }
 
 func genValue(n int) interface{} {
@@ -296,6 +289,9 @@ func genArray(n int) []interface{} {
        if f > n {
                f = n
        }
+       if f < 1 {
+               f = 1
+       }
        x := make([]interface{}, f)
        for i := range x {
                x[i] = genValue(((i+1)*n)/f - (i*n)/f)
index 8890508f8555b5b2e3847a4d133ca249862bb153..651d13d4d094dd6adba063ac79c82d9117833115 100644 (file)
@@ -112,7 +112,7 @@ import (
 // to a freshly allocated value and then mapping the element to that value.
 //
 func Unmarshal(data []byte, v interface{}) error {
-       return NewDecoder(bytes.NewBuffer(data)).Decode(v)
+       return NewDecoder(bytes.NewReader(data)).Decode(v)
 }
 
 // Decode works like xml.Unmarshal, except it reads the decoder
index b06599505fc1dccc5780c94fdcfeac67abeb445e..c590782a8d266f0fad192cccfa009d51f248a919 100644 (file)
@@ -29,6 +29,7 @@ import (
        "net/http"
        "os"
        "runtime"
+       "sort"
        "strconv"
        "sync"
 )
@@ -40,8 +41,8 @@ type Var interface {
 
 // Int is a 64-bit integer variable that satisfies the Var interface.
 type Int struct {
-       i  int64
        mu sync.RWMutex
+       i  int64
 }
 
 func (v *Int) String() string {
@@ -64,8 +65,8 @@ func (v *Int) Set(value int64) {
 
 // Float is a 64-bit float variable that satisfies the Var interface.
 type Float struct {
-       f  float64
        mu sync.RWMutex
+       f  float64
 }
 
 func (v *Float) String() string {
@@ -90,8 +91,9 @@ func (v *Float) Set(value float64) {
 
 // Map is a string-to-Var map variable that satisfies the Var interface.
 type Map struct {
-       m  map[string]Var
-       mu sync.RWMutex
+       mu   sync.RWMutex
+       m    map[string]Var
+       keys []string // sorted
 }
 
 // KeyValue represents a single entry in a Map.
@@ -106,13 +108,13 @@ func (v *Map) String() string {
        var b bytes.Buffer
        fmt.Fprintf(&b, "{")
        first := true
-       for key, val := range v.m {
+       v.Do(func(kv KeyValue) {
                if !first {
                        fmt.Fprintf(&b, ", ")
                }
-               fmt.Fprintf(&b, "\"%s\": %v", key, val)
+               fmt.Fprintf(&b, "\"%s\": %v", kv.Key, kv.Value)
                first = false
-       }
+       })
        fmt.Fprintf(&b, "}")
        return b.String()
 }
@@ -122,6 +124,20 @@ func (v *Map) Init() *Map {
        return v
 }
 
+// updateKeys updates the sorted list of keys in v.keys.
+// must be called with v.mu held.
+func (v *Map) updateKeys() {
+       if len(v.m) == len(v.keys) {
+               // No new key.
+               return
+       }
+       v.keys = v.keys[:0]
+       for k := range v.m {
+               v.keys = append(v.keys, k)
+       }
+       sort.Strings(v.keys)
+}
+
 func (v *Map) Get(key string) Var {
        v.mu.RLock()
        defer v.mu.RUnlock()
@@ -132,6 +148,7 @@ func (v *Map) Set(key string, av Var) {
        v.mu.Lock()
        defer v.mu.Unlock()
        v.m[key] = av
+       v.updateKeys()
 }
 
 func (v *Map) Add(key string, delta int64) {
@@ -141,9 +158,11 @@ func (v *Map) Add(key string, delta int64) {
        if !ok {
                // check again under the write lock
                v.mu.Lock()
-               if _, ok = v.m[key]; !ok {
+               av, ok = v.m[key]
+               if !ok {
                        av = new(Int)
                        v.m[key] = av
+                       v.updateKeys()
                }
                v.mu.Unlock()
        }
@@ -162,9 +181,11 @@ func (v *Map) AddFloat(key string, delta float64) {
        if !ok {
                // check again under the write lock
                v.mu.Lock()
-               if _, ok = v.m[key]; !ok {
+               av, ok = v.m[key]
+               if !ok {
                        av = new(Float)
                        v.m[key] = av
+                       v.updateKeys()
                }
                v.mu.Unlock()
        }
@@ -181,15 +202,15 @@ func (v *Map) AddFloat(key string, delta float64) {
 func (v *Map) Do(f func(KeyValue)) {
        v.mu.RLock()
        defer v.mu.RUnlock()
-       for k, v := range v.m {
-               f(KeyValue{k, v})
+       for _, k := range v.keys {
+               f(KeyValue{k, v.m[k]})
        }
 }
 
 // String is a string variable, and satisfies the Var interface.
 type String struct {
-       s  string
        mu sync.RWMutex
+       s  string
 }
 
 func (v *String) String() string {
@@ -215,8 +236,9 @@ func (f Func) String() string {
 
 // All published variables.
 var (
-       mutex sync.RWMutex
-       vars  map[string]Var = make(map[string]Var)
+       mutex   sync.RWMutex
+       vars    = make(map[string]Var)
+       varKeys []string // sorted
 )
 
 // Publish declares a named exported variable. This should be called from a
@@ -229,6 +251,8 @@ func Publish(name string, v Var) {
                log.Panicln("Reuse of exported var name:", name)
        }
        vars[name] = v
+       varKeys = append(varKeys, name)
+       sort.Strings(varKeys)
 }
 
 // Get retrieves a named exported variable.
@@ -270,8 +294,8 @@ func NewString(name string) *String {
 func Do(f func(KeyValue)) {
        mutex.RLock()
        defer mutex.RUnlock()
-       for k, v := range vars {
-               f(KeyValue{k, v})
+       for _, k := range varKeys {
+               f(KeyValue{k, vars[k]})
        }
 }
 
index 572c62beed56cb3eb434ff8ebc124e3512c7822b..d2ea484935e9c5fe08cb52e4c27c01a26b7cab79 100644 (file)
@@ -5,7 +5,10 @@
 package expvar
 
 import (
+       "bytes"
        "encoding/json"
+       "net/http/httptest"
+       "strconv"
        "testing"
 )
 
@@ -15,6 +18,7 @@ func RemoveAll() {
        mutex.Lock()
        defer mutex.Unlock()
        vars = make(map[string]Var)
+       varKeys = nil
 }
 
 func TestInt(t *testing.T) {
@@ -139,3 +143,25 @@ func TestFunc(t *testing.T) {
                t.Errorf(`f.String() = %q, want %q`, s, exp)
        }
 }
+
+func TestHandler(t *testing.T) {
+       RemoveAll()
+       m := NewMap("map1")
+       m.Add("a", 1)
+       m.Add("z", 2)
+       m2 := NewMap("map2")
+       for i := 0; i < 9; i++ {
+               m2.Add(strconv.Itoa(i), int64(i))
+       }
+       rr := httptest.NewRecorder()
+       rr.Body = new(bytes.Buffer)
+       expvarHandler(rr, nil)
+       want := `{
+"map1": {"a": 1, "z": 2},
+"map2": {"0": 0, "1": 1, "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8}
+}
+`
+       if got := rr.Body.String(); got != want {
+               t.Errorf("HTTP handler wrote:\n%s\nWant:\n%s", got, want)
+       }
+}
index 42b3c22048c7d800dcf020004e6e3c61c8ed93b8..ce837ba63e81bd2f569f2cabfedb4886084a1464 100644 (file)
@@ -11,6 +11,7 @@ import (
        "math"
        "runtime"
        "strings"
+       "sync/atomic"
        "testing"
        "time"
        "unicode"
@@ -497,18 +498,18 @@ var fmtTests = []struct {
        {"%v", map[float64]int{math.NaN(): 1, math.NaN(): 2}, "map[NaN:<nil> NaN:<nil>]"},
 
        // Used to crash because nByte didn't allow for a sign.
-       {"%b", int64(-1 << 63), "-1000000000000000000000000000000000000000000000000000000000000000"},
+       {"%b", int64(-1 << 63), zeroFill("-1", 63, "")},
 
        // Used to panic.
-       {"%0100d", 1, "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"},
-       {"%0100d", -1, "-000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"},
-       {"%0.100f", 1.0, "1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},
-       {"%0.100f", -1.0, "-1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},
+       {"%0100d", 1, zeroFill("", 100, "1")},
+       {"%0100d", -1, zeroFill("-", 99, "1")},
+       {"%0.100f", 1.0, zeroFill("1.", 100, "")},
+       {"%0.100f", -1.0, zeroFill("-1.", 100, "")},
 
        // Zero padding floats used to put the minus sign in the middle.
        {"%020f", -1.0, "-000000000001.000000"},
        {"%20f", -1.0, "           -1.000000"},
-       {"%0100f", -1.0, "-00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.000000"},
+       {"%0100f", -1.0, zeroFill("-", 99, "1.000000")},
 
        // Complex fmt used to leave the plus flag set for future entries in the array
        // causing +2+0i and +3+0i instead of 2+0i and 3+0i.
@@ -517,6 +518,33 @@ var fmtTests = []struct {
 
        // Incomplete format specification caused crash.
        {"%.", 3, "%!.(int=3)"},
+
+       // Used to panic with out-of-bounds for very large numeric representations.
+       // nByte is set to handle one bit per uint64 in %b format, with a negative number.
+       // See issue 6777.
+       {"%#064x", 1, zeroFill("0x", 64, "1")},
+       {"%#064x", -1, zeroFill("-0x", 63, "1")},
+       {"%#064b", 1, zeroFill("", 64, "1")},
+       {"%#064b", -1, zeroFill("-", 63, "1")},
+       {"%#064o", 1, zeroFill("", 64, "1")},
+       {"%#064o", -1, zeroFill("-", 63, "1")},
+       {"%#064d", 1, zeroFill("", 64, "1")},
+       {"%#064d", -1, zeroFill("-", 63, "1")},
+       // Test that we handle the crossover above the size of uint64
+       {"%#072x", 1, zeroFill("0x", 72, "1")},
+       {"%#072x", -1, zeroFill("-0x", 71, "1")},
+       {"%#072b", 1, zeroFill("", 72, "1")},
+       {"%#072b", -1, zeroFill("-", 71, "1")},
+       {"%#072o", 1, zeroFill("", 72, "1")},
+       {"%#072o", -1, zeroFill("-", 71, "1")},
+       {"%#072d", 1, zeroFill("", 72, "1")},
+       {"%#072d", -1, zeroFill("-", 71, "1")},
+}
+
+// zeroFill generates zero-filled strings of the specified width. The length
+// of the suffix (but not the prefix) is compensated for in the width calculation.
+func zeroFill(prefix string, width int, suffix string) string {
+       return prefix + strings.Repeat("0", width-len(suffix)) + suffix
 }
 
 func TestSprintf(t *testing.T) {
@@ -606,46 +634,66 @@ func TestReorder(t *testing.T) {
 }
 
 func BenchmarkSprintfEmpty(b *testing.B) {
-       for i := 0; i < b.N; i++ {
+       benchmarkSprintf(b, func(buf *bytes.Buffer) {
                Sprintf("")
-       }
+       })
 }
 
 func BenchmarkSprintfString(b *testing.B) {
-       for i := 0; i < b.N; i++ {
+       benchmarkSprintf(b, func(buf *bytes.Buffer) {
                Sprintf("%s", "hello")
-       }
+       })
 }
 
 func BenchmarkSprintfInt(b *testing.B) {
-       for i := 0; i < b.N; i++ {
+       benchmarkSprintf(b, func(buf *bytes.Buffer) {
                Sprintf("%d", 5)
-       }
+       })
 }
 
 func BenchmarkSprintfIntInt(b *testing.B) {
-       for i := 0; i < b.N; i++ {
+       benchmarkSprintf(b, func(buf *bytes.Buffer) {
                Sprintf("%d %d", 5, 6)
-       }
+       })
 }
 
 func BenchmarkSprintfPrefixedInt(b *testing.B) {
-       for i := 0; i < b.N; i++ {
+       benchmarkSprintf(b, func(buf *bytes.Buffer) {
                Sprintf("This is some meaningless prefix text that needs to be scanned %d", 6)
-       }
+       })
 }
 
 func BenchmarkSprintfFloat(b *testing.B) {
-       for i := 0; i < b.N; i++ {
+       benchmarkSprintf(b, func(buf *bytes.Buffer) {
                Sprintf("%g", 5.23184)
-       }
+       })
 }
 
 func BenchmarkManyArgs(b *testing.B) {
-       var buf bytes.Buffer
-       for i := 0; i < b.N; i++ {
+       benchmarkSprintf(b, func(buf *bytes.Buffer) {
                buf.Reset()
-               Fprintf(&buf, "%2d/%2d/%2d %d:%d:%d %s %s\n", 3, 4, 5, 11, 12, 13, "hello", "world")
+               Fprintf(buf, "%2d/%2d/%2d %d:%d:%d %s %s\n", 3, 4, 5, 11, 12, 13, "hello", "world")
+       })
+}
+
+func benchmarkSprintf(b *testing.B, f func(buf *bytes.Buffer)) {
+       const CallsPerSched = 1000
+       procs := runtime.GOMAXPROCS(-1)
+       N := int32(b.N / CallsPerSched)
+       c := make(chan bool, procs)
+       for p := 0; p < procs; p++ {
+               go func() {
+                       var buf bytes.Buffer
+                       for atomic.AddInt32(&N, -1) >= 0 {
+                               for g := 0; g < CallsPerSched; g++ {
+                                       f(&buf)
+                               }
+                       }
+                       c <- true
+               }()
+       }
+       for p := 0; p < procs; p++ {
+               <-c
        }
 }
 
index a54f12ee9f9f08fd80a1c0c704960779f5834795..3835aa9823a0e0f2f4b1253f64c70328d03c8fcd 100644 (file)
@@ -10,7 +10,9 @@ import (
 )
 
 const (
-       nByte = 65 // %b of an int64, plus a sign.
+       // %b of an int64, plus a sign.
+       // Hex can add 0x and we handle it specially.
+       nByte = 65
 
        ldigits = "0123456789abcdef"
        udigits = "0123456789ABCDEF"
@@ -160,9 +162,16 @@ func (f *fmt) integer(a int64, base uint64, signedness bool, digits string) {
        }
 
        var buf []byte = f.intbuf[0:]
-       if f.widPresent && f.wid > nByte {
-               // We're going to need a bigger boat.
-               buf = make([]byte, f.wid)
+       if f.widPresent {
+               width := f.wid
+               if base == 16 && f.sharp {
+                       // Also adds "0x".
+                       width += 2
+               }
+               if width > nByte {
+                       // We're going to need a bigger boat.
+                       buf = make([]byte, width)
+               }
        }
 
        negative := signedness == signed && a < 0
index c73b8b60283e4e9940096a7ffa2389966c1f76cf..8a337e479d02a22bcc79425372618478d4d967aa 100644 (file)
@@ -284,7 +284,6 @@ var space = [][2]uint16{
        {0x0085, 0x0085},
        {0x00a0, 0x00a0},
        {0x1680, 0x1680},
-       {0x180e, 0x180e},
        {0x2000, 0x200a},
        {0x2028, 0x2029},
        {0x202f, 0x202f},
index d06a9be53123a2c6d58693f1f3f4be7dc91a1a91..096028d34c37118cd76f9d639c6e16089b987dca 100644 (file)
@@ -264,7 +264,6 @@ var cgoEnabled = map[string]bool{
        "dragonfly/amd64": true,
        "freebsd/386":     true,
        "freebsd/amd64":   true,
-       "freebsd/arm":     true,
        "linux/386":       true,
        "linux/amd64":     true,
        "linux/arm":       true,
@@ -303,8 +302,7 @@ func defaultContext() Context {
        case "0":
                c.CgoEnabled = false
        default:
-               // golang.org/issue/5141
-               // cgo should be disabled for cross compilation builds
+               // cgo must be explicitly enabled for cross compilation builds
                if runtime.GOARCH == c.GOARCH && runtime.GOOS == c.GOOS {
                        c.CgoEnabled = cgoEnabled[c.GOOS+"/"+c.GOARCH]
                        break
@@ -358,6 +356,7 @@ type Package struct {
        IgnoredGoFiles []string // .go source files ignored for this build
        CFiles         []string // .c source files
        CXXFiles       []string // .cc, .cpp and .cxx source files
+       MFiles         []string // .m (Objective-C) source files
        HFiles         []string // .h, .hh, .hpp and .hxx source files
        SFiles         []string // .s source files
        SwigFiles      []string // .swig files
@@ -622,6 +621,9 @@ Found:
                case ".cc", ".cpp", ".cxx":
                        p.CXXFiles = append(p.CXXFiles, name)
                        continue
+               case ".m":
+                       p.MFiles = append(p.MFiles, name)
+                       continue
                case ".h", ".hh", ".hpp", ".hxx":
                        p.HFiles = append(p.HFiles, name)
                        continue
@@ -789,7 +791,7 @@ func (ctxt *Context) matchFile(dir, name string, returnImports bool, allTags map
        }
 
        switch ext {
-       case ".go", ".c", ".cc", ".cxx", ".cpp", ".s", ".h", ".hh", ".hpp", ".hxx", ".S", ".swig", ".swigcxx":
+       case ".go", ".c", ".cc", ".cxx", ".cpp", ".m", ".s", ".h", ".hh", ".hpp", ".hxx", ".S", ".swig", ".swigcxx":
                // tentatively okay - read to make sure
        case ".syso":
                // binary, no reading
index 278a22701855ee9efeaaac7c44fae8e4182a5b1f..d238e96eaa850954720898b5f17d2b57a6d1f175 100644 (file)
@@ -29,7 +29,7 @@ var pkgDeps = map[string][]string{
        "errors":      {},
        "io":          {"errors", "sync"},
        "runtime":     {"unsafe"},
-       "sync":        {"sync/atomic", "unsafe"},
+       "sync":        {"runtime", "sync/atomic", "unsafe"},
        "sync/atomic": {"unsafe"},
        "unsafe":      {},
 
@@ -125,7 +125,7 @@ var pkgDeps = map[string][]string{
        "os":            {"L1", "os", "syscall", "time"},
        "path/filepath": {"L2", "os", "syscall"},
        "io/ioutil":     {"L2", "os", "path/filepath", "time"},
-       "os/exec":       {"L2", "os", "syscall"},
+       "os/exec":       {"L2", "os", "path/filepath", "syscall"},
        "os/signal":     {"L2", "os", "syscall"},
 
        // OS enables basic operating system functionality,
@@ -301,7 +301,7 @@ var pkgDeps = map[string][]string{
        // SSL/TLS.
        "crypto/tls": {
                "L4", "CRYPTO-MATH", "CGO", "OS",
-               "crypto/x509", "encoding/pem", "net", "syscall",
+               "container/list", "crypto/x509", "encoding/pem", "net", "syscall",
        },
        "crypto/x509": {
                "L4", "CRYPTO-MATH", "OS", "CGO",
index 2358ed38902f36f9f4758f27b788a6bc08e6eeda..f4ce9f654154247ed6e16eb3ace05593fe953880 100644 (file)
@@ -32,6 +32,17 @@ type Example struct {
 
 // Examples returns the examples found in the files, sorted by Name field.
 // The Order fields record the order in which the examples were encountered.
+//
+// Playable Examples must be in a package whose name ends in "_test".
+// An Example is "playable" (the Play field is non-nil) in either of these
+// circumstances:
+//   - The example function is self-contained: the function references only
+//     identifiers from other packages (or predeclared identifiers, such as
+//     "int") and the test file does not include a dot import.
+//   - The entire test file is the example: the file contains exactly one
+//     example function, zero test or benchmark functions, and at least one
+//     top-level function, type, variable, or constant declaration other
+//     than the example function.
 func Examples(files ...*ast.File) []*Example {
        var list []*Example
        for _, file := range files {
index c4523318f2614773d54b5b856931f79495a9f333..c3e3ee859ab2f623c47634e0c5296b84054e3198 100644 (file)
@@ -1168,16 +1168,19 @@ func (p *parser) parseIndexOrSlice(x ast.Expr) ast.Expr {
                defer un(trace(p, "IndexOrSlice"))
        }
 
+       const N = 3 // change the 3 to 2 to disable 3-index slices
        lbrack := p.expect(token.LBRACK)
        p.exprLev++
-       var index [3]ast.Expr // change the 3 to 2 to disable slice expressions w/ cap
+       var index [N]ast.Expr
+       var colons [N - 1]token.Pos
        if p.tok != token.COLON {
                index[0] = p.parseRhs()
        }
        ncolons := 0
-       for p.tok == token.COLON && ncolons < len(index)-1 {
-               p.next()
+       for p.tok == token.COLON && ncolons < len(colons) {
+               colons[ncolons] = p.pos
                ncolons++
+               p.next()
                if p.tok != token.COLON && p.tok != token.RBRACK && p.tok != token.EOF {
                        index[ncolons] = p.parseRhs()
                }
@@ -1187,7 +1190,21 @@ func (p *parser) parseIndexOrSlice(x ast.Expr) ast.Expr {
 
        if ncolons > 0 {
                // slice expression
-               return &ast.SliceExpr{X: x, Lbrack: lbrack, Low: index[0], High: index[1], Max: index[2], Slice3: ncolons == 2, Rbrack: rbrack}
+               slice3 := false
+               if ncolons == 2 {
+                       slice3 = true
+                       // Check presence of 2nd and 3rd index here rather than during type-checking
+                       // to prevent erroneous programs from passing through gofmt (was issue 7305).
+                       if index[1] == nil {
+                               p.error(colons[0], "2nd index required in 3-index slice")
+                               index[1] = &ast.BadExpr{From: colons[0] + 1, To: colons[1]}
+                       }
+                       if index[2] == nil {
+                               p.error(colons[1], "3rd index required in 3-index slice")
+                               index[2] = &ast.BadExpr{From: colons[1] + 1, To: rbrack}
+                       }
+               }
+               return &ast.SliceExpr{X: x, Lbrack: lbrack, Low: index[0], High: index[1], Max: index[2], Slice3: slice3, Rbrack: rbrack}
        }
 
        return &ast.IndexExpr{X: x, Lbrack: lbrack, Index: index[0], Rbrack: rbrack}
@@ -1745,14 +1762,14 @@ func (p *parser) parseBranchStmt(tok token.Token) *ast.BranchStmt {
        return &ast.BranchStmt{TokPos: pos, Tok: tok, Label: label}
 }
 
-func (p *parser) makeExpr(s ast.Stmt) ast.Expr {
+func (p *parser) makeExpr(s ast.Stmt, kind string) ast.Expr {
        if s == nil {
                return nil
        }
        if es, isExpr := s.(*ast.ExprStmt); isExpr {
                return p.checkExpr(es.X)
        }
-       p.error(s.Pos(), "expected condition, found simple statement")
+       p.error(s.Pos(), fmt.Sprintf("expected %s, found simple statement (missing parentheses around composite literal?)", kind))
        return &ast.BadExpr{From: s.Pos(), To: s.End()}
 }
 
@@ -1779,7 +1796,7 @@ func (p *parser) parseIfStmt() *ast.IfStmt {
                                p.next()
                                x = p.parseRhs()
                        } else {
-                               x = p.makeExpr(s)
+                               x = p.makeExpr(s, "boolean expression")
                                s = nil
                        }
                }
@@ -1910,7 +1927,7 @@ func (p *parser) parseSwitchStmt() ast.Stmt {
                return &ast.TypeSwitchStmt{Switch: pos, Init: s1, Assign: s2, Body: body}
        }
 
-       return &ast.SwitchStmt{Switch: pos, Init: s1, Tag: p.makeExpr(s2), Body: body}
+       return &ast.SwitchStmt{Switch: pos, Init: s1, Tag: p.makeExpr(s2, "switch expression"), Body: body}
 }
 
 func (p *parser) parseCommClause() *ast.CommClause {
@@ -2055,7 +2072,7 @@ func (p *parser) parseForStmt() ast.Stmt {
        return &ast.ForStmt{
                For:  pos,
                Init: s1,
-               Cond: p.makeExpr(s2),
+               Cond: p.makeExpr(s2, "boolean or range expression"),
                Post: s3,
                Body: body,
        }
index 0ef0c560c4a50d95be87d4c7d2012959c74dd04e..22f79930b372ef46b856b28912b579d54eceb532 100644 (file)
@@ -48,14 +48,14 @@ var invalids = []string{
        `package p; func f() { if { /* ERROR "expected operand" */ } };`,
        `package p; func f() { if ; { /* ERROR "expected operand" */ } };`,
        `package p; func f() { if f(); { /* ERROR "expected operand" */ } };`,
-       `package p; func f() { if _ /* ERROR "expected condition" */ = range x; true {} };`,
-       `package p; func f() { switch _ /* ERROR "expected condition" */ = range x; true {} };`,
+       `package p; func f() { if _ /* ERROR "expected boolean expression" */ = range x; true {} };`,
+       `package p; func f() { switch _ /* ERROR "expected switch expression" */ = range x; true {} };`,
        `package p; func f() { for _ = range x ; /* ERROR "expected '{'" */ ; {} };`,
        `package p; func f() { for ; ; _ = range /* ERROR "expected operand" */ x {} };`,
-       `package p; func f() { for ; _ /* ERROR "expected condition" */ = range x ; {} };`,
-       `package p; func f() { switch t /* ERROR "expected condition" */ = t.(type) {} };`,
-       `package p; func f() { switch t /* ERROR "expected condition" */ , t = t.(type) {} };`,
-       `package p; func f() { switch t /* ERROR "expected condition" */ = t.(type), t {} };`,
+       `package p; func f() { for ; _ /* ERROR "expected boolean or range expression" */ = range x ; {} };`,
+       `package p; func f() { switch t /* ERROR "expected switch expression" */ = t.(type) {} };`,
+       `package p; func f() { switch t /* ERROR "expected switch expression" */ , t = t.(type) {} };`,
+       `package p; func f() { switch t /* ERROR "expected switch expression" */ = t.(type), t {} };`,
        `package p; var a = [ /* ERROR "expected expression" */ 1]int;`,
        `package p; var a = [ /* ERROR "expected expression" */ ...]int;`,
        `package p; var a = struct /* ERROR "expected expression" */ {}`,
@@ -76,8 +76,16 @@ var invalids = []string{
        `package p; func f() { _ = x = /* ERROR "expected '=='" */ 0 {}};`,
        `package p; func f() { _ = 1 == func()int { var x bool; x = x = /* ERROR "expected '=='" */ true; return x }() };`,
        `package p; func f() { var s []int; _ = s[] /* ERROR "expected operand" */ };`,
-       `package p; func f() { var s []int; _ = s[::: /* ERROR "expected ']'" */ ] };`,
+       `package p; func f() { var s []int; _ = s[i:j: /* ERROR "3rd index required" */ ] };`,
+       `package p; func f() { var s []int; _ = s[i: /* ERROR "2nd index required" */ :k] };`,
+       `package p; func f() { var s []int; _ = s[i: /* ERROR "2nd index required" */ :] };`,
+       `package p; func f() { var s []int; _ = s[: /* ERROR "2nd index required" */ :] };`,
+       `package p; func f() { var s []int; _ = s[: /* ERROR "2nd index required" */ ::] };`,
        `package p; func f() { var s []int; _ = s[i:j:k: /* ERROR "expected ']'" */ l] };`,
+       `package p; func f() { for x /* ERROR "boolean or range expression" */ = []string {} }`,
+       `package p; func f() { for x /* ERROR "boolean or range expression" */ := []string {} }`,
+       `package p; func f() { for i /* ERROR "boolean or range expression" */ , x = []string {} }`,
+       `package p; func f() { for i /* ERROR "boolean or range expression" */ , x := []string {} }`,
 }
 
 func TestInvalid(t *testing.T) {
index 1e259d5ed2a4f1007cc8cbae778b7d8757e5fa2e..25588ba3b0c0bb166dd518a2adbdb2c5df729501 100644 (file)
@@ -358,73 +358,94 @@ exit:
        return tok, string(s.src[offs:s.offset])
 }
 
-func (s *Scanner) scanEscape(quote rune) {
+// scanEscape parses an escape sequence where rune is the accepted
+// escaped quote. In case of a syntax error, it stops at the offending
+// character (without consuming it) and returns false. Otherwise
+// it returns true.
+func (s *Scanner) scanEscape(quote rune) bool {
        offs := s.offset
 
-       var i, base, max uint32
+       var n int
+       var base, max uint32
        switch s.ch {
        case 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', quote:
                s.next()
-               return
+               return true
        case '0', '1', '2', '3', '4', '5', '6', '7':
-               i, base, max = 3, 8, 255
+               n, base, max = 3, 8, 255
        case 'x':
                s.next()
-               i, base, max = 2, 16, 255
+               n, base, max = 2, 16, 255
        case 'u':
                s.next()
-               i, base, max = 4, 16, unicode.MaxRune
+               n, base, max = 4, 16, unicode.MaxRune
        case 'U':
                s.next()
-               i, base, max = 8, 16, unicode.MaxRune
+               n, base, max = 8, 16, unicode.MaxRune
        default:
-               s.next() // always make progress
-               s.error(offs, "unknown escape sequence")
-               return
+               msg := "unknown escape sequence"
+               if s.ch < 0 {
+                       msg = "escape sequence not terminated"
+               }
+               s.error(offs, msg)
+               return false
        }
 
        var x uint32
-       for ; i > 0 && s.ch != quote && s.ch >= 0; i-- {
+       for n > 0 {
                d := uint32(digitVal(s.ch))
                if d >= base {
-                       s.error(s.offset, "illegal character in escape sequence")
-                       break
+                       msg := fmt.Sprintf("illegal character %#U in escape sequence", s.ch)
+                       if s.ch < 0 {
+                               msg = "escape sequence not terminated"
+                       }
+                       s.error(s.offset, msg)
+                       return false
                }
                x = x*base + d
                s.next()
+               n--
        }
-       // in case of an error, consume remaining chars
-       for ; i > 0 && s.ch != quote && s.ch >= 0; i-- {
-               s.next()
-       }
+
        if x > max || 0xD800 <= x && x < 0xE000 {
                s.error(offs, "escape sequence is invalid Unicode code point")
+               return false
        }
+
+       return true
 }
 
-func (s *Scanner) scanChar() string {
+func (s *Scanner) scanRune() string {
        // '\'' opening already consumed
        offs := s.offset - 1
 
+       valid := true
        n := 0
-       for s.ch != '\'' {
+       for {
                ch := s.ch
-               n++
-               s.next()
                if ch == '\n' || ch < 0 {
-                       s.error(offs, "character literal not terminated")
-                       n = 1
+                       // only report error if we don't have one already
+                       if valid {
+                               s.error(offs, "rune literal not terminated")
+                               valid = false
+                       }
                        break
                }
+               s.next()
+               if ch == '\'' {
+                       break
+               }
+               n++
                if ch == '\\' {
-                       s.scanEscape('\'')
+                       if !s.scanEscape('\'') {
+                               valid = false
+                       }
+                       // continue to read to closing quote
                }
        }
 
-       s.next()
-
-       if n != 1 {
-               s.error(offs, "illegal character literal")
+       if valid && n != 1 {
+               s.error(offs, "illegal rune literal")
        }
 
        return string(s.src[offs:s.offset])
@@ -434,11 +455,14 @@ func (s *Scanner) scanString() string {
        // '"' opening already consumed
        offs := s.offset - 1
 
-       for s.ch != '"' {
+       for {
                ch := s.ch
-               s.next()
                if ch == '\n' || ch < 0 {
-                       s.error(offs, "string not terminated")
+                       s.error(offs, "string literal not terminated")
+                       break
+               }
+               s.next()
+               if ch == '"' {
                        break
                }
                if ch == '\\' {
@@ -446,8 +470,6 @@ func (s *Scanner) scanString() string {
                }
        }
 
-       s.next()
-
        return string(s.src[offs:s.offset])
 }
 
@@ -468,20 +490,21 @@ func (s *Scanner) scanRawString() string {
        offs := s.offset - 1
 
        hasCR := false
-       for s.ch != '`' {
+       for {
                ch := s.ch
+               if ch < 0 {
+                       s.error(offs, "raw string literal not terminated")
+                       break
+               }
                s.next()
+               if ch == '`' {
+                       break
+               }
                if ch == '\r' {
                        hasCR = true
                }
-               if ch < 0 {
-                       s.error(offs, "string not terminated")
-                       break
-               }
        }
 
-       s.next()
-
        lit := s.src[offs:s.offset]
        if hasCR {
                lit = stripCR(lit)
@@ -617,7 +640,7 @@ scanAgain:
                case '\'':
                        insertSemi = true
                        tok = token.CHAR
-                       lit = s.scanChar()
+                       lit = s.scanRune()
                case '`':
                        insertSemi = true
                        tok = token.STRING
index 8c64c2b95ffca6a7f1fe37952133272db66675f6..e0d0b54f68e6d73d11cf7b05bbc290982613d5b3 100644 (file)
@@ -631,7 +631,7 @@ type errorCollector struct {
        pos token.Position // last error position encountered
 }
 
-func checkError(t *testing.T, src string, tok token.Token, pos int, err string) {
+func checkError(t *testing.T, src string, tok token.Token, pos int, lit, err string) {
        var s Scanner
        var h errorCollector
        eh := func(pos token.Position, msg string) {
@@ -640,13 +640,12 @@ func checkError(t *testing.T, src string, tok token.Token, pos int, err string)
                h.pos = pos
        }
        s.Init(fset.AddFile("", fset.Base(), len(src)), []byte(src), eh, ScanComments|dontInsertSemis)
-       _, tok0, _ := s.Scan()
-       _, tok1, _ := s.Scan()
+       _, tok0, lit0 := s.Scan()
        if tok0 != tok {
                t.Errorf("%q: got %s, expected %s", src, tok0, tok)
        }
-       if tok1 != token.EOF {
-               t.Errorf("%q: got %s, expected EOF", src, tok1)
+       if tok0 != token.ILLEGAL && lit0 != lit {
+               t.Errorf("%q: got literal %q, expected %q", src, lit0, lit)
        }
        cnt := 0
        if err != "" {
@@ -667,43 +666,71 @@ var errors = []struct {
        src string
        tok token.Token
        pos int
+       lit string
        err string
 }{
-       {"\a", token.ILLEGAL, 0, "illegal character U+0007"},
-       {`#`, token.ILLEGAL, 0, "illegal character U+0023 '#'"},
-       {`…`, token.ILLEGAL, 0, "illegal character U+2026 '…'"},
-       {`' '`, token.CHAR, 0, ""},
-       {`''`, token.CHAR, 0, "illegal character literal"},
-       {`'\8'`, token.CHAR, 2, "unknown escape sequence"},
-       {`'\08'`, token.CHAR, 3, "illegal character in escape sequence"},
-       {`'\x0g'`, token.CHAR, 4, "illegal character in escape sequence"},
-       {`'\Uffffffff'`, token.CHAR, 2, "escape sequence is invalid Unicode code point"},
-       {`'`, token.CHAR, 0, "character literal not terminated"},
-       {`""`, token.STRING, 0, ""},
-       {`"`, token.STRING, 0, "string not terminated"},
-       {"``", token.STRING, 0, ""},
-       {"`", token.STRING, 0, "string not terminated"},
-       {"/**/", token.COMMENT, 0, ""},
-       {"/*", token.COMMENT, 0, "comment not terminated"},
-       {"077", token.INT, 0, ""},
-       {"078.", token.FLOAT, 0, ""},
-       {"07801234567.", token.FLOAT, 0, ""},
-       {"078e0", token.FLOAT, 0, ""},
-       {"078", token.INT, 0, "illegal octal number"},
-       {"07800000009", token.INT, 0, "illegal octal number"},
-       {"0x", token.INT, 0, "illegal hexadecimal number"},
-       {"0X", token.INT, 0, "illegal hexadecimal number"},
-       {"\"abc\x00def\"", token.STRING, 4, "illegal character NUL"},
-       {"\"abc\x80def\"", token.STRING, 4, "illegal UTF-8 encoding"},
-       {"\ufeff\ufeff", token.ILLEGAL, 3, "illegal byte order mark"},            // only first BOM is ignored
-       {"//\ufeff", token.COMMENT, 2, "illegal byte order mark"},                // only first BOM is ignored
-       {"'\ufeff" + `'`, token.CHAR, 1, "illegal byte order mark"},              // only first BOM is ignored
-       {`"` + "abc\ufeffdef" + `"`, token.STRING, 4, "illegal byte order mark"}, // only first BOM is ignored
+       {"\a", token.ILLEGAL, 0, "", "illegal character U+0007"},
+       {`#`, token.ILLEGAL, 0, "", "illegal character U+0023 '#'"},
+       {`…`, token.ILLEGAL, 0, "", "illegal character U+2026 '…'"},
+       {`' '`, token.CHAR, 0, `' '`, ""},
+       {`''`, token.CHAR, 0, `''`, "illegal rune literal"},
+       {`'12'`, token.CHAR, 0, `'12'`, "illegal rune literal"},
+       {`'123'`, token.CHAR, 0, `'123'`, "illegal rune literal"},
+       {`'\0'`, token.CHAR, 3, `'\0'`, "illegal character U+0027 ''' in escape sequence"},
+       {`'\07'`, token.CHAR, 4, `'\07'`, "illegal character U+0027 ''' in escape sequence"},
+       {`'\8'`, token.CHAR, 2, `'\8'`, "unknown escape sequence"},
+       {`'\08'`, token.CHAR, 3, `'\08'`, "illegal character U+0038 '8' in escape sequence"},
+       {`'\x'`, token.CHAR, 3, `'\x'`, "illegal character U+0027 ''' in escape sequence"},
+       {`'\x0'`, token.CHAR, 4, `'\x0'`, "illegal character U+0027 ''' in escape sequence"},
+       {`'\x0g'`, token.CHAR, 4, `'\x0g'`, "illegal character U+0067 'g' in escape sequence"},
+       {`'\u'`, token.CHAR, 3, `'\u'`, "illegal character U+0027 ''' in escape sequence"},
+       {`'\u0'`, token.CHAR, 4, `'\u0'`, "illegal character U+0027 ''' in escape sequence"},
+       {`'\u00'`, token.CHAR, 5, `'\u00'`, "illegal character U+0027 ''' in escape sequence"},
+       {`'\u000'`, token.CHAR, 6, `'\u000'`, "illegal character U+0027 ''' in escape sequence"},
+       {`'\u000`, token.CHAR, 6, `'\u000`, "escape sequence not terminated"},
+       {`'\u0000'`, token.CHAR, 0, `'\u0000'`, ""},
+       {`'\U'`, token.CHAR, 3, `'\U'`, "illegal character U+0027 ''' in escape sequence"},
+       {`'\U0'`, token.CHAR, 4, `'\U0'`, "illegal character U+0027 ''' in escape sequence"},
+       {`'\U00'`, token.CHAR, 5, `'\U00'`, "illegal character U+0027 ''' in escape sequence"},
+       {`'\U000'`, token.CHAR, 6, `'\U000'`, "illegal character U+0027 ''' in escape sequence"},
+       {`'\U0000'`, token.CHAR, 7, `'\U0000'`, "illegal character U+0027 ''' in escape sequence"},
+       {`'\U00000'`, token.CHAR, 8, `'\U00000'`, "illegal character U+0027 ''' in escape sequence"},
+       {`'\U000000'`, token.CHAR, 9, `'\U000000'`, "illegal character U+0027 ''' in escape sequence"},
+       {`'\U0000000'`, token.CHAR, 10, `'\U0000000'`, "illegal character U+0027 ''' in escape sequence"},
+       {`'\U0000000`, token.CHAR, 10, `'\U0000000`, "escape sequence not terminated"},
+       {`'\U00000000'`, token.CHAR, 0, `'\U00000000'`, ""},
+       {`'\Uffffffff'`, token.CHAR, 2, `'\Uffffffff'`, "escape sequence is invalid Unicode code point"},
+       {`'`, token.CHAR, 0, `'`, "rune literal not terminated"},
+       {`'\`, token.CHAR, 2, `'\`, "escape sequence not terminated"},
+       {"'\n", token.CHAR, 0, "'", "rune literal not terminated"},
+       {"'\n   ", token.CHAR, 0, "'", "rune literal not terminated"},
+       {`""`, token.STRING, 0, `""`, ""},
+       {`"abc`, token.STRING, 0, `"abc`, "string literal not terminated"},
+       {"\"abc\n", token.STRING, 0, `"abc`, "string literal not terminated"},
+       {"\"abc\n   ", token.STRING, 0, `"abc`, "string literal not terminated"},
+       {"``", token.STRING, 0, "``", ""},
+       {"`", token.STRING, 0, "`", "raw string literal not terminated"},
+       {"/**/", token.COMMENT, 0, "/**/", ""},
+       {"/*", token.COMMENT, 0, "/*", "comment not terminated"},
+       {"077", token.INT, 0, "077", ""},
+       {"078.", token.FLOAT, 0, "078.", ""},
+       {"07801234567.", token.FLOAT, 0, "07801234567.", ""},
+       {"078e0", token.FLOAT, 0, "078e0", ""},
+       {"078", token.INT, 0, "078", "illegal octal number"},
+       {"07800000009", token.INT, 0, "07800000009", "illegal octal number"},
+       {"0x", token.INT, 0, "0x", "illegal hexadecimal number"},
+       {"0X", token.INT, 0, "0X", "illegal hexadecimal number"},
+       {"\"abc\x00def\"", token.STRING, 4, "\"abc\x00def\"", "illegal character NUL"},
+       {"\"abc\x80def\"", token.STRING, 4, "\"abc\x80def\"", "illegal UTF-8 encoding"},
+       {"\ufeff\ufeff", token.ILLEGAL, 3, "\ufeff\ufeff", "illegal byte order mark"},                        // only first BOM is ignored
+       {"//\ufeff", token.COMMENT, 2, "//\ufeff", "illegal byte order mark"},                                // only first BOM is ignored
+       {"'\ufeff" + `'`, token.CHAR, 1, "'\ufeff" + `'`, "illegal byte order mark"},                         // only first BOM is ignored
+       {`"` + "abc\ufeffdef" + `"`, token.STRING, 4, `"` + "abc\ufeffdef" + `"`, "illegal byte order mark"}, // only first BOM is ignored
 }
 
 func TestScanErrors(t *testing.T) {
        for _, e := range errors {
-               checkError(t, e.src, e.tok, e.pos, e.err)
+               checkError(t, e.src, e.tok, e.pos, e.lit, e.err)
        }
 }
 
index 2c7e816cff140266eef67c7c392be23f09f436c5..ab8dd5d3b40534e2354846b814d42d3a173ad004 100644 (file)
@@ -26,7 +26,8 @@ func (mr *multiReader) Read(p []byte) (n int, err error) {
 
 // MultiReader returns a Reader that's the logical concatenation of
 // the provided input readers.  They're read sequentially.  Once all
-// inputs are drained, Read will return EOF.
+// inputs have returned EOF, Read will return EOF.  If any of the readers
+// return a non-nil, non-EOF error, Read will return that error.
 func MultiReader(readers ...Reader) Reader {
        return &multiReader{readers}
 }
index 306bf0ac65bcad7e58d44031c60996913f4de1ab..c5ff4252d50f21492efc7929c7e17aa5c61c1fe9 100644 (file)
@@ -136,12 +136,11 @@ func divWW_g(u1, u0, v Word) (q, r Word) {
        q1 := un32 / vn1
        rhat := un32 - q1*vn1
 
-again1:
-       if q1 >= _B2 || q1*vn0 > _B2*rhat+un1 {
+       for q1 >= _B2 || q1*vn0 > _B2*rhat+un1 {
                q1--
                rhat += vn1
-               if rhat < _B2 {
-                       goto again1
+               if rhat >= _B2 {
+                       break
                }
        }
 
@@ -149,12 +148,11 @@ again1:
        q0 := un21 / vn1
        rhat = un21 - q0*vn1
 
-again2:
-       if q0 >= _B2 || q0*vn0 > _B2*rhat+un0 {
+       for q0 >= _B2 || q0*vn0 > _B2*rhat+un0 {
                q0--
                rhat += vn1
-               if rhat < _B2 {
-                       goto again2
+               if rhat >= _B2 {
+                       break
                }
        }
 
index 7bbb152d79cac16bc9cac3f3ca35a2f55306a19b..4591590d409817e6bf8b05af1be5674b6cd06c1a 100644 (file)
@@ -982,17 +982,29 @@ func (z *Int) GobDecode(buf []byte) error {
 }
 
 // MarshalJSON implements the json.Marshaler interface.
-func (x *Int) MarshalJSON() ([]byte, error) {
+func (z *Int) MarshalJSON() ([]byte, error) {
        // TODO(gri): get rid of the []byte/string conversions
-       return []byte(x.String()), nil
+       return []byte(z.String()), nil
 }
 
 // UnmarshalJSON implements the json.Unmarshaler interface.
-func (z *Int) UnmarshalJSON(x []byte) error {
+func (z *Int) UnmarshalJSON(text []byte) error {
        // TODO(gri): get rid of the []byte/string conversions
-       _, ok := z.SetString(string(x), 0)
-       if !ok {
-               return fmt.Errorf("math/big: cannot unmarshal %s into a *big.Int", x)
+       if _, ok := z.SetString(string(text), 0); !ok {
+               return fmt.Errorf("math/big: cannot unmarshal %q into a *big.Int", text)
+       }
+       return nil
+}
+
+// MarshalText implements the encoding.TextMarshaler interface
+func (z *Int) MarshalText() (text []byte, err error) {
+       return []byte(z.String()), nil
+}
+
+// UnmarshalText implements the encoding.TextUnmarshaler interface
+func (z *Int) UnmarshalText(text []byte) error {
+       if _, ok := z.SetString(string(text), 0); !ok {
+               return fmt.Errorf("math/big: cannot unmarshal %q into a *big.Int", text)
        }
        return nil
 }
index 87b975d5c4b6763170124918bdf6eb2c5857a9c9..3dd9c5b712b72d200d71e5e60846f37cb67a0f12 100644 (file)
@@ -9,6 +9,7 @@ import (
        "encoding/gob"
        "encoding/hex"
        "encoding/json"
+       "encoding/xml"
        "fmt"
        "math/rand"
        "testing"
@@ -1528,6 +1529,58 @@ func TestIntJSONEncoding(t *testing.T) {
        }
 }
 
+var intVals = []string{
+       "-141592653589793238462643383279502884197169399375105820974944592307816406286",
+       "-1415926535897932384626433832795028841971",
+       "-141592653589793",
+       "-1",
+       "0",
+       "1",
+       "141592653589793",
+       "1415926535897932384626433832795028841971",
+       "141592653589793238462643383279502884197169399375105820974944592307816406286",
+}
+
+func TestIntJSONEncodingTextMarshaller(t *testing.T) {
+       for _, num := range intVals {
+               var tx Int
+               tx.SetString(num, 0)
+               b, err := json.Marshal(&tx)
+               if err != nil {
+                       t.Errorf("marshaling of %s failed: %s", &tx, err)
+                       continue
+               }
+               var rx Int
+               if err := json.Unmarshal(b, &rx); err != nil {
+                       t.Errorf("unmarshaling of %s failed: %s", &tx, err)
+                       continue
+               }
+               if rx.Cmp(&tx) != 0 {
+                       t.Errorf("JSON encoding of %s failed: got %s want %s", &tx, &rx, &tx)
+               }
+       }
+}
+
+func TestIntXMLEncodingTextMarshaller(t *testing.T) {
+       for _, num := range intVals {
+               var tx Int
+               tx.SetString(num, 0)
+               b, err := xml.Marshal(&tx)
+               if err != nil {
+                       t.Errorf("marshaling of %s failed: %s", &tx, err)
+                       continue
+               }
+               var rx Int
+               if err := xml.Unmarshal(b, &rx); err != nil {
+                       t.Errorf("unmarshaling of %s failed: %s", &tx, err)
+                       continue
+               }
+               if rx.Cmp(&tx) != 0 {
+                       t.Errorf("XML encoding of %s failed: got %s want %s", &tx, &rx, &tx)
+               }
+       }
+}
+
 func TestIssue2607(t *testing.T) {
        // This code sequence used to hang.
        n := NewInt(10)
index 7faee61a465c64b67a8215357f711916ee307b0a..3cdb1d807f5dc4406eab1b9a70e4013a7396f45f 100644 (file)
@@ -585,3 +585,16 @@ func (z *Rat) GobDecode(buf []byte) error {
        z.b.abs = z.b.abs.setBytes(buf[i:])
        return nil
 }
+
+// MarshalText implements the encoding.TextMarshaler interface
+func (r *Rat) MarshalText() (text []byte, err error) {
+       return []byte(r.RatString()), nil
+}
+
+// UnmarshalText implements the encoding.TextUnmarshaler interface
+func (r *Rat) UnmarshalText(text []byte) error {
+       if _, ok := r.SetString(string(text)); !ok {
+               return fmt.Errorf("math/big: cannot unmarshal %q into a *big.Rat", text)
+       }
+       return nil
+}
index 0d432637ba19764d65d7ef4f138d72bd652c1c84..414a67d419d68383455e5ae09e0785a5f79f2b3b 100644 (file)
@@ -7,6 +7,8 @@ package big
 import (
        "bytes"
        "encoding/gob"
+       "encoding/json"
+       "encoding/xml"
        "fmt"
        "math"
        "strconv"
@@ -433,6 +435,69 @@ func TestGobEncodingNilRatInSlice(t *testing.T) {
        }
 }
 
+var ratNums = []string{
+       "-141592653589793238462643383279502884197169399375105820974944592307816406286",
+       "-1415926535897932384626433832795028841971",
+       "-141592653589793",
+       "-1",
+       "0",
+       "1",
+       "141592653589793",
+       "1415926535897932384626433832795028841971",
+       "141592653589793238462643383279502884197169399375105820974944592307816406286",
+}
+
+var ratDenoms = []string{
+       "1",
+       "718281828459045",
+       "7182818284590452353602874713526624977572",
+       "718281828459045235360287471352662497757247093699959574966967627724076630353",
+}
+
+func TestRatJSONEncoding(t *testing.T) {
+       for _, num := range ratNums {
+               for _, denom := range ratDenoms {
+                       var tx Rat
+                       tx.SetString(num + "/" + denom)
+                       b, err := json.Marshal(&tx)
+                       if err != nil {
+                               t.Errorf("marshaling of %s failed: %s", &tx, err)
+                               continue
+                       }
+                       var rx Rat
+                       if err := json.Unmarshal(b, &rx); err != nil {
+                               t.Errorf("unmarshaling of %s failed: %s", &tx, err)
+                               continue
+                       }
+                       if rx.Cmp(&tx) != 0 {
+                               t.Errorf("JSON encoding of %s failed: got %s want %s", &tx, &rx, &tx)
+                       }
+               }
+       }
+}
+
+func TestRatXMLEncoding(t *testing.T) {
+       for _, num := range ratNums {
+               for _, denom := range ratDenoms {
+                       var tx Rat
+                       tx.SetString(num + "/" + denom)
+                       b, err := xml.Marshal(&tx)
+                       if err != nil {
+                               t.Errorf("marshaling of %s failed: %s", &tx, err)
+                               continue
+                       }
+                       var rx Rat
+                       if err := xml.Unmarshal(b, &rx); err != nil {
+                               t.Errorf("unmarshaling of %s failed: %s", &tx, err)
+                               continue
+                       }
+                       if rx.Cmp(&tx) != 0 {
+                               t.Errorf("XML encoding of %s failed: got %s want %s", &tx, &rx, &tx)
+                       }
+               }
+       }
+}
+
 func TestIssue2379(t *testing.T) {
        // 1) no aliasing
        q := NewRat(3, 2)
index 4bc4649317a8b7d3cfee03e9aaa7c6b1d70561a1..6e2388bafef3363d4d78285503339c0e646ccbed 100644 (file)
@@ -9,12 +9,13 @@ import (
        "io"
        "os"
        "regexp"
+       "strings"
        "testing"
 )
 
 func TestReadForm(t *testing.T) {
        testBody := regexp.MustCompile("\n").ReplaceAllString(message, "\r\n")
-       b := bytes.NewBufferString(testBody)
+       b := strings.NewReader(testBody)
        r := NewReader(b, boundary)
        f, err := r.ReadForm(25)
        if err != nil {
index 713e301cdf27d2a35a7a603f207f861682cd44c4..d949ba3f3e5ece6473337cdb51935a7bb32d39c6 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin dragonfly freebsd linux netbsd openbsd
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package mime
 
index 98bd69549935e3d78593703255ed3faeb729d784..7250dcb85ad766d9f8897d776041640bfe6bdb76 100644 (file)
@@ -53,7 +53,9 @@ func TestConnAndListener(t *testing.T) {
                                os.Remove(addr)
                        }
                }(ln, tt.net, addr)
-               ln.Addr()
+               if ln.Addr().Network() != tt.net {
+                       t.Fatalf("got %v; expected %v", ln.Addr().Network(), tt.net)
+               }
 
                done := make(chan int)
                go transponder(t, ln, done)
@@ -63,8 +65,9 @@ func TestConnAndListener(t *testing.T) {
                        t.Fatalf("Dial failed: %v", err)
                }
                defer c.Close()
-               c.LocalAddr()
-               c.RemoteAddr()
+               if c.LocalAddr().Network() != tt.net || c.LocalAddr().Network() != tt.net {
+                       t.Fatalf("got %v->%v; expected %v->%v", c.LocalAddr().Network(), c.RemoteAddr().Network(), tt.net, tt.net)
+               }
                c.SetDeadline(time.Now().Add(someTimeout))
                c.SetReadDeadline(time.Now().Add(someTimeout))
                c.SetWriteDeadline(time.Now().Add(someTimeout))
@@ -96,8 +99,11 @@ func transponder(t *testing.T, ln Listener, done chan<- int) {
                return
        }
        defer c.Close()
-       c.LocalAddr()
-       c.RemoteAddr()
+       network := ln.Addr().Network()
+       if c.LocalAddr().Network() != network || c.LocalAddr().Network() != network {
+               t.Errorf("got %v->%v; expected %v->%v", c.LocalAddr().Network(), c.RemoteAddr().Network(), network, network)
+               return
+       }
        c.SetDeadline(time.Now().Add(someTimeout))
        c.SetReadDeadline(time.Now().Add(someTimeout))
        c.SetWriteDeadline(time.Now().Add(someTimeout))
index 973e69dea5d5b6454b0b9057c827ff8a0a246a48..08a0567ca762321096073f5878197b7eec3f9bf4 100644 (file)
@@ -58,7 +58,7 @@ func TestDialTimeout(t *testing.T) {
                                errc <- err
                        }()
                }
-       case "darwin", "windows":
+       case "darwin", "plan9", "windows":
                // At least OS X 10.7 seems to accept any number of
                // connections, ignoring listen's backlog, so resort
                // to connecting to a hopefully-dead 127/8 address.
index 79d150f8aad0a1281c10c206eb83539d8b697379..df5895afa74f35cc20d6e4e85c25b73a18587a58 100644 (file)
@@ -104,7 +104,7 @@ var googleaddrsipv4 = []string{
        "[::ffff:%02x%02x:%02x%02x]:80",
        "[0:0:0:0:0000:ffff:%d.%d.%d.%d]:80",
        "[0:0:0:0:000000:ffff:%d.%d.%d.%d]:80",
-       "[0:0:0:0:0:ffff::%d.%d.%d.%d]:80",
+       "[0:0:0:0::ffff:%d.%d.%d.%d]:80",
 }
 
 func TestDialGoogleIPv4(t *testing.T) {
index acc8294021716f9742f1576a20ce96851c209bcb..4309a87c3a4a69e397286b453bc0e1830b9163f0 100644 (file)
@@ -13,12 +13,23 @@ import (
 
 // Network file descritor.
 type netFD struct {
-       proto, name, dir string
-       ctl, data        *os.File
-       laddr, raddr     Addr
+       // locking/lifetime of sysfd + serialize access to Read and Write methods
+       fdmu fdMutex
+
+       // immutable until Close
+       proto        string
+       n            string
+       dir          string
+       ctl, data    *os.File
+       laddr, raddr Addr
 }
 
+var (
+       netdir string // default network
+)
+
 func sysInit() {
+       netdir = "/net"
 }
 
 func dial(net string, ra Addr, dialer func(time.Time) (Conn, error), deadline time.Time) (Conn, error) {
@@ -27,16 +38,99 @@ func dial(net string, ra Addr, dialer func(time.Time) (Conn, error), deadline ti
        return dialChannel(net, ra, dialer, deadline)
 }
 
-func newFD(proto, name string, ctl, data *os.File, laddr, raddr Addr) *netFD {
-       return &netFD{proto, name, "/net/" + proto + "/" + name, ctl, data, laddr, raddr}
+func newFD(proto, name string, ctl, data *os.File, laddr, raddr Addr) (*netFD, error) {
+       return &netFD{proto: proto, n: name, dir: netdir + "/" + proto + "/" + name, ctl: ctl, data: data, laddr: laddr, raddr: raddr}, nil
+}
+
+func (fd *netFD) init() error {
+       // stub for future fd.pd.Init(fd)
+       return nil
+}
+
+func (fd *netFD) name() string {
+       var ls, rs string
+       if fd.laddr != nil {
+               ls = fd.laddr.String()
+       }
+       if fd.raddr != nil {
+               rs = fd.raddr.String()
+       }
+       return fd.proto + ":" + ls + "->" + rs
 }
 
 func (fd *netFD) ok() bool { return fd != nil && fd.ctl != nil }
 
+func (fd *netFD) destroy() {
+       if !fd.ok() {
+               return
+       }
+       err := fd.ctl.Close()
+       if fd.data != nil {
+               if err1 := fd.data.Close(); err1 != nil && err == nil {
+                       err = err1
+               }
+       }
+       fd.ctl = nil
+       fd.data = nil
+}
+
+// Add a reference to this fd.
+// Returns an error if the fd cannot be used.
+func (fd *netFD) incref() error {
+       if !fd.fdmu.Incref() {
+               return errClosing
+       }
+       return nil
+}
+
+// Remove a reference to this FD and close if we've been asked to do so
+// (and there are no references left).
+func (fd *netFD) decref() {
+       if fd.fdmu.Decref() {
+               fd.destroy()
+       }
+}
+
+// Add a reference to this fd and lock for reading.
+// Returns an error if the fd cannot be used.
+func (fd *netFD) readLock() error {
+       if !fd.fdmu.RWLock(true) {
+               return errClosing
+       }
+       return nil
+}
+
+// Unlock for reading and remove a reference to this FD.
+func (fd *netFD) readUnlock() {
+       if fd.fdmu.RWUnlock(true) {
+               fd.destroy()
+       }
+}
+
+// Add a reference to this fd and lock for writing.
+// Returns an error if the fd cannot be used.
+func (fd *netFD) writeLock() error {
+       if !fd.fdmu.RWLock(false) {
+               return errClosing
+       }
+       return nil
+}
+
+// Unlock for writing and remove a reference to this FD.
+func (fd *netFD) writeUnlock() {
+       if fd.fdmu.RWUnlock(false) {
+               fd.destroy()
+       }
+}
+
 func (fd *netFD) Read(b []byte) (n int, err error) {
        if !fd.ok() || fd.data == nil {
                return 0, syscall.EINVAL
        }
+       if err := fd.readLock(); err != nil {
+               return 0, err
+       }
+       defer fd.readUnlock()
        n, err = fd.data.Read(b)
        if fd.proto == "udp" && err == io.EOF {
                n = 0
@@ -49,6 +143,10 @@ func (fd *netFD) Write(b []byte) (n int, err error) {
        if !fd.ok() || fd.data == nil {
                return 0, syscall.EINVAL
        }
+       if err := fd.writeLock(); err != nil {
+               return 0, err
+       }
+       defer fd.writeUnlock()
        return fd.data.Write(b)
 }
 
@@ -67,6 +165,9 @@ func (fd *netFD) CloseWrite() error {
 }
 
 func (fd *netFD) Close() error {
+       if !fd.fdmu.IncrefAndClose() {
+               return errClosing
+       }
        if !fd.ok() {
                return syscall.EINVAL
        }
index 64d56c73e06c4316fb0c9fcc143257120db03775..0f8d6de5b547b3b0f544fd01a99ecd1a5ab633cb 100644 (file)
@@ -119,7 +119,7 @@ func (o *operation) InitBuf(buf []byte) {
        o.buf.Len = uint32(len(buf))
        o.buf.Buf = nil
        if len(buf) != 0 {
-               o.buf.Buf = (*byte)(unsafe.Pointer(&buf[0]))
+               o.buf.Buf = &buf[0]
        }
 }
 
@@ -513,12 +513,7 @@ func (fd *netFD) WriteTo(buf []byte, sa syscall.Sockaddr) (int, error) {
        })
 }
 
-func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (*netFD, error) {
-       if err := fd.readLock(); err != nil {
-               return nil, err
-       }
-       defer fd.readUnlock()
-
+func (fd *netFD) acceptOne(toAddr func(syscall.Sockaddr) Addr, rawsa []syscall.RawSockaddrAny, o *operation) (*netFD, error) {
        // Get new socket.
        s, err := sysSocket(fd.family, fd.sotype, 0)
        if err != nil {
@@ -537,9 +532,7 @@ func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (*netFD, error) {
        }
 
        // Submit accept request.
-       o := &fd.rop
        o.handle = s
-       var rawsa [2]syscall.RawSockaddrAny
        o.rsan = int32(unsafe.Sizeof(rawsa[0]))
        _, err = rsrv.ExecIO(o, "AcceptEx", func(o *operation) error {
                return syscall.AcceptEx(o.fd.sysfd, o.handle, (*byte)(unsafe.Pointer(&rawsa[0])), 0, uint32(o.rsan), uint32(o.rsan), &o.qty, &o.o)
@@ -556,6 +549,45 @@ func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (*netFD, error) {
                return nil, &OpError{"Setsockopt", fd.net, fd.laddr, err}
        }
 
+       return netfd, nil
+}
+
+func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (*netFD, error) {
+       if err := fd.readLock(); err != nil {
+               return nil, err
+       }
+       defer fd.readUnlock()
+
+       o := &fd.rop
+       var netfd *netFD
+       var err error
+       var rawsa [2]syscall.RawSockaddrAny
+       for {
+               netfd, err = fd.acceptOne(toAddr, rawsa[:], o)
+               if err == nil {
+                       break
+               }
+               // Sometimes we see WSAECONNRESET and ERROR_NETNAME_DELETED is
+               // returned here. These happen if connection reset is received
+               // before AcceptEx could complete. These errors relate to new
+               // connection, not to AcceptEx, so ignore broken connection and
+               // try AcceptEx again for more connections.
+               operr, ok := err.(*OpError)
+               if !ok {
+                       return nil, err
+               }
+               errno, ok := operr.Err.(syscall.Errno)
+               if !ok {
+                       return nil, err
+               }
+               switch errno {
+               case syscall.ERROR_NETNAME_DELETED, syscall.WSAECONNRESET:
+                       // ignore these and try again
+               default:
+                       return nil, err
+               }
+       }
+
        // Get local and peer addr out of AcceptEx buffer.
        var lrsa, rrsa *syscall.RawSockaddrAny
        var llen, rlen int32
index f6ee1c29e0f2a90a7a22695836a423fb4f03debb..068f0881dd36dd3f7740d7f24960167a0f16df39 100644 (file)
@@ -43,7 +43,7 @@ func newFileFD(f *os.File) (net *netFD, err error) {
        }
        comp := splitAtBytes(path, "/")
        n := len(comp)
-       if n < 3 || comp[0] != "net" {
+       if n < 3 || comp[0][0:3] != "net" {
                return nil, syscall.EPLAN9
        }
 
@@ -58,7 +58,7 @@ func newFileFD(f *os.File) (net *netFD, err error) {
                }
                defer close(fd)
 
-               dir := "/net/" + comp[n-2]
+               dir := netdir + "/" + comp[n-2]
                ctl = os.NewFile(uintptr(fd), dir+"/"+file)
                ctl.Seek(0, 0)
                var buf [16]byte
@@ -71,19 +71,19 @@ func newFileFD(f *os.File) (net *netFD, err error) {
                if len(comp) < 4 {
                        return nil, errors.New("could not find control file for connection")
                }
-               dir := "/net/" + comp[1] + "/" + name
+               dir := netdir + "/" + comp[1] + "/" + name
                ctl, err = os.OpenFile(dir+"/ctl", os.O_RDWR, 0)
                if err != nil {
                        return nil, err
                }
                defer close(int(ctl.Fd()))
        }
-       dir := "/net/" + comp[1] + "/" + name
+       dir := netdir + "/" + comp[1] + "/" + name
        laddr, err := readPlan9Addr(comp[1], dir+"/local")
        if err != nil {
                return nil, err
        }
-       return newFD(comp[1], name, ctl, nil, laddr, nil), nil
+       return newFD(comp[1], name, ctl, nil, laddr, nil)
 }
 
 func newFileConn(f *os.File) (c Conn, err error) {
index acaf18851021efd7ad7c32c9d3960c44cdef0eb8..e4615b74fc376de976fe9d9e0e95e8348ac5cfb1 100644 (file)
@@ -174,6 +174,8 @@ var filePacketConnTests = []struct {
 
        {net: "udp6", addr: "[::1]", ipv6: true},
 
+       {net: "ip4:icmp", addr: "127.0.0.1"},
+
        {net: "unixgram", addr: "@gotest3/net", linux: true},
 }
 
@@ -187,6 +189,10 @@ func TestFilePacketConn(t *testing.T) {
                if skipServerTest(tt.net, "unixgram", tt.addr, tt.ipv6, false, tt.linux) {
                        continue
                }
+               if os.Getuid() != 0 && tt.net == "ip4:icmp" {
+                       t.Log("skipping test; must be root")
+                       continue
+               }
                testFilePacketConnListen(t, tt.net, tt.addr)
                switch tt.addr {
                case "", "0.0.0.0", "[::ffff:0.0.0.0]", "[::]":
index 8fe1b0eb035f5b18d9330504c3c8bce76df32279..38ae47f7847d1d3088b8e0d56495f8b0732f079e 100644 (file)
@@ -129,6 +129,8 @@ func FilePacketConn(f *os.File) (c PacketConn, err error) {
        switch fd.laddr.(type) {
        case *UDPAddr:
                return newUDPConn(fd), nil
+       case *IPAddr:
+               return newIPConn(fd), nil
        case *UnixAddr:
                return newUnixConn(fd), nil
        }
index 91db017245656824884e4c4eb294913026d80094..749f29d326930929939dc2afe4fd33fa5560b696 100644 (file)
@@ -4,13 +4,14 @@
 
 // The wire protocol for HTTP's "chunked" Transfer-Encoding.
 
-// This code is duplicated in httputil/chunked.go.
+// This code is duplicated in net/http and net/http/httputil.
 // Please make any changes in both files.
 
 package http
 
 import (
        "bufio"
+       "bytes"
        "errors"
        "fmt"
        "io"
@@ -57,26 +58,45 @@ func (cr *chunkedReader) beginChunk() {
        }
 }
 
-func (cr *chunkedReader) Read(b []uint8) (n int, err error) {
-       if cr.err != nil {
-               return 0, cr.err
+func (cr *chunkedReader) chunkHeaderAvailable() bool {
+       n := cr.r.Buffered()
+       if n > 0 {
+               peek, _ := cr.r.Peek(n)
+               return bytes.IndexByte(peek, '\n') >= 0
        }
-       if cr.n == 0 {
-               cr.beginChunk()
-               if cr.err != nil {
-                       return 0, cr.err
+       return false
+}
+
+func (cr *chunkedReader) Read(b []uint8) (n int, err error) {
+       for cr.err == nil {
+               if cr.n == 0 {
+                       if n > 0 && !cr.chunkHeaderAvailable() {
+                               // We've read enough. Don't potentially block
+                               // reading a new chunk header.
+                               break
+                       }
+                       cr.beginChunk()
+                       continue
                }
-       }
-       if uint64(len(b)) > cr.n {
-               b = b[0:cr.n]
-       }
-       n, cr.err = cr.r.Read(b)
-       cr.n -= uint64(n)
-       if cr.n == 0 && cr.err == nil {
-               // end of chunk (CRLF)
-               if _, cr.err = io.ReadFull(cr.r, cr.buf[:]); cr.err == nil {
-                       if cr.buf[0] != '\r' || cr.buf[1] != '\n' {
-                               cr.err = errors.New("malformed chunked encoding")
+               if len(b) == 0 {
+                       break
+               }
+               rbuf := b
+               if uint64(len(rbuf)) > cr.n {
+                       rbuf = rbuf[:cr.n]
+               }
+               var n0 int
+               n0, cr.err = cr.r.Read(rbuf)
+               n += n0
+               b = b[n0:]
+               cr.n -= uint64(n0)
+               // If we're at the end of a chunk, read the next two
+               // bytes to verify they are "\r\n".
+               if cr.n == 0 && cr.err == nil {
+                       if _, cr.err = io.ReadFull(cr.r, cr.buf[:2]); cr.err == nil {
+                               if cr.buf[0] != '\r' || cr.buf[1] != '\n' {
+                                       cr.err = errors.New("malformed chunked encoding")
+                               }
                        }
                }
        }
index 0b18c7b55ec23da26dee90affa869da71449dbae..34544790aff42e5704c6f543028877ca2cf748a7 100644 (file)
@@ -2,17 +2,18 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// This code is duplicated in httputil/chunked_test.go.
+// This code is duplicated in net/http and net/http/httputil.
 // Please make any changes in both files.
 
 package http
 
 import (
+       "bufio"
        "bytes"
        "fmt"
        "io"
        "io/ioutil"
-       "runtime"
+       "strings"
        "testing"
 )
 
@@ -41,9 +42,77 @@ func TestChunk(t *testing.T) {
        }
 }
 
+func TestChunkReadMultiple(t *testing.T) {
+       // Bunch of small chunks, all read together.
+       {
+               var b bytes.Buffer
+               w := newChunkedWriter(&b)
+               w.Write([]byte("foo"))
+               w.Write([]byte("bar"))
+               w.Close()
+
+               r := newChunkedReader(&b)
+               buf := make([]byte, 10)
+               n, err := r.Read(buf)
+               if n != 6 || err != io.EOF {
+                       t.Errorf("Read = %d, %v; want 6, EOF", n, err)
+               }
+               buf = buf[:n]
+               if string(buf) != "foobar" {
+                       t.Errorf("Read = %q; want %q", buf, "foobar")
+               }
+       }
+
+       // One big chunk followed by a little chunk, but the small bufio.Reader size
+       // should prevent the second chunk header from being read.
+       {
+               var b bytes.Buffer
+               w := newChunkedWriter(&b)
+               // fillBufChunk is 11 bytes + 3 bytes header + 2 bytes footer = 16 bytes,
+               // the same as the bufio ReaderSize below (the minimum), so even
+               // though we're going to try to Read with a buffer larger enough to also
+               // receive "foo", the second chunk header won't be read yet.
+               const fillBufChunk = "0123456789a"
+               const shortChunk = "foo"
+               w.Write([]byte(fillBufChunk))
+               w.Write([]byte(shortChunk))
+               w.Close()
+
+               r := newChunkedReader(bufio.NewReaderSize(&b, 16))
+               buf := make([]byte, len(fillBufChunk)+len(shortChunk))
+               n, err := r.Read(buf)
+               if n != len(fillBufChunk) || err != nil {
+                       t.Errorf("Read = %d, %v; want %d, nil", n, err, len(fillBufChunk))
+               }
+               buf = buf[:n]
+               if string(buf) != fillBufChunk {
+                       t.Errorf("Read = %q; want %q", buf, fillBufChunk)
+               }
+
+               n, err = r.Read(buf)
+               if n != len(shortChunk) || err != io.EOF {
+                       t.Errorf("Read = %d, %v; want %d, EOF", n, err, len(shortChunk))
+               }
+       }
+
+       // And test that we see an EOF chunk, even though our buffer is already full:
+       {
+               r := newChunkedReader(bufio.NewReader(strings.NewReader("3\r\nfoo\r\n0\r\n")))
+               buf := make([]byte, 3)
+               n, err := r.Read(buf)
+               if n != 3 || err != io.EOF {
+                       t.Errorf("Read = %d, %v; want 3, EOF", n, err)
+               }
+               if string(buf) != "foo" {
+                       t.Errorf("buf = %q; want foo", buf)
+               }
+       }
+}
+
 func TestChunkReaderAllocs(t *testing.T) {
-       // temporarily set GOMAXPROCS to 1 as we are testing memory allocations
-       defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(1))
+       if testing.Short() {
+               t.Skip("skipping in short mode")
+       }
        var buf bytes.Buffer
        w := newChunkedWriter(&buf)
        a, b, c := []byte("aaaaaa"), []byte("bbbbbbbbbbbb"), []byte("cccccccccccccccccccccccc")
@@ -52,26 +121,23 @@ func TestChunkReaderAllocs(t *testing.T) {
        w.Write(c)
        w.Close()
 
-       r := newChunkedReader(&buf)
        readBuf := make([]byte, len(a)+len(b)+len(c)+1)
-
-       var ms runtime.MemStats
-       runtime.ReadMemStats(&ms)
-       m0 := ms.Mallocs
-
-       n, err := io.ReadFull(r, readBuf)
-
-       runtime.ReadMemStats(&ms)
-       mallocs := ms.Mallocs - m0
-       if mallocs > 1 {
-               t.Errorf("%d mallocs; want <= 1", mallocs)
-       }
-
-       if n != len(readBuf)-1 {
-               t.Errorf("read %d bytes; want %d", n, len(readBuf)-1)
-       }
-       if err != io.ErrUnexpectedEOF {
-               t.Errorf("read error = %v; want ErrUnexpectedEOF", err)
+       byter := bytes.NewReader(buf.Bytes())
+       bufr := bufio.NewReader(byter)
+       mallocs := testing.AllocsPerRun(100, func() {
+               byter.Seek(0, 0)
+               bufr.Reset(byter)
+               r := newChunkedReader(bufr)
+               n, err := io.ReadFull(r, readBuf)
+               if n != len(readBuf)-1 {
+                       t.Fatalf("read %d bytes; want %d", n, len(readBuf)-1)
+               }
+               if err != io.ErrUnexpectedEOF {
+                       t.Fatalf("read error = %v; want ErrUnexpectedEOF", err)
+               }
+       })
+       if mallocs > 1.5 {
+               t.Errorf("mallocs = %v; want 1", mallocs)
        }
 }
 
index 82f18a178487cc89f5a977cf68ac736aa0a619d2..389ab58e4182f5d84c5d0fae15d974748e9cf4ee 100644 (file)
@@ -34,9 +34,9 @@ import (
 type PublicSuffixList interface {
        // PublicSuffix returns the public suffix of domain.
        //
-       // Domain is a lowercase punycoded domain name (not an IP address)
-       // without leading or trailing dots. The returned value is in the
-       // same form.
+       // TODO: specify which of the caller and callee is responsible for IP
+       // addresses, for leading and trailing dots, for case sensitivity, and
+       // for IDN/Punycode.
        PublicSuffix(domain string) string
 
        // String returns a description of the source of this public suffix
index 22b7f279689bccdb78e1aa3233ae4b366a84d50e..8074df5bbde17f3ffad29dd1f1fe51be3c772d18 100644 (file)
@@ -32,7 +32,7 @@ func (t *Transport) IdleConnKeysForTesting() (keys []string) {
                return
        }
        for key := range t.idleConn {
-               keys = append(keys, key)
+               keys = append(keys, key.String())
        }
        return
 }
@@ -43,11 +43,12 @@ func (t *Transport) IdleConnCountForTesting(cacheKey string) int {
        if t.idleConn == nil {
                return 0
        }
-       conns, ok := t.idleConn[cacheKey]
-       if !ok {
-               return 0
+       for k, conns := range t.idleConn {
+               if k.String() == cacheKey {
+                       return len(conns)
+               }
        }
-       return len(conns)
+       return 0
 }
 
 func (t *Transport) IdleConnChMapSizeForTesting() int {
@@ -63,4 +64,9 @@ func NewTestTimeoutHandler(handler Handler, ch <-chan time.Time) Handler {
        return &timeoutHandler{handler, f, ""}
 }
 
+func ResetCachedEnvironment() {
+       httpProxyEnv.reset()
+       noProxyEnv.reset()
+}
+
 var DefaultUserAgent = defaultUserAgent
index 8b32ca1d0eaf4652d4bbf649657a793124458c68..9df5cc481897d98ac628b23252bcee0c0a910510 100644 (file)
@@ -13,6 +13,7 @@ import (
        "mime"
        "mime/multipart"
        "net/textproto"
+       "net/url"
        "os"
        "path"
        "path/filepath"
@@ -52,12 +53,14 @@ type FileSystem interface {
 
 // A File is returned by a FileSystem's Open method and can be
 // served by the FileServer implementation.
+//
+// The methods should behave the same as those on an *os.File.
 type File interface {
-       Close() error
-       Stat() (os.FileInfo, error)
+       io.Closer
+       io.Reader
        Readdir(count int) ([]os.FileInfo, error)
-       Read([]byte) (int, error)
        Seek(offset int64, whence int) (int64, error)
+       Stat() (os.FileInfo, error)
 }
 
 func dirList(w ResponseWriter, f File) {
@@ -73,8 +76,11 @@ func dirList(w ResponseWriter, f File) {
                        if d.IsDir() {
                                name += "/"
                        }
-                       // TODO htmlescape
-                       fmt.Fprintf(w, "<a href=\"%s\">%s</a>\n", name, name)
+                       // name may contain '?' or '#', which must be escaped to remain
+                       // part of the URL path, and not indicate the start of a query
+                       // string or fragment.
+                       url := url.URL{Path: name}
+                       fmt.Fprintf(w, "<a href=\"%s\">%s</a>\n", url.String(), htmlReplacer.Replace(name))
                }
        }
        fmt.Fprintf(w, "</pre>\n")
index dd3e9fefeace860f13fd58f0b24fe4be3969202b..c9a77c9f6aaf2187e0c2d4f0a9550ecff9cbc3a8 100644 (file)
@@ -227,6 +227,54 @@ func TestFileServerCleans(t *testing.T) {
        }
 }
 
+func TestFileServerEscapesNames(t *testing.T) {
+       defer afterTest(t)
+       const dirListPrefix = "<pre>\n"
+       const dirListSuffix = "\n</pre>\n"
+       tests := []struct {
+               name, escaped string
+       }{
+               {`simple_name`, `<a href="simple_name">simple_name</a>`},
+               {`"'<>&`, `<a href="%22%27%3C%3E&">&#34;&#39;&lt;&gt;&amp;</a>`},
+               {`?foo=bar#baz`, `<a href="%3Ffoo=bar%23baz">?foo=bar#baz</a>`},
+               {`<combo>?foo`, `<a href="%3Ccombo%3E%3Ffoo">&lt;combo&gt;?foo</a>`},
+       }
+
+       // We put each test file in its own directory in the fakeFS so we can look at it in isolation.
+       fs := make(fakeFS)
+       for i, test := range tests {
+               testFile := &fakeFileInfo{basename: test.name}
+               fs[fmt.Sprintf("/%d", i)] = &fakeFileInfo{
+                       dir:     true,
+                       modtime: time.Unix(1000000000, 0).UTC(),
+                       ents:    []*fakeFileInfo{testFile},
+               }
+               fs[fmt.Sprintf("/%d/%s", i, test.name)] = testFile
+       }
+
+       ts := httptest.NewServer(FileServer(&fs))
+       defer ts.Close()
+       for i, test := range tests {
+               url := fmt.Sprintf("%s/%d", ts.URL, i)
+               res, err := Get(url)
+               if err != nil {
+                       t.Fatalf("test %q: Get: %v", test.name, err)
+               }
+               b, err := ioutil.ReadAll(res.Body)
+               if err != nil {
+                       t.Fatalf("test %q: read Body: %v", test.name, err)
+               }
+               s := string(b)
+               if !strings.HasPrefix(s, dirListPrefix) || !strings.HasSuffix(s, dirListSuffix) {
+                       t.Errorf("test %q: listing dir, full output is %q, want prefix %q and suffix %q", test.name, s, dirListPrefix, dirListSuffix)
+               }
+               if trimmed := strings.TrimSuffix(strings.TrimPrefix(s, dirListPrefix), dirListSuffix); trimmed != test.escaped {
+                       t.Errorf("test %q: listing dir, filename escaped to %q, want %q", test.name, trimmed, test.escaped)
+               }
+               res.Body.Close()
+       }
+}
+
 func mustRemoveAll(dir string) {
        err := os.RemoveAll(dir)
        if err != nil {
@@ -457,8 +505,9 @@ func (f *fakeFileInfo) Mode() os.FileMode {
 
 type fakeFile struct {
        io.ReadSeeker
-       fi   *fakeFileInfo
-       path string // as opened
+       fi     *fakeFileInfo
+       path   string // as opened
+       entpos int
 }
 
 func (f *fakeFile) Close() error               { return nil }
@@ -468,10 +517,20 @@ func (f *fakeFile) Readdir(count int) ([]os.FileInfo, error) {
                return nil, os.ErrInvalid
        }
        var fis []os.FileInfo
-       for _, fi := range f.fi.ents {
-               fis = append(fis, fi)
+
+       limit := f.entpos + count
+       if count <= 0 || limit > len(f.fi.ents) {
+               limit = len(f.fi.ents)
+       }
+       for ; f.entpos < limit; f.entpos++ {
+               fis = append(fis, f.fi.ents[f.entpos])
+       }
+
+       if len(fis) == 0 && count > 0 {
+               return fis, io.EOF
+       } else {
+               return fis, nil
        }
-       return fis, nil
 }
 
 type fakeFS map[string]*fakeFileInfo
@@ -480,7 +539,6 @@ func (fs fakeFS) Open(name string) (File, error) {
        name = path.Clean(name)
        f, ok := fs[name]
        if !ok {
-               println("fake filesystem didn't find file", name)
                return nil, os.ErrNotExist
        }
        return &fakeFile{ReadSeeker: strings.NewReader(f.contents), fi: f, path: name}, nil
index b66d4095153f91fe18343317ee92f20ead9ff849..9632bfd19d5286d181fba0187495c37af68f0469 100644 (file)
@@ -4,15 +4,14 @@
 
 // The wire protocol for HTTP's "chunked" Transfer-Encoding.
 
-// This code is a duplicate of ../chunked.go with these edits:
-//     s/newChunked/NewChunked/g
-//     s/package http/package httputil/
+// This code is duplicated in net/http and net/http/httputil.
 // Please make any changes in both files.
 
 package httputil
 
 import (
        "bufio"
+       "bytes"
        "errors"
        "fmt"
        "io"
@@ -22,13 +21,13 @@ const maxLineLength = 4096 // assumed <= bufio.defaultBufSize
 
 var ErrLineTooLong = errors.New("header line too long")
 
-// NewChunkedReader returns a new chunkedReader that translates the data read from r
+// newChunkedReader returns a new chunkedReader that translates the data read from r
 // out of HTTP "chunked" format before returning it.
 // The chunkedReader returns io.EOF when the final 0-length chunk is read.
 //
-// NewChunkedReader is not needed by normal applications. The http package
+// newChunkedReader is not needed by normal applications. The http package
 // automatically decodes chunking when reading response bodies.
-func NewChunkedReader(r io.Reader) io.Reader {
+func newChunkedReader(r io.Reader) io.Reader {
        br, ok := r.(*bufio.Reader)
        if !ok {
                br = bufio.NewReader(r)
@@ -59,26 +58,45 @@ func (cr *chunkedReader) beginChunk() {
        }
 }
 
-func (cr *chunkedReader) Read(b []uint8) (n int, err error) {
-       if cr.err != nil {
-               return 0, cr.err
+func (cr *chunkedReader) chunkHeaderAvailable() bool {
+       n := cr.r.Buffered()
+       if n > 0 {
+               peek, _ := cr.r.Peek(n)
+               return bytes.IndexByte(peek, '\n') >= 0
        }
-       if cr.n == 0 {
-               cr.beginChunk()
-               if cr.err != nil {
-                       return 0, cr.err
+       return false
+}
+
+func (cr *chunkedReader) Read(b []uint8) (n int, err error) {
+       for cr.err == nil {
+               if cr.n == 0 {
+                       if n > 0 && !cr.chunkHeaderAvailable() {
+                               // We've read enough. Don't potentially block
+                               // reading a new chunk header.
+                               break
+                       }
+                       cr.beginChunk()
+                       continue
                }
-       }
-       if uint64(len(b)) > cr.n {
-               b = b[0:cr.n]
-       }
-       n, cr.err = cr.r.Read(b)
-       cr.n -= uint64(n)
-       if cr.n == 0 && cr.err == nil {
-               // end of chunk (CRLF)
-               if _, cr.err = io.ReadFull(cr.r, cr.buf[:]); cr.err == nil {
-                       if cr.buf[0] != '\r' || cr.buf[1] != '\n' {
-                               cr.err = errors.New("malformed chunked encoding")
+               if len(b) == 0 {
+                       break
+               }
+               rbuf := b
+               if uint64(len(rbuf)) > cr.n {
+                       rbuf = rbuf[:cr.n]
+               }
+               var n0 int
+               n0, cr.err = cr.r.Read(rbuf)
+               n += n0
+               b = b[n0:]
+               cr.n -= uint64(n0)
+               // If we're at the end of a chunk, read the next two
+               // bytes to verify they are "\r\n".
+               if cr.n == 0 && cr.err == nil {
+                       if _, cr.err = io.ReadFull(cr.r, cr.buf[:2]); cr.err == nil {
+                               if cr.buf[0] != '\r' || cr.buf[1] != '\n' {
+                                       cr.err = errors.New("malformed chunked encoding")
+                               }
                        }
                }
        }
@@ -117,16 +135,16 @@ func isASCIISpace(b byte) bool {
        return b == ' ' || b == '\t' || b == '\n' || b == '\r'
 }
 
-// NewChunkedWriter returns a new chunkedWriter that translates writes into HTTP
+// newChunkedWriter returns a new chunkedWriter that translates writes into HTTP
 // "chunked" format before writing them to w. Closing the returned chunkedWriter
 // sends the final 0-length chunk that marks the end of the stream.
 //
-// NewChunkedWriter is not needed by normal applications. The http
+// newChunkedWriter is not needed by normal applications. The http
 // package adds chunking automatically if handlers don't set a
-// Content-Length header. Using NewChunkedWriter inside a handler
+// Content-Length header. Using newChunkedWriter inside a handler
 // would result in double chunking or chunking with a Content-Length
 // length, both of which are wrong.
-func NewChunkedWriter(w io.Writer) io.WriteCloser {
+func newChunkedWriter(w io.Writer) io.WriteCloser {
        return &chunkedWriter{w}
 }
 
index a06bffad5b30f7032cc7bd24a52ed537dbd40f29..a7a57746885e3dd45e8badd2d2f623922ea020f9 100644 (file)
@@ -2,26 +2,25 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// This code is a duplicate of ../chunked_test.go with these edits:
-//     s/newChunked/NewChunked/g
-//     s/package http/package httputil/
+// This code is duplicated in net/http and net/http/httputil.
 // Please make any changes in both files.
 
 package httputil
 
 import (
+       "bufio"
        "bytes"
        "fmt"
        "io"
        "io/ioutil"
-       "runtime"
+       "strings"
        "testing"
 )
 
 func TestChunk(t *testing.T) {
        var b bytes.Buffer
 
-       w := NewChunkedWriter(&b)
+       w := newChunkedWriter(&b)
        const chunk1 = "hello, "
        const chunk2 = "world! 0123456789abcdef"
        w.Write([]byte(chunk1))
@@ -32,7 +31,7 @@ func TestChunk(t *testing.T) {
                t.Fatalf("chunk writer wrote %q; want %q", g, e)
        }
 
-       r := NewChunkedReader(&b)
+       r := newChunkedReader(&b)
        data, err := ioutil.ReadAll(r)
        if err != nil {
                t.Logf(`data: "%s"`, data)
@@ -43,37 +42,102 @@ func TestChunk(t *testing.T) {
        }
 }
 
+func TestChunkReadMultiple(t *testing.T) {
+       // Bunch of small chunks, all read together.
+       {
+               var b bytes.Buffer
+               w := newChunkedWriter(&b)
+               w.Write([]byte("foo"))
+               w.Write([]byte("bar"))
+               w.Close()
+
+               r := newChunkedReader(&b)
+               buf := make([]byte, 10)
+               n, err := r.Read(buf)
+               if n != 6 || err != io.EOF {
+                       t.Errorf("Read = %d, %v; want 6, EOF", n, err)
+               }
+               buf = buf[:n]
+               if string(buf) != "foobar" {
+                       t.Errorf("Read = %q; want %q", buf, "foobar")
+               }
+       }
+
+       // One big chunk followed by a little chunk, but the small bufio.Reader size
+       // should prevent the second chunk header from being read.
+       {
+               var b bytes.Buffer
+               w := newChunkedWriter(&b)
+               // fillBufChunk is 11 bytes + 3 bytes header + 2 bytes footer = 16 bytes,
+               // the same as the bufio ReaderSize below (the minimum), so even
+               // though we're going to try to Read with a buffer larger enough to also
+               // receive "foo", the second chunk header won't be read yet.
+               const fillBufChunk = "0123456789a"
+               const shortChunk = "foo"
+               w.Write([]byte(fillBufChunk))
+               w.Write([]byte(shortChunk))
+               w.Close()
+
+               r := newChunkedReader(bufio.NewReaderSize(&b, 16))
+               buf := make([]byte, len(fillBufChunk)+len(shortChunk))
+               n, err := r.Read(buf)
+               if n != len(fillBufChunk) || err != nil {
+                       t.Errorf("Read = %d, %v; want %d, nil", n, err, len(fillBufChunk))
+               }
+               buf = buf[:n]
+               if string(buf) != fillBufChunk {
+                       t.Errorf("Read = %q; want %q", buf, fillBufChunk)
+               }
+
+               n, err = r.Read(buf)
+               if n != len(shortChunk) || err != io.EOF {
+                       t.Errorf("Read = %d, %v; want %d, EOF", n, err, len(shortChunk))
+               }
+       }
+
+       // And test that we see an EOF chunk, even though our buffer is already full:
+       {
+               r := newChunkedReader(bufio.NewReader(strings.NewReader("3\r\nfoo\r\n0\r\n")))
+               buf := make([]byte, 3)
+               n, err := r.Read(buf)
+               if n != 3 || err != io.EOF {
+                       t.Errorf("Read = %d, %v; want 3, EOF", n, err)
+               }
+               if string(buf) != "foo" {
+                       t.Errorf("buf = %q; want foo", buf)
+               }
+       }
+}
+
 func TestChunkReaderAllocs(t *testing.T) {
-       // temporarily set GOMAXPROCS to 1 as we are testing memory allocations
-       defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(1))
+       if testing.Short() {
+               t.Skip("skipping in short mode")
+       }
        var buf bytes.Buffer
-       w := NewChunkedWriter(&buf)
+       w := newChunkedWriter(&buf)
        a, b, c := []byte("aaaaaa"), []byte("bbbbbbbbbbbb"), []byte("cccccccccccccccccccccccc")
        w.Write(a)
        w.Write(b)
        w.Write(c)
        w.Close()
 
-       r := NewChunkedReader(&buf)
        readBuf := make([]byte, len(a)+len(b)+len(c)+1)
-
-       var ms runtime.MemStats
-       runtime.ReadMemStats(&ms)
-       m0 := ms.Mallocs
-
-       n, err := io.ReadFull(r, readBuf)
-
-       runtime.ReadMemStats(&ms)
-       mallocs := ms.Mallocs - m0
-       if mallocs > 1 {
-               t.Errorf("%d mallocs; want <= 1", mallocs)
-       }
-
-       if n != len(readBuf)-1 {
-               t.Errorf("read %d bytes; want %d", n, len(readBuf)-1)
-       }
-       if err != io.ErrUnexpectedEOF {
-               t.Errorf("read error = %v; want ErrUnexpectedEOF", err)
+       byter := bytes.NewReader(buf.Bytes())
+       bufr := bufio.NewReader(byter)
+       mallocs := testing.AllocsPerRun(100, func() {
+               byter.Seek(0, 0)
+               bufr.Reset(byter)
+               r := newChunkedReader(bufr)
+               n, err := io.ReadFull(r, readBuf)
+               if n != len(readBuf)-1 {
+                       t.Fatalf("read %d bytes; want %d", n, len(readBuf)-1)
+               }
+               if err != io.ErrUnexpectedEOF {
+                       t.Fatalf("read error = %v; want ErrUnexpectedEOF", err)
+               }
+       })
+       if mallocs > 1.5 {
+               t.Errorf("mallocs = %v; want 1", mallocs)
        }
 }
 
index 265499fb00d23a563ba17dca6010a9a6384182e6..ab1eab21bc63f44bcf50a30c74240aa35a4d9c58 100644 (file)
@@ -29,7 +29,7 @@ func drainBody(b io.ReadCloser) (r1, r2 io.ReadCloser, err error) {
        if err = b.Close(); err != nil {
                return nil, nil, err
        }
-       return ioutil.NopCloser(&buf), ioutil.NopCloser(bytes.NewBuffer(buf.Bytes())), nil
+       return ioutil.NopCloser(&buf), ioutil.NopCloser(bytes.NewReader(buf.Bytes())), nil
 }
 
 // dumpConn is a net.Conn which writes to Writer and reads from Reader
index 987a820487d9d4f6c7e85b30d561470b63b83391..a1dbfc39d6be446e802a00cf90ee28c535fd71ba 100644 (file)
@@ -119,7 +119,7 @@ func TestDumpRequest(t *testing.T) {
                        }
                        switch b := tt.Body.(type) {
                        case []byte:
-                               tt.Req.Body = ioutil.NopCloser(bytes.NewBuffer(b))
+                               tt.Req.Body = ioutil.NopCloser(bytes.NewReader(b))
                        case func() io.ReadCloser:
                                tt.Req.Body = b()
                        }
diff --git a/libgo/go/net/http/httputil/httputil.go b/libgo/go/net/http/httputil/httputil.go
new file mode 100644 (file)
index 0000000..74fb6c6
--- /dev/null
@@ -0,0 +1,32 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package httputil provides HTTP utility functions, complementing the
+// more common ones in the net/http package.
+package httputil
+
+import "io"
+
+// NewChunkedReader returns a new chunkedReader that translates the data read from r
+// out of HTTP "chunked" format before returning it.
+// The chunkedReader returns io.EOF when the final 0-length chunk is read.
+//
+// NewChunkedReader is not needed by normal applications. The http package
+// automatically decodes chunking when reading response bodies.
+func NewChunkedReader(r io.Reader) io.Reader {
+       return newChunkedReader(r)
+}
+
+// NewChunkedWriter returns a new chunkedWriter that translates writes into HTTP
+// "chunked" format before writing them to w. Closing the returned chunkedWriter
+// sends the final 0-length chunk that marks the end of the stream.
+//
+// NewChunkedWriter is not needed by normal applications. The http
+// package adds chunking automatically if handlers don't set a
+// Content-Length header. Using NewChunkedWriter inside a handler
+// would result in double chunking or chunking with a Content-Length
+// length, both of which are wrong.
+func NewChunkedWriter(w io.Writer) io.WriteCloser {
+       return newChunkedWriter(w)
+}
index 507938acac71cefe2adce14d011261e597e60e9c..86d23e03706e5ce7ba4b1ab4233835b75ebaa1f7 100644 (file)
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Package httputil provides HTTP utility functions, complementing the
-// more common ones in the net/http package.
 package httputil
 
 import (
index 1990f64dbd89253c653ab932e30144845d752fc9..48ada5f5fdbf1774a5895db8f2ecdecf33f974e9 100644 (file)
@@ -144,6 +144,10 @@ func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
        }
        defer res.Body.Close()
 
+       for _, h := range hopHeaders {
+               res.Header.Del(h)
+       }
+
        copyHeader(rw.Header(), res.Header)
 
        rw.WriteHeader(res.StatusCode)
index 1c0444ec486f2cffcdbe4104ac0362ee461e7159..e9539b44b6ee93c6437d33659bc389d3fddf6c38 100644 (file)
@@ -16,6 +16,12 @@ import (
        "time"
 )
 
+const fakeHopHeader = "X-Fake-Hop-Header-For-Test"
+
+func init() {
+       hopHeaders = append(hopHeaders, fakeHopHeader)
+}
+
 func TestReverseProxy(t *testing.T) {
        const backendResponse = "I am the backend"
        const backendStatus = 404
@@ -36,6 +42,10 @@ func TestReverseProxy(t *testing.T) {
                        t.Errorf("backend got Host header %q, want %q", g, e)
                }
                w.Header().Set("X-Foo", "bar")
+               w.Header().Set("Upgrade", "foo")
+               w.Header().Set(fakeHopHeader, "foo")
+               w.Header().Add("X-Multi-Value", "foo")
+               w.Header().Add("X-Multi-Value", "bar")
                http.SetCookie(w, &http.Cookie{Name: "flavor", Value: "chocolateChip"})
                w.WriteHeader(backendStatus)
                w.Write([]byte(backendResponse))
@@ -64,6 +74,12 @@ func TestReverseProxy(t *testing.T) {
        if g, e := res.Header.Get("X-Foo"), "bar"; g != e {
                t.Errorf("got X-Foo %q; expected %q", g, e)
        }
+       if c := res.Header.Get(fakeHopHeader); c != "" {
+               t.Errorf("got %s header value %q", fakeHopHeader, c)
+       }
+       if g, e := len(res.Header["X-Multi-Value"]), 2; g != e {
+               t.Errorf("got %d X-Multi-Value header values; expected %d", g, e)
+       }
        if g, e := len(res.Header["Set-Cookie"]), 1; g != e {
                t.Fatalf("got %d SetCookies, want %d", g, e)
        }
index 449ccaeea760a4cb7266028258f65b8ca725b18e..d0726f61f3bf3e64fa21839661a1a23354da724e 100644 (file)
@@ -71,8 +71,8 @@ func TestCacheKeys(t *testing.T) {
                        proxy = u
                }
                cm := connectMethod{proxy, tt.scheme, tt.addr}
-               if cm.String() != tt.key {
-                       t.Fatalf("{%q, %q, %q} cache key %q; want %q", tt.proxy, tt.scheme, tt.addr, cm.String(), tt.key)
+               if got := cm.key().String(); got != tt.key {
+                       t.Fatalf("{%q, %q, %q} cache key = %q; want %q", tt.proxy, tt.scheme, tt.addr, got, tt.key)
                }
        }
 }
index 0c1e16b8d5eb93de47f610777a55d0c4db638d5c..68d141398aab3e2420c22112489cec0af6a57999 100644 (file)
@@ -80,7 +80,7 @@ func TestParseFormUnknownContentType(t *testing.T) {
                req := &Request{
                        Method: "POST",
                        Header: Header(test.contentType),
-                       Body:   ioutil.NopCloser(bytes.NewBufferString("body")),
+                       Body:   ioutil.NopCloser(strings.NewReader("body")),
                }
                err := req.ParseForm()
                switch {
@@ -218,6 +218,7 @@ func TestMultipartReaderOrder(t *testing.T) {
        if err := req.ParseMultipartForm(25); err != nil {
                t.Fatalf("ParseMultipartForm: %v", err)
        }
+       defer req.MultipartForm.RemoveAll()
        if _, err := req.MultipartReader(); err == nil {
                t.Fatal("expected an error from MultipartReader after call to ParseMultipartForm")
        }
@@ -368,7 +369,7 @@ func testMissingFile(t *testing.T, req *Request) {
 }
 
 func newTestMultipartRequest(t *testing.T) *Request {
-       b := bytes.NewBufferString(strings.Replace(message, "\n", "\r\n", -1))
+       b := strings.NewReader(strings.Replace(message, "\n", "\r\n", -1))
        req, err := NewRequest("POST", "/", b)
        if err != nil {
                t.Fatal("NewRequest:", err)
index b27b1f7ce3b7d0915744231d62e4d2d5db32f5df..561eea28e5ab6059eabf34f088c84f9276688ce1 100644 (file)
@@ -427,7 +427,7 @@ func TestRequestWrite(t *testing.T) {
                        }
                        switch b := tt.Body.(type) {
                        case []byte:
-                               tt.Req.Body = ioutil.NopCloser(bytes.NewBuffer(b))
+                               tt.Req.Body = ioutil.NopCloser(bytes.NewReader(b))
                        case func() io.ReadCloser:
                                tt.Req.Body = b()
                        }
index 2ec1d408728c1a49f90bc59a2538b5aceff1c1a9..0b991c72ef0e462c781778051d7784cea40519fe 100644 (file)
@@ -141,6 +141,9 @@ func ReadResponse(r *bufio.Reader, req *Request) (*Response, error) {
        // Parse the response headers.
        mimeHeader, err := tp.ReadMIMEHeader()
        if err != nil {
+               if err == io.EOF {
+                       err = io.ErrUnexpectedEOF
+               }
                return nil, err
        }
        resp.Header = Header(mimeHeader)
index f73172189e94985fbd9c815be98024fb376ce506..d6e77b19c107d195a7dc0492550bd388bf804a46 100644 (file)
@@ -618,6 +618,15 @@ func TestResponseContentLengthShortBody(t *testing.T) {
        }
 }
 
+func TestReadResponseUnexpectedEOF(t *testing.T) {
+       br := bufio.NewReader(strings.NewReader("HTTP/1.1 301 Moved Permanently\r\n" +
+               "Location: http://example.com"))
+       _, err := ReadResponse(br, nil)
+       if err != io.ErrUnexpectedEOF {
+               t.Errorf("ReadResponse = %v; want io.ErrUnexpectedEOF", err)
+       }
+}
+
 func TestNeedsSniff(t *testing.T) {
        // needsSniff returns true with an empty response.
        r := &response{}
index 5c10e2161cfd6efa8681f42947aad9aa2bc84918..4799b4792b34cf410b8726f7cc9b7b04519a2e9b 100644 (file)
@@ -7,6 +7,7 @@ package http
 import (
        "bytes"
        "io/ioutil"
+       "strings"
        "testing"
 )
 
@@ -41,7 +42,7 @@ func TestResponseWrite(t *testing.T) {
                                ProtoMinor:    0,
                                Request:       dummyReq("GET"),
                                Header:        Header{},
-                               Body:          ioutil.NopCloser(bytes.NewBufferString("abcdef")),
+                               Body:          ioutil.NopCloser(strings.NewReader("abcdef")),
                                ContentLength: -1,
                        },
                        "HTTP/1.0 200 OK\r\n" +
@@ -56,7 +57,7 @@ func TestResponseWrite(t *testing.T) {
                                ProtoMinor:       1,
                                Request:          dummyReq("GET"),
                                Header:           Header{},
-                               Body:             ioutil.NopCloser(bytes.NewBufferString("abcdef")),
+                               Body:             ioutil.NopCloser(strings.NewReader("abcdef")),
                                ContentLength:    6,
                                TransferEncoding: []string{"chunked"},
                                Close:            true,
index 1dba1873ea5280499536453ed88d1ae1f7f2f796..e7a3e6ea75f90f6e7b4c29cd220b99ca9217fdc1 100644 (file)
@@ -419,7 +419,7 @@ func TestServeMuxHandlerRedirects(t *testing.T) {
 func TestMuxRedirectLeadingSlashes(t *testing.T) {
        paths := []string{"//foo.txt", "///foo.txt", "/../../foo.txt"}
        for _, path := range paths {
-               req, err := ReadRequest(bufio.NewReader(bytes.NewBufferString("GET " + path + " HTTP/1.1\r\nHost: test\r\n\r\n")))
+               req, err := ReadRequest(bufio.NewReader(strings.NewReader("GET " + path + " HTTP/1.1\r\nHost: test\r\n\r\n")))
                if err != nil {
                        t.Errorf("%s", err)
                }
@@ -441,6 +441,9 @@ func TestMuxRedirectLeadingSlashes(t *testing.T) {
 }
 
 func TestServerTimeouts(t *testing.T) {
+       if runtime.GOOS == "plan9" {
+               t.Skip("skipping test; see http://golang.org/issue/7237")
+       }
        defer afterTest(t)
        reqNum := 0
        ts := httptest.NewUnstartedServer(HandlerFunc(func(res ResponseWriter, req *Request) {
@@ -517,6 +520,9 @@ func TestServerTimeouts(t *testing.T) {
 // shouldn't cause a handler to block forever on reads (next HTTP
 // request) that will never happen.
 func TestOnlyWriteTimeout(t *testing.T) {
+       if runtime.GOOS == "plan9" {
+               t.Skip("skipping test; see http://golang.org/issue/7237")
+       }
        defer afterTest(t)
        var conn net.Conn
        var afterTimeoutErrc = make(chan error, 1)
@@ -840,6 +846,9 @@ func TestHeadResponses(t *testing.T) {
 }
 
 func TestTLSHandshakeTimeout(t *testing.T) {
+       if runtime.GOOS == "plan9" {
+               t.Skip("skipping test; see http://golang.org/issue/7237")
+       }
        defer afterTest(t)
        ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
        ts.Config.ReadTimeout = 250 * time.Millisecond
@@ -1414,6 +1423,9 @@ func TestRequestBodyLimit(t *testing.T) {
 // TestClientWriteShutdown tests that if the client shuts down the write
 // side of their TCP connection, the server doesn't send a 400 Bad Request.
 func TestClientWriteShutdown(t *testing.T) {
+       if runtime.GOOS == "plan9" {
+               t.Skip("skipping test; see http://golang.org/issue/7237")
+       }
        defer afterTest(t)
        ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
        defer ts.Close()
@@ -2062,30 +2074,35 @@ func TestServerReaderFromOrder(t *testing.T) {
        }
 }
 
-// Issue 6157
-func TestNoContentTypeOnNotModified(t *testing.T) {
-       ht := newHandlerTest(HandlerFunc(func(w ResponseWriter, r *Request) {
-               if r.URL.Path == "/header" {
-                       w.Header().Set("Content-Length", "123")
-               }
-               w.WriteHeader(StatusNotModified)
-               if r.URL.Path == "/more" {
-                       w.Write([]byte("stuff"))
-               }
-       }))
-       for _, req := range []string{
-               "GET / HTTP/1.0",
-               "GET /header HTTP/1.0",
-               "GET /more HTTP/1.0",
-               "GET / HTTP/1.1",
-               "GET /header HTTP/1.1",
-               "GET /more HTTP/1.1",
-       } {
-               got := ht.rawResponse(req)
-               if !strings.Contains(got, "304 Not Modified") {
-                       t.Errorf("Non-304 Not Modified for %q: %s", req, got)
-               } else if strings.Contains(got, "Content-Length") {
-                       t.Errorf("Got a Content-Length from %q: %s", req, got)
+// Issue 6157, Issue 6685
+func TestCodesPreventingContentTypeAndBody(t *testing.T) {
+       for _, code := range []int{StatusNotModified, StatusNoContent, StatusContinue} {
+               ht := newHandlerTest(HandlerFunc(func(w ResponseWriter, r *Request) {
+                       if r.URL.Path == "/header" {
+                               w.Header().Set("Content-Length", "123")
+                       }
+                       w.WriteHeader(code)
+                       if r.URL.Path == "/more" {
+                               w.Write([]byte("stuff"))
+                       }
+               }))
+               for _, req := range []string{
+                       "GET / HTTP/1.0",
+                       "GET /header HTTP/1.0",
+                       "GET /more HTTP/1.0",
+                       "GET / HTTP/1.1",
+                       "GET /header HTTP/1.1",
+                       "GET /more HTTP/1.1",
+               } {
+                       got := ht.rawResponse(req)
+                       wantStatus := fmt.Sprintf("%d %s", code, StatusText(code))
+                       if !strings.Contains(got, wantStatus) {
+                               t.Errorf("Code %d: Wanted %q Modified for %q: %s", code, req, got)
+                       } else if strings.Contains(got, "Content-Length") {
+                               t.Errorf("Code %d: Got a Content-Length from %q: %s", code, req, got)
+                       } else if strings.Contains(got, "stuff") {
+                               t.Errorf("Code %d: Response contains a body from %q: %s", code, req, got)
+                       }
                }
        }
 }
@@ -2148,6 +2165,57 @@ func TestTransportAndServerSharedBodyRace(t *testing.T) {
        (<-backendRespc).Body.Close()
 }
 
+// Test that a hanging Request.Body.Read from another goroutine can't
+// cause the Handler goroutine's Request.Body.Close to block.
+func TestRequestBodyCloseDoesntBlock(t *testing.T) {
+       t.Skipf("Skipping known issue; see golang.org/issue/7121")
+       if testing.Short() {
+               t.Skip("skipping in -short mode")
+       }
+       defer afterTest(t)
+
+       readErrCh := make(chan error, 1)
+       errCh := make(chan error, 2)
+
+       server := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
+               go func(body io.Reader) {
+                       _, err := body.Read(make([]byte, 100))
+                       readErrCh <- err
+               }(req.Body)
+               time.Sleep(500 * time.Millisecond)
+       }))
+       defer server.Close()
+
+       closeConn := make(chan bool)
+       defer close(closeConn)
+       go func() {
+               conn, err := net.Dial("tcp", server.Listener.Addr().String())
+               if err != nil {
+                       errCh <- err
+                       return
+               }
+               defer conn.Close()
+               _, err = conn.Write([]byte("POST / HTTP/1.1\r\nConnection: close\r\nHost: foo\r\nContent-Length: 100000\r\n\r\n"))
+               if err != nil {
+                       errCh <- err
+                       return
+               }
+               // And now just block, making the server block on our
+               // 100000 bytes of body that will never arrive.
+               <-closeConn
+       }()
+       select {
+       case err := <-readErrCh:
+               if err == nil {
+                       t.Error("Read was nil. Expected error.")
+               }
+       case err := <-errCh:
+               t.Error(err)
+       case <-time.After(5 * time.Second):
+               t.Error("timeout")
+       }
+}
+
 func TestResponseWriterWriteStringAllocs(t *testing.T) {
        t.Skip("allocs test unreliable with gccgo")
        ht := newHandlerTest(HandlerFunc(func(w ResponseWriter, r *Request) {
@@ -2191,7 +2259,9 @@ func BenchmarkClientServer(b *testing.B) {
                if err != nil {
                        b.Fatal("Get:", err)
                }
+               defer res.Body.Close()
                all, err := ioutil.ReadAll(res.Body)
+               res.Body.Close()
                if err != nil {
                        b.Fatal("ReadAll:", err)
                }
@@ -2234,6 +2304,7 @@ func benchmarkClientServerParallel(b *testing.B, conc int) {
                                        continue
                                }
                                all, err := ioutil.ReadAll(res.Body)
+                               res.Body.Close()
                                if err != nil {
                                        b.Logf("ReadAll: %v", err)
                                        continue
@@ -2271,6 +2342,7 @@ func BenchmarkServer(b *testing.B) {
                                log.Panicf("Get: %v", err)
                        }
                        all, err := ioutil.ReadAll(res.Body)
+                       res.Body.Close()
                        if err != nil {
                                log.Panicf("ReadAll: %v", err)
                        }
index 7ebd8575f3beb7d1640b14451e8c0cfb12fe2aa1..fea1898fd7e794c3e98f973808c931a9f2acb22e 100644 (file)
@@ -735,7 +735,7 @@ func (cw *chunkWriter) writeHeader(p []byte) {
        // response header and this is our first (and last) write, set
        // it, even to zero. This helps HTTP/1.0 clients keep their
        // "keep-alive" connections alive.
-       // Exceptions: 304 responses never get Content-Length, and if
+       // Exceptions: 304/204/1xx responses never get Content-Length, and if
        // it was a HEAD request, we don't know the difference between
        // 0 actual bytes and 0 bytes because the handler noticed it
        // was a HEAD request and chose not to write anything.  So for
@@ -743,7 +743,7 @@ func (cw *chunkWriter) writeHeader(p []byte) {
        // write non-zero bytes.  If it's actually 0 bytes and the
        // handler never looked at the Request.Method, we just don't
        // send a Content-Length header.
-       if w.handlerDone && w.status != StatusNotModified && header.get("Content-Length") == "" && (!isHEAD || len(p) > 0) {
+       if w.handlerDone && bodyAllowedForStatus(w.status) && header.get("Content-Length") == "" && (!isHEAD || len(p) > 0) {
                w.contentLength = int64(len(p))
                setHeader.contentLength = strconv.AppendInt(cw.res.clenBuf[:0], int64(len(p)), 10)
        }
@@ -792,7 +792,7 @@ func (cw *chunkWriter) writeHeader(p []byte) {
        }
 
        code := w.status
-       if code == StatusNotModified {
+       if !bodyAllowedForStatus(code) {
                // Must not have body.
                // RFC 2616 section 10.3.5: "the response MUST NOT include other entity-headers"
                for _, k := range []string{"Content-Type", "Content-Length", "Transfer-Encoding"} {
@@ -821,7 +821,7 @@ func (cw *chunkWriter) writeHeader(p []byte) {
                hasCL = false
        }
 
-       if w.req.Method == "HEAD" || code == StatusNotModified {
+       if w.req.Method == "HEAD" || !bodyAllowedForStatus(code) {
                // do nothing
        } else if code == StatusNoContent {
                delHeader("Transfer-Encoding")
@@ -915,7 +915,7 @@ func (w *response) bodyAllowed() bool {
        if !w.wroteHeader {
                panic("")
        }
-       return w.status != StatusNotModified
+       return bodyAllowedForStatus(w.status)
 }
 
 // The Life Of A Write is like this:
@@ -997,11 +997,10 @@ func (w *response) finishRequest() {
        w.cw.close()
        w.conn.buf.Flush()
 
-       // Close the body, unless we're about to close the whole TCP connection
-       // anyway.
-       if !w.closeAfterReply {
-               w.req.Body.Close()
-       }
+       // Close the body (regardless of w.closeAfterReply) so we can
+       // re-use its bufio.Reader later safely.
+       w.req.Body.Close()
+
        if w.req.MultipartForm != nil {
                w.req.MultipartForm.RemoveAll()
        }
@@ -1084,7 +1083,7 @@ func validNPN(proto string) bool {
 func (c *conn) serve() {
        defer func() {
                if err := recover(); err != nil {
-                       const size = 4096
+                       const size = 64 << 10
                        buf := make([]byte, size)
                        buf = buf[:runtime.Stack(buf, false)]
                        log.Printf("http: panic serving %v: %v\n%s", c.remoteAddr, err, buf)
@@ -1608,11 +1607,11 @@ func (srv *Server) ListenAndServe() error {
        if addr == "" {
                addr = ":http"
        }
-       l, e := net.Listen("tcp", addr)
-       if e != nil {
-               return e
+       ln, err := net.Listen("tcp", addr)
+       if err != nil {
+               return err
        }
-       return srv.Serve(l)
+       return srv.Serve(tcpKeepAliveListener{ln.(*net.TCPListener)})
 }
 
 // Serve accepts incoming connections on the Listener l, creating a
@@ -1742,12 +1741,12 @@ func (srv *Server) ListenAndServeTLS(certFile, keyFile string) error {
                return err
        }
 
-       conn, err := net.Listen("tcp", addr)
+       ln, err := net.Listen("tcp", addr)
        if err != nil {
                return err
        }
 
-       tlsListener := tls.NewListener(conn, config)
+       tlsListener := tls.NewListener(tcpKeepAliveListener{ln.(*net.TCPListener)}, config)
        return srv.Serve(tlsListener)
 }
 
@@ -1837,6 +1836,24 @@ func (tw *timeoutWriter) WriteHeader(code int) {
        tw.w.WriteHeader(code)
 }
 
+// tcpKeepAliveListener sets TCP keep-alive timeouts on accepted
+// connections. It's used by ListenAndServe and ListenAndServeTLS so
+// dead TCP connections (e.g. closing laptop mid-download) eventually
+// go away.
+type tcpKeepAliveListener struct {
+       *net.TCPListener
+}
+
+func (ln tcpKeepAliveListener) Accept() (c net.Conn, err error) {
+       tc, err := ln.AcceptTCP()
+       if err != nil {
+               return
+       }
+       tc.SetKeepAlive(true)
+       tc.SetKeepAlivePeriod(3 * time.Minute)
+       return tc, nil
+}
+
 // globalOptionsHandler responds to "OPTIONS *" requests.
 type globalOptionsHandler struct{}
 
index 4a2bda19facf83d23bf79e51560c100ffc674327..2eec9d9abc4788357d636a56d6b5deba79ae6f6b 100644 (file)
@@ -60,7 +60,7 @@ func newTransferWriter(r interface{}) (t *transferWriter, err error) {
                                        // Stich the Body back together again, re-attaching our
                                        // consumed byte.
                                        t.ContentLength = -1
-                                       t.Body = io.MultiReader(bytes.NewBuffer(buf[:]), t.Body)
+                                       t.Body = io.MultiReader(bytes.NewReader(buf[:]), t.Body)
                                } else {
                                        // Body is actually empty.
                                        t.Body = nil
@@ -559,6 +559,17 @@ func (b *body) readLocked(p []byte) (n int, err error) {
                }
        }
 
+       // If we can return an EOF here along with the read data, do
+       // so. This is optional per the io.Reader contract, but doing
+       // so helps the HTTP transport code recycle its connection
+       // earlier (since it will see this EOF itself), even if the
+       // client doesn't do future reads or Close.
+       if err == nil && n > 0 {
+               if lr, ok := b.src.(*io.LimitedReader); ok && lr.N == 0 {
+                       err = io.EOF
+               }
+       }
+
        return n, err
 }
 
index fb5ef37a0f0e605f7e11d220130709f0a6a37606..48cd540b9f75ae034319ecae6969baff8af98ce9 100644 (file)
@@ -6,6 +6,7 @@ package http
 
 import (
        "bufio"
+       "io"
        "strings"
        "testing"
 )
@@ -35,3 +36,29 @@ func TestBodyReadBadTrailer(t *testing.T) {
                t.Errorf("final Read was successful (%q), expected error from trailer read", got)
        }
 }
+
+func TestFinalChunkedBodyReadEOF(t *testing.T) {
+       res, err := ReadResponse(bufio.NewReader(strings.NewReader(
+               "HTTP/1.1 200 OK\r\n"+
+                       "Transfer-Encoding: chunked\r\n"+
+                       "\r\n"+
+                       "0a\r\n"+
+                       "Body here\n\r\n"+
+                       "09\r\n"+
+                       "continued\r\n"+
+                       "0\r\n"+
+                       "\r\n")), nil)
+       if err != nil {
+               t.Fatal(err)
+       }
+       want := "Body here\ncontinued"
+       buf := make([]byte, len(want))
+       n, err := res.Body.Read(buf)
+       if n != len(want) || err != io.EOF {
+               t.Logf("body = %#v", res.Body)
+               t.Errorf("Read = %v, %v; want %d, EOF", n, err, len(want))
+       }
+       if string(buf) != want {
+               t.Errorf("buf = %q; want %q", buf, want)
+       }
+}
index f6871afacd7a3c26efc3d76350b314be29897da1..2c312a77a02e1418f6f0d335cf62ee6a56b063b0 100644 (file)
@@ -41,8 +41,8 @@ const DefaultMaxIdleConnsPerHost = 2
 // Transport can also cache connections for future re-use.
 type Transport struct {
        idleMu     sync.Mutex
-       idleConn   map[string][]*persistConn
-       idleConnCh map[string]chan *persistConn
+       idleConn   map[connectMethodKey][]*persistConn
+       idleConnCh map[connectMethodKey]chan *persistConn
        reqMu      sync.Mutex
        reqConn    map[*Request]*persistConn
        altMu      sync.RWMutex
@@ -99,7 +99,7 @@ type Transport struct {
 // A nil URL and nil error are returned if no proxy is defined in the
 // environment, or a proxy should not be used for the given request.
 func ProxyFromEnvironment(req *Request) (*url.URL, error) {
-       proxy := getenvEitherCase("HTTP_PROXY")
+       proxy := httpProxyEnv.Get()
        if proxy == "" {
                return nil, nil
        }
@@ -243,24 +243,49 @@ func (t *Transport) CancelRequest(req *Request) {
 // Private implementation past this point.
 //
 
-func getenvEitherCase(k string) string {
-       if v := os.Getenv(strings.ToUpper(k)); v != "" {
-               return v
+var (
+       httpProxyEnv = &envOnce{
+               names: []string{"HTTP_PROXY", "http_proxy"},
        }
-       return os.Getenv(strings.ToLower(k))
+       noProxyEnv = &envOnce{
+               names: []string{"NO_PROXY", "no_proxy"},
+       }
+)
+
+// envOnce looks up an environment variable (optionally by multiple
+// names) once. It mitigates expensive lookups on some platforms
+// (e.g. Windows).
+type envOnce struct {
+       names []string
+       once  sync.Once
+       val   string
 }
 
-func (t *Transport) connectMethodForRequest(treq *transportRequest) (*connectMethod, error) {
-       cm := &connectMethod{
-               targetScheme: treq.URL.Scheme,
-               targetAddr:   canonicalAddr(treq.URL),
+func (e *envOnce) Get() string {
+       e.once.Do(e.init)
+       return e.val
+}
+
+func (e *envOnce) init() {
+       for _, n := range e.names {
+               e.val = os.Getenv(n)
+               if e.val != "" {
+                       return
+               }
        }
+}
+
+// reset is used by tests
+func (e *envOnce) reset() {
+       e.once = sync.Once{}
+       e.val = ""
+}
+
+func (t *Transport) connectMethodForRequest(treq *transportRequest) (cm connectMethod, err error) {
+       cm.targetScheme = treq.URL.Scheme
+       cm.targetAddr = canonicalAddr(treq.URL)
        if t.Proxy != nil {
-               var err error
                cm.proxyURL, err = t.Proxy(treq.Request)
-               if err != nil {
-                       return nil, err
-               }
        }
        return cm, nil
 }
@@ -316,7 +341,7 @@ func (t *Transport) putIdleConn(pconn *persistConn) bool {
                }
        }
        if t.idleConn == nil {
-               t.idleConn = make(map[string][]*persistConn)
+               t.idleConn = make(map[connectMethodKey][]*persistConn)
        }
        if len(t.idleConn[key]) >= max {
                t.idleMu.Unlock()
@@ -336,7 +361,7 @@ func (t *Transport) putIdleConn(pconn *persistConn) bool {
 // getIdleConnCh returns a channel to receive and return idle
 // persistent connection for the given connectMethod.
 // It may return nil, if persistent connections are not being used.
-func (t *Transport) getIdleConnCh(cm *connectMethod) chan *persistConn {
+func (t *Transport) getIdleConnCh(cm connectMethod) chan *persistConn {
        if t.DisableKeepAlives {
                return nil
        }
@@ -344,7 +369,7 @@ func (t *Transport) getIdleConnCh(cm *connectMethod) chan *persistConn {
        t.idleMu.Lock()
        defer t.idleMu.Unlock()
        if t.idleConnCh == nil {
-               t.idleConnCh = make(map[string]chan *persistConn)
+               t.idleConnCh = make(map[connectMethodKey]chan *persistConn)
        }
        ch, ok := t.idleConnCh[key]
        if !ok {
@@ -354,7 +379,7 @@ func (t *Transport) getIdleConnCh(cm *connectMethod) chan *persistConn {
        return ch
 }
 
-func (t *Transport) getIdleConn(cm *connectMethod) (pconn *persistConn) {
+func (t *Transport) getIdleConn(cm connectMethod) (pconn *persistConn) {
        key := cm.key()
        t.idleMu.Lock()
        defer t.idleMu.Unlock()
@@ -373,7 +398,7 @@ func (t *Transport) getIdleConn(cm *connectMethod) (pconn *persistConn) {
                        // 2 or more cached connections; pop last
                        // TODO: queue?
                        pconn = pconns[len(pconns)-1]
-                       t.idleConn[key] = pconns[0 : len(pconns)-1]
+                       t.idleConn[key] = pconns[:len(pconns)-1]
                }
                if !pconn.isBroken() {
                        return
@@ -405,7 +430,7 @@ func (t *Transport) dial(network, addr string) (c net.Conn, err error) {
 // specified in the connectMethod.  This includes doing a proxy CONNECT
 // and/or setting up TLS.  If this doesn't return an error, the persistConn
 // is ready to write requests to.
-func (t *Transport) getConn(cm *connectMethod) (*persistConn, error) {
+func (t *Transport) getConn(cm connectMethod) (*persistConn, error) {
        if pc := t.getIdleConn(cm); pc != nil {
                return pc, nil
        }
@@ -440,7 +465,7 @@ func (t *Transport) getConn(cm *connectMethod) (*persistConn, error) {
        }
 }
 
-func (t *Transport) dialConn(cm *connectMethod) (*persistConn, error) {
+func (t *Transport) dialConn(cm connectMethod) (*persistConn, error) {
        conn, err := t.dial("tcp", cm.addr())
        if err != nil {
                if cm.proxyURL != nil {
@@ -550,7 +575,7 @@ func useProxy(addr string) bool {
                }
        }
 
-       no_proxy := getenvEitherCase("NO_PROXY")
+       no_proxy := noProxyEnv.Get()
        if no_proxy == "*" {
                return false
        }
@@ -603,20 +628,20 @@ type connectMethod struct {
        targetAddr   string   // Not used if proxy + http targetScheme (4th example in table)
 }
 
-func (ck *connectMethod) key() string {
-       return ck.String() // TODO: use a struct type instead
-}
-
-func (ck *connectMethod) String() string {
+func (cm *connectMethod) key() connectMethodKey {
        proxyStr := ""
-       targetAddr := ck.targetAddr
-       if ck.proxyURL != nil {
-               proxyStr = ck.proxyURL.String()
-               if ck.targetScheme == "http" {
+       targetAddr := cm.targetAddr
+       if cm.proxyURL != nil {
+               proxyStr = cm.proxyURL.String()
+               if cm.targetScheme == "http" {
                        targetAddr = ""
                }
        }
-       return strings.Join([]string{proxyStr, ck.targetScheme, targetAddr}, "|")
+       return connectMethodKey{
+               proxy:  proxyStr,
+               scheme: cm.targetScheme,
+               addr:   targetAddr,
+       }
 }
 
 // addr returns the first hop "host:port" to which we need to TCP connect.
@@ -637,11 +662,23 @@ func (cm *connectMethod) tlsHost() string {
        return h
 }
 
+// connectMethodKey is the map key version of connectMethod, with a
+// stringified proxy URL (or the empty string) instead of a pointer to
+// a URL.
+type connectMethodKey struct {
+       proxy, scheme, addr string
+}
+
+func (k connectMethodKey) String() string {
+       // Only used by tests.
+       return fmt.Sprintf("%s|%s|%s", k.proxy, k.scheme, k.addr)
+}
+
 // persistConn wraps a connection, usually a persistent one
 // (but may be used for non-keep-alive requests as well)
 type persistConn struct {
        t        *Transport
-       cacheKey string // its connectMethod.String()
+       cacheKey connectMethodKey
        conn     net.Conn
        closed   bool                // whether conn has been closed
        br       *bufio.Reader       // from conn
@@ -832,6 +869,18 @@ type writeRequest struct {
        ch  chan<- error
 }
 
+type httpError struct {
+       err     string
+       timeout bool
+}
+
+func (e *httpError) Error() string   { return e.err }
+func (e *httpError) Timeout() bool   { return e.timeout }
+func (e *httpError) Temporary() bool { return true }
+
+var errTimeout error = &httpError{err: "net/http: timeout awaiting response headers", timeout: true}
+var errClosed error = &httpError{err: "net/http: transport closed before response was received"}
+
 func (pc *persistConn) roundTrip(req *transportRequest) (resp *Response, err error) {
        pc.t.setReqConn(req.Request, pc)
        pc.lk.Lock()
@@ -902,11 +951,11 @@ WaitResponse:
                        pconnDeadCh = nil                               // avoid spinning
                        failTicker = time.After(100 * time.Millisecond) // arbitrary time to wait for resc
                case <-failTicker:
-                       re = responseAndError{err: errors.New("net/http: transport closed before response was received")}
+                       re = responseAndError{err: errClosed}
                        break WaitResponse
                case <-respHeaderTimer:
                        pc.close()
-                       re = responseAndError{err: errors.New("net/http: timeout awaiting response headers")}
+                       re = responseAndError{err: errTimeout}
                        break WaitResponse
                case re = <-resc:
                        break WaitResponse
index 2ce2b6b5180c86c6c73d047e8cda3f7665b2cc19..2678d71b1dec19b0e9257ecadd69c61d3648c3ff 100644 (file)
@@ -271,6 +271,58 @@ func TestTransportIdleCacheKeys(t *testing.T) {
        }
 }
 
+// Tests that the HTTP transport re-uses connections when a client
+// reads to the end of a response Body without closing it.
+func TestTransportReadToEndReusesConn(t *testing.T) {
+       defer afterTest(t)
+       const msg = "foobar"
+
+       var addrSeen map[string]int
+       ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+               addrSeen[r.RemoteAddr]++
+               if r.URL.Path == "/chunked/" {
+                       w.WriteHeader(200)
+                       w.(http.Flusher).Flush()
+               } else {
+                       w.Header().Set("Content-Type", strconv.Itoa(len(msg)))
+                       w.WriteHeader(200)
+               }
+               w.Write([]byte(msg))
+       }))
+       defer ts.Close()
+
+       buf := make([]byte, len(msg))
+
+       for pi, path := range []string{"/content-length/", "/chunked/"} {
+               wantLen := []int{len(msg), -1}[pi]
+               addrSeen = make(map[string]int)
+               for i := 0; i < 3; i++ {
+                       res, err := http.Get(ts.URL + path)
+                       if err != nil {
+                               t.Errorf("Get %s: %v", path, err)
+                               continue
+                       }
+                       // We want to close this body eventually (before the
+                       // defer afterTest at top runs), but not before the
+                       // len(addrSeen) check at the bottom of this test,
+                       // since Closing this early in the loop would risk
+                       // making connections be re-used for the wrong reason.
+                       defer res.Body.Close()
+
+                       if res.ContentLength != int64(wantLen) {
+                               t.Errorf("%s res.ContentLength = %d; want %d", path, res.ContentLength, wantLen)
+                       }
+                       n, err := res.Body.Read(buf)
+                       if n != len(msg) || err != io.EOF {
+                               t.Errorf("%s Read = %v, %v; want %d, EOF", path, n, err, len(msg))
+                       }
+               }
+               if len(addrSeen) != 1 {
+                       t.Errorf("for %s, server saw %d distinct client addresses; want 1", path, len(addrSeen))
+               }
+       }
+}
+
 func TestTransportMaxPerHostIdleConns(t *testing.T) {
        defer afterTest(t)
        resch := make(chan string)
@@ -741,6 +793,9 @@ func TestTransportGzipRecursive(t *testing.T) {
 
 // tests that persistent goroutine connections shut down when no longer desired.
 func TestTransportPersistConnLeak(t *testing.T) {
+       if runtime.GOOS == "plan9" {
+               t.Skip("skipping test; see http://golang.org/issue/7237")
+       }
        defer afterTest(t)
        gotReqCh := make(chan bool)
        unblockCh := make(chan bool)
@@ -807,6 +862,9 @@ func TestTransportPersistConnLeak(t *testing.T) {
 // golang.org/issue/4531: Transport leaks goroutines when
 // request.ContentLength is explicitly short
 func TestTransportPersistConnLeakShortBody(t *testing.T) {
+       if runtime.GOOS == "plan9" {
+               t.Skip("skipping test; see http://golang.org/issue/7237")
+       }
        defer afterTest(t)
        ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
        }))
@@ -1014,6 +1072,9 @@ func TestTransportConcurrency(t *testing.T) {
 }
 
 func TestIssue4191_InfiniteGetTimeout(t *testing.T) {
+       if runtime.GOOS == "plan9" {
+               t.Skip("skipping test; see http://golang.org/issue/7237")
+       }
        defer afterTest(t)
        const debug = false
        mux := NewServeMux()
@@ -1075,6 +1136,9 @@ func TestIssue4191_InfiniteGetTimeout(t *testing.T) {
 }
 
 func TestIssue4191_InfiniteGetToPutTimeout(t *testing.T) {
+       if runtime.GOOS == "plan9" {
+               t.Skip("skipping test; see http://golang.org/issue/7237")
+       }
        defer afterTest(t)
        const debug = false
        mux := NewServeMux()
@@ -1173,6 +1237,20 @@ func TestTransportResponseHeaderTimeout(t *testing.T) {
        for i, tt := range tests {
                res, err := c.Get(ts.URL + tt.path)
                if err != nil {
+                       uerr, ok := err.(*url.Error)
+                       if !ok {
+                               t.Errorf("error is not an url.Error; got: %#v", err)
+                               continue
+                       }
+                       nerr, ok := uerr.Err.(net.Error)
+                       if !ok {
+                               t.Errorf("error does not satisfy net.Error interface; got: %#v", err)
+                               continue
+                       }
+                       if !nerr.Timeout() {
+                               t.Errorf("want timeout error; got: %q", nerr)
+                               continue
+                       }
                        if strings.Contains(err.Error(), tt.wantErr) {
                                continue
                        }
@@ -1283,7 +1361,7 @@ func TestTransportCloseResponseBody(t *testing.T) {
                t.Fatal(err)
        }
        if !bytes.Equal(buf, want) {
-               t.Errorf("read %q; want %q", buf, want)
+               t.Fatalf("read %q; want %q", buf, want)
        }
        didClose := make(chan error, 1)
        go func() {
@@ -1566,6 +1644,7 @@ func TestProxyFromEnvironment(t *testing.T) {
        for _, tt := range proxyFromEnvTests {
                os.Setenv("HTTP_PROXY", tt.env)
                os.Setenv("NO_PROXY", tt.noenv)
+               ResetCachedEnvironment()
                reqURL := tt.req
                if reqURL == "" {
                        reqURL = "http://example.com"
index 1207c0f269da08f20a813512308d8c3211c8fb98..1115d0fc40b6f366d3002d071feff133c1add70b 100644 (file)
@@ -45,15 +45,41 @@ loop:
        return ift, nil
 }
 
+const (
+       // See linux/if_arp.h.
+       // Note that Linux doesn't support IPv4 over IPv6 tunneling.
+       sysARPHardwareIPv4IPv4 = 768 // IPv4 over IPv4 tunneling
+       sysARPHardwareIPv6IPv6 = 769 // IPv6 over IPv6 tunneling
+       sysARPHardwareIPv6IPv4 = 776 // IPv6 over IPv4 tunneling
+       sysARPHardwareGREIPv4  = 778 // any over GRE over IPv4 tunneling
+       sysARPHardwareGREIPv6  = 823 // any over GRE over IPv6 tunneling
+)
+
 func newLink(ifim *syscall.IfInfomsg, attrs []syscall.NetlinkRouteAttr) *Interface {
        ifi := &Interface{Index: int(ifim.Index), Flags: linkFlags(ifim.Flags)}
        for _, a := range attrs {
                switch a.Attr.Type {
                case syscall.IFLA_ADDRESS:
+                       // We never return any /32 or /128 IP address
+                       // prefix on any IP tunnel interface as the
+                       // hardware address.
+                       switch len(a.Value) {
+                       case IPv4len:
+                               switch ifim.Type {
+                               case sysARPHardwareIPv4IPv4, sysARPHardwareGREIPv4, sysARPHardwareIPv6IPv4:
+                                       continue
+                               }
+                       case IPv6len:
+                               switch ifim.Type {
+                               case sysARPHardwareIPv6IPv6, sysARPHardwareGREIPv6:
+                                       continue
+                               }
+                       }
                        var nonzero bool
                        for _, b := range a.Value {
                                if b != 0 {
                                        nonzero = true
+                                       break
                                }
                        }
                        if nonzero {
@@ -147,19 +173,31 @@ loop:
 }
 
 func newAddr(ifi *Interface, ifam *syscall.IfAddrmsg, attrs []syscall.NetlinkRouteAttr) Addr {
-       for _, a := range attrs {
-               if ifi.Flags&FlagPointToPoint != 0 && a.Attr.Type == syscall.IFA_LOCAL ||
-                       ifi.Flags&FlagPointToPoint == 0 && a.Attr.Type == syscall.IFA_ADDRESS {
-                       switch ifam.Family {
-                       case syscall.AF_INET:
-                               return &IPNet{IP: IPv4(a.Value[0], a.Value[1], a.Value[2], a.Value[3]), Mask: CIDRMask(int(ifam.Prefixlen), 8*IPv4len)}
-                       case syscall.AF_INET6:
-                               ifa := &IPNet{IP: make(IP, IPv6len), Mask: CIDRMask(int(ifam.Prefixlen), 8*IPv6len)}
-                               copy(ifa.IP, a.Value[:])
-                               return ifa
+       var ipPointToPoint bool
+       // Seems like we need to make sure whether the IP interface
+       // stack consists of IP point-to-point numbered or unnumbered
+       // addressing over point-to-point link encapsulation.
+       if ifi.Flags&FlagPointToPoint != 0 {
+               for _, a := range attrs {
+                       if a.Attr.Type == syscall.IFA_LOCAL {
+                               ipPointToPoint = true
+                               break
                        }
                }
        }
+       for _, a := range attrs {
+               if ipPointToPoint && a.Attr.Type == syscall.IFA_ADDRESS || !ipPointToPoint && a.Attr.Type == syscall.IFA_LOCAL {
+                       continue
+               }
+               switch ifam.Family {
+               case syscall.AF_INET:
+                       return &IPNet{IP: IPv4(a.Value[0], a.Value[1], a.Value[2], a.Value[3]), Mask: CIDRMask(int(ifam.Prefixlen), 8*IPv4len)}
+               case syscall.AF_INET6:
+                       ifa := &IPNet{IP: make(IP, IPv6len), Mask: CIDRMask(int(ifam.Prefixlen), 8*IPv6len)}
+                       copy(ifa.IP, a.Value[:])
+                       return ifa
+               }
+       }
        return nil
 }
 
index fcec4164f4c74c9ff57845b79dfdb19d91118483..914ed50826f8c402ecb769460d16fe6996c1665a 100644 (file)
@@ -12,19 +12,45 @@ import (
        "syscall"
 )
 
+func probe(filename, query string) bool {
+       var file *file
+       var err error
+       if file, err = open(filename); err != nil {
+               return false
+       }
+
+       r := false
+       for line, ok := file.readLine(); ok && !r; line, ok = file.readLine() {
+               f := getFields(line)
+               if len(f) < 3 {
+                       continue
+               }
+               for i := 0; i < len(f); i++ {
+                       if query == f[i] {
+                               r = true
+                               break
+                       }
+               }
+       }
+       file.close()
+       return r
+}
+
 func probeIPv4Stack() bool {
-       // TODO(mikio): implement this when Plan 9 supports IPv6-only
-       // kernel.
-       return true
+       return probe(netdir+"/iproute", "4i")
 }
 
 // probeIPv6Stack returns two boolean values.  If the first boolean
 // value is true, kernel supports basic IPv6 functionality.  If the
 // second boolean value is true, kernel supports IPv6 IPv4-mapping.
 func probeIPv6Stack() (supportsIPv6, supportsIPv4map bool) {
-       // TODO(mikio): implement this once Plan 9 gets an IPv6
-       // protocol stack implementation.
-       return false, false
+       // Plan 9 uses IPv6 natively, see ip(3).
+       r := probe(netdir+"/iproute", "6i")
+       v := false
+       if r {
+               v = probe(netdir+"/iproute", "4i")
+       }
+       return r, v
 }
 
 // parsePlan9Addr parses address of the form [ip!]port (e.g. 127.0.0.1!80).
@@ -133,18 +159,18 @@ func dialPlan9(net string, laddr, raddr Addr) (fd *netFD, err error) {
                f.Close()
                return nil, &OpError{"dial", f.Name(), raddr, err}
        }
-       data, err := os.OpenFile("/net/"+proto+"/"+name+"/data", os.O_RDWR, 0)
+       data, err := os.OpenFile(netdir+"/"+proto+"/"+name+"/data", os.O_RDWR, 0)
        if err != nil {
                f.Close()
                return nil, &OpError{"dial", net, raddr, err}
        }
-       laddr, err = readPlan9Addr(proto, "/net/"+proto+"/"+name+"/local")
+       laddr, err = readPlan9Addr(proto, netdir+"/"+proto+"/"+name+"/local")
        if err != nil {
                data.Close()
                f.Close()
                return nil, &OpError{"dial", proto, raddr, err}
        }
-       return newFD(proto, name, f, data, laddr, raddr), nil
+       return newFD(proto, name, f, data, laddr, raddr)
 }
 
 func listenPlan9(net string, laddr Addr) (fd *netFD, err error) {
@@ -158,20 +184,24 @@ func listenPlan9(net string, laddr Addr) (fd *netFD, err error) {
                f.Close()
                return nil, &OpError{"announce", proto, laddr, err}
        }
-       laddr, err = readPlan9Addr(proto, "/net/"+proto+"/"+name+"/local")
+       laddr, err = readPlan9Addr(proto, netdir+"/"+proto+"/"+name+"/local")
        if err != nil {
                f.Close()
                return nil, &OpError{Op: "listen", Net: net, Err: err}
        }
-       return newFD(proto, name, f, nil, laddr, nil), nil
+       return newFD(proto, name, f, nil, laddr, nil)
 }
 
-func (l *netFD) netFD() *netFD {
-       return newFD(l.proto, l.name, l.ctl, l.data, l.laddr, l.raddr)
+func (l *netFD) netFD() (*netFD, error) {
+       return newFD(l.proto, l.n, l.ctl, l.data, l.laddr, l.raddr)
 }
 
 func (l *netFD) acceptPlan9() (fd *netFD, err error) {
        defer func() { netErr(err) }()
+       if err := l.readLock(); err != nil {
+               return nil, err
+       }
+       defer l.readUnlock()
        f, err := os.Open(l.dir + "/listen")
        if err != nil {
                return nil, &OpError{"accept", l.dir + "/listen", l.laddr, err}
@@ -183,16 +213,16 @@ func (l *netFD) acceptPlan9() (fd *netFD, err error) {
                return nil, &OpError{"accept", l.dir + "/listen", l.laddr, err}
        }
        name := string(buf[:n])
-       data, err := os.OpenFile("/net/"+l.proto+"/"+name+"/data", os.O_RDWR, 0)
+       data, err := os.OpenFile(netdir+"/"+l.proto+"/"+name+"/data", os.O_RDWR, 0)
        if err != nil {
                f.Close()
                return nil, &OpError{"accept", l.proto, l.laddr, err}
        }
-       raddr, err := readPlan9Addr(l.proto, "/net/"+l.proto+"/"+name+"/remote")
+       raddr, err := readPlan9Addr(l.proto, netdir+"/"+l.proto+"/"+name+"/remote")
        if err != nil {
                data.Close()
                f.Close()
                return nil, &OpError{"accept", l.proto, l.laddr, err}
        }
-       return newFD(l.proto, name, f, data, l.laddr, raddr), nil
+       return newFD(l.proto, name, f, data, l.laddr, raddr)
 }
index a755ff2aacc49e3c3f79dd78b10a2ea522ce9932..2ccd997c2cba1b7efb15a798b6da6f22cebce83d 100644 (file)
@@ -16,6 +16,10 @@ func query(filename, query string, bufSize int) (res []string, err error) {
        }
        defer file.Close()
 
+       _, err = file.Seek(0, 0)
+       if err != nil {
+               return
+       }
        _, err = file.WriteString(query)
        if err != nil {
                return
@@ -45,7 +49,7 @@ func queryCS(net, host, service string) (res []string, err error) {
        if host == "" {
                host = "*"
        }
-       return query("/net/cs", net+"!"+host+"!"+service, 128)
+       return query(netdir+"/cs", net+"!"+host+"!"+service, 128)
 }
 
 func queryCS1(net string, ip IP, port int) (clone, dest string, err error) {
@@ -66,7 +70,7 @@ func queryCS1(net string, ip IP, port int) (clone, dest string, err error) {
 }
 
 func queryDNS(addr string, typ string) (res []string, err error) {
-       return query("/net/dns", addr+" "+typ, 1024)
+       return query(netdir+"/dns", addr+" "+typ, 1024)
 }
 
 // toLower returns a lower-case version of in. Restricting us to
@@ -93,7 +97,7 @@ func toLower(in string) string {
 // lookupProtocol looks up IP protocol name and returns
 // the corresponding protocol number.
 func lookupProtocol(name string) (proto int, err error) {
-       lines, err := query("/net/cs", "!protocol="+toLower(name), 128)
+       lines, err := query(netdir+"/cs", "!protocol="+toLower(name), 128)
        if err != nil {
                return 0, err
        }
@@ -113,12 +117,13 @@ func lookupProtocol(name string) (proto int, err error) {
 }
 
 func lookupHost(host string) (addrs []string, err error) {
-       // Use /net/cs instead of /net/dns because cs knows about
+       // Use netdir/cs instead of netdir/dns because cs knows about
        // host names in local network (e.g. from /lib/ndb/local)
        lines, err := queryCS("net", host, "1")
        if err != nil {
                return
        }
+loop:
        for _, line := range lines {
                f := getFields(line)
                if len(f) < 2 {
@@ -131,6 +136,12 @@ func lookupHost(host string) (addrs []string, err error) {
                if ParseIP(addr) == nil {
                        continue
                }
+               // only return unique addresses
+               for _, a := range addrs {
+                       if a == addr {
+                               continue loop
+                       }
+               }
                addrs = append(addrs, addr)
        }
        return
index dc2ab44dab247c0e5eb1b2329a99fe70130da9d0..4b332c1b5be6e8ffd2cf95e1eaf1246f341f9ee8 100644 (file)
@@ -159,7 +159,9 @@ func (a *Address) String() string {
        // If every character is printable ASCII, quoting is simple.
        allPrintable := true
        for i := 0; i < len(a.Name); i++ {
-               if !isVchar(a.Name[i]) {
+               // isWSP here should actually be isFWS,
+               // but we don't support folding yet.
+               if !isVchar(a.Name[i]) && !isWSP(a.Name[i]) {
                        allPrintable = false
                        break
                }
@@ -167,7 +169,7 @@ func (a *Address) String() string {
        if allPrintable {
                b := bytes.NewBufferString(`"`)
                for i := 0; i < len(a.Name); i++ {
-                       if !isQtext(a.Name[i]) {
+                       if !isQtext(a.Name[i]) && !isWSP(a.Name[i]) {
                                b.WriteByte('\\')
                        }
                        b.WriteByte(a.Name[i])
@@ -535,3 +537,9 @@ func isVchar(c byte) bool {
        // Visible (printing) characters.
        return '!' <= c && c <= '~'
 }
+
+// isWSP returns true if c is a WSP (white space).
+// WSP is a space or horizontal tab (RFC5234 Appendix B).
+func isWSP(c byte) bool {
+       return c == ' ' || c == '\t'
+}
index 3c037f38385209ec3b23555d7d5c0a9475359370..1bb4e8bc40137e6c72d9049b03d7b55c1014ea04 100644 (file)
@@ -277,6 +277,14 @@ func TestAddressFormatting(t *testing.T) {
                        &Address{Name: "Böb", Address: "bob@example.com"},
                        `=?utf-8?q?B=C3=B6b?= <bob@example.com>`,
                },
+               {
+                       &Address{Name: "Bob Jane", Address: "bob@example.com"},
+                       `"Bob Jane" <bob@example.com>`,
+               },
+               {
+                       &Address{Name: "Böb Jacöb", Address: "bob@example.com"},
+                       `=?utf-8?q?B=C3=B6b_Jac=C3=B6b?= <bob@example.com>`,
+               },
        }
        for _, test := range tests {
                s := test.addr.String()
index 7eb2dcf5a9fc84ecb3cd1882f796c44eb8e4466b..6b264b46b8e769898c09b08159103a7f449f94af 100644 (file)
@@ -217,10 +217,11 @@ func isExportedOrBuiltinType(t reflect.Type) bool {
 // Register publishes in the server the set of methods of the
 // receiver value that satisfy the following conditions:
 //     - exported method
-//     - two arguments, both pointers to exported structs
+//     - two arguments, both of exported type
+//     - the second argument is a pointer
 //     - one return value, of type error
 // It returns an error if the receiver is not an exported type or has
-// no methods or unsuitable methods. It also logs the error using package log.
+// no suitable methods. It also logs the error using package log.
 // The client accesses each method using a string of the form "Type.Method",
 // where Type is the receiver's concrete type.
 func (server *Server) Register(rcvr interface{}) error {
diff --git a/libgo/go/net/sockopt_plan9.go b/libgo/go/net/sockopt_plan9.go
new file mode 100644 (file)
index 0000000..8bc689b
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2014 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package net
+
+func setKeepAlive(fd *netFD, keepalive bool) error {
+       if keepalive {
+               _, e := fd.ctl.WriteAt([]byte("keepalive"), 0)
+               return e
+       }
+       return nil
+}
index cf9c0f8904764bafb1e37d9cdb296713b57d40d6..6e1a8b9a1928f1168364ba43890365af425b87ae 100644 (file)
@@ -62,12 +62,18 @@ func (c *TCPConn) SetLinger(sec int) error {
 // SetKeepAlive sets whether the operating system should send
 // keepalive messages on the connection.
 func (c *TCPConn) SetKeepAlive(keepalive bool) error {
-       return syscall.EPLAN9
+       if !c.ok() {
+               return syscall.EPLAN9
+       }
+       return setKeepAlive(c.fd, keepalive)
 }
 
 // SetKeepAlivePeriod sets period between keep alives.
 func (c *TCPConn) SetKeepAlivePeriod(d time.Duration) error {
-       return syscall.EPLAN9
+       if !c.ok() {
+               return syscall.EPLAN9
+       }
+       return setKeepAlivePeriod(c.fd, d)
 }
 
 // SetNoDelay controls whether the operating system should delay
diff --git a/libgo/go/net/tcpsockopt_plan9.go b/libgo/go/net/tcpsockopt_plan9.go
new file mode 100644 (file)
index 0000000..0e7a664
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2014 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// TCP socket options for plan9
+
+package net
+
+import (
+       "time"
+)
+
+// Set keep alive period.
+func setKeepAlivePeriod(fd *netFD, d time.Duration) error {
+       cmd := "keepalive " + string(int64(d/time.Millisecond))
+       _, e := fd.ctl.WriteAt([]byte(cmd), 0)
+       return e
+}
index 0bf4312f248b04befe5acf13ed2784fec466fff0..8ef1407977f5a3839af7ae01ea8a38742090c4ef 100644 (file)
@@ -7,7 +7,10 @@
 package net
 
 import (
+       "os"
+       "syscall"
        "time"
+       "unsafe"
 )
 
 func setKeepAlivePeriod(fd *netFD, d time.Duration) error {
@@ -16,6 +19,16 @@ func setKeepAlivePeriod(fd *netFD, d time.Duration) error {
        }
        defer fd.decref()
 
-       // We can't actually set this per connection.  Act as a noop rather than an error.
-       return nil
+       // Windows expects milliseconds so round to next highest millisecond.
+       d += (time.Millisecond - time.Nanosecond)
+       millis := uint32(d / time.Millisecond)
+       ka := syscall.TCPKeepalive{
+               OnOff:    1,
+               Time:     millis,
+               Interval: millis,
+       }
+       ret := uint32(0)
+       size := uint32(unsafe.Sizeof(ka))
+       err := syscall.WSAIoctl(fd.sysfd, syscall.SIO_KEEPALIVE_VALS, (*byte)(unsafe.Pointer(&ka)), size, nil, 0, &ret, nil, 0)
+       return os.NewSyscallError("WSAIoctl", err)
 }
index 73621706d5c814213c915700e9078ccfb8863cc8..510ac5e4aaa6037b91c32fc084064307680a1fa6 100644 (file)
@@ -190,7 +190,8 @@ func ListenUDP(net string, laddr *UDPAddr) (*UDPConn, error) {
        if err != nil {
                return nil, err
        }
-       return newUDPConn(l.netFD()), nil
+       fd, err := l.netFD()
+       return newUDPConn(fd), err
 }
 
 // ListenMulticastUDP listens for incoming multicast UDP packets
index 5deb8f47c6c2de5422b6fed5f24c765aa3fb1040..452ac925428d1ae50453b08e9fbf71172405feda 100644 (file)
@@ -166,9 +166,12 @@ var dualStackListenerTests = []struct {
 }
 
 // TestDualStackTCPListener tests both single and double listen
-// to a test listener with various address families, differnet
+// to a test listener with various address families, different
 // listening address and same port.
 func TestDualStackTCPListener(t *testing.T) {
+       if testing.Short() {
+               t.Skip("skipping in -short mode, see issue 5001")
+       }
        switch runtime.GOOS {
        case "plan9":
                t.Skipf("skipping test on %q", runtime.GOOS)
@@ -178,7 +181,7 @@ func TestDualStackTCPListener(t *testing.T) {
        }
 
        for _, tt := range dualStackListenerTests {
-               if tt.wildcard && (testing.Short() || !*testExternal) {
+               if tt.wildcard && !*testExternal {
                        continue
                }
                switch runtime.GOOS {
index b82f3cee0b57d21fa83b77b7c1928135b982300d..54d9d16c99e69702b534533a440ff4a3f6b96de8 100644 (file)
@@ -280,7 +280,11 @@ func (l *UnixListener) AcceptUnix() (*UnixConn, error) {
        if l == nil || l.fd == nil {
                return nil, syscall.EINVAL
        }
-       fd, err := l.fd.accept(sockaddrToUnix)
+       toAddr := sockaddrToUnix
+       if l.fd.sotype == syscall.SOCK_SEQPACKET {
+               toAddr = sockaddrToUnixpacket
+       }
+       fd, err := l.fd.accept(toAddr)
        if err != nil {
                return nil, err
        }
index bb00f110fe97bd70334036c908e0796b33935ea9..4f6a54a560acab2f44c446983fbbe0702029b7cd 100644 (file)
@@ -5,13 +5,16 @@
 package net
 
 import (
+       "flag"
        "fmt"
        "testing"
 )
 
+var testDNSFlood = flag.Bool("dnsflood", false, "whether to test dns query flooding")
+
 func TestDNSThreadLimit(t *testing.T) {
-       if testing.Short() || !*testExternal {
-               t.Skip("skipping test to avoid external network")
+       if !*testDNSFlood {
+               t.Skip("test disabled; use -dnsflood to enable")
        }
 
        const N = 10000
index 9fa7ad664f48b6ab4e8fb61a8041bf1a69441f03..67c390283c7336349d714bef3c36d13126088a97 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin dragonfly freebsd linux netbsd openbsd
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package os
 
index e16d71a649262ea57713987d07777c95a66d97db..5ec07ee1b1b68d369c1798b6be27382bc2e9ebb1 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin dragonfly freebsd linux netbsd openbsd
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package os_test
 
index 6250349e5bad33715ac232e54aa93028ffb6f870..f281495e6b8e09ecc4eb144022f1fd4346282e28 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin dragonfly freebsd linux netbsd openbsd
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package os
 
index 491cc242bb27a0c150db5f8ea6736312be3ba5d1..4680036fddcc6eefc19db1cbff5b1bbe59ceb0e9 100644 (file)
@@ -12,6 +12,7 @@ import (
        "errors"
        "io"
        "os"
+       "path/filepath"
        "strconv"
        "sync"
        "syscall"
@@ -33,7 +34,8 @@ type Cmd struct {
        // Path is the path of the command to run.
        //
        // This is the only field that must be set to a non-zero
-       // value.
+       // value. If Path is relative, it is evaluated relative
+       // to Dir.
        Path string
 
        // Args holds command line arguments, including the command as Args[0].
@@ -84,7 +86,7 @@ type Cmd struct {
        // available after a call to Wait or Run.
        ProcessState *os.ProcessState
 
-       err             error // last error (from LookPath, stdin, stdout, stderr)
+       lookPathErr     error // LookPath error, if any.
        finished        bool  // when Wait was called
        childFiles      []*os.File
        closeAfterStart []io.Closer
@@ -96,8 +98,7 @@ type Cmd struct {
 // Command returns the Cmd struct to execute the named program with
 // the given arguments.
 //
-// It sets Path and Args in the returned structure and zeroes the
-// other fields.
+// It sets only the Path and Args in the returned structure.
 //
 // If name contains no path separators, Command uses LookPath to
 // resolve the path to a complete name if possible. Otherwise it uses
@@ -107,19 +108,22 @@ type Cmd struct {
 // followed by the elements of arg, so arg should not include the
 // command name itself. For example, Command("echo", "hello")
 func Command(name string, arg ...string) *Cmd {
-       aname, err := LookPath(name)
-       if err != nil {
-               aname = name
-       }
-       return &Cmd{
-               Path: aname,
+       cmd := &Cmd{
+               Path: name,
                Args: append([]string{name}, arg...),
-               err:  err,
        }
+       if filepath.Base(name) == name {
+               if lp, err := LookPath(name); err != nil {
+                       cmd.lookPathErr = err
+               } else {
+                       cmd.Path = lp
+               }
+       }
+       return cmd
 }
 
 // interfaceEqual protects against panics from doing equality tests on
-// two interfaces with non-comparable underlying types
+// two interfaces with non-comparable underlying types.
 func interfaceEqual(a, b interface{}) bool {
        defer func() {
                recover()
@@ -235,10 +239,10 @@ func (c *Cmd) Run() error {
 
 // Start starts the specified command but does not wait for it to complete.
 func (c *Cmd) Start() error {
-       if c.err != nil {
+       if c.lookPathErr != nil {
                c.closeDescriptors(c.closeAfterStart)
                c.closeDescriptors(c.closeAfterWait)
-               return c.err
+               return c.lookPathErr
        }
        if c.Process != nil {
                return errors.New("exec: already started")
index 32868fc7463b80e10cbfbb331b727b841a7796b9..06248925da28c3aa422ca71b50f78aa9eb368512 100644 (file)
@@ -48,6 +48,33 @@ func TestEcho(t *testing.T) {
        }
 }
 
+func TestCommandRelativeName(t *testing.T) {
+       // Run our own binary as a relative path
+       // (e.g. "_test/exec.test") our parent directory.
+       base := filepath.Base(os.Args[0]) // "exec.test"
+       dir := filepath.Dir(os.Args[0])   // "/tmp/go-buildNNNN/os/exec/_test"
+       if dir == "." {
+               t.Skip("skipping; running test at root somehow")
+       }
+       parentDir := filepath.Dir(dir) // "/tmp/go-buildNNNN/os/exec"
+       dirBase := filepath.Base(dir)  // "_test"
+       if dirBase == "." {
+               t.Skipf("skipping; unexpected shallow dir of %q", dir)
+       }
+
+       cmd := exec.Command(filepath.Join(dirBase, base), "-test.run=TestHelperProcess", "--", "echo", "foo")
+       cmd.Dir = parentDir
+       cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"}
+
+       out, err := cmd.Output()
+       if err != nil {
+               t.Errorf("echo: %v", err)
+       }
+       if g, e := string(out), "foo\n"; g != e {
+               t.Errorf("echo: want %q, got %q", e, g)
+       }
+}
+
 func TestCatStdin(t *testing.T) {
        // Cat, testing stdin and stdout.
        input := "Input string\nLine 2"
@@ -484,6 +511,8 @@ func TestHelperProcess(*testing.T) {
        switch runtime.GOOS {
        case "dragonfly", "freebsd", "netbsd", "openbsd":
                ofcmd = "fstat"
+       case "plan9":
+               ofcmd = "/bin/cat"
        }
 
        args := os.Args
@@ -574,6 +603,14 @@ func TestHelperProcess(*testing.T) {
                        // the cloned file descriptors that result from opening
                        // /dev/urandom.
                        // http://golang.org/issue/3955
+               case "plan9":
+                       // TODO(0intro): Determine why Plan 9 is leaking
+                       // file descriptors.
+                       // http://golang.org/issue/7118
+               case "solaris":
+                       // TODO(aram): This fails on Solaris because libc opens
+                       // its own files, as it sees fit. Darwin does the same,
+                       // see: http://golang.org/issue/2603
                default:
                        // Now verify that there are no other open fds.
                        var files []*os.File
@@ -585,7 +622,14 @@ func TestHelperProcess(*testing.T) {
                                }
                                if got := f.Fd(); got != wantfd {
                                        fmt.Printf("leaked parent file. fd = %d; want %d\n", got, wantfd)
-                                       out, _ := exec.Command(ofcmd, "-p", fmt.Sprint(os.Getpid())).CombinedOutput()
+                                       var args []string
+                                       switch runtime.GOOS {
+                                       case "plan9":
+                                               args = []string{fmt.Sprintf("/proc/%d/fd", os.Getpid())}
+                                       default:
+                                               args = []string{"-p", fmt.Sprint(os.Getpid())}
+                                       }
+                                       out, _ := exec.Command(ofcmd, args...).CombinedOutput()
                                        fmt.Print(string(out))
                                        os.Exit(1)
                                }
index 7ff2d201bcb51b6c5392af09c819ffad16608593..7b9dec7e8b50894c4d1a1b0ff9848465c59c7087 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin dragonfly freebsd linux netbsd openbsd
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package exec
 
index f1ab6deffdcc0cb5c8bb4bd9f1498a15e25d885b..051db664a894de54a5152c975b9572b83e57e46b 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin dragonfly freebsd linux netbsd openbsd
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package exec
 
index fb123aefbcc8229bc8569947c9f4369b781b559a..8a4d019d2f748ee4d45a513370b5a59c5a20f628 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin dragonfly freebsd linux netbsd openbsd windows
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
 
 package os
 
index 5572e628e6e497d03a8dee9f0c88a6e0000cb482..3c05b8f080625136d1692f5e4a35b245194afb47 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin dragonfly freebsd linux netbsd openbsd
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package os
 
index e6496558ca5ed95253e9e5912f92f77627eb5e1c..a804b81973135590061f07cd00db17c7a1a3e12b 100644 (file)
@@ -332,6 +332,8 @@ func rename(oldname, newname string) error {
        dirname := oldname[:lastIndex(oldname, '/')+1]
        if hasPrefix(newname, dirname) {
                newname = newname[len(dirname):]
+       } else {
+               return &LinkError{"rename", oldname, newname, ErrInvalid}
        }
 
        // If newname still contains slashes after removing the oldname
index 4a17877547dff0b158aad86e6bc644ed827a3057..441ad5384d70a20d3e75a7566789c69ed3d82d61 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin dragonfly freebsd linux netbsd openbsd windows
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
 
 package os
 
index 2a7b958a4b48b87f0b486ee28b97890a95c3abb9..33588421dc0df7f647d821ff636abab0ca7558c1 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin dragonfly freebsd linux netbsd openbsd
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package os
 
index 43d4677b0dd2507603b6a3ab2e5ce6f03f03a36d..0392b06c4094a8cf7c9e5e5ef6f5c26a22414278 100644 (file)
@@ -394,11 +394,12 @@ func touch(t *testing.T, name string) {
 }
 
 func TestReaddirStatFailures(t *testing.T) {
-       if runtime.GOOS == "windows" {
-               // Windows already does this correctly, but is
-               // structured with different syscalls such that it
-               // doesn't use Lstat, so the hook below for testing it
-               // wouldn't work.
+       switch runtime.GOOS {
+       case "windows", "plan9":
+               // Windows and Plan 9 already do this correctly,
+               // but are structured with different syscalls such
+               // that they don't use Lstat, so the hook below for
+               // testing it wouldn't work.
                t.Skipf("skipping test on %v", runtime.GOOS)
        }
        dir, err := ioutil.TempDir("", "")
index 1e8a66122503f4703fdabbe0e0fd8c898eeead5c..21d40ccaf848c9b8cfe50a61008a3b0c88afe910 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin dragonfly freebsd linux netbsd openbsd
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package os_test
 
index 3bf63bf8042f3f2452fafcc265a7e552cd971ae6..bdf9fe642187b58548a85e414fc8807251faea75 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin dragonfly freebsd linux netbsd openbsd
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package os
 
index 73d35b4d5ebaf66a1c9e14878d19fb40e5864c1f..0ea8e4b1f83cd531219e1085de4e41bf60e0dc6d 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin dragonfly freebsd netbsd openbsd
+// +build darwin dragonfly freebsd netbsd openbsd solaris
 
 package os
 
index 741f2a0edfcf49f63e1b7ae38819035328b78b87..076fe3f93bd1fcd53220e66c8dba75e218d1d071 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin dragonfly freebsd linux netbsd openbsd
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package signal
 
index 318488dc04acb86b8187641f608152784507514b..80dc4304aaa4d625586ecb0c8f35bca5cf21b0e4 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin dragonfly freebsd linux netbsd openbsd windows
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
 
 package signal
 
index e4622b9371150698088783ed423c597f2705b7c1..3e88bd829e656a28d20a1d3b6b5f3f1683d28f62 100644 (file)
@@ -24,8 +24,10 @@ func fileInfoFromStat(st *syscall.Stat_t, name string) FileInfo {
        }
        fs.mode = FileMode(st.Mode & 0777)
        switch st.Mode & syscall.S_IFMT {
-       case syscall.S_IFBLK, syscall.S_IFCHR:
+       case syscall.S_IFBLK:
                fs.mode |= ModeDevice
+       case syscall.S_IFCHR:
+               fs.mode |= ModeDevice | ModeCharDevice
        case syscall.S_IFDIR:
                fs.mode |= ModeDir
        case syscall.S_IFIFO:
@@ -43,6 +45,9 @@ func fileInfoFromStat(st *syscall.Stat_t, name string) FileInfo {
        if st.Mode&syscall.S_ISUID != 0 {
                fs.mode |= ModeSetuid
        }
+       if st.Mode&syscall.S_ISVTX != 0 {
+               fs.mode |= ModeSticky
+       }
        return fs
 }
 
index 2d309ed33300fb22eb644b5be4c5e517baf340df..0db08067201f5167067268d5d72ba3ef9579103e 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin dragonfly freebsd linux netbsd openbsd
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
 // +build cgo
 
 package user
index d927b342be0bdba869d84684d5e0d32192e9e287..2be675c3af1dc0b89765a5787507c67c7394903e 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin dragonfly freebsd linux netbsd openbsd
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package filepath
 
index 03ddd49f008bd282963e02212d4203ffe3b19d28..b248743de70e247a43d8385ad8c17d99ad7a13af 100644 (file)
@@ -113,7 +113,7 @@ func makeMethodValue(op string, v Value) Value {
        // Cause panic if method is not appropriate.
        // The panic would still happen during the call if we omit this,
        // but we want Interface() and other operations to fail early.
-       t, _, _ := methodReceiver(op, rcvr, int(v.flag)>>flagMethodShift)
+       t, _ := methodReceiver(op, rcvr, int(v.flag)>>flagMethodShift)
 
        fv := &makeFuncImpl{
                code:   code,
index 46cd3ad5144b83e5a2d1a287f7c19ea35074fa5b..7809fb01f2326494421f8789ca2d31f039d71413 100644 (file)
@@ -127,17 +127,16 @@ func MakeFuncStubGo(regs *i386Regs, c *makeFuncImpl) {
        }
 
        v := out[0]
-       w := v.iword()
        switch v.Kind() {
        case Ptr, UnsafePointer:
-               regs.eax = uint32(uintptr(w))
+               regs.eax = uint32(uintptr(v.pointer()))
        case Float32:
-               regs.st0 = float64(*(*float32)(unsafe.Pointer(w)))
+               regs.st0 = float64(*(*float32)(v.ptr))
                regs.sf = true
        case Float64:
-               regs.st0 = *(*float64)(unsafe.Pointer(w))
+               regs.st0 = *(*float64)(v.ptr)
                regs.sf = true
        default:
-               regs.eax = uint32(loadScalar(unsafe.Pointer(w), v.typ.size))
+               regs.eax = uint32(loadScalar(v.ptr, v.typ.size))
        }
 }
index ad1893a8e997b0da47d01caf5eefe3afd280a70c..7118951d1fd98c6624a9bf67cf80bee55b0394cf 100644 (file)
@@ -363,9 +363,11 @@ argloop:
 
        if len(out) == 1 && ret2 == amd64NoClass {
                v := out[0]
-               w := v.iword()
-               if v.Kind() != Ptr && v.Kind() != UnsafePointer {
-                       w = iword(loadScalar(unsafe.Pointer(w), v.typ.size))
+               var w unsafe.Pointer
+               if v.Kind() == Ptr || v.Kind() == UnsafePointer {
+                       w = v.pointer()
+               } else {
+                       w = unsafe.Pointer(loadScalar(v.ptr, v.typ.size))
                }
                switch ret1 {
                case amd64Integer:
index 877bfac6d245a32548e356df70aea165311792f1..64081b9ea515567e5bccd4dd7ff931def396561d 100644 (file)
@@ -216,52 +216,11 @@ func methodName() string {
 // bigger than a pointer, its word is a pointer to v's data.
 // Otherwise, its word holds the data stored
 // in its leading bytes (so is not a pointer).
-// Because the value sometimes holds a pointer, we use
-// unsafe.Pointer to represent it, so that if iword appears
-// in a struct, the garbage collector knows that might be
-// a pointer.
-// TODO: get rid of all occurrences of iword (except in the interface decls below?)
-// We want to get rid of the "feature" that an unsafe.Pointer is sometimes a pointer
-// and sometimes a uintptr.
+// This type is very dangerous for the garbage collector because
+// it must be treated conservatively.  We try to never expose it
+// to the GC here so that GC remains precise.
 type iword unsafe.Pointer
 
-// Get an iword that represents this value.
-// TODO: this function goes away at some point
-func (v Value) iword() iword {
-       t := v.typ
-       if t == nil {
-               return iword(nil)
-       }
-       if v.flag&flagIndir != 0 {
-               if v.kind() != Ptr && v.kind() != UnsafePointer {
-                       return iword(v.ptr)
-               }
-               // Have indirect but want direct word.
-               if t.pointers() {
-                       return iword(*(*unsafe.Pointer)(v.ptr))
-               }
-               return iword(loadScalar(v.ptr, v.typ.size))
-       }
-       if t.pointers() {
-               return iword(v.ptr)
-       }
-       // return iword(v.scalar)
-       panic("reflect: missing flagIndir")
-}
-
-// Build a Value from a type/iword pair, plus any extra flags.
-// TODO: this function goes away at some point
-func fromIword(t *rtype, w iword, fl flag) Value {
-       fl |= flag(t.Kind()) << flagKindShift
-       if t.Kind() != Ptr && t.Kind() != UnsafePointer {
-               return Value{t, unsafe.Pointer(w) /* 0, */, fl | flagIndir}
-       } else if t.pointers() {
-               return Value{t, unsafe.Pointer(w) /* 0, */, fl}
-       } else {
-               panic("reflect: can't reach")
-       }
-}
-
 // loadScalar loads n bytes at p from memory into a uintptr
 // that forms the second word of an interface.  The data
 // must be non-pointer in nature.
@@ -473,11 +432,14 @@ func (v Value) call(op string, in []Value) []Value {
        // Get function pointer, type.
        t := v.typ
        var (
-               fn   unsafe.Pointer
-               rcvr iword
+               fn       unsafe.Pointer
+               rcvr     Value
+               rcvrtype *rtype
        )
        if v.flag&flagMethod != 0 {
-               t, fn, rcvr = methodReceiver(op, v, int(v.flag)>>flagMethodShift)
+               rcvrtype = t
+               rcvr = v
+               t, fn = methodReceiver(op, v, int(v.flag)>>flagMethodShift)
        } else if v.flag&flagIndir != 0 {
                fn = *(*unsafe.Pointer)(v.ptr)
        } else {
@@ -564,8 +526,14 @@ func (v Value) call(op string, in []Value) []Value {
        off := 0
        if v.flag&flagMethod != 0 {
                // Hard-wired first argument.
-               p := new(iword)
-               *p = rcvr
+               p := new(unsafe.Pointer)
+               if rcvr.typ.Kind() == Interface {
+                       *p = unsafe.Pointer((*nonEmptyInterface)(v.ptr).word)
+               } else if rcvr.typ.Kind() == Ptr || rcvr.typ.Kind() == UnsafePointer {
+                       *p = rcvr.pointer()
+               } else {
+                       *p = rcvr.ptr
+               }
                params[0] = unsafe.Pointer(p)
                off = 1
        }
@@ -614,7 +582,9 @@ func (v Value) call(op string, in []Value) []Value {
 // described by v. The Value v may or may not have the
 // flagMethod bit set, so the kind cached in v.flag should
 // not be used.
-func methodReceiver(op string, v Value, methodIndex int) (t *rtype, fn unsafe.Pointer, rcvr iword) {
+// The return value t gives the method type signature (without the receiver).
+// The return value fn is a pointer to the method code.
+func methodReceiver(op string, v Value, methodIndex int) (t *rtype, fn unsafe.Pointer) {
        i := methodIndex
        if v.typ.Kind() == Interface {
                tt := (*interfaceType)(unsafe.Pointer(v.typ))
@@ -625,13 +595,12 @@ func methodReceiver(op string, v Value, methodIndex int) (t *rtype, fn unsafe.Po
                if m.pkgPath != nil {
                        panic("reflect: " + op + " of unexported method")
                }
-               t = m.typ
                iface := (*nonEmptyInterface)(v.ptr)
                if iface.itab == nil {
                        panic("reflect: " + op + " of method on nil interface value")
                }
                fn = unsafe.Pointer(&iface.itab.fun[i])
-               rcvr = iface.word
+               t = m.typ
        } else {
                ut := v.typ.uncommon()
                if ut == nil || i < 0 || i >= len(ut.methods) {
@@ -643,15 +612,34 @@ func methodReceiver(op string, v Value, methodIndex int) (t *rtype, fn unsafe.Po
                }
                fn = unsafe.Pointer(&m.tfn)
                t = m.mtyp
-               // Can't call iword here, because it checks v.kind,
-               // and that is always Func.
-               if v.flag&flagIndir != 0 && (v.typ.Kind() == Ptr || v.typ.Kind() == UnsafePointer) {
-                       rcvr = iword(loadScalar(v.ptr, v.typ.size))
+       }
+       return
+}
+
+// v is a method receiver.  Store at p the word which is used to
+// encode that receiver at the start of the argument list.
+// Reflect uses the "interface" calling convention for
+// methods, which always uses one word to record the receiver.
+func storeRcvr(v Value, p unsafe.Pointer) {
+       t := v.typ
+       if t.Kind() == Interface {
+               // the interface data word becomes the receiver word
+               iface := (*nonEmptyInterface)(v.ptr)
+               *(*unsafe.Pointer)(p) = unsafe.Pointer(iface.word)
+       } else if v.flag&flagIndir != 0 {
+               if t.size > ptrSize {
+                       *(*unsafe.Pointer)(p) = v.ptr
+               } else if t.pointers() {
+                       *(*unsafe.Pointer)(p) = *(*unsafe.Pointer)(v.ptr)
                } else {
-                       rcvr = iword(v.ptr)
+                       *(*uintptr)(p) = loadScalar(v.ptr, t.size)
                }
+       } else if t.pointers() {
+               *(*unsafe.Pointer)(p) = v.ptr
+       } else {
+               // *(*uintptr)(p) = v.scalar
+               panic("reflect: missing flagIndir")
        }
-       return
 }
 
 // align returns the result of rounding x up to a multiple of n.
@@ -1000,24 +988,6 @@ func valueInterface(v Value, safe bool) interface{} {
                })(v.ptr)
        }
 
-       // Non-interface value.
-       var eface emptyInterface
-       eface.typ = toType(v.typ).common()
-       eface.word = v.iword()
-
-       // Don't need to allocate if v is not addressable or fits in one word.
-       if v.flag&flagAddr != 0 && v.kind() != Ptr && v.kind() != UnsafePointer {
-               // eface.word is a pointer to the actual data,
-               // which might be changed.  We need to return
-               // a pointer to unchanging data, so make a copy.
-               ptr := unsafe_New(v.typ)
-               memmove(ptr, unsafe.Pointer(eface.word), v.typ.size)
-               eface.word = iword(ptr)
-       }
-
-       if v.flag&flagIndir == 0 && v.kind() != Ptr && v.kind() != UnsafePointer {
-               panic("missing flagIndir")
-       }
        // TODO: pass safe to packEface so we don't need to copy if safe==true?
        return packEface(v)
 }
@@ -1035,8 +1005,13 @@ func (v Value) InterfaceData() [2]uintptr {
        return *(*[2]uintptr)(v.ptr)
 }
 
-// IsNil returns true if v is a nil value.
-// It panics if v's Kind is not Chan, Func, Interface, Map, Ptr, or Slice.
+// IsNil reports whether its argument v is nil. The argument must be
+// a chan, func, interface, map, pointer, or slice value; if it is
+// not, IsNil panics. Note that IsNil is not always equivalent to a
+// regular comparison with nil in Go. For example, if v was created
+// by calling ValueOf with an uninitialized interface variable i,
+// i==nil will be true but v.IsNil will panic as v will be the zero
+// Value.
 func (v Value) IsNil() bool {
        k := v.kind()
        switch k {
@@ -1366,9 +1341,19 @@ func (v Value) recv(nb bool) (val Value, ok bool) {
        if ChanDir(tt.dir)&RecvDir == 0 {
                panic("reflect: recv on send-only channel")
        }
-       word, selected, ok := chanrecv(v.typ, v.pointer(), nb)
-       if selected {
-               val = fromIword(tt.elem, word, 0)
+       t := tt.elem
+       val = Value{t, nil /* 0, */, flag(t.Kind()) << flagKindShift}
+       var p unsafe.Pointer
+       if t.Kind() != Ptr && t.Kind() != UnsafePointer {
+               p = unsafe_New(t)
+               val.ptr = p
+               val.flag |= flagIndir
+       } else {
+               p = unsafe.Pointer(&val.ptr)
+       }
+       selected, ok := chanrecv(v.typ, v.pointer(), nb, p)
+       if !selected {
+               val = Value{}
        }
        return
 }
@@ -1391,7 +1376,16 @@ func (v Value) send(x Value, nb bool) (selected bool) {
        }
        x.mustBeExported()
        x = x.assignTo("reflect.Value.Send", tt.elem, nil)
-       return chansend(v.typ, v.pointer(), x.iword(), nb)
+       var p unsafe.Pointer
+       if x.flag&flagIndir != 0 {
+               p = x.ptr
+       } else if x.typ.pointers() {
+               p = unsafe.Pointer(&x.ptr)
+       } else {
+               // p = unsafe.Pointer(&x.scalar)
+               panic("reflect: missing flagIndir")
+       }
+       return chansend(v.typ, v.pointer(), p, nb)
 }
 
 // Set assigns x to the value v.
@@ -1714,9 +1708,9 @@ func (v Value) String() string {
 
 // TryRecv attempts to receive a value from the channel v but will not block.
 // It panics if v's Kind is not Chan.
-// If the receive cannot finish without blocking, x is the zero Value.
-// The boolean ok is true if the value x corresponds to a send
-// on the channel, false if it is a zero value received because the channel is closed.
+// If the receive delivers a value, x is the transferred value and ok is true.
+// If the receive cannot finish without blocking, x is the zero Value and ok is false.
+// If the channel is closed, x is the zero value for the channel's element type and ok is false.
 func (v Value) TryRecv() (x Value, ok bool) {
        v.mustBe(Chan)
        v.mustBeExported()
@@ -1964,17 +1958,18 @@ func Copy(dst, src Value) int {
 // A runtimeSelect is a single case passed to rselect.
 // This must match ../runtime/chan.c:/runtimeSelect
 type runtimeSelect struct {
-       dir uintptr // 0, SendDir, or RecvDir
-       typ *rtype  // channel type
-       ch  iword   // interface word for channel
-       val iword   // interface word for value (for SendDir)
+       dir uintptr        // 0, SendDir, or RecvDir
+       typ *rtype         // channel type
+       ch  unsafe.Pointer // channel
+       val unsafe.Pointer // ptr to data (SendDir) or ptr to receive buffer (RecvDir)
 }
 
-// rselect runs a select. It returns the index of the chosen case,
-// and if the case was a receive, the interface word of the received
-// value and the conventional OK bool to indicate whether the receive
-// corresponds to a sent value.
-func rselect([]runtimeSelect) (chosen int, recv iword, recvOK bool)
+// rselect runs a select.  It returns the index of the chosen case.
+// If the case was a receive, val is filled in with the received value.
+// The conventional OK bool indicates whether the receive corresponds
+// to a sent value.
+//go:noescape
+func rselect([]runtimeSelect) (chosen int, recvOK bool)
 
 // A SelectDir describes the communication direction of a select case.
 type SelectDir int
@@ -2054,7 +2049,7 @@ func Select(cases []SelectCase) (chosen int, recv Value, recvOK bool) {
                        if ChanDir(tt.dir)&SendDir == 0 {
                                panic("reflect.Select: SendDir case using recv-only channel")
                        }
-                       rc.ch = *(*iword)(ch.iword())
+                       rc.ch = ch.pointer()
                        rc.typ = &tt.rtype
                        v := c.Send
                        if !v.IsValid() {
@@ -2062,7 +2057,14 @@ func Select(cases []SelectCase) (chosen int, recv Value, recvOK bool) {
                        }
                        v.mustBeExported()
                        v = v.assignTo("reflect.Select", tt.elem, nil)
-                       rc.val = v.iword()
+                       if v.flag&flagIndir != 0 {
+                               rc.val = v.ptr
+                       } else if v.typ.pointers() {
+                               rc.val = unsafe.Pointer(&v.ptr)
+                       } else {
+                               // rc.val = unsafe.Pointer(&v.scalar)
+                               panic("reflect: missing flagIndir")
+                       }
 
                case SelectRecv:
                        if c.Send.IsValid() {
@@ -2075,18 +2077,26 @@ func Select(cases []SelectCase) (chosen int, recv Value, recvOK bool) {
                        ch.mustBe(Chan)
                        ch.mustBeExported()
                        tt := (*chanType)(unsafe.Pointer(ch.typ))
-                       rc.typ = &tt.rtype
                        if ChanDir(tt.dir)&RecvDir == 0 {
                                panic("reflect.Select: RecvDir case using send-only channel")
                        }
-                       rc.ch = *(*iword)(ch.iword())
+                       rc.ch = ch.pointer()
+                       rc.typ = &tt.rtype
+                       rc.val = unsafe_New(tt.elem)
                }
        }
 
-       chosen, word, recvOK := rselect(runcases)
+       chosen, recvOK = rselect(runcases)
        if runcases[chosen].dir == uintptr(SelectRecv) {
                tt := (*chanType)(unsafe.Pointer(runcases[chosen].typ))
-               recv = fromIword(tt.elem, word, 0)
+               t := tt.elem
+               p := runcases[chosen].val
+               fl := flag(t.Kind()) << flagKindShift
+               if t.Kind() != Ptr && t.Kind() != UnsafePointer {
+                       recv = Value{t, p /* 0, */, fl | flagIndir}
+               } else {
+                       recv = Value{t, *(*unsafe.Pointer)(p) /* 0, */, fl}
+               }
        }
        return chosen, recv, recvOK
 }
@@ -2539,8 +2549,12 @@ func cvtI2I(v Value, typ Type) Value {
 func chancap(ch unsafe.Pointer) int
 func chanclose(ch unsafe.Pointer)
 func chanlen(ch unsafe.Pointer) int
-func chanrecv(t *rtype, ch unsafe.Pointer, nb bool) (val iword, selected, received bool)
-func chansend(t *rtype, ch unsafe.Pointer, val iword, nb bool) bool
+
+//go:noescape
+func chanrecv(t *rtype, ch unsafe.Pointer, nb bool, val unsafe.Pointer) (selected, received bool)
+
+//go:noescape
+func chansend(t *rtype, ch unsafe.Pointer, val unsafe.Pointer, nb bool) bool
 
 func makechan(typ *rtype, size uint64) (ch unsafe.Pointer)
 func makemap(t *rtype) (m unsafe.Pointer)
index 0046026eaebdcfe1c8ed14525c3c451ad07aa7aa..6ce5902a5aa1311d5ac31b6ab03af99e4992e5ba 100644 (file)
@@ -70,7 +70,6 @@ import (
 var debug = false
 
 // Regexp is the representation of a compiled regular expression.
-// The public interface is entirely through methods.
 // A Regexp is safe for concurrent use by multiple goroutines.
 type Regexp struct {
        // read-only after Compile
index 269d6c3b87409f027932d34397c7b0823b1864f0..f3089294c6aa782d2d0acb055fd0476728336988 100644 (file)
@@ -100,12 +100,12 @@ var parseTests = []parseTest{
        {`\P{Braille}`, `cc{0x0-0x27ff 0x2900-0x10ffff}`},
        {`\p{^Braille}`, `cc{0x0-0x27ff 0x2900-0x10ffff}`},
        {`\P{^Braille}`, `cc{0x2800-0x28ff}`},
-       {`\pZ`, `cc{0x20 0xa0 0x1680 0x180e 0x2000-0x200a 0x2028-0x2029 0x202f 0x205f 0x3000}`},
+       {`\pZ`, `cc{0x20 0xa0 0x1680 0x2000-0x200a 0x2028-0x2029 0x202f 0x205f 0x3000}`},
        {`[\p{Braille}]`, `cc{0x2800-0x28ff}`},
        {`[\P{Braille}]`, `cc{0x0-0x27ff 0x2900-0x10ffff}`},
        {`[\p{^Braille}]`, `cc{0x0-0x27ff 0x2900-0x10ffff}`},
        {`[\P{^Braille}]`, `cc{0x2800-0x28ff}`},
-       {`[\pZ]`, `cc{0x20 0xa0 0x1680 0x180e 0x2000-0x200a 0x2028-0x2029 0x202f 0x205f 0x3000}`},
+       {`[\pZ]`, `cc{0x20 0xa0 0x1680 0x2000-0x200a 0x2028-0x2029 0x202f 0x205f 0x3000}`},
        {`\p{Lu}`, mkCharClass(unicode.IsUpper)},
        {`[\p{Lu}]`, mkCharClass(unicode.IsUpper)},
        {`(?i)[\p{Lu}]`, mkCharClass(isUpperFold)},
index 937c8259fdd8503f31394fa76cb8031b64d9e1e1..a67dc9b494829fe68b529485d8a1b5e03ca4e528 100644 (file)
@@ -19,6 +19,25 @@ func BenchmarkAppend(b *testing.B) {
        }
 }
 
+func BenchmarkAppendGrowByte(b *testing.B) {
+       for i := 0; i < b.N; i++ {
+               var x []byte
+               for j := 0; j < 1<<20; j++ {
+                       x = append(x, byte(j))
+               }
+       }
+}
+
+func BenchmarkAppendGrowString(b *testing.B) {
+       var s string
+       for i := 0; i < b.N; i++ {
+               var x []string
+               for j := 0; j < 1<<20; j++ {
+                       x = append(x, s)
+               }
+       }
+}
+
 func benchmarkAppendBytes(b *testing.B, length int) {
        b.StopTimer()
        x := make([]byte, 0, N)
index eb2c7c60d0cdc0bdeeee8924fa2296b27268d0eb..782176c883639152035cbfe0a8da8c180043c935 100644 (file)
@@ -9,8 +9,327 @@ import (
        "sync"
        "sync/atomic"
        "testing"
+       "time"
 )
 
+func TestChan(t *testing.T) {
+       defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
+       N := 200
+       if testing.Short() {
+               N = 20
+       }
+       for chanCap := 0; chanCap < N; chanCap++ {
+               {
+                       // Ensure that receive from empty chan blocks.
+                       c := make(chan int, chanCap)
+                       recv1 := false
+                       go func() {
+                               _ = <-c
+                               recv1 = true
+                       }()
+                       recv2 := false
+                       go func() {
+                               _, _ = <-c
+                               recv2 = true
+                       }()
+                       time.Sleep(time.Millisecond)
+                       if recv1 || recv2 {
+                               t.Fatalf("chan[%d]: receive from empty chan", chanCap)
+                       }
+                       // Ensure that non-blocking receive does not block.
+                       select {
+                       case _ = <-c:
+                               t.Fatalf("chan[%d]: receive from empty chan", chanCap)
+                       default:
+                       }
+                       select {
+                       case _, _ = <-c:
+                               t.Fatalf("chan[%d]: receive from empty chan", chanCap)
+                       default:
+                       }
+                       c <- 0
+                       c <- 0
+               }
+
+               {
+                       // Ensure that send to full chan blocks.
+                       c := make(chan int, chanCap)
+                       for i := 0; i < chanCap; i++ {
+                               c <- i
+                       }
+                       sent := uint32(0)
+                       go func() {
+                               c <- 0
+                               atomic.StoreUint32(&sent, 1)
+                       }()
+                       time.Sleep(time.Millisecond)
+                       if atomic.LoadUint32(&sent) != 0 {
+                               t.Fatalf("chan[%d]: send to full chan", chanCap)
+                       }
+                       // Ensure that non-blocking send does not block.
+                       select {
+                       case c <- 0:
+                               t.Fatalf("chan[%d]: send to full chan", chanCap)
+                       default:
+                       }
+                       <-c
+               }
+
+               {
+                       // Ensure that we receive 0 from closed chan.
+                       c := make(chan int, chanCap)
+                       for i := 0; i < chanCap; i++ {
+                               c <- i
+                       }
+                       close(c)
+                       for i := 0; i < chanCap; i++ {
+                               v := <-c
+                               if v != i {
+                                       t.Fatalf("chan[%d]: received %v, expected %v", chanCap, v, i)
+                               }
+                       }
+                       if v := <-c; v != 0 {
+                               t.Fatalf("chan[%d]: received %v, expected %v", chanCap, v, 0)
+                       }
+                       if v, ok := <-c; v != 0 || ok {
+                               t.Fatalf("chan[%d]: received %v/%v, expected %v/%v", chanCap, v, ok, 0, false)
+                       }
+               }
+
+               {
+                       // Ensure that close unblocks receive.
+                       c := make(chan int, chanCap)
+                       done := make(chan bool)
+                       go func() {
+                               v, ok := <-c
+                               done <- v == 0 && ok == false
+                       }()
+                       time.Sleep(time.Millisecond)
+                       close(c)
+                       if !<-done {
+                               t.Fatalf("chan[%d]: received non zero from closed chan", chanCap)
+                       }
+               }
+
+               {
+                       // Send 100 integers,
+                       // ensure that we receive them non-corrupted in FIFO order.
+                       c := make(chan int, chanCap)
+                       go func() {
+                               for i := 0; i < 100; i++ {
+                                       c <- i
+                               }
+                       }()
+                       for i := 0; i < 100; i++ {
+                               v := <-c
+                               if v != i {
+                                       t.Fatalf("chan[%d]: received %v, expected %v", chanCap, v, i)
+                               }
+                       }
+
+                       // Same, but using recv2.
+                       go func() {
+                               for i := 0; i < 100; i++ {
+                                       c <- i
+                               }
+                       }()
+                       for i := 0; i < 100; i++ {
+                               v, ok := <-c
+                               if !ok {
+                                       t.Fatalf("chan[%d]: receive failed, expected %v", chanCap, i)
+                               }
+                               if v != i {
+                                       t.Fatalf("chan[%d]: received %v, expected %v", chanCap, v, i)
+                               }
+                       }
+
+                       // Send 1000 integers in 4 goroutines,
+                       // ensure that we receive what we send.
+                       const P = 4
+                       const L = 1000
+                       for p := 0; p < P; p++ {
+                               go func() {
+                                       for i := 0; i < L; i++ {
+                                               c <- i
+                                       }
+                               }()
+                       }
+                       done := make(chan map[int]int)
+                       for p := 0; p < P; p++ {
+                               go func() {
+                                       recv := make(map[int]int)
+                                       for i := 0; i < L; i++ {
+                                               v := <-c
+                                               recv[v] = recv[v] + 1
+                                       }
+                                       done <- recv
+                               }()
+                       }
+                       recv := make(map[int]int)
+                       for p := 0; p < P; p++ {
+                               for k, v := range <-done {
+                                       recv[k] = recv[k] + v
+                               }
+                       }
+                       if len(recv) != L {
+                               t.Fatalf("chan[%d]: received %v values, expected %v", chanCap, len(recv), L)
+                       }
+                       for _, v := range recv {
+                               if v != P {
+                                       t.Fatalf("chan[%d]: received %v values, expected %v", chanCap, v, P)
+                               }
+                       }
+               }
+
+               {
+                       // Test len/cap.
+                       c := make(chan int, chanCap)
+                       if len(c) != 0 || cap(c) != chanCap {
+                               t.Fatalf("chan[%d]: bad len/cap, expect %v/%v, got %v/%v", chanCap, 0, chanCap, len(c), cap(c))
+                       }
+                       for i := 0; i < chanCap; i++ {
+                               c <- i
+                       }
+                       if len(c) != chanCap || cap(c) != chanCap {
+                               t.Fatalf("chan[%d]: bad len/cap, expect %v/%v, got %v/%v", chanCap, chanCap, chanCap, len(c), cap(c))
+                       }
+               }
+
+       }
+}
+
+func TestSelfSelect(t *testing.T) {
+       // Ensure that send/recv on the same chan in select
+       // does not crash nor deadlock.
+       defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(2))
+       for _, chanCap := range []int{0, 10} {
+               var wg sync.WaitGroup
+               wg.Add(2)
+               c := make(chan int, chanCap)
+               for p := 0; p < 2; p++ {
+                       p := p
+                       go func() {
+                               defer wg.Done()
+                               for i := 0; i < 1000; i++ {
+                                       if p == 0 || i%2 == 0 {
+                                               select {
+                                               case c <- p:
+                                               case v := <-c:
+                                                       if chanCap == 0 && v == p {
+                                                               t.Fatalf("self receive")
+                                                       }
+                                               }
+                                       } else {
+                                               select {
+                                               case v := <-c:
+                                                       if chanCap == 0 && v == p {
+                                                               t.Fatalf("self receive")
+                                                       }
+                                               case c <- p:
+                                               }
+                                       }
+                               }
+                       }()
+               }
+               wg.Wait()
+       }
+}
+
+func TestSelectStress(t *testing.T) {
+       defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(10))
+       var c [4]chan int
+       c[0] = make(chan int)
+       c[1] = make(chan int)
+       c[2] = make(chan int, 2)
+       c[3] = make(chan int, 3)
+       N := int(1e5)
+       if testing.Short() {
+               N /= 10
+       }
+       // There are 4 goroutines that send N values on each of the chans,
+       // + 4 goroutines that receive N values on each of the chans,
+       // + 1 goroutine that sends N values on each of the chans in a single select,
+       // + 1 goroutine that receives N values on each of the chans in a single select.
+       // All these sends, receives and selects interact chaotically at runtime,
+       // but we are careful that this whole construct does not deadlock.
+       var wg sync.WaitGroup
+       wg.Add(10)
+       for k := 0; k < 4; k++ {
+               k := k
+               go func() {
+                       for i := 0; i < N; i++ {
+                               c[k] <- 0
+                       }
+                       wg.Done()
+               }()
+               go func() {
+                       for i := 0; i < N; i++ {
+                               <-c[k]
+                       }
+                       wg.Done()
+               }()
+       }
+       go func() {
+               var n [4]int
+               c1 := c
+               for i := 0; i < 4*N; i++ {
+                       select {
+                       case c1[3] <- 0:
+                               n[3]++
+                               if n[3] == N {
+                                       c1[3] = nil
+                               }
+                       case c1[2] <- 0:
+                               n[2]++
+                               if n[2] == N {
+                                       c1[2] = nil
+                               }
+                       case c1[0] <- 0:
+                               n[0]++
+                               if n[0] == N {
+                                       c1[0] = nil
+                               }
+                       case c1[1] <- 0:
+                               n[1]++
+                               if n[1] == N {
+                                       c1[1] = nil
+                               }
+                       }
+               }
+               wg.Done()
+       }()
+       go func() {
+               var n [4]int
+               c1 := c
+               for i := 0; i < 4*N; i++ {
+                       select {
+                       case <-c1[0]:
+                               n[0]++
+                               if n[0] == N {
+                                       c1[0] = nil
+                               }
+                       case <-c1[1]:
+                               n[1]++
+                               if n[1] == N {
+                                       c1[1] = nil
+                               }
+                       case <-c1[2]:
+                               n[2]++
+                               if n[2] == N {
+                                       c1[2] = nil
+                               }
+                       case <-c1[3]:
+                               n[3]++
+                               if n[3] == N {
+                                       c1[3] = nil
+                               }
+                       }
+               }
+               wg.Done()
+       }()
+       wg.Wait()
+}
+
 func TestChanSendInterface(t *testing.T) {
        type mt struct{}
        m := &mt{}
@@ -29,34 +348,35 @@ func TestChanSendInterface(t *testing.T) {
 
 func TestPseudoRandomSend(t *testing.T) {
        n := 100
-       c := make(chan int)
-       l := make([]int, n)
-       var m sync.Mutex
-       m.Lock()
-       go func() {
+       for _, chanCap := range []int{0, n} {
+               c := make(chan int, chanCap)
+               l := make([]int, n)
+               var m sync.Mutex
+               m.Lock()
+               go func() {
+                       for i := 0; i < n; i++ {
+                               runtime.Gosched()
+                               l[i] = <-c
+                       }
+                       m.Unlock()
+               }()
                for i := 0; i < n; i++ {
-                       runtime.Gosched()
-                       l[i] = <-c
+                       select {
+                       case c <- 1:
+                       case c <- 0:
+                       }
                }
-               m.Unlock()
-       }()
-       for i := 0; i < n; i++ {
-               select {
-               case c <- 0:
-               case c <- 1:
+               m.Lock() // wait
+               n0 := 0
+               n1 := 0
+               for _, i := range l {
+                       n0 += (i + 1) % 2
+                       n1 += i
                }
-       }
-       m.Lock() // wait
-       n0 := 0
-       n1 := 0
-       for _, i := range l {
-               n0 += (i + 1) % 2
-               n1 += i
-               if n0 > n/10 && n1 > n/10 {
-                       return
+               if n0 <= n/10 || n1 <= n/10 {
+                       t.Errorf("Want pseudorandom, got %d zeros and %d ones (chan cap %d)", n0, n1, chanCap)
                }
        }
-       t.Errorf("Want pseudo random, got %d zeros and %d ones", n0, n1)
 }
 
 func TestMultiConsumer(t *testing.T) {
@@ -110,23 +430,19 @@ func TestMultiConsumer(t *testing.T) {
        }
 }
 
-func BenchmarkSelectUncontended(b *testing.B) {
+func BenchmarkChanNonblocking(b *testing.B) {
        const CallsPerSched = 1000
        procs := runtime.GOMAXPROCS(-1)
        N := int32(b.N / CallsPerSched)
        c := make(chan bool, procs)
+       myc := make(chan int)
        for p := 0; p < procs; p++ {
                go func() {
-                       myc1 := make(chan int, 1)
-                       myc2 := make(chan int, 1)
-                       myc1 <- 0
                        for atomic.AddInt32(&N, -1) >= 0 {
                                for g := 0; g < CallsPerSched; g++ {
                                        select {
-                                       case <-myc1:
-                                               myc2 <- 0
-                                       case <-myc2:
-                                               myc1 <- 0
+                                       case <-myc:
+                                       default:
                                        }
                                }
                        }
@@ -138,119 +454,94 @@ func BenchmarkSelectUncontended(b *testing.B) {
        }
 }
 
+func BenchmarkSelectUncontended(b *testing.B) {
+       b.RunParallel(func(pb *testing.PB) {
+               myc1 := make(chan int, 1)
+               myc2 := make(chan int, 1)
+               myc1 <- 0
+               for pb.Next() {
+                       select {
+                       case <-myc1:
+                               myc2 <- 0
+                       case <-myc2:
+                               myc1 <- 0
+                       }
+               }
+       })
+}
+
 func BenchmarkSelectContended(b *testing.B) {
-       const CallsPerSched = 1000
-       procs := runtime.GOMAXPROCS(-1)
-       N := int32(b.N / CallsPerSched)
-       c := make(chan bool, procs)
+       procs := runtime.GOMAXPROCS(0)
        myc1 := make(chan int, procs)
        myc2 := make(chan int, procs)
-       for p := 0; p < procs; p++ {
+       b.RunParallel(func(pb *testing.PB) {
                myc1 <- 0
-               go func() {
-                       for atomic.AddInt32(&N, -1) >= 0 {
-                               for g := 0; g < CallsPerSched; g++ {
-                                       select {
-                                       case <-myc1:
-                                               myc2 <- 0
-                                       case <-myc2:
-                                               myc1 <- 0
-                                       }
-                               }
+               for pb.Next() {
+                       select {
+                       case <-myc1:
+                               myc2 <- 0
+                       case <-myc2:
+                               myc1 <- 0
                        }
-                       c <- true
-               }()
-       }
-       for p := 0; p < procs; p++ {
-               <-c
-       }
+               }
+       })
 }
 
 func BenchmarkSelectNonblock(b *testing.B) {
-       const CallsPerSched = 1000
-       procs := runtime.GOMAXPROCS(-1)
-       N := int32(b.N / CallsPerSched)
-       c := make(chan bool, procs)
-       for p := 0; p < procs; p++ {
-               go func() {
-                       myc1 := make(chan int)
-                       myc2 := make(chan int)
-                       myc3 := make(chan int, 1)
-                       myc4 := make(chan int, 1)
-                       for atomic.AddInt32(&N, -1) >= 0 {
-                               for g := 0; g < CallsPerSched; g++ {
-                                       select {
-                                       case <-myc1:
-                                       default:
-                                       }
-                                       select {
-                                       case myc2 <- 0:
-                                       default:
-                                       }
-                                       select {
-                                       case <-myc3:
-                                       default:
-                                       }
-                                       select {
-                                       case myc4 <- 0:
-                                       default:
-                                       }
-                               }
+       b.RunParallel(func(pb *testing.PB) {
+               myc1 := make(chan int)
+               myc2 := make(chan int)
+               myc3 := make(chan int, 1)
+               myc4 := make(chan int, 1)
+               for pb.Next() {
+                       select {
+                       case <-myc1:
+                       default:
                        }
-                       c <- true
-               }()
-       }
-       for p := 0; p < procs; p++ {
-               <-c
-       }
+                       select {
+                       case myc2 <- 0:
+                       default:
+                       }
+                       select {
+                       case <-myc3:
+                       default:
+                       }
+                       select {
+                       case myc4 <- 0:
+                       default:
+                       }
+               }
+       })
 }
 
 func BenchmarkChanUncontended(b *testing.B) {
-       const CallsPerSched = 1000
-       procs := runtime.GOMAXPROCS(-1)
-       N := int32(b.N / CallsPerSched)
-       c := make(chan bool, procs)
-       for p := 0; p < procs; p++ {
-               go func() {
-                       myc := make(chan int, CallsPerSched)
-                       for atomic.AddInt32(&N, -1) >= 0 {
-                               for g := 0; g < CallsPerSched; g++ {
-                                       myc <- 0
-                               }
-                               for g := 0; g < CallsPerSched; g++ {
-                                       <-myc
-                               }
+       const C = 100
+       b.RunParallel(func(pb *testing.PB) {
+               myc := make(chan int, C)
+               for pb.Next() {
+                       for i := 0; i < C; i++ {
+                               myc <- 0
                        }
-                       c <- true
-               }()
-       }
-       for p := 0; p < procs; p++ {
-               <-c
-       }
+                       for i := 0; i < C; i++ {
+                               <-myc
+                       }
+               }
+       })
 }
 
 func BenchmarkChanContended(b *testing.B) {
-       const CallsPerSched = 1000
-       procs := runtime.GOMAXPROCS(-1)
-       N := int32(b.N / CallsPerSched)
-       c := make(chan bool, procs)
-       myc := make(chan int, procs*CallsPerSched)
-       for p := 0; p < procs; p++ {
-               go func() {
-                       for atomic.AddInt32(&N, -1) >= 0 {
-                               for g := 0; g < CallsPerSched; g++ {
-                                       myc <- 0
-                               }
-                               for g := 0; g < CallsPerSched; g++ {
-                                       <-myc
-                               }
+       const C = 100
+       myc := make(chan int, C*runtime.GOMAXPROCS(0))
+       b.RunParallel(func(pb *testing.PB) {
+               for pb.Next() {
+                       for i := 0; i < C; i++ {
+                               myc <- 0
                        }
-                       c <- true
-               }()
-       }
-       for p := 0; p < procs; p++ {
-               <-c
-       }
+                       for i := 0; i < C; i++ {
+                               <-myc
+                       }
+               }
+       })
 }
 
 func BenchmarkChanSync(b *testing.B) {
@@ -350,33 +641,95 @@ func BenchmarkChanProdConsWork100(b *testing.B) {
        benchmarkChanProdCons(b, 100, 100)
 }
 
-func BenchmarkChanCreation(b *testing.B) {
+func BenchmarkSelectProdCons(b *testing.B) {
        const CallsPerSched = 1000
        procs := runtime.GOMAXPROCS(-1)
        N := int32(b.N / CallsPerSched)
-       c := make(chan bool, procs)
+       c := make(chan bool, 2*procs)
+       myc := make(chan int, 128)
+       myclose := make(chan bool)
        for p := 0; p < procs; p++ {
                go func() {
+                       // Producer: sends to myc.
+                       foo := 0
+                       // Intended to not fire during benchmarking.
+                       mytimer := time.After(time.Hour)
                        for atomic.AddInt32(&N, -1) >= 0 {
                                for g := 0; g < CallsPerSched; g++ {
-                                       myc := make(chan int, 1)
-                                       myc <- 0
-                                       <-myc
+                                       // Model some local work.
+                                       for i := 0; i < 100; i++ {
+                                               foo *= 2
+                                               foo /= 2
+                                       }
+                                       select {
+                                       case myc <- 1:
+                                       case <-mytimer:
+                                       case <-myclose:
+                                       }
                                }
                        }
-                       c <- true
+                       myc <- 0
+                       c <- foo == 42
+               }()
+               go func() {
+                       // Consumer: receives from myc.
+                       foo := 0
+                       // Intended to not fire during benchmarking.
+                       mytimer := time.After(time.Hour)
+               loop:
+                       for {
+                               select {
+                               case v := <-myc:
+                                       if v == 0 {
+                                               break loop
+                                       }
+                               case <-mytimer:
+                               case <-myclose:
+                               }
+                               // Model some local work.
+                               for i := 0; i < 100; i++ {
+                                       foo *= 2
+                                       foo /= 2
+                               }
+                       }
+                       c <- foo == 42
                }()
        }
        for p := 0; p < procs; p++ {
                <-c
+               <-c
        }
 }
 
+func BenchmarkChanCreation(b *testing.B) {
+       b.RunParallel(func(pb *testing.PB) {
+               for pb.Next() {
+                       myc := make(chan int, 1)
+                       myc <- 0
+                       <-myc
+               }
+       })
+}
+
 func BenchmarkChanSem(b *testing.B) {
        type Empty struct{}
-       c := make(chan Empty, 1)
-       for i := 0; i < b.N; i++ {
-               c <- Empty{}
+       const CallsPerSched = 1000
+       procs := runtime.GOMAXPROCS(0)
+       N := int32(b.N / CallsPerSched)
+       c := make(chan bool, procs)
+       myc := make(chan Empty, procs)
+       for p := 0; p < procs; p++ {
+               go func() {
+                       for atomic.AddInt32(&N, -1) >= 0 {
+                               for g := 0; g < CallsPerSched; g++ {
+                                       myc <- Empty{}
+                                       <-myc
+                               }
+                       }
+                       c <- true
+               }()
+       }
+       for p := 0; p < procs; p++ {
                <-c
        }
 }
index 8337d5d5b3477a0641db20e31b5fd93e3cbd0e3b..a724fdf8f605c0d9db6de26472aa4fc95a631cb5 100644 (file)
@@ -91,7 +91,9 @@ func (x byDuration) Less(i, j int) bool { return x[i] < x[j] }
 // at startup, or 100 if the variable is not set.
 // A negative percentage disables garbage collection.
 func SetGCPercent(percent int) int {
-       return setGCPercent(percent)
+       old := setGCPercent(percent)
+       runtime.GC()
+       return old
 }
 
 // FreeOSMemory forces a garbage collection followed by an
index 2896b21417afad5ece2836198dfe2b4fc758cd3d..c29b0a226a2b08c583a2f73827e3a324c14c69c3 100644 (file)
@@ -18,6 +18,7 @@ var (
        dunno     = []byte("???")
        centerDot = []byte("·")
        dot       = []byte(".")
+       slash     = []byte("/")
 )
 
 // PrintStack prints to standard error the stack trace returned by Stack.
@@ -84,6 +85,11 @@ func function(pc uintptr) []byte {
        //      runtime/debug.*T·ptrmethod
        // and want
        //      *T.ptrmethod
+       // Since the package path might contains dots (e.g. code.google.com/...),
+       // we first remove the path prefix if there is one.
+       if lastslash := bytes.LastIndex(name, slash); lastslash >= 0 {
+               name = name[lastslash+1:]
+       }
        if period := bytes.Index(name, dot); period >= 0 {
                name = name[period+1:]
        }
index 88d5df5e415f5adf93d12cbdabaaabc2429e52e6..d759a54a51958f2969cb6f020dcf36bee4036913 100644 (file)
@@ -107,19 +107,20 @@ func NewErrorString(s string, ret *interface{}) {
 }
 
 // An errorCString represents a runtime error described by a single C string.
-type errorCString uintptr
+// Not "type errorCString uintptr" because of http://golang.org/issue/7084.
+type errorCString struct{ cstr uintptr }
 
 func (e errorCString) RuntimeError() {}
 
 func cstringToGo(uintptr) string
 
 func (e errorCString) Error() string {
-       return "runtime error: " + cstringToGo(uintptr(e))
+       return "runtime error: " + cstringToGo(e.cstr)
 }
 
 // For calling from C.
 func NewErrorCString(s uintptr, ret *interface{}) {
-       *ret = errorCString(s)
+       *ret = errorCString{s}
 }
 
 type stringer interface {
index 2f678b6bc9cb23b4993349559d14696474970ce9..436c28deae99790cbb6ddf37ef4a2aebd808a98d 100644 (file)
@@ -82,3 +82,7 @@ var TestSchedLocalQueueSteal1 = testSchedLocalQueueSteal
 
 var hashLoad float64 // declared in hashmap.c
 var HashLoad = &hashLoad
+
+func memclrBytes(b []byte)
+
+var MemclrBytes = memclrBytes
index 505aae605513ccd5fc7583556f513fb9f479c5ec..e51877704538b6b3ff020937be25943661bd1ba4 100644 (file)
@@ -71,6 +71,8 @@ func TestLFStack(t *testing.T) {
        }
 }
 
+var stress []*MyNode
+
 func TestLFStackStress(t *testing.T) {
        const K = 100
        P := 4 * GOMAXPROCS(-1)
@@ -80,14 +82,15 @@ func TestLFStackStress(t *testing.T) {
        }
        // Create 2 stacks.
        stacks := [2]*uint64{new(uint64), new(uint64)}
-       // Need to keep additional referenfces to nodes, the stack is not all that type-safe.
-       var nodes []*MyNode
+       // Need to keep additional references to nodes,
+       // the lock-free stack is not type-safe.
+       stress = nil
        // Push K elements randomly onto the stacks.
        sum := 0
        for i := 0; i < K; i++ {
                sum += i
                node := &MyNode{data: i}
-               nodes = append(nodes, node)
+               stress = append(stress, node)
                LFStackPush(stacks[i%2], fromMyNode(node))
        }
        c := make(chan bool, P)
@@ -127,4 +130,7 @@ func TestLFStackStress(t *testing.T) {
        if sum2 != sum {
                t.Fatalf("Wrong sum %d/%d", sum2, sum)
        }
+
+       // Let nodes be collected now.
+       stress = nil
 }
index 3d18e3be82c0f909c5466d636ac91a47853abcff..fe5d3ad86c911191f35e3932dc191991de6a9921 100644 (file)
@@ -422,8 +422,7 @@ func TestMapIterOrder(t *testing.T) {
                t.Skip("skipping for gccgo")
        }
 
-       // TODO: For issue 6719, add 3 and 7 to this list.
-       for _, n := range [...]int{9, 15} {
+       for _, n := range [...]int{3, 7, 9, 15} {
                // Make m be {0: true, 1: true, ..., n-1: true}.
                m := make(map[int]bool)
                for i := 0; i < n; i++ {
index ba6d1cf6ab9f6677272b685f55c4b1ae37e99046..fb35535c3a3d0bbeebd5bbbe5c6bda85060930c6 100644 (file)
@@ -60,11 +60,10 @@ type MemStats struct {
 
 var Sizeof_C_MStats uintptr // filled in by malloc.goc
 
-var VmemStats MemStats
-
 func init() {
-       if Sizeof_C_MStats != unsafe.Sizeof(VmemStats) {
-               println(Sizeof_C_MStats, unsafe.Sizeof(VmemStats))
+       var memStats MemStats
+       if Sizeof_C_MStats != unsafe.Sizeof(memStats) {
+               println(Sizeof_C_MStats, unsafe.Sizeof(memStats))
                panic("MStats vs MemStatsType size mismatch")
        }
 }
index 9525f06826e0bf5ec4887a929b0b399e752cd299..5c01aac97a91c9cfd88062d5a40562e580b1b2ee 100644 (file)
@@ -5,6 +5,7 @@
 package runtime_test
 
 import (
+       . "runtime"
        "testing"
 )
 
@@ -80,7 +81,7 @@ func TestMemmoveAlias(t *testing.T) {
        }
 }
 
-func bmMemmove(n int, b *testing.B) {
+func bmMemmove(b *testing.B, n int) {
        x := make([]byte, n)
        y := make([]byte, n)
        b.SetBytes(int64(n))
@@ -89,28 +90,74 @@ func bmMemmove(n int, b *testing.B) {
        }
 }
 
-func BenchmarkMemmove0(b *testing.B)    { bmMemmove(0, b) }
-func BenchmarkMemmove1(b *testing.B)    { bmMemmove(1, b) }
-func BenchmarkMemmove2(b *testing.B)    { bmMemmove(2, b) }
-func BenchmarkMemmove3(b *testing.B)    { bmMemmove(3, b) }
-func BenchmarkMemmove4(b *testing.B)    { bmMemmove(4, b) }
-func BenchmarkMemmove5(b *testing.B)    { bmMemmove(5, b) }
-func BenchmarkMemmove6(b *testing.B)    { bmMemmove(6, b) }
-func BenchmarkMemmove7(b *testing.B)    { bmMemmove(7, b) }
-func BenchmarkMemmove8(b *testing.B)    { bmMemmove(8, b) }
-func BenchmarkMemmove9(b *testing.B)    { bmMemmove(9, b) }
-func BenchmarkMemmove10(b *testing.B)   { bmMemmove(10, b) }
-func BenchmarkMemmove11(b *testing.B)   { bmMemmove(11, b) }
-func BenchmarkMemmove12(b *testing.B)   { bmMemmove(12, b) }
-func BenchmarkMemmove13(b *testing.B)   { bmMemmove(13, b) }
-func BenchmarkMemmove14(b *testing.B)   { bmMemmove(14, b) }
-func BenchmarkMemmove15(b *testing.B)   { bmMemmove(15, b) }
-func BenchmarkMemmove16(b *testing.B)   { bmMemmove(16, b) }
-func BenchmarkMemmove32(b *testing.B)   { bmMemmove(32, b) }
-func BenchmarkMemmove64(b *testing.B)   { bmMemmove(64, b) }
-func BenchmarkMemmove128(b *testing.B)  { bmMemmove(128, b) }
-func BenchmarkMemmove256(b *testing.B)  { bmMemmove(256, b) }
-func BenchmarkMemmove512(b *testing.B)  { bmMemmove(512, b) }
-func BenchmarkMemmove1024(b *testing.B) { bmMemmove(1024, b) }
-func BenchmarkMemmove2048(b *testing.B) { bmMemmove(2048, b) }
-func BenchmarkMemmove4096(b *testing.B) { bmMemmove(4096, b) }
+func BenchmarkMemmove0(b *testing.B)    { bmMemmove(b, 0) }
+func BenchmarkMemmove1(b *testing.B)    { bmMemmove(b, 1) }
+func BenchmarkMemmove2(b *testing.B)    { bmMemmove(b, 2) }
+func BenchmarkMemmove3(b *testing.B)    { bmMemmove(b, 3) }
+func BenchmarkMemmove4(b *testing.B)    { bmMemmove(b, 4) }
+func BenchmarkMemmove5(b *testing.B)    { bmMemmove(b, 5) }
+func BenchmarkMemmove6(b *testing.B)    { bmMemmove(b, 6) }
+func BenchmarkMemmove7(b *testing.B)    { bmMemmove(b, 7) }
+func BenchmarkMemmove8(b *testing.B)    { bmMemmove(b, 8) }
+func BenchmarkMemmove9(b *testing.B)    { bmMemmove(b, 9) }
+func BenchmarkMemmove10(b *testing.B)   { bmMemmove(b, 10) }
+func BenchmarkMemmove11(b *testing.B)   { bmMemmove(b, 11) }
+func BenchmarkMemmove12(b *testing.B)   { bmMemmove(b, 12) }
+func BenchmarkMemmove13(b *testing.B)   { bmMemmove(b, 13) }
+func BenchmarkMemmove14(b *testing.B)   { bmMemmove(b, 14) }
+func BenchmarkMemmove15(b *testing.B)   { bmMemmove(b, 15) }
+func BenchmarkMemmove16(b *testing.B)   { bmMemmove(b, 16) }
+func BenchmarkMemmove32(b *testing.B)   { bmMemmove(b, 32) }
+func BenchmarkMemmove64(b *testing.B)   { bmMemmove(b, 64) }
+func BenchmarkMemmove128(b *testing.B)  { bmMemmove(b, 128) }
+func BenchmarkMemmove256(b *testing.B)  { bmMemmove(b, 256) }
+func BenchmarkMemmove512(b *testing.B)  { bmMemmove(b, 512) }
+func BenchmarkMemmove1024(b *testing.B) { bmMemmove(b, 1024) }
+func BenchmarkMemmove2048(b *testing.B) { bmMemmove(b, 2048) }
+func BenchmarkMemmove4096(b *testing.B) { bmMemmove(b, 4096) }
+
+func TestMemclr(t *testing.T) {
+       size := 512
+       if testing.Short() {
+               size = 128 + 16
+       }
+       mem := make([]byte, size)
+       for i := 0; i < size; i++ {
+               mem[i] = 0xee
+       }
+       for n := 0; n < size; n++ {
+               for x := 0; x <= size-n; x++ { // offset in mem
+                       MemclrBytes(mem[x : x+n])
+                       for i := 0; i < x; i++ {
+                               if mem[i] != 0xee {
+                                       t.Fatalf("overwrite prefix mem[%d] = %d", i, mem[i])
+                               }
+                       }
+                       for i := x; i < x+n; i++ {
+                               if mem[i] != 0 {
+                                       t.Fatalf("failed clear mem[%d] = %d", i, mem[i])
+                               }
+                               mem[i] = 0xee
+                       }
+                       for i := x + n; i < size; i++ {
+                               if mem[i] != 0xee {
+                                       t.Fatalf("overwrite suffix mem[%d] = %d", i, mem[i])
+                               }
+                       }
+               }
+       }
+}
+
+func bmMemclr(b *testing.B, n int) {
+       x := make([]byte, n)
+       b.SetBytes(int64(n))
+       for i := 0; i < b.N; i++ {
+               MemclrBytes(x)
+       }
+}
+func BenchmarkMemclr5(b *testing.B)     { bmMemclr(b, 5) }
+func BenchmarkMemclr16(b *testing.B)    { bmMemclr(b, 16) }
+func BenchmarkMemclr64(b *testing.B)    { bmMemclr(b, 64) }
+func BenchmarkMemclr256(b *testing.B)   { bmMemclr(b, 256) }
+func BenchmarkMemclr4096(b *testing.B)  { bmMemclr(b, 4096) }
+func BenchmarkMemclr65536(b *testing.B) { bmMemclr(b, 65536) }
index 3b8428519d74c4bc275f026d77de4e7fbeacaae4..98080457cb581e14a3e4b8bbfcb70f0263eb727a 100644 (file)
@@ -20,7 +20,7 @@ import (
        "text/tabwriter"
 )
 
-// BUG(rsc): Profiles are incomplete and inaccuate on NetBSD, OpenBSD, and OS X.
+// BUG(rsc): Profiles are incomplete and inaccuate on NetBSD and OS X.
 // See http://golang.org/issue/6047 for details.
 
 // A Profile is a collection of stack traces showing the call sequences
index e556ca11e0690ee04dd912680f3adb8cabbafc55..923c5b384160bf380d4b21b3e7ce0ccc2f36b353 100644 (file)
@@ -33,10 +33,6 @@ func TestCPUProfile(t *testing.T) {
 }
 
 func TestCPUProfileMultithreaded(t *testing.T) {
-       // TODO(brainman): delete when issue 6986 is fixed.
-       if runtime.GOOS == "windows" && runtime.GOARCH == "amd64" {
-               t.Skip("skipping broken test on windows-amd64-race")
-       }
        buf := make([]byte, 100000)
        defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(2))
        testCPUProfile(t, []string{"crc32.update"}, func() {
@@ -142,7 +138,11 @@ func testCPUProfile(t *testing.T, need []string, f func()) {
                t.Logf("no CPU profile samples collected")
                ok = false
        }
-       min := total / uintptr(len(have)) / 3
+       // We'd like to check a reasonable minimum, like
+       // total / len(have) / smallconstant, but this test is
+       // pretty flaky (see bug 7095).  So we'll just test to
+       // make sure we got at least one sample.
+       min := uintptr(1)
        for i, name := range need {
                if have[i] < min {
                        t.Logf("%s has %d samples out of %d, want at least %d, ideally %d", name, have[i], total, min, total/uintptr(len(have)))
@@ -193,9 +193,6 @@ func TestCPUProfileWithFork(t *testing.T) {
 // If it did, it would see inconsistent state and would either record an incorrect stack
 // or crash because the stack was malformed.
 func TestGoroutineSwitch(t *testing.T) {
-       if runtime.GOOS == "windows" {
-               t.Skip("flaky test; see http://golang.org/issue/6417")
-       }
        // How much to try. These defaults take about 1 seconds
        // on a 2012 MacBook Pro. The ones in short mode take
        // about 0.1 seconds.
@@ -221,7 +218,7 @@ func TestGoroutineSwitch(t *testing.T) {
                        // exists to record a PC without a traceback. Those are okay.
                        if len(stk) == 2 {
                                f := runtime.FuncForPC(stk[1])
-                               if f != nil && f.Name() == "System" {
+                               if f != nil && (f.Name() == "System" || f.Name() == "ExternalCode") {
                                        return
                                }
                        }
@@ -248,10 +245,6 @@ func TestGoroutineSwitch(t *testing.T) {
 
 // Test that profiling of division operations is okay, especially on ARM. See issue 6681.
 func TestMathBigDivide(t *testing.T) {
-       // TODO(brainman): delete when issue 6986 is fixed.
-       if runtime.GOOS == "windows" && runtime.GOARCH == "amd64" {
-               t.Skip("skipping broken test on windows-amd64-race")
-       }
        testCPUProfile(t, nil, func() {
                t := time.After(5 * time.Second)
                pi := new(big.Int)
@@ -272,9 +265,9 @@ func TestMathBigDivide(t *testing.T) {
 
 // Operating systems that are expected to fail the tests. See issue 6047.
 var badOS = map[string]bool{
-       "darwin":  true,
-       "netbsd":  true,
-       "openbsd": true,
+       "darwin": true,
+       "netbsd": true,
+       "plan9":  true,
 }
 
 func TestBlockProfile(t *testing.T) {
index 29f71e7448caf14aa924aef0b8514b1dfe2d7d69..bdcb199d72782da49ac0401102d85a51865dc341 100644 (file)
@@ -246,6 +246,49 @@ func TestPreemptionGC(t *testing.T) {
        atomic.StoreUint32(&stop, 1)
 }
 
+func TestGCFairness(t *testing.T) {
+       output := executeTest(t, testGCFairnessSource, nil)
+       want := "OK\n"
+       if output != want {
+               t.Fatalf("want %s, got %s\n", want, output)
+       }
+}
+
+const testGCFairnessSource = `
+package main
+
+import (
+       "fmt"
+       "os"
+       "runtime"
+       "time"
+)
+
+func main() {
+       runtime.GOMAXPROCS(1)
+       f, err := os.Open("/dev/null")
+       if os.IsNotExist(err) {
+               // This test tests what it is intended to test only if writes are fast.
+               // If there is no /dev/null, we just don't execute the test.
+               fmt.Println("OK")
+               return
+       }
+       if err != nil {
+               fmt.Println(err)
+               os.Exit(1)
+       }
+       for i := 0; i < 2; i++ {
+               go func() {
+                       for {
+                               f.Write([]byte("."))
+                       }
+               }()
+       }
+       time.Sleep(10 * time.Millisecond)
+       fmt.Println("OK")
+}
+`
+
 func stackGrowthRecursive(i int) {
        var pad [128]uint64
        if i != 0 && pad[0] == 0 {
index 9eb07c3a03f26aebee9b403d0c92d7ccd44dd815..ca49d21a0d1df969b97c29c9bf96290fcd023326 100644 (file)
@@ -4,6 +4,18 @@
 
 package sync
 
+import (
+       "runtime"
+       "sync/atomic"
+       "unsafe"
+)
+
+const (
+       cacheLineSize = 128
+       poolLocalSize = 2 * cacheLineSize
+       poolLocalCap  = poolLocalSize/unsafe.Sizeof(*(*interface{})(nil)) - 1
+)
+
 // A Pool is a set of temporary objects that may be individually saved
 // and retrieved.
 //
@@ -26,29 +38,58 @@ package sync
 //
 // This is an experimental type and might not be released.
 type Pool struct {
-       next *Pool         // for use by runtime. must be first.
-       list []interface{} // offset known to runtime
-       mu   Mutex         // guards list
+       // The following fields are known to runtime.
+       next         *Pool      // for use by runtime
+       local        *poolLocal // local fixed-size per-P pool, actually an array
+       localSize    uintptr    // size of the local array
+       globalOffset uintptr    // offset of global
+       // The rest is not known to runtime.
 
        // New optionally specifies a function to generate
        // a value when Get would otherwise return nil.
        // It may not be changed concurrently with calls to Get.
        New func() interface{}
+
+       pad [cacheLineSize]byte
+       // Read-mostly date above this point, mutable data follows.
+       mu     Mutex
+       global []interface{} // global fallback pool
 }
 
-func runtime_registerPool(*Pool)
+// Local per-P Pool appendix.
+type poolLocal struct {
+       tail   int
+       unused int
+       buf    [poolLocalCap]interface{}
+}
+
+func init() {
+       var v poolLocal
+       if unsafe.Sizeof(v) != poolLocalSize {
+               panic("sync: incorrect pool size")
+       }
+}
 
 // Put adds x to the pool.
 func (p *Pool) Put(x interface{}) {
+       if raceenabled {
+               // Under race detector the Pool degenerates into no-op.
+               // It's conforming, simple and does not introduce excessive
+               // happens-before edges between unrelated goroutines.
+               return
+       }
        if x == nil {
                return
        }
-       p.mu.Lock()
-       if p.list == nil {
-               runtime_registerPool(p)
+       l := p.pin()
+       t := l.tail
+       if t < int(poolLocalCap) {
+               l.buf[t] = x
+               l.tail = t + 1
+               runtime_procUnpin()
+               return
        }
-       p.list = append(p.list, x)
-       p.mu.Unlock()
+       p.putSlow(l, x)
 }
 
 // Get selects an arbitrary item from the Pool, removes it from the
@@ -60,16 +101,122 @@ func (p *Pool) Put(x interface{}) {
 // If Get would otherwise return nil and p.New is non-nil, Get returns
 // the result of calling p.New.
 func (p *Pool) Get() interface{} {
+       if raceenabled {
+               if p.New != nil {
+                       return p.New()
+               }
+               return nil
+       }
+       l := p.pin()
+       t := l.tail
+       if t > 0 {
+               t -= 1
+               x := l.buf[t]
+               l.tail = t
+               runtime_procUnpin()
+               return x
+       }
+       return p.getSlow()
+}
+
+func (p *Pool) putSlow(l *poolLocal, x interface{}) {
+       // Grab half of items from local pool and put to global pool.
+       // Can not lock the mutex while pinned.
+       const N = int(poolLocalCap/2 + 1)
+       var buf [N]interface{}
+       buf[0] = x
+       for i := 1; i < N; i++ {
+               l.tail--
+               buf[i] = l.buf[l.tail]
+       }
+       runtime_procUnpin()
+
+       p.mu.Lock()
+       p.global = append(p.global, buf[:]...)
+       p.mu.Unlock()
+}
+
+func (p *Pool) getSlow() (x interface{}) {
+       // Grab a batch of items from global pool and put to local pool.
+       // Can not lock the mutex while pinned.
+       runtime_procUnpin()
        p.mu.Lock()
-       var x interface{}
-       if n := len(p.list); n > 0 {
-               x = p.list[n-1]
-               p.list[n-1] = nil // Just to be safe
-               p.list = p.list[:n-1]
+       pid := runtime_procPin()
+       s := p.localSize
+       l := p.local
+       if uintptr(pid) < s {
+               l = indexLocal(l, pid)
+               // Get the item to return.
+               last := len(p.global) - 1
+               if last >= 0 {
+                       x = p.global[last]
+                       p.global = p.global[:last]
+               }
+               // Try to refill local pool, we may have been rescheduled to another P.
+               if last > 0 && l.tail == 0 {
+                       n := int(poolLocalCap / 2)
+                       gl := len(p.global)
+                       if n > gl {
+                               n = gl
+                       }
+                       copy(l.buf[:], p.global[gl-n:])
+                       p.global = p.global[:gl-n]
+                       l.tail = n
+               }
        }
+       runtime_procUnpin()
        p.mu.Unlock()
+
        if x == nil && p.New != nil {
                x = p.New()
        }
-       return x
+       return
 }
+
+// pin pins current goroutine to P, disables preemption and returns poolLocal pool for the P.
+// Caller must call runtime_procUnpin() when done with the pool.
+func (p *Pool) pin() *poolLocal {
+       pid := runtime_procPin()
+       // In pinSlow we store to localSize and then to local, here we load in opposite order.
+       // Since we've disabled preemption, GC can not happen in between.
+       // Thus here we must observe local at least as large localSize.
+       // We can observe a newer/larger local, it is fine (we must observe its zero-initialized-ness).
+       s := atomic.LoadUintptr(&p.localSize) // load-acquire
+       l := p.local                          // load-consume
+       if uintptr(pid) < s {
+               return indexLocal(l, pid)
+       }
+       return p.pinSlow()
+}
+
+func (p *Pool) pinSlow() *poolLocal {
+       // Retry under the mutex.
+       runtime_procUnpin()
+       p.mu.Lock()
+       defer p.mu.Unlock()
+       pid := runtime_procPin()
+       s := p.localSize
+       l := p.local
+       if uintptr(pid) < s {
+               return indexLocal(l, pid)
+       }
+       if p.local == nil {
+               p.globalOffset = unsafe.Offsetof(p.global)
+               runtime_registerPool(p)
+       }
+       // If GOMAXPROCS changes between GCs, we re-allocate the array and lose the old one.
+       size := runtime.GOMAXPROCS(0)
+       local := make([]poolLocal, size)
+       atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&p.local)), unsafe.Pointer(&local[0])) // store-release
+       atomic.StoreUintptr(&p.localSize, uintptr(size))                                            // store-release
+       return &local[pid]
+}
+
+func indexLocal(l *poolLocal, i int) *poolLocal {
+       return (*poolLocal)(unsafe.Pointer(uintptr(unsafe.Pointer(l)) + unsafe.Sizeof(*l)*uintptr(i))) // uh...
+}
+
+// Implemented in runtime.
+func runtime_registerPool(*Pool)
+func runtime_procPin() int
+func runtime_procUnpin()
index f88dab494367dc236cf0568de334f0d051af9ff1..39ba7a913d3c7aeac94ae1e5871a89f37a8703c4 100644 (file)
@@ -2,6 +2,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Pool is no-op under race detector, so all these tests do not work.
+// +build !race
+
 package sync_test
 
 import (
@@ -11,7 +14,6 @@ import (
        "sync/atomic"
        "testing"
        "time"
-       "unsafe"
 )
 
 func TestPool(t *testing.T) {
@@ -74,8 +76,8 @@ func TestPoolGC(t *testing.T) {
        var fin uint32
        const N = 100
        for i := 0; i < N; i++ {
-               v := new(int)
-               runtime.SetFinalizer(v, func(vv *int) {
+               v := new(string)
+               runtime.SetFinalizer(v, func(vv *string) {
                        atomic.AddUint32(&fin, 1)
                })
                p.Put(v)
@@ -130,28 +132,41 @@ func TestPoolStress(t *testing.T) {
 }
 
 func BenchmarkPool(b *testing.B) {
-       procs := runtime.GOMAXPROCS(-1)
-       var dec func() bool
-       if unsafe.Sizeof(b.N) == 8 {
-               n := int64(b.N)
-               dec = func() bool {
-                       return atomic.AddInt64(&n, -1) >= 0
-               }
-       } else {
-               n := int32(b.N)
-               dec = func() bool {
-                       return atomic.AddInt32(&n, -1) >= 0
-               }
+       var p Pool
+       var wg WaitGroup
+       n0 := uintptr(b.N)
+       n := n0
+       for i := 0; i < runtime.GOMAXPROCS(0); i++ {
+               wg.Add(1)
+               go func() {
+                       defer wg.Done()
+                       for atomic.AddUintptr(&n, ^uintptr(0)) < n0 {
+                               for b := 0; b < 100; b++ {
+                                       p.Put(1)
+                                       p.Get()
+                               }
+                       }
+               }()
        }
+       wg.Wait()
+}
+
+func BenchmarkPoolOverlflow(b *testing.B) {
        var p Pool
        var wg WaitGroup
-       for i := 0; i < procs; i++ {
+       n0 := uintptr(b.N)
+       n := n0
+       for i := 0; i < runtime.GOMAXPROCS(0); i++ {
                wg.Add(1)
                go func() {
                        defer wg.Done()
-                       for dec() {
-                               p.Put(1)
-                               p.Get()
+                       for atomic.AddUintptr(&n, ^uintptr(0)) < n0 {
+                               for b := 0; b < 100; b++ {
+                                       p.Put(1)
+                               }
+                               for b := 0; b < 100; b++ {
+                                       p.Get()
+                               }
                        }
                }()
        }
index 73630bc61499fd59457bde13e2cac6d7924af8db..6c9fb823560d292b71f989abd0ec861c5c59ab87 100644 (file)
@@ -32,3 +32,13 @@ func _() {
                _ int = syscall.TCOFLUSH
        )
 }
+
+func _() {
+       _ = syscall.Flock_t{
+               Type:   int16(0),
+               Whence: int16(0),
+               Start:  int64(0),
+               Len:    int64(0),
+               Pid:    int32(0),
+       }
+}
index b9c2d7f9b00038835d385cb2a3b15797002af11b..85f38e08665c4b41edcedbbc58791d64d6ae01ce 100644 (file)
@@ -208,6 +208,9 @@ func FDZero(set *FdSet) {
 //sys  fcntl(fd int, cmd int, arg int) (val int, err error)
 //__go_fcntl(fd _C_int, cmd _C_int, arg _C_int) _C_int
 
+//sys  FcntlFlock(fd uintptr, cmd int, lk *Flock_t) (err error)
+//__go_fcntl_flock(fd _C_int, cmd _C_int, arg *Flock_t) _C_int
+
 //sys  Fdatasync(fd int) (err error)
 //fdatasync(fd _C_int) _C_int
 
index 5296cec9c6edb9e56fab11ab3c2833167d9635eb..48ba191c6da928a8ace2ea6f014db72d081f3f54 100644 (file)
@@ -69,10 +69,10 @@ func AttachLsf(fd int, i []SockFilter) error {
        var p SockFprog
        p.Len = uint16(len(i))
        p.Filter = (*SockFilter)(unsafe.Pointer(&i[0]))
-       return setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, (*byte)(unsafe.Pointer(&p)), Socklen_t(unsafe.Sizeof(p)))
+       return setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, unsafe.Pointer(&p), Socklen_t(unsafe.Sizeof(p)))
 }
 
 func DetachLsf(fd int) error {
        var dummy int
-       return setsockopt(fd, SOL_SOCKET, SO_DETACH_FILTER, (*byte)(unsafe.Pointer(&dummy)), Socklen_t(unsafe.Sizeof(dummy)))
+       return setsockopt(fd, SOL_SOCKET, SO_DETACH_FILTER, unsafe.Pointer(&dummy), Socklen_t(unsafe.Sizeof(dummy)))
 }
index 8d009222a182002c402087b8796ea76c32c87c86..6fbd2ac8ef32db37e0e10502fae0a6a5d3a9f0c2 100644 (file)
@@ -199,6 +199,8 @@ BEGIN {
            args = sprintf("%s_p%d, %s(len(%s))", args, goarg, cparam[2], goname)
        } else if (gotype == "uintptr" && ctype ~ /^\*/) {
            args = sprintf("%s(%s)(unsafe.Pointer(%s))", args, ctype, goname)
+       } else if (gotype == "unsafe.Pointer" && ctype ~ /^\*/) {
+           args = sprintf("%s(%s)(%s)", args, ctype, goname)
        } else {
            args = sprintf("%s%s(%s)", args, ctype, goname)
        }
similarity index 74%
rename from libgo/go/syscall/rlimit_linux_test.go
rename to libgo/go/syscall/rlimit_unix_test.go
index 4ec720e936083e5e0714d3b39b31a1a3341ecfe6..fc9b02609cf09ecc63c2aacc3397ef74f37c21fa 100644 (file)
@@ -2,9 +2,12 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// +build darwin dragonfly freebsd linux netbsd openbsd
+
 package syscall_test
 
 import (
+       "runtime"
        "syscall"
        "testing"
 )
@@ -32,7 +35,14 @@ func TestRlimit(t *testing.T) {
        set = rlimit
        set.Cur = set.Max - 1
        if set != get {
-               t.Fatalf("Rlimit: change failed: wanted %#v got %#v", set, get)
+               // Seems like Darwin requires some privilege to
+               // increase the soft limit of rlimit sandbox, though
+               // Setrlimit never reports an error.
+               switch runtime.GOOS {
+               case "darwin":
+               default:
+                       t.Fatalf("Rlimit: change failed: wanted %#v got %#v", set, get)
+               }
        }
        err = syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rlimit)
        if err != nil {
index f4dba36908eb90fa2d09db20bbfd991b31ed8ff7..491f52c100e30b484b1f539bfe9aa34472ccd1ab 100644 (file)
@@ -213,67 +213,67 @@ func Socketpair(domain, typ, proto int) (fd [2]int, err error) {
 func GetsockoptByte(fd, level, opt int) (value byte, err error) {
        var n byte
        vallen := Socklen_t(1)
-       err = getsockopt(fd, level, opt, uintptr(unsafe.Pointer(&n)), &vallen)
+       err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
        return n, err
 }
 
 func GetsockoptInt(fd, level, opt int) (value int, err error) {
        var n int32
        vallen := Socklen_t(4)
-       err = getsockopt(fd, level, opt, (uintptr)(unsafe.Pointer(&n)), &vallen)
+       err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
        return int(n), err
 }
 
 func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
        vallen := Socklen_t(4)
-       err = getsockopt(fd, level, opt, uintptr(unsafe.Pointer(&value[0])), &vallen)
+       err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
        return value, err
 }
 
 func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
        var value IPMreq
        vallen := Socklen_t(SizeofIPMreq)
-       err := getsockopt(fd, level, opt, uintptr(unsafe.Pointer(&value)), &vallen)
+       err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
        return &value, err
 }
 
 func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {
        var value IPMreqn
        vallen := Socklen_t(SizeofIPMreqn)
-       err := getsockopt(fd, level, opt, uintptr(unsafe.Pointer(&value)), &vallen)
+       err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
        return &value, err
 }
 
 func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
        var value IPv6Mreq
        vallen := Socklen_t(SizeofIPv6Mreq)
-       err := getsockopt(fd, level, opt, uintptr(unsafe.Pointer(&value)), &vallen)
+       err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
        return &value, err
 }
 
-//sys  setsockopt(s int, level int, name int, val *byte, vallen Socklen_t) (err error)
+//sys  setsockopt(s int, level int, name int, val unsafe.Pointer, vallen Socklen_t) (err error)
 //setsockopt(s _C_int, level _C_int, optname _C_int, val *byte, vallen Socklen_t) _C_int
 
 func SetsockoptByte(fd, level, opt int, value byte) (err error) {
        var n = byte(value)
-       return setsockopt(fd, level, opt, (*byte)(unsafe.Pointer(&n)), 1)
+       return setsockopt(fd, level, opt, unsafe.Pointer(&n), 1)
 }
 
 func SetsockoptInt(fd, level, opt int, value int) (err error) {
        var n = int32(value)
-       return setsockopt(fd, level, opt, (*byte)(unsafe.Pointer(&n)), 4)
+       return setsockopt(fd, level, opt, unsafe.Pointer(&n), 4)
 }
 
 func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) {
-       return setsockopt(fd, level, opt, (*byte)(unsafe.Pointer(&value[0])), 4)
+       return setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4)
 }
 
 func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) {
-       return setsockopt(fd, level, opt, (*byte)(unsafe.Pointer(tv)), Socklen_t(unsafe.Sizeof(*tv)))
+       return setsockopt(fd, level, opt, unsafe.Pointer(tv), Socklen_t(unsafe.Sizeof(*tv)))
 }
 
 func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error {
-       return setsockopt(fd, level, opt, (*byte)(unsafe.Pointer(filter)), SizeofICMPv6Filter)
+       return setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter)
 }
 
 type Linger struct {
@@ -282,23 +282,23 @@ type Linger struct {
 }
 
 func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) {
-       return setsockopt(fd, level, opt, (*byte)(unsafe.Pointer(l)), Socklen_t(unsafe.Sizeof(*l)))
+       return setsockopt(fd, level, opt, unsafe.Pointer(l), Socklen_t(unsafe.Sizeof(*l)))
 }
 
 func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) {
-       return setsockopt(fd, level, opt, (*byte)(unsafe.Pointer(mreq)), Socklen_t(unsafe.Sizeof(*mreq)))
+       return setsockopt(fd, level, opt, unsafe.Pointer(mreq), Socklen_t(unsafe.Sizeof(*mreq)))
 }
 
 func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {
-       return setsockopt(fd, level, opt, (*byte)(unsafe.Pointer(mreq)), Socklen_t(unsafe.Sizeof(*mreq)))
+       return setsockopt(fd, level, opt, unsafe.Pointer(mreq), Socklen_t(unsafe.Sizeof(*mreq)))
 }
 
 func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) {
-       return setsockopt(fd, level, opt, (*byte)(unsafe.Pointer(mreq)), Socklen_t(unsafe.Sizeof(*mreq)))
+       return setsockopt(fd, level, opt, unsafe.Pointer(mreq), Socklen_t(unsafe.Sizeof(*mreq)))
 }
 
 func SetsockoptString(fd, level, opt int, s string) (err error) {
-       return setsockopt(fd, level, opt, (*byte)(unsafe.Pointer(&[]byte(s)[0])), Socklen_t(len(s)))
+       return setsockopt(fd, level, opt, unsafe.Pointer(&[]byte(s)[0]), Socklen_t(len(s)))
 }
 
 //sys  recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *Socklen_t) (n int, err error)
index 06d7dab464a0fe07d1d1c11495d2f4570109ab76..fd96524f13bd87aed1720a6e870f1e08783289d0 100644 (file)
@@ -18,7 +18,7 @@ package syscall
 //sysnb        socketpair(domain int, typ int, proto int, fd *[2]_C_int) (err error)
 //socketpair(domain _C_int, typ _C_int, protocol _C_int, fd *[2]_C_int) _C_int
 
-//sys  getsockopt(s int, level int, name int, val uintptr, vallen *Socklen_t) (err error)
+//sys  getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *Socklen_t) (err error)
 //getsockopt(s _C_int, level _C_int, name _C_int, val *byte, vallen *Socklen_t) _C_int
 
 //sys  sendto(s int, buf []byte, flags int, to *RawSockaddrAny, tolen Socklen_t) (err error)
index 8f86c622b9faddd4abaa7e7882740e999d5b55e6..04400107d06f69bea46aeb9a6c286967f7358403 100644 (file)
@@ -19,7 +19,7 @@ package syscall
 //sysnb        socketpair(domain int, typ int, proto int, fd *[2]_C_int) (err error)
 //__xnet_socketpair(domain _C_int, typ _C_int, protocol _C_int, fd *[2]_C_int) _C_int
 
-//sys  getsockopt(s int, level int, name int, val uintptr, vallen *Socklen_t) (err error)
+//sys  getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *Socklen_t) (err error)
 //__xnet_getsockopt(s _C_int, level _C_int, name _C_int, val *byte, vallen *Socklen_t) _C_int
 
 //sys  sendto(s int, buf []byte, flags int, to *RawSockaddrAny, tolen Socklen_t) (err error)
index 5559c7c69b7ee63ffa1922dc6f1758cbe0efdc1c..fcb90dbfa753b54879d0b5964c3ded38992c4dbc 100644 (file)
@@ -124,7 +124,7 @@ func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (d
                cap  int
        }{addr, length, length}
 
-       // Use unsafe to turn sl into a []byte.
+       // Use unsafeto turn sl into a []byte.
        b := *(*[]byte)(unsafe.Pointer(&sl))
 
        // Register mapping in m and return it.
index 3473c5b2cbffdb3c4de3b4a0430bdcc50d61138f..e6f3c6d7903214c776d08afa983a56b7252e520d 100644 (file)
@@ -10,6 +10,7 @@ import (
        "os"
        "runtime"
        "sync"
+       "sync/atomic"
        "time"
 )
 
@@ -34,12 +35,15 @@ type InternalBenchmark struct {
 // timing and to specify the number of iterations to run.
 type B struct {
        common
-       N               int
-       benchmark       InternalBenchmark
-       bytes           int64
-       timerOn         bool
-       showAllocResult bool
-       result          BenchmarkResult
+       N                int
+       previousN        int           // number of iterations in the previous run
+       previousDuration time.Duration // total duration of the previous run
+       benchmark        InternalBenchmark
+       bytes            int64
+       timerOn          bool
+       showAllocResult  bool
+       result           BenchmarkResult
+       parallelism      int // RunParallel creates parallelism*GOMAXPROCS goroutines
        // The initial states of memStats.Mallocs and memStats.TotalAlloc.
        startAllocs uint64
        startBytes  uint64
@@ -74,7 +78,7 @@ func (b *B) StopTimer() {
        }
 }
 
-// ResetTimer sets the elapsed benchmark time to zero.
+// ResetTimer zeros the elapsed benchmark time and memory allocation counters.
 // It does not affect whether the timer is running.
 func (b *B) ResetTimer() {
        if b.timerOn {
@@ -114,10 +118,13 @@ func (b *B) runN(n int) {
        // by clearing garbage from previous runs.
        runtime.GC()
        b.N = n
+       b.parallelism = 1
        b.ResetTimer()
        b.StartTimer()
        b.benchmark.F(b)
        b.StopTimer()
+       b.previousN = n
+       b.previousDuration = b.duration
 }
 
 func min(x, y int) int {
@@ -343,6 +350,84 @@ func (b *B) trimOutput() {
        }
 }
 
+// A PB is used by RunParallel for running parallel benchmarks.
+type PB struct {
+       globalN *uint64 // shared between all worker goroutines iteration counter
+       grain   uint64  // acquire that many iterations from globalN at once
+       cache   uint64  // local cache of acquired iterations
+       bN      uint64  // total number of iterations to execute (b.N)
+}
+
+// Next reports whether there are more iterations to execute.
+func (pb *PB) Next() bool {
+       if pb.cache == 0 {
+               n := atomic.AddUint64(pb.globalN, pb.grain)
+               if n <= pb.bN {
+                       pb.cache = pb.grain
+               } else if n < pb.bN+pb.grain {
+                       pb.cache = pb.bN + pb.grain - n
+               } else {
+                       return false
+               }
+       }
+       pb.cache--
+       return true
+}
+
+// RunParallel runs a benchmark in parallel.
+// It creates multiple goroutines and distributes b.N iterations among them.
+// The number of goroutines defaults to GOMAXPROCS. To increase parallelism for
+// non-CPU-bound benchmarks, call SetParallelism before RunParallel.
+// RunParallel is usually used with the go test -cpu flag.
+//
+// The body function will be run in each goroutine. It should set up any
+// goroutine-local state and then iterate until pb.Next returns false.
+// It should not use the StartTimer, StopTimer, or ResetTimer functions,
+// because they have global effect.
+func (b *B) RunParallel(body func(*PB)) {
+       // Calculate grain size as number of iterations that take ~100µs.
+       // 100µs is enough to amortize the overhead and provide sufficient
+       // dynamic load balancing.
+       grain := uint64(0)
+       if b.previousN > 0 && b.previousDuration > 0 {
+               grain = 1e5 * uint64(b.previousN) / uint64(b.previousDuration)
+       }
+       if grain < 1 {
+               grain = 1
+       }
+       // We expect the inner loop and function call to take at least 10ns,
+       // so do not do more than 100µs/10ns=1e4 iterations.
+       if grain > 1e4 {
+               grain = 1e4
+       }
+
+       n := uint64(0)
+       numProcs := b.parallelism * runtime.GOMAXPROCS(0)
+       var wg sync.WaitGroup
+       wg.Add(numProcs)
+       for p := 0; p < numProcs; p++ {
+               go func() {
+                       defer wg.Done()
+                       pb := &PB{
+                               globalN: &n,
+                               grain:   grain,
+                               bN:      uint64(b.N),
+                       }
+                       body(pb)
+               }()
+       }
+       wg.Wait()
+}
+
+// SetParallelism sets the number of goroutines used by RunParallel to p*GOMAXPROCS.
+// There is usually no need to call SetParallelism for CPU-bound benchmarks.
+// If p is less than 1, this call will have no effect.
+func (b *B) SetParallelism(p int) {
+       if p >= 1 {
+               b.parallelism = p
+       }
+}
+
 // Benchmark benchmarks a single function. Useful for creating
 // custom benchmarks that do not use the "go test" command.
 func Benchmark(f func(b *B)) BenchmarkResult {
index 94e994dfae08b6af86d09c94ba7dd62ddfa111c0..9997b9920424509670b61166e94fa20406f37e72 100644 (file)
@@ -5,7 +5,11 @@
 package testing_test
 
 import (
+       "bytes"
+       "runtime"
+       "sync/atomic"
        "testing"
+       "text/template"
 )
 
 var roundDownTests = []struct {
@@ -56,3 +60,53 @@ func TestRoundUp(t *testing.T) {
                }
        }
 }
+
+func TestRunParallel(t *testing.T) {
+       testing.Benchmark(func(b *testing.B) {
+               procs := uint32(0)
+               iters := uint64(0)
+               b.SetParallelism(3)
+               b.RunParallel(func(pb *testing.PB) {
+                       atomic.AddUint32(&procs, 1)
+                       for pb.Next() {
+                               atomic.AddUint64(&iters, 1)
+                       }
+               })
+               if want := uint32(3 * runtime.GOMAXPROCS(0)); procs != want {
+                       t.Errorf("got %v procs, want %v", procs, want)
+               }
+               if iters != uint64(b.N) {
+                       t.Errorf("got %v iters, want %v", iters, b.N)
+               }
+       })
+}
+
+func TestRunParallelFail(t *testing.T) {
+       testing.Benchmark(func(b *testing.B) {
+               b.RunParallel(func(pb *testing.PB) {
+                       // The function must be able to log/abort
+                       // w/o crashing/deadlocking the whole benchmark.
+                       b.Log("log")
+                       b.Error("error")
+                       b.Fatal("fatal")
+               })
+       })
+}
+
+func ExampleB_RunParallel() {
+       // Parallel benchmark for text/template.Template.Execute on a single object.
+       testing.Benchmark(func(b *testing.B) {
+               templ := template.Must(template.New("test").Parse("Hello, {{.}}!"))
+               // RunParallel will create GOMAXPROCS goroutines
+               // and distribute work among them.
+               b.RunParallel(func(pb *testing.PB) {
+                       // Each goroutine has its own bytes.Buffer.
+                       var buf bytes.Buffer
+                       for pb.Next() {
+                               // The loop body is executed b.N times total across all goroutines.
+                               buf.Reset()
+                               templ.Execute(&buf, "World")
+                       }
+               })
+       })
+}
index 52dc166dd93c2417da92322fe3e47482e95fcc09..855f3a9bbe9145e1fd69d2111405adf36dbd47f5 100644 (file)
@@ -43,6 +43,7 @@
 //
 // If a benchmark needs some expensive setup before running, the timer
 // may be reset:
+//
 //     func BenchmarkBigLen(b *testing.B) {
 //         big := NewBig()
 //         b.ResetTimer()
 //         }
 //     }
 //
+// If a benchmark needs to test performance in a parallel setting, it may use
+// the RunParallel helper function; such benchmarks are intended to be used with
+// the go test -cpu flag:
+//
+//     func BenchmarkTemplateParallel(b *testing.B) {
+//         templ := template.Must(template.New("test").Parse("Hello, {{.}}!"))
+//         b.RunParallel(func(pb *testing.PB) {
+//             var buf bytes.Buffer
+//             for pb.Next() {
+//                 buf.Reset()
+//                 templ.Execute(&buf, "World")
+//             }
+//         })
+//     }
+//
 // Examples
 //
 // The package also runs and verifies example code. Example functions may
@@ -143,10 +159,11 @@ var (
 // common holds the elements common between T and B and
 // captures common methods such as Errorf.
 type common struct {
-       mu      sync.RWMutex // guards output and failed
-       output  []byte       // Output generated by test or benchmark.
-       failed  bool         // Test or benchmark has failed.
-       skipped bool         // Test of benchmark has been skipped.
+       mu       sync.RWMutex // guards output and failed
+       output   []byte       // Output generated by test or benchmark.
+       failed   bool         // Test or benchmark has failed.
+       skipped  bool         // Test of benchmark has been skipped.
+       finished bool
 
        start    time.Time // Time test or benchmark started
        duration time.Duration
@@ -275,6 +292,7 @@ func (c *common) FailNow() {
        // it would run on a test failure.  Because we send on c.signal during
        // a top-of-stack deferred function now, we know that the send
        // only happens after any other stacked defers have completed.
+       c.finished = true
        runtime.Goexit()
 }
 
@@ -338,6 +356,7 @@ func (c *common) Skipf(format string, args ...interface{}) {
 // those other goroutines.
 func (c *common) SkipNow() {
        c.skip()
+       c.finished = true
        runtime.Goexit()
 }
 
@@ -379,7 +398,11 @@ func tRunner(t *T, test *InternalTest) {
        defer func() {
                t.duration = time.Now().Sub(t.start)
                // If the test panicked, print any test output before dying.
-               if err := recover(); err != nil {
+               err := recover()
+               if !t.finished && err == nil {
+                       err = fmt.Errorf("test executed panic(nil) or runtime.Goexit")
+               }
+               if err != nil {
                        t.Fail()
                        t.report()
                        panic(err)
@@ -389,6 +412,7 @@ func tRunner(t *T, test *InternalTest) {
 
        t.start = time.Now()
        test.F(t)
+       t.finished = true
 }
 
 // An internal function but exported because it is cross-package; part of the implementation
index 496eed4a31db81b370587f4514efcc755d5172bb..086ab5660eb935fd0d95eeebda6d4fbe678b34f4 100644 (file)
@@ -360,7 +360,7 @@ func TestScanSelectedMask(t *testing.T) {
 func TestScanNext(t *testing.T) {
        const BOM = '\uFEFF'
        BOMs := string(BOM)
-       s := new(Scanner).Init(bytes.NewBufferString(BOMs + "if a == bcd /* com" + BOMs + "ment */ {\n\ta += c\n}" + BOMs + "// line comment ending in eof"))
+       s := new(Scanner).Init(strings.NewReader(BOMs + "if a == bcd /* com" + BOMs + "ment */ {\n\ta += c\n}" + BOMs + "// line comment ending in eof"))
        checkTok(t, s, 1, s.Scan(), Ident, "if") // the first BOM is ignored
        checkTok(t, s, 1, s.Scan(), Ident, "a")
        checkTok(t, s, 1, s.Scan(), '=', "=")
@@ -402,7 +402,7 @@ func TestScanWhitespace(t *testing.T) {
 }
 
 func testError(t *testing.T, src, pos, msg string, tok rune) {
-       s := new(Scanner).Init(bytes.NewBufferString(src))
+       s := new(Scanner).Init(strings.NewReader(src))
        errorCalled := false
        s.Error = func(s *Scanner, m string) {
                if !errorCalled {
@@ -491,13 +491,13 @@ func checkScanPos(t *testing.T, s *Scanner, offset, line, column int, char rune)
 
 func TestPos(t *testing.T) {
        // corner case: empty source
-       s := new(Scanner).Init(bytes.NewBufferString(""))
+       s := new(Scanner).Init(strings.NewReader(""))
        checkPos(t, s.Pos(), Position{Offset: 0, Line: 1, Column: 1})
        s.Peek() // peek doesn't affect the position
        checkPos(t, s.Pos(), Position{Offset: 0, Line: 1, Column: 1})
 
        // corner case: source with only a newline
-       s = new(Scanner).Init(bytes.NewBufferString("\n"))
+       s = new(Scanner).Init(strings.NewReader("\n"))
        checkPos(t, s.Pos(), Position{Offset: 0, Line: 1, Column: 1})
        checkNextPos(t, s, 1, 2, 1, '\n')
        // after EOF position doesn't change
@@ -509,7 +509,7 @@ func TestPos(t *testing.T) {
        }
 
        // corner case: source with only a single character
-       s = new(Scanner).Init(bytes.NewBufferString("本"))
+       s = new(Scanner).Init(strings.NewReader("本"))
        checkPos(t, s.Pos(), Position{Offset: 0, Line: 1, Column: 1})
        checkNextPos(t, s, 3, 1, 2, '本')
        // after EOF position doesn't change
@@ -521,7 +521,7 @@ func TestPos(t *testing.T) {
        }
 
        // positions after calling Next
-       s = new(Scanner).Init(bytes.NewBufferString("  foo६४  \n\n本語\n"))
+       s = new(Scanner).Init(strings.NewReader("  foo६४  \n\n本語\n"))
        checkNextPos(t, s, 1, 1, 2, ' ')
        s.Peek() // peek doesn't affect the position
        checkNextPos(t, s, 2, 1, 3, ' ')
@@ -546,7 +546,7 @@ func TestPos(t *testing.T) {
        }
 
        // positions after calling Scan
-       s = new(Scanner).Init(bytes.NewBufferString("abc\n本語\n\nx"))
+       s = new(Scanner).Init(strings.NewReader("abc\n本語\n\nx"))
        s.Mode = 0
        s.Whitespace = 0
        checkScanPos(t, s, 0, 1, 1, 'a')
index 722ac8d877a7fecb5ce30ddc7088137daafc3809..c0c32d5deca51d2057b4c4658be67486f2159284 100644 (file)
@@ -434,9 +434,13 @@ func (b *Writer) terminateCell(htab bool) int {
        return len(*line)
 }
 
-func handlePanic(err *error) {
+func handlePanic(err *error, op string) {
        if e := recover(); e != nil {
-               *err = e.(osError).err // re-panics if it's not a local osError
+               if nerr, ok := e.(osError); ok {
+                       *err = nerr.err
+                       return
+               }
+               panic("tabwriter: panic during " + op)
        }
 }
 
@@ -447,7 +451,7 @@ func handlePanic(err *error) {
 //
 func (b *Writer) Flush() (err error) {
        defer b.reset() // even in the presence of errors
-       defer handlePanic(&err)
+       defer handlePanic(&err, "Flush")
 
        // add current cell if not empty
        if b.cell.size > 0 {
@@ -471,7 +475,7 @@ var hbar = []byte("---\n")
 // while writing to the underlying output stream.
 //
 func (b *Writer) Write(buf []byte) (n int, err error) {
-       defer handlePanic(&err)
+       defer handlePanic(&err, "Write")
 
        // split text into cells
        n = 0
index b0526a03f738b616787e3a4ff4fab555b79c9b1a..9d3111e2c2730502017b5c86696dbbd10558cb74 100644 (file)
@@ -613,3 +613,40 @@ func Test(t *testing.T) {
                check(t, e.testname, e.minwidth, e.tabwidth, e.padding, e.padchar, e.flags, e.src, e.expected)
        }
 }
+
+type panicWriter struct{}
+
+func (panicWriter) Write([]byte) (int, error) {
+       panic("cannot write")
+}
+
+func wantPanicString(t *testing.T, want string) {
+       if e := recover(); e != nil {
+               got, ok := e.(string)
+               switch {
+               case !ok:
+                       t.Errorf("got %v (%T), want panic string", e, e)
+               case got != want:
+                       t.Errorf("wrong panic message: got %q, want %q", got, want)
+               }
+       }
+}
+
+func TestPanicDuringFlush(t *testing.T) {
+       defer wantPanicString(t, "tabwriter: panic during Flush")
+       var p panicWriter
+       w := new(Writer)
+       w.Init(p, 0, 0, 5, ' ', 0)
+       io.WriteString(w, "a")
+       w.Flush()
+       t.Errorf("failed to panic during Flush")
+}
+
+func TestPanicDuringWrite(t *testing.T) {
+       defer wantPanicString(t, "tabwriter: panic during Write")
+       var p panicWriter
+       w := new(Writer)
+       w.Init(p, 0, 0, 5, ' ', 0)
+       io.WriteString(w, "a\n\n") // the second \n triggers a call to w.Write and thus a panic
+       t.Errorf("failed to panic during Write")
+}
index 43b0b266eca77c742bded27274995308223e7b6e..6de37a19963f35a3c345b549f979e34babc42d36 100644 (file)
@@ -594,6 +594,9 @@ func (s *state) validateType(value reflect.Value, typ reflect.Type) reflect.Valu
                switch {
                case value.Kind() == reflect.Ptr && value.Type().Elem().AssignableTo(typ):
                        value = value.Elem()
+                       if !value.IsValid() {
+                               s.errorf("dereference of nil pointer of type %s", typ)
+                       }
                case reflect.PtrTo(value.Type()).AssignableTo(typ) && value.CanAddr():
                        value = value.Addr()
                default:
index f60702de8f14aea8041debc506e08f8b75f10eab..868f2cb94c392d649c6ab907e3d9c28cad8e646c 100644 (file)
@@ -512,6 +512,8 @@ var execTests = []execTest{
        {"bug9", "{{.cause}}", "neglect", map[string]string{"cause": "neglect"}, true},
        // Field chain starting with function did not work.
        {"bug10", "{{mapOfThree.three}}-{{(mapOfThree).three}}", "3-3", 0, true},
+       // Dereferencing nil pointer while evaluating function arguments should not panic. Issue 7333.
+       {"bug11", "{{valueString .PS}}", "", T{}, false},
 }
 
 func zeroArgs() string {
@@ -546,6 +548,11 @@ func vfunc(V, *V) string {
        return "vfunc"
 }
 
+// valueString takes a string, not a pointer.
+func valueString(v string) string {
+       return "value is ignored"
+}
+
 func add(args ...int) int {
        sum := 0
        for _, x := range args {
@@ -580,17 +587,18 @@ func mapOfThree() interface{} {
 func testExecute(execTests []execTest, template *Template, t *testing.T) {
        b := new(bytes.Buffer)
        funcs := FuncMap{
-               "add":        add,
-               "count":      count,
-               "dddArg":     dddArg,
-               "echo":       echo,
-               "makemap":    makemap,
-               "mapOfThree": mapOfThree,
-               "oneArg":     oneArg,
-               "stringer":   stringer,
-               "typeOf":     typeOf,
-               "vfunc":      vfunc,
-               "zeroArgs":   zeroArgs,
+               "add":         add,
+               "count":       count,
+               "dddArg":      dddArg,
+               "echo":        echo,
+               "makemap":     makemap,
+               "mapOfThree":  mapOfThree,
+               "oneArg":      oneArg,
+               "stringer":    stringer,
+               "typeOf":      typeOf,
+               "valueString": valueString,
+               "vfunc":       vfunc,
+               "zeroArgs":    zeroArgs,
        }
        for _, test := range execTests {
                var tmpl *Template
diff --git a/libgo/go/time/format_test.go b/libgo/go/time/format_test.go
new file mode 100644 (file)
index 0000000..9327339
--- /dev/null
@@ -0,0 +1,512 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package time_test
+
+import (
+       "fmt"
+       "strconv"
+       "strings"
+       "testing"
+       "testing/quick"
+       . "time"
+)
+
+type TimeFormatTest struct {
+       time           Time
+       formattedValue string
+}
+
+var rfc3339Formats = []TimeFormatTest{
+       {Date(2008, 9, 17, 20, 4, 26, 0, UTC), "2008-09-17T20:04:26Z"},
+       {Date(1994, 9, 17, 20, 4, 26, 0, FixedZone("EST", -18000)), "1994-09-17T20:04:26-05:00"},
+       {Date(2000, 12, 26, 1, 15, 6, 0, FixedZone("OTO", 15600)), "2000-12-26T01:15:06+04:20"},
+}
+
+func TestRFC3339Conversion(t *testing.T) {
+       for _, f := range rfc3339Formats {
+               if f.time.Format(RFC3339) != f.formattedValue {
+                       t.Error("RFC3339:")
+                       t.Errorf("  want=%+v", f.formattedValue)
+                       t.Errorf("  have=%+v", f.time.Format(RFC3339))
+               }
+       }
+}
+
+type FormatTest struct {
+       name   string
+       format string
+       result string
+}
+
+var formatTests = []FormatTest{
+       {"ANSIC", ANSIC, "Wed Feb  4 21:00:57 2009"},
+       {"UnixDate", UnixDate, "Wed Feb  4 21:00:57 PST 2009"},
+       {"RubyDate", RubyDate, "Wed Feb 04 21:00:57 -0800 2009"},
+       {"RFC822", RFC822, "04 Feb 09 21:00 PST"},
+       {"RFC850", RFC850, "Wednesday, 04-Feb-09 21:00:57 PST"},
+       {"RFC1123", RFC1123, "Wed, 04 Feb 2009 21:00:57 PST"},
+       {"RFC1123Z", RFC1123Z, "Wed, 04 Feb 2009 21:00:57 -0800"},
+       {"RFC3339", RFC3339, "2009-02-04T21:00:57-08:00"},
+       {"RFC3339Nano", RFC3339Nano, "2009-02-04T21:00:57.0123456-08:00"},
+       {"Kitchen", Kitchen, "9:00PM"},
+       {"am/pm", "3pm", "9pm"},
+       {"AM/PM", "3PM", "9PM"},
+       {"two-digit year", "06 01 02", "09 02 04"},
+       // Three-letter months and days must not be followed by lower-case letter.
+       {"Janet", "Hi Janet, the Month is January", "Hi Janet, the Month is February"},
+       // Time stamps, Fractional seconds.
+       {"Stamp", Stamp, "Feb  4 21:00:57"},
+       {"StampMilli", StampMilli, "Feb  4 21:00:57.012"},
+       {"StampMicro", StampMicro, "Feb  4 21:00:57.012345"},
+       {"StampNano", StampNano, "Feb  4 21:00:57.012345600"},
+}
+
+func TestFormat(t *testing.T) {
+       // The numeric time represents Thu Feb  4 21:00:57.012345600 PST 2010
+       time := Unix(0, 1233810057012345600)
+       for _, test := range formatTests {
+               result := time.Format(test.format)
+               if result != test.result {
+                       t.Errorf("%s expected %q got %q", test.name, test.result, result)
+               }
+       }
+}
+
+func TestFormatShortYear(t *testing.T) {
+       years := []int{
+               -100001, -100000, -99999,
+               -10001, -10000, -9999,
+               -1001, -1000, -999,
+               -101, -100, -99,
+               -11, -10, -9,
+               -1, 0, 1,
+               9, 10, 11,
+               99, 100, 101,
+               999, 1000, 1001,
+               9999, 10000, 10001,
+               99999, 100000, 100001,
+       }
+
+       for _, y := range years {
+               time := Date(y, January, 1, 0, 0, 0, 0, UTC)
+               result := time.Format("2006.01.02")
+               var want string
+               if y < 0 {
+                       // The 4 in %04d counts the - sign, so print -y instead
+                       // and introduce our own - sign.
+                       want = fmt.Sprintf("-%04d.%02d.%02d", -y, 1, 1)
+               } else {
+                       want = fmt.Sprintf("%04d.%02d.%02d", y, 1, 1)
+               }
+               if result != want {
+                       t.Errorf("(jan 1 %d).Format(\"2006.01.02\") = %q, want %q", y, result, want)
+               }
+       }
+}
+
+type ParseTest struct {
+       name       string
+       format     string
+       value      string
+       hasTZ      bool // contains a time zone
+       hasWD      bool // contains a weekday
+       yearSign   int  // sign of year, -1 indicates the year is not present in the format
+       fracDigits int  // number of digits of fractional second
+}
+
+var parseTests = []ParseTest{
+       {"ANSIC", ANSIC, "Thu Feb  4 21:00:57 2010", false, true, 1, 0},
+       {"UnixDate", UnixDate, "Thu Feb  4 21:00:57 PST 2010", true, true, 1, 0},
+       {"RubyDate", RubyDate, "Thu Feb 04 21:00:57 -0800 2010", true, true, 1, 0},
+       {"RFC850", RFC850, "Thursday, 04-Feb-10 21:00:57 PST", true, true, 1, 0},
+       {"RFC1123", RFC1123, "Thu, 04 Feb 2010 21:00:57 PST", true, true, 1, 0},
+       {"RFC1123", RFC1123, "Thu, 04 Feb 2010 22:00:57 PDT", true, true, 1, 0},
+       {"RFC1123Z", RFC1123Z, "Thu, 04 Feb 2010 21:00:57 -0800", true, true, 1, 0},
+       {"RFC3339", RFC3339, "2010-02-04T21:00:57-08:00", true, false, 1, 0},
+       {"custom: \"2006-01-02 15:04:05-07\"", "2006-01-02 15:04:05-07", "2010-02-04 21:00:57-08", true, false, 1, 0},
+       // Optional fractional seconds.
+       {"ANSIC", ANSIC, "Thu Feb  4 21:00:57.0 2010", false, true, 1, 1},
+       {"UnixDate", UnixDate, "Thu Feb  4 21:00:57.01 PST 2010", true, true, 1, 2},
+       {"RubyDate", RubyDate, "Thu Feb 04 21:00:57.012 -0800 2010", true, true, 1, 3},
+       {"RFC850", RFC850, "Thursday, 04-Feb-10 21:00:57.0123 PST", true, true, 1, 4},
+       {"RFC1123", RFC1123, "Thu, 04 Feb 2010 21:00:57.01234 PST", true, true, 1, 5},
+       {"RFC1123Z", RFC1123Z, "Thu, 04 Feb 2010 21:00:57.01234 -0800", true, true, 1, 5},
+       {"RFC3339", RFC3339, "2010-02-04T21:00:57.012345678-08:00", true, false, 1, 9},
+       {"custom: \"2006-01-02 15:04:05\"", "2006-01-02 15:04:05", "2010-02-04 21:00:57.0", false, false, 1, 0},
+       // Amount of white space should not matter.
+       {"ANSIC", ANSIC, "Thu Feb 4 21:00:57 2010", false, true, 1, 0},
+       {"ANSIC", ANSIC, "Thu      Feb     4     21:00:57     2010", false, true, 1, 0},
+       // Case should not matter
+       {"ANSIC", ANSIC, "THU FEB 4 21:00:57 2010", false, true, 1, 0},
+       {"ANSIC", ANSIC, "thu feb 4 21:00:57 2010", false, true, 1, 0},
+       // Fractional seconds.
+       {"millisecond", "Mon Jan _2 15:04:05.000 2006", "Thu Feb  4 21:00:57.012 2010", false, true, 1, 3},
+       {"microsecond", "Mon Jan _2 15:04:05.000000 2006", "Thu Feb  4 21:00:57.012345 2010", false, true, 1, 6},
+       {"nanosecond", "Mon Jan _2 15:04:05.000000000 2006", "Thu Feb  4 21:00:57.012345678 2010", false, true, 1, 9},
+       // Leading zeros in other places should not be taken as fractional seconds.
+       {"zero1", "2006.01.02.15.04.05.0", "2010.02.04.21.00.57.0", false, false, 1, 1},
+       {"zero2", "2006.01.02.15.04.05.00", "2010.02.04.21.00.57.01", false, false, 1, 2},
+       // Month and day names only match when not followed by a lower-case letter.
+       {"Janet", "Hi Janet, the Month is January: Jan _2 15:04:05 2006", "Hi Janet, the Month is February: Feb  4 21:00:57 2010", false, true, 1, 0},
+
+       // GMT with offset.
+       {"GMT-8", UnixDate, "Fri Feb  5 05:00:57 GMT-8 2010", true, true, 1, 0},
+
+       // Accept any number of fractional second digits (including none) for .999...
+       // In Go 1, .999... was completely ignored in the format, meaning the first two
+       // cases would succeed, but the next four would not. Go 1.1 accepts all six.
+       {"", "2006-01-02 15:04:05.9999 -0700 MST", "2010-02-04 21:00:57 -0800 PST", true, false, 1, 0},
+       {"", "2006-01-02 15:04:05.999999999 -0700 MST", "2010-02-04 21:00:57 -0800 PST", true, false, 1, 0},
+       {"", "2006-01-02 15:04:05.9999 -0700 MST", "2010-02-04 21:00:57.0123 -0800 PST", true, false, 1, 4},
+       {"", "2006-01-02 15:04:05.999999999 -0700 MST", "2010-02-04 21:00:57.0123 -0800 PST", true, false, 1, 4},
+       {"", "2006-01-02 15:04:05.9999 -0700 MST", "2010-02-04 21:00:57.012345678 -0800 PST", true, false, 1, 9},
+       {"", "2006-01-02 15:04:05.999999999 -0700 MST", "2010-02-04 21:00:57.012345678 -0800 PST", true, false, 1, 9},
+
+       // issue 4502.
+       {"", StampNano, "Feb  4 21:00:57.012345678", false, false, -1, 9},
+       {"", "Jan _2 15:04:05.999", "Feb  4 21:00:57.012300000", false, false, -1, 4},
+       {"", "Jan _2 15:04:05.999", "Feb  4 21:00:57.012345678", false, false, -1, 9},
+       {"", "Jan _2 15:04:05.999999999", "Feb  4 21:00:57.0123", false, false, -1, 4},
+       {"", "Jan _2 15:04:05.999999999", "Feb  4 21:00:57.012345678", false, false, -1, 9},
+}
+
+func TestParse(t *testing.T) {
+       for _, test := range parseTests {
+               time, err := Parse(test.format, test.value)
+               if err != nil {
+                       t.Errorf("%s error: %v", test.name, err)
+               } else {
+                       checkTime(time, &test, t)
+               }
+       }
+}
+
+func TestParseInSydney(t *testing.T) {
+       loc, err := LoadLocation("Australia/Sydney")
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       // Check that Parse (and ParseInLocation) understand
+       // that Feb EST and Aug EST are different time zones in Sydney
+       // even though both are called EST.
+       t1, err := ParseInLocation("Jan 02 2006 MST", "Feb 01 2013 EST", loc)
+       if err != nil {
+               t.Fatal(err)
+       }
+       t2 := Date(2013, February, 1, 00, 00, 00, 0, loc)
+       if t1 != t2 {
+               t.Fatalf("ParseInLocation(Feb 01 2013 EST, Sydney) = %v, want %v", t1, t2)
+       }
+       _, offset := t1.Zone()
+       if offset != 11*60*60 {
+               t.Fatalf("ParseInLocation(Feb 01 2013 EST, Sydney).Zone = _, %d, want _, %d", offset, 11*60*60)
+       }
+
+       t1, err = ParseInLocation("Jan 02 2006 MST", "Aug 01 2013 EST", loc)
+       if err != nil {
+               t.Fatal(err)
+       }
+       t2 = Date(2013, August, 1, 00, 00, 00, 0, loc)
+       if t1 != t2 {
+               t.Fatalf("ParseInLocation(Aug 01 2013 EST, Sydney) = %v, want %v", t1, t2)
+       }
+       _, offset = t1.Zone()
+       if offset != 10*60*60 {
+               t.Fatalf("ParseInLocation(Aug 01 2013 EST, Sydney).Zone = _, %d, want _, %d", offset, 10*60*60)
+       }
+}
+
+func TestLoadLocationZipFile(t *testing.T) {
+       t.Skip("gccgo does not use the zip file")
+
+       ForceZipFileForTesting(true)
+       defer ForceZipFileForTesting(false)
+
+       _, err := LoadLocation("Australia/Sydney")
+       if err != nil {
+               t.Fatal(err)
+       }
+}
+
+var rubyTests = []ParseTest{
+       {"RubyDate", RubyDate, "Thu Feb 04 21:00:57 -0800 2010", true, true, 1, 0},
+       // Ignore the time zone in the test. If it parses, it'll be OK.
+       {"RubyDate", RubyDate, "Thu Feb 04 21:00:57 -0000 2010", false, true, 1, 0},
+       {"RubyDate", RubyDate, "Thu Feb 04 21:00:57 +0000 2010", false, true, 1, 0},
+       {"RubyDate", RubyDate, "Thu Feb 04 21:00:57 +1130 2010", false, true, 1, 0},
+}
+
+// Problematic time zone format needs special tests.
+func TestRubyParse(t *testing.T) {
+       for _, test := range rubyTests {
+               time, err := Parse(test.format, test.value)
+               if err != nil {
+                       t.Errorf("%s error: %v", test.name, err)
+               } else {
+                       checkTime(time, &test, t)
+               }
+       }
+}
+
+func checkTime(time Time, test *ParseTest, t *testing.T) {
+       // The time should be Thu Feb  4 21:00:57 PST 2010
+       if test.yearSign >= 0 && test.yearSign*time.Year() != 2010 {
+               t.Errorf("%s: bad year: %d not %d", test.name, time.Year(), 2010)
+       }
+       if time.Month() != February {
+               t.Errorf("%s: bad month: %s not %s", test.name, time.Month(), February)
+       }
+       if time.Day() != 4 {
+               t.Errorf("%s: bad day: %d not %d", test.name, time.Day(), 4)
+       }
+       if time.Hour() != 21 {
+               t.Errorf("%s: bad hour: %d not %d", test.name, time.Hour(), 21)
+       }
+       if time.Minute() != 0 {
+               t.Errorf("%s: bad minute: %d not %d", test.name, time.Minute(), 0)
+       }
+       if time.Second() != 57 {
+               t.Errorf("%s: bad second: %d not %d", test.name, time.Second(), 57)
+       }
+       // Nanoseconds must be checked against the precision of the input.
+       nanosec, err := strconv.ParseUint("012345678"[:test.fracDigits]+"000000000"[:9-test.fracDigits], 10, 0)
+       if err != nil {
+               panic(err)
+       }
+       if time.Nanosecond() != int(nanosec) {
+               t.Errorf("%s: bad nanosecond: %d not %d", test.name, time.Nanosecond(), nanosec)
+       }
+       name, offset := time.Zone()
+       if test.hasTZ && offset != -28800 {
+               t.Errorf("%s: bad tz offset: %s %d not %d", test.name, name, offset, -28800)
+       }
+       if test.hasWD && time.Weekday() != Thursday {
+               t.Errorf("%s: bad weekday: %s not %s", test.name, time.Weekday(), Thursday)
+       }
+}
+
+func TestFormatAndParse(t *testing.T) {
+       const fmt = "Mon MST " + RFC3339 // all fields
+       f := func(sec int64) bool {
+               t1 := Unix(sec, 0)
+               if t1.Year() < 1000 || t1.Year() > 9999 {
+                       // not required to work
+                       return true
+               }
+               t2, err := Parse(fmt, t1.Format(fmt))
+               if err != nil {
+                       t.Errorf("error: %s", err)
+                       return false
+               }
+               if t1.Unix() != t2.Unix() || t1.Nanosecond() != t2.Nanosecond() {
+                       t.Errorf("FormatAndParse %d: %q(%d) %q(%d)", sec, t1, t1.Unix(), t2, t2.Unix())
+                       return false
+               }
+               return true
+       }
+       f32 := func(sec int32) bool { return f(int64(sec)) }
+       cfg := &quick.Config{MaxCount: 10000}
+
+       // Try a reasonable date first, then the huge ones.
+       if err := quick.Check(f32, cfg); err != nil {
+               t.Fatal(err)
+       }
+       if err := quick.Check(f, cfg); err != nil {
+               t.Fatal(err)
+       }
+}
+
+type ParseTimeZoneTest struct {
+       value  string
+       length int
+       ok     bool
+}
+
+var parseTimeZoneTests = []ParseTimeZoneTest{
+       {"gmt hi there", 0, false},
+       {"GMT hi there", 3, true},
+       {"GMT+12 hi there", 6, true},
+       {"GMT+00 hi there", 3, true}, // 0 or 00 is not a legal offset.
+       {"GMT-5 hi there", 5, true},
+       {"GMT-51 hi there", 3, true},
+       {"ChST hi there", 4, true},
+       {"MSDx", 3, true},
+       {"MSDY", 0, false}, // four letters must end in T.
+       {"ESAST hi", 5, true},
+       {"ESASTT hi", 0, false}, // run of upper-case letters too long.
+       {"ESATY hi", 0, false},  // five letters must end in T.
+}
+
+func TestParseTimeZone(t *testing.T) {
+       for _, test := range parseTimeZoneTests {
+               length, ok := ParseTimeZone(test.value)
+               if ok != test.ok {
+                       t.Errorf("expected %t for %q got %t", test.ok, test.value, ok)
+               } else if length != test.length {
+                       t.Errorf("expected %d for %q got %d", test.length, test.value, length)
+               }
+       }
+}
+
+type ParseErrorTest struct {
+       format string
+       value  string
+       expect string // must appear within the error
+}
+
+var parseErrorTests = []ParseErrorTest{
+       {ANSIC, "Feb  4 21:00:60 2010", "cannot parse"}, // cannot parse Feb as Mon
+       {ANSIC, "Thu Feb  4 21:00:57 @2010", "cannot parse"},
+       {ANSIC, "Thu Feb  4 21:00:60 2010", "second out of range"},
+       {ANSIC, "Thu Feb  4 21:61:57 2010", "minute out of range"},
+       {ANSIC, "Thu Feb  4 24:00:60 2010", "hour out of range"},
+       {"Mon Jan _2 15:04:05.000 2006", "Thu Feb  4 23:00:59x01 2010", "cannot parse"},
+       {"Mon Jan _2 15:04:05.000 2006", "Thu Feb  4 23:00:59.xxx 2010", "cannot parse"},
+       {"Mon Jan _2 15:04:05.000 2006", "Thu Feb  4 23:00:59.-123 2010", "fractional second out of range"},
+       // issue 4502. StampNano requires exactly 9 digits of precision.
+       {StampNano, "Dec  7 11:22:01.000000", `cannot parse ".000000" as ".000000000"`},
+       {StampNano, "Dec  7 11:22:01.0000000000", "extra text: 0"},
+       // issue 4493. Helpful errors.
+       {RFC3339, "2006-01-02T15:04:05Z07:00", `parsing time "2006-01-02T15:04:05Z07:00": extra text: 07:00`},
+       {RFC3339, "2006-01-02T15:04_abc", `parsing time "2006-01-02T15:04_abc" as "2006-01-02T15:04:05Z07:00": cannot parse "_abc" as ":"`},
+       {RFC3339, "2006-01-02T15:04:05_abc", `parsing time "2006-01-02T15:04:05_abc" as "2006-01-02T15:04:05Z07:00": cannot parse "_abc" as "Z07:00"`},
+       {RFC3339, "2006-01-02T15:04:05Z_abc", `parsing time "2006-01-02T15:04:05Z_abc": extra text: _abc`},
+}
+
+func TestParseErrors(t *testing.T) {
+       for _, test := range parseErrorTests {
+               _, err := Parse(test.format, test.value)
+               if err == nil {
+                       t.Errorf("expected error for %q %q", test.format, test.value)
+               } else if strings.Index(err.Error(), test.expect) < 0 {
+                       t.Errorf("expected error with %q for %q %q; got %s", test.expect, test.format, test.value, err)
+               }
+       }
+}
+
+func TestNoonIs12PM(t *testing.T) {
+       noon := Date(0, January, 1, 12, 0, 0, 0, UTC)
+       const expect = "12:00PM"
+       got := noon.Format("3:04PM")
+       if got != expect {
+               t.Errorf("got %q; expect %q", got, expect)
+       }
+       got = noon.Format("03:04PM")
+       if got != expect {
+               t.Errorf("got %q; expect %q", got, expect)
+       }
+}
+
+func TestMidnightIs12AM(t *testing.T) {
+       midnight := Date(0, January, 1, 0, 0, 0, 0, UTC)
+       expect := "12:00AM"
+       got := midnight.Format("3:04PM")
+       if got != expect {
+               t.Errorf("got %q; expect %q", got, expect)
+       }
+       got = midnight.Format("03:04PM")
+       if got != expect {
+               t.Errorf("got %q; expect %q", got, expect)
+       }
+}
+
+func Test12PMIsNoon(t *testing.T) {
+       noon, err := Parse("3:04PM", "12:00PM")
+       if err != nil {
+               t.Fatal("error parsing date:", err)
+       }
+       if noon.Hour() != 12 {
+               t.Errorf("got %d; expect 12", noon.Hour())
+       }
+       noon, err = Parse("03:04PM", "12:00PM")
+       if err != nil {
+               t.Fatal("error parsing date:", err)
+       }
+       if noon.Hour() != 12 {
+               t.Errorf("got %d; expect 12", noon.Hour())
+       }
+}
+
+func Test12AMIsMidnight(t *testing.T) {
+       midnight, err := Parse("3:04PM", "12:00AM")
+       if err != nil {
+               t.Fatal("error parsing date:", err)
+       }
+       if midnight.Hour() != 0 {
+               t.Errorf("got %d; expect 0", midnight.Hour())
+       }
+       midnight, err = Parse("03:04PM", "12:00AM")
+       if err != nil {
+               t.Fatal("error parsing date:", err)
+       }
+       if midnight.Hour() != 0 {
+               t.Errorf("got %d; expect 0", midnight.Hour())
+       }
+}
+
+// Check that a time without a Zone still produces a (numeric) time zone
+// when formatted with MST as a requested zone.
+func TestMissingZone(t *testing.T) {
+       time, err := Parse(RubyDate, "Thu Feb 02 16:10:03 -0500 2006")
+       if err != nil {
+               t.Fatal("error parsing date:", err)
+       }
+       expect := "Thu Feb  2 16:10:03 -0500 2006" // -0500 not EST
+       str := time.Format(UnixDate)               // uses MST as its time zone
+       if str != expect {
+               t.Errorf("got %s; expect %s", str, expect)
+       }
+}
+
+func TestMinutesInTimeZone(t *testing.T) {
+       time, err := Parse(RubyDate, "Mon Jan 02 15:04:05 +0123 2006")
+       if err != nil {
+               t.Fatal("error parsing date:", err)
+       }
+       expected := (1*60 + 23) * 60
+       _, offset := time.Zone()
+       if offset != expected {
+               t.Errorf("ZoneOffset = %d, want %d", offset, expected)
+       }
+}
+
+type SecondsTimeZoneOffsetTest struct {
+       format         string
+       value          string
+       expectedoffset int
+}
+
+var secondsTimeZoneOffsetTests = []SecondsTimeZoneOffsetTest{
+       {"2006-01-02T15:04:05-070000", "1871-01-01T05:33:02-003408", -(34*60 + 8)},
+       {"2006-01-02T15:04:05-07:00:00", "1871-01-01T05:33:02-00:34:08", -(34*60 + 8)},
+       {"2006-01-02T15:04:05-070000", "1871-01-01T05:33:02+003408", 34*60 + 8},
+       {"2006-01-02T15:04:05-07:00:00", "1871-01-01T05:33:02+00:34:08", 34*60 + 8},
+       {"2006-01-02T15:04:05Z070000", "1871-01-01T05:33:02-003408", -(34*60 + 8)},
+       {"2006-01-02T15:04:05Z07:00:00", "1871-01-01T05:33:02+00:34:08", 34*60 + 8},
+}
+
+func TestParseSecondsInTimeZone(t *testing.T) {
+       // should accept timezone offsets with seconds like: Zone America/New_York   -4:56:02 -      LMT     1883 Nov 18 12:03:58
+       for _, test := range secondsTimeZoneOffsetTests {
+               time, err := Parse(test.format, test.value)
+               if err != nil {
+                       t.Fatal("error parsing date:", err)
+               }
+               _, offset := time.Zone()
+               if offset != test.expectedoffset {
+                       t.Errorf("ZoneOffset = %d, want %d", offset, test.expectedoffset)
+               }
+       }
+}
+
+func TestFormatSecondsInTimeZone(t *testing.T) {
+       d := Date(1871, 9, 17, 20, 4, 26, 0, FixedZone("LMT", -(34*60+8)))
+       timestr := d.Format("2006-01-02T15:04:05Z070000")
+       expected := "1871-09-17T20:04:26-003408"
+       if timestr != expected {
+               t.Errorf("Got %s, want %s", timestr, expected)
+       }
+}
index 87fdd3216fa7cc213e1ec83ae30043466c582c4d..4ba6d478debac433b4307e657be6251b97bad1a7 100644 (file)
@@ -36,9 +36,13 @@ func CheckRuntimeTimerOverflow() error {
        startTimer(r)
 
        timeout := 100 * Millisecond
-       if runtime.GOOS == "windows" {
-               // Allow more time for gobuilder to succeed.
+       switch runtime.GOOS {
+       // Allow more time for gobuilder to succeed.
+       case "windows":
                timeout = Second
+       case "plan9":
+               // TODO(0intro): We don't know why it is needed.
+               timeout = 3 * Second
        }
 
        // Start a goroutine that should send on t.C before the timeout.
@@ -74,7 +78,15 @@ func CheckRuntimeTimerOverflow() error {
                        if Now().After(stop) {
                                return errors.New("runtime timer stuck: overflow in addtimer")
                        }
-                       runtime.Gosched()
+                       // Issue 6874. This test previously called runtime.Gosched to try to yield
+                       // to the goroutine servicing t, however the scheduler has a bias towards the
+                       // previously running goroutine in an idle system. Combined with high load due
+                       // to all CPUs busy running tests t's goroutine could be delayed beyond the
+                       // timeout window.
+                       //
+                       // Calling runtime.GC() reduces the worst case lantency for scheduling t by 20x
+                       // under the current Go 1.3 scheduler.
+                       runtime.GC()
                }
        }
 }
index cb09a84469ee4a771dbe69453ba1d8e571fc0dff..e86e294ee7a4aba8f8d74f377fe3dc14bc39080f 100644 (file)
@@ -399,6 +399,9 @@ func TestIssue5745(t *testing.T) {
 }
 
 func TestOverflowRuntimeTimer(t *testing.T) {
+       if testing.Short() {
+               t.Skip("skipping in short mode, see issue 6874")
+       }
        if err := CheckRuntimeTimerOverflow(); err != nil {
                t.Fatalf(err.Error())
        }
index 60a3ce08f906f0587c6f41e91bc6d696d1b1aab1..36c214b6b093b99d3df23918807bd654d76eae24 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin dragonfly freebsd linux netbsd openbsd
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package time
 
index 77429b836b21f1286ab9c0f0873e934b8084838f..2615517d9ad13c08188214d2f2418915cb7df644 100644 (file)
@@ -12,8 +12,6 @@ import (
        "math/big"
        "math/rand"
        "runtime"
-       "strconv"
-       "strings"
        "testing"
        "testing/quick"
        . "time"
@@ -372,504 +370,6 @@ func TestTruncateRound(t *testing.T) {
        quick.Check(f4, cfg)
 }
 
-type TimeFormatTest struct {
-       time           Time
-       formattedValue string
-}
-
-var rfc3339Formats = []TimeFormatTest{
-       {Date(2008, 9, 17, 20, 4, 26, 0, UTC), "2008-09-17T20:04:26Z"},
-       {Date(1994, 9, 17, 20, 4, 26, 0, FixedZone("EST", -18000)), "1994-09-17T20:04:26-05:00"},
-       {Date(2000, 12, 26, 1, 15, 6, 0, FixedZone("OTO", 15600)), "2000-12-26T01:15:06+04:20"},
-}
-
-func TestRFC3339Conversion(t *testing.T) {
-       for _, f := range rfc3339Formats {
-               if f.time.Format(RFC3339) != f.formattedValue {
-                       t.Error("RFC3339:")
-                       t.Errorf("  want=%+v", f.formattedValue)
-                       t.Errorf("  have=%+v", f.time.Format(RFC3339))
-               }
-       }
-}
-
-type FormatTest struct {
-       name   string
-       format string
-       result string
-}
-
-var formatTests = []FormatTest{
-       {"ANSIC", ANSIC, "Wed Feb  4 21:00:57 2009"},
-       {"UnixDate", UnixDate, "Wed Feb  4 21:00:57 PST 2009"},
-       {"RubyDate", RubyDate, "Wed Feb 04 21:00:57 -0800 2009"},
-       {"RFC822", RFC822, "04 Feb 09 21:00 PST"},
-       {"RFC850", RFC850, "Wednesday, 04-Feb-09 21:00:57 PST"},
-       {"RFC1123", RFC1123, "Wed, 04 Feb 2009 21:00:57 PST"},
-       {"RFC1123Z", RFC1123Z, "Wed, 04 Feb 2009 21:00:57 -0800"},
-       {"RFC3339", RFC3339, "2009-02-04T21:00:57-08:00"},
-       {"RFC3339Nano", RFC3339Nano, "2009-02-04T21:00:57.0123456-08:00"},
-       {"Kitchen", Kitchen, "9:00PM"},
-       {"am/pm", "3pm", "9pm"},
-       {"AM/PM", "3PM", "9PM"},
-       {"two-digit year", "06 01 02", "09 02 04"},
-       // Three-letter months and days must not be followed by lower-case letter.
-       {"Janet", "Hi Janet, the Month is January", "Hi Janet, the Month is February"},
-       // Time stamps, Fractional seconds.
-       {"Stamp", Stamp, "Feb  4 21:00:57"},
-       {"StampMilli", StampMilli, "Feb  4 21:00:57.012"},
-       {"StampMicro", StampMicro, "Feb  4 21:00:57.012345"},
-       {"StampNano", StampNano, "Feb  4 21:00:57.012345600"},
-}
-
-func TestFormat(t *testing.T) {
-       // The numeric time represents Thu Feb  4 21:00:57.012345600 PST 2010
-       time := Unix(0, 1233810057012345600)
-       for _, test := range formatTests {
-               result := time.Format(test.format)
-               if result != test.result {
-                       t.Errorf("%s expected %q got %q", test.name, test.result, result)
-               }
-       }
-}
-
-func TestFormatShortYear(t *testing.T) {
-       years := []int{
-               -100001, -100000, -99999,
-               -10001, -10000, -9999,
-               -1001, -1000, -999,
-               -101, -100, -99,
-               -11, -10, -9,
-               -1, 0, 1,
-               9, 10, 11,
-               99, 100, 101,
-               999, 1000, 1001,
-               9999, 10000, 10001,
-               99999, 100000, 100001,
-       }
-
-       for _, y := range years {
-               time := Date(y, January, 1, 0, 0, 0, 0, UTC)
-               result := time.Format("2006.01.02")
-               var want string
-               if y < 0 {
-                       // The 4 in %04d counts the - sign, so print -y instead
-                       // and introduce our own - sign.
-                       want = fmt.Sprintf("-%04d.%02d.%02d", -y, 1, 1)
-               } else {
-                       want = fmt.Sprintf("%04d.%02d.%02d", y, 1, 1)
-               }
-               if result != want {
-                       t.Errorf("(jan 1 %d).Format(\"2006.01.02\") = %q, want %q", y, result, want)
-               }
-       }
-}
-
-type ParseTest struct {
-       name       string
-       format     string
-       value      string
-       hasTZ      bool // contains a time zone
-       hasWD      bool // contains a weekday
-       yearSign   int  // sign of year, -1 indicates the year is not present in the format
-       fracDigits int  // number of digits of fractional second
-}
-
-var parseTests = []ParseTest{
-       {"ANSIC", ANSIC, "Thu Feb  4 21:00:57 2010", false, true, 1, 0},
-       {"UnixDate", UnixDate, "Thu Feb  4 21:00:57 PST 2010", true, true, 1, 0},
-       {"RubyDate", RubyDate, "Thu Feb 04 21:00:57 -0800 2010", true, true, 1, 0},
-       {"RFC850", RFC850, "Thursday, 04-Feb-10 21:00:57 PST", true, true, 1, 0},
-       {"RFC1123", RFC1123, "Thu, 04 Feb 2010 21:00:57 PST", true, true, 1, 0},
-       {"RFC1123", RFC1123, "Thu, 04 Feb 2010 22:00:57 PDT", true, true, 1, 0},
-       {"RFC1123Z", RFC1123Z, "Thu, 04 Feb 2010 21:00:57 -0800", true, true, 1, 0},
-       {"RFC3339", RFC3339, "2010-02-04T21:00:57-08:00", true, false, 1, 0},
-       {"custom: \"2006-01-02 15:04:05-07\"", "2006-01-02 15:04:05-07", "2010-02-04 21:00:57-08", true, false, 1, 0},
-       // Optional fractional seconds.
-       {"ANSIC", ANSIC, "Thu Feb  4 21:00:57.0 2010", false, true, 1, 1},
-       {"UnixDate", UnixDate, "Thu Feb  4 21:00:57.01 PST 2010", true, true, 1, 2},
-       {"RubyDate", RubyDate, "Thu Feb 04 21:00:57.012 -0800 2010", true, true, 1, 3},
-       {"RFC850", RFC850, "Thursday, 04-Feb-10 21:00:57.0123 PST", true, true, 1, 4},
-       {"RFC1123", RFC1123, "Thu, 04 Feb 2010 21:00:57.01234 PST", true, true, 1, 5},
-       {"RFC1123Z", RFC1123Z, "Thu, 04 Feb 2010 21:00:57.01234 -0800", true, true, 1, 5},
-       {"RFC3339", RFC3339, "2010-02-04T21:00:57.012345678-08:00", true, false, 1, 9},
-       {"custom: \"2006-01-02 15:04:05\"", "2006-01-02 15:04:05", "2010-02-04 21:00:57.0", false, false, 1, 0},
-       // Amount of white space should not matter.
-       {"ANSIC", ANSIC, "Thu Feb 4 21:00:57 2010", false, true, 1, 0},
-       {"ANSIC", ANSIC, "Thu      Feb     4     21:00:57     2010", false, true, 1, 0},
-       // Case should not matter
-       {"ANSIC", ANSIC, "THU FEB 4 21:00:57 2010", false, true, 1, 0},
-       {"ANSIC", ANSIC, "thu feb 4 21:00:57 2010", false, true, 1, 0},
-       // Fractional seconds.
-       {"millisecond", "Mon Jan _2 15:04:05.000 2006", "Thu Feb  4 21:00:57.012 2010", false, true, 1, 3},
-       {"microsecond", "Mon Jan _2 15:04:05.000000 2006", "Thu Feb  4 21:00:57.012345 2010", false, true, 1, 6},
-       {"nanosecond", "Mon Jan _2 15:04:05.000000000 2006", "Thu Feb  4 21:00:57.012345678 2010", false, true, 1, 9},
-       // Leading zeros in other places should not be taken as fractional seconds.
-       {"zero1", "2006.01.02.15.04.05.0", "2010.02.04.21.00.57.0", false, false, 1, 1},
-       {"zero2", "2006.01.02.15.04.05.00", "2010.02.04.21.00.57.01", false, false, 1, 2},
-       // Month and day names only match when not followed by a lower-case letter.
-       {"Janet", "Hi Janet, the Month is January: Jan _2 15:04:05 2006", "Hi Janet, the Month is February: Feb  4 21:00:57 2010", false, true, 1, 0},
-
-       // GMT with offset.
-       {"GMT-8", UnixDate, "Fri Feb  5 05:00:57 GMT-8 2010", true, true, 1, 0},
-
-       // Accept any number of fractional second digits (including none) for .999...
-       // In Go 1, .999... was completely ignored in the format, meaning the first two
-       // cases would succeed, but the next four would not. Go 1.1 accepts all six.
-       {"", "2006-01-02 15:04:05.9999 -0700 MST", "2010-02-04 21:00:57 -0800 PST", true, false, 1, 0},
-       {"", "2006-01-02 15:04:05.999999999 -0700 MST", "2010-02-04 21:00:57 -0800 PST", true, false, 1, 0},
-       {"", "2006-01-02 15:04:05.9999 -0700 MST", "2010-02-04 21:00:57.0123 -0800 PST", true, false, 1, 4},
-       {"", "2006-01-02 15:04:05.999999999 -0700 MST", "2010-02-04 21:00:57.0123 -0800 PST", true, false, 1, 4},
-       {"", "2006-01-02 15:04:05.9999 -0700 MST", "2010-02-04 21:00:57.012345678 -0800 PST", true, false, 1, 9},
-       {"", "2006-01-02 15:04:05.999999999 -0700 MST", "2010-02-04 21:00:57.012345678 -0800 PST", true, false, 1, 9},
-
-       // issue 4502.
-       {"", StampNano, "Feb  4 21:00:57.012345678", false, false, -1, 9},
-       {"", "Jan _2 15:04:05.999", "Feb  4 21:00:57.012300000", false, false, -1, 4},
-       {"", "Jan _2 15:04:05.999", "Feb  4 21:00:57.012345678", false, false, -1, 9},
-       {"", "Jan _2 15:04:05.999999999", "Feb  4 21:00:57.0123", false, false, -1, 4},
-       {"", "Jan _2 15:04:05.999999999", "Feb  4 21:00:57.012345678", false, false, -1, 9},
-}
-
-func TestParse(t *testing.T) {
-       for _, test := range parseTests {
-               time, err := Parse(test.format, test.value)
-               if err != nil {
-                       t.Errorf("%s error: %v", test.name, err)
-               } else {
-                       checkTime(time, &test, t)
-               }
-       }
-}
-
-func TestParseInSydney(t *testing.T) {
-       loc, err := LoadLocation("Australia/Sydney")
-       if err != nil {
-               t.Fatal(err)
-       }
-
-       // Check that Parse (and ParseInLocation) understand
-       // that Feb EST and Aug EST are different time zones in Sydney
-       // even though both are called EST.
-       t1, err := ParseInLocation("Jan 02 2006 MST", "Feb 01 2013 EST", loc)
-       if err != nil {
-               t.Fatal(err)
-       }
-       t2 := Date(2013, February, 1, 00, 00, 00, 0, loc)
-       if t1 != t2 {
-               t.Fatalf("ParseInLocation(Feb 01 2013 EST, Sydney) = %v, want %v", t1, t2)
-       }
-       _, offset := t1.Zone()
-       if offset != 11*60*60 {
-               t.Fatalf("ParseInLocation(Feb 01 2013 EST, Sydney).Zone = _, %d, want _, %d", offset, 11*60*60)
-       }
-
-       t1, err = ParseInLocation("Jan 02 2006 MST", "Aug 01 2013 EST", loc)
-       if err != nil {
-               t.Fatal(err)
-       }
-       t2 = Date(2013, August, 1, 00, 00, 00, 0, loc)
-       if t1 != t2 {
-               t.Fatalf("ParseInLocation(Aug 01 2013 EST, Sydney) = %v, want %v", t1, t2)
-       }
-       _, offset = t1.Zone()
-       if offset != 10*60*60 {
-               t.Fatalf("ParseInLocation(Aug 01 2013 EST, Sydney).Zone = _, %d, want _, %d", offset, 10*60*60)
-       }
-}
-
-func TestLoadLocationZipFile(t *testing.T) {
-       t.Skip("gccgo does not use the zip file")
-
-       ForceZipFileForTesting(true)
-       defer ForceZipFileForTesting(false)
-
-       _, err := LoadLocation("Australia/Sydney")
-       if err != nil {
-               t.Fatal(err)
-       }
-}
-
-var rubyTests = []ParseTest{
-       {"RubyDate", RubyDate, "Thu Feb 04 21:00:57 -0800 2010", true, true, 1, 0},
-       // Ignore the time zone in the test. If it parses, it'll be OK.
-       {"RubyDate", RubyDate, "Thu Feb 04 21:00:57 -0000 2010", false, true, 1, 0},
-       {"RubyDate", RubyDate, "Thu Feb 04 21:00:57 +0000 2010", false, true, 1, 0},
-       {"RubyDate", RubyDate, "Thu Feb 04 21:00:57 +1130 2010", false, true, 1, 0},
-}
-
-// Problematic time zone format needs special tests.
-func TestRubyParse(t *testing.T) {
-       for _, test := range rubyTests {
-               time, err := Parse(test.format, test.value)
-               if err != nil {
-                       t.Errorf("%s error: %v", test.name, err)
-               } else {
-                       checkTime(time, &test, t)
-               }
-       }
-}
-
-func checkTime(time Time, test *ParseTest, t *testing.T) {
-       // The time should be Thu Feb  4 21:00:57 PST 2010
-       if test.yearSign >= 0 && test.yearSign*time.Year() != 2010 {
-               t.Errorf("%s: bad year: %d not %d", test.name, time.Year(), 2010)
-       }
-       if time.Month() != February {
-               t.Errorf("%s: bad month: %s not %s", test.name, time.Month(), February)
-       }
-       if time.Day() != 4 {
-               t.Errorf("%s: bad day: %d not %d", test.name, time.Day(), 4)
-       }
-       if time.Hour() != 21 {
-               t.Errorf("%s: bad hour: %d not %d", test.name, time.Hour(), 21)
-       }
-       if time.Minute() != 0 {
-               t.Errorf("%s: bad minute: %d not %d", test.name, time.Minute(), 0)
-       }
-       if time.Second() != 57 {
-               t.Errorf("%s: bad second: %d not %d", test.name, time.Second(), 57)
-       }
-       // Nanoseconds must be checked against the precision of the input.
-       nanosec, err := strconv.ParseUint("012345678"[:test.fracDigits]+"000000000"[:9-test.fracDigits], 10, 0)
-       if err != nil {
-               panic(err)
-       }
-       if time.Nanosecond() != int(nanosec) {
-               t.Errorf("%s: bad nanosecond: %d not %d", test.name, time.Nanosecond(), nanosec)
-       }
-       name, offset := time.Zone()
-       if test.hasTZ && offset != -28800 {
-               t.Errorf("%s: bad tz offset: %s %d not %d", test.name, name, offset, -28800)
-       }
-       if test.hasWD && time.Weekday() != Thursday {
-               t.Errorf("%s: bad weekday: %s not %s", test.name, time.Weekday(), Thursday)
-       }
-}
-
-func TestFormatAndParse(t *testing.T) {
-       const fmt = "Mon MST " + RFC3339 // all fields
-       f := func(sec int64) bool {
-               t1 := Unix(sec, 0)
-               if t1.Year() < 1000 || t1.Year() > 9999 {
-                       // not required to work
-                       return true
-               }
-               t2, err := Parse(fmt, t1.Format(fmt))
-               if err != nil {
-                       t.Errorf("error: %s", err)
-                       return false
-               }
-               if t1.Unix() != t2.Unix() || t1.Nanosecond() != t2.Nanosecond() {
-                       t.Errorf("FormatAndParse %d: %q(%d) %q(%d)", sec, t1, t1.Unix(), t2, t2.Unix())
-                       return false
-               }
-               return true
-       }
-       f32 := func(sec int32) bool { return f(int64(sec)) }
-       cfg := &quick.Config{MaxCount: 10000}
-
-       // Try a reasonable date first, then the huge ones.
-       if err := quick.Check(f32, cfg); err != nil {
-               t.Fatal(err)
-       }
-       if err := quick.Check(f, cfg); err != nil {
-               t.Fatal(err)
-       }
-}
-
-type ParseTimeZoneTest struct {
-       value  string
-       length int
-       ok     bool
-}
-
-var parseTimeZoneTests = []ParseTimeZoneTest{
-       {"gmt hi there", 0, false},
-       {"GMT hi there", 3, true},
-       {"GMT+12 hi there", 6, true},
-       {"GMT+00 hi there", 3, true}, // 0 or 00 is not a legal offset.
-       {"GMT-5 hi there", 5, true},
-       {"GMT-51 hi there", 3, true},
-       {"ChST hi there", 4, true},
-       {"MSDx", 3, true},
-       {"MSDY", 0, false}, // four letters must end in T.
-       {"ESAST hi", 5, true},
-       {"ESASTT hi", 0, false}, // run of upper-case letters too long.
-       {"ESATY hi", 0, false},  // five letters must end in T.
-}
-
-func TestParseTimeZone(t *testing.T) {
-       for _, test := range parseTimeZoneTests {
-               length, ok := ParseTimeZone(test.value)
-               if ok != test.ok {
-                       t.Errorf("expected %t for %q got %t", test.ok, test.value, ok)
-               } else if length != test.length {
-                       t.Errorf("expected %d for %q got %d", test.length, test.value, length)
-               }
-       }
-}
-
-type ParseErrorTest struct {
-       format string
-       value  string
-       expect string // must appear within the error
-}
-
-var parseErrorTests = []ParseErrorTest{
-       {ANSIC, "Feb  4 21:00:60 2010", "cannot parse"}, // cannot parse Feb as Mon
-       {ANSIC, "Thu Feb  4 21:00:57 @2010", "cannot parse"},
-       {ANSIC, "Thu Feb  4 21:00:60 2010", "second out of range"},
-       {ANSIC, "Thu Feb  4 21:61:57 2010", "minute out of range"},
-       {ANSIC, "Thu Feb  4 24:00:60 2010", "hour out of range"},
-       {"Mon Jan _2 15:04:05.000 2006", "Thu Feb  4 23:00:59x01 2010", "cannot parse"},
-       {"Mon Jan _2 15:04:05.000 2006", "Thu Feb  4 23:00:59.xxx 2010", "cannot parse"},
-       {"Mon Jan _2 15:04:05.000 2006", "Thu Feb  4 23:00:59.-123 2010", "fractional second out of range"},
-       // issue 4502. StampNano requires exactly 9 digits of precision.
-       {StampNano, "Dec  7 11:22:01.000000", `cannot parse ".000000" as ".000000000"`},
-       {StampNano, "Dec  7 11:22:01.0000000000", "extra text: 0"},
-       // issue 4493. Helpful errors.
-       {RFC3339, "2006-01-02T15:04:05Z07:00", `parsing time "2006-01-02T15:04:05Z07:00": extra text: 07:00`},
-       {RFC3339, "2006-01-02T15:04_abc", `parsing time "2006-01-02T15:04_abc" as "2006-01-02T15:04:05Z07:00": cannot parse "_abc" as ":"`},
-       {RFC3339, "2006-01-02T15:04:05_abc", `parsing time "2006-01-02T15:04:05_abc" as "2006-01-02T15:04:05Z07:00": cannot parse "_abc" as "Z07:00"`},
-       {RFC3339, "2006-01-02T15:04:05Z_abc", `parsing time "2006-01-02T15:04:05Z_abc": extra text: _abc`},
-}
-
-func TestParseErrors(t *testing.T) {
-       for _, test := range parseErrorTests {
-               _, err := Parse(test.format, test.value)
-               if err == nil {
-                       t.Errorf("expected error for %q %q", test.format, test.value)
-               } else if strings.Index(err.Error(), test.expect) < 0 {
-                       t.Errorf("expected error with %q for %q %q; got %s", test.expect, test.format, test.value, err)
-               }
-       }
-}
-
-func TestNoonIs12PM(t *testing.T) {
-       noon := Date(0, January, 1, 12, 0, 0, 0, UTC)
-       const expect = "12:00PM"
-       got := noon.Format("3:04PM")
-       if got != expect {
-               t.Errorf("got %q; expect %q", got, expect)
-       }
-       got = noon.Format("03:04PM")
-       if got != expect {
-               t.Errorf("got %q; expect %q", got, expect)
-       }
-}
-
-func TestMidnightIs12AM(t *testing.T) {
-       midnight := Date(0, January, 1, 0, 0, 0, 0, UTC)
-       expect := "12:00AM"
-       got := midnight.Format("3:04PM")
-       if got != expect {
-               t.Errorf("got %q; expect %q", got, expect)
-       }
-       got = midnight.Format("03:04PM")
-       if got != expect {
-               t.Errorf("got %q; expect %q", got, expect)
-       }
-}
-
-func Test12PMIsNoon(t *testing.T) {
-       noon, err := Parse("3:04PM", "12:00PM")
-       if err != nil {
-               t.Fatal("error parsing date:", err)
-       }
-       if noon.Hour() != 12 {
-               t.Errorf("got %d; expect 12", noon.Hour())
-       }
-       noon, err = Parse("03:04PM", "12:00PM")
-       if err != nil {
-               t.Fatal("error parsing date:", err)
-       }
-       if noon.Hour() != 12 {
-               t.Errorf("got %d; expect 12", noon.Hour())
-       }
-}
-
-func Test12AMIsMidnight(t *testing.T) {
-       midnight, err := Parse("3:04PM", "12:00AM")
-       if err != nil {
-               t.Fatal("error parsing date:", err)
-       }
-       if midnight.Hour() != 0 {
-               t.Errorf("got %d; expect 0", midnight.Hour())
-       }
-       midnight, err = Parse("03:04PM", "12:00AM")
-       if err != nil {
-               t.Fatal("error parsing date:", err)
-       }
-       if midnight.Hour() != 0 {
-               t.Errorf("got %d; expect 0", midnight.Hour())
-       }
-}
-
-// Check that a time without a Zone still produces a (numeric) time zone
-// when formatted with MST as a requested zone.
-func TestMissingZone(t *testing.T) {
-       time, err := Parse(RubyDate, "Thu Feb 02 16:10:03 -0500 2006")
-       if err != nil {
-               t.Fatal("error parsing date:", err)
-       }
-       expect := "Thu Feb  2 16:10:03 -0500 2006" // -0500 not EST
-       str := time.Format(UnixDate)               // uses MST as its time zone
-       if str != expect {
-               t.Errorf("got %s; expect %s", str, expect)
-       }
-}
-
-func TestMinutesInTimeZone(t *testing.T) {
-       time, err := Parse(RubyDate, "Mon Jan 02 15:04:05 +0123 2006")
-       if err != nil {
-               t.Fatal("error parsing date:", err)
-       }
-       expected := (1*60 + 23) * 60
-       _, offset := time.Zone()
-       if offset != expected {
-               t.Errorf("ZoneOffset = %d, want %d", offset, expected)
-       }
-}
-
-type SecondsTimeZoneOffsetTest struct {
-       format         string
-       value          string
-       expectedoffset int
-}
-
-var secondsTimeZoneOffsetTests = []SecondsTimeZoneOffsetTest{
-       {"2006-01-02T15:04:05-070000", "1871-01-01T05:33:02-003408", -(34*60 + 8)},
-       {"2006-01-02T15:04:05-07:00:00", "1871-01-01T05:33:02-00:34:08", -(34*60 + 8)},
-       {"2006-01-02T15:04:05-070000", "1871-01-01T05:33:02+003408", 34*60 + 8},
-       {"2006-01-02T15:04:05-07:00:00", "1871-01-01T05:33:02+00:34:08", 34*60 + 8},
-       {"2006-01-02T15:04:05Z070000", "1871-01-01T05:33:02-003408", -(34*60 + 8)},
-       {"2006-01-02T15:04:05Z07:00:00", "1871-01-01T05:33:02+00:34:08", 34*60 + 8},
-}
-
-func TestParseSecondsInTimeZone(t *testing.T) {
-       // should accept timezone offsets with seconds like: Zone America/New_York   -4:56:02 -      LMT     1883 Nov 18 12:03:58
-       for _, test := range secondsTimeZoneOffsetTests {
-               time, err := Parse(test.format, test.value)
-               if err != nil {
-                       t.Fatal("error parsing date:", err)
-               }
-               _, offset := time.Zone()
-               if offset != test.expectedoffset {
-                       t.Errorf("ZoneOffset = %d, want %d", offset, test.expectedoffset)
-               }
-       }
-}
-
-func TestFormatSecondsInTimeZone(t *testing.T) {
-       d := Date(1871, 9, 17, 20, 4, 26, 0, FixedZone("LMT", -(34*60+8)))
-       timestr := d.Format("2006-01-02T15:04:05Z070000")
-       expected := "1871-09-17T20:04:26-003408"
-       if timestr != expected {
-               t.Errorf("Got %s, want %s", timestr, expected)
-       }
-}
-
 type ISOWeekTest struct {
        year       int // year
        month, day int // month and day
@@ -1494,7 +994,7 @@ var minDurationTests = []struct {
 func TestDurationMinutes(t *testing.T) {
        for _, tt := range minDurationTests {
                if got := tt.d.Minutes(); got != tt.want {
-                       t.Errorf("d.Minutes() = %d; want: %d", got, tt.want)
+                       t.Errorf("d.Minutes() = %g; want: %g", got, tt.want)
                }
        }
 }
@@ -1512,7 +1012,7 @@ var hourDurationTests = []struct {
 func TestDurationHours(t *testing.T) {
        for _, tt := range hourDurationTests {
                if got := tt.d.Hours(); got != tt.want {
-                       t.Errorf("d.Hours() = %d; want: %d", got, tt.want)
+                       t.Errorf("d.Hours() = %g; want: %g", got, tt.want)
                }
        }
 }
index 1c6186258f9b2953057268e54ed72cb651aa662c..c8e53a27cf02328ffc8a16909e95dcbea219765d 100644 (file)
@@ -45,6 +45,13 @@ type zoneTrans struct {
        isstd, isutc bool  // ignored - no idea what these mean
 }
 
+// alpha and omega are the beginning and end of time for zone
+// transitions.
+const (
+       alpha = -1 << 63  // math.MinInt64
+       omega = 1<<63 - 1 // math.MaxInt64
+)
+
 // UTC represents Universal Coordinated Time (UTC).
 var UTC *Location = &utcLoc
 
@@ -83,9 +90,9 @@ func FixedZone(name string, offset int) *Location {
        l := &Location{
                name:       name,
                zone:       []zone{{name, offset, false}},
-               tx:         []zoneTrans{{-1 << 63, 0, false, false}},
-               cacheStart: -1 << 63,
-               cacheEnd:   1<<63 - 1,
+               tx:         []zoneTrans{{alpha, 0, false, false}},
+               cacheStart: alpha,
+               cacheEnd:   omega,
        }
        l.cacheZone = &l.zone[0]
        return l
@@ -101,12 +108,12 @@ func FixedZone(name string, offset int) *Location {
 func (l *Location) lookup(sec int64) (name string, offset int, isDST bool, start, end int64) {
        l = l.get()
 
-       if len(l.tx) == 0 {
+       if len(l.zone) == 0 {
                name = "UTC"
                offset = 0
                isDST = false
-               start = -1 << 63
-               end = 1<<63 - 1
+               start = alpha
+               end = omega
                return
        }
 
@@ -119,10 +126,24 @@ func (l *Location) lookup(sec int64) (name string, offset int, isDST bool, start
                return
        }
 
+       if len(l.tx) == 0 || sec < l.tx[0].when {
+               zone := &l.zone[l.lookupFirstZone()]
+               name = zone.name
+               offset = zone.offset
+               isDST = zone.isDST
+               start = alpha
+               if len(l.tx) > 0 {
+                       end = l.tx[0].when
+               } else {
+                       end = omega
+               }
+               return
+       }
+
        // Binary search for entry with largest time <= sec.
        // Not using sort.Search to avoid dependencies.
        tx := l.tx
-       end = 1<<63 - 1
+       end = omega
        lo := 0
        hi := len(tx)
        for hi-lo > 1 {
@@ -144,6 +165,58 @@ func (l *Location) lookup(sec int64) (name string, offset int, isDST bool, start
        return
 }
 
+// lookupFirstZone returns the index of the time zone to use for times
+// before the first transition time, or when there are no transition
+// times.
+//
+// The reference implementation in localtime.c from
+// http://www.iana.org/time-zones/repository/releases/tzcode2013g.tar.gz
+// implements the following algorithm for these cases:
+// 1) If the first zone is unused by the transitions, use it.
+// 2) Otherwise, if there are transition times, and the first
+//    transition is to a zone in daylight time, find the first
+//    non-daylight-time zone before and closest to the first transition
+//    zone.
+// 3) Otherwise, use the first zone that is not daylight time, if
+//    there is one.
+// 4) Otherwise, use the first zone.
+func (l *Location) lookupFirstZone() int {
+       // Case 1.
+       if !l.firstZoneUsed() {
+               return 0
+       }
+
+       // Case 2.
+       if len(l.tx) > 0 && l.zone[l.tx[0].index].isDST {
+               for zi := int(l.tx[0].index) - 1; zi >= 0; zi-- {
+                       if !l.zone[zi].isDST {
+                               return zi
+                       }
+               }
+       }
+
+       // Case 3.
+       for zi := range l.zone {
+               if !l.zone[zi].isDST {
+                       return zi
+               }
+       }
+
+       // Case 4.
+       return 0
+}
+
+// firstZoneUsed returns whether the first zone is used by some
+// transition.
+func (l *Location) firstZoneUsed() bool {
+       for _, tx := range l.tx {
+               if tx.index == 0 {
+                       return true
+               }
+       }
+       return false
+}
+
 // lookupName returns information about the time zone with
 // the given name (such as "EST") at the given pseudo-Unix time
 // (what the given time of day would be in UTC).
index 0e8f3811bedc1d4d1919e9c717651dfffa5cb881..4bb0cb3909683536e22e8b6c93ab986f079b0b3c 100644 (file)
@@ -100,7 +100,7 @@ func loadZoneDataPlan9(s string) (l *Location, err error) {
        for i := range tx {
                if tx[i].when <= sec && (i+1 == len(tx) || sec < tx[i+1].when) {
                        l.cacheStart = tx[i].when
-                       l.cacheEnd = 1<<63 - 1
+                       l.cacheEnd = omega
                        if i+1 < len(tx) {
                                l.cacheEnd = tx[i+1].when
                        }
index 7714aa9f583ae4507740d77701c4203e88841b69..4bb4bf665cc23675fd6c39e56e3d1710418cd379 100644 (file)
@@ -173,7 +173,7 @@ func loadZoneData(bytes []byte) (l *Location, err error) {
        if len(tx) == 0 {
                // Build fake transition to cover all time.
                // This happens in fixed locations like "Etc/GMT0".
-               tx = append(tx, zoneTrans{when: -1 << 63, index: 0})
+               tx = append(tx, zoneTrans{when: alpha, index: 0})
        }
 
        // Committed to succeed.
@@ -185,7 +185,7 @@ func loadZoneData(bytes []byte) (l *Location, err error) {
        for i := range tx {
                if tx[i].when <= sec && (i+1 == len(tx) || sec < tx[i+1].when) {
                        l.cacheStart = tx[i].when
-                       l.cacheEnd = 1<<63 - 1
+                       l.cacheEnd = omega
                        if i+1 < len(tx) {
                                l.cacheEnd = tx[i+1].when
                        }
diff --git a/libgo/go/time/zoneinfo_test.go b/libgo/go/time/zoneinfo_test.go
new file mode 100644 (file)
index 0000000..03f54a6
--- /dev/null
@@ -0,0 +1,56 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package time_test
+
+import (
+       "testing"
+       "time"
+)
+
+// Test that we get the correct results for times before the first
+// transition time.  To do this we explicitly check early dates in a
+// couple of specific timezones.
+func TestFirstZone(t *testing.T) {
+       t.Skip("gccgo does not use the zip file")
+
+       time.ForceZipFileForTesting(true)
+       defer time.ForceZipFileForTesting(false)
+
+       const format = "Mon, 02 Jan 2006 15:04:05 -0700 (MST)"
+       var tests = []struct {
+               zone  string
+               unix  int64
+               want1 string
+               want2 string
+       }{
+               {
+                       "PST8PDT",
+                       -1633269601,
+                       "Sun, 31 Mar 1918 01:59:59 -0800 (PST)",
+                       "Sun, 31 Mar 1918 03:00:00 -0700 (PDT)",
+               },
+               {
+                       "Pacific/Fakaofo",
+                       1325242799,
+                       "Thu, 29 Dec 2011 23:59:59 -1100 (TKT)",
+                       "Sat, 31 Dec 2011 00:00:00 +1300 (TKT)",
+               },
+       }
+
+       for _, test := range tests {
+               z, err := time.LoadLocation(test.zone)
+               if err != nil {
+                       t.Fatal(err)
+               }
+               s := time.Unix(test.unix, 0).In(z).Format(format)
+               if s != test.want1 {
+                       t.Errorf("for %s %d got %q want %q", test.zone, test.unix, s, test.want1)
+               }
+               s = time.Unix(test.unix+1, 0).In(z).Format(format)
+               if s != test.want2 {
+                       t.Errorf("for %s %d got %q want %q", test.zone, test.unix, s, test.want2)
+               }
+       }
+}
index 1a4d115b932cd29b3270209da332915e5b464b3c..e70decb36cb5622f8f45169db56f4c7043d0f373 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin dragonfly freebsd linux netbsd openbsd
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
 
 // Parse "zoneinfo" time zone file.
 // This is a fairly standard file format used on OS X, Linux, BSD, Sun, and others.
index 7e4d146d89eed68f4bfcdd1984cafde87471f2ed..377a892153858016b1a81dec8a7c9f3648516a37 100644 (file)
@@ -165,8 +165,8 @@ func initLocalFromTZI(i *syscall.Timezoneinformation) {
        if nzone == 1 {
                // No daylight savings.
                std.offset = -int(i.Bias) * 60
-               l.cacheStart = -1 << 63
-               l.cacheEnd = 1<<63 - 1
+               l.cacheStart = alpha
+               l.cacheEnd = omega
                l.cacheZone = std
                l.tx = make([]zoneTrans, 1)
                l.tx[0].when = l.cacheStart
index fadaa57d8b5b6f70062f33111a021f43280e958a..3b389e93f14914e91df7b84eef323e4476ef8300 100644 (file)
@@ -74,7 +74,7 @@ const (
 
 type d [MaxCase]rune // to make the CaseRanges text shorter
 
-// If the Delta field of a CaseRange is UpperLower or LowerUpper, it means
+// If the Delta field of a CaseRange is UpperLower, it means
 // this CaseRange represents a sequence of the form (say)
 // Upper Lower Upper Lower.
 const (
index 395cc71a0b61f4590f116551e7ec963f788e0ef3..e2ba0011aca312088a56ef4699d1458455317522 100644 (file)
@@ -182,7 +182,7 @@ var inPropTest = []T{
        {0x0EC4, "Logical_Order_Exception"},
        {0x2FFFF, "Noncharacter_Code_Point"},
        {0x065E, "Other_Alphabetic"},
-       {0x2069, "Other_Default_Ignorable_Code_Point"},
+       {0x2065, "Other_Default_Ignorable_Code_Point"},
        {0x0BD7, "Other_Grapheme_Extend"},
        {0x0387, "Other_ID_Continue"},
        {0x212E, "Other_ID_Start"},
index d8101d68100f50ae4df81b786583a945c2a6fa77..5670d1c5b171b653584fe0ad445b2cd3e442e4b0 100644 (file)
@@ -3,13 +3,13 @@
 // license that can be found in the LICENSE file.
 
 // Generated by running
-//     maketables --tables=all --data=http://www.unicode.org/Public/6.2.0/ucd/UnicodeData.txt --casefolding=http://www.unicode.org/Public/6.2.0/ucd/CaseFolding.txt
+//     maketables --tables=all --data=http://www.unicode.org/Public/6.3.0/ucd/UnicodeData.txt --casefolding=http://www.unicode.org/Public/6.3.0/ucd/CaseFolding.txt
 // DO NOT EDIT
 
 package unicode
 
 // Version is the Unicode edition from which the tables are derived.
-const Version = "6.2.0"
+const Version = "6.3.0"
 
 // Categories is the set of Unicode category tables.
 var Categories = map[string]*RangeTable{
@@ -57,11 +57,12 @@ var _C = &RangeTable{
                {0x007f, 0x009f, 1},
                {0x00ad, 0x0600, 1363},
                {0x0601, 0x0604, 1},
-               {0x06dd, 0x070f, 50},
+               {0x061c, 0x06dd, 193},
+               {0x070f, 0x180e, 4351},
                {0x200b, 0x200f, 1},
                {0x202a, 0x202e, 1},
                {0x2060, 0x2064, 1},
-               {0x206a, 0x206f, 1},
+               {0x2066, 0x206f, 1},
                {0xd800, 0xf8ff, 1},
                {0xfeff, 0xfff9, 250},
                {0xfffa, 0xfffb, 1},
@@ -89,11 +90,12 @@ var _Cf = &RangeTable{
        R16: []Range16{
                {0x00ad, 0x0600, 1363},
                {0x0601, 0x0604, 1},
-               {0x06dd, 0x070f, 50},
+               {0x061c, 0x06dd, 193},
+               {0x070f, 0x180e, 4351},
                {0x200b, 0x200f, 1},
                {0x202a, 0x202e, 1},
                {0x2060, 0x2064, 1},
-               {0x206a, 0x206f, 1},
+               {0x2066, 0x206f, 1},
                {0xfeff, 0xfff9, 250},
                {0xfffa, 0xfffb, 1},
        },
@@ -1549,7 +1551,7 @@ var _Mc = &RangeTable{
                {0x1933, 0x1938, 1},
                {0x19b0, 0x19c0, 1},
                {0x19c8, 0x19c9, 1},
-               {0x1a19, 0x1a1b, 1},
+               {0x1a19, 0x1a1a, 1},
                {0x1a55, 0x1a57, 2},
                {0x1a61, 0x1a63, 2},
                {0x1a64, 0x1a6d, 9},
@@ -1721,8 +1723,8 @@ var _Mn = &RangeTable{
                {0x1932, 0x1939, 7},
                {0x193a, 0x193b, 1},
                {0x1a17, 0x1a18, 1},
-               {0x1a56, 0x1a58, 2},
-               {0x1a59, 0x1a5e, 1},
+               {0x1a1b, 0x1a56, 59},
+               {0x1a58, 0x1a5e, 1},
                {0x1a60, 0x1a62, 2},
                {0x1a65, 0x1a6c, 1},
                {0x1a73, 0x1a7c, 1},
@@ -2090,6 +2092,7 @@ var _P = &RangeTable{
                {0x2053, 0x205e, 1},
                {0x207d, 0x207e, 1},
                {0x208d, 0x208e, 1},
+               {0x2308, 0x230b, 1},
                {0x2329, 0x232a, 1},
                {0x2768, 0x2775, 1},
                {0x27c5, 0x27c6, 1},
@@ -2187,7 +2190,8 @@ var _Pe = &RangeTable{
                {0x007d, 0x0f3b, 3774},
                {0x0f3d, 0x169c, 1887},
                {0x2046, 0x207e, 56},
-               {0x208e, 0x232a, 668},
+               {0x208e, 0x2309, 635},
+               {0x230b, 0x232a, 31},
                {0x2769, 0x2775, 2},
                {0x27c6, 0x27e7, 33},
                {0x27e9, 0x27ef, 2},
@@ -2364,7 +2368,8 @@ var _Ps = &RangeTable{
                {0x0f3c, 0x169b, 1887},
                {0x201a, 0x201e, 4},
                {0x2045, 0x207d, 56},
-               {0x208d, 0x2329, 668},
+               {0x208d, 0x2308, 635},
+               {0x230a, 0x2329, 31},
                {0x2768, 0x2774, 2},
                {0x27c5, 0x27e6, 33},
                {0x27e8, 0x27ee, 2},
@@ -2454,7 +2459,8 @@ var _S = &RangeTable{
                {0x2141, 0x2144, 1},
                {0x214a, 0x214d, 1},
                {0x214f, 0x2190, 65},
-               {0x2191, 0x2328, 1},
+               {0x2191, 0x2307, 1},
+               {0x230c, 0x2328, 1},
                {0x232b, 0x23f3, 1},
                {0x2400, 0x2426, 1},
                {0x2440, 0x244a, 1},
@@ -2634,7 +2640,6 @@ var _Sm = &RangeTable{
                {0x21cf, 0x21d2, 3},
                {0x21d4, 0x21f4, 32},
                {0x21f5, 0x22ff, 1},
-               {0x2308, 0x230b, 1},
                {0x2320, 0x2321, 1},
                {0x237c, 0x239b, 31},
                {0x239c, 0x23b3, 1},
@@ -2822,8 +2827,8 @@ var _So = &RangeTable{
 var _Z = &RangeTable{
        R16: []Range16{
                {0x0020, 0x00a0, 128},
-               {0x1680, 0x180e, 398},
-               {0x2000, 0x200a, 1},
+               {0x1680, 0x2000, 2432},
+               {0x2001, 0x200a, 1},
                {0x2028, 0x2029, 1},
                {0x202f, 0x205f, 48},
                {0x3000, 0x3000, 1},
@@ -2846,8 +2851,8 @@ var _Zp = &RangeTable{
 var _Zs = &RangeTable{
        R16: []Range16{
                {0x0020, 0x00a0, 128},
-               {0x1680, 0x180e, 398},
-               {0x2000, 0x200a, 1},
+               {0x1680, 0x2000, 2432},
+               {0x2001, 0x200a, 1},
                {0x202f, 0x205f, 48},
                {0x3000, 0x3000, 1},
        },
@@ -2906,7 +2911,7 @@ var (
 )
 
 // Generated by running
-//     maketables --scripts=all --url=http://www.unicode.org/Public/6.2.0/ucd/
+//     maketables --scripts=all --url=http://www.unicode.org/Public/6.3.0/ucd/
 // DO NOT EDIT
 
 // Scripts is the set of Unicode script tables.
@@ -3020,6 +3025,7 @@ var _Arabic = &RangeTable{
                {0x0600, 0x0604, 1},
                {0x0606, 0x060b, 1},
                {0x060d, 0x061a, 1},
+               {0x061c, 0x061c, 1},
                {0x061e, 0x061e, 1},
                {0x0620, 0x063f, 1},
                {0x0641, 0x064a, 1},
@@ -3249,7 +3255,7 @@ var _Common = &RangeTable{
                {0x1cf5, 0x1cf6, 1},
                {0x2000, 0x200b, 1},
                {0x200e, 0x2064, 1},
-               {0x206a, 0x2070, 1},
+               {0x2066, 0x2070, 1},
                {0x2074, 0x207e, 1},
                {0x2080, 0x208e, 1},
                {0x20a0, 0x20ba, 1},
@@ -3285,6 +3291,7 @@ var _Common = &RangeTable{
                {0xa700, 0xa721, 1},
                {0xa788, 0xa78a, 1},
                {0xa830, 0xa839, 1},
+               {0xa9cf, 0xa9cf, 1},
                {0xfd3e, 0xfd3f, 1},
                {0xfdfd, 0xfdfd, 1},
                {0xfe10, 0xfe19, 1},
@@ -3714,7 +3721,7 @@ var _Inscriptional_Parthian = &RangeTable{
 var _Javanese = &RangeTable{
        R16: []Range16{
                {0xa980, 0xa9cd, 1},
-               {0xa9cf, 0xa9d9, 1},
+               {0xa9d0, 0xa9d9, 1},
                {0xa9de, 0xa9df, 1},
        },
 }
@@ -4407,7 +4414,7 @@ var (
 )
 
 // Generated by running
-//     maketables --props=all --url=http://www.unicode.org/Public/6.2.0/ucd/
+//     maketables --props=all --url=http://www.unicode.org/Public/6.3.0/ucd/
 // DO NOT EDIT
 
 // Properties is the set of Unicode property tables.
@@ -4457,8 +4464,10 @@ var _ASCII_Hex_Digit = &RangeTable{
 
 var _Bidi_Control = &RangeTable{
        R16: []Range16{
+               {0x061c, 0x061c, 1},
                {0x200e, 0x200f, 1},
                {0x202a, 0x202e, 1},
+               {0x2066, 0x2069, 1},
        },
 }
 
@@ -4935,7 +4944,7 @@ var _Other_Default_Ignorable_Code_Point = &RangeTable{
                {0x034f, 0x034f, 1},
                {0x115f, 0x1160, 1},
                {0x17b4, 0x17b5, 1},
-               {0x2065, 0x2069, 1},
+               {0x2065, 0x2065, 1},
                {0x3164, 0x3164, 1},
                {0xffa0, 0xffa0, 1},
                {0xfff0, 0xfff8, 1},
@@ -5057,6 +5066,7 @@ var _Other_Math = &RangeTable{
                {0x21d5, 0x21db, 1},
                {0x21dd, 0x21dd, 1},
                {0x21e4, 0x21e5, 1},
+               {0x2308, 0x230b, 1},
                {0x23b4, 0x23b5, 1},
                {0x23b7, 0x23b7, 1},
                {0x23d0, 0x23d0, 1},
@@ -5444,7 +5454,6 @@ var _White_Space = &RangeTable{
                {0x0085, 0x0085, 1},
                {0x00a0, 0x00a0, 1},
                {0x1680, 0x1680, 1},
-               {0x180e, 0x180e, 1},
                {0x2000, 0x200a, 1},
                {0x2028, 0x2029, 1},
                {0x202f, 0x202f, 1},
@@ -5491,7 +5500,7 @@ var (
 )
 
 // Generated by running
-//     maketables --data=http://www.unicode.org/Public/6.2.0/ucd/UnicodeData.txt --casefolding=http://www.unicode.org/Public/6.2.0/ucd/CaseFolding.txt
+//     maketables --data=http://www.unicode.org/Public/6.3.0/ucd/UnicodeData.txt --casefolding=http://www.unicode.org/Public/6.3.0/ucd/CaseFolding.txt
 // DO NOT EDIT
 
 // CaseRanges is the table describing case mappings for all letters with
@@ -6376,7 +6385,7 @@ var foldMn = &RangeTable{
 // If there is no entry for a script name, there are no such points.
 var FoldScript = map[string]*RangeTable{}
 
-// Range entries: 3462 16-bit, 832 32-bit, 4294 total.
-// Range bytes: 20772 16-bit, 9984 32-bit, 30756 total.
+// Range entries: 3471 16-bit, 832 32-bit, 4303 total.
+// Range bytes: 20826 16-bit, 9984 32-bit, 30810 total.
 
 // Fold orbit bytes: 63 pairs, 252 bytes
index 65e9f3a1d825036551f731bd6bc1eec7e2261eb8..8a3693123b126e7edbe3b12b1c7f24f29e17a9e6 100755 (executable)
@@ -163,7 +163,7 @@ done
   done
 done
 
-runtime="chan.c cpuprof.c env_posix.c lock_futex.c lock_sema.c mcache.c mcentral.c mfinal.c mfixalloc.c mgc0.c mgc0.h mheap.c msize.c netpoll.goc netpoll_epoll.c netpoll_kqueue.c netpoll_stub.c panic.c print.c proc.c race.h runtime.c runtime.h signal_unix.c signal_unix.h malloc.h malloc.goc mprof.goc parfor.c runtime1.goc sema.goc sigqueue.goc string.goc time.goc"
+runtime="chan.c cpuprof.c env_posix.c lock_futex.c lock_sema.c mcache.c mcentral.c mfixalloc.c mgc0.c mgc0.h mheap.c msize.c netpoll.goc netpoll_epoll.c netpoll_kqueue.c netpoll_stub.c panic.c print.c proc.c race.h runtime.c runtime.h signal_unix.c signal_unix.h malloc.h malloc.goc mprof.goc parfor.c runtime1.goc sema.goc sigqueue.goc string.goc time.goc"
 for f in $runtime; do
   merge_c $f $f
 done
index bb6abfd04b0c06015572a3aa024eb1f45e4d4469..e188155e5faab4ac59859f5d153770c51d9d2759 100755 (executable)
@@ -250,6 +250,16 @@ for flag in F_GETLK F_SETLK F_SETLKW; do
   fi
 done
 
+# The Flock_t struct for fcntl.
+grep '^type _flock ' gen-sysinfo.go | \
+    sed -e 's/type _flock/type Flock_t/' \
+      -e 's/l_type/Type/' \
+      -e 's/l_whence/Whence/' \
+      -e 's/l_start/Start/' \
+      -e 's/l_len/Len/' \
+      -e 's/l_pid/Pid/' \
+    >> ${OUT}
+
 # The signal numbers.
 grep '^const _SIG[^_]' gen-sysinfo.go | \
   grep -v '^const _SIGEV_' | \
index 6bd12e43d9c225da7c2d4d6801bd54e38474ec6d..cd3a2c5d173c604222bf4764c7863e5809a6be30 100644 (file)
@@ -8,8 +8,6 @@
 #include "race.h"
 #include "malloc.h"
 
-#define        NOSELGEN        1
-
 typedef        struct  WaitQ   WaitQ;
 typedef        struct  SudoG   SudoG;
 typedef        struct  Select  Select;
@@ -20,8 +18,8 @@ typedef struct        __go_channel_type       ChanType;
 
 struct SudoG
 {
-       G*      g;              // g and selgen constitute
-       uint32  selgen;         // a weak pointer to g
+       G*      g;
+       uint32* selectdone;
        SudoG*  link;
        int64   releasetime;
        byte*   elem;           // data element
@@ -43,6 +41,7 @@ struct        Hchan
        uint8   elemalign;
        uint8   pad;                    // ensures proper alignment of the buffer that follows Hchan in memory
        bool    closed;
+       const Type* elemtype;           // element type
        uintgo  sendx;                  // send index
        uintgo  recvx;                  // receive index
        WaitQ   recvq;                  // list of recv waiters
@@ -89,8 +88,8 @@ static        SudoG*  dequeue(WaitQ*);
 static void    enqueue(WaitQ*, SudoG*);
 static void    racesync(Hchan*, SudoG*);
 
-Hchan*
-runtime_makechan_c(ChanType *t, int64 hint)
+static Hchan*
+makechan(ChanType *t, int64 hint)
 {
        Hchan *c;
        uintptr n;
@@ -102,16 +101,16 @@ runtime_makechan_c(ChanType *t, int64 hint)
        if(elem->__size >= (1<<16))
                runtime_throw("makechan: invalid channel element type");
 
-       if(hint < 0 || (intgo)hint != hint || (elem->__size > 0 && (uintptr)hint > MaxMem / elem->__size))
+       if(hint < 0 || (intgo)hint != hint || (elem->__size > 0 && (uintptr)hint > (MaxMem - sizeof(*c)) / elem->__size))
                runtime_panicstring("makechan: size out of range");
 
        n = sizeof(*c);
        n = ROUND(n, elem->__align);
 
        // allocate memory in one call
-       c = (Hchan*)runtime_mallocgc(n + hint*elem->__size, (uintptr)t | TypeInfo_Chan, 0);
+       c = (Hchan*)runtime_mallocgc(sizeof(*c) + hint*elem->__size, (uintptr)t | TypeInfo_Chan, 0);
        c->elemsize = elem->__size;
-       c->elemalign = elem->__align;
+       c->elemtype = elem;
        c->dataqsiz = hint;
 
        if(debug)
@@ -131,7 +130,7 @@ reflect_makechan(ChanType *t, uint64 size)
 {
        Hchan *c;
 
-       c = runtime_makechan_c(t, size);
+       c = makechan(t, size);
        return c;
 }
 
@@ -139,13 +138,13 @@ reflect_makechan(ChanType *t, uint64 size)
 Hchan*
 __go_new_channel(ChanType *t, uintptr hint)
 {
-       return runtime_makechan_c(t, hint);
+       return makechan(t, hint);
 }
 
 Hchan*
 __go_new_channel_big(ChanType *t, uint64 hint)
 {
-       return runtime_makechan_c(t, hint);
+       return makechan(t, hint);
 }
 
 /*
@@ -162,8 +161,8 @@ __go_new_channel_big(ChanType *t, uint64 hint)
  * been closed.  it is easiest to loop and re-run
  * the operation; we'll see that it's now closed.
  */
-void
-runtime_chansend(ChanType *t, Hchan *c, byte *ep, bool *pres, void *pc)
+static bool
+chansend(ChanType *t, Hchan *c, byte *ep, bool block, void *pc)
 {
        SudoG *sg;
        SudoG mysg;
@@ -173,14 +172,15 @@ runtime_chansend(ChanType *t, Hchan *c, byte *ep, bool *pres, void *pc)
 
        g = runtime_g();
 
+       if(raceenabled)
+               runtime_racereadobjectpc(ep, t->__element_type, runtime_getcallerpc(&t), chansend);
+
        if(c == nil) {
                USED(t);
-               if(pres != nil) {
-                       *pres = false;
-                       return;
-               }
+               if(!block)
+                       return false;
                runtime_park(nil, nil, "chan send (nil chan)");
-               return;  // not reached
+               return false;  // not reached
        }
 
        if(runtime_gcwaiting())
@@ -199,7 +199,7 @@ runtime_chansend(ChanType *t, Hchan *c, byte *ep, bool *pres, void *pc)
 
        runtime_lock(c);
        if(raceenabled)
-               runtime_racereadpc(c, pc, runtime_chansend);
+               runtime_racereadpc(c, pc, chansend);
        if(c->closed)
                goto closed;
 
@@ -219,24 +219,20 @@ runtime_chansend(ChanType *t, Hchan *c, byte *ep, bool *pres, void *pc)
                if(sg->releasetime)
                        sg->releasetime = runtime_cputicks();
                runtime_ready(gp);
-
-               if(pres != nil)
-                       *pres = true;
-               return;
+               return true;
        }
 
-       if(pres != nil) {
+       if(!block) {
                runtime_unlock(c);
-               *pres = false;
-               return;
+               return false;
        }
 
        mysg.elem = ep;
        mysg.g = g;
-       mysg.selgen = NOSELGEN;
+       mysg.selectdone = nil;
        g->param = nil;
        enqueue(&c->sendq, &mysg);
-       runtime_park(runtime_unlock, c, "chan send");
+       runtime_parkunlock(c, "chan send");
 
        if(g->param == nil) {
                runtime_lock(c);
@@ -248,23 +244,22 @@ runtime_chansend(ChanType *t, Hchan *c, byte *ep, bool *pres, void *pc)
        if(mysg.releasetime > 0)
                runtime_blockevent(mysg.releasetime - t0, 2);
 
-       return;
+       return true;
 
 asynch:
        if(c->closed)
                goto closed;
 
        if(c->qcount >= c->dataqsiz) {
-               if(pres != nil) {
+               if(!block) {
                        runtime_unlock(c);
-                       *pres = false;
-                       return;
+                       return false;
                }
                mysg.g = g;
                mysg.elem = nil;
-               mysg.selgen = NOSELGEN;
+               mysg.selectdone = nil;
                enqueue(&c->sendq, &mysg);
-               runtime_park(runtime_unlock, c, "chan send");
+               runtime_parkunlock(c, "chan send");
 
                runtime_lock(c);
                goto asynch;
@@ -287,20 +282,19 @@ asynch:
                runtime_ready(gp);
        } else
                runtime_unlock(c);
-       if(pres != nil)
-               *pres = true;
        if(mysg.releasetime > 0)
                runtime_blockevent(mysg.releasetime - t0, 2);
-       return;
+       return true;
 
 closed:
        runtime_unlock(c);
        runtime_panicstring("send on closed channel");
+       return false;  // not reached
 }
 
 
-void
-runtime_chanrecv(ChanType *t, Hchan* c, byte *ep, bool *selected, bool *received)
+static bool
+chanrecv(ChanType *t, Hchan* c, byte *ep, bool block, bool *received)
 {
        SudoG *sg;
        SudoG mysg;
@@ -311,6 +305,8 @@ runtime_chanrecv(ChanType *t, Hchan* c, byte *ep, bool *selected, bool *received
        if(runtime_gcwaiting())
                runtime_gosched();
 
+       // raceenabled: don't need to check ep, as it is always on the stack.
+
        if(debug)
                runtime_printf("chanrecv: chan=%p\n", c);
 
@@ -318,12 +314,10 @@ runtime_chanrecv(ChanType *t, Hchan* c, byte *ep, bool *selected, bool *received
 
        if(c == nil) {
                USED(t);
-               if(selected != nil) {
-                       *selected = false;
-                       return;
-               }
+               if(!block)
+                       return false;
                runtime_park(nil, nil, "chan receive (nil chan)");
-               return;  // not reached
+               return false;  // not reached
        }
 
        t0 = 0;
@@ -354,25 +348,22 @@ runtime_chanrecv(ChanType *t, Hchan* c, byte *ep, bool *selected, bool *received
                        sg->releasetime = runtime_cputicks();
                runtime_ready(gp);
 
-               if(selected != nil)
-                       *selected = true;
                if(received != nil)
                        *received = true;
-               return;
+               return true;
        }
 
-       if(selected != nil) {
+       if(!block) {
                runtime_unlock(c);
-               *selected = false;
-               return;
+               return false;
        }
 
        mysg.elem = ep;
        mysg.g = g;
-       mysg.selgen = NOSELGEN;
+       mysg.selectdone = nil;
        g->param = nil;
        enqueue(&c->recvq, &mysg);
-       runtime_park(runtime_unlock, c, "chan receive");
+       runtime_parkunlock(c, "chan receive");
 
        if(g->param == nil) {
                runtime_lock(c);
@@ -385,25 +376,24 @@ runtime_chanrecv(ChanType *t, Hchan* c, byte *ep, bool *selected, bool *received
                *received = true;
        if(mysg.releasetime > 0)
                runtime_blockevent(mysg.releasetime - t0, 2);
-       return;
+       return true;
 
 asynch:
        if(c->qcount <= 0) {
                if(c->closed)
                        goto closed;
 
-               if(selected != nil) {
+               if(!block) {
                        runtime_unlock(c);
-                       *selected = false;
                        if(received != nil)
                                *received = false;
-                       return;
+                       return false;
                }
                mysg.g = g;
                mysg.elem = nil;
-               mysg.selgen = NOSELGEN;
+               mysg.selectdone = nil;
                enqueue(&c->recvq, &mysg);
-               runtime_park(runtime_unlock, c, "chan receive");
+               runtime_parkunlock(c, "chan receive");
 
                runtime_lock(c);
                goto asynch;
@@ -429,19 +419,15 @@ asynch:
        } else
                runtime_unlock(c);
 
-       if(selected != nil)
-               *selected = true;
        if(received != nil)
                *received = true;
        if(mysg.releasetime > 0)
                runtime_blockevent(mysg.releasetime - t0, 2);
-       return;
+       return true;
 
 closed:
        if(ep != nil)
                runtime_memclr(ep, c->elemsize);
-       if(selected != nil)
-               *selected = true;
        if(received != nil)
                *received = false;
        if(raceenabled)
@@ -449,6 +435,7 @@ closed:
        runtime_unlock(c);
        if(mysg.releasetime > 0)
                runtime_blockevent(mysg.releasetime - t0, 2);
+       return true;
 }
 
 // The compiler generates a call to __go_send_small to send a value 8
@@ -461,46 +448,46 @@ __go_send_small(ChanType *t, Hchan* c, uint64 val)
                byte b[sizeof(uint64)];
                uint64 v;
        } u;
-       byte *p;
+       byte *v;
 
        u.v = val;
 #ifndef WORDS_BIGENDIAN
-       p = u.b;
+       v = u.b;
 #else
-       p = u.b + sizeof(uint64) - t->__element_type->__size;
+       v = u.b + sizeof(uint64) - t->__element_type->__size;
 #endif
-       runtime_chansend(t, c, p, nil, runtime_getcallerpc(&t));
+       chansend(t, c, v, true, runtime_getcallerpc(&t));
 }
 
 // The compiler generates a call to __go_send_big to send a value
 // larger than 8 bytes or smaller.
 void
-__go_send_big(ChanType *t, Hchan* c, byte* p)
+__go_send_big(ChanType *t, Hchan* c, byte* v)
 {
-       runtime_chansend(t, c, p, nil, runtime_getcallerpc(&t));
+       chansend(t, c, v, true, runtime_getcallerpc(&t));
 }
 
 // The compiler generates a call to __go_receive to receive a
 // value from a channel.
 void
-__go_receive(ChanType *t, Hchan* c, byte* p)
+__go_receive(ChanType *t, Hchan* c, byte* v)
 {
-       runtime_chanrecv(t, c, p, nil, nil);
+       chanrecv(t, c, v, true, nil);
 }
 
-_Bool runtime_chanrecv2(ChanType *t, Hchan* c, byte* p)
+_Bool runtime_chanrecv2(ChanType *t, Hchan* c, byte* v)
   __asm__ (GOSYM_PREFIX "runtime.chanrecv2");
 
 _Bool
-runtime_chanrecv2(ChanType *t, Hchan* c, byte* p)
+runtime_chanrecv2(ChanType *t, Hchan* c, byte* v)
 {
        bool received;
 
-       runtime_chanrecv(t, c, p, nil, &received);
+       chanrecv(t, c, v, true, &received);
        return received;
 }
 
-// func selectnbsend(c chan any, elem any) bool
+// func selectnbsend(c chan any, elem *any) bool
 //
 // compiler implements
 //
@@ -520,12 +507,12 @@ runtime_chanrecv2(ChanType *t, Hchan* c, byte* p)
 //     }
 //
 _Bool
-runtime_selectnbsend(ChanType *t, Hchan *c, byte *p)
+runtime_selectnbsend(ChanType *t, Hchan *c, byte *val)
 {
        bool res;
 
-       runtime_chansend(t, c, p, &res, runtime_getcallerpc(&t));
-       return res;
+       res = chansend(t, c, val, false, runtime_getcallerpc(&t));
+       return (_Bool)res;
 }
 
 // func selectnbrecv(elem *any, c chan any) bool
@@ -552,8 +539,8 @@ runtime_selectnbrecv(ChanType *t, byte *v, Hchan *c)
 {
        bool selected;
 
-       runtime_chanrecv(t, c, v, &selected, nil);
-       return selected;
+       selected = chanrecv(t, c, v, false, nil);
+       return (_Bool)selected;
 }
 
 // func selectnbrecv2(elem *any, ok *bool, c chan any) bool
@@ -582,88 +569,60 @@ runtime_selectnbrecv2(ChanType *t, byte *v, _Bool *received, Hchan *c)
        bool r;
 
        r = false;
-       runtime_chanrecv(t, c, v, &selected, received == nil ? nil : &r);
+       selected = chanrecv(t, c, v, false, received == nil ? nil : &r);
        if(received != nil)
                *received = r;
        return selected;
 }
 
 // For reflect:
-//     func chansend(c chan, val iword, nb bool) (selected bool)
-// where an iword is the same word an interface value would use:
-// the actual data if it fits, or else a pointer to the data.
+//     func chansend(c chan, val *any, nb bool) (selected bool)
+// where val points to the data to be sent.
+//
+// The "uintptr selected" is really "bool selected" but saying
+// uintptr gets us the right alignment for the output parameter block.
 
-_Bool reflect_chansend(ChanType *, Hchan *, uintptr, _Bool)
+_Bool reflect_chansend(ChanType *, Hchan *, byte *, _Bool)
   __asm__ (GOSYM_PREFIX "reflect.chansend");
 
 _Bool
-reflect_chansend(ChanType *t, Hchan *c, uintptr val, _Bool nb)
+reflect_chansend(ChanType *t, Hchan *c, byte *val, _Bool nb)
 {
        bool selected;
-       bool *sp;
-       byte *vp;
 
-       if(nb) {
-               selected = false;
-               sp = (bool*)&selected;
-       } else {
-               selected = true;
-               sp = nil;
-       }
-       if(__go_is_pointer_type(t->__element_type))
-               vp = (byte*)&val;
-       else
-               vp = (byte*)val;
-       runtime_chansend(t, c, vp, sp, runtime_getcallerpc(&t));
-       return selected;
+       selected = chansend(t, c, val, !nb, runtime_getcallerpc(&t));
+       return (_Bool)selected;
 }
 
 // For reflect:
-//     func chanrecv(c chan, nb bool) (val iword, selected, received bool)
-// where an iword is the same word an interface value would use:
-// the actual data if it fits, or else a pointer to the data.
+//     func chanrecv(c chan, nb bool, val *any) (selected, received bool)
+// where val points to a data area that will be filled in with the
+// received value.  val must have the size and type of the channel element type.
 
 struct chanrecv_ret
 {
-       uintptr val;
        _Bool selected;
        _Bool received;
 };
 
-struct chanrecv_ret reflect_chanrecv(ChanType *, Hchan *, _Bool)
+struct chanrecv_ret reflect_chanrecv(ChanType *, Hchan *, _Bool, byte *val)
   __asm__ (GOSYM_PREFIX "reflect.chanrecv");
 
 struct chanrecv_ret
-reflect_chanrecv(ChanType *t, Hchan *c, _Bool nb)
+reflect_chanrecv(ChanType *t, Hchan *c, _Bool nb, byte *val)
 {
        struct chanrecv_ret ret;
-       byte *vp;
-       bool *sp;
        bool selected;
        bool received;
 
-       if(nb) {
-               selected = false;
-               sp = &selected;
-       } else {
-               ret.selected = true;
-               sp = nil;
-       }
        received = false;
-       if(__go_is_pointer_type(t->__element_type)) {
-               vp = (byte*)&ret.val;
-       } else {
-               vp = runtime_mal(t->__element_type->__size);
-               ret.val = (uintptr)vp;
-       }
-       runtime_chanrecv(t, c, vp, sp, &received);
-       if(nb)
-               ret.selected = selected;
-       ret.received = received;
+       selected = chanrecv(t, c, val, !nb, &received);
+       ret.selected = (_Bool)selected;
+       ret.received = (_Bool)received;
        return ret;
 }
 
-static void newselect(int32, Select**);
+static Select* newselect(int32);
 
 // newselect(size uint32) (sel *byte);
 
@@ -672,14 +631,11 @@ void* runtime_newselect(int32) __asm__ (GOSYM_PREFIX "runtime.newselect");
 void*
 runtime_newselect(int32 size)
 {
-       Select *sel;
-
-       newselect(size, &sel);
-       return (void*)sel;
+       return (void*)newselect(size);
 }
 
-static void
-newselect(int32 size, Select **selp)
+static Select*
+newselect(int32 size)
 {
        int32 n;
        Select *sel;
@@ -701,10 +657,10 @@ newselect(int32 size, Select **selp)
        sel->ncase = 0;
        sel->lockorder = (void*)(sel->scase + size);
        sel->pollorder = (void*)(sel->lockorder + size);
-       *selp = sel;
 
        if(debug)
                runtime_printf("newselect s=%p size=%d\n", sel, size);
+       return sel;
 }
 
 // cut in half to give stack a chance to split
@@ -880,6 +836,14 @@ selunlock(Select *sel)
        }
 }
 
+static bool
+selparkcommit(G *gp, void *sel)
+{
+       USED(gp);
+       selunlock(sel);
+       return true;
+}
+
 void
 runtime_block(void)
 {
@@ -902,7 +866,7 @@ static int
 selectgo(Select **selp)
 {
        Select *sel;
-       uint32 o, i, j, k;
+       uint32 o, i, j, k, done;
        int64 t0;
        Scase *cas, *dfl;
        Hchan *c;
@@ -1008,7 +972,7 @@ loop:
 
                case CaseSend:
                        if(raceenabled)
-                               runtime_racereadpc(c, runtime_selectgo, runtime_chansend);
+                               runtime_racereadpc(c, runtime_selectgo, chansend);
                        if(c->closed)
                                goto sclose;
                        if(c->dataqsiz > 0) {
@@ -1035,13 +999,14 @@ loop:
 
 
        // pass 2 - enqueue on all chans
+       done = 0;
        for(i=0; i<sel->ncase; i++) {
                o = sel->pollorder[i];
                cas = &sel->scase[o];
                c = cas->chan;
                sg = &cas->sg;
                sg->g = g;
-               sg->selgen = g->selgen;
+               sg->selectdone = &done;
 
                switch(cas->kind) {
                case CaseRecv:
@@ -1055,7 +1020,7 @@ loop:
        }
 
        g->param = nil;
-       runtime_park((void(*)(Lock*))selunlock, (Lock*)sel, "select");
+       runtime_park(selparkcommit, sel, "select");
 
        sellock(sel);
        sg = g->param;
@@ -1091,13 +1056,23 @@ loop:
                        *cas->receivedp = true;
        }
 
+       if(raceenabled) {
+               if(cas->kind == CaseRecv && cas->sg.elem != nil)
+                       runtime_racewriteobjectpc(cas->sg.elem, c->elemtype, selectgo, chanrecv);
+               else if(cas->kind == CaseSend)
+                       runtime_racereadobjectpc(cas->sg.elem, c->elemtype, selectgo, chansend);
+       }
+
        selunlock(sel);
        goto retc;
 
 asyncrecv:
        // can receive from buffer
-       if(raceenabled)
+       if(raceenabled) {
+               if(cas->sg.elem != nil)
+                       runtime_racewriteobjectpc(cas->sg.elem, c->elemtype, selectgo, chanrecv);
                runtime_raceacquire(chanbuf(c, c->recvx));
+       }
        if(cas->receivedp != nil)
                *cas->receivedp = true;
        if(cas->sg.elem != nil)
@@ -1120,8 +1095,10 @@ asyncrecv:
 
 asyncsend:
        // can send to buffer
-       if(raceenabled)
+       if(raceenabled) {
                runtime_racerelease(chanbuf(c, c->sendx));
+               runtime_racereadobjectpc(cas->sg.elem, c->elemtype, selectgo, chansend);
+       }
        runtime_memmove(chanbuf(c, c->sendx), cas->sg.elem, c->elemsize);
        if(++c->sendx == c->dataqsiz)
                c->sendx = 0;
@@ -1140,8 +1117,11 @@ asyncsend:
 
 syncrecv:
        // can receive from sleeping sender (sg)
-       if(raceenabled)
+       if(raceenabled) {
+               if(cas->sg.elem != nil)
+                       runtime_racewriteobjectpc(cas->sg.elem, c->elemtype, selectgo, chanrecv);
                racesync(c, sg);
+       }
        selunlock(sel);
        if(debug)
                runtime_printf("syncrecv: sel=%p c=%p o=%d\n", sel, c, o);
@@ -1169,8 +1149,10 @@ rclose:
 
 syncsend:
        // can send to sleeping receiver (sg)
-       if(raceenabled)
+       if(raceenabled) {
+               runtime_racereadobjectpc(cas->sg.elem, c->elemtype, selectgo, chansend);
                racesync(c, sg);
+       }
        selunlock(sel);
        if(debug)
                runtime_printf("syncsend: sel=%p c=%p o=%d\n", sel, c, o);
@@ -1204,7 +1186,7 @@ struct runtimeSelect
        uintptr dir;
        ChanType *typ;
        Hchan *ch;
-       uintptr val;
+       byte *val;
 };
 
 // This enum must match ../reflect/value.go:/SelectDir.
@@ -1214,14 +1196,13 @@ enum SelectDir {
        SelectDefault,
 };
 
+// func rselect(cases []runtimeSelect) (chosen int, recvOK bool)
+
 struct rselect_ret {
        intgo chosen;
-       uintptr word;
-       bool recvOK;
+       _Bool recvOK;
 };
 
-// func rselect(cases []runtimeSelect) (chosen int, word uintptr, recvOK bool)
-
 struct rselect_ret reflect_rselect(Slice)
      __asm__ (GOSYM_PREFIX "reflect.rselect");
 
@@ -1229,36 +1210,18 @@ struct rselect_ret
 reflect_rselect(Slice cases)
 {
        struct rselect_ret ret;
+       intgo chosen;
+       bool recvOK;
        int32 i;
        Select *sel;
        runtimeSelect* rcase, *rc;
-       void *elem;
-       void *recvptr;
-       uintptr maxsize;
-       bool onlyptr;
 
-       ret.chosen = -1;
-       ret.word = 0;
-       ret.recvOK = false;
+       chosen = -1;
+       recvOK = false;
 
-       maxsize = 0;
-       onlyptr = true;
        rcase = (runtimeSelect*)cases.__values;
-       for(i=0; i<cases.__count; i++) {
-               rc = &rcase[i];
-               if(rc->dir == SelectRecv && rc->ch != nil) {
-                       if(maxsize < rc->typ->__element_type->__size)
-                               maxsize = rc->typ->__element_type->__size;
-                       if(!__go_is_pointer_type(rc->typ->__element_type))
-                               onlyptr = false;
-               }
-       }
-
-       recvptr = nil;
-       if(!onlyptr)
-               recvptr = runtime_mal(maxsize);
 
-       newselect(cases.__count, &sel);
+       sel = newselect(cases.__count);
        for(i=0; i<cases.__count; i++) {
                rc = &rcase[i];
                switch(rc->dir) {
@@ -1268,28 +1231,20 @@ reflect_rselect(Slice cases)
                case SelectSend:
                        if(rc->ch == nil)
                                break;
-                       if(!__go_is_pointer_type(rc->typ->__element_type))
-                               elem = (void*)rc->val;
-                       else
-                               elem = (void*)&rc->val;
-                       selectsend(sel, rc->ch, i, elem);
+                       selectsend(sel, rc->ch, i, rc->val);
                        break;
                case SelectRecv:
                        if(rc->ch == nil)
                                break;
-                       if(!__go_is_pointer_type(rc->typ->__element_type))
-                               elem = recvptr;
-                       else
-                               elem = &ret.word;
-                       selectrecv(sel, rc->ch, i, elem, &ret.recvOK);
+                       selectrecv(sel, rc->ch, i, rc->val, &recvOK);
                        break;
                }
        }
 
-       ret.chosen = (intgo)(uintptr)selectgo(&sel);
-       if(rcase[ret.chosen].dir == SelectRecv && !__go_is_pointer_type(rcase[ret.chosen].typ->__element_type))
-               ret.word = (uintptr)recvptr;
+       chosen = (intgo)(uintptr)selectgo(&sel);
 
+       ret.chosen = chosen;
+       ret.recvOK = (_Bool)recvOK;
        return ret;
 }
 
@@ -1428,12 +1383,11 @@ loop:
                return nil;
        q->first = sgp->link;
 
-       // if sgp is stale, ignore it
-       if(sgp->selgen != NOSELGEN &&
-               (sgp->selgen != sgp->g->selgen ||
-               !runtime_cas(&sgp->g->selgen, sgp->selgen, sgp->selgen + 2))) {
-               //prints("INVALID PSEUDOG POINTER\n");
-               goto loop;
+       // if sgp participates in a select and is already signaled, ignore it
+       if(sgp->selectdone != nil) {
+               // claim the right to signal
+               if(*sgp->selectdone != 0 || !runtime_cas(sgp->selectdone, 0, 1))
+                       goto loop;
        }
 
        return sgp;
index 3219550af99d7ca945cb08299ec654ef6cd542d6..93f90f54118a49928f77df1a1c16884a66c20052 100644 (file)
@@ -2,10 +2,12 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin dragonfly freebsd linux netbsd openbsd windows
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
 
 #include "runtime.h"
 #include "array.h"
+#include "arch.h"
+#include "malloc.h"
 
 extern Slice syscall_Envs __asm__ (GOSYM_PREFIX "syscall.Envs");
 
index 8d5dee21616c2cd7557de2cf6ea8e7a8d82dd26f..1b2d49e53c1bc789e3018d4d2cd7351260a21193 100644 (file)
@@ -37,6 +37,7 @@ __go_append (struct __go_open_array a, void *bvalues, uintptr_t bcount,
   if (count > a.__capacity)
     {
       intgo m;
+      uintptr capmem;
       void *n;
 
       m = a.__capacity;
@@ -57,7 +58,9 @@ __go_append (struct __go_open_array a, void *bvalues, uintptr_t bcount,
       if (element_size > 0 && (uintptr) m > MaxMem / element_size)
        runtime_panicstring ("growslice: cap out of range");
 
-      n = __go_alloc (m * element_size);
+      capmem = runtime_roundupsize (m * element_size);
+
+      n = __go_alloc (capmem);
       __builtin_memcpy (n, a.__values, a.__count * element_size);
 
       a.__values = n;
index 4c61ae7db2f26aaed0030fa4cce63179d98bad21..5dd8c3105f73022084091a5bd6d7477caa1c3105 100644 (file)
@@ -20,7 +20,7 @@ __go_defer (_Bool *frame, void (*pfn) (void *), void *arg)
   struct __go_defer_stack *n;
 
   g = runtime_g ();
-  n = (struct __go_defer_stack *) __go_alloc (sizeof (struct __go_defer_stack));
+  n = runtime_newdefer ();
   n->__next = g->defer;
   n->__frame = frame;
   n->__panic = g->panic;
@@ -28,7 +28,7 @@ __go_defer (_Bool *frame, void (*pfn) (void *), void *arg)
   n->__arg = arg;
   n->__retaddr = NULL;
   n->__makefunc_can_recover = 0;
-  n->__free = 1;
+  n->__special = 0;
   g->defer = n;
 }
 
@@ -44,7 +44,6 @@ __go_undefer (_Bool *frame)
     {
       struct __go_defer_stack *d;
       void (*pfn) (void *);
-      M *m;
 
       d = g->defer;
       pfn = d->__pfn;
@@ -59,9 +58,8 @@ __go_undefer (_Bool *frame)
         call to syscall.CgocallBackDone, in which case we will not
         have a memory context.  Don't try to free anything in that
         case--the GC will release it later.  */
-      m = runtime_m ();
-      if (m != NULL && m->mcache != NULL && d->__free)
-       __go_free (d);
+      if (runtime_m () != NULL)
+       runtime_freedefer (d);
 
       /* Since we are executing a defer function here, we know we are
         returning from the calling function.  If the calling
index d110a8766e3cdb26f53a6cbc6487c2c2082b9060..acf2d40c69c2c16564d8d6b869b99b0b6fc7873b 100644 (file)
@@ -20,8 +20,8 @@ struct __go_defer_stack
 
   /* The value of the panic stack when this function is deferred.
      This function can not recover this value from the panic stack.
-     This can happen if a deferred function uses its own defer
-     statement.  */
+     This can happen if a deferred function has a defer statement
+     itself.  */
   struct __go_panic_stack *__panic;
 
   /* The function to call.  */
@@ -41,7 +41,7 @@ struct __go_defer_stack
      useful.  */
   _Bool __makefunc_can_recover;
 
-  /* Set to true if this defer stack entry should be freed when
-     done.  */
-  _Bool __free;
+  /* Set to true if this defer stack entry is not part of the defer
+     pool.  */
+  _Bool __special;
 };
index 0cacbcd91cbb511b5e5a869140f76f345273b656..77975c6e083a29fa01a890e94bcf591a87940d14 100644 (file)
@@ -54,7 +54,6 @@ __go_panic (struct __go_empty_interface arg)
     {
       struct __go_defer_stack *d;
       void (*pfn) (void *);
-      M *m;
 
       d = g->defer;
       if (d == NULL)
@@ -101,9 +100,8 @@ __go_panic (struct __go_empty_interface arg)
         call to syscall.CgocallBackDone, in which case we will not
         have a memory context.  Don't try to free anything in that
         case--the GC will release it later.  */
-      m = runtime_m ();
-      if (m != NULL && m->mcache != NULL && d->__free)
-       __go_free (d);
+      if (runtime_m () != NULL)
+       runtime_freedefer (d);
     }
 
   /* The panic was not recovered.  */
index 6c7378c9ecf3477c0bff152999533660285d3b00..a75d7c412772362341cfc78d7a144a6c03ae8d78 100644 (file)
@@ -11,6 +11,8 @@
 
 #include "go-alloc.h"
 #include "runtime.h"
+#include "arch.h"
+#include "malloc.h"
 
 /* Set the C environment from Go.  This is called by syscall.Setenv.  */
 
@@ -23,6 +25,7 @@ setenv_c (String k, String v)
   unsigned char *kn;
   const byte *vs;
   unsigned char *vn;
+  intgo len;
 
   ks = k.str;
   if (ks == NULL)
@@ -38,14 +41,22 @@ setenv_c (String k, String v)
 
   if (ks != NULL && ks[k.len] != 0)
     {
-      kn = __go_alloc (k.len + 1);
+      // Objects that are explicitly freed must be at least 16 bytes in size,
+      // so that they are not allocated using tiny alloc.
+      len = k.len + 1;
+      if (len < TinySize)
+       len = TinySize;
+      kn = __go_alloc (len);
       __builtin_memcpy (kn, ks, k.len);
       ks = kn;
     }
 
   if (vs != NULL && vs[v.len] != 0)
     {
-      vn = __go_alloc (v.len + 1);
+      len = v.len + 1;
+      if (len < TinySize)
+       len = TinySize;
+      vn = __go_alloc (len);
       __builtin_memcpy (vn, vs, v.len);
       vs = vn;
     }
@@ -54,7 +65,10 @@ setenv_c (String k, String v)
 
 #else /* !defined(HAVE_SETENV) */
 
-  kn = __go_alloc (k.len + v.len + 2);
+  len = k.len + v.len + 2;
+  if (len < TinySize)
+    len = TinySize;
+  kn = __go_alloc (len);
   __builtin_memcpy (kn, ks, k.len);
   kn[k.len] = '=';
   __builtin_memcpy (kn + k.len + 1, vs, v.len);
index 5e030330f29533c9d341a951fe967b8308d87621..a4edb50da5f72b8324684600927c14e0665b1ce8 100644 (file)
 struct __go_open_array
 __go_string_to_byte_array (String str)
 {
+  uintptr cap;
   unsigned char *data;
   struct __go_open_array ret;
 
-  data = (unsigned char *) runtime_mallocgc (str.len, 0,
-                                            FlagNoScan | FlagNoZero);
+  cap = runtime_roundupsize (str.len);
+  data = (unsigned char *) runtime_mallocgc (cap, 0, FlagNoScan | FlagNoZero);
   __builtin_memcpy (data, str.str, str.len);
+  if (cap != (uintptr) str.len)
+    __builtin_memset (data + str.len, 0, cap - (uintptr) str.len);
   ret.__values = (void *) data;
   ret.__count = str.len;
-  ret.__capacity = str.len;
+  ret.__capacity = (intgo) cap;
   return ret;
 }
index d91c9e2df82c00d536cda19f6b04f6f1b30d3605..554688913101acb0021298c28220da0ff3087328 100644 (file)
@@ -17,6 +17,7 @@ __go_string_to_int_array (String str)
   size_t c;
   const unsigned char *p;
   const unsigned char *pend;
+  uintptr mem;
   uint32_t *data;
   uint32_t *pd;
   struct __go_open_array ret;
@@ -32,8 +33,11 @@ __go_string_to_int_array (String str)
       p += __go_get_rune (p, pend - p, &rune);
     }
 
-  data = (uint32_t *) runtime_mallocgc (c * sizeof (uint32_t), 0,
-                                       FlagNoScan | FlagNoZero);
+  if (c > MaxMem / sizeof (uint32_t))
+    runtime_throw ("out of memory");
+
+  mem = runtime_roundupsize (c * sizeof (uint32_t));
+  data = (uint32_t *) runtime_mallocgc (mem, 0, FlagNoScan | FlagNoZero);
   p = str.str;
   pd = data;
   while (p < pend)
@@ -43,9 +47,10 @@ __go_string_to_int_array (String str)
       p += __go_get_rune (p, pend - p, &rune);
       *pd++ = rune;
     }
-
+  if (mem > (uintptr) c * sizeof (uint32_t))
+    __builtin_memset (data + c, 0, mem - (uintptr) c * sizeof (uint32_t));
   ret.__values = (void *) data;
   ret.__count = c;
-  ret.__capacity = c;
+  ret.__capacity = (intgo) (mem / sizeof (uint32_t));
   return ret;
 }
index 04b0a28607aa4d0ccdcef7df6f87e60349777290..849256b631fca5fb4d2683ee860a7fa351b34d47 100644 (file)
@@ -80,7 +80,6 @@ __go_check_defer (_Bool *frame)
        {
          struct __go_defer_stack *d;
          void (*pfn) (void *);
-         M *m;
 
          d = g->defer;
          if (d == NULL || d->__frame != frame || d->__pfn == NULL)
@@ -91,9 +90,8 @@ __go_check_defer (_Bool *frame)
 
          (*pfn) (d->__arg);
 
-         m = runtime_m ();
-         if (m != NULL && m->mcache != NULL && d->__free)
-           __go_free (d);
+         if (runtime_m () != NULL)
+           runtime_freedefer (d);
 
          if (n->__was_recovered)
            {
@@ -122,7 +120,6 @@ __go_check_defer (_Bool *frame)
           && g->defer->__frame == frame)
     {
       struct __go_defer_stack *d;
-      M *m;
 
       /* This is the defer function which called recover.  Simply
         return to stop the stack unwind, and let the Go code continue
@@ -130,9 +127,8 @@ __go_check_defer (_Bool *frame)
       d = g->defer;
       g->defer = d->__next;
 
-      m = runtime_m ();
-      if (m != NULL && m->mcache != NULL && d->__free)
-       __go_free (d);
+      if (runtime_m () != NULL)
+       runtime_freedefer (d);
 
       /* We are returning from this function.  */
       *frame = 1;
index 682c08d64d4d11822a752c41e833b57c28ba684c..705f55ee20bd4f58dcdcb9e3291c8202fc44d96b 100644 (file)
@@ -26,6 +26,12 @@ __go_fcntl (int fd, int cmd, int arg)
   return fcntl (fd, cmd, arg);
 }
 
+int
+__go_fcntl_flock (int fd, int cmd, struct flock *arg)
+{
+  return fcntl (fd, cmd, arg);
+}
+
 #ifdef HAVE_OPEN64
 
 int
index fa2701328958ae94a9b0891b883cc350a1baf7dd..33ef073c907e1029a1c92d3c971f0e575b69daba 100644 (file)
@@ -124,26 +124,36 @@ runtime_notewakeup(Note *n)
 void
 runtime_notesleep(Note *n)
 {
+       M *m = runtime_m();
+
   /* For gccgo it's OK to sleep in non-g0, and it happens in
      stoptheworld because we have not implemented preemption.
 
        if(runtime_g() != runtime_m()->g0)
                runtime_throw("notesleep not on g0");
   */
-       while(runtime_atomicload((uint32*)&n->key) == 0)
+       while(runtime_atomicload((uint32*)&n->key) == 0) {
+               m->blocked = true;
                runtime_futexsleep((uint32*)&n->key, 0, -1);
+               m->blocked = false;
+       }
 }
 
 static bool
 notetsleep(Note *n, int64 ns, int64 deadline, int64 now)
 {
+       M *m = runtime_m();
+
        // Conceptually, deadline and now are local variables.
        // They are passed as arguments so that the space for them
        // does not count against our nosplit stack sequence.
 
        if(ns < 0) {
-               while(runtime_atomicload((uint32*)&n->key) == 0)
+               while(runtime_atomicload((uint32*)&n->key) == 0) {
+                       m->blocked = true;
                        runtime_futexsleep((uint32*)&n->key, 0, -1);
+                       m->blocked = false;
+               }
                return true;
        }
 
@@ -152,7 +162,9 @@ notetsleep(Note *n, int64 ns, int64 deadline, int64 now)
 
        deadline = runtime_nanotime() + ns;
        for(;;) {
+               m->blocked = true;
                runtime_futexsleep((uint32*)&n->key, 0, ns);
+               m->blocked = false;
                if(runtime_atomicload((uint32*)&n->key) != 0)
                        break;
                now = runtime_nanotime();
index 000b9fcf7010349ec76e73a189f1cd46f78d8834..d0d551de874ad0add64453e0d27e97404754284e 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin netbsd openbsd plan9 windows
+// +build darwin netbsd openbsd plan9 solaris windows
 
 #include "runtime.h"
 
@@ -167,7 +167,9 @@ runtime_notesleep(Note *n)
                return;
        }
        // Queued.  Sleep.
+       m->blocked = true;
        runtime_semasleep(-1);
+       m->blocked = false;
 }
 
 static bool
@@ -190,18 +192,23 @@ notetsleep(Note *n, int64 ns, int64 deadline, M *mp)
 
        if(ns < 0) {
                // Queued.  Sleep.
+               m->blocked = true;
                runtime_semasleep(-1);
+               m->blocked = false;
                return true;
        }
 
        deadline = runtime_nanotime() + ns;
        for(;;) {
                // Registered.  Sleep.
+               m->blocked = true;
                if(runtime_semasleep(ns) >= 0) {
+                       m->blocked = false;
                        // Acquired semaphore, semawakeup unregistered us.
                        // Done.
                        return true;
                }
+               m->blocked = false;
 
                // Interrupted or timed out.  Still registered.  Semaphore not acquired.
                ns = deadline - runtime_nanotime();
@@ -223,8 +230,10 @@ notetsleep(Note *n, int64 ns, int64 deadline, M *mp)
                } else if(mp == (M*)LOCKED) {
                        // Wakeup happened so semaphore is available.
                        // Grab it to avoid getting out of sync.
+                       m->blocked = true;
                        if(runtime_semasleep(-1) < 0)
                                runtime_throw("runtime: unable to acquire - semaphore out of sync");
+                       m->blocked = false;
                        return true;
                } else
                        runtime_throw("runtime: unexpected waitm - semaphore out of sync");
index 33d0c39b36732545575f22d742f41577baa8f1f0..798d875b9bc98877aa8e888b4fbb9f516a906058 100644 (file)
@@ -54,6 +54,7 @@ package runtime
 
 // Mark mheap as 'no pointers', it does not contain interesting pointers but occupies ~45K.
 MHeap runtime_mheap;
+MStats mstats;
 
 int32  runtime_checking;
 
@@ -62,6 +63,9 @@ extern MStats mstats; // defined in zruntime_def_$GOOS_$GOARCH.go
 extern volatile intgo runtime_MemProfileRate
   __asm__ (GOSYM_PREFIX "runtime.MemProfileRate");
 
+static void* largealloc(uint32, uintptr*);
+static void profilealloc(void *v, uintptr size, uintptr typ);
+
 // Allocate an object of at least size bytes.
 // Small objects are allocated from the per-thread cache's free lists.
 // Large objects (> 32 kB) are allocated straight from the heap.
@@ -72,12 +76,12 @@ runtime_mallocgc(uintptr size, uintptr typ, uint32 flag)
        M *m;
        G *g;
        int32 sizeclass;
+       uintptr tinysize, size1;
        intgo rate;
        MCache *c;
        MCacheList *l;
-       uintptr npages;
-       MSpan *s;
-       MLink *v;
+       MLink *v, *next;
+       byte *tiny;
        bool incallback;
 
        if(size == 0) {
@@ -119,6 +123,81 @@ runtime_mallocgc(uintptr size, uintptr typ, uint32 flag)
 
        c = m->mcache;
        if(!runtime_debug.efence && size <= MaxSmallSize) {
+               if((flag&(FlagNoScan|FlagNoGC)) == FlagNoScan && size < TinySize) {
+                       // Tiny allocator.
+                       //
+                       // Tiny allocator combines several tiny allocation requests
+                       // into a single memory block. The resulting memory block
+                       // is freed when all subobjects are unreachable. The subobjects
+                       // must be FlagNoScan (don't have pointers), this ensures that
+                       // the amount of potentially wasted memory is bounded.
+                       //
+                       // Size of the memory block used for combining (TinySize) is tunable.
+                       // Current setting is 16 bytes, which relates to 2x worst case memory
+                       // wastage (when all but one subobjects are unreachable).
+                       // 8 bytes would result in no wastage at all, but provides less
+                       // opportunities for combining.
+                       // 32 bytes provides more opportunities for combining,
+                       // but can lead to 4x worst case wastage.
+                       // The best case winning is 8x regardless of block size.
+                       //
+                       // Objects obtained from tiny allocator must not be freed explicitly.
+                       // So when an object will be freed explicitly, we ensure that
+                       // its size >= TinySize.
+                       //
+                       // SetFinalizer has a special case for objects potentially coming
+                       // from tiny allocator, it such case it allows to set finalizers
+                       // for an inner byte of a memory block.
+                       //
+                       // The main targets of tiny allocator are small strings and
+                       // standalone escaping variables. On a json benchmark
+                       // the allocator reduces number of allocations by ~12% and
+                       // reduces heap size by ~20%.
+
+                       tinysize = c->tinysize;
+                       if(size <= tinysize) {
+                               tiny = c->tiny;
+                               // Align tiny pointer for required (conservative) alignment.
+                               if((size&7) == 0)
+                                       tiny = (byte*)ROUND((uintptr)tiny, 8);
+                               else if((size&3) == 0)
+                                       tiny = (byte*)ROUND((uintptr)tiny, 4);
+                               else if((size&1) == 0)
+                                       tiny = (byte*)ROUND((uintptr)tiny, 2);
+                               size1 = size + (tiny - c->tiny);
+                               if(size1 <= tinysize) {
+                                       // The object fits into existing tiny block.
+                                       v = (MLink*)tiny;
+                                       c->tiny += size1;
+                                       c->tinysize -= size1;
+                                       m->mallocing = 0;
+                                       m->locks--;
+                                       if(incallback)
+                                               runtime_entersyscall();
+                                       return v;
+                               }
+                       }
+                       // Allocate a new TinySize block.
+                       l = &c->list[TinySizeClass];
+                       if(l->list == nil)
+                               runtime_MCache_Refill(c, TinySizeClass);
+                       v = l->list;
+                       next = v->next;
+                       if(next != nil)  // prefetching nil leads to a DTLB miss
+                               PREFETCH(next);
+                       l->list = next;
+                       l->nlist--;
+                       ((uint64*)v)[0] = 0;
+                       ((uint64*)v)[1] = 0;
+                       // See if we need to replace the existing tiny block with the new one
+                       // based on amount of remaining free space.
+                       if(TinySize-size > tinysize) {
+                               c->tiny = (byte*)v + size;
+                               c->tinysize = TinySize - size;
+                       }
+                       size = TinySize;
+                       goto done;
+               }
                // Allocate from mcache free lists.
                // Inlined version of SizeToClass().
                if(size <= 1024-8)
@@ -130,31 +209,22 @@ runtime_mallocgc(uintptr size, uintptr typ, uint32 flag)
                if(l->list == nil)
                        runtime_MCache_Refill(c, sizeclass);
                v = l->list;
-               l->list = v->next;
+               next = v->next;
+               if(next != nil)  // prefetching nil leads to a DTLB miss
+                       PREFETCH(next);
+               l->list = next;
                l->nlist--;
                if(!(flag & FlagNoZero)) {
                        v->next = nil;
                        // block is zeroed iff second word is zero ...
-                       if(size > sizeof(uintptr) && ((uintptr*)v)[1] != 0)
+                       if(size > 2*sizeof(uintptr) && ((uintptr*)v)[1] != 0)
                                runtime_memclr((byte*)v, size);
                }
+       done:
                c->local_cachealloc += size;
        } else {
-               // TODO(rsc): Report tracebacks for very large allocations.
-
                // Allocate directly from heap.
-               npages = size >> PageShift;
-               if((size & PageMask) != 0)
-                       npages++;
-               s = runtime_MHeap_Alloc(&runtime_mheap, npages, 0, 1, !(flag & FlagNoZero));
-               if(s == nil)
-                       runtime_throw("out of memory");
-               s->limit = (byte*)(s->start<<PageShift) + size;
-               size = npages<<PageShift;
-               v = (void*)(s->start << PageShift);
-
-               // setup for mark sweep
-               runtime_markspan(v, 0, 0, true);
+               v = largealloc(flag, &size);
        }
 
        if(flag & FlagNoGC)
@@ -180,40 +250,83 @@ runtime_mallocgc(uintptr size, uintptr typ, uint32 flag)
        m->mallocing = 0;
        if(UseSpanType && !(flag & FlagNoScan) && typ != 0 && m->settype_bufsize == nelem(m->settype_buf))
                runtime_settype_flush(m);
-       m->locks--;
+       if(raceenabled)
+               runtime_racemalloc(v, size);
 
        if(runtime_debug.allocfreetrace)
                goto profile;
 
        if(!(flag & FlagNoProfiling) && (rate = runtime_MemProfileRate) > 0) {
-               if(size >= (uint32) rate)
-                       goto profile;
-               if((uint32) m->mcache->next_sample > size)
-                       m->mcache->next_sample -= size;
+               if(size < (uintptr)rate && size < (uintptr)(uint32)c->next_sample)
+                       c->next_sample -= size;
                else {
-                       // pick next profile time
-                       // If you change this, also change allocmcache.
-                       if(rate > 0x3fffffff)   // make 2*rate not overflow
-                               rate = 0x3fffffff;
-                       m->mcache->next_sample = runtime_fastrand1() % (2*rate);
                profile:
-                       runtime_setblockspecial(v, true);
-                       runtime_MProf_Malloc(v, size, typ);
+                       profilealloc(v, size, typ);
                }
        }
 
+       m->locks--;
+
        if(!(flag & FlagNoInvokeGC) && mstats.heap_alloc >= mstats.next_gc)
                runtime_gc(0);
 
-       if(raceenabled)
-               runtime_racemalloc(v, size);
-
        if(incallback)
                runtime_entersyscall();
 
        return v;
 }
 
+static void*
+largealloc(uint32 flag, uintptr *sizep)
+{
+       uintptr npages, size;
+       MSpan *s;
+       void *v;
+
+       // Allocate directly from heap.
+       size = *sizep;
+       if(size + PageSize < size)
+               runtime_throw("out of memory");
+       npages = size >> PageShift;
+       if((size & PageMask) != 0)
+               npages++;
+       s = runtime_MHeap_Alloc(&runtime_mheap, npages, 0, 1, !(flag & FlagNoZero));
+       if(s == nil)
+               runtime_throw("out of memory");
+       s->limit = (byte*)(s->start<<PageShift) + size;
+       *sizep = npages<<PageShift;
+       v = (void*)(s->start << PageShift);
+       // setup for mark sweep
+       runtime_markspan(v, 0, 0, true);
+       return v;
+}
+
+static void
+profilealloc(void *v, uintptr size, uintptr typ)
+{
+       uintptr rate;
+       int32 next;
+       MCache *c;
+
+       c = runtime_m()->mcache;
+       rate = runtime_MemProfileRate;
+       if(size < rate) {
+               // pick next profile time
+               // If you change this, also change allocmcache.
+               if(rate > 0x3fffffff)   // make 2*rate not overflow
+                       rate = 0x3fffffff;
+               next = runtime_fastrand1() % (2*rate);
+               // Subtract the "remainder" of the current allocation.
+               // Otherwise objects that are close in size to sampling rate
+               // will be under-sampled, because we consistently discard this remainder.
+               next -= (size - c->next_sample);
+               if(next < 0)
+                       next = 0;
+               c->next_sample = next;
+       }
+       runtime_MProf_Malloc(v, size, typ);
+}
+
 void*
 __go_alloc(uintptr size)
 {
@@ -228,7 +341,6 @@ __go_free(void *v)
        int32 sizeclass;
        MSpan *s;
        MCache *c;
-       uint32 prof;
        uintptr size;
 
        if(v == nil)
@@ -246,18 +358,27 @@ __go_free(void *v)
                runtime_printf("free %p: not an allocated block\n", v);
                runtime_throw("free runtime_mlookup");
        }
-       prof = runtime_blockspecial(v);
+       size = s->elemsize;
+       sizeclass = s->sizeclass;
+       // Objects that are smaller than TinySize can be allocated using tiny alloc,
+       // if then such object is combined with an object with finalizer, we will crash.
+       if(size < TinySize)
+               runtime_throw("freeing too small block");
 
        if(raceenabled)
                runtime_racefree(v);
 
-       // Find size class for v.
-       sizeclass = s->sizeclass;
+       // Ensure that the span is swept.
+       // If we free into an unswept span, we will corrupt GC bitmaps.
+       runtime_MSpan_EnsureSwept(s);
+
+       if(s->specials != nil)
+               runtime_freeallspecials(s, v, size);
+
        c = m->mcache;
        if(sizeclass == 0) {
                // Large object.
-               size = s->npages<<PageShift;
-               *(uintptr*)(s->start<<PageShift) = (uintptr)0xfeedfeedfeedfeedll;       // mark as "needs to be zeroed"
+               s->needzero = 1;
                // Must mark v freed before calling unmarkspan and MHeap_Free:
                // they might coalesce v into other spans and change the bitmap further.
                runtime_markfreed(v, size);
@@ -270,9 +391,10 @@ __go_free(void *v)
                c->local_largefree += size;
        } else {
                // Small object.
-               size = runtime_class_to_size[sizeclass];
-               if(size > sizeof(uintptr))
+               if(size > 2*sizeof(uintptr))
                        ((uintptr*)v)[1] = (uintptr)0xfeedfeedfeedfeedll;       // mark as "needs to be zeroed"
+               else if(size > sizeof(uintptr))
+                       ((uintptr*)v)[1] = 0;
                // Must mark v freed before calling MCache_Free:
                // it might coalesce v and other blocks into a bigger span
                // and change the bitmap further.
@@ -280,8 +402,6 @@ __go_free(void *v)
                c->local_nsmallfree[sizeclass]++;
                runtime_MCache_Free(c, v, sizeclass, size);
        }
-       if(prof)
-               runtime_MProf_Free(v, size);
        m->mallocing = 0;
 }
 
@@ -392,6 +512,12 @@ runtime_purgecachedstats(MCache *c)
 extern uintptr runtime_sizeof_C_MStats
   __asm__ (GOSYM_PREFIX "runtime.Sizeof_C_MStats");
 
+// Size of the trailing by_size array differs between Go and C,
+// NumSizeClasses was changed, but we can not change Go struct because of backward compatibility.
+// sizeof_C_MStats is what C thinks about size of Go struct.
+
+// Initialized in mallocinit because it's defined in go/runtime/mem.go.
+
 #define MaxArena32 (2U<<30)
 
 void
@@ -400,11 +526,10 @@ runtime_mallocinit(void)
        byte *p;
        uintptr arena_size, bitmap_size, spans_size;
        extern byte _end[];
-       byte *want;
        uintptr limit;
        uint64 i;
 
-       runtime_sizeof_C_MStats = sizeof(MStats);
+       runtime_sizeof_C_MStats = sizeof(MStats) - (NumSizeClasses - 61) * sizeof(mstats.by_size[0]);
 
        p = nil;
        arena_size = 0;
@@ -419,6 +544,9 @@ runtime_mallocinit(void)
 
        runtime_InitSizes();
 
+       if(runtime_class_to_size[TinySizeClass] != TinySize)
+               runtime_throw("bad TinySizeClass");
+
        // limit = runtime_memlimit();
        // See https://code.google.com/p/go/issues/detail?id=5049
        // TODO(rsc): Fix after 1.1.
@@ -457,7 +585,7 @@ runtime_mallocinit(void)
                spans_size = arena_size / PageSize * sizeof(runtime_mheap.spans[0]);
                spans_size = ROUND(spans_size, PageSize);
                for(i = 0; i < HeapBaseOptions; i++) {
-                       p = runtime_SysReserve(HeapBase(i), bitmap_size + spans_size + arena_size);
+                       p = runtime_SysReserve(HeapBase(i), bitmap_size + spans_size + arena_size + PageSize);
                        if(p != nil)
                                break;
                }
@@ -499,18 +627,16 @@ runtime_mallocinit(void)
                // So adjust it upward a little bit ourselves: 1/4 MB to get
                // away from the running binary image and then round up
                // to a MB boundary.
-               want = (byte*)ROUND((uintptr)_end + (1<<18), 1<<20);
-               if(0xffffffff - (uintptr)want <= bitmap_size + spans_size + arena_size)
-                 want = 0;
-               p = runtime_SysReserve(want, bitmap_size + spans_size + arena_size);
+               p = (byte*)ROUND((uintptr)_end + (1<<18), 1<<20);
+               p = runtime_SysReserve(p, bitmap_size + spans_size + arena_size + PageSize);
                if(p == nil)
                        runtime_throw("runtime: cannot reserve arena virtual address space");
-               if((uintptr)p & (((uintptr)1<<PageShift)-1))
-                       runtime_printf("runtime: SysReserve returned unaligned address %p; asked for %p", p,
-                               bitmap_size+spans_size+arena_size);
        }
-       if((uintptr)p & (((uintptr)1<<PageShift)-1))
-               runtime_throw("runtime: SysReserve returned unaligned address");
+
+       // PageSize can be larger than OS definition of page size,
+       // so SysReserve can give us a PageSize-unaligned pointer.
+       // To overcome this we ask for PageSize more and round up the pointer.
+       p = (byte*)ROUND((uintptr)p, PageSize);
 
        runtime_mheap.spans = (MSpan**)p;
        runtime_mheap.bitmap = p + spans_size;
@@ -523,7 +649,7 @@ runtime_mallocinit(void)
        runtime_m()->mcache = runtime_allocmcache();
 
        // See if it works.
-       runtime_free(runtime_malloc(1));
+       runtime_free(runtime_malloc(TinySize));
 }
 
 void*
@@ -828,16 +954,18 @@ func SetFinalizer(obj Eface, finalizer Eface) {
                goto throw;
        }
        ot = (const PtrType*)obj.type;
-       if(ot->__element_type != nil && ot->__element_type->__size == 0) {
+       // As an implementation detail we do not run finalizers for zero-sized objects,
+       // because we use &runtime_zerobase for all such allocations.
+       if(ot->__element_type != nil && ot->__element_type->__size == 0)
                return;
-       }
        if(!runtime_mlookup(obj.__object, &base, &size, nil) || obj.__object != base) {
-               runtime_printf("runtime.SetFinalizer: pointer not at beginning of allocated block\n");
-               goto throw;
+               // As an implementation detail we allow to set finalizers for an inner byte
+               // of an object if it could come from tiny alloc (see mallocgc for details).
+               if(ot->__element_type == nil || (ot->__element_type->__code&GO_NO_POINTERS) == 0 || ot->__element_type->__size >= TinySize) {
+                       runtime_printf("runtime.SetFinalizer: pointer not at beginning of allocated block\n");
+                       goto throw;
+               }
        }
-       ft = nil;
-       ot = (const PtrType*)obj.__type_descriptor;
-       fint = nil;
        if(finalizer.__type_descriptor != nil) {
                if(finalizer.__type_descriptor->__code != GO_FUNC)
                        goto badfunc;
@@ -856,11 +984,15 @@ func SetFinalizer(obj Eface, finalizer Eface) {
                        // ok - satisfies non-empty interface
                } else
                        goto badfunc;
-       }
 
-       if(!runtime_addfinalizer(obj.__object, finalizer.__type_descriptor != nil ? *(void**)finalizer.__object : nil, ft, ot)) {
-               runtime_printf("runtime.SetFinalizer: finalizer already set\n");
-               goto throw;
+               ot = (const PtrType*)obj.__type_descriptor;
+               if(!runtime_addfinalizer(obj.__object, *(FuncVal**)finalizer.__object, ft, ot)) {
+                       runtime_printf("runtime.SetFinalizer: finalizer already set\n");
+                       goto throw;
+               }
+       } else {
+               // NOTE: asking to remove a finalizer when there currently isn't one set is OK.
+               runtime_removefinalizer(obj.__object);
        }
        return;
 
index 16f51a51bdc69f8fc34bbf99d2ab53e7a8b9dc84..b5dc5a43aba3077af1d4121c9a4cabc8f54fb1bc 100644 (file)
 //
 // The small objects on the MCache and MCentral free lists
 // may or may not be zeroed.  They are zeroed if and only if
-// the second word of the object is zero.  The spans in the
-// page heap are always zeroed.  When a span full of objects
-// is returned to the page heap, the objects that need to be
-// are zeroed first.  There are two main benefits to delaying the
+// the second word of the object is zero.  A span in the
+// page heap is zeroed unless s->needzero is set. When a span
+// is allocated to break into small objects, it is zeroed if needed
+// and s->needzero is set. There are two main benefits to delaying the
 // zeroing this way:
 //
 //     1. stack frames allocated from the small object lists
-//        can avoid zeroing altogether.
+//        or the page heap can avoid zeroing altogether.
 //     2. the cost of zeroing when reusing a small object is
 //        charged to the mutator, not the garbage collector.
 //
@@ -90,7 +90,7 @@ typedef struct GCStats        GCStats;
 
 enum
 {
-       PageShift       = 12,
+       PageShift       = 13,
        PageSize        = 1<<PageShift,
        PageMask        = PageSize - 1,
 };
@@ -103,11 +103,15 @@ enum
        // size classes.  NumSizeClasses is that number.  It's needed here
        // because there are static arrays of this length; when msize runs its
        // size choosing algorithm it double-checks that NumSizeClasses agrees.
-       NumSizeClasses = 61,
+       NumSizeClasses = 67,
 
        // Tunable constants.
        MaxSmallSize = 32<<10,
 
+       // Tiny allocator parameters, see "Tiny allocator" comment in malloc.goc.
+       TinySize = 16,
+       TinySizeClass = 2,
+
        FixAllocChunk = 16<<10,         // Chunk size for FixAlloc
        MaxMHeapList = 1<<(20 - PageShift),     // Maximum page length for fixed-size list in MHeap.
        HeapAllocChunk = 1<<20,         // Chunk size for heap growth
@@ -256,7 +260,7 @@ struct MStats
 };
 
 extern MStats mstats
-  __asm__ (GOSYM_PREFIX "runtime.VmemStats");
+  __asm__ (GOSYM_PREFIX "runtime.memStats");
 
 // Size classes.  Computed and initialized by InitSizes.
 //
@@ -269,6 +273,7 @@ extern MStats mstats
 //     making new objects in class i
 
 int32  runtime_SizeToClass(int32);
+uintptr        runtime_roundupsize(uintptr);
 extern int32   runtime_class_to_size[NumSizeClasses];
 extern int32   runtime_class_to_allocnpages[NumSizeClasses];
 extern int8    runtime_size_to_class8[1024/8 + 1];
@@ -291,6 +296,10 @@ struct MCache
        // so they are grouped here for better caching.
        int32 next_sample;              // trigger heap sample after allocating this many bytes
        intptr local_cachealloc;        // bytes allocated (or freed) from cache since last lock of heap
+       // Allocator cache for tiny objects w/o pointers.
+       // See "Tiny allocator" comment in malloc.goc.
+       byte*   tiny;
+       uintptr tinysize;
        // The rest is not accessed on every malloc.
        MCacheList list[NumSizeClasses];
        // Local allocator stats, flushed during GC.
@@ -341,6 +350,43 @@ struct MTypes
        uintptr data;
 };
 
+enum
+{
+       KindSpecialFinalizer = 1,
+       KindSpecialProfile = 2,
+       // Note: The finalizer special must be first because if we're freeing
+       // an object, a finalizer special will cause the freeing operation
+       // to abort, and we want to keep the other special records around
+       // if that happens.
+};
+
+typedef struct Special Special;
+struct Special
+{
+       Special*        next;   // linked list in span
+       uint16          offset; // span offset of object
+       byte            kind;   // kind of Special
+};
+
+// The described object has a finalizer set for it.
+typedef struct SpecialFinalizer SpecialFinalizer;
+struct SpecialFinalizer
+{
+       Special;
+       FuncVal*        fn;
+       const FuncType* ft;
+       const PtrType*  ot;
+};
+
+// The described object is being heap profiled.
+typedef struct Bucket Bucket; // from mprof.goc
+typedef struct SpecialProfile SpecialProfile;
+struct SpecialProfile
+{
+       Special;
+       Bucket* b;
+};
+
 // An MSpan is a run of pages.
 enum
 {
@@ -356,17 +402,28 @@ struct MSpan
        PageID  start;          // starting page number
        uintptr npages;         // number of pages in span
        MLink   *freelist;      // list of free objects
-       uint32  ref;            // number of allocated objects in this span
-       int32   sizeclass;      // size class
+       // sweep generation:
+       // if sweepgen == h->sweepgen - 2, the span needs sweeping
+       // if sweepgen == h->sweepgen - 1, the span is currently being swept
+       // if sweepgen == h->sweepgen, the span is swept and ready to use
+       // h->sweepgen is incremented by 2 after every GC
+       uint32  sweepgen;
+       uint16  ref;            // number of allocated objects in this span
+       uint8   sizeclass;      // size class
+       uint8   state;          // MSpanInUse etc
+       uint8   needzero;       // needs to be zeroed before allocation
        uintptr elemsize;       // computed from sizeclass or from npages
-       uint32  state;          // MSpanInUse etc
        int64   unusedsince;    // First time spotted by GC in MSpanFree state
        uintptr npreleased;     // number of pages released to the OS
        byte    *limit;         // end of data in span
        MTypes  types;          // types of allocated objects in this span
+       Lock    specialLock;    // TODO: use to protect types also (instead of settype_lock)
+       Special *specials;      // linked list of special records sorted by offset.
 };
 
 void   runtime_MSpan_Init(MSpan *span, PageID start, uintptr npages);
+void   runtime_MSpan_EnsureSwept(MSpan *span);
+bool   runtime_MSpan_Sweep(MSpan *span);
 
 // Every MSpan is in one doubly-linked list,
 // either one of the MHeap's free lists or one of the
@@ -374,6 +431,7 @@ void        runtime_MSpan_Init(MSpan *span, PageID start, uintptr npages);
 void   runtime_MSpanList_Init(MSpan *list);
 bool   runtime_MSpanList_IsEmpty(MSpan *list);
 void   runtime_MSpanList_Insert(MSpan *list, MSpan *span);
+void   runtime_MSpanList_InsertBack(MSpan *list, MSpan *span);
 void   runtime_MSpanList_Remove(MSpan *span);  // from whatever list it is in
 
 
@@ -390,7 +448,7 @@ struct MCentral
 void   runtime_MCentral_Init(MCentral *c, int32 sizeclass);
 int32  runtime_MCentral_AllocList(MCentral *c, MLink **first);
 void   runtime_MCentral_FreeList(MCentral *c, MLink *first);
-void   runtime_MCentral_FreeSpan(MCentral *c, MSpan *s, int32 n, MLink *start, MLink *end);
+bool   runtime_MCentral_FreeSpan(MCentral *c, MSpan *s, int32 n, MLink *start, MLink *end);
 
 // Main malloc heap.
 // The heap itself is the "free[]" and "large" arrays,
@@ -399,10 +457,15 @@ struct MHeap
 {
        Lock;
        MSpan free[MaxMHeapList];       // free lists of given length
-       MSpan large;                    // free lists length >= MaxMHeapList
-       MSpan **allspans;
+       MSpan freelarge;                // free lists length >= MaxMHeapList
+       MSpan busy[MaxMHeapList];       // busy lists of large objects of given length
+       MSpan busylarge;                // busy lists of large objects length >= MaxMHeapList
+       MSpan **allspans;               // all spans out there
+       MSpan **sweepspans;             // copy of allspans referenced by sweeper
        uint32  nspan;
        uint32  nspancap;
+       uint32  sweepgen;               // sweep generation, see comment in MSpan
+       uint32  sweepdone;              // all spans are swept
 
        // span lookup
        MSpan** spans;
@@ -426,6 +489,9 @@ struct MHeap
 
        FixAlloc spanalloc;     // allocator for Span*
        FixAlloc cachealloc;    // allocator for MCache*
+       FixAlloc specialfinalizeralloc; // allocator for SpecialFinalizer*
+       FixAlloc specialprofilealloc;   // allocator for SpecialProfile*
+       Lock speciallock; // lock for sepcial record allocators.
 
        // Malloc stats.
        uint64 largefree;       // bytes freed for large objects (>MaxSmallSize)
@@ -435,7 +501,7 @@ struct MHeap
 extern MHeap runtime_mheap;
 
 void   runtime_MHeap_Init(MHeap *h);
-MSpan* runtime_MHeap_Alloc(MHeap *h, uintptr npage, int32 sizeclass, int32 acct, int32 zeroed);
+MSpan* runtime_MHeap_Alloc(MHeap *h, uintptr npage, int32 sizeclass, bool large, bool needzero);
 void   runtime_MHeap_Free(MHeap *h, MSpan *s, int32 acct);
 MSpan* runtime_MHeap_Lookup(MHeap *h, void *v);
 MSpan* runtime_MHeap_LookupMaybe(MHeap *h, void *v);
@@ -449,6 +515,7 @@ void*       runtime_mallocgc(uintptr size, uintptr typ, uint32 flag);
 void*  runtime_persistentalloc(uintptr size, uintptr align, uint64 *stat);
 int32  runtime_mlookup(void *v, byte **base, uintptr *size, MSpan **s);
 void   runtime_gc(int32 force);
+uintptr        runtime_sweepone(void);
 void   runtime_markscan(void *v);
 void   runtime_marknogc(void *v);
 void   runtime_checkallocated(void *v, uintptr n);
@@ -457,8 +524,6 @@ void        runtime_checkfreed(void *v, uintptr n);
 extern int32   runtime_checking;
 void   runtime_markspan(void *v, uintptr size, uintptr n, bool leftover);
 void   runtime_unmarkspan(void *v, uintptr size);
-bool   runtime_blockspecial(void*);
-void   runtime_setblockspecial(void*, bool);
 void   runtime_purgecachedstats(MCache*);
 void*  runtime_cnew(const Type*);
 void*  runtime_cnewarray(const Type*, intgo);
@@ -486,17 +551,25 @@ struct Obj
 };
 
 void   runtime_MProf_Malloc(void*, uintptr, uintptr);
-void   runtime_MProf_Free(void*, uintptr);
+void   runtime_MProf_Free(Bucket*, void*, uintptr, bool);
 void   runtime_MProf_GC(void);
-void   runtime_MProf_Mark(void (*addroot)(Obj));
+void   runtime_MProf_TraceGC(void);
+struct Workbuf;
+void   runtime_MProf_Mark(struct Workbuf**, void (*)(struct Workbuf**, Obj));
 int32  runtime_gcprocs(void);
 void   runtime_helpgc(int32 nproc);
 void   runtime_gchelper(void);
 
+void   runtime_setprofilebucket(void *p, Bucket *b);
+
 struct __go_func_type;
 struct __go_ptr_type;
-bool   runtime_getfinalizer(void *p, bool del, FuncVal **fn, const struct __go_func_type **ft, const struct __go_ptr_type **ot);
-void   runtime_walkfintab(void (*fn)(void*), void (*scan)(Obj));
+bool   runtime_addfinalizer(void *p, FuncVal *fn, const struct __go_func_type*, const struct __go_ptr_type*);
+void   runtime_removefinalizer(void*);
+void   runtime_queuefinalizer(void *p, FuncVal *fn, const struct __go_func_type *ft, const struct __go_ptr_type *ot);
+
+void   runtime_freeallspecials(MSpan *span, void *p, uintptr size);
+bool   runtime_freespecial(Special *s, void *p, uintptr size, bool freed);
 
 enum
 {
@@ -514,6 +587,6 @@ void        runtime_gc_itab_ptr(Eface*);
 
 void   runtime_memorydump(void);
 
-void   runtime_proc_scan(void (*)(Obj));
-void   runtime_time_scan(void (*)(Obj));
-void   runtime_netpoll_scan(void (*)(Obj));
+void   runtime_proc_scan(struct Workbuf**, void (*)(struct Workbuf**, Obj));
+void   runtime_time_scan(struct Workbuf**, void (*)(struct Workbuf**, Obj));
+void   runtime_netpoll_scan(struct Workbuf**, void (*)(struct Workbuf**, Obj));
index 81916101e46b11d48ac0b093942e9cead7bbab9d..12853367c961806ff7634daa2af6196e4f3da848 100644 (file)
@@ -39,17 +39,58 @@ runtime_MCentral_AllocList(MCentral *c, MLink **pfirst)
 {
        MSpan *s;
        int32 cap, n;
+       uint32 sg;
 
        runtime_lock(c);
-       // Replenish central list if empty.
-       if(runtime_MSpanList_IsEmpty(&c->nonempty)) {
-               if(!MCentral_Grow(c)) {
+       sg = runtime_mheap.sweepgen;
+retry:
+       for(s = c->nonempty.next; s != &c->nonempty; s = s->next) {
+               if(s->sweepgen == sg-2 && runtime_cas(&s->sweepgen, sg-2, sg-1)) {
                        runtime_unlock(c);
-                       *pfirst = nil;
-                       return 0;
+                       runtime_MSpan_Sweep(s);
+                       runtime_lock(c);
+                       // the span could have been moved to heap, retry
+                       goto retry;
+               }
+               if(s->sweepgen == sg-1) {
+                       // the span is being swept by background sweeper, skip
+                       continue;
+               }
+               // we have a nonempty span that does not require sweeping, allocate from it
+               goto havespan;
+       }
+
+       for(s = c->empty.next; s != &c->empty; s = s->next) {
+               if(s->sweepgen == sg-2 && runtime_cas(&s->sweepgen, sg-2, sg-1)) {
+                       // we have an empty span that requires sweeping,
+                       // sweep it and see if we can free some space in it
+                       runtime_MSpanList_Remove(s);
+                       // swept spans are at the end of the list
+                       runtime_MSpanList_InsertBack(&c->empty, s);
+                       runtime_unlock(c);
+                       runtime_MSpan_Sweep(s);
+                       runtime_lock(c);
+                       // the span could be moved to nonempty or heap, retry
+                       goto retry;
+               }
+               if(s->sweepgen == sg-1) {
+                       // the span is being swept by background sweeper, skip
+                       continue;
                }
+               // already swept empty span,
+               // all subsequent ones must also be either swept or in process of sweeping
+               break;
+       }
+
+       // Replenish central list if empty.
+       if(!MCentral_Grow(c)) {
+               runtime_unlock(c);
+               *pfirst = nil;
+               return 0;
        }
        s = c->nonempty.next;
+
+havespan:
        cap = (s->npages << PageShift) / s->elemsize;
        n = cap - s->ref;
        *pfirst = s->freelist;
@@ -57,7 +98,7 @@ runtime_MCentral_AllocList(MCentral *c, MLink **pfirst)
        s->ref += n;
        c->nfree -= n;
        runtime_MSpanList_Remove(s);
-       runtime_MSpanList_Insert(&c->empty, s);
+       runtime_MSpanList_InsertBack(&c->empty, s);
        runtime_unlock(c);
        return n;
 }
@@ -106,7 +147,7 @@ MCentral_Free(MCentral *c, void *v)
                size = runtime_class_to_size[c->sizeclass];
                runtime_MSpanList_Remove(s);
                runtime_unmarkspan((byte*)(s->start<<PageShift), s->npages<<PageShift);
-               *(uintptr*)(s->start<<PageShift) = 1;  // needs zeroing
+               s->needzero = 1;
                s->freelist = nil;
                c->nfree -= (s->npages << PageShift) / size;
                runtime_unlock(c);
@@ -116,8 +157,9 @@ MCentral_Free(MCentral *c, void *v)
 }
 
 // Free n objects from a span s back into the central free list c.
-// Called from GC.
-void
+// Called during sweep.
+// Returns true if the span was returned to heap.
+bool
 runtime_MCentral_FreeSpan(MCentral *c, MSpan *s, int32 n, MLink *start, MLink *end)
 {
        int32 size;
@@ -136,19 +178,21 @@ runtime_MCentral_FreeSpan(MCentral *c, MSpan *s, int32 n, MLink *start, MLink *e
        s->ref -= n;
        c->nfree += n;
 
-       // If s is completely freed, return it to the heap.
-       if(s->ref == 0) {
-               size = runtime_class_to_size[c->sizeclass];
-               runtime_MSpanList_Remove(s);
-               *(uintptr*)(s->start<<PageShift) = 1;  // needs zeroing
-               s->freelist = nil;
-               c->nfree -= (s->npages << PageShift) / size;
-               runtime_unlock(c);
-               runtime_unmarkspan((byte*)(s->start<<PageShift), s->npages<<PageShift);
-               runtime_MHeap_Free(&runtime_mheap, s, 0);
-       } else {
+       if(s->ref != 0) {
                runtime_unlock(c);
+               return false;
        }
+
+       // s is completely freed, return it to the heap.
+       size = runtime_class_to_size[c->sizeclass];
+       runtime_MSpanList_Remove(s);
+       s->needzero = 1;
+       s->freelist = nil;
+       c->nfree -= (s->npages << PageShift) / size;
+       runtime_unlock(c);
+       runtime_unmarkspan((byte*)(s->start<<PageShift), s->npages<<PageShift);
+       runtime_MHeap_Free(&runtime_mheap, s, 0);
+       return true;
 }
 
 void
diff --git a/libgo/runtime/mfinal.c b/libgo/runtime/mfinal.c
deleted file mode 100644 (file)
index 625af52..0000000
+++ /dev/null
@@ -1,218 +0,0 @@
-// Copyright 2010 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "runtime.h"
-#include "arch.h"
-#include "malloc.h"
-#include "go-type.h"
-
-enum { debug = 0 };
-
-typedef struct Fin Fin;
-struct Fin
-{
-       FuncVal *fn;
-       const struct __go_func_type *ft;
-       const struct __go_ptr_type *ot;
-};
-
-// Finalizer hash table.  Direct hash, linear scan, at most 3/4 full.
-// Table size is power of 3 so that hash can be key % max.
-// Key[i] == (void*)-1 denotes free but formerly occupied entry
-// (doesn't stop the linear scan).
-// Key and val are separate tables because the garbage collector
-// must be instructed to ignore the pointers in key but follow the
-// pointers in val.
-typedef struct Fintab Fintab;
-struct Fintab
-{
-       Lock;
-       void **fkey;
-       Fin *val;
-       int32 nkey;     // number of non-nil entries in key
-       int32 ndead;    // number of dead (-1) entries in key
-       int32 max;      // size of key, val allocations
-};
-
-#define TABSZ 17
-#define TAB(p) (&fintab[((uintptr)(p)>>3)%TABSZ])
-
-static struct {
-       Fintab;
-       uint8 pad[0 /* CacheLineSize - sizeof(Fintab) */];      
-} fintab[TABSZ];
-
-static void
-addfintab(Fintab *t, void *k, FuncVal *fn, const struct __go_func_type *ft, const struct __go_ptr_type *ot)
-{
-       int32 i, j;
-
-       i = (uintptr)k % (uintptr)t->max;
-       for(j=0; j<t->max; j++) {
-               if(t->fkey[i] == nil) {
-                       t->nkey++;
-                       goto ret;
-               }
-               if(t->fkey[i] == (void*)-1) {
-                       t->ndead--;
-                       goto ret;
-               }
-               if(++i == t->max)
-                       i = 0;
-       }
-
-       // cannot happen - table is known to be non-full
-       runtime_throw("finalizer table inconsistent");
-
-ret:
-       t->fkey[i] = k;
-       t->val[i].fn = fn;
-       t->val[i].ft = ft;
-       t->val[i].ot = ot;
-}
-
-static bool
-lookfintab(Fintab *t, void *k, bool del, Fin *f)
-{
-       int32 i, j;
-
-       if(t->max == 0)
-               return false;
-       i = (uintptr)k % (uintptr)t->max;
-       for(j=0; j<t->max; j++) {
-               if(t->fkey[i] == nil)
-                       return false;
-               if(t->fkey[i] == k) {
-                       if(f)
-                               *f = t->val[i];
-                       if(del) {
-                               t->fkey[i] = (void*)-1;
-                               t->val[i].fn = nil;
-                               t->val[i].ft = nil;
-                               t->val[i].ot = nil;
-                               t->ndead++;
-                       }
-                       return true;
-               }
-               if(++i == t->max)
-                       i = 0;
-       }
-
-       // cannot happen - table is known to be non-full
-       runtime_throw("finalizer table inconsistent");
-       return false;
-}
-
-static void
-resizefintab(Fintab *tab)
-{
-       Fintab newtab;
-       void *k;
-       int32 i;
-
-       runtime_memclr((byte*)&newtab, sizeof newtab);
-       newtab.max = tab->max;
-       if(newtab.max == 0)
-               newtab.max = 3*3*3;
-       else if(tab->ndead < tab->nkey/2) {
-               // grow table if not many dead values.
-               // otherwise just rehash into table of same size.
-               newtab.max *= 3;
-       }
-       
-       newtab.fkey = runtime_mallocgc(newtab.max*sizeof newtab.fkey[0], 0, FlagNoInvokeGC|FlagNoScan);
-       newtab.val = runtime_mallocgc(newtab.max*sizeof newtab.val[0], 0, FlagNoInvokeGC);
-       
-       for(i=0; i<tab->max; i++) {
-               k = tab->fkey[i];
-               if(k != nil && k != (void*)-1)
-                       addfintab(&newtab, k, tab->val[i].fn, tab->val[i].ft, tab->val[i].ot);
-       }
-       
-       runtime_free(tab->fkey);
-       runtime_free(tab->val);
-       
-       tab->fkey = newtab.fkey;
-       tab->val = newtab.val;
-       tab->nkey = newtab.nkey;
-       tab->ndead = newtab.ndead;
-       tab->max = newtab.max;
-}
-
-bool
-runtime_addfinalizer(void *p, FuncVal *f, const struct __go_func_type *ft, const struct __go_ptr_type *ot)
-{
-       Fintab *tab;
-       byte *base;
-       
-       if(debug) {
-               if(!runtime_mlookup(p, &base, nil, nil) || p != base)
-                       runtime_throw("addfinalizer on invalid pointer");
-       }
-       
-       tab = TAB(p);
-       runtime_lock(tab);
-       if(f == nil) {
-               lookfintab(tab, p, true, nil);
-               runtime_unlock(tab);
-               return true;
-       }
-
-       if(lookfintab(tab, p, false, nil)) {
-               runtime_unlock(tab);
-               return false;
-       }
-
-       if(tab->nkey >= tab->max/2+tab->max/4) {
-               // keep table at most 3/4 full:
-               // allocate new table and rehash.
-               resizefintab(tab);
-       }
-
-       addfintab(tab, p, f, ft, ot);
-       runtime_setblockspecial(p, true);
-       runtime_unlock(tab);
-       return true;
-}
-
-// get finalizer; if del, delete finalizer.
-// caller is responsible for updating RefHasFinalizer (special) bit.
-bool
-runtime_getfinalizer(void *p, bool del, FuncVal **fn, const struct __go_func_type **ft, const struct __go_ptr_type **ot)
-{
-       Fintab *tab;
-       bool res;
-       Fin f;
-       
-       tab = TAB(p);
-       runtime_lock(tab);
-       res = lookfintab(tab, p, del, &f);
-       runtime_unlock(tab);
-       if(res==false)
-               return false;
-       *fn = f.fn;
-       *ft = f.ft;
-       *ot = f.ot;
-       return true;
-}
-
-void
-runtime_walkfintab(void (*fn)(void*), void (*addroot)(Obj))
-{
-       void **key;
-       void **ekey;
-       int32 i;
-
-       for(i=0; i<TABSZ; i++) {
-               runtime_lock(&fintab[i]);
-               key = fintab[i].fkey;
-               ekey = key + fintab[i].max;
-               for(; key < ekey; key++)
-                       if(*key != nil && *key != ((void*)-1))
-                               fn(*key);
-               addroot((Obj){(byte*)&fintab[i].fkey, sizeof(void*), 0});
-               addroot((Obj){(byte*)&fintab[i].val, sizeof(void*), 0});
-               runtime_unlock(&fintab[i]);
-       }
-}
index d665d92664288f40a1b0dc331229b274c68abdfa..10dd412eea6d94a4de4c2c211427aefeafaabf91 100644 (file)
@@ -2,7 +2,53 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Garbage collector.
+// Garbage collector (GC).
+//
+// GC is:
+// - mark&sweep
+// - mostly precise (with the exception of some C-allocated objects, assembly frames/arguments, etc)
+// - parallel (up to MaxGcproc threads)
+// - partially concurrent (mark is stop-the-world, while sweep is concurrent)
+// - non-moving/non-compacting
+// - full (non-partial)
+//
+// GC rate.
+// Next GC is after we've allocated an extra amount of memory proportional to
+// the amount already in use. The proportion is controlled by GOGC environment variable
+// (100 by default). If GOGC=100 and we're using 4M, we'll GC again when we get to 8M
+// (this mark is tracked in next_gc variable). This keeps the GC cost in linear
+// proportion to the allocation cost. Adjusting GOGC just changes the linear constant
+// (and also the amount of extra memory used).
+//
+// Concurrent sweep.
+// The sweep phase proceeds concurrently with normal program execution.
+// The heap is swept span-by-span both lazily (when a goroutine needs another span)
+// and concurrently in a background goroutine (this helps programs that are not CPU bound).
+// However, at the end of the stop-the-world GC phase we don't know the size of the live heap,
+// and so next_gc calculation is tricky and happens as follows.
+// At the end of the stop-the-world phase next_gc is conservatively set based on total
+// heap size; all spans are marked as "needs sweeping".
+// Whenever a span is swept, next_gc is decremented by GOGC*newly_freed_memory.
+// The background sweeper goroutine simply sweeps spans one-by-one bringing next_gc
+// closer to the target value. However, this is not enough to avoid over-allocating memory.
+// Consider that a goroutine wants to allocate a new span for a large object and
+// there are no free swept spans, but there are small-object unswept spans.
+// If the goroutine naively allocates a new span, it can surpass the yet-unknown
+// target next_gc value. In order to prevent such cases (1) when a goroutine needs
+// to allocate a new small-object span, it sweeps small-object spans for the same
+// object size until it frees at least one object; (2) when a goroutine needs to
+// allocate large-object span from heap, it sweeps spans until it frees at least
+// that many pages into heap. Together these two measures ensure that we don't surpass
+// target next_gc value by a large margin. There is an exception: if a goroutine sweeps
+// and frees two nonadjacent one-page spans to the heap, it will allocate a new two-page span,
+// but there can still be other one-page unswept spans which could be combined into a two-page span.
+// It's critical to ensure that no operations proceed on unswept spans (that would corrupt
+// mark bits in GC bitmap). During GC all mcaches are flushed into the central cache,
+// so they are empty. When a goroutine grabs a new span into mcache, it sweeps it.
+// When a goroutine explicitly frees an object or sets a finalizer, it ensures that
+// the span is swept (either by sweeping it, or by waiting for the concurrent sweep to finish).
+// The finalizer goroutine is kicked off only when all spans are swept.
+// When the next GC starts, it sweeps all not-yet-swept spans (if any).
 
 #include <unistd.h>
 
 #define cap __capacity
 // Iface aka __go_interface
 #define tab __methods
-// Eface aka __go_empty_interface.
-#define type __type_descriptor
 // Hmap aka __go_map
 typedef struct __go_map Hmap;
 // Type aka __go_type_descriptor
-#define kind __code
 #define string __reflection
 #define KindPtr GO_PTR
 #define KindNoPointers GO_NO_POINTERS
@@ -43,15 +86,19 @@ extern void * __splitstack_find_context (void *context[10], size_t *, void **,
 
 enum {
        Debug = 0,
-       DebugMark = 0,  // run second pass to check mark
        CollectStats = 0,
        ScanStackByFrames = 1,
        IgnorePreciseGC = 0,
+       ConcurrentSweep = 1,
 
        // Four bits per word (see #defines below).
        wordsPerBitmapWord = sizeof(void*)*8/4,
        bitShift = sizeof(void*)*8/4,
 
+       WorkbufSize     = 16*1024,
+       RootBlockSize   = 4*1024,
+       FinBlockSize    = 4*1024,
+
        handoffThreshold = 4,
        IntermediateBufferCapacity = 64,
 
@@ -66,8 +113,20 @@ enum {
        BitsPointer = 1,
        BitsIface = 2,
        BitsEface = 3,
+
+       RootData        = 0,
+       RootBss         = 1,
+       RootFinalizers  = 2,
+       RootSpanTypes   = 3,
+       RootFlushCaches = 4,
+       RootCount       = 5,
 };
 
+#define GcpercentUnknown (-2)
+
+// Initialized from $GOGC.  GOGC=off means no gc.
+static int32 gcpercent = GcpercentUnknown;
+
 static struct
 {
        Lock;  
@@ -89,16 +148,34 @@ sync_runtime_registerPool(void **p)
 static void
 clearpools(void)
 {
-       void **p, **next;
-
-       for(p = pools.head; p != nil; p = next) {
-               next = p[0];
-               p[0] = nil; // next
-               p[1] = nil; // slice
-               p[2] = nil;
-               p[3] = nil;
+       void **pool, **next;
+       P *p, **pp;
+       MCache *c;
+       uintptr off;
+
+       // clear sync.Pool's
+       for(pool = pools.head; pool != nil; pool = next) {
+               next = pool[0];
+               pool[0] = nil; // next
+               pool[1] = nil; // local
+               pool[2] = nil; // localSize
+               off = (uintptr)pool[3] / sizeof(void*);
+               pool[off+0] = nil; // global slice
+               pool[off+1] = nil;
+               pool[off+2] = nil;
        }
        pools.head = nil;
+
+       for(pp=runtime_allp; (p=*pp) != nil; pp++) {
+               // clear tinyalloc pool
+               c = p->mcache;
+               if(c != nil) {
+                       c->tiny = nil;
+                       c->tinysize = 0;
+               }
+               // clear defer pools
+               p->deferpool = nil;
+       }
 }
 
 // Bits in per-word bitmap.
@@ -149,11 +226,10 @@ clearpools(void)
 //
 uint32 runtime_worldsema = 1;
 
-// The size of Workbuf is N*PageSize.
 typedef struct Workbuf Workbuf;
 struct Workbuf
 {
-#define SIZE (2*PageSize-sizeof(LFNode)-sizeof(uintptr))
+#define SIZE (WorkbufSize-sizeof(LFNode)-sizeof(uintptr))
        LFNode  node; // must be first
        uintptr nobj;
        Obj     obj[SIZE/sizeof(Obj) - 1];
@@ -180,45 +256,42 @@ struct FinBlock
        Finalizer fin[1];
 };
 
-static G *fing;
-static FinBlock *finq; // list of finalizers that are to be executed
-static FinBlock *finc; // cache of free blocks
-static FinBlock *allfin; // list of all blocks
-static Lock finlock;
-static int32 fingwait;
+static G       *fing;
+static FinBlock        *finq; // list of finalizers that are to be executed
+static FinBlock        *finc; // cache of free blocks
+static FinBlock        *allfin; // list of all blocks
+static int32   fingwait;
+static Lock    gclock;
 
-static void runfinq(void*);
+static void    runfinq(void*);
+static void    bgsweep(void*);
 static Workbuf* getempty(Workbuf*);
 static Workbuf* getfull(Workbuf*);
 static void    putempty(Workbuf*);
 static Workbuf* handoff(Workbuf*);
 static void    gchelperstart(void);
+static void    flushallmcaches(void);
+static void    addstackroots(G *gp, Workbuf **wbufp);
 
 static struct {
        uint64  full;  // lock-free list of full blocks
        uint64  empty; // lock-free list of empty blocks
        byte    pad0[CacheLineSize]; // prevents false-sharing between full/empty and nproc/nwait
        uint32  nproc;
+       int64   tstart;
        volatile uint32 nwait;
        volatile uint32 ndone;
-       volatile uint32 debugmarkdone;
        Note    alldone;
        ParFor  *markfor;
-       ParFor  *sweepfor;
 
        Lock;
        byte    *chunk;
        uintptr nchunk;
-
-       Obj     *roots;
-       uint32  nroot;
-       uint32  rootcap;
 } work __attribute__((aligned(8)));
 
 enum {
        GC_DEFAULT_PTR = GC_NUM_INSTR,
        GC_CHAN,
-       GC_G_PTR,
 
        GC_NUM_INSTR2
 };
@@ -250,6 +323,8 @@ static struct {
                uint64 foundword;
                uint64 foundspan;
        } markonly;
+       uint32 nbgsweep;
+       uint32 npausesweep;
 } gcstats;
 
 // markonly marks an object. It returns true if the object
@@ -638,11 +713,6 @@ static uintptr defaultProg[2] = {PtrSize, GC_DEFAULT_PTR};
 static uintptr chanProg[2] = {0, GC_CHAN};
 #endif
 
-#if 0
-// G* program
-static uintptr gptrProg[2] = {0, GC_G_PTR};
-#endif
-
 // Local variables of a program fragment or loop
 typedef struct Frame Frame;
 struct Frame {
@@ -713,15 +783,11 @@ checkptr(void *obj, uintptr objti)
 // a work list in the Workbuf* structures and loops in the main function
 // body.  Keeping an explicit work list is easier on the stack allocator and
 // more efficient.
-//
-// wbuf: current work buffer
-// wp:   storage for next queued pointer (write pointer)
-// nobj: number of queued objects
 static void
-scanblock(Workbuf *wbuf, Obj *wp, uintptr nobj, bool keepworking)
+scanblock(Workbuf *wbuf, bool keepworking)
 {
        byte *b, *arena_start, *arena_used;
-       uintptr n, i, end_b, elemsize, size, ti, objti, count /* , type */;
+       uintptr n, i, end_b, elemsize, size, ti, objti, count, /* type, */ nobj;
        uintptr *pc, precise_type, nominal_size;
 #if 0
        uintptr *chan_ret, chancap;
@@ -738,8 +804,9 @@ scanblock(Workbuf *wbuf, Obj *wp, uintptr nobj, bool keepworking)
        Hchan *chan;
        ChanType *chantype;
 #endif
+       Obj *wp;
 
-       if(sizeof(Workbuf) % PageSize != 0)
+       if(sizeof(Workbuf) % WorkbufSize != 0)
                runtime_throw("scanblock: size of Workbuf is suboptimal");
 
        // Memory arena parameters.
@@ -751,6 +818,14 @@ scanblock(Workbuf *wbuf, Obj *wp, uintptr nobj, bool keepworking)
        precise_type = false;
        nominal_size = 0;
 
+       if(wbuf) {
+               nobj = wbuf->nobj;
+               wp = &wbuf->obj[nobj];
+       } else {
+               nobj = 0;
+               wp = nil;
+       }
+
        // Initialize sbuf
        scanbuffers = &bufferList[runtime_m()->helpgc];
 
@@ -904,11 +979,11 @@ scanblock(Workbuf *wbuf, Obj *wp, uintptr nobj, bool keepworking)
                case GC_EFACE:
                        eface = (Eface*)(stack_top.b + pc[1]);
                        pc += 2;
-                       if(eface->type == nil)
+                       if(eface->__type_descriptor == nil)
                                continue;
 
                        // eface->type
-                       t = eface->type;
+                       t = eface->__type_descriptor;
                        if((const byte*)t >= arena_start && (const byte*)t < arena_used) {
                                union { const Type *tc; Type *tr; } u;
                                u.tc = t;
@@ -920,11 +995,11 @@ scanblock(Workbuf *wbuf, Obj *wp, uintptr nobj, bool keepworking)
                        // eface->__object
                        if((byte*)eface->__object >= arena_start && (byte*)eface->__object < arena_used) {
                                if(t->__size <= sizeof(void*)) {
-                                       if((t->kind & KindNoPointers))
+                                       if((t->__code & KindNoPointers))
                                                continue;
 
                                        obj = eface->__object;
-                                       if((t->kind & ~KindNoPointers) == KindPtr)
+                                       if((t->__code & ~KindNoPointers) == KindPtr)
                                                // objti = (uintptr)((PtrType*)t)->elem->gc;
                                                objti = 0;
                                } else {
@@ -953,11 +1028,11 @@ scanblock(Workbuf *wbuf, Obj *wp, uintptr nobj, bool keepworking)
                                // t = iface->tab->type;
                                t = nil;
                                if(t->__size <= sizeof(void*)) {
-                                       if((t->kind & KindNoPointers))
+                                       if((t->__code & KindNoPointers))
                                                continue;
 
                                        obj = iface->__object;
-                                       if((t->kind & ~KindNoPointers) == KindPtr)
+                                       if((t->__code & ~KindNoPointers) == KindPtr)
                                                // objti = (uintptr)((const PtrType*)t)->elem->gc;
                                                objti = 0;
                                } else {
@@ -1064,7 +1139,7 @@ scanblock(Workbuf *wbuf, Obj *wp, uintptr nobj, bool keepworking)
                        }
                        if(markonly(chan)) {
                                chantype = (ChanType*)pc[2];
-                               if(!(chantype->elem->kind & KindNoPointers)) {
+                               if(!(chantype->elem->__code & KindNoPointers)) {
                                        // Start chanProg.
                                        chan_ret = pc+3;
                                        pc = chanProg+1;
@@ -1077,7 +1152,7 @@ scanblock(Workbuf *wbuf, Obj *wp, uintptr nobj, bool keepworking)
                case GC_CHAN:
                        // There are no heap pointers in struct Hchan,
                        // so we can ignore the leading sizeof(Hchan) bytes.
-                       if(!(chantype->elem->kind & KindNoPointers)) {
+                       if(!(chantype->elem->__code & KindNoPointers)) {
                                // Channel's buffer follows Hchan immediately in memory.
                                // Size of buffer (cap(c)) is second int in the chan struct.
                                chancap = ((uintgo*)chan)[1];
@@ -1098,13 +1173,6 @@ scanblock(Workbuf *wbuf, Obj *wp, uintptr nobj, bool keepworking)
                        continue;
 #endif
 
-#if 0
-               case GC_G_PTR:
-                       obj = (void*)stack_top.b;
-                       scanstack(obj, &sbuf);
-                       goto next_block;
-#endif
-
                default:
                        runtime_throw("scanblock: invalid GC instruction");
                        return;
@@ -1149,80 +1217,15 @@ scanblock(Workbuf *wbuf, Obj *wp, uintptr nobj, bool keepworking)
        }
 }
 
-// debug_scanblock is the debug copy of scanblock.
-// it is simpler, slower, single-threaded, recursive,
-// and uses bitSpecial as the mark bit.
-static void
-debug_scanblock(byte *b, uintptr n)
-{
-       byte *obj, *p;
-       void **vp;
-       uintptr size, *bitp, bits, shift, i, xbits, off;
-       MSpan *s;
-
-       if(!DebugMark)
-               runtime_throw("debug_scanblock without DebugMark");
-
-       if((intptr)n < 0) {
-               runtime_printf("debug_scanblock %p %D\n", b, (int64)n);
-               runtime_throw("debug_scanblock");
-       }
-
-       // Align b to a word boundary.
-       off = (uintptr)b & (PtrSize-1);
-       if(off != 0) {
-               b += PtrSize - off;
-               n -= PtrSize - off;
-       }
-
-       vp = (void**)b;
-       n /= PtrSize;
-       for(i=0; i<(uintptr)n; i++) {
-               obj = (byte*)vp[i];
-
-               // Words outside the arena cannot be pointers.
-               if((byte*)obj < runtime_mheap.arena_start || (byte*)obj >= runtime_mheap.arena_used)
-                       continue;
-
-               // Round down to word boundary.
-               obj = (void*)((uintptr)obj & ~((uintptr)PtrSize-1));
-
-               // Consult span table to find beginning.
-               s = runtime_MHeap_LookupMaybe(&runtime_mheap, obj);
-               if(s == nil)
-                       continue;
-
-               p =  (byte*)((uintptr)s->start<<PageShift);
-               size = s->elemsize;
-               if(s->sizeclass == 0) {
-                       obj = p;
-               } else {
-                       int32 i = ((byte*)obj - p)/size;
-                       obj = p+i*size;
-               }
-
-               // Now that we know the object header, reload bits.
-               off = (uintptr*)obj - (uintptr*)runtime_mheap.arena_start;
-               bitp = (uintptr*)runtime_mheap.arena_start - off/wordsPerBitmapWord - 1;
-               shift = off % wordsPerBitmapWord;
-               xbits = *bitp;
-               bits = xbits >> shift;
-
-               // Now we have bits, bitp, and shift correct for
-               // obj pointing at the base of the object.
-               // If not allocated or already marked, done.
-               if((bits & bitAllocated) == 0 || (bits & bitSpecial) != 0)  // NOTE: bitSpecial not bitMarked
-                       continue;
-               *bitp |= bitSpecial<<shift;
-               if(!(bits & bitMarked))
-                       runtime_printf("found unmarked block %p in %p\n", obj, vp+i);
-
-               // If object has no pointers, don't need to scan further.
-               if((bits & bitScan) == 0)
-                       continue;
+static struct root_list* roots;
 
-               debug_scanblock(obj, size);
-       }
+void
+__go_register_gc_roots (struct root_list* r)
+{
+       // FIXME: This needs locking if multiple goroutines can call
+       // dlopen simultaneously.
+       r->next = roots;
+       roots = r;
 }
 
 // Append obj to the work buffer.
@@ -1280,19 +1283,126 @@ enqueue(Obj obj, Workbuf **_wbuf, Obj **_wp, uintptr *_nobj)
        *_nobj = nobj;
 }
 
+static void
+enqueue1(Workbuf **wbufp, Obj obj)
+{
+       Workbuf *wbuf;
+
+       wbuf = *wbufp;
+       if(wbuf->nobj >= nelem(wbuf->obj))
+               *wbufp = wbuf = getempty(wbuf);
+       wbuf->obj[wbuf->nobj++] = obj;
+}
+
 static void
 markroot(ParFor *desc, uint32 i)
 {
-       Obj *wp;
        Workbuf *wbuf;
-       uintptr nobj;
+       FinBlock *fb;
+       MHeap *h;
+       MSpan **allspans, *s;
+       uint32 spanidx, sg;
+       G *gp;
+       void *p;
 
        USED(&desc);
-       wp = nil;
-       wbuf = nil;
-       nobj = 0;
-       enqueue(work.roots[i], &wbuf, &wp, &nobj);
-       scanblock(wbuf, wp, nobj, false);
+       wbuf = getempty(nil);
+       switch(i) {
+       case RootData:
+               // For gccgo this is both data and bss.
+               {
+                       struct root_list *pl;
+
+                       for(pl = roots; pl != nil; pl = pl->next) {
+                               struct root *pr = &pl->roots[0];
+                               while(1) {
+                                       void *decl = pr->decl;
+                                       if(decl == nil)
+                                               break;
+                                       enqueue1(&wbuf, (Obj){decl, pr->size, 0});
+                                       pr++;
+                               }
+                       }
+               }
+               break;
+
+       case RootBss:
+               // For gccgo we use this for all the other global roots.
+               enqueue1(&wbuf, (Obj){(byte*)&runtime_m0, sizeof runtime_m0, 0});
+               enqueue1(&wbuf, (Obj){(byte*)&runtime_g0, sizeof runtime_g0, 0});
+               enqueue1(&wbuf, (Obj){(byte*)&runtime_allg, sizeof runtime_allg, 0});
+               enqueue1(&wbuf, (Obj){(byte*)&runtime_allm, sizeof runtime_allm, 0});
+               enqueue1(&wbuf, (Obj){(byte*)&runtime_allp, sizeof runtime_allp, 0});
+               enqueue1(&wbuf, (Obj){(byte*)&work, sizeof work, 0});
+               runtime_proc_scan(&wbuf, enqueue1);
+               runtime_MProf_Mark(&wbuf, enqueue1);
+               runtime_time_scan(&wbuf, enqueue1);
+               runtime_netpoll_scan(&wbuf, enqueue1);
+               break;
+
+       case RootFinalizers:
+               for(fb=allfin; fb; fb=fb->alllink)
+                       enqueue1(&wbuf, (Obj){(byte*)fb->fin, fb->cnt*sizeof(fb->fin[0]), 0});
+               break;
+
+       case RootSpanTypes:
+               // mark span types and MSpan.specials (to walk spans only once)
+               h = &runtime_mheap;
+               sg = h->sweepgen;
+               allspans = h->allspans;
+               for(spanidx=0; spanidx<runtime_mheap.nspan; spanidx++) {
+                       Special *sp;
+                       SpecialFinalizer *spf;
+
+                       s = allspans[spanidx];
+                       if(s->sweepgen != sg) {
+                               runtime_printf("sweep %d %d\n", s->sweepgen, sg);
+                               runtime_throw("gc: unswept span");
+                       }
+                       if(s->state != MSpanInUse)
+                               continue;
+                       // The garbage collector ignores type pointers stored in MSpan.types:
+                       //  - Compiler-generated types are stored outside of heap.
+                       //  - The reflect package has runtime-generated types cached in its data structures.
+                       //    The garbage collector relies on finding the references via that cache.
+                       if(s->types.compression == MTypes_Words || s->types.compression == MTypes_Bytes)
+                               markonly((byte*)s->types.data);
+                       for(sp = s->specials; sp != nil; sp = sp->next) {
+                               if(sp->kind != KindSpecialFinalizer)
+                                       continue;
+                               // don't mark finalized object, but scan it so we
+                               // retain everything it points to.
+                               spf = (SpecialFinalizer*)sp;
+                               // A finalizer can be set for an inner byte of an object, find object beginning.
+                               p = (void*)((s->start << PageShift) + spf->offset/s->elemsize*s->elemsize);
+                               enqueue1(&wbuf, (Obj){p, s->elemsize, 0});
+                               enqueue1(&wbuf, (Obj){(void*)&spf->fn, PtrSize, 0});
+                               enqueue1(&wbuf, (Obj){(void*)&spf->ft, PtrSize, 0});
+                               enqueue1(&wbuf, (Obj){(void*)&spf->ot, PtrSize, 0});
+                       }
+               }
+               break;
+
+       case RootFlushCaches:
+               flushallmcaches();
+               break;
+
+       default:
+               // the rest is scanning goroutine stacks
+               if(i - RootCount >= runtime_allglen)
+                       runtime_throw("markroot: bad index");
+               gp = runtime_allg[i - RootCount];
+               // remember when we've first observed the G blocked
+               // needed only to output in traceback
+               if((gp->status == Gwaiting || gp->status == Gsyscall) && gp->waitsince == 0)
+                       gp->waitsince = work.tstart;
+               addstackroots(gp, &wbuf);
+               break;
+               
+       }
+
+       if(wbuf)
+               scanblock(wbuf, false);
 }
 
 // Get an empty work buffer off the work.empty list,
@@ -1395,32 +1505,22 @@ handoff(Workbuf *b)
 }
 
 static void
-addroot(Obj obj)
+addstackroots(G *gp, Workbuf **wbufp)
 {
-       uint32 cap;
-       Obj *new;
-
-       if(work.nroot >= work.rootcap) {
-               cap = PageSize/sizeof(Obj);
-               if(cap < 2*work.rootcap)
-                       cap = 2*work.rootcap;
-               new = (Obj*)runtime_SysAlloc(cap*sizeof(Obj), &mstats.gc_sys);
-               if(new == nil)
-                       runtime_throw("runtime: cannot allocate memory");
-               if(work.roots != nil) {
-                       runtime_memmove(new, work.roots, work.rootcap*sizeof(Obj));
-                       runtime_SysFree(work.roots, work.rootcap*sizeof(Obj), &mstats.gc_sys);
-               }
-               work.roots = new;
-               work.rootcap = cap;
+       switch(gp->status){
+       default:
+               runtime_printf("unexpected G.status %d (goroutine %p %D)\n", gp->status, gp, gp->goid);
+               runtime_throw("mark - bad status");
+       case Gdead:
+               return;
+       case Grunning:
+               runtime_throw("mark - world not stopped");
+       case Grunnable:
+       case Gsyscall:
+       case Gwaiting:
+               break;
        }
-       work.roots[work.nroot] = obj;
-       work.nroot++;
-}
 
-static void
-addstackroots(G *gp)
-{
 #ifdef USING_SPLIT_STACK
        M *mp;
        void* sp;
@@ -1458,11 +1558,11 @@ addstackroots(G *gp)
                }
        }
        if(sp != nil) {
-               addroot((Obj){sp, spsize, 0});
+               enqueue1(wbufp, (Obj){sp, spsize, 0});
                while((sp = __splitstack_find(next_segment, next_sp,
                                              &spsize, &next_segment,
                                              &next_sp, &initial_sp)) != nil)
-                       addroot((Obj){sp, spsize, 0});
+                       enqueue1(wbufp, (Obj){sp, spsize, 0});
        }
 #else
        M *mp;
@@ -1484,159 +1584,23 @@ addstackroots(G *gp)
        }
        top = (byte*)gp->gcinitial_sp + gp->gcstack_size;
        if(top > bottom)
-               addroot((Obj){bottom, top - bottom, 0});
+               enqueue1(wbufp, (Obj){bottom, top - bottom, 0});
        else
-               addroot((Obj){top, bottom - top, 0});
+               enqueue1(wbufp, (Obj){top, bottom - top, 0});
 #endif
 }
 
-static void
-addfinroots(void *v)
-{
-       uintptr size;
-       void *base;
-
-       size = 0;
-       if(!runtime_mlookup(v, (byte**)&base, &size, nil) || !runtime_blockspecial(base))
-               runtime_throw("mark - finalizer inconsistency");
-
-       // do not mark the finalizer block itself.  just mark the things it points at.
-       addroot((Obj){base, size, 0});
-}
-
-static struct root_list* roots;
-
 void
-__go_register_gc_roots (struct root_list* r)
-{
-       // FIXME: This needs locking if multiple goroutines can call
-       // dlopen simultaneously.
-       r->next = roots;
-       roots = r;
-}
-
-static void
-addroots(void)
-{
-       struct root_list *pl;
-       G *gp;
-       FinBlock *fb;
-       MSpan *s, **allspans;
-       uint32 spanidx;
-
-       work.nroot = 0;
-
-       // mark data+bss.
-       for(pl = roots; pl != nil; pl = pl->next) {
-               struct root* pr = &pl->roots[0];
-               while(1) {
-                       void *decl = pr->decl;
-                       if(decl == nil)
-                               break;
-                       addroot((Obj){decl, pr->size, 0});
-                       pr++;
-               }
-       }
-
-       addroot((Obj){(byte*)&runtime_m0, sizeof runtime_m0, 0});
-       addroot((Obj){(byte*)&runtime_g0, sizeof runtime_g0, 0});
-       addroot((Obj){(byte*)&runtime_allg, sizeof runtime_allg, 0});
-       addroot((Obj){(byte*)&runtime_allm, sizeof runtime_allm, 0});
-       addroot((Obj){(byte*)&runtime_allp, sizeof runtime_allp, 0});
-       runtime_proc_scan(addroot);
-       runtime_MProf_Mark(addroot);
-       runtime_time_scan(addroot);
-       runtime_netpoll_scan(addroot);
-
-       // MSpan.types
-       allspans = runtime_mheap.allspans;
-       for(spanidx=0; spanidx<runtime_mheap.nspan; spanidx++) {
-               s = allspans[spanidx];
-               if(s->state == MSpanInUse) {
-                       // The garbage collector ignores type pointers stored in MSpan.types:
-                       //  - Compiler-generated types are stored outside of heap.
-                       //  - The reflect package has runtime-generated types cached in its data structures.
-                       //    The garbage collector relies on finding the references via that cache.
-                       switch(s->types.compression) {
-                       case MTypes_Empty:
-                       case MTypes_Single:
-                               break;
-                       case MTypes_Words:
-                       case MTypes_Bytes:
-                               markonly((byte*)s->types.data);
-                               break;
-                       }
-               }
-       }
-
-       // stacks
-       for(gp=runtime_allg; gp!=nil; gp=gp->alllink) {
-               switch(gp->status){
-               default:
-                       runtime_printf("unexpected G.status %d\n", gp->status);
-                       runtime_throw("mark - bad status");
-               case Gdead:
-                       break;
-               case Grunning:
-                       runtime_throw("mark - world not stopped");
-               case Grunnable:
-               case Gsyscall:
-               case Gwaiting:
-                       addstackroots(gp);
-                       break;
-               }
-       }
-
-       runtime_walkfintab(addfinroots, addroot);
-
-       for(fb=allfin; fb; fb=fb->alllink)
-               addroot((Obj){(byte*)fb->fin, fb->cnt*sizeof(fb->fin[0]), 0});
-
-       addroot((Obj){(byte*)&work, sizeof work, 0});
-}
-
-static void
-addfreelists(void)
-{
-       int32 i;
-       P *p, **pp;
-       MCache *c;
-       MLink *m;
-
-       // Mark objects in the MCache of each P so we don't collect them.
-       for(pp=runtime_allp; (p=*pp); pp++) {
-               c = p->mcache;
-               if(c==nil)
-                       continue;
-               for(i = 0; i < NumSizeClasses; i++) {
-                       for(m = c->list[i].list; m != nil; m = m->next) {
-                               markonly(m);
-                       }
-               }
-       }
-       // Note: the sweeper will mark objects in each span's freelist.
-}
-
-static bool
-handlespecial(byte *p, uintptr size)
+runtime_queuefinalizer(void *p, FuncVal *fn, const FuncType *ft, const PtrType *ot)
 {
-       FuncVal *fn;
-       const struct __go_func_type *ft;
-       const struct __go_ptr_type *ot;
        FinBlock *block;
        Finalizer *f;
-       
-       if(!runtime_getfinalizer(p, true, &fn, &ft, &ot)) {
-               runtime_setblockspecial(p, false);
-               runtime_MProf_Free(p, size);
-               return false;
-       }
 
-       runtime_lock(&finlock);
+       runtime_lock(&gclock);
        if(finq == nil || finq->cnt == finq->cap) {
                if(finc == nil) {
-                       finc = runtime_persistentalloc(PageSize, 0, &mstats.gc_sys);
-                       finc->cap = (PageSize - sizeof(FinBlock)) / sizeof(Finalizer) + 1;
+                       finc = runtime_persistentalloc(FinBlockSize, 0, &mstats.gc_sys);
+                       finc->cap = (FinBlockSize - sizeof(FinBlock)) / sizeof(Finalizer) + 1;
                        finc->alllink = allfin;
                        allfin = finc;
                }
@@ -1651,37 +1615,64 @@ handlespecial(byte *p, uintptr size)
        f->ft = ft;
        f->ot = ot;
        f->arg = p;
-       runtime_unlock(&finlock);
-       return true;
+       runtime_unlock(&gclock);
+}
+
+void
+runtime_MSpan_EnsureSwept(MSpan *s)
+{
+       M *m = runtime_m();
+       uint32 sg;
+
+       sg = runtime_mheap.sweepgen;
+       if(runtime_atomicload(&s->sweepgen) == sg)
+               return;
+       m->locks++;
+       if(runtime_cas(&s->sweepgen, sg-2, sg-1)) {
+               runtime_MSpan_Sweep(s);
+               m->locks--;
+               return;
+       }
+       m->locks--;
+       // unfortunate condition, and we don't have efficient means to wait
+       while(runtime_atomicload(&s->sweepgen) != sg)
+               runtime_osyield();  
 }
 
 // Sweep frees or collects finalizers for blocks not marked in the mark phase.
 // It clears the mark bits in preparation for the next GC round.
-static void
-sweepspan(ParFor *desc, uint32 idx)
+// Returns true if the span was returned to heap.
+bool
+runtime_MSpan_Sweep(MSpan *s)
 {
        M *m;
-       int32 cl, n, npages;
-       uintptr size, off, *bitp, shift;
+       int32 cl, n, npages, nfree;
+       uintptr size, off, *bitp, shift, bits;
+       uint32 sweepgen;
        byte *p;
        MCache *c;
        byte *arena_start;
        MLink head, *end;
-       int32 nfree;
        byte *type_data;
        byte compression;
        uintptr type_data_inc;
-       MSpan *s;
        MLink *x;
+       Special *special, **specialp, *y;
+       bool res, sweepgenset;
 
        m = runtime_m();
 
-       USED(&desc);
-       s = runtime_mheap.allspans[idx];
-       if(s->state != MSpanInUse)
-               return;
+       // It's critical that we enter this function with preemption disabled,
+       // GC must not start while we are in the middle of this function.
+       if(m->locks == 0 && m->mallocing == 0 && runtime_g() != m->g0)
+               runtime_throw("MSpan_Sweep: m is not locked");
+       sweepgen = runtime_mheap.sweepgen;
+       if(s->state != MSpanInUse || s->sweepgen != sweepgen-1) {
+               runtime_printf("MSpan_Sweep: state=%d sweepgen=%d mheap.sweepgen=%d\n",
+                       s->state, s->sweepgen, sweepgen);
+               runtime_throw("MSpan_Sweep: bad span state");
+       }
        arena_start = runtime_mheap.arena_start;
-       p = (byte*)(s->start << PageShift);
        cl = s->sizeclass;
        size = s->elemsize;
        if(cl == 0) {
@@ -1691,9 +1682,11 @@ sweepspan(ParFor *desc, uint32 idx)
                npages = runtime_class_to_allocnpages[cl];
                n = (npages << PageShift) / size;
        }
+       res = false;
        nfree = 0;
        end = &head;
        c = m->mcache;
+       sweepgenset = false;
 
        // mark any free objects in this span so we don't collect them
        for(x = s->freelist; x != nil; x = x->next) {
@@ -1706,6 +1699,35 @@ sweepspan(ParFor *desc, uint32 idx)
                *bitp |= bitMarked<<shift;
        }
        
+       // Unlink & free special records for any objects we're about to free.
+       specialp = &s->specials;
+       special = *specialp;
+       while(special != nil) {
+               // A finalizer can be set for an inner byte of an object, find object beginning.
+               p = (byte*)(s->start << PageShift) + special->offset/size*size;
+               off = (uintptr*)p - (uintptr*)arena_start;
+               bitp = (uintptr*)arena_start - off/wordsPerBitmapWord - 1;
+               shift = off % wordsPerBitmapWord;
+               bits = *bitp>>shift;
+               if((bits & (bitAllocated|bitMarked)) == bitAllocated) {
+                       // Find the exact byte for which the special was setup
+                       // (as opposed to object beginning).
+                       p = (byte*)(s->start << PageShift) + special->offset;
+                       // about to free object: splice out special record
+                       y = special;
+                       special = special->next;
+                       *specialp = special;
+                       if(!runtime_freespecial(y, p, size, false)) {
+                               // stop freeing of object if it has a finalizer
+                               *bitp |= bitMarked << shift;
+                       }
+               } else {
+                       // object is still live: keep special record
+                       specialp = &special->next;
+                       special = *specialp;
+               }
+       }
+
        type_data = (byte*)s->types.data;
        type_data_inc = sizeof(uintptr);
        compression = s->types.compression;
@@ -1719,9 +1741,8 @@ sweepspan(ParFor *desc, uint32 idx)
        // Sweep through n objects of given size starting at p.
        // This thread owns the span now, so it can manipulate
        // the block bitmap without atomic operations.
+       p = (byte*)(s->start << PageShift);
        for(; n > 0; n--, p += size, type_data+=type_data_inc) {
-               uintptr off, *bitp, shift, bits;
-
                off = (uintptr*)p - (uintptr*)arena_start;
                bitp = (uintptr*)arena_start - off/wordsPerBitmapWord - 1;
                shift = off % wordsPerBitmapWord;
@@ -1731,36 +1752,28 @@ sweepspan(ParFor *desc, uint32 idx)
                        continue;
 
                if((bits & bitMarked) != 0) {
-                       if(DebugMark) {
-                               if(!(bits & bitSpecial))
-                                       runtime_printf("found spurious mark on %p\n", p);
-                               *bitp &= ~(bitSpecial<<shift);
-                       }
                        *bitp &= ~(bitMarked<<shift);
                        continue;
                }
 
-               // Special means it has a finalizer or is being profiled.
-               // In DebugMark mode, the bit has been coopted so
-               // we have to assume all blocks are special.
-               if(DebugMark || (bits & bitSpecial) != 0) {
-                       if(handlespecial(p, size))
-                               continue;
-               }
-
                // Clear mark, scan, and special bits.
                *bitp &= ~((bitScan|bitMarked|bitSpecial)<<shift);
 
                if(cl == 0) {
                        // Free large span.
                        runtime_unmarkspan(p, 1<<PageShift);
-                       *(uintptr*)p = (uintptr)0xdeaddeaddeaddeadll;   // needs zeroing
+                       s->needzero = 1;
+                       // important to set sweepgen before returning it to heap
+                       runtime_atomicstore(&s->sweepgen, sweepgen);
+                       sweepgenset = true;
                        if(runtime_debug.efence)
                                runtime_SysFree(p, size, &mstats.gc_sys);
                        else
                                runtime_MHeap_Free(&runtime_mheap, s, 1);
                        c->local_nlargefree++;
                        c->local_largefree += size;
+                       runtime_xadd64(&mstats.next_gc, -(uint64)(size * (gcpercent + 100)/100));
+                       res = true;
                } else {
                        // Free small object.
                        switch(compression) {
@@ -1771,19 +1784,106 @@ sweepspan(ParFor *desc, uint32 idx)
                                *(byte*)type_data = 0;
                                break;
                        }
-                       if(size > sizeof(uintptr))
+                       if(size > 2*sizeof(uintptr))
                                ((uintptr*)p)[1] = (uintptr)0xdeaddeaddeaddeadll;       // mark as "needs to be zeroed"
-                       
+                       else if(size > sizeof(uintptr))
+                               ((uintptr*)p)[1] = 0;
+
                        end->next = (MLink*)p;
                        end = (MLink*)p;
                        nfree++;
                }
        }
 
+       if(!sweepgenset) {
+               // The span must be in our exclusive ownership until we update sweepgen,
+               // check for potential races.
+               if(s->state != MSpanInUse || s->sweepgen != sweepgen-1) {
+                       runtime_printf("MSpan_Sweep: state=%d sweepgen=%d mheap.sweepgen=%d\n",
+                               s->state, s->sweepgen, sweepgen);
+                       runtime_throw("MSpan_Sweep: bad span state after sweep");
+               }
+               runtime_atomicstore(&s->sweepgen, sweepgen);
+       }
        if(nfree) {
                c->local_nsmallfree[cl] += nfree;
                c->local_cachealloc -= nfree * size;
-               runtime_MCentral_FreeSpan(&runtime_mheap.central[cl], s, nfree, head.next, end);
+               runtime_xadd64(&mstats.next_gc, -(uint64)(nfree * size * (gcpercent + 100)/100));
+               res = runtime_MCentral_FreeSpan(&runtime_mheap.central[cl], s, nfree, head.next, end);
+       }
+       return res;
+}
+
+// State of background sweep.
+// Pretected by gclock.
+static struct
+{
+       G*      g;
+       bool    parked;
+
+       MSpan** spans;
+       uint32  nspan;
+       uint32  spanidx;
+} sweep;
+
+// background sweeping goroutine
+static void
+bgsweep(void* dummy __attribute__ ((unused)))
+{
+       runtime_g()->issystem = 1;
+       for(;;) {
+               while(runtime_sweepone() != (uintptr)-1) {
+                       gcstats.nbgsweep++;
+                       runtime_gosched();
+               }
+               runtime_lock(&gclock);
+               if(finq != nil) {
+                       // kick off or wake up goroutine to run queued finalizers
+                       if(fing == nil)
+                               fing = __go_go(runfinq, nil);
+                       else if(fingwait) {
+                               fingwait = 0;
+                               runtime_ready(fing);
+                       }
+               }
+               sweep.parked = true;
+               runtime_parkunlock(&gclock, "GC sweep wait");
+       }
+}
+
+// sweeps one span
+// returns number of pages returned to heap, or -1 if there is nothing to sweep
+uintptr
+runtime_sweepone(void)
+{
+       M *m = runtime_m();
+       MSpan *s;
+       uint32 idx, sg;
+       uintptr npages;
+
+       // increment locks to ensure that the goroutine is not preempted
+       // in the middle of sweep thus leaving the span in an inconsistent state for next GC
+       m->locks++;
+       sg = runtime_mheap.sweepgen;
+       for(;;) {
+               idx = runtime_xadd(&sweep.spanidx, 1) - 1;
+               if(idx >= sweep.nspan) {
+                       runtime_mheap.sweepdone = true;
+                       m->locks--;
+                       return (uintptr)-1;
+               }
+               s = sweep.spans[idx];
+               if(s->state != MSpanInUse) {
+                       s->sweepgen = sg;
+                       continue;
+               }
+               if(s->sweepgen != sg-2 || !runtime_cas(&s->sweepgen, sg-2, sg-1))
+                       continue;
+               npages = s->npages;
+               if(!runtime_MSpan_Sweep(s))
+                       npages = 0;
+               m->locks--;
+               return npages;
        }
 }
 
@@ -1874,34 +1974,14 @@ runtime_gchelper(void)
        runtime_parfordo(work.markfor);
 
        // help other threads scan secondary blocks
-       scanblock(nil, nil, 0, true);
+       scanblock(nil, true);
 
-       if(DebugMark) {
-               // wait while the main thread executes mark(debug_scanblock)
-               while(runtime_atomicload(&work.debugmarkdone) == 0)
-                       runtime_usleep(10);
-       }
-
-       runtime_parfordo(work.sweepfor);
        bufferList[runtime_m()->helpgc].busy = 0;
        nproc = work.nproc;  // work.nproc can change right after we increment work.ndone
        if(runtime_xadd(&work.ndone, +1) == nproc-1)
                runtime_notewakeup(&work.alldone);
 }
 
-#define GcpercentUnknown (-2)
-
-// Initialized from $GOGC.  GOGC=off means no gc.
-//
-// Next gc is after we've allocated an extra amount of
-// memory proportional to the amount already in use.
-// If gcpercent=100 and we're using 4M, we'll gc again
-// when we get to 8M.  This keeps the gc cost in linear
-// proportion to the allocation cost.  Adjusting gcpercent
-// just changes the linear constant (and also the amount of
-// extra memory used).
-static int32 gcpercent = GcpercentUnknown;
-
 static void
 cachestats(void)
 {
@@ -1916,13 +1996,26 @@ cachestats(void)
        }
 }
 
+static void
+flushallmcaches(void)
+{
+       P *p, **pp;
+       MCache *c;
+
+       // Flush MCache's to MCentral.
+       for(pp=runtime_allp; (p=*pp) != nil; pp++) {
+               c = p->mcache;
+               if(c==nil)
+                       continue;
+               runtime_MCache_ReleaseAll(c);
+       }
+}
+
 static void
 updatememstats(GCStats *stats)
 {
        M *mp;
        MSpan *s;
-       MCache *c;
-       P *p, **pp;
        uint32 i;
        uint64 stacks_inuse, smallfree;
        uint64 *src, *dst;
@@ -1963,12 +2056,7 @@ updatememstats(GCStats *stats)
        }
 
        // Flush MCache's to MCentral.
-       for(pp=runtime_allp; (p=*pp) != nil; pp++) {
-               c = p->mcache;
-               if(c==nil)
-                       continue;
-               runtime_MCache_ReleaseAll(c);
-       }
+       flushallmcaches();
 
        // Aggregate local stats.
        cachestats();
@@ -2081,6 +2169,9 @@ runtime_gc(int32 force)
        a.start_time = runtime_nanotime();
        m->gcing = 1;
        runtime_stoptheworld();
+       
+       if(runtime_debug.allocfreetrace)
+               runtime_MProf_TraceGC();
 
        clearpools();
 
@@ -2108,19 +2199,24 @@ runtime_gc(int32 force)
        m->locks--;
 
        // now that gc is done, kick off finalizer thread if needed
-       if(finq != nil) {
-               runtime_lock(&finlock);
-               // kick off or wake up goroutine to run queued finalizers
-               if(fing == nil)
-                       fing = __go_go(runfinq, nil);
-               else if(fingwait) {
-                       fingwait = 0;
-                       runtime_ready(fing);
+       if(!ConcurrentSweep) {
+               if(finq != nil) {
+                       runtime_lock(&gclock);
+                       // kick off or wake up goroutine to run queued finalizers
+                       if(fing == nil)
+                               fing = __go_go(runfinq, nil);
+                       else if(fingwait) {
+                               fingwait = 0;
+                               runtime_ready(fing);
+                       }
+                       runtime_unlock(&gclock);
                }
-               runtime_unlock(&finlock);
+               // give the queued finalizers, if any, a chance to run
+               runtime_gosched();
+       } else {
+               // For gccgo, let other goroutines run.
+               runtime_gosched();
        }
-       // give the queued finalizers, if any, a chance to run
-       runtime_gosched();
 }
 
 static void
@@ -2137,7 +2233,7 @@ gc(struct gc_args *args)
 {
        M *m;
        int64 t0, t1, t2, t3, t4;
-       uint64 heap0, heap1, obj0, obj1, ninstr;
+       uint64 heap0, heap1, obj, ninstr;
        GCStats stats;
        M *mp;
        uint32 i;
@@ -2146,6 +2242,7 @@ gc(struct gc_args *args)
        m = runtime_m();
 
        t0 = args->start_time;
+       work.tstart = args->start_time; 
 
        if(CollectStats)
                runtime_memclr((byte*)&gcstats, sizeof(gcstats));
@@ -2153,61 +2250,50 @@ gc(struct gc_args *args)
        for(mp=runtime_allm; mp; mp=mp->alllink)
                runtime_settype_flush(mp);
 
-       heap0 = 0;
-       obj0 = 0;
-       if(runtime_debug.gctrace) {
-               updatememstats(nil);
-               heap0 = mstats.heap_alloc;
-               obj0 = mstats.nmalloc - mstats.nfree;
-       }
-
        m->locks++;     // disable gc during mallocs in parforalloc
        if(work.markfor == nil)
                work.markfor = runtime_parforalloc(MaxGcproc);
-       if(work.sweepfor == nil)
-               work.sweepfor = runtime_parforalloc(MaxGcproc);
        m->locks--;
 
        if(itabtype == nil) {
                // get C pointer to the Go type "itab"
                // runtime_gc_itab_ptr(&eface);
-               // itabtype = ((PtrType*)eface.type)->elem;
+               // itabtype = ((PtrType*)eface.__type_descriptor)->elem;
        }
 
+       t1 = runtime_nanotime();
+
+       // Sweep what is not sweeped by bgsweep.
+       while(runtime_sweepone() != (uintptr)-1)
+               gcstats.npausesweep++;
+
        work.nwait = 0;
        work.ndone = 0;
-       work.debugmarkdone = 0;
        work.nproc = runtime_gcprocs();
-       addroots();
-       addfreelists();
-       runtime_parforsetup(work.markfor, work.nproc, work.nroot, nil, false, markroot);
-       runtime_parforsetup(work.sweepfor, work.nproc, runtime_mheap.nspan, nil, true, sweepspan);
+       runtime_parforsetup(work.markfor, work.nproc, RootCount + runtime_allglen, nil, false, markroot);
        if(work.nproc > 1) {
                runtime_noteclear(&work.alldone);
                runtime_helpgc(work.nproc);
        }
 
-       t1 = runtime_nanotime();
+       t2 = runtime_nanotime();
 
        gchelperstart();
        runtime_parfordo(work.markfor);
-       scanblock(nil, nil, 0, true);
-
-       if(DebugMark) {
-               for(i=0; i<work.nroot; i++)
-                       debug_scanblock(work.roots[i].p, work.roots[i].n);
-               runtime_atomicstore(&work.debugmarkdone, 1);
-       }
-       t2 = runtime_nanotime();
+       scanblock(nil, true);
 
-       runtime_parfordo(work.sweepfor);
-       bufferList[m->helpgc].busy = 0;
        t3 = runtime_nanotime();
 
+       bufferList[m->helpgc].busy = 0;
        if(work.nproc > 1)
                runtime_notesleep(&work.alldone);
 
        cachestats();
+       // next_gc calculation is tricky with concurrent sweep since we don't know size of live heap
+       // estimate what was live heap size after previous GC (for tracing only)
+       heap0 = mstats.next_gc*100/(gcpercent+100);
+       // conservatively set next_gc to high value assuming that everything is live
+       // concurrent/lazy sweep will reduce this number while discovering new garbage
        mstats.next_gc = mstats.heap_alloc+mstats.heap_alloc*gcpercent/100;
 
        t4 = runtime_nanotime();
@@ -2221,20 +2307,23 @@ gc(struct gc_args *args)
        if(runtime_debug.gctrace) {
                updatememstats(&stats);
                heap1 = mstats.heap_alloc;
-               obj1 = mstats.nmalloc - mstats.nfree;
+               obj = mstats.nmalloc - mstats.nfree;
 
-               stats.nprocyield += work.sweepfor->nprocyield;
-               stats.nosyield += work.sweepfor->nosyield;
-               stats.nsleep += work.sweepfor->nsleep;
+               stats.nprocyield += work.markfor->nprocyield;
+               stats.nosyield += work.markfor->nosyield;
+               stats.nsleep += work.markfor->nsleep;
 
-               runtime_printf("gc%d(%d): %D+%D+%D ms, %D -> %D MB %D -> %D (%D-%D) objects,"
+               runtime_printf("gc%d(%d): %D+%D+%D ms, %D -> %D MB, %D (%D-%D) objects,"
+                               " %d/%d/%d sweeps,"
                                " %D(%D) handoff, %D(%D) steal, %D/%D/%D yields\n",
-                       mstats.numgc, work.nproc, (t2-t1)/1000000, (t3-t2)/1000000, (t1-t0+t4-t3)/1000000,
-                       heap0>>20, heap1>>20, obj0, obj1,
+                       mstats.numgc, work.nproc, (t3-t2)/1000000, (t2-t1)/1000000, (t1-t0+t4-t3)/1000000,
+                       heap0>>20, heap1>>20, obj,
                        mstats.nmalloc, mstats.nfree,
+                       sweep.nspan, gcstats.nbgsweep, gcstats.npausesweep,
                        stats.nhandoff, stats.nhandoffcnt,
-                       work.sweepfor->nsteal, work.sweepfor->nstealcnt,
+                       work.markfor->nsteal, work.markfor->nstealcnt,
                        stats.nprocyield, stats.nosyield, stats.nsleep);
+               gcstats.nbgsweep = gcstats.npausesweep = 0;
                if(CollectStats) {
                        runtime_printf("scan: %D bytes, %D objects, %D untyped, %D types from MSpan\n",
                                gcstats.nbytes, gcstats.obj.cnt, gcstats.obj.notype, gcstats.obj.typelookup);
@@ -2261,9 +2350,44 @@ gc(struct gc_args *args)
                }
        }
 
+       // We cache current runtime_mheap.allspans array in sweep.spans,
+       // because the former can be resized and freed.
+       // Otherwise we would need to take heap lock every time
+       // we want to convert span index to span pointer.
+
+       // Free the old cached array if necessary.
+       if(sweep.spans && sweep.spans != runtime_mheap.allspans)
+               runtime_SysFree(sweep.spans, sweep.nspan*sizeof(sweep.spans[0]), &mstats.other_sys);
+       // Cache the current array.
+       runtime_mheap.sweepspans = runtime_mheap.allspans;
+       runtime_mheap.sweepgen += 2;
+       runtime_mheap.sweepdone = false;
+       sweep.spans = runtime_mheap.allspans;
+       sweep.nspan = runtime_mheap.nspan;
+       sweep.spanidx = 0;
+
+       // Temporary disable concurrent sweep, because we see failures on builders.
+       if(ConcurrentSweep) {
+               runtime_lock(&gclock);
+               if(sweep.g == nil)
+                       sweep.g = __go_go(bgsweep, nil);
+               else if(sweep.parked) {
+                       sweep.parked = false;
+                       runtime_ready(sweep.g);
+               }
+               runtime_unlock(&gclock);
+       } else {
+               // Sweep all spans eagerly.
+               while(runtime_sweepone() != (uintptr)-1)
+                       gcstats.npausesweep++;
+       }
+
        runtime_MProf_GC();
 }
 
+extern uintptr runtime_sizeof_C_MStats
+  __asm__ (GOSYM_PREFIX "runtime.Sizeof_C_MStats");
+
 void runtime_ReadMemStats(MStats *)
   __asm__ (GOSYM_PREFIX "runtime.ReadMemStats");
 
@@ -2281,7 +2405,9 @@ runtime_ReadMemStats(MStats *stats)
        m->gcing = 1;
        runtime_stoptheworld();
        updatememstats(nil);
-       *stats = mstats;
+       // Size of the trailing by_size array differs between Go and C,
+       // NumSizeClasses was changed, but we can not change Go struct because of backward compatibility.
+       runtime_memmove(stats, &mstats, runtime_sizeof_C_MStats);
        m->gcing = 0;
        m->locks++;
        runtime_semrelease(&runtime_worldsema);
@@ -2366,15 +2492,15 @@ runfinq(void* dummy __attribute__ ((unused)))
        Iface iface;
 
        for(;;) {
-               runtime_lock(&finlock);
+               runtime_lock(&gclock);
                fb = finq;
                finq = nil;
                if(fb == nil) {
                        fingwait = 1;
-                       runtime_park(runtime_unlock, &finlock, "finalizer wait");
+                       runtime_parkunlock(&gclock, "finalizer wait");
                        continue;
                }
-               runtime_unlock(&finlock);
+               runtime_unlock(&gclock);
                if(raceenabled)
                        runtime_racefingo();
                for(; fb; fb=next) {
@@ -2385,12 +2511,12 @@ runfinq(void* dummy __attribute__ ((unused)))
 
                                f = &fb->fin[i];
                                fint = ((const Type**)f->ft->__in.array)[0];
-                               if(fint->kind == KindPtr) {
+                               if(fint->__code == KindPtr) {
                                        // direct use of pointer
                                        param = &f->arg;
                                } else if(((const InterfaceType*)fint)->__methods.__count == 0) {
                                        // convert to empty interface
-                                       ef.type = (const Type*)f->ot;
+                                       ef.__type_descriptor = (const Type*)f->ot;
                                        ef.__object = f->arg;
                                        param = &ef;
                                } else {
@@ -2585,50 +2711,6 @@ runtime_unmarkspan(void *v, uintptr n)
                *b-- = 0;
 }
 
-bool
-runtime_blockspecial(void *v)
-{
-       uintptr *b, off, shift;
-
-       if(DebugMark)
-               return true;
-
-       off = (uintptr*)v - (uintptr*)runtime_mheap.arena_start;
-       b = (uintptr*)runtime_mheap.arena_start - off/wordsPerBitmapWord - 1;
-       shift = off % wordsPerBitmapWord;
-
-       return (*b & (bitSpecial<<shift)) != 0;
-}
-
-void
-runtime_setblockspecial(void *v, bool s)
-{
-       uintptr *b, off, shift, bits, obits;
-
-       if(DebugMark)
-               return;
-
-       off = (uintptr*)v - (uintptr*)runtime_mheap.arena_start;
-       b = (uintptr*)runtime_mheap.arena_start - off/wordsPerBitmapWord - 1;
-       shift = off % wordsPerBitmapWord;
-
-       for(;;) {
-               obits = *b;
-               if(s)
-                       bits = obits | (bitSpecial<<shift);
-               else
-                       bits = obits & ~(bitSpecial<<shift);
-               if(runtime_gomaxprocs == 1) {
-                       *b = bits;
-                       break;
-               } else {
-                       // more than one goroutine is potentially running: use atomic op
-                       if(runtime_casp((void**)b, (void*)obits, (void*)bits))
-                               break;
-               }
-       }
-}
-
 void
 runtime_MHeap_MapBits(MHeap *h)
 {
index 1b8ab79160610b9cbb5b7acd069fd69949786457..3a5eb15a596e7789bd4e8842b942db3e680394e5 100644 (file)
@@ -41,7 +41,10 @@ RecordSpan(void *vh, byte *p)
                        runtime_throw("runtime: cannot allocate memory");
                if(h->allspans) {
                        runtime_memmove(all, h->allspans, h->nspancap*sizeof(all[0]));
-                       runtime_SysFree(h->allspans, h->nspancap*sizeof(all[0]), &mstats.other_sys);
+                       // Don't free the old array if it's referenced by sweep.
+                       // See the comment in mgc0.c.
+                       if(h->allspans != runtime_mheap.sweepspans)
+                               runtime_SysFree(h->allspans, h->nspancap*sizeof(all[0]), &mstats.other_sys);
                }
                h->allspans = all;
                h->nspancap = cap;
@@ -57,10 +60,15 @@ runtime_MHeap_Init(MHeap *h)
 
        runtime_FixAlloc_Init(&h->spanalloc, sizeof(MSpan), RecordSpan, h, &mstats.mspan_sys);
        runtime_FixAlloc_Init(&h->cachealloc, sizeof(MCache), nil, nil, &mstats.mcache_sys);
+       runtime_FixAlloc_Init(&h->specialfinalizeralloc, sizeof(SpecialFinalizer), nil, nil, &mstats.other_sys);
+       runtime_FixAlloc_Init(&h->specialprofilealloc, sizeof(SpecialProfile), nil, nil, &mstats.other_sys);
        // h->mapcache needs no init
-       for(i=0; i<nelem(h->free); i++)
+       for(i=0; i<nelem(h->free); i++) {
                runtime_MSpanList_Init(&h->free[i]);
-       runtime_MSpanList_Init(&h->large);
+               runtime_MSpanList_Init(&h->busy[i]);
+       }
+       runtime_MSpanList_Init(&h->freelarge);
+       runtime_MSpanList_Init(&h->busylarge);
        for(i=0; i<nelem(h->central); i++)
                runtime_MCentral_Init(&h->central[i], i);
 }
@@ -84,10 +92,86 @@ runtime_MHeap_MapSpans(MHeap *h)
        h->spans_mapped = n;
 }
 
+// Sweeps spans in list until reclaims at least npages into heap.
+// Returns the actual number of pages reclaimed.
+static uintptr
+MHeap_ReclaimList(MHeap *h, MSpan *list, uintptr npages)
+{
+       MSpan *s;
+       uintptr n;
+       uint32 sg;
+
+       n = 0;
+       sg = runtime_mheap.sweepgen;
+retry:
+       for(s = list->next; s != list; s = s->next) {
+               if(s->sweepgen == sg-2 && runtime_cas(&s->sweepgen, sg-2, sg-1)) {
+                       runtime_MSpanList_Remove(s);
+                       // swept spans are at the end of the list
+                       runtime_MSpanList_InsertBack(list, s);
+                       runtime_unlock(h);
+                       n += runtime_MSpan_Sweep(s);
+                       runtime_lock(h);
+                       if(n >= npages)
+                               return n;
+                       // the span could have been moved elsewhere
+                       goto retry;
+               }
+               if(s->sweepgen == sg-1) {
+                       // the span is being sweept by background sweeper, skip
+                       continue;
+               }
+               // already swept empty span,
+               // all subsequent ones must also be either swept or in process of sweeping
+               break;
+       }
+       return n;
+}
+
+// Sweeps and reclaims at least npage pages into heap.
+// Called before allocating npage pages.
+static void
+MHeap_Reclaim(MHeap *h, uintptr npage)
+{
+       uintptr reclaimed, n;
+
+       // First try to sweep busy spans with large objects of size >= npage,
+       // this has good chances of reclaiming the necessary space.
+       for(n=npage; n < nelem(h->busy); n++) {
+               if(MHeap_ReclaimList(h, &h->busy[n], npage))
+                       return;  // Bingo!
+       }
+
+       // Then -- even larger objects.
+       if(MHeap_ReclaimList(h, &h->busylarge, npage))
+               return;  // Bingo!
+
+       // Now try smaller objects.
+       // One such object is not enough, so we need to reclaim several of them.
+       reclaimed = 0;
+       for(n=0; n < npage && n < nelem(h->busy); n++) {
+               reclaimed += MHeap_ReclaimList(h, &h->busy[n], npage-reclaimed);
+               if(reclaimed >= npage)
+                       return;
+       }
+
+       // Now sweep everything that is not yet swept.
+       runtime_unlock(h);
+       for(;;) {
+               n = runtime_sweepone();
+               if(n == (uintptr)-1)  // all spans are swept
+                       break;
+               reclaimed += n;
+               if(reclaimed >= npage)
+                       break;
+       }
+       runtime_lock(h);
+}
+
 // Allocate a new span of npage pages from the heap
 // and record its size class in the HeapMap and HeapMapCache.
 MSpan*
-runtime_MHeap_Alloc(MHeap *h, uintptr npage, int32 sizeclass, int32 acct, int32 zeroed)
+runtime_MHeap_Alloc(MHeap *h, uintptr npage, int32 sizeclass, bool large, bool needzero)
 {
        MSpan *s;
 
@@ -97,14 +181,22 @@ runtime_MHeap_Alloc(MHeap *h, uintptr npage, int32 sizeclass, int32 acct, int32
        s = MHeap_AllocLocked(h, npage, sizeclass);
        if(s != nil) {
                mstats.heap_inuse += npage<<PageShift;
-               if(acct) {
+               if(large) {
                        mstats.heap_objects++;
                        mstats.heap_alloc += npage<<PageShift;
+                       // Swept spans are at the end of lists.
+                       if(s->npages < nelem(h->free))
+                               runtime_MSpanList_InsertBack(&h->busy[s->npages], s);
+                       else
+                               runtime_MSpanList_InsertBack(&h->busylarge, s);
                }
        }
        runtime_unlock(h);
-       if(s != nil && *(uintptr*)(s->start<<PageShift) != 0 && zeroed)
-               runtime_memclr((byte*)(s->start<<PageShift), s->npages<<PageShift);
+       if(s != nil) {
+               if(needzero && s->needzero)
+                       runtime_memclr((byte*)(s->start<<PageShift), s->npages<<PageShift);
+               s->needzero = 0;
+       }
        return s;
 }
 
@@ -115,6 +207,11 @@ MHeap_AllocLocked(MHeap *h, uintptr npage, int32 sizeclass)
        MSpan *s, *t;
        PageID p;
 
+       // To prevent excessive heap growth, before allocating n pages
+       // we need to sweep and reclaim at least n pages.
+       if(!h->sweepdone)
+               MHeap_Reclaim(h, npage);
+
        // Try in fixed-size lists up to max.
        for(n=npage; n < nelem(h->free); n++) {
                if(!runtime_MSpanList_IsEmpty(&h->free[n])) {
@@ -138,29 +235,12 @@ HaveSpan:
        if(s->npages < npage)
                runtime_throw("MHeap_AllocLocked - bad npages");
        runtime_MSpanList_Remove(s);
+       runtime_atomicstore(&s->sweepgen, h->sweepgen);
        s->state = MSpanInUse;
        mstats.heap_idle -= s->npages<<PageShift;
        mstats.heap_released -= s->npreleased<<PageShift;
-       if(s->npreleased > 0) {
-               // We have called runtime_SysUnused with these pages, and on
-               // Unix systems it called madvise.  At this point at least
-               // some BSD-based kernels will return these pages either as
-               // zeros or with the old data.  For our caller, the first word
-               // in the page indicates whether the span contains zeros or
-               // not (this word was set when the span was freed by
-               // MCentral_Free or runtime_MCentral_FreeSpan).  If the first
-               // page in the span is returned as zeros, and some subsequent
-               // page is returned with the old data, then we will be
-               // returning a span that is assumed to be all zeros, but the
-               // actual data will not be all zeros.  Avoid that problem by
-               // explicitly marking the span as not being zeroed, just in
-               // case.  The beadbead constant we use here means nothing, it
-               // is just a unique constant not seen elsewhere in the
-               // runtime, as a clue in case it turns up unexpectedly in
-               // memory or in a stack trace.
+       if(s->npreleased > 0)
                runtime_SysUsed((void*)(s->start<<PageShift), s->npages<<PageShift);
-               *(uintptr*)(s->start<<PageShift) = (uintptr)0xbeadbeadbeadbeadULL;
-       }
        s->npreleased = 0;
 
        if(s->npages > npage) {
@@ -174,7 +254,8 @@ HaveSpan:
                        h->spans[p-1] = s;
                h->spans[p] = t;
                h->spans[p+t->npages-1] = t;
-               *(uintptr*)(t->start<<PageShift) = *(uintptr*)(s->start<<PageShift);  // copy "needs zeroing" mark
+               t->needzero = s->needzero;
+               runtime_atomicstore(&t->sweepgen, h->sweepgen);
                t->state = MSpanInUse;
                MHeap_FreeLocked(h, t);
                t->unusedsince = s->unusedsince; // preserve age
@@ -197,7 +278,7 @@ HaveSpan:
 static MSpan*
 MHeap_AllocLarge(MHeap *h, uintptr npage)
 {
-       return BestFit(&h->large, npage, nil);
+       return BestFit(&h->freelarge, npage, nil);
 }
 
 // Search list for smallest span with >= npage pages.
@@ -258,6 +339,7 @@ MHeap_Grow(MHeap *h, uintptr npage)
        p -= ((uintptr)h->arena_start>>PageShift);
        h->spans[p] = s;
        h->spans[p + s->npages - 1] = s;
+       runtime_atomicstore(&s->sweepgen, h->sweepgen);
        s->state = MSpanInUse;
        MHeap_FreeLocked(h, s);
        return true;
@@ -319,20 +401,19 @@ runtime_MHeap_Free(MHeap *h, MSpan *s, int32 acct)
 static void
 MHeap_FreeLocked(MHeap *h, MSpan *s)
 {
-       uintptr *sp, *tp;
        MSpan *t;
        PageID p;
 
        s->types.compression = MTypes_Empty;
 
-       if(s->state != MSpanInUse || s->ref != 0) {
-               runtime_printf("MHeap_FreeLocked - span %p ptr %p state %d ref %d\n", s, s->start<<PageShift, s->state, s->ref);
+       if(s->state != MSpanInUse || s->ref != 0 || s->sweepgen != h->sweepgen) {
+               runtime_printf("MHeap_FreeLocked - span %p ptr %p state %d ref %d sweepgen %d/%d\n",
+                       s, s->start<<PageShift, s->state, s->ref, s->sweepgen, h->sweepgen);
                runtime_throw("MHeap_FreeLocked - invalid free");
        }
        mstats.heap_idle += s->npages<<PageShift;
        s->state = MSpanFree;
        runtime_MSpanList_Remove(s);
-       sp = (uintptr*)(s->start<<PageShift);
        // Stamp newly unused spans. The scavenger will use that
        // info to potentially give back some pages to the OS.
        s->unusedsince = runtime_nanotime();
@@ -342,13 +423,10 @@ MHeap_FreeLocked(MHeap *h, MSpan *s)
        p = s->start;
        p -= (uintptr)h->arena_start >> PageShift;
        if(p > 0 && (t = h->spans[p-1]) != nil && t->state != MSpanInUse) {
-               if(t->npreleased == 0) {  // cant't touch this otherwise
-                       tp = (uintptr*)(t->start<<PageShift);
-                       *tp |= *sp;     // propagate "needs zeroing" mark
-               }
                s->start = t->start;
                s->npages += t->npages;
                s->npreleased = t->npreleased; // absorb released pages
+               s->needzero |= t->needzero;
                p -= t->npages;
                h->spans[p] = s;
                runtime_MSpanList_Remove(t);
@@ -356,12 +434,9 @@ MHeap_FreeLocked(MHeap *h, MSpan *s)
                runtime_FixAlloc_Free(&h->spanalloc, t);
        }
        if((p+s->npages)*sizeof(h->spans[0]) < h->spans_mapped && (t = h->spans[p+s->npages]) != nil && t->state != MSpanInUse) {
-               if(t->npreleased == 0) {  // cant't touch this otherwise
-                       tp = (uintptr*)(t->start<<PageShift);
-                       *sp |= *tp;     // propagate "needs zeroing" mark
-               }
                s->npages += t->npages;
                s->npreleased += t->npreleased;
+               s->needzero |= t->needzero;
                h->spans[p + s->npages - 1] = s;
                runtime_MSpanList_Remove(t);
                t->state = MSpanDead;
@@ -372,7 +447,7 @@ MHeap_FreeLocked(MHeap *h, MSpan *s)
        if(s->npages < nelem(h->free))
                runtime_MSpanList_Insert(&h->free[s->npages], s);
        else
-               runtime_MSpanList_Insert(&h->large, s);
+               runtime_MSpanList_Insert(&h->freelarge, s);
 }
 
 static void
@@ -427,7 +502,7 @@ scavenge(int32 k, uint64 now, uint64 limit)
        sumreleased = 0;
        for(i=0; i < nelem(h->free); i++)
                sumreleased += scavengelist(&h->free[i], now, limit);
-       sumreleased += scavengelist(&h->large, now, limit);
+       sumreleased += scavengelist(&h->freelarge, now, limit);
 
        if(runtime_debug.gctrace > 0) {
                if(sumreleased > 0)
@@ -516,10 +591,13 @@ runtime_MSpan_Init(MSpan *span, PageID start, uintptr npages)
        span->ref = 0;
        span->sizeclass = 0;
        span->elemsize = 0;
-       span->state = 0;
+       span->state = MSpanDead;
        span->unusedsince = 0;
        span->npreleased = 0;
        span->types.compression = MTypes_Empty;
+       span->specialLock.key = 0;
+       span->specials = nil;
+       span->needzero = 0;
 }
 
 // Initialize an empty doubly-linked list.
@@ -561,4 +639,212 @@ runtime_MSpanList_Insert(MSpan *list, MSpan *span)
        span->prev->next = span;
 }
 
+void
+runtime_MSpanList_InsertBack(MSpan *list, MSpan *span)
+{
+       if(span->next != nil || span->prev != nil) {
+               runtime_printf("failed MSpanList_Insert %p %p %p\n", span, span->next, span->prev);
+               runtime_throw("MSpanList_Insert");
+       }
+       span->next = list;
+       span->prev = list->prev;
+       span->next->prev = span;
+       span->prev->next = span;
+}
+
+// Adds the special record s to the list of special records for
+// the object p.  All fields of s should be filled in except for
+// offset & next, which this routine will fill in.
+// Returns true if the special was successfully added, false otherwise.
+// (The add will fail only if a record with the same p and s->kind
+//  already exists.)
+static bool
+addspecial(void *p, Special *s)
+{
+       MSpan *span;
+       Special **t, *x;
+       uintptr offset;
+       byte kind;
+
+       span = runtime_MHeap_LookupMaybe(&runtime_mheap, p);
+       if(span == nil)
+               runtime_throw("addspecial on invalid pointer");
+
+       // Ensure that the span is swept.
+       // GC accesses specials list w/o locks. And it's just much safer.
+       runtime_MSpan_EnsureSwept(span);
+
+       offset = (uintptr)p - (span->start << PageShift);
+       kind = s->kind;
+
+       runtime_lock(&span->specialLock);
+
+       // Find splice point, check for existing record.
+       t = &span->specials;
+       while((x = *t) != nil) {
+               if(offset == x->offset && kind == x->kind) {
+                       runtime_unlock(&span->specialLock);
+                       return false; // already exists
+               }
+               if(offset < x->offset || (offset == x->offset && kind < x->kind))
+                       break;
+               t = &x->next;
+       }
+       // Splice in record, fill in offset.
+       s->offset = offset;
+       s->next = x;
+       *t = s;
+       runtime_unlock(&span->specialLock);
+       return true;
+}
 
+// Removes the Special record of the given kind for the object p.
+// Returns the record if the record existed, nil otherwise.
+// The caller must FixAlloc_Free the result.
+static Special*
+removespecial(void *p, byte kind)
+{
+       MSpan *span;
+       Special *s, **t;
+       uintptr offset;
+
+       span = runtime_MHeap_LookupMaybe(&runtime_mheap, p);
+       if(span == nil)
+               runtime_throw("removespecial on invalid pointer");
+
+       // Ensure that the span is swept.
+       // GC accesses specials list w/o locks. And it's just much safer.
+       runtime_MSpan_EnsureSwept(span);
+
+       offset = (uintptr)p - (span->start << PageShift);
+
+       runtime_lock(&span->specialLock);
+       t = &span->specials;
+       while((s = *t) != nil) {
+               // This function is used for finalizers only, so we don't check for
+               // "interior" specials (p must be exactly equal to s->offset).
+               if(offset == s->offset && kind == s->kind) {
+                       *t = s->next;
+                       runtime_unlock(&span->specialLock);
+                       return s;
+               }
+               t = &s->next;
+       }
+       runtime_unlock(&span->specialLock);
+       return nil;
+}
+
+// Adds a finalizer to the object p.  Returns true if it succeeded.
+bool
+runtime_addfinalizer(void *p, FuncVal *f, const FuncType *ft, const PtrType *ot)
+{
+       SpecialFinalizer *s;
+
+       runtime_lock(&runtime_mheap.speciallock);
+       s = runtime_FixAlloc_Alloc(&runtime_mheap.specialfinalizeralloc);
+       runtime_unlock(&runtime_mheap.speciallock);
+       s->kind = KindSpecialFinalizer;
+       s->fn = f;
+       s->ft = ft;
+       s->ot = ot;
+       if(addspecial(p, s))
+               return true;
+
+       // There was an old finalizer
+       runtime_lock(&runtime_mheap.speciallock);
+       runtime_FixAlloc_Free(&runtime_mheap.specialfinalizeralloc, s);
+       runtime_unlock(&runtime_mheap.speciallock);
+       return false;
+}
+
+// Removes the finalizer (if any) from the object p.
+void
+runtime_removefinalizer(void *p)
+{
+       SpecialFinalizer *s;
+
+       s = (SpecialFinalizer*)removespecial(p, KindSpecialFinalizer);
+       if(s == nil)
+               return; // there wasn't a finalizer to remove
+       runtime_lock(&runtime_mheap.speciallock);
+       runtime_FixAlloc_Free(&runtime_mheap.specialfinalizeralloc, s);
+       runtime_unlock(&runtime_mheap.speciallock);
+}
+
+// Set the heap profile bucket associated with addr to b.
+void
+runtime_setprofilebucket(void *p, Bucket *b)
+{
+       SpecialProfile *s;
+
+       runtime_lock(&runtime_mheap.speciallock);
+       s = runtime_FixAlloc_Alloc(&runtime_mheap.specialprofilealloc);
+       runtime_unlock(&runtime_mheap.speciallock);
+       s->kind = KindSpecialProfile;
+       s->b = b;
+       if(!addspecial(p, s))
+               runtime_throw("setprofilebucket: profile already set");
+}
+
+// Do whatever cleanup needs to be done to deallocate s.  It has
+// already been unlinked from the MSpan specials list.
+// Returns true if we should keep working on deallocating p.
+bool
+runtime_freespecial(Special *s, void *p, uintptr size, bool freed)
+{
+       SpecialFinalizer *sf;
+       SpecialProfile *sp;
+
+       switch(s->kind) {
+       case KindSpecialFinalizer:
+               sf = (SpecialFinalizer*)s;
+               runtime_queuefinalizer(p, sf->fn, sf->ft, sf->ot);
+               runtime_lock(&runtime_mheap.speciallock);
+               runtime_FixAlloc_Free(&runtime_mheap.specialfinalizeralloc, sf);
+               runtime_unlock(&runtime_mheap.speciallock);
+               return false; // don't free p until finalizer is done
+       case KindSpecialProfile:
+               sp = (SpecialProfile*)s;
+               runtime_MProf_Free(sp->b, p, size, freed);
+               runtime_lock(&runtime_mheap.speciallock);
+               runtime_FixAlloc_Free(&runtime_mheap.specialprofilealloc, sp);
+               runtime_unlock(&runtime_mheap.speciallock);
+               return true;
+       default:
+               runtime_throw("bad special kind");
+               return true;
+       }
+}
+
+// Free all special records for p.
+void
+runtime_freeallspecials(MSpan *span, void *p, uintptr size)
+{
+       Special *s, **t, *list;
+       uintptr offset;
+
+       // first, collect all specials into the list; then, free them
+       // this is required to not cause deadlock between span->specialLock and proflock
+       list = nil;
+       offset = (uintptr)p - (span->start << PageShift);
+       runtime_lock(&span->specialLock);
+       t = &span->specials;
+       while((s = *t) != nil) {
+               if(offset + size <= s->offset)
+                       break;
+               if(offset <= s->offset) {
+                       *t = s->next;
+                       s->next = list;
+                       list = s;
+               } else
+                       t = &s->next;
+       }
+       runtime_unlock(&span->specialLock);
+
+       while(list != nil) {
+               s = list;
+               list = s->next;
+               if(!runtime_freespecial(s, p, size, true))
+                       runtime_throw("can't explicitly free an object with a finalizer");
+       }
+}
index 469ddfebb369ab534306905bc0a6111162e06d67..24f8fe5e3b76d2d0aa3080257cbb3b14348d5246 100644 (file)
@@ -23,7 +23,6 @@ enum { MProf, BProf };  // profile types
 
 // Per-call-stack profiling information.
 // Lookup by hashing call stack into a linked-list hash table.
-typedef struct Bucket Bucket;
 struct Bucket
 {
        Bucket  *next;  // next in hash list
@@ -35,14 +34,33 @@ struct Bucket
        {
                struct  // typ == MProf
                {
+                       // The following complex 3-stage scheme of stats accumulation
+                       // is required to obtain a consistent picture of mallocs and frees
+                       // for some point in time.
+                       // The problem is that mallocs come in real time, while frees
+                       // come only after a GC during concurrent sweeping. So if we would
+                       // naively count them, we would get a skew toward mallocs.
+                       //
+                       // Mallocs are accounted in recent stats.
+                       // Explicit frees are accounted in recent stats.
+                       // GC frees are accounted in prev stats.
+                       // After GC prev stats are added to final stats and
+                       // recent stats are moved into prev stats.
                        uintptr allocs;
                        uintptr frees;
                        uintptr alloc_bytes;
                        uintptr free_bytes;
-                       uintptr recent_allocs;  // since last gc
+
+                       uintptr prev_allocs;  // since last but one till last gc
+                       uintptr prev_frees;
+                       uintptr prev_alloc_bytes;
+                       uintptr prev_free_bytes;
+
+                       uintptr recent_allocs;  // since last gc till now
                        uintptr recent_frees;
                        uintptr recent_alloc_bytes;
                        uintptr recent_free_bytes;
+
                };
                struct  // typ == BProf
                {
@@ -50,7 +68,8 @@ struct Bucket
                        int64   cycles;
                };
        };
-       uintptr hash;
+       uintptr hash;   // hash of size + stk
+       uintptr size;
        uintptr nstk;
        Location stk[1];
 };
@@ -64,7 +83,7 @@ static uintptr bucketmem;
 
 // Return the bucket for stk[0:nstk], allocating new bucket if needed.
 static Bucket*
-stkbucket(int32 typ, Location *stk, int32 nstk, bool alloc)
+stkbucket(int32 typ, uintptr size, Location *stk, int32 nstk, bool alloc)
 {
        int32 i, j;
        uintptr h;
@@ -83,12 +102,17 @@ stkbucket(int32 typ, Location *stk, int32 nstk, bool alloc)
                h += h<<10;
                h ^= h>>6;
        }
+       // hash in size
+       h += size;
+       h += h<<10;
+       h ^= h>>6;
+       // finalize
        h += h<<3;
        h ^= h>>11;
 
        i = h%BuckHashSize;
        for(b = buckhash[i]; b; b=b->next) {
-               if(b->typ == typ && b->hash == h && b->nstk == (uintptr)nstk) {
+               if(b->typ == typ && b->hash == h && b->size == size && b->nstk == (uintptr)nstk) {
                        for(j = 0; j < nstk; j++) {
                                if(b->stk[j].pc != stk[j].pc ||
                                   b->stk[j].lineno != stk[j].lineno ||
@@ -108,6 +132,7 @@ stkbucket(int32 typ, Location *stk, int32 nstk, bool alloc)
        runtime_memmove(b->stk, stk, nstk*sizeof stk[0]);
        b->typ = typ;
        b->hash = h;
+       b->size = size;
        b->nstk = nstk;
        b->next = buckhash[i];
        buckhash[i] = b;
@@ -127,10 +152,16 @@ MProf_GC(void)
        Bucket *b;
 
        for(b=mbuckets; b; b=b->allnext) {
-               b->allocs += b->recent_allocs;
-               b->frees += b->recent_frees;
-               b->alloc_bytes += b->recent_alloc_bytes;
-               b->free_bytes += b->recent_free_bytes;
+               b->allocs += b->prev_allocs;
+               b->frees += b->prev_frees;
+               b->alloc_bytes += b->prev_alloc_bytes;
+               b->free_bytes += b->prev_free_bytes;
+
+               b->prev_allocs = b->recent_allocs;
+               b->prev_frees = b->recent_frees;
+               b->prev_alloc_bytes = b->recent_alloc_bytes;
+               b->prev_free_bytes = b->recent_free_bytes;
+
                b->recent_allocs = 0;
                b->recent_frees = 0;
                b->recent_alloc_bytes = 0;
@@ -147,115 +178,6 @@ runtime_MProf_GC(void)
        runtime_unlock(&proflock);
 }
 
-// Map from pointer to Bucket* that allocated it.
-// Three levels:
-//     Linked-list hash table for top N-AddrHashShift bits.
-//     Array index for next AddrDenseBits bits.
-//     Linked list for next AddrHashShift-AddrDenseBits bits.
-// This is more efficient than using a general map,
-// because of the typical clustering of the pointer keys.
-
-typedef struct AddrHash AddrHash;
-typedef struct AddrEntry AddrEntry;
-
-enum {
-       AddrHashBits = 12,      // good for 4GB of used address space
-       AddrHashShift = 20,     // each AddrHash knows about 1MB of address space
-       AddrDenseBits = 8,      // good for a profiling rate of 4096 bytes
-};
-
-struct AddrHash
-{
-       AddrHash *next; // next in top-level hash table linked list
-       uintptr addr;   // addr>>20
-       AddrEntry *dense[1<<AddrDenseBits];
-};
-
-struct AddrEntry
-{
-       AddrEntry *next;        // next in bottom-level linked list
-       uint32 addr;
-       Bucket *b;
-};
-
-static AddrHash **addrhash;    // points to (AddrHash*)[1<<AddrHashBits]
-static AddrEntry *addrfree;
-static uintptr addrmem;
-
-// Multiplicative hash function:
-// hashMultiplier is the bottom 32 bits of int((sqrt(5)-1)/2 * (1<<32)).
-// This is a good multiplier as suggested in CLR, Knuth.  The hash
-// value is taken to be the top AddrHashBits bits of the bottom 32 bits
-// of the multiplied value.
-enum {
-       HashMultiplier = 2654435769U
-};
-
-// Set the bucket associated with addr to b.
-static void
-setaddrbucket(uintptr addr, Bucket *b)
-{
-       int32 i;
-       uint32 h;
-       AddrHash *ah;
-       AddrEntry *e;
-
-       h = (uint32)((addr>>AddrHashShift)*HashMultiplier) >> (32-AddrHashBits);
-       for(ah=addrhash[h]; ah; ah=ah->next)
-               if(ah->addr == (addr>>AddrHashShift))
-                       goto found;
-
-       ah = runtime_persistentalloc(sizeof *ah, 0, &mstats.buckhash_sys);
-       addrmem += sizeof *ah;
-       ah->next = addrhash[h];
-       ah->addr = addr>>AddrHashShift;
-       addrhash[h] = ah;
-
-found:
-       if((e = addrfree) == nil) {
-               e = runtime_persistentalloc(64*sizeof *e, 0, &mstats.buckhash_sys);
-               addrmem += 64*sizeof *e;
-               for(i=0; i+1<64; i++)
-                       e[i].next = &e[i+1];
-               e[63].next = nil;
-       }
-       addrfree = e->next;
-       e->addr = (uint32)~(addr & ((1<<AddrHashShift)-1));
-       e->b = b;
-       h = (addr>>(AddrHashShift-AddrDenseBits))&(nelem(ah->dense)-1); // entry in dense is top 8 bits of low 20.
-       e->next = ah->dense[h];
-       ah->dense[h] = e;
-}
-
-// Get the bucket associated with addr and clear the association.
-static Bucket*
-getaddrbucket(uintptr addr)
-{
-       uint32 h;
-       AddrHash *ah;
-       AddrEntry *e, **l;
-       Bucket *b;
-
-       h = (uint32)((addr>>AddrHashShift)*HashMultiplier) >> (32-AddrHashBits);
-       for(ah=addrhash[h]; ah; ah=ah->next)
-               if(ah->addr == (addr>>AddrHashShift))
-                       goto found;
-       return nil;
-
-found:
-       h = (addr>>(AddrHashShift-AddrDenseBits))&(nelem(ah->dense)-1); // entry in dense is top 8 bits of low 20.
-       for(l=&ah->dense[h]; (e=*l) != nil; l=&e->next) {
-               if(e->addr == (uint32)~(addr & ((1<<AddrHashShift)-1))) {
-                       *l = e->next;
-                       b = e->b;
-                       e->next = addrfree;
-                       addrfree = e;
-                       return b;
-               }
-       }
-       return nil;
-}
-
 static const char*
 typeinfoname(int32 typeinfo)
 {
@@ -285,6 +207,18 @@ printstackframes(Location *stk, int32 nstk)
        }
 }
 
+// Called by collector to report a gc in allocfreetrace mode.
+void
+runtime_MProf_TraceGC(void)
+{
+       Location stk[32];
+       int32 nstk;
+
+       nstk = runtime_callers(1, stk, nelem(stk));
+       runtime_printf("MProf_TraceGC\n");
+       printstackframes(stk, nstk);
+}
+
 // Called by malloc to record a profiled block.
 void
 runtime_MProf_Malloc(void *p, uintptr size, uintptr typ)
@@ -295,39 +229,44 @@ runtime_MProf_Malloc(void *p, uintptr size, uintptr typ)
        const char *name;
        int32 nstk;
 
-       nstk = runtime_callers(1, stk, 32);
+       nstk = runtime_callers(1, stk, nelem(stk));
        runtime_lock(&proflock);
-        if(runtime_debug.allocfreetrace) {
+       if(runtime_debug.allocfreetrace) {
                type = (Type*)(typ & ~3);
                name = typeinfoname(typ & 3);
                runtime_printf("MProf_Malloc(p=%p, size=%p, type=%p <%s", p, size, type, name);
                if(type != nil)
-                       runtime_printf(" of %S", *type->__reflection);
+                       runtime_printf(" of %S", *type->__reflection);
                runtime_printf(">)\n");
                printstackframes(stk, nstk);
        }
-       b = stkbucket(MProf, stk, nstk, true);
+       b = stkbucket(MProf, size, stk, nstk, true);
        b->recent_allocs++;
        b->recent_alloc_bytes += size;
-       setaddrbucket((uintptr)p, b);
        runtime_unlock(&proflock);
+
+       // Setprofilebucket locks a bunch of other mutexes, so we call it outside of proflock.
+       // This reduces potential contention and chances of deadlocks.
+       // Since the object must be alive during call to MProf_Malloc,
+       // it's fine to do this non-atomically.
+       runtime_setprofilebucket(p, b);
 }
 
 // Called when freeing a profiled block.
 void
-runtime_MProf_Free(void *p, uintptr size)
+runtime_MProf_Free(Bucket *b, void *p, uintptr size, bool freed)
 {
-       Bucket *b;
-
        runtime_lock(&proflock);
-       b = getaddrbucket((uintptr)p);
-       if(b != nil) {
+       if(freed) {
                b->recent_frees++;
                b->recent_free_bytes += size;
-               if(runtime_debug.allocfreetrace) {
-                       runtime_printf("MProf_Free(p=%p, size=%p)\n", p, size);
-                       printstackframes(b->stk, b->nstk);
-               }
+       } else {
+               b->prev_frees++;
+               b->prev_free_bytes += size;
+       }
+       if(runtime_debug.allocfreetrace) {
+               runtime_printf("MProf_Free(p=%p, size=%p)\n", p, size);
+               printstackframes(b->stk, b->nstk);
        }
        runtime_unlock(&proflock);
 }
@@ -366,9 +305,9 @@ runtime_blockevent(int64 cycles, int32 skip)
        if(rate <= 0 || (rate > cycles && runtime_fastrand1()%rate > cycles))
                return;
 
-       nstk = runtime_callers(skip, stk, 32);
+       nstk = runtime_callers(skip, stk, nelem(stk));
        runtime_lock(&proflock);
-       b = stkbucket(BProf, stk, nstk, true);
+       b = stkbucket(BProf, 0, stk, nstk, true);
        b->count++;
        b->cycles += cycles;
        runtime_unlock(&proflock);
@@ -420,6 +359,7 @@ func MemProfile(p Slice, include_inuse_zero bool) (n int, ok bool) {
                // garbage collection is disabled from the beginning of execution,
                // accumulate stats as if a GC just happened, and recount buckets.
                MProf_GC();
+               MProf_GC();
                n = 0;
                for(b=mbuckets; b; b=b->allnext)
                        if(include_inuse_zero || b->alloc_bytes != b->free_bytes)
@@ -437,13 +377,11 @@ func MemProfile(p Slice, include_inuse_zero bool) (n int, ok bool) {
 }
 
 void
-runtime_MProf_Mark(void (*addroot)(Obj))
+runtime_MProf_Mark(struct Workbuf **wbufp, void (*enqueue1)(struct Workbuf**, Obj))
 {
        // buckhash is not allocated via mallocgc.
-       addroot((Obj){(byte*)&mbuckets, sizeof mbuckets, 0});
-       addroot((Obj){(byte*)&bbuckets, sizeof bbuckets, 0});
-       addroot((Obj){(byte*)&addrhash, sizeof addrhash, 0});
-       addroot((Obj){(byte*)&addrfree, sizeof addrfree, 0});
+       enqueue1(wbufp, (Obj){(byte*)&mbuckets, sizeof mbuckets, 0});
+       enqueue1(wbufp, (Obj){(byte*)&bbuckets, sizeof bbuckets, 0});
 }
 
 // Must match BlockProfileRecord in debug.go.
@@ -568,6 +506,7 @@ saveg(G *gp, TRecord *r)
 }
 
 func GoroutineProfile(b Slice) (n int, ok bool) {
+       uintptr i;
        TRecord *r;
        G *gp;
        
@@ -584,7 +523,8 @@ func GoroutineProfile(b Slice) (n int, ok bool) {
                        ok = true;
                        r = (TRecord*)b.__values;
                        saveg(g, r++);
-                       for(gp = runtime_allg; gp != nil; gp = gp->alllink) {
+                       for(i = 0; i < runtime_allglen; i++) {
+                               gp = runtime_allg[i];
                                if(gp == g || gp->status == Gdead)
                                        continue;
                                saveg(gp, r++);
@@ -596,9 +536,3 @@ func GoroutineProfile(b Slice) (n int, ok bool) {
                runtime_starttheworld();
        }
 }
-
-void
-runtime_mprofinit(void)
-{
-       addrhash = runtime_persistentalloc((1<<AddrHashBits)*sizeof *addrhash, 0, &mstats.buckhash_sys);
-}
index 745a76958c8aecfd616530e8ae0d2f12dd0d5c60..34509d0456817c3872018aa2cc134f780da6cf99 100644 (file)
@@ -44,8 +44,8 @@ int32 runtime_class_to_allocnpages[NumSizeClasses];
 int8 runtime_size_to_class8[1024/8 + 1];
 int8 runtime_size_to_class128[(MaxSmallSize-1024)/128 + 1];
 
-static int32
-SizeToClass(int32 size)
+int32
+runtime_SizeToClass(int32 size)
 {
        if(size > MaxSmallSize)
                runtime_throw("SizeToClass - invalid size");
@@ -90,9 +90,9 @@ runtime_InitSizes(void)
                // objects into the page, we might as well
                // use just this size instead of having two
                // different sizes.
-               if(sizeclass > 1
-               && (int32)npages == runtime_class_to_allocnpages[sizeclass-1]
-               && allocsize/size == allocsize/runtime_class_to_size[sizeclass-1]) {
+               if(sizeclass > 1 &&
+                       (int32)npages == runtime_class_to_allocnpages[sizeclass-1] &&
+                       allocsize/size == allocsize/runtime_class_to_size[sizeclass-1]) {
                        runtime_class_to_size[sizeclass-1] = size;
                        continue;
                }
@@ -119,7 +119,7 @@ runtime_InitSizes(void)
        // Double-check SizeToClass.
        if(0) {
                for(n=0; n < MaxSmallSize; n++) {
-                       sizeclass = SizeToClass(n);
+                       sizeclass = runtime_SizeToClass(n);
                        if(sizeclass < 1 || sizeclass >= NumSizeClasses || runtime_class_to_size[sizeclass] < n) {
                                runtime_printf("size=%d sizeclass=%d runtime_class_to_size=%d\n", n, sizeclass, runtime_class_to_size[sizeclass]);
                                runtime_printf("incorrect SizeToClass");
@@ -158,3 +158,18 @@ dump:
        }
        runtime_throw("InitSizes failed");
 }
+
+// Returns size of the memory block that mallocgc will allocate if you ask for the size.
+uintptr
+runtime_roundupsize(uintptr size)
+{
+       if(size < MaxSmallSize) {
+               if(size <= 1024-8)
+                       return runtime_class_to_size[runtime_size_to_class8[(size+7)>>3]];
+               else
+                       return runtime_class_to_size[runtime_size_to_class128[(size-1024+127) >> 7]];
+       }
+       if(size + PageSize < size)
+               return size;
+       return ROUND(size, PageSize);
+}
index 02705734dd8eb1637e08933db2585c9460a8a394..15dd58c07bcb70532e50265021ac2b770ec75057 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin dragonfly freebsd linux netbsd openbsd windows
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
 
 package net
 
@@ -24,21 +24,45 @@ package net
 // An implementation must call the following function to denote that the pd is ready.
 // void runtime_netpollready(G **gpp, PollDesc *pd, int32 mode);
 
+// PollDesc contains 2 binary semaphores, rg and wg, to park reader and writer
+// goroutines respectively. The semaphore can be in the following states:
+// READY - io readiness notification is pending;
+//         a goroutine consumes the notification by changing the state to nil.
+// WAIT - a goroutine prepares to park on the semaphore, but not yet parked;
+//        the goroutine commits to park by changing the state to G pointer,
+//        or, alternatively, concurrent io notification changes the state to READY,
+//        or, alternatively, concurrent timeout/close changes the state to nil.
+// G pointer - the goroutine is blocked on the semaphore;
+//             io notification or timeout/close changes the state to READY or nil respectively
+//             and unparks the goroutine.
+// nil - nothing of the above.
 #define READY ((G*)1)
+#define WAIT  ((G*)2)
+
+enum
+{
+       PollBlockSize   = 4*1024,
+};
 
 struct PollDesc
 {
        PollDesc* link; // in pollcache, protected by pollcache.Lock
+
+       // The lock protects pollOpen, pollSetDeadline, pollUnblock and deadlineimpl operations.
+       // This fully covers seq, rt and wt variables. fd is constant throughout the PollDesc lifetime.
+       // pollReset, pollWait, pollWaitCanceled and runtime_netpollready (IO rediness notification)
+       // proceed w/o taking the lock. So closing, rg, rd, wg and wd are manipulated
+       // in a lock-free way by all operations.
        Lock;           // protectes the following fields
        uintptr fd;
        bool    closing;
        uintptr seq;    // protects from stale timers and ready notifications
-       G*      rg;     // G waiting for read or READY (binary semaphore)
+       G*      rg;     // READY, WAIT, G waiting for read or nil
        Timer   rt;     // read deadline timer (set if rt.fv != nil)
        int64   rd;     // read deadline
-       G*      wg;     // the same for writes
-       Timer   wt;
-       int64   wd;
+       G*      wg;     // READY, WAIT, G waiting for write or nil
+       Timer   wt;     // write deadline timer
+       int64   wd;     // write deadline
 };
 
 static struct
@@ -52,7 +76,7 @@ static struct
        // seq is incremented when deadlines are changed or descriptor is reused.
 } pollcache;
 
-static bool    netpollblock(PollDesc*, int32);
+static bool    netpollblock(PollDesc*, int32, bool);
 static G*      netpollunblock(PollDesc*, int32, bool);
 static void    deadline(int64, Eface);
 static void    readDeadline(int64, Eface);
@@ -102,7 +126,6 @@ func runtime_pollClose(pd *PollDesc) {
 }
 
 func runtime_pollReset(pd *PollDesc, mode int) (err int) {
-       runtime_lock(pd);
        err = checkerr(pd, mode);
        if(err)
                goto ret;
@@ -111,14 +134,15 @@ func runtime_pollReset(pd *PollDesc, mode int) (err int) {
        else if(mode == 'w')
                pd->wg = nil;
 ret:
-       runtime_unlock(pd);
 }
 
 func runtime_pollWait(pd *PollDesc, mode int) (err int) {
-       runtime_lock(pd);
        err = checkerr(pd, mode);
        if(err == 0) {
-               while(!netpollblock(pd, mode)) {
+               // As for now only Solaris uses level-triggered IO.
+               if(Solaris)
+                       runtime_netpollarm(pd->fd, mode);
+               while(!netpollblock(pd, mode, false)) {
                        err = checkerr(pd, mode);
                        if(err != 0)
                                break;
@@ -127,15 +151,13 @@ func runtime_pollWait(pd *PollDesc, mode int) (err int) {
                        // Pretend it has not happened and retry.
                }
        }
-       runtime_unlock(pd);
 }
 
 func runtime_pollWaitCanceled(pd *PollDesc, mode int) {
-       runtime_lock(pd);
-       // wait for ioready, ignore closing or timeouts.
-       while(!netpollblock(pd, mode))
+       // This function is used only on windows after a failed attempt to cancel
+       // a pending async IO operation. Wait for ioready, ignore closing or timeouts.
+       while(!netpollblock(pd, mode, true))
                ;
-       runtime_unlock(pd);
 }
 
 func runtime_pollSetDeadline(pd *PollDesc, d int64, mode int) {
@@ -190,7 +212,7 @@ func runtime_pollSetDeadline(pd *PollDesc, d int64, mode int) {
        }
        // If we set the new deadline in the past, unblock currently pending IO if any.
        rg = nil;
-       wg = nil;
+       runtime_atomicstorep(&wg, nil);  // full memory barrier between stores to rd/wd and load of rg/wg in netpollunblock
        if(pd->rd < 0)
                rg = netpollunblock(pd, 'r', false);
        if(pd->wd < 0)
@@ -210,6 +232,7 @@ func runtime_pollUnblock(pd *PollDesc) {
                runtime_throw("runtime_pollUnblock: already closing");
        pd->closing = true;
        pd->seq++;
+       runtime_atomicstorep(&rg, nil);  // full memory barrier between store to closing and read of rg/wg in netpollunblock
        rg = netpollunblock(pd, 'r', false);
        wg = netpollunblock(pd, 'w', false);
        if(pd->rt.fv) {
@@ -240,12 +263,10 @@ runtime_netpollready(G **gpp, PollDesc *pd, int32 mode)
        G *rg, *wg;
 
        rg = wg = nil;
-       runtime_lock(pd);
        if(mode == 'r' || mode == 'r'+'w')
                rg = netpollunblock(pd, 'r', true);
        if(mode == 'w' || mode == 'r'+'w')
                wg = netpollunblock(pd, 'w', true);
-       runtime_unlock(pd);
        if(rg) {
                rg->schedlink = *gpp;
                *gpp = rg;
@@ -266,51 +287,75 @@ checkerr(PollDesc *pd, int32 mode)
        return 0;
 }
 
+static bool
+blockcommit(G *gp, G **gpp)
+{
+       return runtime_casp(gpp, WAIT, gp);
+}
+
 // returns true if IO is ready, or false if timedout or closed
+// waitio - wait only for completed IO, ignore errors
 static bool
-netpollblock(PollDesc *pd, int32 mode)
+netpollblock(PollDesc *pd, int32 mode, bool waitio)
 {
-       G **gpp;
+       G **gpp, *old;
 
        gpp = &pd->rg;
        if(mode == 'w')
                gpp = &pd->wg;
-       if(*gpp == READY) {
-               *gpp = nil;
-               return true;
+
+       // set the gpp semaphore to WAIT
+       for(;;) {
+               old = *gpp;
+               if(old == READY) {
+                       *gpp = nil;
+                       return true;
+               }
+               if(old != nil)
+                       runtime_throw("netpollblock: double wait");
+               if(runtime_casp(gpp, nil, WAIT))
+                       break;
        }
-       if(*gpp != nil)
-               runtime_throw("netpollblock: double wait");
-       *gpp = runtime_g();
-       runtime_park(runtime_unlock, &pd->Lock, "IO wait");
-       runtime_lock(pd);
-       if(runtime_g()->param)
-               return true;
-       return false;
+
+       // need to recheck error states after setting gpp to WAIT
+       // this is necessary because runtime_pollUnblock/runtime_pollSetDeadline/deadlineimpl
+       // do the opposite: store to closing/rd/wd, membarrier, load of rg/wg
+       if(waitio || checkerr(pd, mode) == 0)
+               runtime_park((bool(*)(G*, void*))blockcommit, gpp, "IO wait");
+       // be careful to not lose concurrent READY notification
+       old = runtime_xchgp(gpp, nil);
+       if(old > WAIT)
+               runtime_throw("netpollblock: corrupted state");
+       return old == READY;
 }
 
 static G*
 netpollunblock(PollDesc *pd, int32 mode, bool ioready)
 {
-       G **gpp, *old;
+       G **gpp, *old, *new;
 
        gpp = &pd->rg;
        if(mode == 'w')
                gpp = &pd->wg;
-       if(*gpp == READY)
-               return nil;
-       if(*gpp == nil) {
-               // Only set READY for ioready. runtime_pollWait
-               // will check for timeout/cancel before waiting.
+
+       for(;;) {
+               old = *gpp;
+               if(old == READY)
+                       return nil;
+               if(old == nil && !ioready) {
+                       // Only set READY for ioready. runtime_pollWait
+                       // will check for timeout/cancel before waiting.
+                       return nil;
+               }
+               new = nil;
                if(ioready)
-                       *gpp = READY;
-               return nil;
+                       new = READY;
+               if(runtime_casp(gpp, old, new))
+                       break;
        }
-       old = *gpp;
-       // pass unblock reason onto blocked g
-       old->param = (void*)(uintptr)ioready;
-       *gpp = nil;
-       return old;
+       if(old > WAIT)
+               return old;  // must be G*
+       return nil;
 }
 
 static void
@@ -336,14 +381,14 @@ deadlineimpl(int64 now, Eface arg, bool read, bool write)
                if(pd->rd <= 0 || pd->rt.fv == nil)
                        runtime_throw("deadlineimpl: inconsistent read deadline");
                pd->rd = -1;
-               pd->rt.fv = nil;
+               runtime_atomicstorep(&pd->rt.fv, nil);  // full memory barrier between store to rd and load of rg in netpollunblock
                rg = netpollunblock(pd, 'r', false);
        }
        if(write) {
                if(pd->wd <= 0 || (pd->wt.fv == nil && !read))
                        runtime_throw("deadlineimpl: inconsistent write deadline");
                pd->wd = -1;
-               pd->wt.fv = nil;
+               runtime_atomicstorep(&pd->wt.fv, nil);  // full memory barrier between store to wd and load of wg in netpollunblock
                wg = netpollunblock(pd, 'w', false);
        }
        runtime_unlock(pd);
@@ -379,7 +424,7 @@ allocPollDesc(void)
 
        runtime_lock(&pollcache);
        if(pollcache.first == nil) {
-               n = PageSize/sizeof(*pd);
+               n = PollBlockSize/sizeof(*pd);
                if(n == 0)
                        n = 1;
                // Must be in non-GC memory because can be referenced
index 2acbca32322151c38ae30106c22fecac2801d2fb..fe534c9591d061b27870a5d146187535be45e34a 100644 (file)
@@ -116,6 +116,14 @@ runtime_netpollclose(uintptr fd)
        return -res;
 }
 
+void
+runtime_netpollarm(uintptr fd, int32 mode)
+{
+       USED(fd);
+       USED(mode);
+       runtime_throw("unused");
+}
+
 // polls for ready network connections
 // returns list of goroutines that become runnable
 G*
@@ -159,7 +167,8 @@ retry:
 }
 
 void
-runtime_netpoll_scan(void (*addroot)(Obj))
+runtime_netpoll_scan(struct Workbuf** wbufp, void (*enqueue1)(struct Workbuf**, Obj))
 {
-       USED(addroot);
+       USED(wbufp);
+       USED(enqueue1);
 }
index 5d3f85617b6d1325d9c7aa61563bd14b9946c493..bc38644ac78ecfd9593e820a5a9e107d970a065c 100644 (file)
@@ -59,6 +59,13 @@ runtime_netpollclose(uintptr fd)
        return 0;
 }
 
+void
+runtime_netpollarm(uintptr fd, int32 mode)
+{
+       USED(fd, mode);
+       runtime_throw("unused");
+}
+
 // Polls for ready network connections.
 // Returns list of goroutines that become runnable.
 G*
@@ -104,7 +111,8 @@ retry:
 }
 
 void
-runtime_netpoll_scan(void (*addroot)(Obj))
+runtime_netpoll_scan(struct Workbuf** wbufp, void (*enqueue1)(struct Workbuf**, Obj))
 {
-       USED(addroot);
+       USED(wbufp);
+       USED(enqueue1);
 }
index 788d19f6190441e0a9d170498ec71724de0e5181..b46133591184c7cdc7ef1e78676b0515dc7243c4 100644 (file)
@@ -246,7 +246,7 @@ runtime_netpoll(bool block)
 }
 
 void
-runtime_netpoll_scan(void (*addroot)(Obj))
+runtime_netpoll_scan(struct Workbuf** wbufp, void (*enqueue1)(struct Workbuf**, Obj))
 {
-       addroot((Obj){(byte*)&data, sizeof data, 0});
+       enqueue1(wbufp, (Obj){(byte*)&data, sizeof data, 0});
 }
index a88c9f5b9c2d4bd1bfb7ece1370818ef70177af6..468a610f6f9d42f054dc3d7cbcc540105be33e24 100644 (file)
@@ -19,7 +19,8 @@ runtime_netpoll(bool block)
 }
 
 void
-runtime_netpoll_scan(void (*addroot)(Obj))
+runtime_netpoll_scan(struct Workbuf** wbufp, void (*enqueue1)(struct Workbuf**, Obj))
 {
+       USED(wbufp);
        USED(addroot);
 }
index 8fe321f6af2de675268a7ee3b246dd82db406d4e..78d4dd948c6506bb0c32af26f082489a683492ca 100644 (file)
 uint32 runtime_panicking;
 static Lock paniclk;
 
+// Allocate a Defer, usually using per-P pool.
+// Each defer must be released with freedefer.
+Defer*
+runtime_newdefer()
+{
+       Defer *d;
+       P *p;
+
+       d = nil;
+       p = runtime_m()->p;
+       d = p->deferpool;
+       if(d)
+               p->deferpool = d->__next;
+       if(d == nil) {
+               // deferpool is empty
+               d = runtime_malloc(sizeof(Defer));
+       }
+       return d;
+}
+
+// Free the given defer.
+// The defer cannot be used after this call.
+void
+runtime_freedefer(Defer *d)
+{
+       P *p;
+
+       if(d->__special)
+               return;
+       p = runtime_m()->p;
+       d->__next = p->deferpool;
+       p->deferpool = d;
+       // No need to wipe out pointers in argp/pc/fn/args,
+       // because we empty the pool before GC.
+}
+
 // Run all deferred functions for the current goroutine.
 static void
 rundefer(void)
@@ -28,8 +64,7 @@ rundefer(void)
                d->__pfn = nil;
                if (pfn != nil)
                        (*pfn)(d->__arg);
-               if (d->__free)
-                 runtime_free(d);
+               runtime_freedefer(d);
        }
 }
 
@@ -44,18 +79,34 @@ runtime_startpanic(void)
                m->mallocing = 1; // tell rest of panic not to try to malloc
        } else if(m->mcache == nil) // can happen if called from signal handler or throw
                m->mcache = runtime_allocmcache();
-       if(m->dying) {
+       switch(m->dying) {
+       case 0:
+               m->dying = 1;
+               if(runtime_g() != nil)
+                       runtime_g()->writebuf = nil;
+               runtime_xadd(&runtime_panicking, 1);
+               runtime_lock(&paniclk);
+               if(runtime_debug.schedtrace > 0 || runtime_debug.scheddetail > 0)
+                       runtime_schedtrace(true);
+               runtime_freezetheworld();
+               return;
+       case 1:
+               // Something failed while panicing, probably the print of the
+               // argument to panic().  Just print a stack trace and exit.
+               m->dying = 2;
                runtime_printf("panic during panic\n");
+               runtime_dopanic(0);
                runtime_exit(3);
+       case 2:
+               // This is a genuine bug in the runtime, we couldn't even
+               // print the stack trace successfully.
+               m->dying = 3;
+               runtime_printf("stack trace unavailable\n");
+               runtime_exit(4);
+       default:
+               // Can't even print!  Just exit.
+               runtime_exit(5);
        }
-       m->dying = 1;
-       if(runtime_g() != nil)
-               runtime_g()->writebuf = nil;
-       runtime_xadd(&runtime_panicking, 1);
-       runtime_lock(&paniclk);
-       if(runtime_debug.schedtrace > 0 || runtime_debug.scheddetail > 0)
-               runtime_schedtrace(true);
-       runtime_freezetheworld();
 }
 
 void
index c627ac1d5d36037896a22ff5a07884fb2a1000e0..1e1551989cbef7b7eeefeff390d951d6a46fc47d 100644 (file)
@@ -392,17 +392,23 @@ struct Sched {
        int32   profilehz;      // cpu profiling rate
 };
 
-// The max value of GOMAXPROCS.
-// There are no fundamental restrictions on the value.
-enum { MaxGomaxprocs = 1<<8 };
+enum
+{
+       // The max value of GOMAXPROCS.
+       // There are no fundamental restrictions on the value.
+       MaxGomaxprocs = 1<<8,
+
+       // Number of goroutine ids to grab from runtime_sched.goidgen to local per-P cache at once.
+       // 16 seems to provide enough amortization, but other than that it's mostly arbitrary number.
+       GoidCacheBatch = 16,
+};
 
 Sched  runtime_sched;
 int32  runtime_gomaxprocs;
 uint32 runtime_needextram = 1;
 bool   runtime_iscgo = true;
 M      runtime_m0;
-G      runtime_g0;      // idle goroutine for m0
-G*     runtime_allg;
+G      runtime_g0;     // idle goroutine for m0
 G*     runtime_lastg;
 M*     runtime_allm;
 P**    runtime_allp;
@@ -412,10 +418,15 @@ int32     runtime_ncpu;
 bool   runtime_precisestack;
 static int32   newprocs;
 
+static Lock allglock;  // the following vars are protected by this lock or by stoptheworld
+G**    runtime_allg;
+uintptr runtime_allglen;
+static uintptr allgcap;
+
 void* runtime_mstart(void*);
 static void runqput(P*, G*);
 static G* runqget(P*);
-static void runqgrow(P*);
+static bool runqputslow(P*, G*, uint32, uint32);
 static G* runqsteal(P*, P*);
 static void mput(M*);
 static M* mget(void);
@@ -442,12 +453,14 @@ static void gfput(P*, G*);
 static G* gfget(P*);
 static void gfpurge(P*);
 static void globrunqput(G*);
+static void globrunqputbatch(G*, G*, int32);
 static G* globrunqget(P*, int32);
 static P* pidleget(void);
 static void pidleput(P*);
 static void injectglist(G*);
 static bool preemptall(void);
 static bool exitsyscallfast(void);
+static void allgadd(G*);
 
 // The bootstrap sequence is:
 //
@@ -476,7 +489,6 @@ runtime_schedinit(void)
        runtime_sched.maxmcount = 10000;
        runtime_precisestack = 0;
 
-       runtime_mprofinit();
        runtime_mallocinit();
        mcommoninit(m);
        
@@ -541,7 +553,7 @@ runtime_main(void* dummy __attribute__((unused)))
        d.__retaddr = nil;
        d.__makefunc_can_recover = 0;
        d.__frame = &frame;
-       d.__free = 0;
+       d.__special = true;
        g->defer = &d;
 
        if(m != &runtime_m0)
@@ -579,6 +591,7 @@ void
 runtime_goroutineheader(G *gp)
 {
        const char *status;
+       int64 waitfor;
 
        switch(gp->status) {
        case Gidle:
@@ -603,7 +616,16 @@ runtime_goroutineheader(G *gp)
                status = "???";
                break;
        }
-       runtime_printf("goroutine %D [%s]:\n", gp->goid, status);
+
+       // approx time the G is blocked, in minutes
+       waitfor = 0;
+       if((gp->status == Gwaiting || gp->status == Gsyscall) && gp->waitsince != 0)
+               waitfor = (runtime_nanotime() - gp->waitsince) / (60LL*1000*1000*1000);
+
+       if(waitfor < 1)
+               runtime_printf("goroutine %D [%s]:\n", gp->goid, status);
+       else
+               runtime_printf("goroutine %D [%s, %D minutes]:\n", gp->goid, status, waitfor);
 }
 
 void
@@ -624,7 +646,7 @@ runtime_printcreatedby(G *g)
 struct Traceback
 {
        G* gp;
-       Location locbuf[100];
+       Location locbuf[TracebackMaxFrames];
        int32 c;
 };
 
@@ -634,6 +656,7 @@ runtime_tracebackothers(G * volatile me)
        G * volatile gp;
        Traceback tb;
        int32 traceback;
+       volatile uintptr i;
 
        tb.gp = me;
        traceback = runtime_gotraceback(nil);
@@ -657,7 +680,9 @@ runtime_tracebackothers(G * volatile me)
                runtime_printcreatedby(gp);
        }
 
-       for(gp = runtime_allg; gp != nil; gp = gp->alllink) {
+       runtime_lock(&allglock);
+       for(i = 0; i < runtime_allglen; i++) {
+               gp = runtime_allg[i];
                if(gp == me || gp == m->curg || gp->status == Gdead)
                        continue;
                if(gp->issystem && traceback < 2)
@@ -696,6 +721,7 @@ runtime_tracebackothers(G * volatile me)
                        runtime_printcreatedby(gp);
                }
        }
+       runtime_unlock(&allglock);
 }
 
 static void
@@ -1038,6 +1064,7 @@ struct CgoThreadStart
 {
        M *m;
        G *g;
+       uintptr *tls;
        void (*fn)(void);
 };
 
@@ -1200,14 +1227,7 @@ runtime_newextram(void)
        gp->lockedm = mp;
        gp->goid = runtime_xadd64(&runtime_sched.goidgen, 1);
        // put on allg for garbage collector
-       runtime_lock(&runtime_sched);
-       if(runtime_lastg == nil)
-               runtime_allg = gp;
-       else
-               runtime_lastg->alllink = gp;
-       runtime_lastg = gp;
-       runtime_unlock(&runtime_sched);
-       gp->goid = runtime_xadd64(&runtime_sched.goidgen, 1);
+       allgadd(gp);
 
        // The context for gp will be set up in runtime_needm.  But
        // here we need to set up the context for g0.
@@ -1379,7 +1399,7 @@ mspinning(void)
 }
 
 // Schedules some M to run the p (creates an M if necessary).
-// If p==nil, tries to get an idle P, if no idle P's returns false.
+// If p==nil, tries to get an idle P, if no idle P's does nothing.
 static void
 startm(P *p, bool spinning)
 {
@@ -1543,6 +1563,7 @@ execute(G *gp)
                runtime_throw("execute: bad g status");
        }
        gp->status = Grunning;
+       gp->waitsince = 0;
        m->p->schedtick++;
        m->curg = gp;
        gp->m = m;
@@ -1760,10 +1781,10 @@ top:
        execute(gp);
 }
 
-// Puts the current goroutine into a waiting state and unlocks the lock.
-// The goroutine can be made runnable again by calling runtime_ready(gp).
+// Puts the current goroutine into a waiting state and calls unlockf.
+// If unlockf returns false, the goroutine is resumed.
 void
-runtime_park(void(*unlockf)(Lock*), Lock *lock, const char *reason)
+runtime_park(bool(*unlockf)(G*, void*), void *lock, const char *reason)
 {
        m->waitlock = lock;
        m->waitunlockf = unlockf;
@@ -1771,17 +1792,39 @@ runtime_park(void(*unlockf)(Lock*), Lock *lock, const char *reason)
        runtime_mcall(park0);
 }
 
+static bool
+parkunlock(G *gp, void *lock)
+{
+       USED(gp);
+       runtime_unlock(lock);
+       return true;
+}
+
+// Puts the current goroutine into a waiting state and unlocks the lock.
+// The goroutine can be made runnable again by calling runtime_ready(gp).
+void
+runtime_parkunlock(Lock *lock, const char *reason)
+{
+       runtime_park(parkunlock, lock, reason);
+}
+
 // runtime_park continuation on g0.
 static void
 park0(G *gp)
 {
+       bool ok;
+
        gp->status = Gwaiting;
        gp->m = nil;
        m->curg = nil;
        if(m->waitunlockf) {
-               m->waitunlockf(m->waitlock);
+               ok = m->waitunlockf(gp, m->waitlock);
                m->waitunlockf = nil;
                m->waitlock = nil;
+               if(!ok) {
+                       gp->status = Grunnable;
+                       execute(gp);  // Schedule it back, never returns.
+               }
        }
        if(m->lockedg) {
                stoplockedm();
@@ -1968,6 +2011,7 @@ runtime_exitsyscall(void)
        if(gp->isbackground)  // do not consider blocked scavenger for deadlock detection
                incidlelocked(-1);
 
+       g->waitsince = 0;
        if(exitsyscallfast()) {
                // There's a cpu for us, so we can run.
                m->p->syscalltick++;
@@ -2160,11 +2204,13 @@ __go_go(void (*fn)(void*), void* arg)
        byte *sp;
        size_t spsize;
        G *newg;
+       P *p;
 
 //runtime_printf("newproc1 %p %p narg=%d nret=%d\n", fn->fn, argp, narg, nret);
        m->locks++;  // disable preemption because it can be holding p in a local var
 
-       if((newg = gfget(m->p)) != nil) {
+       p = m->p;
+       if((newg = gfget(p)) != nil) {
 #ifdef USING_SPLIT_STACK
                int dont_block_signals = 0;
 
@@ -2181,20 +2227,18 @@ __go_go(void (*fn)(void*), void* arg)
 #endif
        } else {
                newg = runtime_malg(StackMin, &sp, &spsize);
-               runtime_lock(&runtime_sched);
-               if(runtime_lastg == nil)
-                       runtime_allg = newg;
-               else
-                       runtime_lastg->alllink = newg;
-               runtime_lastg = newg;
-               runtime_unlock(&runtime_sched);
+               allgadd(newg);
        }
 
        newg->entry = (byte*)fn;
        newg->param = arg;
        newg->gopc = (uintptr)__builtin_return_address(0);
        newg->status = Grunnable;
-       newg->goid = runtime_xadd64(&runtime_sched.goidgen, 1);
+       if(p->goidcache == p->goidcacheend) {
+               p->goidcache = runtime_xadd64(&runtime_sched.goidgen, GoidCacheBatch);
+               p->goidcacheend = p->goidcache + GoidCacheBatch;
+       }
+       newg->goid = p->goidcache++;
 
        {
                // Avoid warnings about variables clobbered by
@@ -2211,7 +2255,7 @@ __go_go(void (*fn)(void*), void* arg)
                vnewg->context.uc_stack.ss_size = vspsize;
                makecontext(&vnewg->context, kickoff, 0);
 
-               runqput(m->p, vnewg);
+               runqput(p, vnewg);
 
                if(runtime_atomicload(&runtime_sched.npidle) != 0 && runtime_atomicload(&runtime_sched.nmspinning) == 0 && fn != runtime_main)  // TODO: fast atomic
                        wakep();
@@ -2220,6 +2264,31 @@ __go_go(void (*fn)(void*), void* arg)
        }
 }
 
+static void
+allgadd(G *gp)
+{
+       G **new;
+       uintptr cap;
+
+       runtime_lock(&allglock);
+       if(runtime_allglen >= allgcap) {
+               cap = 4096/sizeof(new[0]);
+               if(cap < 2*allgcap)
+                       cap = 2*allgcap;
+               new = runtime_malloc(cap*sizeof(new[0]));
+               if(new == nil)
+                       runtime_throw("runtime: cannot allocate memory");
+               if(runtime_allg != nil) {
+                       runtime_memmove(new, runtime_allg, runtime_allglen*sizeof(new[0]));
+                       runtime_free(runtime_allg);
+               }
+               runtime_allg = new;
+               allgcap = cap;
+       }
+       runtime_allg[runtime_allglen++] = gp;
+       runtime_unlock(&allglock);
+}
+
 // Put on gfree list.
 // If local list is too long, transfer a batch to the global list.
 static void
@@ -2415,19 +2484,21 @@ runtime_gcount(void)
 {
        G *gp;
        int32 n, s;
+       uintptr i;
 
        n = 0;
-       runtime_lock(&runtime_sched);
+       runtime_lock(&allglock);
        // TODO(dvyukov): runtime.NumGoroutine() is O(N).
        // We do not want to increment/decrement centralized counter in newproc/goexit,
        // just to make runtime.NumGoroutine() faster.
        // Compromise solution is to introduce per-P counters of active goroutines.
-       for(gp = runtime_allg; gp; gp = gp->alllink) {
+       for(i = 0; i < runtime_allglen; i++) {
+               gp = runtime_allg[i];
                s = gp->status;
                if(s == Grunnable || s == Grunning || s == Gsyscall || s == Gwaiting)
                        n++;
        }
-       runtime_unlock(&runtime_sched);
+       runtime_unlock(&allglock);
        return n;
 }
 
@@ -2441,32 +2512,39 @@ static struct {
        Lock;
        void (*fn)(uintptr*, int32);
        int32 hz;
-       uintptr pcbuf[100];
-       Location locbuf[100];
+       uintptr pcbuf[TracebackMaxFrames];
+       Location locbuf[TracebackMaxFrames];
 } prof;
 
-static void
-System(void)
-{
-}
+static void System(void) {}
+static void GC(void) {}
 
 // Called if we receive a SIGPROF signal.
 void
 runtime_sigprof()
 {
+       M *mp = m;
        int32 n, i;
        bool traceback;
 
        if(prof.fn == nil || prof.hz == 0)
                return;
+
+       if(mp == nil)
+               return;
+
        traceback = true;
-       // Windows does profiling in a dedicated thread w/o m.
-       if(!Windows && (m == nil || m->mcache == nil))
+
+       if(mp->mcache == nil)
                traceback = false;
-       
+
+       // Profiling runs concurrently with GC, so it must not allocate.
+       mp->mallocing++;
+
        runtime_lock(&prof);
        if(prof.fn == nil) {
                runtime_unlock(&prof);
+               mp->mallocing--;
                return;
        }
        n = 0;
@@ -2484,13 +2562,17 @@ runtime_sigprof()
                for(i = 0; i < n; i++)
                        prof.pcbuf[i] = prof.locbuf[i].pc;
        }
-       if (!traceback || n <= 0) {
+       if(!traceback || n <= 0) {
                n = 2;
                prof.pcbuf[0] = (uintptr)runtime_getcallerpc(&n);
-               prof.pcbuf[1] = (uintptr)System + 1;
+               if(mp->gcing || mp->helpgc)
+                       prof.pcbuf[1] = (uintptr)GC;
+               else
+                       prof.pcbuf[1] = (uintptr)System;
        }
        prof.fn(prof.pcbuf, n);
        runtime_unlock(&prof);
+       mp->mallocing--;
 }
 
 // Arrange to call fn with a traceback hz times a second.
@@ -2533,6 +2615,7 @@ static void
 procresize(int32 new)
 {
        int32 i, old;
+       bool empty;
        G *gp;
        P *p;
 
@@ -2554,27 +2637,42 @@ procresize(int32 new)
                        else
                                p->mcache = runtime_allocmcache();
                }
-               if(p->runq == nil) {
-                       p->runqsize = 128;
-                       p->runq = (G**)runtime_mallocgc(p->runqsize*sizeof(G*), 0, FlagNoInvokeGC);
-               }
        }
 
        // redistribute runnable G's evenly
-       for(i = 0; i < old; i++) {
-               p = runtime_allp[i];
-               while((gp = runqget(p)) != nil)
-                       globrunqput(gp);
+       // collect all runnable goroutines in global queue preserving FIFO order
+       // FIFO order is required to ensure fairness even during frequent GCs
+       // see http://golang.org/issue/7126
+       empty = false;
+       while(!empty) {
+               empty = true;
+               for(i = 0; i < old; i++) {
+                       p = runtime_allp[i];
+                       if(p->runqhead == p->runqtail)
+                               continue;
+                       empty = false;
+                       // pop from tail of local queue
+                       p->runqtail--;
+                       gp = p->runq[p->runqtail%nelem(p->runq)];
+                       // push onto head of global queue
+                       gp->schedlink = runtime_sched.runqhead;
+                       runtime_sched.runqhead = gp;
+                       if(runtime_sched.runqtail == nil)
+                               runtime_sched.runqtail = gp;
+                       runtime_sched.runqsize++;
+               }
        }
+       // fill local queues with at most nelem(p->runq)/2 goroutines
        // start at 1 because current M already executes some G and will acquire allp[0] below,
        // so if we have a spare G we want to put it into allp[1].
-       for(i = 1; runtime_sched.runqhead; i++) {
+       for(i = 1; (uint32)i < (uint32)new * nelem(p->runq)/2 && runtime_sched.runqsize > 0; i++) {
                gp = runtime_sched.runqhead;
                runtime_sched.runqhead = gp->schedlink;
+               if(runtime_sched.runqhead == nil)
+                       runtime_sched.runqtail = nil;
+               runtime_sched.runqsize--;
                runqput(runtime_allp[i%new], gp);
        }
-       runtime_sched.runqtail = nil;
-       runtime_sched.runqsize = 0;
 
        // free unused P's
        for(i = new; i < old; i++) {
@@ -2656,28 +2754,39 @@ checkdead(void)
 {
        G *gp;
        int32 run, grunning, s;
+       uintptr i;
 
        // -1 for sysmon
        run = runtime_sched.mcount - runtime_sched.nmidle - runtime_sched.nmidlelocked - 1 - countextra();
        if(run > 0)
                return;
+       // If we are dying because of a signal caught on an already idle thread,
+       // freezetheworld will cause all running threads to block.
+       // And runtime will essentially enter into deadlock state,
+       // except that there is a thread that will call runtime_exit soon.
+       if(runtime_panicking > 0)
+               return;
        if(run < 0) {
-               runtime_printf("checkdead: nmidle=%d nmidlelocked=%d mcount=%d\n",
+               runtime_printf("runtime: checkdead: nmidle=%d nmidlelocked=%d mcount=%d\n",
                        runtime_sched.nmidle, runtime_sched.nmidlelocked, runtime_sched.mcount);
                runtime_throw("checkdead: inconsistent counts");
        }
        grunning = 0;
-       for(gp = runtime_allg; gp; gp = gp->alllink) {
+       runtime_lock(&allglock);
+       for(i = 0; i < runtime_allglen; i++) {
+               gp = runtime_allg[i];
                if(gp->isbackground)
                        continue;
                s = gp->status;
                if(s == Gwaiting)
                        grunning++;
                else if(s == Grunnable || s == Grunning || s == Gsyscall) {
-                       runtime_printf("checkdead: find g %D in status %d\n", gp->goid, s);
+                       runtime_unlock(&allglock);
+                       runtime_printf("runtime: checkdead: find g %D in status %d\n", gp->goid, s);
                        runtime_throw("checkdead: runnable g");
                }
        }
+       runtime_unlock(&allglock);
        if(grunning == 0)  // possible if main goroutine calls runtime_Goexit()
                runtime_exit(0);
        m->throwing = -1;  // do not dump full stacks
@@ -2774,16 +2883,19 @@ retake(int64 now)
                pd = &pdesc[i];
                s = p->status;
                if(s == Psyscall) {
-                       // Retake P from syscall if it's there for more than 1 sysmon tick (20us).
-                       // But only if there is other work to do.
+                       // Retake P from syscall if it's there for more than 1 sysmon tick (at least 20us).
                        t = p->syscalltick;
                        if(pd->syscalltick != t) {
                                pd->syscalltick = t;
                                pd->syscallwhen = now;
                                continue;
                        }
+                       // On the one hand we don't want to retake Ps if there is no other work to do,
+                       // but on the other hand we want to retake them eventually
+                       // because they can prevent the sysmon thread from deep sleep.
                        if(p->runqhead == p->runqtail &&
-                               runtime_atomicload(&runtime_sched.nmspinning) + runtime_atomicload(&runtime_sched.npidle) > 0)
+                               runtime_atomicload(&runtime_sched.nmspinning) + runtime_atomicload(&runtime_sched.npidle) > 0 &&
+                               pd->syscallwhen + 10*1000*1000 > now)
                                continue;
                        // Need to decrement number of idle locked M's
                        // (pretending that one more is running) before the CAS.
@@ -2828,7 +2940,8 @@ runtime_schedtrace(bool detailed)
        static int64 starttime;
        int64 now;
        int64 id1, id2, id3;
-       int32 i, q, t, h, s;
+       int32 i, t, h;
+       uintptr gi;
        const char *fmt;
        M *mp, *lockedm;
        G *gp, *lockedg;
@@ -2855,15 +2968,11 @@ runtime_schedtrace(bool detailed)
                if(p == nil)
                        continue;
                mp = p->m;
-               t = p->runqtail;
-               h = p->runqhead;
-               s = p->runqsize;
-               q = t - h;
-               if(q < 0)
-                       q += s;
+               h = runtime_atomicload(&p->runqhead);
+               t = runtime_atomicload(&p->runqtail);
                if(detailed)
-                       runtime_printf("  P%d: status=%d schedtick=%d syscalltick=%d m=%d runqsize=%d/%d gfreecnt=%d\n",
-                               i, p->status, p->schedtick, p->syscalltick, mp ? mp->id : -1, q, s, p->gfreecnt);
+                       runtime_printf("  P%d: status=%d schedtick=%d syscalltick=%d m=%d runqsize=%d gfreecnt=%d\n",
+                               i, p->status, p->schedtick, p->syscalltick, mp ? mp->id : -1, t-h, p->gfreecnt);
                else {
                        // In non-detailed mode format lengths of per-P run queues as:
                        // [len1 len2 len3 len4]
@@ -2874,7 +2983,7 @@ runtime_schedtrace(bool detailed)
                                fmt = " [%d";
                        else if(i == runtime_gomaxprocs-1)
                                fmt = " %d]\n";
-                       runtime_printf(fmt, q);
+                       runtime_printf(fmt, t-h);
                }
        }
        if(!detailed) {
@@ -2895,18 +3004,21 @@ runtime_schedtrace(bool detailed)
                if(lockedg)
                        id3 = lockedg->goid;
                runtime_printf("  M%d: p=%D curg=%D mallocing=%d throwing=%d gcing=%d"
-                       " locks=%d dying=%d helpgc=%d spinning=%d lockedg=%D\n",
+                       " locks=%d dying=%d helpgc=%d spinning=%d blocked=%d lockedg=%D\n",
                        mp->id, id1, id2,
                        mp->mallocing, mp->throwing, mp->gcing, mp->locks, mp->dying, mp->helpgc,
-                       mp->spinning, id3);
+                       mp->spinning, m->blocked, id3);
        }
-       for(gp = runtime_allg; gp; gp = gp->alllink) {
+       runtime_lock(&allglock);
+       for(gi = 0; gi < runtime_allglen; gi++) {
+               gp = runtime_allg[gi];
                mp = gp->m;
                lockedm = gp->lockedm;
                runtime_printf("  G%D: status=%d(%s) m=%d lockedm=%d\n",
                        gp->goid, gp->status, gp->waitreason, mp ? mp->id : -1,
                        lockedm ? lockedm->id : -1);
        }
+       runtime_unlock(&allglock);
        runtime_unlock(&runtime_sched);
 }
 
@@ -2949,6 +3061,20 @@ globrunqput(G *gp)
        runtime_sched.runqsize++;
 }
 
+// Put a batch of runnable goroutines on the global runnable queue.
+// Sched must be locked.
+static void
+globrunqputbatch(G *ghead, G *gtail, int32 n)
+{
+       gtail->schedlink = nil;
+       if(runtime_sched.runqtail)
+               runtime_sched.runqtail->schedlink = ghead;
+       else
+               runtime_sched.runqhead = ghead;
+       runtime_sched.runqtail = gtail;
+       runtime_sched.runqsize += n;
+}
+
 // Try get a batch of G's from the global runnable queue.
 // Sched must be locked.
 static G*
@@ -2964,6 +3090,8 @@ globrunqget(P *p, int32 max)
                n = runtime_sched.runqsize;
        if(max > 0 && n > max)
                n = max;
+       if((uint32)n > nelem(p->runq)/2)
+               n = nelem(p->runq)/2;
        runtime_sched.runqsize -= n;
        if(runtime_sched.runqsize == 0)
                runtime_sched.runqtail = nil;
@@ -3003,78 +3131,98 @@ pidleget(void)
        return p;
 }
 
-// Put g on local runnable queue.
-// TODO(dvyukov): consider using lock-free queue.
+// Try to put g on local runnable queue.
+// If it's full, put onto global queue.
+// Executed only by the owner P.
 static void
 runqput(P *p, G *gp)
 {
-       int32 h, t, s;
+       uint32 h, t;
 
-       runtime_lock(p);
 retry:
-       h = p->runqhead;
+       h = runtime_atomicload(&p->runqhead);  // load-acquire, synchronize with consumers
        t = p->runqtail;
-       s = p->runqsize;
-       if(t == h-1 || (h == 0 && t == s-1)) {
-               runqgrow(p);
-               goto retry;
+       if(t - h < nelem(p->runq)) {
+               p->runq[t%nelem(p->runq)] = gp;
+               runtime_atomicstore(&p->runqtail, t+1);  // store-release, makes the item available for consumption
+               return;
        }
-       p->runq[t++] = gp;
-       if(t == s)
-               t = 0;
-       p->runqtail = t;
-       runtime_unlock(p);
+       if(runqputslow(p, gp, h, t))
+               return;
+       // the queue is not full, now the put above must suceed
+       goto retry;
+}
+
+// Put g and a batch of work from local runnable queue on global queue.
+// Executed only by the owner P.
+static bool
+runqputslow(P *p, G *gp, uint32 h, uint32 t)
+{
+       G *batch[nelem(p->runq)/2+1];
+       uint32 n, i;
+
+       // First, grab a batch from local queue.
+       n = t-h;
+       n = n/2;
+       if(n != nelem(p->runq)/2)
+               runtime_throw("runqputslow: queue is not full");
+       for(i=0; i<n; i++)
+               batch[i] = p->runq[(h+i)%nelem(p->runq)];
+       if(!runtime_cas(&p->runqhead, h, h+n))  // cas-release, commits consume
+               return false;
+       batch[n] = gp;
+       // Link the goroutines.
+       for(i=0; i<n; i++)
+               batch[i]->schedlink = batch[i+1];
+       // Now put the batch on global queue.
+       runtime_lock(&runtime_sched);
+       globrunqputbatch(batch[0], batch[n], n+1);
+       runtime_unlock(&runtime_sched);
+       return true;
 }
 
 // Get g from local runnable queue.
+// Executed only by the owner P.
 static G*
 runqget(P *p)
 {
        G *gp;
-       int32 t, h, s;
+       uint32 t, h;
 
-       if(p->runqhead == p->runqtail)
-               return nil;
-       runtime_lock(p);
-       h = p->runqhead;
-       t = p->runqtail;
-       s = p->runqsize;
-       if(t == h) {
-               runtime_unlock(p);
-               return nil;
+       for(;;) {
+               h = runtime_atomicload(&p->runqhead);  // load-acquire, synchronize with other consumers
+               t = p->runqtail;
+               if(t == h)
+                       return nil;
+               gp = p->runq[h%nelem(p->runq)];
+               if(runtime_cas(&p->runqhead, h, h+1))  // cas-release, commits consume
+                       return gp;
        }
-       gp = p->runq[h++];
-       if(h == s)
-               h = 0;
-       p->runqhead = h;
-       runtime_unlock(p);
-       return gp;
 }
 
-// Grow local runnable queue.
-// TODO(dvyukov): consider using fixed-size array
-// and transfer excess to the global list (local queue can grow way too big).
-static void
-runqgrow(P *p)
+// Grabs a batch of goroutines from local runnable queue.
+// batch array must be of size nelem(p->runq)/2. Returns number of grabbed goroutines.
+// Can be executed by any P.
+static uint32
+runqgrab(P *p, G **batch)
 {
-       G **q;
-       int32 s, t, h, t2;
+       uint32 t, h, n, i;
 
-       h = p->runqhead;
-       t = p->runqtail;
-       s = p->runqsize;
-       t2 = 0;
-       q = runtime_malloc(2*s*sizeof(*q));
-       while(t != h) {
-               q[t2++] = p->runq[h++];
-               if(h == s)
-                       h = 0;
+       for(;;) {
+               h = runtime_atomicload(&p->runqhead);  // load-acquire, synchronize with other consumers
+               t = runtime_atomicload(&p->runqtail);  // load-acquire, synchronize with the producer
+               n = t-h;
+               n = n - n/2;
+               if(n == 0)
+                       break;
+               if(n > nelem(p->runq)/2)  // read inconsistent h and t
+                       continue;
+               for(i=0; i<n; i++)
+                       batch[i] = p->runq[(h+i)%nelem(p->runq)];
+               if(runtime_cas(&p->runqhead, h, h+n))  // cas-release, commits consume
+                       break;
        }
-       runtime_free(p->runq);
-       p->runq = q;
-       p->runqhead = 0;
-       p->runqtail = t2;
-       p->runqsize = 2*s;
+       return n;
 }
 
 // Steal half of elements from local runnable queue of p2
@@ -3083,57 +3231,24 @@ runqgrow(P *p)
 static G*
 runqsteal(P *p, P *p2)
 {
-       G *gp, *gp1;
-       int32 t, h, s, t2, h2, s2, c, i;
+       G *gp;
+       G *batch[nelem(p->runq)/2];
+       uint32 t, h, n, i;
 
-       if(p2->runqhead == p2->runqtail)
+       n = runqgrab(p2, batch);
+       if(n == 0)
                return nil;
-       // sort locks to prevent deadlocks
-       if(p < p2)
-               runtime_lock(p);
-       runtime_lock(p2);
-       if(p2->runqhead == p2->runqtail) {
-               runtime_unlock(p2);
-               if(p < p2)
-                       runtime_unlock(p);
-               return nil;
-       }
-       if(p >= p2)
-               runtime_lock(p);
-       // now we've locked both queues and know the victim is not empty
-       h = p->runqhead;
+       n--;
+       gp = batch[n];
+       if(n == 0)
+               return gp;
+       h = runtime_atomicload(&p->runqhead);  // load-acquire, synchronize with consumers
        t = p->runqtail;
-       s = p->runqsize;
-       h2 = p2->runqhead;
-       t2 = p2->runqtail;
-       s2 = p2->runqsize;
-       gp = p2->runq[h2++];  // return value
-       if(h2 == s2)
-               h2 = 0;
-       // steal roughly half
-       if(t2 > h2)
-               c = (t2 - h2) / 2;
-       else
-               c = (s2 - h2 + t2) / 2;
-       // copy
-       for(i = 0; i != c; i++) {
-               // the target queue is full?
-               if(t == h-1 || (h == 0 && t == s-1))
-                       break;
-               // the victim queue is empty?
-               if(t2 == h2)
-                       break;
-               gp1 = p2->runq[h2++];
-               if(h2 == s2)
-                       h2 = 0;
-               p->runq[t++] = gp1;
-               if(t == s)
-                       t = 0;
-       }
-       p->runqtail = t;
-       p2->runqhead = h2;
-       runtime_unlock(p2);
-       runtime_unlock(p);
+       if(t - h + n >= nelem(p->runq))
+               runtime_throw("runqsteal: runq overflow");
+       for(i=0; i<n; i++, t++)
+               p->runq[t%nelem(p->runq)] = batch[i];
+       runtime_atomicstore(&p->runqtail, t);  // store-release, makes the item available for consumption
        return gp;
 }
 
@@ -3144,14 +3259,10 @@ void
 runtime_testSchedLocalQueue(void)
 {
        P p;
-       G gs[1000];
+       G gs[nelem(p.runq)];
        int32 i, j;
 
        runtime_memclr((byte*)&p, sizeof(p));
-       p.runqsize = 1;
-       p.runqhead = 0;
-       p.runqtail = 0;
-       p.runq = runtime_malloc(p.runqsize*sizeof(*p.runq));
 
        for(i = 0; i < (int32)nelem(gs); i++) {
                if(runqget(&p) != nil)
@@ -3176,20 +3287,11 @@ void
 runtime_testSchedLocalQueueSteal(void)
 {
        P p1, p2;
-       G gs[1000], *gp;
+       G gs[nelem(p1.runq)], *gp;
        int32 i, j, s;
 
        runtime_memclr((byte*)&p1, sizeof(p1));
-       p1.runqsize = 1;
-       p1.runqhead = 0;
-       p1.runqtail = 0;
-       p1.runq = runtime_malloc(p1.runqsize*sizeof(*p1.runq));
-
        runtime_memclr((byte*)&p2, sizeof(p2));
-       p2.runqsize = nelem(gs);
-       p2.runqhead = 0;
-       p2.runqtail = 0;
-       p2.runq = runtime_malloc(p2.runqsize*sizeof(*p2.runq));
 
        for(i = 0; i < (int32)nelem(gs); i++) {
                for(j = 0; j < i; j++) {
@@ -3239,9 +3341,9 @@ runtime_debug_setMaxThreads(intgo in)
 }
 
 void
-runtime_proc_scan(void (*addroot)(Obj))
+runtime_proc_scan(struct Workbuf** wbufp, void (*enqueue1)(struct Workbuf**, Obj))
 {
-       addroot((Obj){(byte*)&runtime_sched, sizeof runtime_sched, 0});
+       enqueue1(wbufp, (Obj){(byte*)&runtime_sched, sizeof runtime_sched, 0});
 }
 
 // When a function calls a closure, it passes the closure value to
@@ -3271,3 +3373,30 @@ runtime_gcwaiting(void)
 {
        return runtime_sched.gcwaiting;
 }
+
+// func runtime_procPin() int
+
+intgo sync_runtime_procPin(void)
+  __asm__(GOSYM_PREFIX "sync.runtime_procPin");
+
+intgo
+sync_runtime_procPin()
+{
+       M *mp;
+
+       mp = m;
+       // Disable preemption.
+       mp->locks++;
+       return mp->p->id;
+}
+
+// func runtime_procUnpin()
+
+void sync_runtime_procUnpin(void)
+  __asm__ (GOSYM_PREFIX "sync.runtime_procUnpin");
+
+void
+sync_runtime_procUnpin(void)
+{
+       m->locks--;
+}
index c97e672fed5ccee5d1d88d643d026d1c925e7866..e84c5d4ec9127a458efd3412bb2ef2e80e2aa4a4 100644 (file)
@@ -24,8 +24,8 @@ void  runtime_racewritepc(void *addr, void *callpc, void *pc);
 void   runtime_racereadpc(void *addr, void *callpc, void *pc);
 void   runtime_racewriterangepc(void *addr, uintptr sz, void *callpc, void *pc);
 void   runtime_racereadrangepc(void *addr, uintptr sz, void *callpc, void *pc);
-void   runtime_racereadobjectpc(void *addr, Type *t, void *callpc, void *pc);
-void   runtime_racewriteobjectpc(void *addr, Type *t, void *callpc, void *pc);
+void   runtime_racereadobjectpc(void *addr, const Type *t, void *callpc, void *pc);
+void   runtime_racewriteobjectpc(void *addr, const Type *t, void *callpc, void *pc);
 void   runtime_racefingo(void);
 void   runtime_raceacquire(void *addr);
 void   runtime_raceacquireg(G *gp, void *addr);
index 4f9909bbc8aaf8e6b1f82dd7811d0405b1c2e1d8..eb32a8d7fe89132d33f20f872898fae97600d591 100644 (file)
@@ -353,3 +353,12 @@ runtime_debug_setMaxStack(intgo in)
        runtime_maxstacksize = in;
        return out;
 }
+
+void memclrBytes(Slice)
+     __asm__ (GOSYM_PREFIX "runtime.memclrBytes");
+
+void
+memclrBytes(Slice s)
+{
+       runtime_memclr(s.__values, s.__count);
+}
index ef6090fb6f85cd944951ba3414d1c8674ea060a9..9d5e42f50dc66626034f738724c7a12862d9ccf4 100644 (file)
@@ -205,12 +205,12 @@ struct    G
        void*   gcinitial_sp;
        ucontext_t gcregs;
        byte*   entry;          // initial function
-       G*      alllink;        // on allg
        void*   param;          // passed parameter on wakeup
        bool    fromgogo;       // reached from gogo
        int16   status;
        uint32  selgen;         // valid sudog pointer
        int64   goid;
+       int64   waitsince;      // approx time when the G become blocked
        const char*     waitreason;     // if status==Gwaiting
        G*      schedlink;
        bool    ispanic;
@@ -221,8 +221,6 @@ struct      G
        int32   sig;
        int32   writenbuf;
        byte*   writebuf;
-       // DeferChunk*  dchunk;
-       // DeferChunk*  dchunknext;
        uintptr sigcode0;
        uintptr sigcode1;
        // uintptr      sigpc;
@@ -256,7 +254,8 @@ struct      M
        int32   dying;
        int32   profilehz;
        int32   helpgc;
-       bool    spinning;
+       bool    spinning;       // M is out of work and is actively looking for work
+       bool    blocked;        // M is blocked on a Note
        uint32  fastrand;
        uint64  ncgocall;       // number of cgo calls in total
        int32   ncgo;           // number of cgo calls currently in progress
@@ -276,8 +275,7 @@ struct      M
        bool    racecall;
        bool    needextram;
        bool    dropextram;     // for gccgo: drop after call is done.
-       void*   racepc;
-       void    (*waitunlockf)(Lock*);
+       bool    (*waitunlockf)(G*, void*);
        void*   waitlock;
 
        uintptr settype_buf[1024];
@@ -297,12 +295,16 @@ struct P
        uint32  syscalltick;    // incremented on every system call
        M*      m;              // back-link to associated M (nil if idle)
        MCache* mcache;
+       Defer*  deferpool;      // pool of available Defer structs (see panic.c)
+
+       // Cache of goroutine ids, amortizes accesses to runtime_sched.goidgen.
+       uint64  goidcache;
+       uint64  goidcacheend;
 
        // Queue of runnable goroutines.
-       G**     runq;
-       int32   runqhead;
-       int32   runqtail;
-       int32   runqsize;
+       uint32  runqhead;
+       uint32  runqtail;
+       G*      runq[256];
 
        // Available G's (status == Gdead)
        G*      gfree;
@@ -359,6 +361,15 @@ enum {
    Windows = 0
 };
 #endif
+#ifdef GOOS_solaris
+enum {
+   Solaris = 1
+};
+#else
+enum {
+   Solaris = 0
+};
+#endif
 
 struct Timers
 {
@@ -458,12 +469,18 @@ void      runtime_hashinit(void);
 
 void   runtime_traceback(void);
 void   runtime_tracebackothers(G*);
+enum
+{
+       // The maximum number of frames we print for a traceback
+       TracebackMaxFrames = 100,
+};
 
 /*
  * external data
  */
 extern uintptr runtime_zerobase;
-extern G*      runtime_allg;
+extern G**     runtime_allg;
+extern uintptr runtime_allglen;
 extern G*      runtime_lastg;
 extern M*      runtime_allm;
 extern P**     runtime_allp;
@@ -514,21 +531,6 @@ void       runtime_printtrace(Location*, int32, bool);
 #define runtime_read(d, v, n) read((d), (v), (n))
 #define runtime_write(d, v, n) write((d), (v), (n))
 #define runtime_close(d) close(d)
-#define runtime_cas(pval, old, new) __sync_bool_compare_and_swap (pval, old, new)
-#define runtime_cas64(pval, old, new) __sync_bool_compare_and_swap (pval, old, new)
-#define runtime_casp(pval, old, new) __sync_bool_compare_and_swap (pval, old, new)
-// Don't confuse with XADD x86 instruction,
-// this one is actually 'addx', that is, add-and-fetch.
-#define runtime_xadd(p, v) __sync_add_and_fetch (p, v)
-#define runtime_xadd64(p, v) __sync_add_and_fetch (p, v)
-#define runtime_xchg(p, v) __atomic_exchange_n (p, v, __ATOMIC_SEQ_CST)
-#define runtime_xchg64(p, v) __atomic_exchange_n (p, v, __ATOMIC_SEQ_CST)
-#define runtime_atomicload(p) __atomic_load_n (p, __ATOMIC_SEQ_CST)
-#define runtime_atomicstore(p, v) __atomic_store_n (p, v, __ATOMIC_SEQ_CST)
-#define runtime_atomicstore64(p, v) __atomic_store_n (p, v, __ATOMIC_SEQ_CST)
-#define runtime_atomicload64(p) __atomic_load_n (p, __ATOMIC_SEQ_CST)
-#define runtime_atomicloadp(p) __atomic_load_n (p, __ATOMIC_SEQ_CST)
-#define runtime_atomicstorep(p, v) __atomic_store_n (p, v, __ATOMIC_SEQ_CST)
 void   runtime_ready(G*);
 const byte*    runtime_getenv(const char*);
 int32  runtime_atoi(const byte*);
@@ -546,7 +548,6 @@ void        runtime_mallocinit(void);
 void   runtime_mprofinit(void);
 #define runtime_malloc(s) __go_alloc(s)
 #define runtime_free(p) __go_free(p)
-bool   runtime_addfinalizer(void*, FuncVal *fn, const struct __go_func_type *, const struct __go_ptr_type *);
 #define runtime_getcallersp(p) __builtin_frame_address(1)
 int32  runtime_mcount(void);
 int32  runtime_gcount(void);
@@ -554,6 +555,24 @@ void       runtime_mcall(void(*)(G*));
 uint32 runtime_fastrand1(void);
 int32  runtime_timediv(int64, int32, int32*);
 
+// atomic operations
+#define runtime_cas(pval, old, new) __sync_bool_compare_and_swap (pval, old, new)
+#define runtime_cas64(pval, old, new) __sync_bool_compare_and_swap (pval, old, new)
+#define runtime_casp(pval, old, new) __sync_bool_compare_and_swap (pval, old, new)
+// Don't confuse with XADD x86 instruction,
+// this one is actually 'addx', that is, add-and-fetch.
+#define runtime_xadd(p, v) __sync_add_and_fetch (p, v)
+#define runtime_xadd64(p, v) __sync_add_and_fetch (p, v)
+#define runtime_xchg(p, v) __atomic_exchange_n (p, v, __ATOMIC_SEQ_CST)
+#define runtime_xchg64(p, v) __atomic_exchange_n (p, v, __ATOMIC_SEQ_CST)
+#define runtime_xchgp(p, v) __atomic_exchange_n (p, v, __ATOMIC_SEQ_CST)
+#define runtime_atomicload(p) __atomic_load_n (p, __ATOMIC_SEQ_CST)
+#define runtime_atomicstore(p, v) __atomic_store_n (p, v, __ATOMIC_SEQ_CST)
+#define runtime_atomicstore64(p, v) __atomic_store_n (p, v, __ATOMIC_SEQ_CST)
+#define runtime_atomicload64(p) __atomic_load_n (p, __ATOMIC_SEQ_CST)
+#define runtime_atomicloadp(p) __atomic_load_n (p, __ATOMIC_SEQ_CST)
+#define runtime_atomicstorep(p, v) __atomic_store_n (p, v, __ATOMIC_SEQ_CST)
+
 void runtime_setmg(M*, G*);
 void runtime_newextram(void);
 #define runtime_exit(s) exit(s)
@@ -561,7 +580,8 @@ void runtime_newextram(void);
 void   runtime_gosched(void);
 void   runtime_gosched0(G*);
 void   runtime_schedtrace(bool);
-void   runtime_park(void(*)(Lock*), Lock*, const char*);
+void   runtime_park(bool(*)(G*, void*), void*, const char*);
+void   runtime_parkunlock(Lock*, const char*);
 void   runtime_tsleep(int64, const char*);
 M*     runtime_newm(void);
 void   runtime_goexit(void);
@@ -593,6 +613,7 @@ int32       runtime_netpollopen(uintptr, PollDesc*);
 int32   runtime_netpollclose(uintptr);
 void   runtime_netpollready(G**, PollDesc*, int32);
 uintptr        runtime_netpollfd(PollDesc*);
+void   runtime_netpollarm(uintptr, int32);
 void   runtime_crash(void);
 void   runtime_parsedebugvars(void);
 void   _rt0_go(void);
@@ -743,9 +764,6 @@ void        runtime_lockOSThread(void);
 void   runtime_unlockOSThread(void);
 
 bool   runtime_showframe(String, bool);
-Hchan* runtime_makechan_c(ChanType*, int64);
-void   runtime_chansend(ChanType*, Hchan*, byte*, bool*, void*);
-void   runtime_chanrecv(ChanType*, Hchan*, byte*, bool*, bool*);
 void   runtime_printcreatedby(G*);
 
 uintptr        runtime_memlimit(void);
@@ -793,3 +811,5 @@ void*       __go_get_closure(void);
 
 bool   runtime_gcwaiting(void);
 void   runtime_badsignal(int);
+Defer* runtime_newdefer(void);
+void   runtime_freedefer(Defer*);
index f5d5bc89e3d9d13fa72b093041c583a413deb9d1..50f0e973d70b46534430389720afcd2b40ad9288 100644 (file)
@@ -136,7 +136,7 @@ runtime_semacquire(uint32 volatile *addr, bool profile)
                // Any semrelease after the cansemacquire knows we're waiting
                // (we set nwait above), so go to sleep.
                semqueue(root, addr, &s);
-               runtime_park(runtime_unlock, root, "semacquire");
+               runtime_parkunlock(root, "semacquire");
                if(cansemacquire(addr)) {
                        if(t0)
                                runtime_blockevent(s.releasetime - t0, 3);
@@ -259,7 +259,7 @@ func runtime_Syncsemacquire(s *SyncSema) {
                else
                        s->tail->next = &w;
                s->tail = &w;
-               runtime_park(runtime_unlock, s, "semacquire");
+               runtime_parkunlock(s, "semacquire");
                if(t0)
                        runtime_blockevent(w.releasetime - t0, 2);
        }
@@ -293,7 +293,7 @@ func runtime_Syncsemrelease(s *SyncSema, n uint32) {
                else
                        s->tail->next = &w;
                s->tail = &w;
-               runtime_park(runtime_unlock, s, "semarelease");
+               runtime_parkunlock(s, "semarelease");
        } else
                runtime_unlock(s);
 }
index 6c191d03f79cc7e054689740519ed5f34359fa23..66638dec56bbffbdef44471f8085803e79af10b0 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin dragonfly freebsd linux openbsd netbsd
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
 
 #include <sys/time.h>
 
index a7446e93c45022978309c46f008d7e7ea2cf57ef..a0e80ccf45b4af10c75548adc87072b73f566b8b 100644 (file)
@@ -43,11 +43,9 @@ gostringsize(intgo l, byte** pmem)
                *pmem = nil;
                return runtime_emptystring;
        }
-       // leave room for NUL for C runtime (e.g., callers of getenv)
-       mem = runtime_mallocgc(l+1, 0, FlagNoScan|FlagNoZero);
+       mem = runtime_mallocgc(l, 0, FlagNoScan|FlagNoZero);
        s.str = mem;
        s.len = l;
-       mem[l] = 0;
        *pmem = mem;
        return s;
 }
index e4e35ec08468d0e5bc843a06e258876c1c855d5d..13ce41fc8e0daf7f252f76a49813a61fabb685f5 100644 (file)
@@ -78,7 +78,7 @@ runtime_tsleep(int64 ns, const char *reason)
        t.arg.__object = g;
        runtime_lock(&timers);
        addtimer(&t);
-       runtime_park(runtime_unlock, &timers, reason);
+       runtime_parkunlock(&timers, reason);
 }
 
 void
@@ -221,12 +221,20 @@ timerproc(void* dummy __attribute__ ((unused)))
                                runtime_raceacquire(t);
                        __go_set_closure(t->fv);
                        f(now, arg);
+
+                       // clear f and arg to avoid leak while sleeping for next timer
+                       f = nil;
+                       USED(f);
+                       arg.__type_descriptor = nil;
+                       arg.__object = nil;
+                       USED(&arg);
+
                        runtime_lock(&timers);
                }
                if(delta < 0) {
                        // No timers left - put goroutine to sleep.
                        timers.rescheduling = true;
-                       runtime_park(runtime_unlock, &timers, "timer goroutine (idle)");
+                       runtime_parkunlock(&timers, "timer goroutine (idle)");
                        continue;
                }
                // At least one timer pending.  Sleep until then.
@@ -320,7 +328,7 @@ dumptimers(const char *msg)
 }
 
 void
-runtime_time_scan(void (*addroot)(Obj))
+runtime_time_scan(struct Workbuf** wbufp, void (*enqueue1)(struct Workbuf**, Obj))
 {
-       addroot((Obj){(byte*)&timers, sizeof timers, 0});
+       enqueue1(wbufp, (Obj){(byte*)&timers, sizeof timers, 0});
 }