aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml40
-rw-r--r--HOWTO/INSTALL.md10
-rw-r--r--OTP_VERSION2
-rw-r--r--erts/aclocal.m414
-rw-r--r--erts/doc/src/absform.xml928
-rw-r--r--erts/doc/src/driver_entry.xml5
-rw-r--r--erts/doc/src/erl.xml89
-rw-r--r--erts/doc/src/erl_dist_protocol.xml4
-rw-r--r--erts/doc/src/erl_driver.xml20
-rw-r--r--erts/doc/src/erl_ext_dist.xml4
-rw-r--r--erts/doc/src/erl_nif.xml11
-rw-r--r--erts/doc/src/erl_prim_loader.xml35
-rw-r--r--erts/doc/src/erlang.xml7321
-rw-r--r--erts/doc/src/erts_alloc.xml74
-rw-r--r--erts/doc/src/escript.xml6
-rw-r--r--erts/doc/src/notes.xml80
-rw-r--r--erts/doc/src/time_correction.xml772
-rw-r--r--erts/emulator/beam/atom.names1
-rw-r--r--erts/emulator/beam/beam_debug.c6
-rw-r--r--erts/emulator/beam/bif.c7
-rw-r--r--erts/emulator/beam/dist.c41
-rw-r--r--erts/emulator/beam/erl_alloc.c84
-rw-r--r--erts/emulator/beam/erl_alloc.types5
-rw-r--r--erts/emulator/beam/erl_alloc_util.c56
-rw-r--r--erts/emulator/beam/erl_alloc_util.h2
-rw-r--r--erts/emulator/beam/erl_ao_firstfit_alloc.c22
-rw-r--r--erts/emulator/beam/erl_bif_port.c10
-rw-r--r--erts/emulator/beam/erl_driver.h4
-rw-r--r--erts/emulator/beam/erl_gc.c36
-rw-r--r--erts/emulator/beam/erl_nif.c1
-rw-r--r--erts/emulator/beam/erl_nif.h4
-rw-r--r--erts/emulator/beam/erl_nif_api_funcs.h2
-rw-r--r--erts/emulator/beam/erl_node_tables.c150
-rw-r--r--erts/emulator/beam/erl_process.c11
-rw-r--r--erts/emulator/beam/erl_process.h17
-rw-r--r--erts/emulator/beam/erl_process_lock.h6
-rw-r--r--erts/emulator/beam/external.c76
-rw-r--r--erts/emulator/beam/io.c8
-rw-r--r--erts/emulator/beam/packet_parser.c5
-rw-r--r--erts/emulator/beam/packet_parser.h3
-rw-r--r--erts/emulator/beam/sys.h1
-rw-r--r--erts/emulator/beam/utils.c3
-rw-r--r--erts/emulator/drivers/common/efile_drv.c1
-rw-r--r--erts/emulator/drivers/common/inet_drv.c20
-rw-r--r--erts/emulator/hipe/hipe_native_bif.c3
-rw-r--r--erts/emulator/hipe/hipe_x86_signal.c31
-rw-r--r--erts/emulator/sys/common/erl_poll.h2
-rw-r--r--erts/emulator/sys/win32/erl_win32_sys_ddll.c3
-rw-r--r--erts/emulator/sys/win32/erl_win_dyn_driver.h4
-rw-r--r--erts/emulator/test/alloc_SUITE.erl250
-rw-r--r--erts/emulator/test/alloc_SUITE_data/Makefile.src3
-rw-r--r--erts/emulator/test/alloc_SUITE_data/allocator_test.h20
-rw-r--r--erts/emulator/test/alloc_SUITE_data/basic.c3
-rw-r--r--erts/emulator/test/alloc_SUITE_data/basic.erl10
-rw-r--r--erts/emulator/test/alloc_SUITE_data/bucket_index.c2
-rw-r--r--erts/emulator/test/alloc_SUITE_data/bucket_index.erl10
-rw-r--r--erts/emulator/test/alloc_SUITE_data/bucket_mask.c4
-rw-r--r--erts/emulator/test/alloc_SUITE_data/bucket_mask.erl10
-rw-r--r--erts/emulator/test/alloc_SUITE_data/coalesce.c3
-rw-r--r--erts/emulator/test/alloc_SUITE_data/coalesce.erl10
-rw-r--r--erts/emulator/test/alloc_SUITE_data/cpool.c9
-rw-r--r--erts/emulator/test/alloc_SUITE_data/cpool.erl10
-rw-r--r--erts/emulator/test/alloc_SUITE_data/migration.c343
-rw-r--r--erts/emulator/test/alloc_SUITE_data/migration.erl10
-rw-r--r--erts/emulator/test/alloc_SUITE_data/mseg_clear_cache.c3
-rw-r--r--erts/emulator/test/alloc_SUITE_data/mseg_clear_cache.erl10
-rw-r--r--erts/emulator/test/alloc_SUITE_data/rbtree.c14
-rw-r--r--erts/emulator/test/alloc_SUITE_data/rbtree.erl10
-rw-r--r--erts/emulator/test/alloc_SUITE_data/realloc_copy.c2
-rw-r--r--erts/emulator/test/alloc_SUITE_data/realloc_copy.erl10
-rw-r--r--erts/emulator/test/alloc_SUITE_data/testcase_driver.c255
-rw-r--r--erts/emulator/test/alloc_SUITE_data/testcase_driver.h15
-rw-r--r--erts/emulator/test/alloc_SUITE_data/threads.c6
-rw-r--r--erts/emulator/test/alloc_SUITE_data/threads.erl10
-rw-r--r--erts/emulator/test/distribution_SUITE_data/run.erl47
-rw-r--r--erts/emulator/test/map_SUITE.erl206
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_mod.c2
-rw-r--r--erts/emulator/test/process_SUITE.erl10
-rw-r--r--erts/epmd/src/epmd.c2
-rw-r--r--erts/etc/common/ct_run.c25
-rw-r--r--erts/etc/common/dialyzer.c24
-rw-r--r--erts/etc/common/erlc.c22
-rw-r--r--erts/etc/common/erlexec.c3
-rw-r--r--erts/etc/common/escript.c25
-rw-r--r--erts/etc/common/heart.c2
-rw-r--r--erts/etc/common/typer.c26
-rw-r--r--erts/etc/win32/msys_tools/vc/cc.sh10
-rw-r--r--erts/etc/win32/msys_tools/vc/emu_cc.sh1
-rw-r--r--erts/etc/win32/msys_tools/vc/mc.sh7
-rw-r--r--erts/etc/win32/msys_tools/vc/rc.sh7
-rw-r--r--erts/etc/win32/nsis/Makefile10
-rwxr-xr-xerts/etc/win32/nsis/find_redist.sh2
-rw-r--r--erts/include/internal/ethread.h3
-rw-r--r--erts/preloaded/ebin/init.beambin48768 -> 48812 bytes
-rw-r--r--erts/preloaded/ebin/prim_inet.beambin72748 -> 72712 bytes
-rw-r--r--erts/preloaded/src/erlang.erl3
-rw-r--r--erts/preloaded/src/init.erl2
-rw-r--r--erts/preloaded/src/prim_inet.erl7
-rw-r--r--lib/asn1/src/asn1rtt_ber.erl4
-rw-r--r--lib/asn1/test/testPrimStrings.erl9
-rw-r--r--lib/common_test/src/ct_conn_log_h.erl22
-rw-r--r--lib/common_test/src/ct_netconfc.erl28
-rw-r--r--lib/common_test/test/ct_netconfc_SUITE_data/netconfc1_SUITE.erl23
-rw-r--r--lib/compiler/doc/src/notes.xml26
-rw-r--r--lib/compiler/src/cerl_trees.erl4
-rw-r--r--lib/compiler/src/sys_core_fold.erl6
-rw-r--r--lib/compiler/test/bs_match_SUITE.erl22
-rw-r--r--lib/crypto/doc/src/crypto.xml95
-rw-r--r--lib/debugger/doc/src/notes.xml2
-rw-r--r--lib/dialyzer/doc/src/notes.xml32
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/fun_arity35
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/fun_arity.erl127
-rw-r--r--lib/erl_docgen/doc/src/erl_docgen_app.xml3
-rw-r--r--lib/erl_docgen/priv/dtd/cites.dtd2
-rw-r--r--lib/erl_docgen/priv/dtd/common.dtd22
-rw-r--r--lib/erl_docgen/priv/dtd/common.header.dtd4
-rw-r--r--lib/erl_docgen/priv/dtd/common.refs.dtd16
-rw-r--r--lib/erl_docgen/priv/dtd/erlref.dtd3
-rw-r--r--lib/erl_docgen/priv/dtd/terms.dtd2
-rw-r--r--lib/erl_docgen/priv/xsl/db_html.xsl5
-rw-r--r--lib/erl_docgen/priv/xsl/db_man.xsl6
-rw-r--r--lib/erl_docgen/priv/xsl/db_pdf.xsl6
-rw-r--r--lib/erl_docgen/src/docgen_edoc_xml_cb.erl24
-rw-r--r--lib/erl_docgen/vsn.mk2
-rw-r--r--lib/erl_interface/src/connect/ei_resolve.c14
-rw-r--r--lib/eunit/doc/overview.edoc4
-rw-r--r--lib/eunit/include/eunit.hrl1
-rw-r--r--lib/hipe/cerl/erl_bif_types.erl14
-rw-r--r--lib/hipe/doc/src/hipe_app.xml17
-rw-r--r--lib/hipe/doc/src/notes.xml32
-rw-r--r--lib/hipe/rtl/Makefile2
-rw-r--r--lib/hipe/rtl/hipe_rtl_binary_construct.erl9
-rw-r--r--lib/hipe/rtl/hipe_rtl_binary_match.erl104
-rw-r--r--lib/hipe/rtl/hipe_tagscheme.erl30
-rw-r--r--lib/hipe/test/bs_SUITE_data/bs_construct.erl16
-rw-r--r--lib/hipe/test/bs_SUITE_data/bs_match.erl108
-rw-r--r--lib/inets/doc/src/http_uri.xml13
-rw-r--r--lib/inets/doc/src/httpd.xml13
-rw-r--r--lib/inets/doc/src/httpd_custom_api.xml14
-rw-r--r--lib/inets/doc/src/notes.xml66
-rw-r--r--lib/inets/src/http_client/httpc_handler.erl85
-rw-r--r--lib/inets/src/http_lib/http_chunk.erl184
-rw-r--r--lib/inets/src/http_lib/http_response.erl32
-rw-r--r--lib/inets/src/http_lib/http_transport.erl206
-rw-r--r--lib/inets/src/http_lib/http_uri.erl31
-rw-r--r--lib/inets/src/http_lib/http_util.erl69
-rw-r--r--lib/inets/src/http_server/Makefile12
-rw-r--r--lib/inets/src/http_server/httpd_conf.erl101
-rw-r--r--lib/inets/src/http_server/httpd_custom.erl31
-rw-r--r--lib/inets/src/http_server/httpd_custom_api.erl31
-rw-r--r--lib/inets/src/http_server/httpd_example.erl10
-rw-r--r--lib/inets/src/http_server/httpd_request_handler.erl25
-rw-r--r--lib/inets/src/http_server/httpd_response.erl48
-rw-r--r--lib/inets/src/http_server/httpd_sup.erl4
-rw-r--r--lib/inets/src/http_server/httpd_util.erl28
-rw-r--r--lib/inets/src/http_server/mod_auth_server.erl2
-rw-r--r--lib/inets/src/http_server/mod_esi.erl47
-rw-r--r--lib/inets/src/http_server/mod_security_server.erl4
-rw-r--r--lib/inets/test/http_format_SUITE.erl238
-rw-r--r--lib/inets/test/httpc_SUITE.erl91
-rw-r--r--lib/inets/test/httpd_1_1.erl11
-rw-r--r--lib/inets/test/httpd_SUITE.erl71
-rw-r--r--lib/inets/test/httpd_test_lib.erl20
-rw-r--r--lib/inets/test/uri_SUITE.erl23
-rw-r--r--lib/inets/vsn.mk2
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpInputStream.java3
-rw-r--r--lib/kernel/doc/src/app.xml2
-rw-r--r--lib/kernel/doc/src/application.xml5
-rw-r--r--lib/kernel/doc/src/auth.xml8
-rw-r--r--lib/kernel/doc/src/code.xml10
-rw-r--r--lib/kernel/doc/src/disk_log.xml12
-rw-r--r--lib/kernel/doc/src/erl_ddll.xml22
-rw-r--r--lib/kernel/doc/src/error_logger.xml2
-rw-r--r--lib/kernel/doc/src/file.xml29
-rw-r--r--lib/kernel/doc/src/gen_sctp.xml14
-rw-r--r--lib/kernel/doc/src/gen_tcp.xml5
-rw-r--r--lib/kernel/doc/src/gen_udp.xml4
-rw-r--r--lib/kernel/doc/src/inet.xml35
-rw-r--r--lib/kernel/doc/src/inet_res.xml31
-rw-r--r--lib/kernel/doc/src/net_adm.xml4
-rw-r--r--lib/kernel/doc/src/notes.xml23
-rw-r--r--lib/kernel/doc/src/os.xml4
-rw-r--r--lib/kernel/src/file_io_server.erl122
-rw-r--r--lib/kernel/src/inet.erl18
-rw-r--r--lib/kernel/src/inet6_tcp.erl19
-rw-r--r--lib/kernel/src/inet6_tcp_dist.erl365
-rw-r--r--lib/kernel/src/inet_db.erl38
-rw-r--r--lib/kernel/src/inet_dns_record_adts.pl6
-rw-r--r--lib/kernel/src/inet_int.hrl1
-rw-r--r--lib/kernel/src/inet_tcp.erl16
-rw-r--r--lib/kernel/src/inet_tcp_dist.erl157
-rw-r--r--lib/kernel/test/bif_SUITE.erl10
-rw-r--r--lib/kernel/test/file_SUITE.erl64
-rw-r--r--lib/kernel/test/gen_tcp_api_SUITE.erl19
-rw-r--r--lib/kernel/test/inet_sockopt_SUITE.erl82
-rw-r--r--lib/mnesia/doc/src/notes.xml18
-rw-r--r--lib/mnesia/src/mnesia_bup.erl14
-rw-r--r--lib/mnesia/test/mnesia_evil_backup.erl10
-rw-r--r--lib/mnesia/vsn.mk2
-rw-r--r--lib/observer/src/cdv_ets_cb.erl2
-rw-r--r--lib/observer/src/crashdump_viewer.erl2
-rw-r--r--lib/observer/src/observer_sys_wx.erl6
-rw-r--r--lib/os_mon/doc/src/cpu_sup.xml2
-rw-r--r--lib/parsetools/doc/src/leex.xml2
-rw-r--r--lib/parsetools/doc/src/yecc.xml2
-rw-r--r--lib/public_key/doc/src/public_key.xml31
-rwxr-xr-xlib/public_key/priv/convert.escript50
-rwxr-xr-xlib/public_key/priv/generate25
-rw-r--r--lib/public_key/priv/moduli193
-rw-r--r--lib/public_key/src/Makefile7
-rw-r--r--lib/public_key/src/pubkey_moduli.hrl395
-rw-r--r--lib/public_key/src/pubkey_ssh.erl194
-rw-r--r--lib/public_key/src/public_key.erl45
-rw-r--r--lib/public_key/test/public_key_SUITE.erl32
-rw-r--r--lib/public_key/test/public_key_SUITE_data/openssh_ecdsa_pub1
-rw-r--r--lib/public_key/test/public_key_SUITE_data/ssh2_ecdsa_pub6
-rw-r--r--lib/public_key/vsn.mk2
-rw-r--r--lib/runtime_tools/doc/src/dbg.xml7
-rw-r--r--lib/snmp/doc/src/snmp_advanced_agent.xml2
-rw-r--r--lib/snmp/doc/src/snmp_agent_netif.xml3
-rw-r--r--lib/snmp/doc/src/snmp_app.xml276
-rw-r--r--lib/snmp/doc/src/snmp_config.xml280
-rw-r--r--lib/snmp/doc/src/snmp_manager_netif.xml3
-rw-r--r--lib/snmp/doc/src/snmpa.xml4
-rw-r--r--lib/snmp/doc/src/snmpm.xml8
-rw-r--r--lib/snmp/src/app/snmp.appup.src1
-rw-r--r--lib/snmp/src/misc/snmp_conf.erl2
-rw-r--r--lib/ssh/doc/src/notes.xml58
-rw-r--r--lib/ssh/doc/src/ssh.xml193
-rw-r--r--lib/ssh/doc/src/ssh_app.xml211
-rw-r--r--lib/ssh/doc/src/ssh_connection.xml6
-rw-r--r--lib/ssh/doc/src/using_ssh.xml6
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-architecture-15.2.ps3315
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-architecture-15.txt1624
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-connect-18.2.ps2557
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-connect-18.txt1232
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-filexfer-02.2.ps2853
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-filexfer-02.txt1627
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-filexfer-03.2.ps3511
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-filexfer-03.txt1962
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-filexfer-04.txt2130
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-transport-17.2.ps3205
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-transport-17.txt1624
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-userauth-18.2.ps1881
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-userauth-18.txt896
-rw-r--r--lib/ssh/src/ssh.erl241
-rw-r--r--lib/ssh/src/ssh.hrl19
-rw-r--r--lib/ssh/src/ssh_acceptor.erl7
-rw-r--r--lib/ssh/src/ssh_auth.erl182
-rw-r--r--lib/ssh/src/ssh_auth.hrl3
-rw-r--r--lib/ssh/src/ssh_connect.hrl3
-rw-r--r--lib/ssh/src/ssh_connection.erl31
-rw-r--r--lib/ssh/src/ssh_connection_handler.erl310
-rw-r--r--lib/ssh/src/ssh_file.erl94
-rw-r--r--lib/ssh/src/ssh_message.erl153
-rw-r--r--lib/ssh/src/ssh_sftpd.erl22
-rw-r--r--lib/ssh/src/ssh_transport.erl946
-rw-r--r--lib/ssh/src/ssh_transport.hrl36
-rw-r--r--lib/ssh/test/Makefile2
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE.erl91
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa5
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa.pub1
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa2565
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa256.pub1
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key2565
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key256.pub1
-rw-r--r--lib/ssh/test/ssh_basic_SUITE.erl382
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa2565
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa256.pub1
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa3846
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa384.pub1
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa5217
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa521.pub1
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key2565
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key256.pub1
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key3846
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key384.pub1
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key5217
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key521.pub1
-rw-r--r--lib/ssh/test/ssh_connection_SUITE.erl121
-rw-r--r--lib/ssh/test/ssh_key_cb.erl45
-rw-r--r--lib/ssh/test/ssh_key_cb_options.erl44
-rw-r--r--lib/ssh/test/ssh_options_SUITE.erl175
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE.erl260
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/dh_group_test.moduli3
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE.erl47
-rw-r--r--lib/ssh/test/ssh_sftp_SUITE.erl6
-rw-r--r--lib/ssh/test/ssh_sftpd_SUITE.erl2
-rw-r--r--lib/ssh/test/ssh_test_lib.erl213
-rw-r--r--lib/ssh/test/ssh_to_openssh_SUITE.erl285
-rw-r--r--lib/ssh/test/ssh_trpt_test_lib.erl16
-rw-r--r--lib/ssh/vsn.mk3
-rw-r--r--lib/ssl/doc/src/notes.xml23
-rw-r--r--lib/ssl/doc/src/ssl.xml4
-rw-r--r--lib/ssl/doc/src/ssl_app.xml18
-rw-r--r--lib/ssl/src/dtls_connection.erl2
-rw-r--r--lib/ssl/src/inet_tls_dist.erl2
-rw-r--r--lib/ssl/src/ssl_connection.erl4
-rw-r--r--lib/ssl/src/ssl_dist_sup.erl2
-rw-r--r--lib/ssl/src/ssl_internal.hrl3
-rw-r--r--lib/ssl/src/ssl_manager.erl186
-rw-r--r--lib/ssl/src/ssl_session.erl11
-rw-r--r--lib/ssl/src/ssl_session_cache.erl8
-rw-r--r--lib/ssl/src/ssl_session_cache_api.erl1
-rw-r--r--lib/ssl/src/ssl_tls_dist_proxy.erl86
-rw-r--r--lib/ssl/src/ssl_v3.erl1
-rw-r--r--lib/ssl/src/tls_connection.erl3
-rw-r--r--lib/ssl/src/tls_record.erl62
-rw-r--r--lib/ssl/test/ssl_basic_SUITE.erl1
-rw-r--r--lib/ssl/test/ssl_dist_SUITE.erl149
-rw-r--r--lib/ssl/test/ssl_session_cache_SUITE.erl152
-rw-r--r--lib/stdlib/doc/src/array.xml4
-rw-r--r--lib/stdlib/doc/src/assert_hrl.xml11
-rw-r--r--lib/stdlib/doc/src/beam_lib.xml18
-rw-r--r--lib/stdlib/doc/src/binary.xml4
-rw-r--r--lib/stdlib/doc/src/c.xml2
-rw-r--r--lib/stdlib/doc/src/calendar.xml4
-rw-r--r--lib/stdlib/doc/src/dets.xml56
-rw-r--r--lib/stdlib/doc/src/digraph.xml6
-rw-r--r--lib/stdlib/doc/src/digraph_utils.xml5
-rw-r--r--lib/stdlib/doc/src/epp.xml2
-rw-r--r--lib/stdlib/doc/src/erl_anno.xml34
-rw-r--r--lib/stdlib/doc/src/erl_parse.xml2
-rw-r--r--lib/stdlib/doc/src/erl_pp.xml4
-rw-r--r--lib/stdlib/doc/src/erl_scan.xml36
-rw-r--r--lib/stdlib/doc/src/erl_tar.xml3
-rw-r--r--lib/stdlib/doc/src/ets.xml15
-rw-r--r--lib/stdlib/doc/src/file_sorter.xml52
-rw-r--r--lib/stdlib/doc/src/gen_event.xml4
-rw-r--r--lib/stdlib/doc/src/gen_fsm.xml2
-rw-r--r--lib/stdlib/doc/src/gen_server.xml2
-rw-r--r--lib/stdlib/doc/src/io.xml18
-rw-r--r--lib/stdlib/doc/src/lists.xml6
-rw-r--r--lib/stdlib/doc/src/math.xml2
-rw-r--r--lib/stdlib/doc/src/notes.xml53
-rw-r--r--lib/stdlib/doc/src/rand.xml2
-rw-r--r--lib/stdlib/doc/src/random.xml16
-rw-r--r--lib/stdlib/doc/src/re.xml16
-rw-r--r--lib/stdlib/doc/src/sofs.xml5
-rw-r--r--lib/stdlib/doc/src/supervisor.xml2
-rw-r--r--lib/stdlib/doc/src/sys.xml4
-rw-r--r--lib/stdlib/doc/src/timer.xml8
-rw-r--r--lib/stdlib/doc/src/unicode.xml2
-rw-r--r--lib/stdlib/doc/src/zip.xml2
-rw-r--r--lib/stdlib/src/beam_lib.erl17
-rw-r--r--lib/stdlib/src/edlin.erl4
-rw-r--r--lib/stdlib/src/erl_lint.erl3
-rw-r--r--lib/stdlib/src/erl_pp.erl21
-rw-r--r--lib/stdlib/src/rand.erl2
-rw-r--r--lib/stdlib/src/shell.erl15
-rw-r--r--lib/stdlib/src/supervisor.erl2
-rw-r--r--lib/stdlib/test/erl_lint_SUITE.erl39
-rw-r--r--lib/stdlib/test/erl_pp_SUITE.erl3
-rw-r--r--lib/stdlib/test/rand_SUITE.erl3
-rw-r--r--lib/test_server/doc/src/notes.xml12
-rw-r--r--lib/test_server/src/ts_lib.erl4
-rw-r--r--lib/tools/doc/src/eprof.xml2
-rw-r--r--lib/tools/emacs/erlang.el2
-rw-r--r--lib/tools/src/make.erl10
-rw-r--r--lib/typer/src/typer.erl10
-rw-r--r--lib/wx/api_gen/gl_gen_erl.erl12
-rw-r--r--lib/wx/api_gen/wx_extra/wxEvtHandler.c_src4
-rw-r--r--lib/wx/api_gen/wx_gen_cpp.erl6
-rw-r--r--lib/wx/api_gen/wxapi.conf8
-rw-r--r--lib/wx/c_src/gen/wxe_derived_dest.h10
-rw-r--r--lib/wx/c_src/gen/wxe_events.cpp5
-rw-r--r--lib/wx/c_src/gen/wxe_funcs.cpp58
-rw-r--r--lib/wx/c_src/gen/wxe_macros.h8
-rw-r--r--lib/wx/c_src/wxe_helpers.cpp58
-rw-r--r--lib/wx/c_src/wxe_helpers.h4
-rw-r--r--lib/wx/c_src/wxe_impl.cpp105
-rw-r--r--lib/wx/c_src/wxe_impl.h4
-rw-r--r--lib/wx/examples/demo/ex_canvas.erl47
-rw-r--r--lib/wx/src/gen/gl.erl72
-rw-r--r--lib/wx/src/gen/glu.erl8
-rw-r--r--lib/wx/src/gen/wxDCOverlay.erl70
-rw-r--r--lib/wx/src/gen/wxOverlay.erl57
-rw-r--r--lib/wx/src/gen/wxe_debug.hrl7
-rw-r--r--lib/wx/src/gen/wxe_funcs.hrl7
-rw-r--r--lib/wx/src/wxe_server.erl21
-rw-r--r--lib/wx/src/wxe_util.erl17
-rw-r--r--lib/xmerl/src/xmerl_xsd.erl127
-rw-r--r--lib/xmerl/test/xmerl_xsd_SUITE.erl18
-rw-r--r--lib/xmerl/test/xmerl_xsd_SUITE_data/book.xml5
-rw-r--r--lib/xmerl/test/xmerl_xsd_SUITE_data/book.xsd13
-rw-r--r--lib/xmerl/test/xmerl_xsd_SUITE_data/xml.xsd287
-rw-r--r--make/otp_release_targets.mk11
-rwxr-xr-xotp_build4
-rw-r--r--otp_versions.table7
-rw-r--r--system/doc/design_principles/des_princ.xml2
-rw-r--r--system/doc/efficiency_guide/binaryhandling.xml6
-rw-r--r--system/doc/reference_manual/processes.xml4
-rw-r--r--system/doc/reference_manual/typespec.xml11
-rw-r--r--system/doc/tutorial/ei.c2
-rw-r--r--system/doc/tutorial/example.xmlsrc6
395 files changed, 14554 insertions, 37167 deletions
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000000..48d8031bd0
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,40 @@
+language: erlang
+
+otp_release:
+ - 18.0
+
+sudo: false
+
+addons:
+ apt:
+ packages:
+ - autoconf
+ - libncurses-dev
+ - build-essential
+ - libssl-dev
+ - libwxgtk2.8-dev
+ - libgl1-mesa-dev
+ - libglu1-mesa-dev
+ - libpng3
+ - default-jdk
+ - g++
+ - xsltproc
+
+before_script:
+ - set -e
+ - export ERL_TOP=$PWD
+ - export PATH=$ERL_TOP/bin:$PATH
+ - export ERL_LIBS=''
+ - export MAKEFLAGS=-j6
+ - kerl_deactivate
+
+script:
+ - ./otp_build all -a
+
+after_success:
+ - ./otp_build tests && make release_docs
+
+after_script:
+ - cd $ERL_TOP/release/tests/test_server && $ERL_TOP/bin/erl -s ts install -s ts smoke_test batch -s init stop
+
+
diff --git a/HOWTO/INSTALL.md b/HOWTO/INSTALL.md
index 0dab438b10..51e8648a4a 100644
--- a/HOWTO/INSTALL.md
+++ b/HOWTO/INSTALL.md
@@ -210,6 +210,14 @@ the `$PATH`.
$ export PATH=$ERL_TOP/bin:$PATH # Assuming bash/sh
+For the FOP print formatter, two steps must be taken:
+
+* Adding the location of your installation of `fop` in `$FOP_HOME`.
+
+ $ export FOP_HOME=/path/to/fop/dir # Assuming bash/sh
+
+* Adding the `fop` script (in `$FOP_HOME`) to your `$PATH`, either by adding `$FOP_HOME` to `$PATH`, or by copying the `fop` script to a directory already in your `$PATH`.
+
Build the documentation.
$ make docs
@@ -508,7 +516,7 @@ If you have Xcode 4.3, or later, you will also need to download
If you want to build the `wx` application, you will need to get wxWidgets-3.0
(`wxWidgets-3.0.0.tar.bz2` from <http://sourceforge.net/projects/wxwindows/files/3.0.0/>) or get it from github with bug fixes:
- $ git clone --branch WX_3_0_branch [email protected]:wxWidgets/wxWidgets.git
+ $ git clone --branch WX_3_0_BRANCH [email protected]:wxWidgets/wxWidgets.git
Be aware that the wxWidgets-3.0 is a new release of wxWidgets, it is not as
mature as the old releases and the OS X port still lags behind the other ports.
diff --git a/OTP_VERSION b/OTP_VERSION
index 33718932a4..5f8e72c36b 100644
--- a/OTP_VERSION
+++ b/OTP_VERSION
@@ -1 +1 @@
-18.1
+18.1.5
diff --git a/erts/aclocal.m4 b/erts/aclocal.m4
index 390d6cfc4d..3d52538933 100644
--- a/erts/aclocal.m4
+++ b/erts/aclocal.m4
@@ -142,18 +142,18 @@ MIXED_MSYS=no
AC_MSG_CHECKING(for mixed cygwin or msys and native VC++ environment)
if test "X$host" = "Xwin32" -a "x$GCC" != "xyes"; then
- if test -x /usr/bin/cygpath; then
- CFLAGS="-O2"
- MIXED_CYGWIN=yes
- AC_MSG_RESULT([Cygwin and VC])
- MIXED_CYGWIN_VC=yes
- CPPFLAGS="$CPPFLAGS -DERTS_MIXED_CYGWIN_VC"
- elif test -x /usr/bin/msysinfo; then
+ if test -x /usr/bin/msys-?.0.dll; then
CFLAGS="-O2"
MIXED_MSYS=yes
AC_MSG_RESULT([MSYS and VC])
MIXED_MSYS_VC=yes
CPPFLAGS="$CPPFLAGS -DERTS_MIXED_MSYS_VC"
+ elif test -x /usr/bin/cygpath; then
+ CFLAGS="-O2"
+ MIXED_CYGWIN=yes
+ AC_MSG_RESULT([Cygwin and VC])
+ MIXED_CYGWIN_VC=yes
+ CPPFLAGS="$CPPFLAGS -DERTS_MIXED_CYGWIN_VC"
else
AC_MSG_RESULT([undeterminable])
AC_MSG_ERROR(Seems to be mixed windows but not with cygwin, cannot handle this!)
diff --git a/erts/doc/src/absform.xml b/erts/doc/src/absform.xml
index 547d5e583d..ca06794a53 100644
--- a/erts/doc/src/absform.xml
+++ b/erts/doc/src/absform.xml
@@ -11,7 +11,7 @@
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
-
+
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
@@ -19,7 +19,7 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-
+
</legalnotice>
<title>The Abstract Format</title>
@@ -35,24 +35,24 @@
<p></p>
<p>This document describes the standard representation of parse trees for Erlang
programs as Erlang terms. This representation is known as the <em>abstract format</em>.
- Functions dealing with such parse trees are <c><![CDATA[compile:forms/[1,2]]]></c>
+ Functions dealing with such parse trees are <c>compile:forms/[1,2]</c>
and functions in the modules
- <c><![CDATA[epp]]></c>,
- <c><![CDATA[erl_eval]]></c>,
- <c><![CDATA[erl_lint]]></c>,
- <c><![CDATA[erl_pp]]></c>,
- <c><![CDATA[erl_parse]]></c>,
+ <c>epp</c>,
+ <c>erl_eval</c>,
+ <c>erl_lint</c>,
+ <c>erl_pp</c>,
+ <c>erl_parse</c>,
and
- <c><![CDATA[io]]></c>.
+ <c>io</c>.
They are also used as input and output for parse transforms (see the module
- <c><![CDATA[compile]]></c>).</p>
- <p>We use the function <c><![CDATA[Rep]]></c> to denote the mapping from an Erlang source
- construct <c><![CDATA[C]]></c> to its abstract format representation <c><![CDATA[R]]></c>, and write
- <c><![CDATA[R = Rep(C)]]></c>.
+ <c>compile</c>).</p>
+ <p>We use the function <c>Rep</c> to denote the mapping from an Erlang source
+ construct <c>C</c> to its abstract format representation <c>R</c>, and write
+ <c>R = Rep(C)</c>.
</p>
- <p>The word <c><![CDATA[LINE]]></c> below represents an integer, and denotes the
+ <p>The word <c>LINE</c> below represents an integer, and denotes the
number of the line in the source file where the construction occurred.
- Several instances of <c><![CDATA[LINE]]></c> in the same construction may denote
+ Several instances of <c>LINE</c> in the same construction may denote
different lines.</p>
<p>Since operators are not terms in their own right, when operators are
mentioned below, the representation of an operator should be taken to
@@ -61,229 +61,116 @@
</p>
<section>
- <title>Module declarations and forms</title>
+ <title>Module Declarations and Forms</title>
<p>A module declaration consists of a sequence of forms that are either
function declarations or attributes.</p>
<list type="bulleted">
<item>If D is a module declaration consisting of the forms
- <c><![CDATA[F_1]]></c>, ..., <c><![CDATA[F_k]]></c>, then
- Rep(D) = <c><![CDATA[[Rep(F_1), ..., Rep(F_k)]]]></c>.</item>
- <item>If F is an attribute <c><![CDATA[-module(Mod)]]></c>, then
- Rep(F) = <c><![CDATA[{attribute,LINE,module,Mod}]]></c>.</item>
- <item>If F is an attribute <c><![CDATA[-export([Fun_1/A_1, ..., Fun_k/A_k])]]></c>, then
- Rep(F) = <c><![CDATA[{attribute,LINE,export,[{Fun_1,A_1}, ..., {Fun_k,A_k}]}]]></c>.</item>
- <item>If F is an attribute <c><![CDATA[-import(Mod,[Fun_1/A_1, ..., Fun_k/A_k])]]></c>, then
- Rep(F) = <c><![CDATA[{attribute,LINE,import,{Mod,[{Fun_1,A_1}, ..., {Fun_k,A_k}]}}]]></c>.</item>
- <item>If F is an attribute <c><![CDATA[-compile(Options)]]></c>, then
- Rep(F) = <c><![CDATA[{attribute,LINE,compile,Options}]]></c>.</item>
- <item>If F is an attribute <c><![CDATA[-file(File,Line)]]></c>, then
- Rep(F) = <c><![CDATA[{attribute,LINE,file,{File,Line}}]]></c>.</item>
- <item>If F is a record declaration <c><![CDATA[-record(Name,{V_1, ..., V_k})]]></c>, then
- Rep(F) =
- <c><![CDATA[{attribute,LINE,record,{Name,[Rep(V_1), ..., Rep(V_k)]}}]]></c>. For Rep(V), see below.</item>
- <item>If F is a type attribute (i.e. <c><![CDATA[opaque]]></c> or
- <c><![CDATA[type]]></c>)
- <c><![CDATA[-Attr Name(A_1, ..., A_k) :: T]]></c> where each
- <c><![CDATA[A_i]]></c> is a variable, then Rep(F) =
- <c><![CDATA[{attribute,LINE,Attr,{Name,Rep(T),[Rep(A_1), ..., Rep(A_k)]}}]]></c>.
- For Rep(T), see below.</item>
- <item>If F is a type spec (i.e. <c><![CDATA[callback]]></c> or
- <c><![CDATA[spec]]></c>)
- <c><![CDATA[-Attr F Tc_1; ...; Tc_k]]></c>,
- where each <c><![CDATA[Tc_i]]></c> is a fun type clause with an
- argument sequence of the same length <c><![CDATA[Arity]]></c>, then
- Rep(F) =
- <c><![CDATA[{Attr,LINE,{{F,Arity},[Rep(Tc_1), ..., Rep(Tc_k)]}}]]></c>.
- For Rep(Tc_i), see below.</item>
- <item>If F is a type spec (i.e. <c><![CDATA[callback]]></c> or
- <c><![CDATA[spec]]></c>)
- <c><![CDATA[-Attr Mod:F Tc_1; ...; Tc_k]]></c>,
- where each <c><![CDATA[Tc_i]]></c> is a fun type clause with an
- argument sequence of the same length <c><![CDATA[Arity]]></c>, then
- Rep(F) =
- <c><![CDATA[{Attr,LINE,{{Mod,F,Arity},[Rep(Tc_1), ..., Rep(Tc_k)]}}]]></c>.
- For Rep(Tc_i), see below.</item>
- <item>If F is a wild attribute <c><![CDATA[-A(T)]]></c>, then
- Rep(F) = <c><![CDATA[{attribute,LINE,A,T}]]></c>.
+ <c>F_1</c>, ..., <c>F_k</c>, then
+ Rep(D) = <c>[Rep(F_1), ..., Rep(F_k)]</c>.</item>
+ <item>If F is an attribute <c>-module(Mod)</c>, then
+ Rep(F) = <c>{attribute,LINE,module,Mod}</c>.</item>
+ <item>If F is an attribute <c>-behavior(Behavior)</c>, then
+ Rep(F) = <c>{attribute,LINE,behavior,Behavior}</c>.</item>
+ <item>If F is an attribute <c>-behaviour(Behaviour)</c>, then
+ Rep(F) = <c>{attribute,LINE,behaviour,Behaviour}</c>.</item>
+ <item>If F is an attribute <c>-export([Fun_1/A_1, ..., Fun_k/A_k])</c>, then
+ Rep(F) = <c>{attribute,LINE,export,[{Fun_1,A_1}, ..., {Fun_k,A_k}]}</c>.</item>
+ <item>If F is an attribute <c>-import(Mod,[Fun_1/A_1, ..., Fun_k/A_k])</c>, then
+ Rep(F) = <c>{attribute,LINE,import,{Mod,[{Fun_1,A_1}, ..., {Fun_k,A_k}]}}</c>.</item>
+ <item>If F is an attribute <c>-export_type([Type_1/A_1, ..., Type_k/A_k])</c>, then
+ Rep(F) = <c>{attribute,LINE,export_type,[{Type_1,A_1}, ..., {Type_k,A_k}]}</c>.</item>
+ <item>If F is an attribute <c>-compile(Options)</c>, then
+ Rep(F) = <c>{attribute,LINE,compile,Options}</c>.</item>
+ <item>If F is an attribute <c>-file(File,Line)</c>, then
+ Rep(F) = <c>{attribute,LINE,file,{File,Line}}</c>.</item>
+ <item>If F is a record declaration
+ <c>-record(Name,{V_1, ..., V_k})</c>, then Rep(F) =
+ <c>{attribute,LINE,record,{Name,[Rep(V_1), ..., Rep(V_k)]}}</c>.
+ For Rep(V), see below.</item>
+ <item>If F is a type declaration
+ <c>-Type Name(V_1, ..., V_k) :: T</c>, where
+ <c>Type</c> is either the atom <c>type</c> or the atom <c>opaque</c>,
+ each <c>V_i</c> is a variable, and <c>T</c> is a type, then Rep(F) =
+ <c>{attribute,LINE,Type,{Name,Rep(T),[Rep(V_1), ..., Rep(V_k)]}}</c>.
+ </item>
+ <item>If F is a function specification
+ <c>-Spec Name Ft_1; ...; Ft_k</c>,
+ where <c>Spec</c> is either the atom <c>spec</c> or the atom
+ <c>callback</c>, and each <c>Ft_i</c> is a possibly constrained
+ function type with an argument sequence of the same length
+ <c>Arity</c>, then Rep(F) =
+ <c>{attribute,Line,Spec,{{Name,Arity},[Rep(Ft_1), ..., Rep(Ft_k)]}}</c>.
+ </item>
+ <item>If F is a function specification
+ <c>-spec Mod:Name Ft_1; ...; Ft_k</c>,
+ where each <c>Ft_i</c> is a possibly constrained
+ function type with an argument sequence of the same length
+ <c>Arity</c>, then Rep(F) =
+ <c>{attribute,Line,spec,{{Mod,Name,Arity},[Rep(Ft_1), ..., Rep(Ft_k)]}}</c>.
+ </item>
+ <item>If F is a wild attribute <c>-A(T)</c>, then
+ Rep(F) = <c>{attribute,LINE,A,T}</c>.
<br></br></item>
- <item>If F is a function declaration <c><![CDATA[Name Fc_1 ; ... ; Name Fc_k]]></c>,
- where each <c><![CDATA[Fc_i]]></c> is a function clause with a
- pattern sequence of the same length <c><![CDATA[Arity]]></c>, then
- Rep(F) = <c><![CDATA[{function,LINE,Name,Arity,[Rep(Fc_1), ...,Rep(Fc_k)]}]]></c>.</item>
+ <item>If F is a function declaration
+ <c>Name Fc_1 ; ... ; Name Fc_k</c>,
+ where each <c>Fc_i</c> is a function clause with a
+ pattern sequence of the same length <c>Arity</c>, then
+ Rep(F) = <c>{function,LINE,Name,Arity,[Rep(Fc_1), ...,Rep(Fc_k)]}</c>.
+ </item>
</list>
<section>
- <title>Type clauses</title>
- <list type="bulleted">
- <item>If T is a fun type clause
- <c><![CDATA[(A_1, ..., A_n) -> Ret]]></c>, where each
- <c><![CDATA[A_i]]></c> and <c><![CDATA[Ret]]></c> are types, then
- Rep(T) =
- <c><![CDATA[{type,LINE,'fun',[{type,LINE,product,[Rep(A_1), ..., Rep(A_n)]},Rep(Ret)]}]]></c>.
- </item>
- <item>If T is a bounded fun type clause <c><![CDATA[Tc when Tg]]></c>,
- where <c><![CDATA[Tc]]></c> is an unbounded fun type clause and
- <c><![CDATA[Tg]]></c> is a type guard sequence, then Rep(T) =
- <c><![CDATA[{type,LINE,bounded_fun,[Rep(Tc),Rep(Tg)]}]]></c>.</item>
- </list>
- </section>
-
- <section>
- <title>Type guards</title>
- <list type="bulleted">
- <item>If G is a constraint <c><![CDATA[F(A_1, ..., A_k)]]></c>, where
- <c><![CDATA[F]]></c> is an atom and each <c><![CDATA[A_i]]></c> is a
- type, then Rep(G) =
- <c><![CDATA[{type,LINE,constraint,[Rep(F),[Rep(A_1), ..., Rep(A_k)]]}]]></c>.
- </item>
- <item>If G is a type definition <c><![CDATA[Name :: Type]]></c>,
- where <c><![CDATA[Name]]></c> is a variable and
- <c><![CDATA[Type]]></c> is a type, then Rep(G) =
- <c><![CDATA[{type,LINE,constraint,[{atom,LINE,is_subtype},[Rep(Name),Rep(Type)]]}]]></c>.</item>
- </list>
- </section>
-
- <section>
- <title>Types</title>
+ <title>Record Fields</title>
+ <p>Each field in a record declaration may have an optional
+ explicit default initializer expression, as well as an
+ optional type.</p>
<list type="bulleted">
- <item>If T is a type definition <c><![CDATA[Name :: Type]]></c>,
- where <c><![CDATA[Name]]></c> is a variable and
- <c><![CDATA[Type]]></c> is a type, then Rep(T) =
- <c><![CDATA[{ann_type,LINE,[Rep(Name),Rep(Type)]}]]></c>.</item>
- <item>If T is a type union <c><![CDATA[A_1 | ... | A_k]]></c>,
- where each <c><![CDATA[A_i]]></c> is a type, then Rep(T) =
- <c><![CDATA[{type,LINE,union,[Rep(A_1), ..., Rep(A_k)]}]]></c>.</item>
- <item>If T is a type range <c><![CDATA[L .. R]]></c>,
- where <c><![CDATA[L]]></c> and <c><![CDATA[R]]></c> are types, then
- Rep(T) = <c><![CDATA[{type,LINE,range,[Rep(L), Rep(R)]}]]></c>.</item>
- <item>If T is a binary operation <c><![CDATA[L Op R]]></c>,
- where <c><![CDATA[Op]]></c> is an arithmetic or bitwise binary operator
- and <c><![CDATA[L]]></c> and <c><![CDATA[R]]></c> are types, then
- Rep(T) = <c><![CDATA[{op,LINE,Op,Rep(L),Rep(R)}]]></c>.</item>
- <item>If T is <c><![CDATA[Op A]]></c>, where <c><![CDATA[Op]]></c> is an
- arithmetic or bitwise unary operator and <c><![CDATA[A]]></c> is a
- type, then Rep(T) = <c><![CDATA[{op,LINE,Op,Rep(A)}]]></c>.</item>
- <item>If T is a fun type <c><![CDATA[fun()]]></c>, then Rep(T) =
- <c><![CDATA[{type,LINE,'fun',[]}]]></c>.</item>
- <item>If T is a variable <c><![CDATA[V]]></c>, then Rep(T) =
- <c><![CDATA[{var,LINE,A}]]></c>, where <c><![CDATA[A]]></c> is an atom
- with a printname consisting of the same characters as
- <c><![CDATA[V]]></c>.</item>
- <item>If T is an atomic literal L and L is not a string literal, then
- Rep(T) = Rep(L).</item>
- <item>If T is a tuple or map type <c><![CDATA[F()]]></c> (i.e.
- <c><![CDATA[tuple]]></c> or <c><![CDATA[map]]></c>), then Rep(T) =
- <c><![CDATA[{type,LINE,F,any}]]></c>.</item>
- <item>If T is a type <c><![CDATA[F(A_1, ..., A_k)]]></c>, where each
- <c><![CDATA[A_i]]></c> is a type, then Rep(T) =
- <c><![CDATA[{user_type,LINE,F,[Rep(A_1), ..., Rep(A_k)]}]]></c>.</item>
- <item>If T is a remote type <c><![CDATA[M:F(A_1, ..., A_k)]]></c>, where
- each <c><![CDATA[A_i]]></c> is a type and <c><![CDATA[M]]></c> and
- <c><![CDATA[F]]></c>, then Rep(T) =
- <c><![CDATA[{remote_type,LINE,[Rep(M),Rep(F),[Rep(A_1), ..., Rep(A_k)]]}]]></c>.
+ <item>If V is <c>A</c>, then
+ Rep(V) = <c>{record_field,LINE,Rep(A)}</c>.</item>
+ <item>If V is <c>A = E</c>,
+ where <c>E</c> is an expression, then
+ Rep(V) = <c>{record_field,LINE,Rep(A),Rep(E)}</c>.</item>
+ <item>If V is <c>A :: T</c>, where <c>T</c> is a
+ type and it does not contain
+ <c>undefined</c> syntactically, then Rep(V) =
+ <c>{typed_record_field,{record_field,LINE,Rep(A)},Rep(undefined | T)}</c>.
</item>
- <item>If T is the nil type <c><![CDATA[[]]]></c>, then Rep(T) =
- <c><![CDATA[{type,LINE,nil,[]}]]></c>.</item>
- <item>If T is a list type <c><![CDATA[[A]]]></c>, where
- <c><![CDATA[A]]></c> is a type, then Rep(T) =
- <c><![CDATA[{type,LINE,list,[Rep(A)]}]]></c>.</item>
- <item>If T is a non-empty list type <c><![CDATA[[A, ...]]]></c>, where
- <c><![CDATA[A]]></c> is a type, then Rep(T) =
- <c><![CDATA[{type,LINE,nonempty_list,[Rep(A)]}]]></c>.</item>
- <item>If T is a map type <c><![CDATA[#{P_1, ..., P_k}]]></c>, where each
- <c><![CDATA[P_i]]></c> is a map pair type, then Rep(T) =
- <c><![CDATA[{type,LINE,map,[Rep(P_1), ..., Rep(P_k)]}]]></c>.</item>
- <item>If T is a map pair type <c><![CDATA[K => V]]></c>, where
- <c><![CDATA[K]]></c> and <c><![CDATA[V]]></c> are types,
- then Rep(T) =
- <c><![CDATA[{type,LINE,map_field_assoc,[Rep(K),Rep(V)]}]]></c>.</item>
- <item>If T is a tuple type <c><![CDATA[{A_1, ..., A_k}]]></c>, where
- each <c><![CDATA[A_i]]></c> is a type, then Rep(T) =
- <c><![CDATA[{type,LINE,tuple,[Rep(A_1), ..., Rep(A_k)]}]]></c>.</item>
- <item>If T is a record type <c><![CDATA[#Name{}]]></c>, where
- <c><![CDATA[Name]]></c> is an atom, then Rep(T) =
- <c><![CDATA[{type,LINE,record,[Rep(Name)]}]]></c>.</item>
- <item>If T is a record type <c><![CDATA[#Name{F_1, ..., F_k}]]></c>,
- where <c><![CDATA[Name]]></c> is an atom, then Rep(T) =
- <c><![CDATA[{type,LINE,record,[Rep(Name),[Rep(F_1), ..., Rep(F_k)]]}]]></c>.
+ <item>If V is <c>A :: T</c>, where <c>T</c> is a type, then Rep(V) =
+ <c>{typed_record_field,{record_field,LINE,Rep(A)},Rep(T)}</c>.
+ </item>
+ <item>If V is <c>A = E :: T</c>, where
+ <c>E</c> is an expression and <c>T</c> is a type, then Rep(V) =
+ <c>{typed_record_field,{record_field,LINE,Rep(A),Rep(E)},Rep(T)}</c>.
</item>
- <item>If T is a record field type <c><![CDATA[Name :: Type]]></c>,
- where <c><![CDATA[Name]]></c> is an atom, then Rep(T) =
- <c><![CDATA[{type,LINE,field_type,[Rep(Name),Rep(Type)]}]]></c>.</item>
- <item>If T is a record field type <c><![CDATA[<<>>]]></c>, then Rep(T) =
- <c><![CDATA[{type,LINE,binary,[{integer,LINE,0},{integer,LINE,0}]}]]></c>.
- </item>
- <item>If T is a binary type <c><![CDATA[<< _ : B >>]]></c>, where
- <c><![CDATA[B]]></c> is a type, then Rep(T) =
- <c><![CDATA[{type,LINE,binary,[Rep(B),{integer,LINE,0}]}]]></c>.</item>
- <item>If T is a binary type <c><![CDATA[<< _ : _ * U >>]]></c>,
- where <c><![CDATA[U]]></c> is a type, then Rep(T) =
- <c><![CDATA[{type,LINE,binary,[{integer,LINE,0},Rep(U)]}]]></c>.</item>
- <item>If T is a binary type <c><![CDATA[<< _ : B , _ : _ * U >>]]></c>,
- where <c><![CDATA[B]]></c> and <c><![CDATA[U]]></c> is a type, then
- Rep(T) =
- <c><![CDATA[{type,LINE,binary,[Rep(B),Rep(U)]}]]></c>.</item>
-
- <item>If T is a fun type <c><![CDATA[fun((...) -> Ret)]]></c>, then
- Rep(T) = <c><![CDATA[{type,LINE,'fun',[{type,LINE,product,[]},Rep(Ret)]}]]></c>.
- </item>
- <item>If T is a fun type <c><![CDATA[fun(Tc)]]></c>, where
- <c><![CDATA[Tc]]></c> is an unbounded fun type clause,
- then Rep(T) = <c><![CDATA[Rep(Tc)]]></c>.</item>
</list>
</section>
<section>
- <title>Record fields</title>
- <p>Each field in a record declaration may have an optional
- explicit default initializer expression</p>
- <list type="bulleted">
- <item>If V is <c><![CDATA[A]]></c>, then
- Rep(V) = <c><![CDATA[{record_field,LINE,Rep(A)}]]></c>.</item>
- <item>If V is <c><![CDATA[A = E]]></c>, then
- Rep(V) = <c><![CDATA[{record_field,LINE,Rep(A),Rep(E)}]]></c>.</item>
- <item>If V is <c><![CDATA[A :: T]]></c>, where <c><![CDATA[A]]></c> is
- an atom and <c><![CDATA[T]]></c> is a type and it does not contain
- <c><![CDATA[undefined]]></c> syntactically, then Rep(V) =
- <c><![CDATA[{typed_record_field,{record_field,LINE,Rep(A)},Rep(undefined | T)}]]></c>.
- Note that if <![CDATA[T]]> is an annotated type, it will be wrapped in
- parentheses.</item>
- <item>If V is <c><![CDATA[A :: T]]></c>, where <c><![CDATA[A]]></c> is
- an atom and <c><![CDATA[T]]></c> is a type, then Rep(V) =
- <c><![CDATA[{typed_record_field,{record_field,LINE,Rep(A)},Rep(T)}]]></c>.
- </item>
- <item>If V is <c><![CDATA[A = E :: T]]></c>, where <c><![CDATA[A]]></c>
- is an atom, <c><![CDATA[E]]></c> is an expression and
- <c><![CDATA[T]]></c> is a type, then Rep(V) =
- <c><![CDATA[{typed_record_field,{record_field,LINE,Rep(A),Rep(E)},Rep(T)}]]></c>.
- </item>
- </list>
- </section>
-
- <section>
- <title>Representation of parse errors and end of file</title>
+ <title>Representation of Parse Errors and End-of-file</title>
<p>In addition to the representations of forms, the list that represents
- a module declaration (as returned by functions in <c><![CDATA[erl_parse]]></c> and
- <c><![CDATA[epp]]></c>) may contain tuples <c><![CDATA[{error,E}]]></c> and <c><![CDATA[{warning,W}]]></c>, denoting
- syntactically incorrect forms and warnings, and <c><![CDATA[{eof,LINE}]]></c>, denoting an end
- of stream encountered before a complete form had been parsed.</p>
+ a module declaration (as returned by functions in <c>erl_parse</c> and
+ <c>epp</c>) may contain tuples <c>{error,E}</c> and
+ <c>{warning,W}</c>, denoting syntactically incorrect forms and
+ warnings, and <c>{eof,LINE}</c>, denoting an end-of-stream
+ encountered before a complete form had been parsed.</p>
</section>
</section>
<section>
- <title>Atomic literals</title>
+ <title>Atomic Literals</title>
<p>There are five kinds of atomic literals, which are represented in the
same way in patterns, expressions and guards:</p>
<list type="bulleted">
<item>If L is an integer or character literal, then
- Rep(L) = <c><![CDATA[{integer,LINE,L}]]></c>.</item>
+ Rep(L) = <c>{integer,LINE,L}</c>.</item>
<item>If L is a float literal, then
- Rep(L) = <c><![CDATA[{float,LINE,L}]]></c>.</item>
+ Rep(L) = <c>{float,LINE,L}</c>.</item>
<item>If L is a string literal consisting of the characters
- <c><![CDATA[C_1]]></c>, ..., <c><![CDATA[C_k]]></c>, then
- Rep(L) = <c><![CDATA[{string,LINE,[C_1, ..., C_k]}]]></c>.</item>
+ <c>C_1</c>, ..., <c>C_k</c>, then
+ Rep(L) = <c>{string,LINE,[C_1, ..., C_k]}</c>.</item>
<item>If L is an atom literal, then
- Rep(L) = <c><![CDATA[{atom,LINE,L}]]></c>.</item>
+ Rep(L) = <c>{atom,LINE,L}</c>.</item>
</list>
<p>Note that negative integer and float literals do not occur as such; they are
parsed as an application of the unary negation operator.</p>
@@ -291,47 +178,47 @@
<section>
<title>Patterns</title>
- <p>If <c><![CDATA[Ps]]></c> is a sequence of patterns <c><![CDATA[P_1, ..., P_k]]></c>, then
- Rep(Ps) = <c><![CDATA[[Rep(P_1), ..., Rep(P_k)]]]></c>. Such sequences occur as the
+ <p>If <c>Ps</c> is a sequence of patterns <c>P_1, ..., P_k</c>, then
+ Rep(Ps) = <c>[Rep(P_1), ..., Rep(P_k)]</c>. Such sequences occur as the
list of arguments to a function or fun.</p>
<p>Individual patterns are represented as follows:</p>
<list type="bulleted">
<item>If P is an atomic literal L, then Rep(P) = Rep(L).</item>
- <item>If P is a compound pattern <c><![CDATA[P_1 = P_2]]></c>, then
- Rep(P) = <c><![CDATA[{match,LINE,Rep(P_1),Rep(P_2)}]]></c>.</item>
- <item>If P is a variable pattern <c><![CDATA[V]]></c>, then
- Rep(P) = <c><![CDATA[{var,LINE,A}]]></c>,
+ <item>If P is a compound pattern <c>P_1 = P_2</c>, then
+ Rep(P) = <c>{match,LINE,Rep(P_1),Rep(P_2)}</c>.</item>
+ <item>If P is a variable pattern <c>V</c>, then
+ Rep(P) = <c>{var,LINE,A}</c>,
where A is an atom with a printname consisting of the same characters as
- <c><![CDATA[V]]></c>.</item>
- <item>If P is a universal pattern <c><![CDATA[_]]></c>, then
- Rep(P) = <c><![CDATA[{var,LINE,'_'}]]></c>.</item>
- <item>If P is a tuple pattern <c><![CDATA[{P_1, ..., P_k}]]></c>, then
- Rep(P) = <c><![CDATA[{tuple,LINE,[Rep(P_1), ..., Rep(P_k)]}]]></c>.</item>
- <item>If P is a nil pattern <c><![CDATA[[]]]></c>, then
- Rep(P) = <c><![CDATA[{nil,LINE}]]></c>.</item>
- <item>If P is a cons pattern <c><![CDATA[[P_h | P_t]]]></c>, then
- Rep(P) = <c><![CDATA[{cons,LINE,Rep(P_h),Rep(P_t)}]]></c>.</item>
- <item>If E is a binary pattern <c><![CDATA[<<P_1:Size_1/TSL_1, ..., P_k:Size_k/TSL_k>>]]></c>, then
- Rep(E) = <c><![CDATA[{bin,LINE,[{bin_element,LINE,Rep(P_1),Rep(Size_1),Rep(TSL_1)}, ..., {bin_element,LINE,Rep(P_k),Rep(Size_k),Rep(TSL_k)}]}]]></c>.
+ <c>V</c>.</item>
+ <item>If P is a universal pattern <c>_</c>, then
+ Rep(P) = <c>{var,LINE,'_'}</c>.</item>
+ <item>If P is a tuple pattern <c>{P_1, ..., P_k}</c>, then
+ Rep(P) = <c>{tuple,LINE,[Rep(P_1), ..., Rep(P_k)]}</c>.</item>
+ <item>If P is a nil pattern <c>[]</c>, then
+ Rep(P) = <c>{nil,LINE}</c>.</item>
+ <item>If P is a cons pattern <c>[P_h | P_t]</c>, then
+ Rep(P) = <c>{cons,LINE,Rep(P_h),Rep(P_t)}</c>.</item>
+ <item>If E is a binary pattern <c>&lt;&lt;P_1:Size_1/TSL_1, ..., P_k:Size_k/TSL_k>></c>, then
+ Rep(E) = <c>{bin,LINE,[{bin_element,LINE,Rep(P_1),Rep(Size_1),Rep(TSL_1)}, ..., {bin_element,LINE,Rep(P_k),Rep(Size_k),Rep(TSL_k)}]}</c>.
For Rep(TSL), see below.
- An omitted <c><![CDATA[Size]]></c> is represented by <c><![CDATA[default]]></c>. An omitted <c><![CDATA[TSL]]></c>
- (type specifier list) is represented by <c><![CDATA[default]]></c>.</item>
- <item>If P is <c><![CDATA[P_1 Op P_2]]></c>, where <c><![CDATA[Op]]></c> is a binary operator (this
- is either an occurrence of <c><![CDATA[++]]></c> applied to a literal string or character
+ An omitted <c>Size</c> is represented by <c>default</c>. An omitted <c>TSL</c>
+ (type specifier list) is represented by <c>default</c>.</item>
+ <item>If P is <c>P_1 Op P_2</c>, where <c>Op</c> is a binary operator (this
+ is either an occurrence of <c>++</c> applied to a literal string or character
list, or an occurrence of an expression that can be evaluated to a number
at compile time),
- then Rep(P) = <c><![CDATA[{op,LINE,Op,Rep(P_1),Rep(P_2)}]]></c>.</item>
- <item>If P is <c><![CDATA[Op P_0]]></c>, where <c><![CDATA[Op]]></c> is a unary operator (this is an
+ then Rep(P) = <c>{op,LINE,Op,Rep(P_1),Rep(P_2)}</c>.</item>
+ <item>If P is <c>Op P_0</c>, where <c>Op</c> is a unary operator (this is an
occurrence of an expression that can be evaluated to a number at compile
- time), then Rep(P) = <c><![CDATA[{op,LINE,Op,Rep(P_0)}]]></c>.</item>
- <item>If P is a record pattern <c><![CDATA[#Name{Field_1=P_1, ..., Field_k=P_k}]]></c>,
+ time), then Rep(P) = <c>{op,LINE,Op,Rep(P_0)}</c>.</item>
+ <item>If P is a record pattern <c>#Name{Field_1=P_1, ..., Field_k=P_k}</c>,
then Rep(P) =
- <c><![CDATA[{record,LINE,Name, [{record_field,LINE,Rep(Field_1),Rep(P_1)}, ..., {record_field,LINE,Rep(Field_k),Rep(P_k)}]}]]></c>.</item>
- <item>If P is <c><![CDATA[#Name.Field]]></c>, then
- Rep(P) = <c><![CDATA[{record_index,LINE,Name,Rep(Field)}]]></c>.</item>
- <item>If P is <c><![CDATA[( P_0 )]]></c>, then
- Rep(P) = <c><![CDATA[Rep(P_0)]]></c>,
- i.e., patterns cannot be distinguished from their bodies.</item>
+ <c>{record,LINE,Name,[{record_field,LINE,Rep(Field_1),Rep(P_1)}, ..., {record_field,LINE,Rep(Field_k),Rep(P_k)}]}</c>.</item>
+ <item>If P is <c>#Name.Field</c>, then
+ Rep(P) = <c>{record_index,LINE,Name,Rep(Field)}</c>.</item>
+ <item>If P is <c>( P_0 )</c>, then
+ Rep(P) = <c>Rep(P_0)</c>,
+ that is, patterns cannot be distinguished from their bodies.</item>
</list>
<p>Note that every pattern has the same source form as some expression, and is
represented the same way as the corresponding expression.</p>
@@ -339,180 +226,167 @@
<section>
<title>Expressions</title>
- <p>A body B is a sequence of expressions <c><![CDATA[E_1, ..., E_k]]></c>, and
- Rep(B) = <c><![CDATA[[Rep(E_1), ..., Rep(E_k)]]]></c>.</p>
+ <p>A body B is a sequence of expressions <c>E_1, ..., E_k</c>, and
+ Rep(B) = <c>[Rep(E_1), ..., Rep(E_k)]</c>.</p>
<p>An expression E is one of the following alternatives:</p>
<list type="bulleted">
- <item>If P is an atomic literal <c><![CDATA[L]]></c>, then
- Rep(P) = Rep(L).</item>
- <item>If E is <c><![CDATA[P = E_0]]></c>, then
- Rep(E) = <c><![CDATA[{match,LINE,Rep(P),Rep(E_0)}]]></c>.</item>
- <item>If E is a variable <c><![CDATA[V]]></c>, then
- Rep(E) = <c><![CDATA[{var,LINE,A}]]></c>,
- where <c><![CDATA[A]]></c> is an atom with a printname consisting of the same
- characters as <c><![CDATA[V]]></c>.</item>
- <item>If E is a tuple skeleton <c><![CDATA[{E_1, ..., E_k}]]></c>, then
- Rep(E) = <c><![CDATA[{tuple,LINE,[Rep(E_1), ..., Rep(E_k)]}]]></c>.</item>
- <item>If E is <c><![CDATA[[]]]></c>, then
- Rep(E) = <c><![CDATA[{nil,LINE}]]></c>.</item>
- <item>If E is a cons skeleton <c><![CDATA[[E_h | E_t]]]></c>, then
- Rep(E) = <c><![CDATA[{cons,LINE,Rep(E_h),Rep(E_t)}]]></c>.</item>
- <item>If E is a binary constructor <c><![CDATA[<<V_1:Size_1/TSL_1, ..., V_k:Size_k/TSL_k>>]]></c>, then
- Rep(E) = <c><![CDATA[{bin,LINE,[{bin_element,LINE,Rep(V_1),Rep(Size_1),Rep(TSL_1)}, ..., {bin_element,LINE,Rep(V_k),Rep(Size_k),Rep(TSL_k)}]}]]></c>.
+ <item>If P is an atomic literal <c>L</c>, then Rep(P) = Rep(L).</item>
+ <item>If E is <c>P = E_0</c>, then
+ Rep(E) = <c>{match,LINE,Rep(P),Rep(E_0)}</c>.</item>
+ <item>If E is a variable <c>V</c>, then Rep(E) = <c>{var,LINE,A}</c>,
+ where <c>A</c> is an atom with a printname consisting of the same
+ characters as <c>V</c>.</item>
+ <item>If E is a tuple skeleton <c>{E_1, ..., E_k}</c>, then
+ Rep(E) = <c>{tuple,LINE,[Rep(E_1), ..., Rep(E_k)]}</c>.</item>
+ <item>If E is <c>[]</c>, then
+ Rep(E) = <c>{nil,LINE}</c>.</item>
+ <item>If E is a cons skeleton <c>[E_h | E_t]</c>, then
+ Rep(E) = <c>{cons,LINE,Rep(E_h),Rep(E_t)}</c>.</item>
+ <item>If E is a binary constructor <c>&lt;&lt;V_1:Size_1/TSL_1, ..., V_k:Size_k/TSL_k>></c>, then Rep(E) =
+ <c>{bin,LINE,[{bin_element,LINE,Rep(V_1),Rep(Size_1),Rep(TSL_1)}, ..., {bin_element,LINE,Rep(V_k),Rep(Size_k),Rep(TSL_k)}]}</c>.
For Rep(TSL), see below.
- An omitted <c><![CDATA[Size]]></c> is represented by <c><![CDATA[default]]></c>. An omitted <c><![CDATA[TSL]]></c>
- (type specifier list) is represented by <c><![CDATA[default]]></c>.</item>
- <item>If E is <c><![CDATA[E_1 Op E_2]]></c>, where <c><![CDATA[Op]]></c> is a binary operator,
- then Rep(E) = <c><![CDATA[{op,LINE,Op,Rep(E_1),Rep(E_2)}]]></c>.</item>
- <item>If E is <c><![CDATA[Op E_0]]></c>, where <c><![CDATA[Op]]></c> is a unary operator, then
- Rep(E) = <c><![CDATA[{op,LINE,Op,Rep(E_0)}]]></c>.</item>
- <item>If E is <c><![CDATA[#Name{Field_1=E_1, ..., Field_k=E_k}]]></c>, then
- Rep(E) =
- <c><![CDATA[{record,LINE,Name, [{record_field,LINE,Rep(Field_1),Rep(E_1)}, ..., {record_field,LINE,Rep(Field_k),Rep(E_k)}]}]]></c>.</item>
- <item>If E is <c><![CDATA[E_0#Name{Field_1=E_1, ..., Field_k=E_k}]]></c>, then
+ An omitted <c>Size</c> is represented by <c>default</c>. An omitted <c>TSL</c>
+ (type specifier list) is represented by <c>default</c>.</item>
+ <item>If E is <c>E_1 Op E_2</c>, where <c>Op</c> is a binary operator,
+ then Rep(E) = <c>{op,LINE,Op,Rep(E_1),Rep(E_2)}</c>.</item>
+ <item>If E is <c>Op E_0</c>, where <c>Op</c> is a unary operator, then
+ Rep(E) = <c>{op,LINE,Op,Rep(E_0)}</c>.</item>
+ <item>If E is <c>#Name{Field_1=E_1, ..., Field_k=E_k}</c>,
+ then Rep(E) =
+ <c>{record,LINE,Name,[{record_field,LINE,Rep(Field_1),Rep(E_1)}, ..., {record_field,LINE,Rep(Field_k),Rep(E_k)}]}</c>.</item>
+ <item>If E is <c>E_0#Name{Field_1=E_1, ..., Field_k=E_k}</c>, then
Rep(E) =
- <c><![CDATA[{record,LINE,Rep(E_0),Name, [{record_field,LINE,Rep(Field_1),Rep(E_1)}, ..., {record_field,LINE,Rep(Field_k),Rep(E_k)}]}]]></c>.</item>
- <item>If E is <c><![CDATA[#Name.Field]]></c>, then
- Rep(E) = <c><![CDATA[{record_index,LINE,Name,Rep(Field)}]]></c>.</item>
- <item>If E is <c><![CDATA[E_0#Name.Field]]></c>, then
- Rep(E) = <c><![CDATA[{record_field,LINE,Rep(E_0),Name,Rep(Field)}]]></c>.</item>
- <item>If E is <c><![CDATA[#{W_1, ..., W_k}]]></c> where each
- <c><![CDATA[W_i]]></c> is a map assoc or exact field, then Rep(E) =
- <c><![CDATA[{map,LINE,[Rep(W_1), ..., Rep(W_k)]}]]></c>. For Rep(W), see
+ <c>{record,LINE,Rep(E_0),Name,[{record_field,LINE,Rep(Field_1),Rep(E_1)}, ..., {record_field,LINE,Rep(Field_k),Rep(E_k)}]}</c>.</item>
+ <item>If E is <c>#Name.Field</c>, then
+ Rep(E) = <c>{record_index,LINE,Name,Rep(Field)}</c>.</item>
+ <item>If E is <c>E_0#Name.Field</c>, then
+ Rep(E) = <c>{record_field,LINE,Rep(E_0),Name,Rep(Field)}</c>.</item>
+ <item>If E is <c>#{W_1, ..., W_k}</c> where each
+ <c>W_i</c> is a map assoc or exact field, then Rep(E) =
+ <c>{map,LINE,[Rep(W_1), ..., Rep(W_k)]}</c>. For Rep(W), see
below.</item>
- <item>If E is <c><![CDATA[E_0#{W_1, ..., W_k}]]></c> where
- <c><![CDATA[W_i]]></c> is a map assoc or exact field, then Rep(E) =
- <c><![CDATA[{map,LINE,Rep(E_0),[Rep(W_1), ..., Rep(W_k)]}]]></c>. For
- Rep(W), see below.</item>
- <item>If E is <c><![CDATA[catch E_0]]></c>, then
- Rep(E) = <c><![CDATA[{'catch',LINE,Rep(E_0)}]]></c>.</item>
- <item>If E is <c><![CDATA[E_0(E_1, ..., E_k)]]></c>, then
- Rep(E) = <c><![CDATA[{call,LINE,Rep(E_0),[Rep(E_1), ..., Rep(E_k)]}]]></c>.</item>
- <item>If E is <c><![CDATA[E_m:E_0(E_1, ..., E_k)]]></c>, then
- Rep(E) =
- <c><![CDATA[{call,LINE,{remote,LINE,Rep(E_m),Rep(E_0)},[Rep(E_1), ..., Rep(E_k)]}]]></c>.</item>
- <item>If E is a list comprehension <c><![CDATA[[E_0 || W_1, ..., W_k]]]></c>,
- where each <c><![CDATA[W_i]]></c> is a generator or a filter, then
- Rep(E) = <c><![CDATA[{lc,LINE,Rep(E_0),[Rep(W_1), ..., Rep(W_k)]}]]></c>. For Rep(W), see
- below.</item>
- <item>If E is a binary comprehension <c><![CDATA[<<E_0 || W_1, ..., W_k>>]]></c>,
- where each <c><![CDATA[W_i]]></c> is a generator or a filter, then
- Rep(E) = <c><![CDATA[{bc,LINE,Rep(E_0),[Rep(W_1), ..., Rep(W_k)]}]]></c>. For Rep(W), see
+ <item>If E is <c>E_0#{W_1, ..., W_k}</c> where
+ <c>W_i</c> is a map assoc or exact field, then Rep(E) =
+ <c>{map,LINE,Rep(E_0),[Rep(W_1), ..., Rep(W_k)]}</c>.
+ For Rep(W), see below.</item>
+ <item>If E is <c>catch E_0</c>, then
+ Rep(E) = <c>{'catch',LINE,Rep(E_0)}</c>.</item>
+ <item>If E is <c>E_0(E_1, ..., E_k)</c>, then
+ Rep(E) = <c>{call,LINE,Rep(E_0),[Rep(E_1), ..., Rep(E_k)]}</c>.</item>
+ <item>If E is <c>E_m:E_0(E_1, ..., E_k)</c>, then Rep(E) =
+ <c>{call,LINE,{remote,LINE,Rep(E_m),Rep(E_0)},[Rep(E_1), ..., Rep(E_k)]}</c>.
+ </item>
+ <item>If E is a list comprehension <c>[E_0 || W_1, ..., W_k]</c>,
+ where each <c>W_i</c> is a generator or a filter, then Rep(E) =
+ <c>{lc,LINE,Rep(E_0),[Rep(W_1), ..., Rep(W_k)]}</c>. For Rep(W), see
below.</item>
- <item>If E is <c><![CDATA[begin B end]]></c>, where <c><![CDATA[B]]></c> is a body, then
- Rep(E) = <c><![CDATA[{block,LINE,Rep(B)}]]></c>.</item>
- <item>If E is <c><![CDATA[if Ic_1 ; ... ; Ic_k end]]></c>,
- where each <c><![CDATA[Ic_i]]></c> is an if clause then
- Rep(E) =
- <c><![CDATA[{'if',LINE,[Rep(Ic_1), ..., Rep(Ic_k)]}]]></c>.</item>
- <item>If E is <c><![CDATA[case E_0 of Cc_1 ; ... ; Cc_k end]]></c>,
- where <c><![CDATA[E_0]]></c> is an expression and each <c><![CDATA[Cc_i]]></c> is a
- case clause then
- Rep(E) =
- <c><![CDATA[{'case',LINE,Rep(E_0),[Rep(Cc_1), ..., Rep(Cc_k)]}]]></c>.</item>
- <item>If E is <c><![CDATA[try B catch Tc_1 ; ... ; Tc_k end]]></c>,
- where <c><![CDATA[B]]></c> is a body and each <c><![CDATA[Tc_i]]></c> is a catch clause then
- Rep(E) =
- <c><![CDATA[{'try',LINE,Rep(B),[],[Rep(Tc_1), ..., Rep(Tc_k)],[]}]]></c>.</item>
- <item>If E is <c><![CDATA[try B of Cc_1 ; ... ; Cc_k catch Tc_1 ; ... ; Tc_n end]]></c>,
- where <c><![CDATA[B]]></c> is a body,
- each <c><![CDATA[Cc_i]]></c> is a case clause and
- each <c><![CDATA[Tc_j]]></c> is a catch clause then
- Rep(E) =
- <c><![CDATA[{'try',LINE,Rep(B),[Rep(Cc_1), ..., Rep(Cc_k)],[Rep(Tc_1), ..., Rep(Tc_n)],[]}]]></c>.</item>
- <item>If E is <c><![CDATA[try B after A end]]></c>,
- where <c><![CDATA[B]]></c> and <c><![CDATA[A]]></c> are bodies then
- Rep(E) =
- <c><![CDATA[{'try',LINE,Rep(B),[],[],Rep(A)}]]></c>.</item>
- <item>If E is <c><![CDATA[try B of Cc_1 ; ... ; Cc_k after A end]]></c>,
- where <c><![CDATA[B]]></c> and <c><![CDATA[A]]></c> are a bodies and
- each <c><![CDATA[Cc_i]]></c> is a case clause then
- Rep(E) =
- <c><![CDATA[{'try',LINE,Rep(B),[Rep(Cc_1), ..., Rep(Cc_k)],[],Rep(A)}]]></c>.</item>
- <item>If E is <c><![CDATA[try B catch Tc_1 ; ... ; Tc_k after A end]]></c>,
- where <c><![CDATA[B]]></c> and <c><![CDATA[A]]></c> are bodies and
- each <c><![CDATA[Tc_i]]></c> is a catch clause then
- Rep(E) =
- <c><![CDATA[{'try',LINE,Rep(B),[],[Rep(Tc_1), ..., Rep(Tc_k)],Rep(A)}]]></c>.</item>
- <item>If E is <c><![CDATA[try B of Cc_1 ; ... ; Cc_k catch Tc_1 ; ... ; Tc_n after A end]]></c>,
- where <c><![CDATA[B]]></c> and <c><![CDATA[A]]></c> are a bodies,
- each <c><![CDATA[Cc_i]]></c> is a case clause and
- each <c><![CDATA[Tc_j]]></c> is a catch clause then
- Rep(E) =
- <c><![CDATA[{'try',LINE,Rep(B),[Rep(Cc_1), ..., Rep(Cc_k)],[Rep(Tc_1), ..., Rep(Tc_n)],Rep(A)}]]></c>.</item>
- <item>If E is <c><![CDATA[receive Cc_1 ; ... ; Cc_k end]]></c>,
- where each <c><![CDATA[Cc_i]]></c> is a case clause then
+ <item>If E is a binary comprehension
+ <c>&lt;&lt;E_0 || W_1, ..., W_k>></c>,
+ where each <c>W_i</c> is a generator or a filter, then
+ Rep(E) = <c>{bc,LINE,Rep(E_0),[Rep(W_1), ..., Rep(W_k)]}</c>.
+ For Rep(W), see below.</item>
+ <item>If E is <c>begin B end</c>, where <c>B</c> is a body, then
+ Rep(E) = <c>{block,LINE,Rep(B)}</c>.</item>
+ <item>If E is <c>if Ic_1 ; ... ; Ic_k end</c>,
+ where each <c>Ic_i</c> is an if clause then Rep(E) =
+ <c>{'if',LINE,[Rep(Ic_1), ..., Rep(Ic_k)]}</c>.</item>
+ <item>If E is <c>case E_0 of Cc_1 ; ... ; Cc_k end</c>,
+ where <c>E_0</c> is an expression and each <c>Cc_i</c> is a
+ case clause then Rep(E) =
+ <c>{'case',LINE,Rep(E_0),[Rep(Cc_1), ..., Rep(Cc_k)]}</c>.</item>
+ <item>If E is <c>try B catch Tc_1 ; ... ; Tc_k end</c>,
+ where <c>B</c> is a body and each <c>Tc_i</c> is a catch clause then
Rep(E) =
- <c><![CDATA[{'receive',LINE,[Rep(Cc_1), ..., Rep(Cc_k)]}]]></c>.</item>
- <item>If E is <c><![CDATA[receive Cc_1 ; ... ; Cc_k after E_0 -> B_t end]]></c>,
- where each <c><![CDATA[Cc_i]]></c> is a case clause,
- <c><![CDATA[E_0]]></c> is an expression and <c><![CDATA[B_t]]></c> is a body, then
+ <c>{'try',LINE,Rep(B),[],[Rep(Tc_1), ..., Rep(Tc_k)],[]}</c>.</item>
+ <item>If E is <c>try B of Cc_1 ; ... ; Cc_k catch Tc_1 ; ... ; Tc_n end</c>,
+ where <c>B</c> is a body,
+ each <c>Cc_i</c> is a case clause and
+ each <c>Tc_j</c> is a catch clause then Rep(E) =
+ <c>{'try',LINE,Rep(B),[Rep(Cc_1), ..., Rep(Cc_k)],[Rep(Tc_1), ..., Rep(Tc_n)],[]}</c>.</item>
+ <item>If E is <c>try B after A end</c>,
+ where <c>B</c> and <c>A</c> are bodies then Rep(E) =
+ <c>{'try',LINE,Rep(B),[],[],Rep(A)}</c>.</item>
+ <item>If E is <c>try B of Cc_1 ; ... ; Cc_k after A end</c>,
+ where <c>B</c> and <c>A</c> are a bodies and
+ each <c>Cc_i</c> is a case clause then Rep(E) =
+ <c>{'try',LINE,Rep(B),[Rep(Cc_1), ..., Rep(Cc_k)],[],Rep(A)}</c>.</item>
+ <item>If E is <c>try B catch Tc_1 ; ... ; Tc_k after A end</c>,
+ where <c>B</c> and <c>A</c> are bodies and
+ each <c>Tc_i</c> is a catch clause then Rep(E) =
+ <c>{'try',LINE,Rep(B),[],[Rep(Tc_1), ..., Rep(Tc_k)],Rep(A)}</c>.</item>
+ <item>If E is <c>try B of Cc_1 ; ... ; Cc_k catch Tc_1 ; ... ; Tc_n after A end</c>,
+ where <c>B</c> and <c>A</c> are a bodies,
+ each <c>Cc_i</c> is a case clause and
+ each <c>Tc_j</c> is a catch clause then
Rep(E) =
- <c><![CDATA[{'receive',LINE,[Rep(Cc_1), ..., Rep(Cc_k)],Rep(E_0),Rep(B_t)}]]></c>.</item>
- <item>If E is <c><![CDATA[fun Name / Arity]]></c>, then
- Rep(E) = <c><![CDATA[{'fun',LINE,{function,Name,Arity}}]]></c>.</item>
- <item>If E is <c><![CDATA[fun Module:Name/Arity]]></c>, then
- Rep(E) = <c><![CDATA[{'fun',LINE,{function,Rep(Module),Rep(Name),Rep(Arity)}}]]></c>.
- (Before the R15 release: Rep(E) = <c><![CDATA[{'fun',LINE,{function,Module,Name,Arity}}]]></c>.)</item>
- <item>If E is <c><![CDATA[fun Fc_1 ; ... ; Fc_k end]]></c>
- where each <c><![CDATA[Fc_i]]></c> is a function clause then Rep(E) =
- <c><![CDATA[{'fun',LINE,{clauses,[Rep(Fc_1), ..., Rep(Fc_k)]}}]]></c>.</item>
- <item>If E is <c><![CDATA[fun Name Fc_1 ; ... ; Name Fc_k end]]></c>
- where <c><![CDATA[Name]]></c> is a variable and each
- <c><![CDATA[Fc_i]]></c> is a function clause then Rep(E) =
- <c><![CDATA[{named_fun,LINE,Name,[Rep(Fc_1), ..., Rep(Fc_k)]}]]></c>.
+ <c>{'try',LINE,Rep(B),[Rep(Cc_1), ..., Rep(Cc_k)],[Rep(Tc_1), ..., Rep(Tc_n)],Rep(A)}</c>.</item>
+ <item>If E is <c>receive Cc_1 ; ... ; Cc_k end</c>,
+ where each <c>Cc_i</c> is a case clause then Rep(E) =
+ <c>{'receive',LINE,[Rep(Cc_1), ..., Rep(Cc_k)]}</c>.</item>
+ <item>If E is <c>receive Cc_1 ; ... ; Cc_k after E_0 -> B_t end</c>,
+ where each <c>Cc_i</c> is a case clause,
+ <c>E_0</c> is an expression and <c>B_t</c> is a body, then Rep(E) =
+ <c>{'receive',LINE,[Rep(Cc_1), ..., Rep(Cc_k)],Rep(E_0),Rep(B_t)}</c>.</item>
+ <item>If E is <c>fun Name / Arity</c>, then
+ Rep(E) = <c>{'fun',LINE,{function,Name,Arity}}</c>.</item>
+ <item>If E is <c>fun Module:Name/Arity</c>, then Rep(E) =
+ <c>{'fun',LINE,{function,Rep(Module),Rep(Name),Rep(Arity)}}</c>.
+ (Before the R15 release: Rep(E) =
+ <c>{'fun',LINE,{function,Module,Name,Arity}}</c>.)</item>
+ <item>If E is <c>fun Fc_1 ; ... ; Fc_k end</c>
+ where each <c>Fc_i</c> is a function clause then Rep(E) =
+ <c>{'fun',LINE,{clauses,[Rep(Fc_1), ..., Rep(Fc_k)]}}</c>.</item>
+ <item>If E is <c>fun Name Fc_1 ; ... ; Name Fc_k end</c>
+ where <c>Name</c> is a variable and each
+ <c>Fc_i</c> is a function clause then Rep(E) =
+ <c>{named_fun,LINE,Name,[Rep(Fc_1), ..., Rep(Fc_k)]}</c>.
</item>
- <item>If E is <c><![CDATA[query [E_0 || W_1, ..., W_k] end]]></c>,
- where each <c><![CDATA[W_i]]></c> is a generator or a filter, then
- Rep(E) = <c><![CDATA[{'query',LINE,{lc,LINE,Rep(E_0),[Rep(W_1), ..., Rep(W_k)]}}]]></c>.
- For Rep(W), see below.</item>
- <item>If E is <c><![CDATA[E_0.Field]]></c>, a Mnesia record access
- inside a query, then
- Rep(E) = <c><![CDATA[{record_field,LINE,Rep(E_0),Rep(Field)}]]></c>.</item>
- <item>If E is <c><![CDATA[( E_0 )]]></c>, then
- Rep(E) = <c><![CDATA[Rep(E_0)]]></c>,
- i.e., parenthesized expressions cannot be distinguished from their bodies.</item>
+ <item>If E is <c>( E_0 )</c>, then
+ Rep(E) = <c>Rep(E_0)</c>, that is, parenthesized
+ expressions cannot be distinguished from their bodies.</item>
</list>
<section>
- <title>Generators and filters</title>
- <p>When W is a generator or a filter (in the body of a list or binary comprehension), then:</p>
+ <title>Generators and Filters</title>
+ <p>When W is a generator or a filter (in the body of a list or
+ binary comprehension), then:</p>
<list type="bulleted">
- <item>If W is a generator <c><![CDATA[P <- E]]></c>, where <c><![CDATA[P]]></c> is a pattern and <c><![CDATA[E]]></c>
- is an expression, then
- Rep(W) = <c><![CDATA[{generate,LINE,Rep(P),Rep(E)}]]></c>.</item>
- <item>If W is a generator <c><![CDATA[P <= E]]></c>, where <c><![CDATA[P]]></c> is a pattern and <c><![CDATA[E]]></c>
- is an expression, then
- Rep(W) = <c><![CDATA[{b_generate,LINE,Rep(P),Rep(E)}]]></c>.</item>
- <item>If W is a filter <c><![CDATA[E]]></c>, which is an expression, then
- Rep(W) = <c><![CDATA[Rep(E)]]></c>.</item>
+ <item>If W is a generator <c>P &lt;- E</c>, where <c>P</c> is
+ a pattern and <c>E</c> is an expression, then
+ Rep(W) = <c>{generate,LINE,Rep(P),Rep(E)}</c>.</item>
+ <item>If W is a generator <c>P &lt;= E</c>, where <c>P</c> is
+ a pattern and <c>E</c> is an expression, then
+ Rep(W) = <c>{b_generate,LINE,Rep(P),Rep(E)}</c>.</item>
+ <item>If W is a filter <c>E</c>, which is an expression, then
+ Rep(W) = <c>Rep(E)</c>.</item>
</list>
</section>
<section>
- <title>Binary element type specifiers</title>
+ <title>Binary Element Type Specifiers</title>
<p>A type specifier list TSL for a binary element is a sequence of type
- specifiers <c><![CDATA[TS_1 - ... - TS_k]]></c>.
- Rep(TSL) = <c><![CDATA[[Rep(TS_1), ..., Rep(TS_k)]]]></c>.</p>
+ specifiers <c>TS_1 - ... - TS_k</c>.
+ Rep(TSL) = <c>[Rep(TS_1), ..., Rep(TS_k)]</c>.</p>
<p>When TS is a type specifier for a binary element, then:</p>
<list type="bulleted">
- <item>If TS is an atom <c><![CDATA[A]]></c>, Rep(TS) = <c><![CDATA[A]]></c>.</item>
- <item>If TS is a couple <c><![CDATA[A:Value]]></c> where <c><![CDATA[A]]></c> is an atom and <c><![CDATA[Value]]></c>
- is an integer, Rep(TS) = <c><![CDATA[{A, Value}]]></c>.</item>
+ <item>If TS is an atom <c>A</c>, then Rep(TS) = <c>A</c>.</item>
+ <item>If TS is a couple <c>A:Value</c> where <c>A</c> is an atom
+ and <c>Value</c> is an integer, then Rep(TS) =
+ <c>{A,Value}</c>.</item>
</list>
</section>
<section>
- <title>Map assoc and exact fields</title>
+ <title>Map Assoc and Exact Fields</title>
<p>When W is an assoc or exact field (in the body of a map), then:</p>
<list type="bulleted">
- <item>If W is an assoc field <c><![CDATA[K => V]]></c>, where
- <c><![CDATA[K]]></c> and <c><![CDATA[V]]></c> are both expressions,
- then Rep(W) = <c><![CDATA[{map_field_assoc,LINE,Rep(K),Rep(V)}]]></c>.
+ <item>If W is an assoc field <c>K => V</c>, where
+ <c>K</c> and <c>V</c> are both expressions,
+ then Rep(W) = <c>{map_field_assoc,LINE,Rep(K),Rep(V)}</c>.
</item>
- <item>If W is an exact field <c><![CDATA[K := V]]></c>, where
- <c><![CDATA[K]]></c> and <c><![CDATA[V]]></c> are both expressions,
- then Rep(W) = <c><![CDATA[{map_field_exact,LINE,Rep(K),Rep(V)}]]></c>.
+ <item>If W is an exact field <c>K := V</c>, where
+ <c>K</c> and <c>V</c> are both expressions,
+ then Rep(W) = <c>{map_field_exact,LINE,Rep(K),Rep(V)}</c>.
</item>
</list>
</section>
@@ -520,112 +394,220 @@
<section>
<title>Clauses</title>
- <p>There are function clauses, if clauses, case clauses
+ <p>There are function clauses, if clauses, case clauses
and catch clauses.</p>
- <p>A clause <c><![CDATA[C]]></c> is one of the following alternatives:</p>
+ <p>A clause <c>C</c> is one of the following alternatives:</p>
<list type="bulleted">
- <item>If C is a function clause <c><![CDATA[( Ps ) -> B]]></c>
- where <c><![CDATA[Ps]]></c> is a pattern sequence and <c><![CDATA[B]]></c> is a body, then
- Rep(C) = <c><![CDATA[{clause,LINE,Rep(Ps),[],Rep(B)}]]></c>.</item>
- <item>If C is a function clause <c><![CDATA[( Ps ) when Gs -> B]]></c>
- where <c><![CDATA[Ps]]></c> is a pattern sequence,
- <c><![CDATA[Gs]]></c> is a guard sequence and <c><![CDATA[B]]></c> is a body, then
- Rep(C) = <c><![CDATA[{clause,LINE,Rep(Ps),Rep(Gs),Rep(B)}]]></c>.</item>
- <item>If C is an if clause <c><![CDATA[Gs -> B]]></c>
- where <c><![CDATA[Gs]]></c> is a guard sequence and <c><![CDATA[B]]></c> is a body, then
- Rep(C) = <c><![CDATA[{clause,LINE,[],Rep(Gs),Rep(B)}]]></c>.</item>
- <item>If C is a case clause <c><![CDATA[P -> B]]></c>
- where <c><![CDATA[P]]></c> is a pattern and <c><![CDATA[B]]></c> is a body, then
- Rep(C) = <c><![CDATA[{clause,LINE,[Rep(P)],[],Rep(B)}]]></c>.</item>
- <item>If C is a case clause <c><![CDATA[P when Gs -> B]]></c>
- where <c><![CDATA[P]]></c> is a pattern,
- <c><![CDATA[Gs]]></c> is a guard sequence and <c><![CDATA[B]]></c> is a body, then
- Rep(C) = <c><![CDATA[{clause,LINE,[Rep(P)],Rep(Gs),Rep(B)}]]></c>.</item>
- <item>If C is a catch clause <c><![CDATA[P -> B]]></c>
- where <c><![CDATA[P]]></c> is a pattern and <c><![CDATA[B]]></c> is a body, then
- Rep(C) = <c><![CDATA[{clause,LINE,[Rep({throw,P,_})],[],Rep(B)}]]></c>.</item>
- <item>If C is a catch clause <c><![CDATA[X : P -> B]]></c>
- where <c><![CDATA[X]]></c> is an atomic literal or a variable pattern,
- <c><![CDATA[P]]></c> is a pattern and <c><![CDATA[B]]></c> is a body, then
- Rep(C) = <c><![CDATA[{clause,LINE,[Rep({X,P,_})],[],Rep(B)}]]></c>.</item>
- <item>If C is a catch clause <c><![CDATA[P when Gs -> B]]></c>
- where <c><![CDATA[P]]></c> is a pattern, <c><![CDATA[Gs]]></c> is a guard sequence
- and <c><![CDATA[B]]></c> is a body, then
- Rep(C) = <c><![CDATA[{clause,LINE,[Rep({throw,P,_})],Rep(Gs),Rep(B)}]]></c>.</item>
- <item>If C is a catch clause <c><![CDATA[X : P when Gs -> B]]></c>
- where <c><![CDATA[X]]></c> is an atomic literal or a variable pattern,
- <c><![CDATA[P]]></c> is a pattern, <c><![CDATA[Gs]]></c> is a guard sequence
- and <c><![CDATA[B]]></c> is a body, then
- Rep(C) = <c><![CDATA[{clause,LINE,[Rep({X,P,_})],Rep(Gs),Rep(B)}]]></c>.</item>
+ <item>If C is a function clause <c>( Ps ) -> B</c>
+ where <c>Ps</c> is a pattern sequence and <c>B</c> is a body, then
+ Rep(C) = <c>{clause,LINE,Rep(Ps),[],Rep(B)}</c>.</item>
+ <item>If C is a function clause <c>( Ps ) when Gs -> B</c>
+ where <c>Ps</c> is a pattern sequence,
+ <c>Gs</c> is a guard sequence and <c>B</c> is a body, then
+ Rep(C) = <c>{clause,LINE,Rep(Ps),Rep(Gs),Rep(B)}</c>.</item>
+ <item>If C is an if clause <c>Gs -> B</c>
+ where <c>Gs</c> is a guard sequence and <c>B</c> is a body, then
+ Rep(C) = <c>{clause,LINE,[],Rep(Gs),Rep(B)}</c>.</item>
+ <item>If C is a case clause <c>P -> B</c>
+ where <c>P</c> is a pattern and <c>B</c> is a body, then
+ Rep(C) = <c>{clause,LINE,[Rep(P)],[],Rep(B)}</c>.</item>
+ <item>If C is a case clause <c>P when Gs -> B</c>
+ where <c>P</c> is a pattern,
+ <c>Gs</c> is a guard sequence and <c>B</c> is a body, then
+ Rep(C) = <c>{clause,LINE,[Rep(P)],Rep(Gs),Rep(B)}</c>.</item>
+ <item>If C is a catch clause <c>P -> B</c>
+ where <c>P</c> is a pattern and <c>B</c> is a body, then
+ Rep(C) = <c>{clause,LINE,[Rep({throw,P,_})],[],Rep(B)}</c>.</item>
+ <item>If C is a catch clause <c>X : P -> B</c>
+ where <c>X</c> is an atomic literal or a variable pattern,
+ <c>P</c> is a pattern and <c>B</c> is a body, then
+ Rep(C) = <c>{clause,LINE,[Rep({X,P,_})],[],Rep(B)}</c>.</item>
+ <item>If C is a catch clause <c>P when Gs -> B</c>
+ where <c>P</c> is a pattern, <c>Gs</c> is a guard sequence
+ and <c>B</c> is a body, then
+ Rep(C) = <c>{clause,LINE,[Rep({throw,P,_})],Rep(Gs),Rep(B)}</c>.</item>
+ <item>If C is a catch clause <c>X : P when Gs -> B</c>
+ where <c>X</c> is an atomic literal or a variable pattern,
+ <c>P</c> is a pattern, <c>Gs</c> is a guard sequence
+ and <c>B</c> is a body, then
+ Rep(C) = <c>{clause,LINE,[Rep({X,P,_})],Rep(Gs),Rep(B)}</c>.</item>
</list>
</section>
<section>
<title>Guards</title>
- <p>A guard sequence Gs is a sequence of guards <c><![CDATA[G_1; ...; G_k]]></c>, and
- Rep(Gs) = <c><![CDATA[[Rep(G_1), ..., Rep(G_k)]]]></c>. If the guard sequence is
- empty, Rep(Gs) = <c><![CDATA[[]]]></c>.</p>
- <p>A guard G is a nonempty sequence of guard tests <c><![CDATA[Gt_1, ..., Gt_k]]></c>, and
- Rep(G) = <c><![CDATA[[Rep(Gt_1), ..., Rep(Gt_k)]]]></c>.</p>
- <p>A guard test <c><![CDATA[Gt]]></c> is one of the following alternatives:</p>
+ <p>A guard sequence Gs is a sequence of guards <c>G_1; ...; G_k</c>, and
+ Rep(Gs) = <c>[Rep(G_1), ..., Rep(G_k)]</c>. If the guard sequence is
+ empty, Rep(Gs) = <c>[]</c>.</p>
+ <p>A guard G is a nonempty sequence of guard tests
+ <c>Gt_1, ..., Gt_k</c>, and Rep(G) =
+ <c>[Rep(Gt_1), ..., Rep(Gt_k)]</c>.</p>
+ <p>A guard test <c>Gt</c> is one of the following alternatives:</p>
<list type="bulleted">
<item>If Gt is an atomic literal L, then Rep(Gt) = Rep(L).</item>
- <item>If Gt is a variable pattern <c><![CDATA[V]]></c>, then
- Rep(Gt) = <c><![CDATA[{var,LINE,A}]]></c>,
- where A is an atom with a printname consisting of the same characters as
- <c><![CDATA[V]]></c>.</item>
- <item>If Gt is a tuple skeleton <c><![CDATA[{Gt_1, ..., Gt_k}]]></c>, then
- Rep(Gt) = <c><![CDATA[{tuple,LINE,[Rep(Gt_1), ..., Rep(Gt_k)]}]]></c>.</item>
- <item>If Gt is <c><![CDATA[[]]]></c>, then
- Rep(Gt) = <c><![CDATA[{nil,LINE}]]></c>.</item>
- <item>If Gt is a cons skeleton <c><![CDATA[[Gt_h | Gt_t]]]></c>, then
- Rep(Gt) = <c><![CDATA[{cons,LINE,Rep(Gt_h),Rep(Gt_t)}]]></c>.</item>
- <item>If Gt is a binary constructor <c><![CDATA[<<Gt_1:Size_1/TSL_1, ..., Gt_k:Size_k/TSL_k>>]]></c>, then
- Rep(Gt) = <c><![CDATA[{bin,LINE,[{bin_element,LINE,Rep(Gt_1),Rep(Size_1),Rep(TSL_1)}, ..., {bin_element,LINE,Rep(Gt_k),Rep(Size_k),Rep(TSL_k)}]}]]></c>.
+ <item>If Gt is a variable pattern <c>V</c>, then
+ Rep(Gt) = <c>{var,LINE,A}</c>, where A is an atom with
+ a printname consisting of the same characters as <c>V</c>.</item>
+ <item>If Gt is a tuple skeleton <c>{Gt_1, ..., Gt_k}</c>, then
+ Rep(Gt) = <c>{tuple,LINE,[Rep(Gt_1), ..., Rep(Gt_k)]}</c>.</item>
+ <item>If Gt is <c>[]</c>, then Rep(Gt) = <c>{nil,LINE}</c>.</item>
+ <item>If Gt is a cons skeleton <c>[Gt_h | Gt_t]</c>, then
+ Rep(Gt) = <c>{cons,LINE,Rep(Gt_h),Rep(Gt_t)}</c>.</item>
+ <item>If Gt is a binary constructor
+ <c>&lt;&lt;Gt_1:Size_1/TSL_1, ..., Gt_k:Size_k/TSL_k>></c>, then
+ Rep(Gt) = <c>{bin,LINE,[{bin_element,LINE,Rep(Gt_1),Rep(Size_1),Rep(TSL_1)}, ..., {bin_element,LINE,Rep(Gt_k),Rep(Size_k),Rep(TSL_k)}]}</c>.
For Rep(TSL), see above.
- An omitted <c><![CDATA[Size]]></c> is represented by <c><![CDATA[default]]></c>. An omitted <c><![CDATA[TSL]]></c>
- (type specifier list) is represented by <c><![CDATA[default]]></c>.</item>
- <item>If Gt is <c><![CDATA[Gt_1 Op Gt_2]]></c>, where <c><![CDATA[Op]]></c>
- is a binary operator, then Rep(Gt) = <c><![CDATA[{op,LINE,Op,Rep(Gt_1),Rep(Gt_2)}]]></c>.</item>
- <item>If Gt is <c><![CDATA[Op Gt_0]]></c>, where <c><![CDATA[Op]]></c> is a unary operator, then
- Rep(Gt) = <c><![CDATA[{op,LINE,Op,Rep(Gt_0)}]]></c>.</item>
- <item>If Gt is <c><![CDATA[#Name{Field_1=Gt_1, ..., Field_k=Gt_k}]]></c>, then
+ An omitted <c>Size</c> is represented by <c>default</c>.
+ An omitted <c>TSL</c> (type specifier list) is represented
+ by <c>default</c>.</item>
+ <item>If Gt is <c>Gt_1 Op Gt_2</c>, where <c>Op</c>
+ is a binary operator, then Rep(Gt) =
+ <c>{op,LINE,Op,Rep(Gt_1),Rep(Gt_2)}</c>.</item>
+ <item>If Gt is <c>Op Gt_0</c>, where <c>Op</c> is a unary operator, then
+ Rep(Gt) = <c>{op,LINE,Op,Rep(Gt_0)}</c>.</item>
+ <item>If Gt is <c>#Name{Field_1=Gt_1, ..., Field_k=Gt_k}</c>, then
Rep(E) =
- <c><![CDATA[{record,LINE,Name, [{record_field,LINE,Rep(Field_1),Rep(Gt_1)}, ..., {record_field,LINE,Rep(Field_k),Rep(Gt_k)}]}]]></c>.</item>
- <item>If Gt is <c><![CDATA[#Name.Field]]></c>, then
- Rep(Gt) = <c><![CDATA[{record_index,LINE,Name,Rep(Field)}]]></c>.</item>
- <item>If Gt is <c><![CDATA[Gt_0#Name.Field]]></c>, then
- Rep(Gt) = <c><![CDATA[{record_field,LINE,Rep(Gt_0),Name,Rep(Field)}]]></c>.</item>
- <item>If Gt is <c><![CDATA[A(Gt_1, ..., Gt_k)]]></c>, where <c><![CDATA[A]]></c> is an atom, then
- Rep(Gt) = <c><![CDATA[{call,LINE,Rep(A),[Rep(Gt_1), ..., Rep(Gt_k)]}]]></c>.</item>
- <item>If Gt is <c><![CDATA[A_m:A(Gt_1, ..., Gt_k)]]></c>, where <c><![CDATA[A_m]]></c> is
- the atom <c><![CDATA[erlang]]></c> and <c><![CDATA[A]]></c> is an atom or an operator, then
- Rep(Gt) = <c><![CDATA[{call,LINE,{remote,LINE,Rep(A_m),Rep(A)},[Rep(Gt_1), ..., Rep(Gt_k)]}]]></c>.</item>
- <item>If Gt is <c><![CDATA[{A_m,A}(Gt_1, ..., Gt_k)]]></c>, where <c><![CDATA[A_m]]></c> is
- the atom <c><![CDATA[erlang]]></c> and <c><![CDATA[A]]></c> is an atom or an operator, then
- Rep(Gt) = <c><![CDATA[{call,LINE,Rep({A_m,A}),[Rep(Gt_1), ..., Rep(Gt_k)]}]]></c>.</item>
- <item>If Gt is <c><![CDATA[( Gt_0 )]]></c>, then
- Rep(Gt) = <c><![CDATA[Rep(Gt_0)]]></c>,
- i.e., parenthesized guard tests cannot be distinguished from their bodies.</item>
+ <c>{record,LINE,Name,[{record_field,LINE,Rep(Field_1),Rep(Gt_1)}, ..., {record_field,LINE,Rep(Field_k),Rep(Gt_k)}]}</c>.</item>
+ <item>If Gt is <c>#Name.Field</c>, then
+ Rep(Gt) = <c>{record_index,LINE,Name,Rep(Field)}</c>.</item>
+ <item>If Gt is <c>Gt_0#Name.Field</c>, then
+ Rep(Gt) = <c>{record_field,LINE,Rep(Gt_0),Name,Rep(Field)}</c>.</item>
+ <item>If Gt is <c>A(Gt_1, ..., Gt_k)</c>, where <c>A</c> is an atom, then
+ Rep(Gt) = <c>{call,LINE,Rep(A),[Rep(Gt_1), ..., Rep(Gt_k)]}</c>.</item>
+ <item>If Gt is <c>A_m:A(Gt_1, ..., Gt_k)</c>, where <c>A_m</c> is
+ the atom <c>erlang</c> and <c>A</c> is an atom or an operator, then
+ Rep(Gt) = <c>{call,LINE,{remote,LINE,Rep(A_m),Rep(A)},[Rep(Gt_1), ..., Rep(Gt_k)]}</c>.</item>
+ <item>If Gt is <c>{A_m,A}(Gt_1, ..., Gt_k)</c>, where <c>A_m</c> is
+ the atom <c>erlang</c> and <c>A</c> is an atom or an operator, then
+ Rep(Gt) = <c>{call,LINE,Rep({A_m,A}),[Rep(Gt_1), ..., Rep(Gt_k)]}</c>.
+ </item>
+ <item>If Gt is <c>( Gt_0 )</c>, then
+ Rep(Gt) = <c>Rep(Gt_0)</c>, that is, parenthesized
+ guard tests cannot be distinguished from their bodies.</item>
</list>
<p>Note that every guard test has the same source form as some expression,
and is represented the same way as the corresponding expression.</p>
</section>
<section>
- <title>The abstract format after preprocessing</title>
- <p>The compilation option <c><![CDATA[debug_info]]></c> can be given to the
- compiler to have the abstract code stored in
- the <c><![CDATA[abstract_code]]></c> chunk in the BEAM file
+ <title>Types</title>
+ <list type="bulleted">
+ <item>If T is an annotated type <c>Anno :: Type</c>,
+ where <c>Anno</c> is a variable and
+ <c>Type</c> is a type, then Rep(T) =
+ <c>{ann_type,LINE,[Rep(Anno),Rep(Type)]}</c>.</item>
+ <item>If T is an atom or integer literal L, then Rep(T) = Rep(L).
+ </item>
+ <item>If T is <c>L Op R</c>,
+ where <c>Op</c> is a binary operator and <c>L</c> and <c>R</c>
+ are types (this is an occurrence of an expression that can be
+ evaluated to an integer at compile time), then
+ Rep(T) = <c>{op,LINE,Op,Rep(L),Rep(R)}</c>.</item>
+ <item>If T is <c>Op A</c>, where <c>Op</c> is a
+ unary operator and <c>A</c> is a type (this is an occurrence of
+ an expression that can be evaluated to an integer at compile time),
+ then Rep(T) = <c>{op,LINE,Op,Rep(A)}</c>.</item>
+ <item>If T is a bitstring type <c>&lt;&lt;_:M,_:_*N>></c>,
+ where <c>M</c> and <c>N</c> are singleton integer types, then Rep(T) =
+ <c>{type,LINE,binary,[Rep(M),Rep(N)]}</c>.</item>
+ <item>If T is the empty list type <c>[]</c>, then Rep(T) =
+ <c>{type,Line,nil,[]}</c>.</item>
+ <item>If T is a fun type <c>fun()</c>, then Rep(T) =
+ <c>{type,LINE,'fun',[]}</c>.</item>
+ <item>If T is a fun type <c>fun((...) -> B)</c>,
+ where <c>B</c> is a type, then
+ Rep(T) = <c>{type,LINE,'fun',[{type,LINE,any},Rep(B)]}</c>.
+ </item>
+ <item>If T is a fun type <c>fun(Ft)</c>, where
+ <c>Ft</c> is a function type,
+ then Rep(T) = <c>Rep(Ft)</c>.</item>
+ <item>If T is an integer range type <c>L .. H</c>,
+ where <c>L</c> and <c>H</c> are singleton integer types, then
+ Rep(T) = <c>{type,LINE,range,[Rep(L),Rep(H)]}</c>.</item>
+ <item>If T is a map type <c>map()</c>, then Rep(T) =
+ <c>{type,LINE,map,any}</c>.</item>
+ <item>If T is a map type <c>#{P_1, ..., P_k}</c>, where each
+ <c>P_i</c> is a map pair type, then Rep(T) =
+ <c>{type,LINE,map,[Rep(P_1), ..., Rep(P_k)]}</c>.</item>
+ <item>If T is a map pair type <c>K => V</c>, where
+ <c>K</c> and <c>V</c> are types, then Rep(T) =
+ <c>{type,LINE,map_field_assoc,[Rep(K),Rep(V)]}</c>.</item>
+ <item>If T is a predefined (or built-in) type <c>N(A_1, ..., A_k)</c>,
+ where each <c>A_i</c> is a type, then Rep(T) =
+ <c>{type,LINE,N,[Rep(A_1), ..., Rep(A_k)]}</c>.</item>
+ <item>If T is a record type <c>#Name{F_1, ..., F_k}</c>,
+ where each <c>F_i</c> is a record field type, then Rep(T) =
+ <c>{type,LINE,record,[Rep(Name),Rep(F_1), ..., Rep(F_k)]}</c>.
+ </item>
+ <item>If T is a record field type <c>Name :: Type</c>,
+ where <c>Type</c> is a type, then Rep(T) =
+ <c>{type,LINE,field_type,[Rep(Name),Rep(Type)]}</c>.</item>
+ <item>If T is a remote type <c>M:N(A_1, ..., A_k)</c>, where
+ each <c>A_i</c> is a type, then Rep(T) =
+ <c>{remote_type,LINE,[Rep(M),Rep(N),[Rep(A_1), ..., Rep(A_k)]]}</c>.
+ </item>
+ <item>If T is a tuple type <c>tuple()</c>, then Rep(T) =
+ <c>{type,LINE,tuple,any}</c>.</item>
+ <item>If T is a tuple type <c>{A_1, ..., A_k}</c>, where
+ each <c>A_i</c> is a type, then Rep(T) =
+ <c>{type,LINE,tuple,[Rep(A_1), ..., Rep(A_k)]}</c>.</item>
+ <item>If T is a type union <c>T_1 | ... | T_k</c>,
+ where each <c>T_i</c> is a type, then Rep(T) =
+ <c>{type,LINE,union,[Rep(T_1), ..., Rep(T_k)]}</c>.</item>
+ <item>If T is a type variable <c>V</c>, then Rep(T) =
+ <c>{var,LINE,A}</c>, where <c>A</c> is an atom with a printname
+ consisting of the same characters as <c>V</c>. A type variable
+ is any variable except underscore (<c>_</c>).</item>
+ <item>If T is a user-defined type <c>N(A_1, ..., A_k)</c>,
+ where each <c>A_i</c> is a type, then Rep(T) =
+ <c>{user_type,LINE,N,[Rep(A_1), ..., Rep(A_k)]}</c>.</item>
+ <item>If T is <c>( T_0 )</c>, then Rep(T) = <c>Rep(T_0)</c>,
+ that is, parenthesized types cannot be distinguished from their
+ bodies.</item>
+ </list>
+
+ <section>
+ <title>Function Types</title>
+ <list type="bulleted">
+ <item>If Ft is a constrained function type <c>Ft_1 when Fc</c>,
+ where <c>Ft_1</c> is a function type and
+ <c>Fc</c> is a function constraint, then Rep(T) =
+ <c>{type,LINE,bounded_fun,[Rep(Ft_1),Rep(Fc)]}</c>.</item>
+ <item>If Ft is a function type <c>(A_1, ..., A_n) -> B</c>,
+ where each <c>A_i</c> and <c>B</c> are types, then
+ Rep(Ft) = <c>{type,LINE,'fun',[{type,LINE,product,[Rep(A_1),
+ ..., Rep(A_n)]},Rep(B)]}</c>.</item>
+ </list>
+ </section>
+
+ <section>
+ <title>Function Constraints</title>
+ <p>A function constraint Fc is a nonempty sequence of constraints
+ <c>C_1, ..., C_k</c>, and
+ Rep(Fc) = <c>[Rep(C_1), ..., Rep(C_k)]</c>.</p>
+ <list type="bulleted">
+ <item>If C is a constraint <c>is_subtype(V, T)</c> or <c>V :: T</c>,
+ where <c>V</c> is a type variable and <c>T</c> is a type, then
+ Rep(C) = <c>{type,LINE,constraint,[Rep(F),[Rep(V),Rep(T)]]}</c>.
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>The Abstract Format After Preprocessing</title>
+ <p>The compilation option <c>debug_info</c> can be given to the
+ compiler to have the abstract code stored in
+ the <c>abstract_code</c> chunk in the BEAM file
(for debugging purposes).</p>
- <p>In OTP R9C and later, the <c><![CDATA[abstract_code]]></c> chunk will
+ <p>In OTP R9C and later, the <c>abstract_code</c> chunk will
contain</p>
- <p><c><![CDATA[{raw_abstract_v1,AbstractCode}]]></c></p>
- <p>where <c><![CDATA[AbstractCode]]></c> is the abstract code as described
+ <p><c>{raw_abstract_v1,AbstractCode}</c></p>
+ <p>where <c>AbstractCode</c> is the abstract code as described
in this document.</p>
<p>In releases of OTP prior to R9C, the abstract code after some more
processing was stored in the BEAM file. The first element of the
- tuple would be either <c><![CDATA[abstract_v1]]></c> (R7B) or <c><![CDATA[abstract_v2]]></c>
+ tuple would be either <c>abstract_v1</c> (R7B) or <c>abstract_v2</c>
(R8B).</p>
</section>
</chapter>
diff --git a/erts/doc/src/driver_entry.xml b/erts/doc/src/driver_entry.xml
index 30772c68fe..bad20d6343 100644
--- a/erts/doc/src/driver_entry.xml
+++ b/erts/doc/src/driver_entry.xml
@@ -4,7 +4,7 @@
<cref>
<header>
<copyright>
- <year>2001</year><year>2013</year>
+ <year>2001</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -126,7 +126,7 @@
<section>
<title>DATA TYPES</title>
<taglist>
- <tag><b>ErlDrvEntry</b></tag>
+ <tag><em>ErlDrvEntry</em></tag>
<item>
<p/>
<code type="none">
@@ -235,6 +235,7 @@ typedef struct erl_drv_entry {
</item>
<tag><marker id="ready_input"/>void (*ready_input)(ErlDrvData drv_data, ErlDrvEvent event)</tag>
+ <item/>
<tag><marker id="ready_output"/>void (*ready_output)(ErlDrvData drv_data, ErlDrvEvent event)</tag>
<item>
<p>This is called when a driver event (given in the
diff --git a/erts/doc/src/erl.xml b/erts/doc/src/erl.xml
index b0322b7d43..ec4a0dee05 100644
--- a/erts/doc/src/erl.xml
+++ b/erts/doc/src/erl.xml
@@ -4,7 +4,7 @@
<comref>
<header>
<copyright>
- <year>1996</year><year>2013</year>
+ <year>1996</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -138,7 +138,7 @@
see <seealso marker="kernel:app">app(4)</seealso> and
<seealso marker="kernel:application">application(3)</seealso>.</p>
</item>
- <tag><marker id="args_file"><c><![CDATA[-args_file FileName]]></c></marker></tag>
+ <tag><marker id="args_file"/><c><![CDATA[-args_file FileName]]></c></tag>
<item>
<p>Command line arguments are read from the file <c><![CDATA[FileName]]></c>.
The arguments read from the file replace the
@@ -203,7 +203,7 @@
<seealso marker="kernel:app">app(4)</seealso> and
<seealso marker="kernel:application">application(3)</seealso>.</p>
</item>
- <tag><marker id="connect_all"><c><![CDATA[-connect_all false]]></c></marker></tag>
+ <tag><marker id="connect_all"/><c><![CDATA[-connect_all false]]></c></tag>
<item>
<p>If this flag is present, <c><![CDATA[global]]></c> will not maintain a
fully connected network of distributed Erlang nodes, and then
@@ -288,7 +288,7 @@
<p>Makes <c><![CDATA[init]]></c> write some debug information while
interpreting the boot script.</p>
</item>
- <tag><marker id="instr"><c><![CDATA[-instr]]></c>(emulator flag)</marker></tag>
+ <tag><marker id="instr"/><c><![CDATA[-instr]]></c>(emulator flag)</tag>
<item>
<p>Selects an instrumented Erlang runtime system (virtual
machine) to run, instead of the ordinary one. When running an
@@ -371,7 +371,7 @@
path, similar to <c><![CDATA[code:add_pathsa/1]]></c>. See
<seealso marker="kernel:code">code(3)</seealso>.
As an alternative to <c>-pa</c>, if several directories are
- to be prepended to the code and the directories have a
+ to be prepended to the code path and the directories have a
common parent directory, that parent directory could be
specified in the <c>ERL_LIBS</c> environment variable.
See <seealso marker="kernel:code">code(3)</seealso>.</p>
@@ -436,7 +436,7 @@
flag and those running with the <c><![CDATA[-name]]></c> flag, as node
names must be unique in distributed Erlang systems.</p>
</item>
- <tag><marker id="smp"><c><![CDATA[-smp [enable|auto|disable]]]></c></marker></tag>
+ <tag><marker id="smp"/><c><![CDATA[-smp [enable|auto|disable]]]></c></tag>
<item>
<p><c>-smp enable</c> and <c>-smp</c> starts the Erlang runtime
system with SMP support enabled. This may fail if no runtime
@@ -462,7 +462,7 @@
<p><c><![CDATA[erl]]></c> invokes the code for the Erlang emulator (virtual
machine), which supports the following flags:</p>
<taglist>
- <tag><marker id="async_thread_stack_size"><c><![CDATA[+a size]]></c></marker></tag>
+ <tag><marker id="async_thread_stack_size"/><c><![CDATA[+a size]]></c></tag>
<item>
<p>Suggested stack size, in kilowords, for threads in the
async-thread pool. Valid range is 16-8192 kilowords. The
@@ -477,7 +477,7 @@
suggestion, and it might even be ignored on some
platforms.</p>
</item>
- <tag><marker id="async_thread_pool_size"><c><![CDATA[+A size]]></c></marker></tag>
+ <tag><marker id="async_thread_pool_size"/><c><![CDATA[+A size]]></c></tag>
<item>
<p>Sets the number of threads in async thread pool, valid range
is 0-1024. If thread support is available, the default is 10.</p>
@@ -496,7 +496,7 @@
<c><![CDATA[werl]]></c>, not <c><![CDATA[erl]]></c> (<c><![CDATA[oldshell]]></c>). Note also that
<c><![CDATA[Ctrl-Break]]></c> is used instead of <c><![CDATA[Ctrl-C]]></c> on Windows.</p>
</item>
- <tag><marker id="+c"><c><![CDATA[+c true | false]]></c></marker></tag>
+ <tag><marker id="+c"/><c><![CDATA[+c true | false]]></c></tag>
<item>
<p>Enable or disable
<seealso marker="time_correction#Time_Correction">time correction</seealso>:</p>
@@ -512,7 +512,7 @@
This is interpreted as <c>+c false</c>.
</p>
</item>
- <tag><marker id="+C_"><c><![CDATA[+C no_time_warp | single_time_warp | multi_time_warp]]></c></marker></tag>
+ <tag><marker id="+C_"/><c><![CDATA[+C no_time_warp | single_time_warp | multi_time_warp]]></c></tag>
<item>
<p>Set
<seealso marker="time_correction#Time_Warp_Modes">time warp mode</seealso>:
@@ -540,7 +540,7 @@
produce a crash dump. On Unix systems, sending an emulator process
a SIGUSR1 signal will also force a crash dump.</p>
</item>
- <tag><marker id="+e"><c><![CDATA[+e Number]]></c></marker></tag>
+ <tag><marker id="+e"/><c><![CDATA[+e Number]]></c></tag>
<item>
<p>Set max number of ETS tables.</p>
</item>
@@ -625,7 +625,7 @@
information about the file names and line numbers.
</p>
</item>
- <tag><marker id="erts_alloc"><c><![CDATA[+MFlag Value]]></c></marker></tag>
+ <tag><marker id="erts_alloc"/><c><![CDATA[+MFlag Value]]></c></tag>
<item>
<p>Memory allocator specific flags, see
<seealso marker="erts_alloc">erts_alloc(3)</seealso> for
@@ -664,10 +664,10 @@
debugging.</item>
</taglist>
</item>
- <tag><marker id="+pc"/><marker id="printable_character_range"><c><![CDATA[+pc Range]]></c></marker></tag>
+ <tag><marker id="+pc"/><marker id="printable_character_range"/><c><![CDATA[+pc Range]]></c></tag>
<item>
<p>Sets the range of characters that the system will consider printable in heuristic detection of strings. This typically affects the shell, debugger and io:format functions (when ~tp is used in the format string).</p>
- <p>Currently two values for the <c>Range</c> are supported:
+ <p>Currently two values for the <c>Range</c> are supported:</p>
<taglist>
<tag><c>latin1</c></tag> <item>The default. Only characters
in the ISO-latin-1 range can be considered printable, which means
@@ -682,11 +682,10 @@
example your font does not cover all Unicode
characters.</item>
</taglist>
- </p>
<p>Se also <seealso marker="stdlib:io#printable_range/0">
io:printable_range/0</seealso>.</p>
</item>
- <tag><marker id="+P"/><marker id="max_processes"><c><![CDATA[+P Number|legacy]]></c></marker></tag>
+ <tag><marker id="+P"/><marker id="max_processes"/><c><![CDATA[+P Number|legacy]]></c></tag>
<item>
<p>Sets the maximum number of simultaneously existing processes for this
system if a <c>Number</c> is passed as value. Valid range for
@@ -706,7 +705,7 @@
circumstances be extremely expensive. The legacy algoritm is deprecated,
and the <c>legacy</c> option is scheduled for removal in OTP-R18.</p>
</item>
- <tag><marker id="+Q"/><marker id="max_ports"><c><![CDATA[+Q Number|legacy]]></c></marker></tag>
+ <tag><marker id="+Q"/><marker id="max_ports"/><c><![CDATA[+Q Number|legacy]]></c></tag>
<item>
<p>Sets the maximum number of simultaneously existing ports for this
system if a Number is passed as value. Valid range for <c>Number</c>
@@ -737,7 +736,7 @@
circumstances be extremely expensive. The legacy algoritm is deprecated,
and the <c>legacy</c> option is scheduled for removal in OTP-R18.</p>
</item>
- <tag><marker id="compat_rel"><c><![CDATA[+R ReleaseNumber]]></c></marker></tag>
+ <tag><marker id="compat_rel"/><c><![CDATA[+R ReleaseNumber]]></c></tag>
<item>
<p>Sets the compatibility mode.</p>
<p>The distribution mechanism is not backwards compatible by
@@ -757,7 +756,7 @@
<item>
<p>Force ets memory block to be moved on realloc.</p>
</item>
- <tag><marker id="+rg"><c><![CDATA[+rg ReaderGroupsLimit]]></c></marker></tag>
+ <tag><marker id="+rg"/><c><![CDATA[+rg ReaderGroupsLimit]]></c></tag>
<item>
<p>Limits the amount of reader groups used by read/write locks
optimized for read operations in the Erlang runtime system. By
@@ -775,7 +774,7 @@
schedulers to logical processors</seealso>, since the reader groups
are distributed better between schedulers.</p>
</item>
- <tag><marker id="+S"><c><![CDATA[+S Schedulers:SchedulerOnline]]></c></marker></tag>
+ <tag><marker id="+S"/><c><![CDATA[+S Schedulers:SchedulerOnline]]></c></tag>
<item>
<p>Sets the number of scheduler threads to create and scheduler
threads to set online when SMP support has been enabled. The maximum for
@@ -800,7 +799,7 @@
SMP support enabled (see the <seealso marker="#smp">-smp</seealso>
flag).</p>
</item>
- <tag><marker id="+SP"><c><![CDATA[+SP SchedulersPercentage:SchedulersOnlinePercentage]]></c></marker></tag>
+ <tag><marker id="+SP"/><c><![CDATA[+SP SchedulersPercentage:SchedulersOnlinePercentage]]></c></tag>
<item>
<p>Similar to <seealso marker="#+S">+S</seealso> but uses percentages to set the
number of scheduler threads to create, based on logical processors configured,
@@ -821,7 +820,7 @@
SMP support enabled (see the <seealso marker="#smp">-smp</seealso>
flag).</p>
</item>
- <tag><marker id="+SDcpu"><c><![CDATA[+SDcpu DirtyCPUSchedulers:DirtyCPUSchedulersOnline]]></c></marker></tag>
+ <tag><marker id="+SDcpu"/><c><![CDATA[+SDcpu DirtyCPUSchedulers:DirtyCPUSchedulersOnline]]></c></tag>
<item>
<p>Sets the number of dirty CPU scheduler threads to create and dirty
CPU scheduler threads to set online when threading support has been
@@ -845,7 +844,7 @@
enabled (it's disabled by default).
</p>
</item>
- <tag><marker id="+SDPcpu"><c><![CDATA[+SDPcpu DirtyCPUSchedulersPercentage:DirtyCPUSchedulersOnlinePercentage]]></c></marker></tag>
+ <tag><marker id="+SDPcpu"/><c><![CDATA[+SDPcpu DirtyCPUSchedulersPercentage:DirtyCPUSchedulersOnlinePercentage]]></c></tag>
<item>
<p>Similar to <seealso marker="#+SDcpu">+SDcpu</seealso> but uses percentages to set the
number of dirty CPU scheduler threads to create and number of dirty CPU scheduler threads
@@ -868,7 +867,7 @@
enabled (it's disabled by default).
</p>
</item>
- <tag><marker id="+SDio"><c><![CDATA[+SDio IOSchedulers]]></c></marker></tag>
+ <tag><marker id="+SDio"/><c><![CDATA[+SDio IOSchedulers]]></c></tag>
<item>
<p>Sets the number of dirty I/O scheduler threads to create when threading
support has been enabled. The valid range is 0-1024. By default, the number
@@ -886,7 +885,7 @@
<item>
<p>Scheduling specific flags.</p>
<taglist>
- <tag><marker id="+sbt"><c>+sbt BindType</c></marker></tag>
+ <tag><marker id="+sbt"/><c>+sbt BindType</c></tag>
<item>
<p>Set scheduler bind type.</p>
<p>Schedulers can also be bound using the
@@ -1010,7 +1009,7 @@
<seealso marker="erlang#system_info_scheduler_bindings">erlang:system_info(scheduler_bindings)</seealso>.
</p>
</item>
- <tag><marker id="+sbwt"><c>+sbwt none|very_short|short|medium|long|very_long</c></marker></tag>
+ <tag><marker id="+sbwt"/><c>+sbwt none|very_short|short|medium|long|very_long</c></tag>
<item>
<p>Set scheduler busy wait threshold. Default is <c>medium</c>.
The threshold determines how long schedulers should busy
@@ -1020,7 +1019,7 @@
without prior notice.
</p>
</item>
- <tag><marker id="+scl"><c>+scl true|false</c></marker></tag>
+ <tag><marker id="+scl"/><c>+scl true|false</c></tag>
<item>
<p>Enable or disable scheduler compaction of load. By default
scheduler compaction of load is enabled. When enabled, load
@@ -1037,7 +1036,7 @@
between schedulers.
</p>
</item>
- <tag><marker id="+sct"><c>+sct CpuTopology</c></marker></tag>
+ <tag><marker id="+sct"/><c>+sct CpuTopology</c></tag>
<item>
<list type="bulleted">
<item><c><![CDATA[<Id> = integer(); when 0 =< <Id> =< 65535]]></c></item>
@@ -1159,7 +1158,7 @@
<p>For more information, see
<seealso marker="erlang#system_info_cpu_topology">erlang:system_info(cpu_topology)</seealso>.</p>
</item>
- <tag><marker id="+secio"><c>+secio true|false</c></marker></tag>
+ <tag><marker id="+secio"/><c>+secio true|false</c></tag>
<item>
<p>Enable or disable eager check I/O scheduling. The default
is currently <c>true</c>. The default was changed from <c>false</c>
@@ -1176,7 +1175,7 @@
<p><seealso marker="erlang#system_info_eager_check_io"><c>erlang:system_info(eager_check_io)</c></seealso>
returns the value of this parameter used when starting the VM.</p>
</item>
- <tag><marker id="+sfwi"><c>+sfwi Interval</c></marker></tag>
+ <tag><marker id="+sfwi"/><c>+sfwi Interval</c></tag>
<item>
<p>Set scheduler forced wakeup interval. All run queues will
be scanned each <c>Interval</c> milliseconds. While there are
@@ -1185,12 +1184,12 @@
disables this feature, which also is the default.
</p>
<p>This feature has been introduced as a temporary workaround
- for lengthy executing native code, and native code that do not
+ for long-executing native code, and native code that does not
bump reductions properly in OTP. When these bugs have be fixed
the <c>+sfwi</c> flag will be removed.
</p>
</item>
- <tag><marker id="+stbt"><c>+stbt BindType</c></marker></tag>
+ <tag><marker id="+stbt"/><c>+stbt BindType</c></tag>
<item>
<p>Try to set scheduler bind type. The same as the
<seealso marker="#+sbt">+sbt</seealso> flag with the exception of
@@ -1198,7 +1197,7 @@
documentation of the <seealso marker="#+sbt">+sbt</seealso> flag.
</p>
</item>
- <tag><marker id="+sub"><c>+sub true|false</c></marker></tag>
+ <tag><marker id="+sub"/><c>+sub true|false</c></tag>
<item>
<p>Enable or disable
<seealso marker="erts:erlang#statistics_scheduler_wall_time">scheduler
@@ -1211,7 +1210,7 @@
balance scheduler utilization between schedulers. That is,
strive for equal scheduler utilization on all schedulers.
<br/>&nbsp;&nbsp;&nbsp;<c>+sub true</c> is only supported on
- systems where the runtime system detects and use a monotonically
+ systems where the runtime system detects and uses a monotonically
increasing high resolution clock. On other systems, the runtime
system will fail to start.
<br/>&nbsp;&nbsp;&nbsp;<c>+sub true</c> implies
@@ -1221,7 +1220,7 @@
utilization.
</p>
</item>
- <tag><marker id="+swct"><c>+swct very_eager|eager|medium|lazy|very_lazy</c></marker></tag>
+ <tag><marker id="+swct"/><c>+swct very_eager|eager|medium|lazy|very_lazy</c></tag>
<item>
<p>
Set scheduler wake cleanup threshold. Default is <c>medium</c>.
@@ -1235,7 +1234,7 @@
<p><em>NOTE:</em> This flag may be removed or changed at any time without prior notice.
</p>
</item>
- <tag><marker id="+sws"><c>+sws default|legacy</c></marker></tag>
+ <tag><marker id="+sws"/><c>+sws default|legacy</c></tag>
<item>
<p>
Set scheduler wakeup strategy. Default strategy changed in erts-5.10/OTP-R16A. This strategy was previously known as <c>proposal</c> in OTP-R15. The <c>legacy</c> strategy was used as default from R13 up to and including R15.
@@ -1243,7 +1242,7 @@
<p><em>NOTE:</em> This flag may be removed or changed at any time without prior notice.
</p>
</item>
- <tag><marker id="+swt"><c>+swt very_low|low|medium|high|very_high</c></marker></tag>
+ <tag><marker id="+swt"/><c>+swt very_low|low|medium|high|very_high</c></tag>
<item>
<p>Set scheduler wakeup threshold. Default is <c>medium</c>.
The threshold determines when to wake up sleeping schedulers
@@ -1257,7 +1256,7 @@
without prior notice.
</p>
</item>
- <tag><marker id="+spp"><c>+spp Bool</c></marker></tag>
+ <tag><marker id="+spp"/><c>+spp Bool</c></tag>
<item>
<p>Set default scheduler hint for port parallelism. If set to
<c>true</c>, the VM will schedule port tasks when doing so will
@@ -1273,7 +1272,7 @@
option to <seealso
marker="erlang#open_port/2">open_port/2</seealso></p>.
</item>
- <tag><marker id="sched_thread_stack_size"><c><![CDATA[+sss size]]></c></marker></tag>
+ <tag><marker id="sched_thread_stack_size"/><c><![CDATA[+sss size]]></c></tag>
<item>
<p>Suggested stack size, in kilowords, for scheduler threads.
Valid range is 4-8192 kilowords. The default stack size
@@ -1281,11 +1280,11 @@
</item>
</taglist>
</item>
- <tag><marker id="+t"><c><![CDATA[+t size]]></c></marker></tag>
+ <tag><marker id="+t"/><c><![CDATA[+t size]]></c></tag>
<item>
<p>Set the maximum number of atoms the VM can handle. Default is 1048576.</p>
</item>
- <tag><marker id="+T"><c><![CDATA[+T Level]]></c></marker></tag>
+ <tag><marker id="+T"/><c><![CDATA[+T Level]]></c></tag>
<item>
<p>Enables modified timing and sets the modified timing level.
Currently valid range is 0-9. The timing of the runtime system
@@ -1339,7 +1338,7 @@
<item>
<p>Miscellaneous flags.</p>
<taglist>
- <tag><marker id="+zdbbl"><c>+zdbbl size</c></marker></tag>
+ <tag><marker id="+zdbbl"/><c>+zdbbl size</c></tag>
<item>
<p>Set the distribution buffer busy limit
(<seealso marker="erlang#system_info_dist_buf_busy_limit">dist_buf_busy_limit</seealso>)
@@ -1352,7 +1351,7 @@
give lower latency and higher throughput at the expense
of higher memory usage.</p>
</item>
- <tag><marker id="+zdntgc"><c>+zdntgc time</c></marker></tag>
+ <tag><marker id="+zdntgc"/><c>+zdntgc time</c></tag>
<item>
<p>Set the delayed node table garbage collection time
(<seealso marker="erlang#system_info_delayed_node_table_gc">delayed_node_table_gc</seealso>)
@@ -1426,7 +1425,7 @@
</item>
</taglist>
</item>
- <tag><marker id="ERL_AFLAGS"><c><![CDATA[ERL_AFLAGS]]></c></marker></tag>
+ <tag><marker id="ERL_AFLAGS"/><c><![CDATA[ERL_AFLAGS]]></c></tag>
<item>
<p>The content of this environment variable will be added to the
beginning of the command line for <c><![CDATA[erl]]></c>.</p>
@@ -1436,7 +1435,7 @@
the <c><![CDATA[-extra]]></c> section, i.e. the end of the command line
following after an <c><![CDATA[-extra]]></c> flag.</p>
</item>
- <tag><marker id="ERL_ZFLAGS"><c><![CDATA[ERL_ZFLAGS]]></c></marker> and <marker id="ERL_FLAGS"><c><![CDATA[ERL_FLAGS]]></c></marker></tag>
+ <tag><marker id="ERL_ZFLAGS"/><c><![CDATA[ERL_ZFLAGS]]></c> and <marker id="ERL_FLAGS"/><c><![CDATA[ERL_FLAGS]]></c></tag>
<item>
<p>The content of these environment variables will be added to the
end of the command line for <c><![CDATA[erl]]></c>.</p>
diff --git a/erts/doc/src/erl_dist_protocol.xml b/erts/doc/src/erl_dist_protocol.xml
index e1a58856f3..b435d5c9b4 100644
--- a/erts/doc/src/erl_dist_protocol.xml
+++ b/erts/doc/src/erl_dist_protocol.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2007</year>
- <year>2013</year>
+ <year>2015</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -549,10 +549,10 @@ If Result > 0, the packet only consists of [119, Result].
-->
</section>
- <marker id="distribution_handshake"/>
<section>
<title>Distribution Handshake</title>
<p>
+ <marker id="distribution_handshake"/>
This section describes the distribution handshake protocol
introduced in the OTP-R6 release of Erlang/OTP. This
description was previously located in
diff --git a/erts/doc/src/erl_driver.xml b/erts/doc/src/erl_driver.xml
index 1f7fe0f961..e717fc0c4e 100644
--- a/erts/doc/src/erl_driver.xml
+++ b/erts/doc/src/erl_driver.xml
@@ -4,7 +4,7 @@
<cref>
<header>
<copyright>
- <year>2001</year><year>2014</year>
+ <year>2001</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -223,7 +223,7 @@
asynchronous function calls, using a thread pool provided by
Erlang. There is also a select call, that can be used for
asynchronous drivers.</item>
- <tag><marker id="multi_threading">Multi-threading</marker></tag>
+ <tag><marker id="multi_threading"/>Multi-threading</tag>
<item>
<p>A POSIX thread like API for multi-threading is provided. The
Erlang driver thread API only provide a subset of the functionality
@@ -297,7 +297,7 @@
<item><p>A driver can add and later remove drivers.</p></item>
<tag>Monitoring processes</tag>
<item><p>A driver can monitor a process that does not own a port.</p></item>
- <tag><marker id="version_management">Version management</marker></tag>
+ <tag><marker id="version_management"/>Version management</tag>
<item>
<p>Version management is enabled for drivers that have set the
<seealso marker="driver_entry#extended_marker">extended_marker</seealso>
@@ -384,12 +384,12 @@
<item>
<p>
Rewrite driver callback
- <c><seealso marker="driver_entry#control">control</seealso></c>
+ <seealso marker="driver_entry#control"><c>control</c></seealso>
to use return type <c>ErlDrvSSizeT</c> instead of <c>int</c>.
</p>
<p>
Rewrite driver callback
- <c><seealso marker="driver_entry#call">call</seealso></c>
+ <seealso marker="driver_entry#call"><c>call</c></seealso>
to use return type <c>ErlDrvSSizeT</c> instead of <c>int</c>.
</p>
<note>
@@ -407,19 +407,19 @@
<item>
<p>
Driver callback
- <c><seealso marker="driver_entry#output">output</seealso></c>
+ <seealso marker="driver_entry#output"><c>output</c></seealso>
now gets <c>ErlDrvSizeT</c> as 3rd argument instead
of previously <c>int</c>.
</p>
<p>
Driver callback
- <c><seealso marker="driver_entry#control">control</seealso></c>
+ <seealso marker="driver_entry#control"><c>control</c></seealso>
now gets <c>ErlDrvSizeT</c> as 4th and 6th arguments instead
of previously <c>int</c>.
</p>
<p>
Driver callback
- <c><seealso marker="driver_entry#call">call</seealso></c>
+ <seealso marker="driver_entry#call"><c>call</c></seealso>
now gets <c>ErlDrvSizeT</c> as 4th and 6th arguments instead
of previously <c>int</c>.
</p>
@@ -2811,7 +2811,7 @@ ERL_DRV_MAP int sz
</func>
<func>
- <name><ret>int</ret><nametext>erl_drv_putenv(char *key, char *value)</nametext></name>
+ <name><ret>int</ret><nametext>erl_drv_putenv(const char *key, char *value)</nametext></name>
<fsummary>Set the value of an environment variable</fsummary>
<desc>
<marker id="erl_drv_putenv"></marker>
@@ -2840,7 +2840,7 @@ ERL_DRV_MAP int sz
</desc>
</func>
<func>
- <name><ret>int</ret><nametext>erl_drv_getenv(char *key, char *value, size_t *value_size)</nametext></name>
+ <name><ret>int</ret><nametext>erl_drv_getenv(const char *key, char *value, size_t *value_size)</nametext></name>
<fsummary>Get the value of an environment variable</fsummary>
<desc>
<marker id="erl_drv_getenv"></marker>
diff --git a/erts/doc/src/erl_ext_dist.xml b/erts/doc/src/erl_ext_dist.xml
index caf1e812c4..2ac974f497 100644
--- a/erts/doc/src/erl_ext_dist.xml
+++ b/erts/doc/src/erl_ext_dist.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2007</year>
- <year>2014</year>
+ <year>2015</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -150,10 +150,10 @@
</note>
</section>
- <marker id="distribution_header"/>
<section>
<title>Distribution header</title>
<p>
+ <marker id="distribution_header"/>
As of erts version 5.7.2 the old atom cache protocol was
dropped and a new one was introduced. This atom cache protocol
introduced the distribution header. Nodes with erts versions
diff --git a/erts/doc/src/erl_nif.xml b/erts/doc/src/erl_nif.xml
index 23c3d5fcee..2d8706169f 100644
--- a/erts/doc/src/erl_nif.xml
+++ b/erts/doc/src/erl_nif.xml
@@ -4,7 +4,7 @@
<cref>
<header>
<copyright>
- <year>2001</year><year>2013</year>
+ <year>2001</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -791,6 +791,10 @@ typedef enum {
and return true, or return false if <c>term</c> is not an unsigned integer or is
outside the bounds of type <c>unsigned long</c>.</p></desc>
</func>
+ <func><name><ret>int</ret><nametext>enif_getenv(const char* key, char* value, size_t *value_size)</nametext></name>
+ <fsummary>Get the value of an environment variable</fsummary>
+ <desc><p>Same as <seealso marker="erl_driver#erl_drv_getenv">erl_drv_getenv</seealso>.</p></desc>
+ </func>
<func><name><ret>int</ret><nametext>enif_has_pending_exception(ErlNifEnv* env, ERL_NIF_TERM* reason)</nametext></name>
<fsummary>Check if an exception has been raised</fsummary>
<desc><p>Return true if a pending exception is associated
@@ -833,9 +837,10 @@ typedef enum {
<fsummary>Determine if a term is an empty list</fsummary>
<desc><p>Return true if <c>term</c> is an empty list.</p></desc>
</func>
- <marker id="enif_is_exception"/><func><name><ret>int</ret><nametext>enif_is_exception(ErlNifEnv* env, ERL_NIF_TERM term)</nametext></name>
+ <func><name><ret>int</ret><nametext>enif_is_exception(ErlNifEnv* env, ERL_NIF_TERM term)</nametext></name>
<fsummary>Determine if a term is an exception</fsummary>
- <desc><p>Return true if <c>term</c> is an exception.</p></desc>
+ <desc><marker id="enif_is_exception"/>
+ <p>Return true if <c>term</c> is an exception.</p></desc>
</func>
<func><name><ret>int</ret><nametext>enif_is_map(ErlNifEnv* env, ERL_NIF_TERM term)</nametext></name>
<fsummary>Determine if a term is a map</fsummary>
diff --git a/erts/doc/src/erl_prim_loader.xml b/erts/doc/src/erl_prim_loader.xml
index d05f0d9aea..db4f132609 100644
--- a/erts/doc/src/erl_prim_loader.xml
+++ b/erts/doc/src/erl_prim_loader.xml
@@ -36,17 +36,11 @@
the system. The start script is also fetched with this low level
loader.</p>
<p><c>erl_prim_loader</c> knows about the environment and how to
- fetch modules. The loader could, for example, fetch files using
- the file system (with absolute file names as input), or a
- database (where the binary format of a module is stored).</p>
+ fetch modules.</p>
<p>The <c>-loader Loader</c> command line flag can be used to
choose the method used by the <c>erl_prim_loader</c>. Two
<c>Loader</c> methods are supported by the Erlang runtime system:
- <c>efile</c> and <c>inet</c>. If another loader is required, then
- it has to be implemented by the user. The <c>Loader</c> provided
- by the user must fulfill the protocol defined below, and it is
- started with the <c>erl_prim_loader</c> by evaluating
- <c>open_port({spawn,Loader},[binary])</c>.</p>
+ <c>efile</c> and <c>inet</c>.</p>
<warning><p>The support for loading of code from archive files is
experimental. The sole purpose of releasing it before it is ready
@@ -83,9 +77,6 @@
started on each of hosts given in <c><anno>Hosts</anno></c> in order to
answer the requests. See <seealso
marker="kernel:erl_boot_server">erl_boot_server(3)</seealso>.</p>
- <p>If <c>-loader</c> is something else, the given port program
- is started. The port program is supposed to follow
- the protocol specified below.</p>
</desc>
</func>
<func>
@@ -175,22 +166,6 @@
</funcs>
<section>
- <title>Protocol</title>
- <p>The following protocol must be followed if a user provided
- loader port program is used. The <c>Loader</c> port program is
- started with the command
- <c>open_port({spawn,Loader},[binary])</c>. The protocol is as
- follows:</p>
- <pre>
-Function Send Receive
--------------------------------------------------------------
-get_file [102 | FileName] [121 | BinaryFile] (on success)
- [122] (failure)
-
-stop eof terminate</pre>
- </section>
-
- <section>
<title>Command Line Flags</title>
<p>The <c>erl_prim_loader</c> module interprets the following
command line flags:</p>
@@ -199,10 +174,8 @@ stop eof terminate</pre>
<item>
<p>Specifies the name of the loader used by
<c>erl_prim_loader</c>. <c>Loader</c> can be <c>efile</c>
- (use the local file system), or <c>inet</c> (load using
- the <c>boot_server</c> on another Erlang node). If
- <c>Loader</c> is user defined, the defined <c>Loader</c> port
- program is started.</p>
+ (use the local file system) or <c>inet</c> (load using
+ the <c>boot_server</c> on another Erlang node).</p>
<p>If the <c>-loader</c> flag is omitted, it defaults to
<c>efile</c>.</p>
</item>
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index 37f0aa289e..c37ed3bea5 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2013</year>
+ <year>1996</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -30,42 +30,43 @@
<file>erlang.xml</file>
</header>
<module>erlang</module>
- <modulesummary>The Erlang BIFs</modulesummary>
+ <modulesummary>The Erlang BIFs.</modulesummary>
<description>
- <p>By convention, most built-in functions (BIFs) are seen as being
- in the module <c>erlang</c>. A number of the BIFs are viewed more
+ <p>By convention, most Built-In Functions (BIFs) are seen as being
+ in this module. Some of the BIFs are viewed more
or less as part of the Erlang programming language and are
- <em>auto-imported</em>. Thus, it is not necessary to specify
- the module name and both the calls <c>atom_to_list(Erlang)</c> and
- <c>erlang:atom_to_list(Erlang)</c> are identical.</p>
- <p>In the text, auto-imported BIFs are listed without module prefix.
+ <em>auto-imported</em>. Thus, it is not necessary to specify the
+ module name. For example, the calls <c>atom_to_list(Erlang)</c>
+ and <c>erlang:atom_to_list(Erlang)</c> are identical.</p>
+ <p>Auto-imported BIFs are listed without module prefix.
BIFs listed with module prefix are not auto-imported.</p>
- <p>BIFs may fail for a variety of reasons. All BIFs fail with
+ <p>BIFs can fail for various reasons. All BIFs fail with
reason <c>badarg</c> if they are called with arguments of an
- incorrect type. The other reasons that may make BIFs fail are
- described in connection with the description of each individual
- BIF.</p>
- <p>Some BIFs may be used in guard tests, these are marked with
+ incorrect type. The other reasons are described in the
+ description of each individual BIF.</p>
+ <p>Some BIFs can be used in guard tests and are marked with
"Allowed in guard tests".</p>
</description>
<datatypes>
<datatype>
- <name><marker id="type-ext_binary">ext_binary()</marker></name>
+ <name>ext_binary()</name>
<desc>
+ <marker id="type-ext_binary"></marker>
<p>A binary data object, structured according to
the Erlang external term format.</p>
</desc>
</datatype>
+
<datatype>
<name name="timestamp"></name>
<desc><p>See <seealso marker="#timestamp/0">erlang:timestamp/0</seealso>.</p>
</desc>
</datatype>
- <marker id="type_time_unit"/>
<datatype>
<name name="time_unit"></name>
- <desc><p>Currently supported time unit representations:</p>
+ <desc><p><marker id="type_time_unit"/>
+ Supported time unit representations:</p>
<taglist>
<tag><c>PartsPerSecond :: integer() >= 1</c></tag>
<item><p>Time unit expressed in parts per second. That is,
@@ -92,11 +93,11 @@
used by the Erlang runtime system.</p>
<p>The <c>native</c> time unit is determined at
- runtime system start, and will remain the same until
+ runtime system start, and remains the same until
the runtime system terminates. If a runtime system
is stopped and then started again (even on the same
machine), the <c>native</c> time unit of the new
- runtime system instance may differ from the
+ runtime system instance can differ from the
<c>native</c> time unit of the old runtime system
instance.</p>
@@ -105,8 +106,7 @@
seconds, native)</c>. The result equals the number
of whole <c>native</c> time units per second. In case
the number of <c>native</c> time units per second does
- not add up to a whole number, the result will be
- rounded downwards.</p>
+ not add up to a whole number, the result is rounded downwards.</p>
<note>
<p>The value of the <c>native</c> time unit gives
@@ -120,7 +120,7 @@
but it gives absolutely no information at all about the
<seealso marker="time_correction#Time_Accuracy">accuracy</seealso>
of time values. The resolution of the <c>native</c> time
- unit and the resolution of time values may differ
+ unit and the resolution of time values can differ
significantly.</p>
</note>
</item>
@@ -139,12 +139,15 @@
<func>
<name name="abs" arity="1" clause_i="1"/>
<name name="abs" arity="1" clause_i="2"/>
- <type variable="Float" name_i="1"/>
- <type variable="Int" name_i="2"/>
- <fsummary>Arithmetical absolute value</fsummary>
- <desc>
- <p>Returns an integer or float which is the arithmetical
- absolute value of <c><anno>Float</anno></c> or <c><anno>Int</anno></c>.</p>
+ <fsummary>Arithmetical absolute value.</fsummary>
+ <type>
+ <v>Float = float()</v>
+ <v>Int = integer()</v>
+ </type>
+ <desc>
+ <p>Returns an integer or float that is the arithmetical
+ absolute value of <c><anno>Float</anno></c> or
+ <c><anno>Int</anno></c>, for example:</p>
<pre>
> <input>abs(-3.33).</input>
3.33
@@ -153,206 +156,214 @@
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="adler32" arity="1"/>
- <fsummary>Compute adler32 checksum</fsummary>
+ <fsummary>Computes adler32 checksum.</fsummary>
<desc>
- <p>Computes and returns the adler32 checksum for <c><anno>Data</anno></c>.</p>
+ <p>Computes and returns the adler32 checksum for
+ <c><anno>Data</anno></c>.</p>
</desc>
</func>
+
<func>
<name name="adler32" arity="2"/>
- <fsummary>Compute adler32 checksum</fsummary>
+ <fsummary>Computes adler32 checksum.</fsummary>
<desc>
- <p>Continue computing the adler32 checksum by combining
- the previous checksum, <c><anno>OldAdler</anno></c>, with the checksum of
- <c><anno>Data</anno></c>.</p>
- <p>The following code:</p>
- <code>
- X = erlang:adler32(Data1),
- Y = erlang:adler32(X,Data2).
- </code>
- <p>- would assign the same value to <c>Y</c> as this would:</p>
- <code>
- Y = erlang:adler32([Data1,Data2]).
- </code>
+ <p>Continues computing the adler32 checksum by combining
+ the previous checksum, <c><anno>OldAdler</anno></c>, with
+ the checksum of <c><anno>Data</anno></c>.</p>
+ <p>The following code:</p>
+ <code>
+ X = erlang:adler32(Data1),
+ Y = erlang:adler32(X,Data2).</code>
+ <p>assigns the same value to <c>Y</c> as this:</p>
+ <code>
+ Y = erlang:adler32([Data1,Data2]).</code>
</desc>
</func>
+
<func>
<name name="adler32_combine" arity="3"/>
- <fsummary>Combine two adler32 checksums</fsummary>
- <desc>
- <p>Combines two previously computed adler32 checksums.
- This computation requires the size of the data object for
- the second checksum to be known.</p>
- <p>The following code:</p>
- <code>
- Y = erlang:adler32(Data1),
- Z = erlang:adler32(Y,Data2).
- </code>
- <p>- would assign the same value to <c>Z</c> as this would:</p>
- <code>
- X = erlang:adler32(Data1),
- Y = erlang:adler32(Data2),
- Z = erlang:adler32_combine(X,Y,iolist_size(Data2)).
- </code>
+ <fsummary>Combines two adler32 checksums.</fsummary>
+ <desc>
+ <p>Combines two previously computed adler32 checksums.
+ This computation requires the size of the data object for
+ the second checksum to be known.</p>
+ <p>The following code:</p>
+ <code>
+ Y = erlang:adler32(Data1),
+ Z = erlang:adler32(Y,Data2).</code>
+ <p>assigns the same value to <c>Z</c> as this:</p>
+ <code>
+ X = erlang:adler32(Data1),
+ Y = erlang:adler32(Data2),
+ Z = erlang:adler32_combine(X,Y,iolist_size(Data2)).</code>
</desc>
</func>
+
<func>
<name name="append_element" arity="2"/>
- <fsummary>Append an extra element to a tuple</fsummary>
- <desc>
- <p>Returns a new tuple which has one element more than
- <c><anno>Tuple1</anno></c>, and contains the elements in <c><anno>Tuple1</anno></c>
- followed by <c><anno>Term</anno></c> as the last element. Semantically
- equivalent to
- <c>list_to_tuple(tuple_to_list(<anno>Tuple1</anno>) ++ [<anno>Term</anno>])</c>, but much
- faster.</p>
+ <fsummary>Appends an extra element to a tuple.</fsummary>
+ <desc>
+ <p>Returns a new tuple that has one element more than
+ <c><anno>Tuple1</anno></c>, and contains the elements in
+ <c><anno>Tuple1</anno></c>
+ followed by <c><anno>Term</anno></c> as the last element.
+ Semantically equivalent to
+ <c>list_to_tuple(tuple_to_list(<anno>Tuple1</anno>) ++
+ [<anno>Term</anno>])</c>, but much faster.</p>
+ <p>Example:</p>
<pre>
> <input>erlang:append_element({one, two}, three).</input>
{one,two,three}</pre>
</desc>
</func>
+
<func>
<name name="apply" arity="2"/>
- <fsummary>Apply a function to an argument list</fsummary>
+ <fsummary>Applies a function to an argument list.</fsummary>
<desc>
- <p>Call a fun, passing the elements in <c><anno>Args</anno></c> as
- arguments.</p>
- <p>Note: If the number of elements in the arguments are known at
- compile-time, the call is better written as
+ <p>Calls a fun, passing the elements in <c><anno>Args</anno></c>
+ as arguments.</p>
+ <p>If the number of elements in the arguments are known at
+ compile time, the call is better written as
<c><anno>Fun</anno>(Arg1, Arg2, ... ArgN)</c>.</p>
<warning>
<p>Earlier, <c><anno>Fun</anno></c> could also be given as
<c>{Module, Function}</c>, equivalent to
- <c>apply(Module, Function, Args)</c>. This usage is
- deprecated and will stop working in a future release of
- Erlang/OTP.</p>
+ <c>apply(Module, Function, Args)</c>. This use is
+ deprecated and will stop working in a future release.</p>
</warning>
</desc>
</func>
+
<func>
<name name="apply" arity="3"/>
- <fsummary>Apply a function to an argument list</fsummary>
+ <fsummary>Applies a function to an argument list.</fsummary>
<desc>
<p>Returns the result of applying <c>Function</c> in
- <c><anno>Module</anno></c> to <c><anno>Args</anno></c>. The applied function must
+ <c><anno>Module</anno></c> to <c><anno>Args</anno></c>.
+ The applied function must
be exported from <c>Module</c>. The arity of the function is
the length of <c>Args</c>.</p>
+ <p>Example:</p>
<pre>
> <input>apply(lists, reverse, [[a, b, c]]).</input>
-[c,b,a]</pre>
- <p><c>apply</c> can be used to evaluate BIFs by using
- the module name <c>erlang</c>.</p>
- <pre>
+[c,b,a]
> <input>apply(erlang, atom_to_list, ['Erlang']).</input>
"Erlang"</pre>
- <p>Note: If the number of arguments are known at compile-time,
+ <p>If the number of arguments are known at compile time,
the call is better written as
<c><anno>Module</anno>:<anno>Function</anno>(Arg1, Arg2, ..., ArgN)</c>.</p>
<p>Failure: <c>error_handler:undefined_function/3</c> is called
if the applied function is not exported. The error handler
can be redefined (see
<seealso marker="#process_flag/2">process_flag/2</seealso>).
- If the <c>error_handler</c> is undefined, or if the user has
+ If <c>error_handler</c> is undefined, or if the user has
redefined the default <c>error_handler</c> so the replacement
module is undefined, an error with the reason <c>undef</c>
is generated.</p>
</desc>
</func>
+
<func>
<name name="atom_to_binary" arity="2"/>
- <fsummary>Return the binary representation of an atom</fsummary>
- <desc>
- <p>Returns a binary which corresponds to the text
- representation of <c><anno>Atom</anno></c>. If <c><anno>Encoding</anno></c>
- is <c>latin1</c>, there will be one byte for each character
- in the text representation. If <c><anno>Encoding</anno></c> is
- <c>utf8</c> or
- <c>unicode</c>, the characters will be encoded using UTF-8
- (meaning that characters from 16#80 up to 0xFF will be
- encoded in two bytes).</p>
-
- <note><p>Currently, <c>atom_to_binary(<anno>Atom</anno>, latin1)</c> can
- never fail because the text representation of an atom can only contain
- characters from 0 to 16#FF. In a future release, the text representation
- of atoms might be allowed to contain any Unicode character
- and <c>atom_to_binary(<anno>Atom</anno>, latin1)</c> will fail if the
- text representation for the <c><anno>Atom</anno></c> contains a Unicode
- character greater than 16#FF.</p></note>
-
+ <fsummary>Returns the binary representation of an atom.</fsummary>
+ <desc>
+ <p>Returns a binary corresponding to the text
+ representation of <c><anno>Atom</anno></c>.
+ If <c><anno>Encoding</anno></c>
+ is <c>latin1</c>, there is one byte for each character
+ in the text representation. If <c><anno>Encoding</anno></c> is
+ <c>utf8</c> or
+ <c>unicode</c>, the characters are encoded using UTF-8
+ (that is, characters from 128 through 255 are
+ encoded in two bytes).</p>
+ <note><p><c>atom_to_binary(<anno>Atom</anno>, latin1)</c> never
+ fails because the text representation of an atom can only
+ contain characters from 0 through 255. In a future release,
+ the text representation
+ of atoms can be allowed to contain any Unicode character and
+ <c>atom_to_binary(<anno>Atom</anno>, latin1)</c> will then fail if the
+ text representation for <c><anno>Atom</anno></c> contains a Unicode
+ character greater than 255.</p></note>
+ <p>Example:</p>
<pre>
> <input>atom_to_binary('Erlang', latin1).</input>
&lt;&lt;"Erlang"&gt;&gt;</pre>
</desc>
</func>
+
<func>
<name name="atom_to_list" arity="1"/>
- <fsummary>Text representation of an atom</fsummary>
+ <fsummary>Text representation of an atom.</fsummary>
<desc>
- <p>Returns a string which corresponds to the text
- representation of <c><anno>Atom</anno></c>.</p>
+ <p>Returns a string corresponding to the text
+ representation of <c><anno>Atom</anno></c>, for example:</p>
<pre>
> <input>atom_to_list('Erlang').</input>
"Erlang"</pre>
</desc>
</func>
+
<func>
<name name="binary_part" arity="2"/>
- <fsummary>Extracts a part of a binary</fsummary>
+ <fsummary>Extracts a part of a binary.</fsummary>
<desc>
- <p>Extracts the part of the binary described by <c><anno>PosLen</anno></c>.</p>
-
- <p>Negative length can be used to extract bytes at the end of a binary:</p>
-
+ <p>Extracts the part of the binary described by
+ <c><anno>PosLen</anno></c>.</p>
+ <p>Negative length can be used to extract bytes at the end
+ of a binary, for example:</p>
<code>
1> Bin = &lt;&lt;1,2,3,4,5,6,7,8,9,10&gt;&gt;.
2> binary_part(Bin,{byte_size(Bin), -5}).
-&lt;&lt;6,7,8,9,10&gt;&gt;
-</code>
-
- <p>If <c><anno>PosLen</anno></c> in any way references outside the binary, a <c>badarg</c> exception is raised.</p>
-
- <p><c><anno>Start</anno></c> is zero-based, i.e.:</p>
+&lt;&lt;6,7,8,9,10&gt;&gt;</code>
+ <p>Failure: <c>badarg</c> if <c><anno>PosLen</anno></c> in any way
+ references outside the binary.</p>
+ <p><c><anno>Start</anno></c> is zero-based, that is:</p>
<code>
1> Bin = &lt;&lt;1,2,3&gt;&gt;
2> binary_part(Bin,{0,2}).
-&lt;&lt;1,2&gt;&gt;
-</code>
-
- <p>See the STDLIB module <c>binary</c> for details about the <c><anno>PosLen</anno></c> semantics.</p>
-
+&lt;&lt;1,2&gt;&gt;</code>
+ <p>For details about the <c><anno>PosLen</anno></c> semantics, see the
+ <seealso marker="stdlib:binary">binary</seealso>
+ manual page in <c>STDLIB</c>.</p>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="binary_part" arity="3"/>
- <fsummary>Extracts a part of a binary</fsummary>
+ <fsummary>Extracts a part of a binary.</fsummary>
<desc>
- <p>The same as <c>binary_part(<anno>Subject</anno>, {<anno>Start</anno>, <anno>Length</anno>})</c>.</p>
-
+ <p>The same as <c>binary_part(<anno>Subject</anno>,
+ {<anno>Start</anno>, <anno>Length</anno>})</c>.</p>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="binary_to_atom" arity="2"/>
- <fsummary>Convert from text representation to an atom</fsummary>
+ <fsummary>Converts from text representation to an atom.</fsummary>
<desc>
<p>Returns the atom whose text representation is
- <c><anno>Binary</anno></c>. If <c><anno>Encoding</anno></c> is <c>latin1</c>, no
- translation of bytes in the binary is done. If <c><anno>Encoding</anno></c>
- is <c>utf8</c> or <c>unicode</c>, the binary must contain
- valid UTF-8 sequences; furthermore, only Unicode characters up
- to 0xFF are allowed.</p>
-
- <note><p><c>binary_to_atom(<anno>Binary</anno>, utf8)</c> will fail if
- the binary contains Unicode characters greater than 16#FF.
- In a future release, such Unicode characters might be allowed
- and <c>binary_to_atom(<anno>Binary</anno>, utf8)</c>
- will not fail in that case. For more information on Unicode support in atoms
- see <seealso marker="erl_ext_dist#utf8_atoms">note on UTF-8 encoded atoms</seealso>
- in the chapter about the external term format in the ERTS User's Guide.</p></note>
-
+ <c><anno>Binary</anno></c>.
+ If <c><anno>Encoding</anno></c> is <c>latin1</c>, no
+ translation of bytes in the binary is done.
+ If <c><anno>Encoding</anno></c>
+ is <c>utf8</c> or <c>unicode</c>, the binary must contain
+ valid UTF-8 sequences. Only Unicode characters up
+ to 255 are allowed.</p>
+ <note><p><c>binary_to_atom(<anno>Binary</anno>, utf8)</c> fails if
+ the binary contains Unicode characters greater than 255.
+ In a future release, such Unicode characters can be allowed
+ and <c>binary_to_atom(<anno>Binary</anno>, utf8)</c> does then not fail.
+ For more information on Unicode support in atoms, see the
+ <seealso marker="erl_ext_dist#utf8_atoms">note on UTF-8
+ encoded atoms</seealso>
+ in Section "External Term Format" in the User's Guide.</p></note>
+ <p>Examples:</p>
<pre>
> <input>binary_to_atom(&lt;&lt;"Erlang"&gt;&gt;, latin1).</input>
'Erlang'
@@ -362,20 +373,24 @@
called as binary_to_atom(&lt;&lt;208,128&gt;&gt;,utf8)</pre>
</desc>
</func>
+
<func>
<name name="binary_to_existing_atom" arity="2"/>
- <fsummary>Convert from text representation to an atom</fsummary>
+ <fsummary>Converts from text representation to an atom.</fsummary>
<desc>
- <p>Works like <seealso marker="#binary_to_atom/2">binary_to_atom/2</seealso>,
- but the atom must already exist.</p>
- <p>Failure: <c>badarg</c> if the atom does not already exist.</p>
+ <p>As
+ <seealso marker="#binary_to_atom/2">binary_to_atom/2</seealso>,
+ but the atom must exist.</p>
+ <p>Failure: <c>badarg</c> if the atom does not exist.</p>
</desc>
</func>
+
<func>
<name name="binary_to_float" arity="1"/>
- <fsummary>Convert from text representation to a float</fsummary>
+ <fsummary>Converts from text representation to a float.</fsummary>
<desc>
- <p>Returns the float whose text representation is <c><anno>Binary</anno></c>.</p>
+ <p>Returns the float whose text representation is
+ <c><anno>Binary</anno></c>, for example:</p>
<pre>
> <input>binary_to_float(&lt;&lt;"2.2017764e+0">>).</input>
2.2017764</pre>
@@ -383,12 +398,13 @@
representation of a float.</p>
</desc>
</func>
+
<func>
<name name="binary_to_integer" arity="1"/>
- <fsummary>Convert from text representation to an integer</fsummary>
+ <fsummary>Converts from text representation to an integer.</fsummary>
<desc>
<p>Returns an integer whose text representation is
- <c><anno>Binary</anno></c>.</p>
+ <c><anno>Binary</anno></c>, for example:</p>
<pre>
> <input>binary_to_integer(&lt;&lt;"123"&gt;&gt;).</input>
123</pre>
@@ -396,12 +412,13 @@
representation of an integer.</p>
</desc>
</func>
+
<func>
<name name="binary_to_integer" arity="2"/>
- <fsummary>Convert from text representation to an integer</fsummary>
+ <fsummary>Converts from text representation to an integer.</fsummary>
<desc>
<p>Returns an integer whose text representation in base
- <c><anno>Base</anno></c> is <c><anno>Binary</anno></c>.</p>
+ <c><anno>Base</anno></c> is <c><anno>Binary</anno></c>, for example:</p>
<pre>
> <input>binary_to_integer(&lt;&lt;"3FF"&gt;&gt;, 16).</input>
1023</pre>
@@ -409,93 +426,101 @@
representation of an integer.</p>
</desc>
</func>
+
<func>
<name name="binary_to_list" arity="1"/>
- <fsummary>Convert a binary to a list</fsummary>
+ <fsummary>Converts a binary to a list.</fsummary>
<desc>
- <p>Returns a list of integers which correspond to the bytes of
+ <p>Returns a list of integers corresponding to the bytes of
<c><anno>Binary</anno></c>.</p>
</desc>
</func>
+
<func>
<name name="binary_to_list" arity="3"/>
- <fsummary>Convert part of a binary to a list</fsummary>
- <type_desc variable="Start">1..byte_size(<anno>Binary</anno>)</type_desc>
+ <fsummary>Converts part of a binary to a list.</fsummary>
+ <type_desc variable="Start">1..byte_size(<c><anno>Binary</anno></c>)</type_desc>
<desc>
<p>As <c>binary_to_list/1</c>, but returns a list of integers
corresponding to the bytes from position <c><anno>Start</anno></c> to
- position <c><anno>Stop</anno></c> in <c><anno>Binary</anno></c>. Positions in the
+ position <c><anno>Stop</anno></c> in <c><anno>Binary</anno></c>.
+ The positions in the
binary are numbered starting from 1.</p>
-
- <note><p>This function's indexing style of using one-based indices for
- binaries is deprecated. New code should use the functions in
- the STDLIB module <c>binary</c> instead. They consequently
- use the same (zero-based) style of indexing.</p></note>
+ <note><p>The one-based indexing for binaries used by
+ this function is deprecated. New code is to use
+ <seealso marker="stdlib:binary#bin_to_list/3">binary:bin_to_list/3</seealso>
+ in <c>STDLIB</c> instead. All functions in module
+ <c>binary</c> consistently use zero-based indexing.</p></note>
</desc>
</func>
+
<func>
<name name="bitstring_to_list" arity="1"/>
- <fsummary>Convert a bitstring to a list</fsummary>
+ <fsummary>Converts a bitstring to a list.</fsummary>
<desc>
- <p>Returns a list of integers which correspond to the bytes of
- <c><anno>Bitstring</anno></c>. If the number of bits in the binary is not
- divisible by 8, the last element of the list will be a bitstring
- containing the remaining bits (1 up to 7 bits).</p>
+ <p>Returns a list of integers corresponding to the bytes of
+ <c><anno>Bitstring</anno></c>. If the number of bits in the binary
+ is not divisible by 8, the last element of the list is a bitstring
+ containing the remaining 1-7 bits.</p>
</desc>
</func>
+
<func>
<name name="binary_to_term" arity="1"/>
- <fsummary>Decode an Erlang external term format binary</fsummary>
+ <fsummary>Decodes an Erlang external term format binary.</fsummary>
<desc>
- <p>Returns an Erlang term which is the result of decoding
- the binary object <c><anno>Binary</anno></c>, which must be encoded
+ <p>Returns an Erlang term that is the result of decoding
+ binary object <c><anno>Binary</anno></c>, which must be encoded
according to the Erlang external term format.</p>
- <warning>
- <p>When decoding binaries from untrusted sources, consider using
- <c>binary_to_term/2</c> to prevent denial of service attacks.</p>
- </warning>
- <p>See also
- <seealso marker="#term_to_binary/1">term_to_binary/1</seealso>
- and
- <seealso marker="#binary_to_term/2">binary_to_term/2</seealso>.</p>
+ <warning><p>When decoding binaries from untrusted sources,
+ consider using <c>binary_to_term/2</c> to prevent Denial
+ of Service attacks.</p></warning>
+ <p>See also
+ <seealso marker="#term_to_binary/1">term_to_binary/1</seealso>
+ and
+ <seealso marker="#binary_to_term/2">binary_to_term/2</seealso>.</p>
</desc>
</func>
+
<func>
<name name="binary_to_term" arity="2"/>
- <fsummary>Decode an Erlang external term format binary</fsummary>
+ <fsummary>Decodes an Erlang external term format binary.</fsummary>
<desc>
<p>As <c>binary_to_term/1</c>, but takes options that affect decoding
of the binary.</p>
<taglist>
<tag><c>safe</c></tag>
<item>
- <p>Use this option when receiving binaries from an untrusted
+ <p>Use this option when receiving binaries from an untrusted
source.</p>
- <p>When enabled, it prevents decoding data that may be used to
- attack the Erlang system. In the event of receiving unsafe
- data, decoding fails with a badarg error.</p>
- <p>Currently, this prevents creation of new atoms directly,
- creation of new atoms indirectly (as they are embedded in
- certain structures like pids, refs, funs, etc.), and creation of
- new external function references. None of those resources are
- currently garbage collected, so unchecked creation of them can
- exhaust available memory.</p>
+ <p>When enabled, it prevents decoding data that can be used to
+ attack the Erlang system. In the event of receiving unsafe
+ data, decoding fails with a <c>badarg</c> error.</p>
+ <p>This prevents creation of new atoms directly,
+ creation of new atoms indirectly (as they are embedded in
+ certain structures, such as process identifiers,
+ refs, and funs), and
+ creation of new external function references.
+ None of those resources are garbage collected, so unchecked
+ creation of them can exhaust available memory.</p>
</item>
</taglist>
- <p>Failure: <c>badarg</c> if <c>safe</c> is specified and unsafe data
- is decoded.</p>
+ <p>Failure: <c>badarg</c> if <c>safe</c> is specified and unsafe
+ data is decoded.</p>
<p>See also
<seealso marker="#term_to_binary/1">term_to_binary/1</seealso>,
<seealso marker="#binary_to_term/1">binary_to_term/1</seealso>,
- and <seealso marker="#list_to_existing_atom/1">
- list_to_existing_atom/1</seealso>.</p>
+ and
+ <seealso marker="#list_to_existing_atom/1">list_to_existing_atom/1</seealso>.</p>
</desc>
</func>
+
<func>
<name name="bit_size" arity="1"/>
- <fsummary>Return the size of a bitstring</fsummary>
+ <fsummary>Returns the size of a bitstring.</fsummary>
<desc>
- <p>Returns an integer which is the size in bits of <c><anno>Bitstring</anno></c>.</p>
+ <p>Returns an integer that is the size in bits of
+ <c><anno>Bitstring</anno></c>, for example:</p>
<pre>
> <input>bit_size(&lt;&lt;433:16,3:3&gt;&gt;).</input>
19
@@ -504,30 +529,34 @@
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="bump_reductions" arity="1"/>
- <fsummary>Increment the reduction counter</fsummary>
+ <fsummary>Increments the reduction counter.</fsummary>
<desc>
<p>This implementation-dependent function increments
the reduction counter for the calling process. In the Beam
emulator, the reduction counter is normally incremented by
- one for each function and BIF call, and a context switch is
- forced when the counter reaches the maximum number of reductions
- for a process (2000 reductions in R12B).</p>
+ one for each function and BIF call. A context switch is
+ forced when the counter reaches the maximum number of
+ reductions for a process (2000 reductions in OTP R12B).</p>
<warning>
- <p>This BIF might be removed in a future version of the Beam
+ <p>This BIF can be removed in a future version of the Beam
machine without prior warning. It is unlikely to be
implemented in other Erlang implementations.</p>
</warning>
</desc>
</func>
+
<func>
<name name="byte_size" arity="1"/>
- <fsummary>Return the size of a bitstring (or binary)</fsummary>
+ <fsummary>Returns the size of a bitstring (or binary).</fsummary>
<desc>
- <p>Returns an integer which is the number of bytes needed to contain
- <c><anno>Bitstring</anno></c>. (That is, if the number of bits in <c><anno>Bitstring</anno></c> is not
- divisible by 8, the resulting number of bytes will be rounded <em>up</em>.)</p>
+ <p>Returns an integer that is the number of bytes needed to
+ contain <c><anno>Bitstring</anno></c>. That is, if the number of bits
+ in <c><anno>Bitstring</anno></c> is not divisible by 8, the resulting
+ number of bytes is rounded <em>up</em>.</p>
+ <p>Examples:</p>
<pre>
> <input>byte_size(&lt;&lt;433:16,3:3&gt;&gt;).</input>
3
@@ -536,18 +565,19 @@
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="cancel_timer" arity="2"/>
- <fsummary>Cancel a timer</fsummary>
+ <fsummary>Cancels a timer.</fsummary>
<desc>
<p>
- Cancels a timer that has been created by either
+ Cancels a timer that has been created by
<seealso marker="#start_timer/4"><c>erlang:start_timer()</c></seealso>,
or <seealso marker="#send_after/4"><c>erlang:send_after()</c></seealso>.
<c><anno>TimerRef</anno></c> identifies the timer, and
was returned by the BIF that created the timer.
</p>
- <p>Currently available <c><anno>Option</anno></c>s:</p>
+ <p>Available <c><anno>Option</anno></c>s:</p>
<taglist>
<tag><c>{async, Async}</c></tag>
<item>
@@ -556,7 +586,7 @@
defaults to <c>false</c> which will cause the
cancellation to be performed synchronously. When
<c>Async</c> is set to <c>true</c>, the cancel
- operation will be performed asynchronously. That is,
+ operation is performed asynchronously. That is,
<c>erlang:cancel_timer()</c> will send an asynchronous
request for cancellation to the timer service that
manages the timer, and then return <c>ok</c>.
@@ -567,17 +597,17 @@
<p>
Request information about the <c><anno>Result</anno></c>
of the cancellation. <c>Info</c> defaults to <c>true</c>
- which means that the <c><anno>Result</anno></c> will
- be given. When <c>Info</c> is set to <c>false</c>, no
+ which means the <c><anno>Result</anno></c> is
+ given. When <c>Info</c> is set to <c>false</c>, no
information about the result of the cancellation
- will be given. When the operation is performed</p>
+ is given. When the operation is performed</p>
<taglist>
<tag>synchronously</tag>
<item>
<p>
- If <c>Info</c> is <c>true</c>, the <c>Result</c> will
+ If <c>Info</c> is <c>true</c>, the <c>Result</c> is
returned by <c>erlang:cancel_timer()</c>; otherwise,
- <c>ok</c> will be returned.
+ <c>ok</c> is returned.
</p>
</item>
<tag>asynchronously</tag>
@@ -585,10 +615,10 @@
<p>
If <c>Info</c> is <c>true</c>, a message on the form
<c>{cancel_timer, <anno>TimerRef</anno>,
- <anno>Result</anno>}</c> will be sent to the
+ <anno>Result</anno>}</c> is sent to the
caller of <c>erlang:cancel_timer()</c> when the
cancellation operation has been performed; otherwise,
- no message will be sent.
+ no message is sent.
</p>
</item>
</taglist>
@@ -597,30 +627,30 @@
<p>
More <c><anno>Option</anno></c>s may be added in the future.
</p>
+ <p>If <c><anno>Result</anno></c> is an integer, it represents
+ the time in milli-seconds left until the canceled timer would
+ have expired.</p>
<p>
- When the <c><anno>Result</anno></c> equals <c>false</c>, a
+ If <c><anno>Result</anno></c> is <c>false</c>, a
timer corresponding to <c><anno>TimerRef</anno></c> could not
be found. This can be either because the timer had expired,
already had been canceled, or because <c><anno>TimerRef</anno></c>
- never has corresponded to a timer. If the timer has expired,
- the timeout message has been sent, but it does not tell you
- whether or not it has arrived at its destination yet. When the
- <c><anno>Result</anno></c> is an integer, it represents the
- time in milli-seconds left until the timer will expire.
+ never corresponded to a timer. Even if the timer had expired,
+ it does not tell you whether or not the timeout message has
+ arrived at its destination yet.
</p>
<note>
<p>
The timer service that manages the timer may be co-located
with another scheduler than the scheduler that the calling
process is executing on. If this is the case, communication
- with the timer service will take much longer time than if it
+ with the timer service takes much longer time than if it
is located locally. If the calling process is in critical
path, and can do other things while waiting for the result
of this operation, or is not interested in the result of
- the operation, you want to use the <c>{async, true}</c>
- option. If using the <c>{async, false}</c> option, the calling
- process will be blocked until the operation has been
- performed.
+ the operation, you want to use option <c>{async, true}</c>.
+ If using option <c>{async, false}</c>, the calling
+ process blocks until the operation has been performed.
</p>
</note>
<p>See also
@@ -632,7 +662,7 @@
</func>
<func>
<name name="cancel_timer" arity="1"/>
- <fsummary>Cancel a timer</fsummary>
+ <fsummary>Cancels a timer.</fsummary>
<desc>
<p>Cancels a timer. The same as calling
<seealso marker="#cancel_timer/2"><c>erlang:cancel_timer(TimerRef,
@@ -641,103 +671,102 @@
</func>
<func>
<name name="check_old_code" arity="1"/>
- <fsummary>Check if a module has old code</fsummary>
+ <fsummary>Checks if a module has old code.</fsummary>
<desc>
- <p>Returns <c>true</c> if the <c><anno>Module</anno></c> has old code,
- and <c>false</c> otherwise.</p>
+ <p>Returns <c>true</c> if <c><anno>Module</anno></c> has old code,
+ otherwise <c>false</c>.</p>
<p>See also <seealso marker="kernel:code">code(3)</seealso>.</p>
</desc>
</func>
+
<func>
<name name="check_process_code" arity="2"/>
- <fsummary>Check if a process is executing old code for a module</fsummary>
+ <fsummary>Checks if a process executes old code for a module.</fsummary>
<desc>
<p>The same as
- <seealso marker="#check_process_code/3"><c>erlang:check_process_code(<anno>Pid</anno>,
- <anno>Module</anno>, [])</c></seealso>.</p>
+ <seealso marker="#check_process_code/3"><c>erlang:check_process_code(<anno>Pid</anno>, <anno>Module</anno>, [])</c></seealso>.</p>
</desc>
</func>
+
<func>
<name name="check_process_code" arity="3"/>
- <fsummary>Check if a process is executing old code for a module</fsummary>
+ <fsummary>Checks if a process executes old code for a module.</fsummary>
<desc>
- <p>Check if the node local process identified by <c><anno>Pid</anno></c>
- is executing old code for <c><anno>Module</anno></c>.</p>
- <p>Currently available <c><anno>Option</anno>s</c>:</p>
+ <p>Checks if the node local process identified by <c><anno>Pid</anno></c>
+ executes old code for <c><anno>Module</anno></c>.</p>
+ <p>The available <c><anno>Option</anno></c>s are as follows:</p>
<taglist>
<tag><c>{allow_gc, boolean()}</c></tag>
<item>
- Determines if garbage collection is allowed when performing
- the operation. If <c>{allow_gc, false}</c> is passed, and
- a garbage collection is needed in order to determine the
- result of the operation, the operation will be aborted
- (see information on <c><anno>CheckResult</anno></c> below).
- The default is to allow garbage collection, i.e.,
- <c>{allow_gc, true}</c>.
+ <p>Determines if garbage collection is allowed when performing
+ the operation. If <c>{allow_gc, false}</c> is passed, and
+ a garbage collection is needed to determine the
+ result of the operation, the operation is aborted (see
+ information on <c><anno>CheckResult</anno></c> in the following).
+ The default is to allow garbage collection, that is,
+ <c>{allow_gc, true}</c>.</p>
</item>
<tag><c>{async, RequestId}</c></tag>
<item>
- The <c>check_process_code/3</c> function will return
- the value <c>async</c> immediately after the request
- has been sent. When the request has been processed, the
- process that called this function will be passed a
- message on the form:<br/>
- <c>{check_process_code, <anno>RequestId</anno>, <anno>CheckResult</anno>}</c>.
+ <p>The function <c>check_process_code/3</c> returns
+ the value <c>async</c> immediately after the request
+ has been sent. When the request has been processed, the
+ process that called this function is passed a
+ message on the form
+ <c>{check_process_code, <anno>RequestId</anno>, <anno>CheckResult</anno>}</c>.</p>
</item>
</taglist>
- <p>If <c><anno>Pid</anno></c> equals <c>self()</c>, and
- no <c>async</c> option has been passed, the operation will
- be performed at once. In all other cases a request for
- the operation will be sent to the process identified by
- <c><anno>Pid</anno></c>, and will be handled when
- appropriate. If no <c>async</c> option has been passed,
- the caller will block until <c><anno>CheckResult</anno></c>
- is available and can be returned.</p>
- <p><c><anno>CheckResult</anno></c> informs about the result of
- the request:</p>
+ <p>If <c><anno>Pid</anno></c> equals <c>self()</c>, and
+ no <c>async</c> option has been passed, the operation
+ is performed at once. Otherwise a request for
+ the operation is sent to the process identified by
+ <c><anno>Pid</anno></c>, and is handled when
+ appropriate. If no <c>async</c> option has been passed,
+ the caller blocks until <c><anno>CheckResult</anno></c>
+ is available and can be returned.</p>
+ <p><c><anno>CheckResult</anno></c> informs about the result of
+ the request as follows:</p>
<taglist>
<tag><c>true</c></tag>
<item>
- The process identified by <c><anno>Pid</anno></c> is
- executing old code for <c><anno>Module</anno></c>.
- That is, the current call of the process executes old
- code for this module, or the process has references
- to old code for this module, or the process contains
- funs that references old code for this module.
+ <p>The process identified by <c><anno>Pid</anno></c>
+ executes old code for <c><anno>Module</anno></c>.
+ That is, the current call of the process executes old
+ code for this module, or the process has references
+ to old code for this module, or the process contains
+ funs that references old code for this module.</p>
</item>
<tag><c>false</c></tag>
<item>
- The process identified by <c><anno>Pid</anno></c> is
- not executing old code for <c><anno>Module</anno></c>.
+ <p>The process identified by <c><anno>Pid</anno></c> does
+ not execute old code for <c><anno>Module</anno></c>.</p>
</item>
<tag><c>aborted</c></tag>
<item>
- The operation was aborted since the process needed to
- be garbage collected in order to determine the result
- of the operation, and the operation was requested
- by passing the <c>{allow_gc, false}</c> option.</item>
+ <p>The operation was aborted, as the process needed to
+ be garbage collected to determine the operation result,
+ and the operation was requested
+ by passing option <c>{allow_gc, false}</c>.</p></item>
</taglist>
<p>See also <seealso marker="kernel:code">code(3)</seealso>.</p>
<p>Failures:</p>
<taglist>
<tag><c>badarg</c></tag>
- <item>
- If <c><anno>Pid</anno></c> is not a node local process identifier.
+ <item>If <c><anno>Pid</anno></c> is not a node local process identifier.
</item>
<tag><c>badarg</c></tag>
- <item>
- If <c><anno>Module</anno></c> is not an atom.
+ <item>If <c><anno>Module</anno></c> is not an atom.
</item>
<tag><c>badarg</c></tag>
- <item>
- If <c><anno>OptionList</anno></c> is not a valid list of options.
+ <item>If <c><anno>OptionList</anno></c> is an invalid list of options.
</item>
</taglist>
</desc>
</func>
+
<func>
<name name="convert_time_unit" arity="3"/>
- <fsummary>Convert time unit of a time value</fsummary>
+ <fsummary>Converts time unit of a time value.</fsummary>
<desc>
<p>Converts the <c><anno>Time</anno></c> value of time unit
<c><anno>FromUnit</anno></c> to the corresponding
@@ -753,100 +782,102 @@
</func>
<func>
<name name="crc32" arity="1"/>
- <fsummary>Compute crc32 (IEEE 802.3) checksum</fsummary>
+ <fsummary>Computes crc32 (IEEE 802.3) checksum.</fsummary>
<desc>
- <p>Computes and returns the crc32 (IEEE 802.3 style) checksum for <c><anno>Data</anno></c>.</p>
+ <p>Computes and returns the crc32 (IEEE 802.3 style) checksum
+ for <c><anno>Data</anno></c>.</p>
</desc>
</func>
+
<func>
<name name="crc32" arity="2"/>
- <fsummary>Compute crc32 (IEEE 802.3) checksum</fsummary>
+ <fsummary>Computes crc32 (IEEE 802.3) checksum.</fsummary>
<desc>
- <p>Continue computing the crc32 checksum by combining
- the previous checksum, <c><anno>OldCrc</anno></c>, with the checksum of
- <c><anno>Data</anno></c>.</p>
- <p>The following code:</p>
- <code>
- X = erlang:crc32(Data1),
- Y = erlang:crc32(X,Data2).
- </code>
- <p>- would assign the same value to <c>Y</c> as this would:</p>
- <code>
- Y = erlang:crc32([Data1,Data2]).
- </code>
+ <p>Continues computing the crc32 checksum by combining
+ the previous checksum, <c><anno>OldCrc</anno></c>, with the checksum of
+ <c><anno>Data</anno></c>.</p>
+ <p>The following code:</p>
+ <code>
+ X = erlang:crc32(Data1),
+ Y = erlang:crc32(X,Data2).</code>
+ <p>assigns the same value to <c>Y</c> as this:</p>
+ <code>
+ Y = erlang:crc32([Data1,Data2]).</code>
</desc>
</func>
+
<func>
<name name="crc32_combine" arity="3"/>
- <fsummary>Combine two crc32 (IEEE 802.3) checksums</fsummary>
- <desc>
- <p>Combines two previously computed crc32 checksums.
- This computation requires the size of the data object for
- the second checksum to be known.</p>
- <p>The following code:</p>
+ <fsummary>Combines two crc32 (IEEE 802.3) checksums.</fsummary>
+ <desc>
+ <p>Combines two previously computed crc32 checksums.
+ This computation requires the size of the data object for
+ the second checksum to be known.</p>
+ <p>The following code:</p>
+ <code>
+ Y = erlang:crc32(Data1),
+ Z = erlang:crc32(Y,Data2).</code>
+ <p>assigns the same value to <c>Z</c> as this:</p>
<code>
- Y = erlang:crc32(Data1),
- Z = erlang:crc32(Y,Data2).
- </code>
- <p>- would assign the same value to <c>Z</c> as this would:</p>
- <code>
- X = erlang:crc32(Data1),
- Y = erlang:crc32(Data2),
- Z = erlang:crc32_combine(X,Y,iolist_size(Data2)).
- </code>
+ X = erlang:crc32(Data1),
+ Y = erlang:crc32(Data2),
+ Z = erlang:crc32_combine(X,Y,iolist_size(Data2)).</code>
</desc>
</func>
+
<func>
<name name="date" arity="0"/>
- <fsummary>Current date</fsummary>
+ <fsummary>Current date.</fsummary>
<desc>
<p>Returns the current date as <c>{Year, Month, Day}</c>.</p>
- <p>The time zone and daylight saving time correction depend on
+ <p>The time zone and Daylight Saving Time correction depend on
the underlying OS.</p>
+ <p>Example:</p>
<pre>
> <input>date().</input>
{1995,2,19}</pre>
</desc>
</func>
+
<func>
<name name="decode_packet" arity="3"/>
- <fsummary>Extracts a protocol packet from a binary</fsummary>
+ <fsummary>Extracts a protocol packet from a binary.</fsummary>
<desc>
-
<p>Decodes the binary <c><anno>Bin</anno></c> according to the packet
- protocol specified by <c><anno>Type</anno></c>. Very similar to the packet
- handling done by sockets with the option {packet,<anno>Type</anno>}.</p>
- <p>If an entire packet is contained in <c><anno>Bin</anno></c> it is
+ protocol specified by <c><anno>Type</anno></c>. Similar to the packet
+ handling done by sockets with option {packet,<anno>Type</anno>}.</p>
+ <p>If an entire packet is contained in <c><anno>Bin</anno></c>, it is
returned together with the remainder of the binary as
<c>{ok,<anno>Packet</anno>,<anno>Rest</anno>}</c>.</p>
<p>If <c><anno>Bin</anno></c> does not contain the entire packet,
- <c>{more,<anno>Length</anno>}</c> is returned. <c><anno>Length</anno></c> is either the
- expected <em>total size</em> of the packet or <c>undefined</c>
- if the expected packet size is not known. <c>decode_packet</c>
+ <c>{more,<anno>Length</anno>}</c> is returned.
+ <c><anno>Length</anno></c> is either the
+ expected <em>total size</em> of the packet, or <c>undefined</c>
+ if the expected packet size is unknown. <c>decode_packet</c>
can then be called again with more data added.</p>
- <p>If the packet does not conform to the protocol format
+ <p>If the packet does not conform to the protocol format,
<c>{error,<anno>Reason</anno>}</c> is returned.</p>
- <p>The following values of <c><anno>Type</anno></c> are valid:</p>
+ <p>The following <c>Type</c>s are valid:</p>
<taglist>
<tag><c>raw | 0</c></tag>
<item>
- <p>No packet handling is done. Entire binary is
+ <p>No packet handling is done. The entire binary is
returned unless it is empty.</p>
</item>
<tag><c>1 | 2 | 4</c></tag>
<item>
<p>Packets consist of a header specifying the number of
bytes in the packet, followed by that number of bytes.
- The length of header can be one, two, or four bytes;
+ The length of the header can be one, two, or four bytes;
the order of the bytes is big-endian. The header
- will be stripped off when the packet is returned.</p>
+ is stripped off when the packet is returned.</p>
</item>
<tag><c>line</c></tag>
<item>
- <p>A packet is a line terminated with newline. The
- newline character is included in the returned packet
- unless the line was truncated according to the option
- <c>line_length</c>.</p>
+ <p>A packet is a line terminated by a delimiter byte,
+ default is the latin1 newline character. The delimiter
+ byte is included in the returned packet unless the line
+ was truncated according to option <c>line_length</c>.</p>
</item>
<tag><c>asn1 | cdr | sunrm | fcgi | tpkt</c></tag>
<item>
@@ -864,41 +895,50 @@
<item>
<p>The Hypertext Transfer Protocol. The packets
are returned with the format according to
- <c><anno>HttpPacket</anno></c> described above. A packet is either a
- request, a response, a header or an end of header
- mark. Invalid lines are returned as <c><anno>HttpError</anno></c>.</p>
- <p>Recognized request methods and header fields are returned as atoms.
- Others are returned as strings. Strings of unrecognized header fields
- are formatted with only capital letters first and after hyphen characters
- (like <c>"Sec-Websocket-Key"</c>).</p>
- <p>The protocol type <c>http</c> should only be used for
- the first line when a <c><anno>HttpRequest</anno></c> or a
- <c><anno>HttpResponse</anno></c> is expected. The following calls
- should use <c>httph</c> to get <c><anno>HttpHeader</anno></c>'s until
- <c>http_eoh</c> is returned that marks the end of the
+ <c><anno>HttpPacket</anno></c> described earlier.
+ A packet is either a
+ request, a response, a header, or an end of header
+ mark. Invalid lines are returned as
+ <c><anno>HttpError</anno></c>.</p>
+ <p>Recognized request methods and header fields are returned
+ as atoms. Others are returned as strings. Strings of
+ unrecognized header fields are formatted with only
+ capital letters first and after hyphen characters, for
+ example, <c>"Sec-Websocket-Key"</c>.</p>
+ <p>The protocol type <c>http</c> is only to be used for
+ the first line when an <c><anno>HttpRequest</anno></c> or an
+ <c><anno>HttpResponse</anno></c> is expected.
+ The following calls are to use <c>httph</c> to get
+ <c><anno>HttpHeader</anno></c>s until
+ <c>http_eoh</c> is returned, which marks the end of the
headers and the beginning of any following message body.</p>
- <p>The variants <c>http_bin</c> and <c>httph_bin</c> will return
+ <p>The variants <c>http_bin</c> and <c>httph_bin</c> return
strings (<c>HttpString</c>) as binaries instead of lists.</p>
</item>
</taglist>
<p>The following options are available:</p>
<taglist>
<tag><c>{packet_size, integer() >= 0}</c></tag>
- <item><p>Sets the max allowed size of the packet body. If
- the packet header indicates that the length of the
- packet is longer than the max allowed length, the packet
- is considered invalid. Default is 0 which means no
- size limit.</p>
+ <item><p>Sets the maximum allowed size of the packet body.
+ If the packet header indicates that the length of the
+ packet is longer than the maximum allowed length, the
+ packet is considered invalid. Default is 0, which means
+ no size limit.</p>
</item>
<tag><c>{line_length, integer() >= 0}</c></tag>
- <item><p>For packet type <c>line</c>, truncate lines longer
- than the indicated length.</p>
- <p>Option <c>line_length</c> also applies to <c>http*</c>
- packet types as an alias for option <c>packet_size</c> in the
- case when <c>packet_size</c> itself is not set. This usage is
- only intended for backward compatibility.</p>
+ <item><p>For packet type <c>line</c>, lines longer than
+ the indicated length are truncated.</p>
+ <p>Option <c>line_length</c> also applies to <c>http*</c>
+ packet types as an alias for option <c>packet_size</c>
+ if <c>packet_size</c> itself is not set. This use is
+ only intended for backward compatibility.</p>
+ </item>
+ <tag><c>{line_delimiter, 0 =&lt; byte() =&lt; 255}</c></tag>
+ <item><p>For packet type <c>line</c>, sets the delimiting byte.
+ Default is the latin1 character <c>$\n</c>.</p>
</item>
</taglist>
+ <p>Examples:</p>
<pre>
> <input>erlang:decode_packet(1,&lt;&lt;3,"abcd"&gt;&gt;,[]).</input>
{ok,&lt;&lt;"abc"&gt;&gt;,&lt;&lt;"d"&gt;&gt;}
@@ -909,13 +949,11 @@
<func>
<name name="delete_element" arity="2"/>
- <fsummary>Delete element at index in a tuple</fsummary>
+ <fsummary>Deletes element at index in a tuple.</fsummary>
<type_desc variable="Index">1..tuple_size(<anno>Tuple1</anno>)</type_desc>
<desc>
- <p>
- Returns a new tuple with element at <c><anno>Index</anno></c> removed from
- tuple <c><anno>Tuple1</anno></c>.
- </p>
+ <p>Returns a new tuple with element at <c><anno>Index</anno></c>
+ removed from tuple <c><anno>Tuple1</anno></c>, for example:</p>
<pre>
> <input>erlang:delete_element(2, {one, two, three}).</input>
{one,three}</pre>
@@ -924,45 +962,49 @@
<func>
<name name="delete_module" arity="1"/>
- <fsummary>Make the current code for a module old</fsummary>
+ <fsummary>Makes the current code for a module old.</fsummary>
<desc>
- <p>Makes the current code for <c><anno>Module</anno></c> become old code, and
- deletes all references for this module from the export table.
+ <p>Makes the current code for <c><anno>Module</anno></c> become old code,
+ and deletes all references for this module from the export table.
Returns <c>undefined</c> if the module does not exist,
otherwise <c>true</c>.</p>
<warning>
<p>This BIF is intended for the code server (see
- <seealso marker="kernel:code">code(3)</seealso>) and should not be
- used elsewhere.</p>
+ <seealso marker="kernel:code">code(3)</seealso>) and is not
+ to be used elsewhere.</p>
</warning>
- <p>Failure: <c>badarg</c> if there is already an old version of
+ <p>Failure: <c>badarg</c> if there already is an old version of
<c>Module</c>.</p>
</desc>
</func>
+
<func>
<name name="demonitor" arity="1"/>
- <fsummary>Stop monitoring</fsummary>
+ <fsummary>Stops monitoring.</fsummary>
<desc>
- <p>If <c><anno>MonitorRef</anno></c> is a reference which the calling process
- obtained by calling
+ <p>If <c><anno>MonitorRef</anno></c> is a reference that the
+ calling process obtained by calling
<seealso marker="#monitor/2">monitor/2</seealso>,
this monitoring is turned off. If the monitoring is already
turned off, nothing happens.</p>
- <p>Once <c>demonitor(<anno>MonitorRef</anno>)</c> has returned it is
- guaranteed that no <c>{'DOWN', <anno>MonitorRef</anno>, _, _, _}</c> message
- due to the monitor will be placed in the caller's message queue
- in the future. A <c>{'DOWN', <anno>MonitorRef</anno>, _, _, _}</c> message
- might have been placed in the caller's message queue prior to
- the call, though. Therefore, in most cases, it is advisable
+ <p>Once <c>demonitor(<anno>MonitorRef</anno>)</c> has returned, it is
+ guaranteed that no <c>{'DOWN',
+ <anno>MonitorRef</anno>, _, _, _}</c> message,
+ because of the monitor, will be placed in the caller message queue
+ in the future. A <c>{'DOWN',
+ <anno>MonitorRef</anno>, _, _, _}</c> message
+ can have been placed in the caller message queue before
+ the call, though. It is therefore usually advisable
to remove such a <c>'DOWN'</c> message from the message queue
- after monitoring has been stopped.
- <seealso marker="#demonitor/2">demonitor(<anno>MonitorRef</anno>, [flush])</seealso> can be used instead of
+ after monitoring has been stopped.
+ <seealso marker="#demonitor/2"><c>demonitor(<anno>MonitorRef</anno>, [flush])</c></seealso>
+ can be used instead of
<c>demonitor(<anno>MonitorRef</anno>)</c> if this cleanup is wanted.</p>
<note>
- <p>Prior to OTP release R11B (erts version 5.5) <c>demonitor/1</c>
- behaved completely asynchronous, i.e., the monitor was active
+ <p>Prior to OTP release R11B (ERTS version 5.5) <c>demonitor/1</c>
+ behaved completely asynchronously, i.e., the monitor was active
until the "demonitor signal" reached the monitored entity. This
- had one undesirable effect, though. You could never know when
+ had one undesirable effect. You could never know when
you were guaranteed <em>not</em> to receive a <c>DOWN</c> message
due to the monitor.</p>
<p>Current behavior can be viewed as two combined operations:
@@ -971,31 +1013,31 @@
</note>
<p>Failure: It is an error if <c><anno>MonitorRef</anno></c> refers to a
monitoring started by another process. Not all such cases are
- cheap to check; if checking is cheap, the call fails with
- <c>badarg</c> (for example if <c><anno>MonitorRef</anno></c> is a remote
- reference).</p>
+ cheap to check. If checking is cheap, the call fails with
+ <c>badarg</c> for example, if <c><anno>MonitorRef</anno></c> is a
+ remote reference.</p>
</desc>
</func>
+
<func>
<name name="demonitor" arity="2"/>
- <fsummary>Stop monitoring</fsummary>
+ <fsummary>Stops monitoring.</fsummary>
<desc>
<p>The returned value is <c>true</c> unless <c>info</c> is part
- of <c><anno>OptionList</anno></c>.
- </p>
+ of <c><anno>OptionList</anno></c>.</p>
<p><c>demonitor(<anno>MonitorRef</anno>, [])</c> is equivalent to
- <seealso marker="#demonitor/1">demonitor(<anno>MonitorRef</anno>)</seealso>.</p>
- <p>Currently the following <c><anno>Option</anno></c>s are valid:</p>
+ <seealso marker="#demonitor/1"><c>demonitor(<anno>MonitorRef</anno>)</c></seealso>.</p>
+ <p>The available <c><anno>Option</anno></c>s are as follows:</p>
<taglist>
<tag><c>flush</c></tag>
<item>
- <p>Remove (one) <c>{_, <anno>MonitorRef</anno>, _, _, _}</c> message,
- if there is one, from the caller's message queue after
+ <p>Removes (one) <c>{_,
+ <anno>MonitorRef</anno>, _, _, _}</c> message,
+ if there is one, from the caller message queue after
monitoring has been stopped.</p>
<p>Calling <c>demonitor(<anno>MonitorRef</anno>, [flush])</c>
is equivalent to the following, but more efficient:</p>
<code type="none">
-
demonitor(MonitorRef),
receive
{_, MonitorRef, _, _, _} ->
@@ -1006,78 +1048,90 @@
</item>
<tag><c>info</c></tag>
<item>
- <p>The returned value is one of the following:</p>
- <taglist>
- <tag><c>true</c></tag>
- <item><p>The monitor was found and removed. In this case
- no <c>'DOWN'</c> message due to this monitor have
- been nor will be placed in the message queue
- of the caller.
- </p>
- </item>
- <tag><c>false</c></tag>
- <item><p>The monitor was not found and could not be removed.
- This probably because someone already has placed a
- <c>'DOWN'</c> message corresponding to this monitor
- in the caller's message queue.
- </p>
- </item>
- </taglist>
- <p>If the <c>info</c> option is combined with the <c>flush</c>
- option, <c>false</c> will be returned if a flush was needed;
- otherwise, <c>true</c>.
- </p>
+ <p>The returned value is one of the following:</p>
+ <taglist>
+ <tag><c>true</c></tag>
+ <item>The monitor was found and removed. In this case,
+ no <c>'DOWN'</c> message corresponding to this
+ monitor has been delivered and will not be delivered.
+ </item>
+ <tag><c>false</c></tag>
+ <item>The monitor was not found and could not be removed.
+ This probably because someone already has placed a
+ <c>'DOWN'</c> message corresponding to this monitor
+ in the caller message queue.
+ </item>
+ </taglist>
+ <p>If option <c>info</c> is combined with option <c>flush</c>,
+ <c>false</c> is returned if a flush was needed,
+ otherwise <c>true</c>.</p>
</item>
</taglist>
<note>
- <p>More options may be added in the future.</p>
+ <p>More options can be added in a future release.</p>
</note>
- <p>Failure: <c>badarg</c> if <c><anno>OptionList</anno></c> is not a list, or
- if <c><anno>Option</anno></c> is not a valid option, or the same failure as for
- <seealso marker="#demonitor/1">demonitor/1</seealso></p>
+ <p>Failures:</p>
+ <taglist>
+ <tag><c>badarg</c></tag>
+ <item>If <c><anno>OptionList</anno></c> is not a list.
+ </item>
+ <tag><c>badarg</c></tag>
+ <item>If <c><anno>Option</anno></c> is an invalid option.
+ </item>
+ <tag><c>badarg</c></tag>
+ <item>The same failure as for
+ <seealso marker="#demonitor/1">demonitor/1</seealso>.
+ </item>
+ </taglist>
</desc>
</func>
+
<func>
<name name="disconnect_node" arity="1"/>
- <fsummary>Force the disconnection of a node</fsummary>
+ <fsummary>Forces the disconnection of a node.</fsummary>
<desc>
- <p>Forces the disconnection of a node. This will appear to
- the node <c><anno>Node</anno></c> as if the local node has crashed. This
- BIF is mainly used in the Erlang network authentication
- protocols. Returns <c>true</c> if disconnection succeeds,
+ <p>Forces the disconnection of a node. This appears to
+ the node <c><anno>Node</anno></c> as if the local node has crashed.
+ This BIF is mainly used in the Erlang network authentication
+ protocols.</p>
+ <p>Returns <c>true</c> if disconnection succeeds,
otherwise <c>false</c>. If the local node is not alive,
- the function returns <c>ignored</c>.</p>
+ <c>ignored</c> is returned.</p>
</desc>
</func>
+
<func>
<name name="display" arity="1"/>
- <fsummary>Print a term on standard output</fsummary>
+ <fsummary>Prints a term on standard output.</fsummary>
<desc>
- <p>Prints a text representation of <c><anno>Term</anno></c> on the standard
- output. On OSE the term is printed to the ramlog.</p>
+ <p>Prints a text representation of <c><anno>Term</anno></c> on the
+ standard output. On OSE, the term is printed to the ramlog.</p>
<warning>
<p>This BIF is intended for debugging only.</p>
</warning>
</desc>
</func>
+
<func>
<name name="element" arity="2"/>
+ <fsummary>Returns the Nth element of a tuple.</fsummary>
<type_desc variable="N">1..tuple_size(<anno>Tuple</anno>)</type_desc>
- <fsummary>Get Nth element of a tuple</fsummary>
<desc>
<p>Returns the <c><anno>N</anno></c>th element (numbering from 1) of
- <c><anno>Tuple</anno></c>.</p>
+ <c><anno>Tuple</anno></c>, for example:</p>
<pre>
> <input>element(2, {a, b, c}).</input>
b</pre>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="erase" arity="0"/>
- <fsummary>Return and delete the process dictionary</fsummary>
+ <fsummary>Returns and deletes the process dictionary.</fsummary>
<desc>
- <p>Returns the process dictionary and deletes it.</p>
+ <p>Returns the process dictionary and deletes it, for
+ example:</p>
<pre>
> <input>put(key1, {1, 2, 3}),</input>
<input>put(key2, [a, b, c]),</input>
@@ -1085,13 +1139,16 @@ b</pre>
[{key1,{1,2,3}},{key2,[a,b,c]}]</pre>
</desc>
</func>
+
<func>
<name name="erase" arity="1"/>
- <fsummary>Return and delete a value from the process dictionary</fsummary>
+ <fsummary>Returns and deletes a value from the process dictionary.</fsummary>
<desc>
- <p>Returns the value <c><anno>Val</anno></c> associated with <c><anno>Key</anno></c> and
- deletes it from the process dictionary. Returns
- <c>undefined</c> if no value is associated with <c><anno>Key</anno></c>.</p>
+ <p>Returns the value <c><anno>Val</anno></c> associated with
+ <c><anno>Key</anno></c> and deletes it from the process dictionary.
+ Returns <c>undefined</c> if no value is associated with
+ <c><anno>Key</anno></c>.</p>
+ <p>Example:</p>
<pre>
> <input>put(key1, {merry, lambs, are, playing}),</input>
<input>X = erase(key1),</input>
@@ -1099,16 +1156,19 @@ b</pre>
{{merry,lambs,are,playing},undefined}</pre>
</desc>
</func>
+
<func>
<name name="error" arity="1"/>
- <fsummary>Stop execution with a given reason</fsummary>
+ <fsummary>Stops execution with a given reason.</fsummary>
<desc>
<p>Stops the execution of the calling process with the reason
- <c><anno>Reason</anno></c>, where <c><anno>Reason</anno></c> is any term. The actual
- exit reason will be <c>{<anno>Reason</anno>, Where}</c>, where <c>Where</c>
+ <c><anno>Reason</anno></c>, where <c><anno>Reason</anno></c>
+ is any term. The exit reason is
+ <c>{<anno>Reason</anno>, Where}</c>, where <c>Where</c>
is a list of the functions most recently called (the current
function first). Since evaluating this function causes
the process to terminate, it has no return value.</p>
+ <p>Example:</p>
<pre>
> <input>catch error(foobar).</input>
{'EXIT',{foobar,[{erl_eval,do_apply,5},
@@ -1118,29 +1178,34 @@ b</pre>
{shell,eval_loop,3}]}}</pre>
</desc>
</func>
+
<func>
<name name="error" arity="2"/>
- <fsummary>Stop execution with a given reason</fsummary>
+ <fsummary>Stops execution with a given reason.</fsummary>
<desc>
<p>Stops the execution of the calling process with the reason
- <c><anno>Reason</anno></c>, where <c><anno>Reason</anno></c> is any term. The actual
- exit reason will be <c>{<anno>Reason</anno>, Where}</c>, where <c>Where</c>
+ <c><anno>Reason</anno></c>, where <c><anno>Reason</anno></c>
+ is any term. The exit reason is
+ <c>{<anno>Reason</anno>, Where}</c>, where <c>Where</c>
is a list of the functions most recently called (the current
- function first). <c><anno>Args</anno></c> is expected to be the list of
- arguments for the current function; in Beam it will be used
- to provide the actual arguments for the current function in
- the <c>Where</c> term. Since evaluating this function causes
+ function first). <c><anno>Args</anno></c> is expected to be the
+ list of arguments for the current function; in Beam it is used
+ to provide the arguments for the current function in
+ the term <c>Where</c>. Since evaluating this function causes
the process to terminate, it has no return value.</p>
</desc>
</func>
+
<func>
<name name="exit" arity="1"/>
- <fsummary>Stop execution with a given reason</fsummary>
+ <fsummary>Stops execution with a given reason.</fsummary>
<desc>
- <p>Stops the execution of the calling process with the exit
- reason <c><anno>Reason</anno></c>, where <c><anno>Reason</anno></c> is any term. Since
+ <p>Stops the execution of the calling process with exit reason
+ <c><anno>Reason</anno></c>, where <c><anno>Reason</anno></c>
+ is any term. Since
evaluating this function causes the process to terminate, it
has no return value.</p>
+ <p>Example:</p>
<pre>
> <input>exit(foobar).</input>
** exception exit: foobar
@@ -1148,110 +1213,117 @@ b</pre>
{'EXIT',foobar}</pre>
</desc>
</func>
+
<func>
<name name="exit" arity="2"/>
- <fsummary>Send an exit signal to a process or a port</fsummary>
+ <fsummary>Sends an exit signal to a process or a port.</fsummary>
<desc>
<p>Sends an exit signal with exit reason <c><anno>Reason</anno></c> to
the process or port identified by <c><anno>Pid</anno></c>.</p>
- <p>The following behavior apply if <c><anno>Reason</anno></c> is any term
- except <c>normal</c> or <c>kill</c>:</p>
- <p>If <c><anno>Pid</anno></c> is not trapping exits, <c><anno>Pid</anno></c> itself will
- exit with exit reason <c><anno>Reason</anno></c>. If <c><anno>Pid</anno></c> is trapping
- exits, the exit signal is transformed into a message
- <c>{'EXIT', From, <anno>Reason</anno>}</c> and delivered to the message
- queue of <c><anno>Pid</anno></c>. <c>From</c> is the pid of the process
- which sent the exit signal. See also
- <seealso marker="#process_flag/2">process_flag/2</seealso>.</p>
- <p>If <c><anno>Reason</anno></c> is the atom <c>normal</c>, <c><anno>Pid</anno></c> will
- not exit. If it is trapping exits, the exit signal is
- transformed into a message <c>{'EXIT', From, normal}</c>
- and delivered to its message queue.</p>
- <p>If <c><anno>Reason</anno></c> is the atom <c>kill</c>, that is if
- <c>exit(<anno>Pid</anno>, kill)</c> is called, an untrappable exit signal
- is sent to <c><anno>Pid</anno></c> which will unconditionally exit with
- exit reason <c>killed</c>.</p>
+ <p>The following behavior applies if <c><anno>Reason</anno></c>
+ is any term, except <c>normal</c> or <c>kill</c>:</p>
+ <list type="bulleted">
+ <item>If <c><anno>Pid</anno></c> is not trapping exits,
+ <c><anno>Pid</anno></c>
+ itself exits with exit reason <c><anno>Reason</anno></c>.
+ </item>
+ <item>If <c><anno>Pid</anno></c> is trapping exits, the exit
+ signal is transformed into a message
+ <c>{'EXIT', From, <anno>Reason</anno>}</c>
+ and delivered to the message queue of <c><anno>Pid</anno></c>.
+ </item>
+ <item><c>From</c> is the process identifier of the process
+ that sent the exit signal. See also
+ <seealso marker="#process_flag/2">process_flag/2</seealso>.
+ </item>
+ </list>
+ <p>If <c><anno>Reason</anno></c> is the atom <c>normal</c>,
+ <c><anno>Pid</anno></c>
+ does not exit. If it is trapping exits, the exit signal is
+ transformed into a message <c>{'EXIT', From, normal}</c>
+ and delivered to its message queue.</p>
+ <p>If <c><anno>Reason</anno></c> is the atom <c>kill</c>,
+ that is, if <c>exit(<anno>Pid</anno>, kill)</c> is called,
+ an untrappable exit signal is sent to <c><anno>Pid</anno></c>,
+ which unconditionally exits with exit reason <c>killed</c>.
+ </p>
</desc>
</func>
+
<func>
<name name="external_size" arity="1"/>
- <fsummary>Calculate the maximum size for a term encoded in the Erlang
- external term format</fsummary>
+ <fsummary>Calculates the maximum size for a term encoded in the Erlang external term format.</fsummary>
<desc>
<p>Calculates, without doing the encoding, the maximum byte size for
a term encoded in the Erlang external term format. The following
condition applies always:</p>
- <p>
<pre>
> <input>Size1 = byte_size(term_to_binary(<anno>Term</anno>)),</input>
> <input>Size2 = erlang:external_size(<anno>Term</anno>),</input>
> <input>true = Size1 =&lt; Size2.</input>
-true
- </pre>
- </p>
- <p>This is equivalent to a call to: <code>erlang:external_size(<anno>Term</anno>, [])
- </code></p>
+true</pre>
+ <p>This is equivalent to a call to:</p>
+<code>erlang:external_size(<anno>Term</anno>, [])</code>
</desc>
</func>
+
<func>
<name name="external_size" arity="2"/>
- <fsummary>Calculate the maximum size for a term encoded in the Erlang
- external term format</fsummary>
+ <fsummary>Calculates the maximum size for a term encoded in the Erlang external term format.</fsummary>
<desc>
<p>Calculates, without doing the encoding, the maximum byte size for
a term encoded in the Erlang external term format. The following
condition applies always:</p>
- <p>
<pre>
> <input>Size1 = byte_size(term_to_binary(<anno>Term</anno>, <anno>Options</anno>)),</input>
> <input>Size2 = erlang:external_size(<anno>Term</anno>, <anno>Options</anno>),</input>
> <input>true = Size1 =&lt; Size2.</input>
-true
- </pre>
- </p>
- <p>The option <c>{minor_version, <anno>Version</anno>}</c> specifies how floats
- are encoded. See
- <seealso marker="#term_to_binary/2">term_to_binary/2</seealso> for
- a more detailed description.
- </p>
+true</pre>
+ <p>Option <c>{minor_version, <anno>Version</anno>}</c> specifies how
+ floats are encoded. For a detailed description, see
+ <seealso marker="#term_to_binary/2">term_to_binary/2</seealso>.</p>
</desc>
</func>
+
<func>
<name name="float" arity="1"/>
- <fsummary>Convert a number to a float</fsummary>
+ <fsummary>Converts a number to a float.</fsummary>
<desc>
- <p>Returns a float by converting <c><anno>Number</anno></c> to a float.</p>
+ <p>Returns a float by converting <c><anno>Number</anno></c> to a float,
+ for example:</p>
<pre>
> <input>float(55).</input>
55.0</pre>
<p>Allowed in guard tests.</p>
<note>
- <p>Note that if used on the top-level in a guard, it will
- test whether the argument is a floating point number; for
- clarity, use
+ <p>If used on the top level in a guard, it tests whether the
+ argument is a floating point number; for clarity, use
<seealso marker="#is_float/1">is_float/1</seealso> instead.</p>
<p>When <c>float/1</c> is used in an expression in a guard,
such as '<c>float(A) == 4.0</c>', it converts a number as
- described above.</p>
+ described earlier.</p>
</note>
</desc>
</func>
+
<func>
<name name="float_to_binary" arity="1"/>
- <fsummary>Text representation of a float</fsummary>
+ <fsummary>Text representation of a float.</fsummary>
<desc>
- <p>The same as <c>float_to_binary(<anno>Float</anno>,[{scientific,20}])</c>.</p>
+ <p>The same as
+ <c>float_to_binary(<anno>Float</anno>,[{scientific,20}])</c>.</p>
</desc>
</func>
+
<func>
<name name="float_to_binary" arity="2"/>
- <fsummary>Text representation of a float formatted using given options</fsummary>
+ <fsummary>Text representation of a float formatted using given options.</fsummary>
<desc>
- <p>Returns a binary which corresponds to the text
+ <p>Returns a binary corresponding to the text
representation of <c><anno>Float</anno></c> using fixed decimal
- point formatting. The <c><anno>Options</anno></c> behave in the same
- way as <seealso marker="#float_to_list/2">float_to_list/2</seealso>.
- </p>
+ point formatting. <c><anno>Options</anno></c> behaves in the same
+ way as <seealso marker="#float_to_list/2">float_to_list/2</seealso>.</p>
+ <p>Examples:</p>
<pre>
> <input>float_to_binary(7.12, [{decimals, 4}]).</input>
&lt;&lt;"7.1200">>
@@ -1259,31 +1331,42 @@ true
&lt;&lt;"7.12">></pre>
</desc>
</func>
+
<func>
<name name="float_to_list" arity="1"/>
- <fsummary>Text representation of a float</fsummary>
+ <fsummary>Text representation of a float.</fsummary>
<desc>
- <p>The same as <c>float_to_list(<anno>Float</anno>,[{scientific,20}])</c>.</p>
+ <p>The same as
+ <c>float_to_list(<anno>Float</anno>,[{scientific,20}])</c>.</p>
</desc>
</func>
+
<func>
<name name="float_to_list" arity="2"/>
- <fsummary>Text representation of a float formatted using given options</fsummary>
- <desc>
- <p>Returns a string which corresponds to the text
- representation of <c>Float</c> using fixed decimal point formatting.
- When <c>decimals</c> option is specified
- the returned value will contain at most <c>Decimals</c> number of
- digits past the decimal point. If the number doesn't fit in the
- internal static buffer of 256 bytes, the function throws <c>badarg</c>.
- When <c>compact</c> option is provided
- the trailing zeros at the end of the list are truncated (this option is
- only meaningful together with the <c>decimals</c> option). When
- <c>scientific</c> option is provided, the float will be formatted using
- scientific notation with <c>Decimals</c> digits of precision. If
- <c>Options</c> is <c>[]</c> the function behaves like
- <c><seealso marker="#float_to_list/1">float_to_list/1</seealso></c>.
- </p>
+ <fsummary>Text representation of a float formatted using given options.</fsummary>
+ <desc>
+ <p>Returns a string corresponding to the text representation
+ of <c>Float</c> using fixed decimal point formatting. The
+ options are as follows:</p>
+ <list type="bulleted">
+ <item>If option <c>decimals</c> is specified, the returned value
+ contains at most <c>Decimals</c> number of digits past the
+ decimal point. If the number does not fit in the internal
+ static buffer of 256 bytes, the function throws <c>badarg</c>.
+ </item>
+ <item>If option <c>compact</c> is provided, the trailing zeros
+ at the end of the list are truncated. This option is only
+ meaningful together with option <c>decimals</c>.
+ </item>
+ <item>If option <c>scientific</c> is provided, the float is
+ formatted using scientific notation with <c>Decimals</c>
+ digits of precision.
+ </item>
+ <item>If <c>Options</c> is <c>[]</c>, the function behaves as
+ <seealso marker="#float_to_list/1">float_to_list/1</seealso>.
+ </item>
+ </list>
+ <p>Examples:</p>
<pre>
> <input>float_to_list(7.12, [{decimals, 4}]).</input>
"7.1200"
@@ -1291,36 +1374,40 @@ true
"7.12"</pre>
</desc>
</func>
+
<func>
<name name="fun_info" arity="1"/>
- <fsummary>Information about a fun</fsummary>
+ <fsummary>Information about a fun.</fsummary>
<desc>
- <p>Returns a list containing information about the fun
- <c><anno>Fun</anno></c>. Each element of the list is a tuple. The order of
- the tuples is not defined, and more tuples may be added in a
+ <p>Returns a list with information about the fun
+ <c><anno>Fun</anno></c>. Each list element is a tuple. The order
+ of the tuples is undefined, and more tuples can be added in a
future release.</p>
<warning>
<p>This BIF is mainly intended for debugging, but it can
- occasionally be useful in library functions that might need
- to verify, for instance, the arity of a fun.</p>
+ sometimes be useful in library functions that need
+ to verify, for example, the arity of a fun.</p>
</warning>
- <p>There are two types of funs with slightly different
- semantics:</p>
- <p>A fun created by <c>fun M:F/A</c> is called an
- <em>external</em> fun. Calling it will always call the
- function <c>F</c> with arity <c>A</c> in the latest code for
- module <c>M</c>. Note that module <c>M</c> does not even need
- to be loaded when the fun <c>fun M:F/A</c> is created.</p>
- <p>All other funs are called <em>local</em>. When a local fun
- is called, the same version of the code that created the fun
- will be called (even if newer version of the module has been
- loaded).</p>
- <p>The following elements will always be present in the list
+ <p>Two types of funs have slightly different semantics:</p>
+ <list type="bulleted">
+ <item>A fun created by <c>fun M:F/A</c> is called an
+ <em>external</em> fun. Calling it will always call the
+ function <c>F</c> with arity <c>A</c> in the latest code for
+ module <c>M</c>. Notice that module <c>M</c> does not even
+ need to be loaded when the fun <c>fun M:F/A</c> is created.
+ </item>
+ <item>All other funs are called <em>local</em>. When a local fun
+ is called, the same version of the code that created the fun
+ is called (even if a newer version of the module has been
+ loaded).
+ </item>
+ </list>
+ <p>The following elements are always present in the list
for both local and external funs:</p>
<taglist>
<tag><c>{type, Type}</c></tag>
<item>
- <p><c>Type</c> is either <c>local</c> or <c>external</c>.</p>
+ <p><c>Type</c> is <c>local</c> or <c>external</c>.</p>
</item>
<tag><c>{module, Module}</c></tag>
<item>
@@ -1335,148 +1422,154 @@ true
<p><c>Name</c> (an atom) is a function name.</p>
<p>If <c>Fun</c> is a local fun, <c>Name</c> is the name
of the local function that implements the fun.
- (This name was generated by the compiler, and is generally
+ (This name was generated by the compiler, and is
only of informational use. As it is a local function, it
- is not possible to call it directly.)
+ cannot be called directly.)
If no code is currently loaded for the fun, <c>[]</c>
- will be returned instead of an atom.</p>
+ is returned instead of an atom.</p>
<p>If <c>Fun</c> is an external fun, <c>Name</c> is the name
of the exported function that the fun refers to.</p>
</item>
<tag><c>{arity, Arity}</c></tag>
<item>
<p><c>Arity</c> is the number of arguments that the fun
- should be called with.</p>
+ is to be called with.</p>
</item>
<tag><c>{env, Env}</c></tag>
<item>
<p><c>Env</c> (a list) is the environment or free variables
- for the fun. (For external funs, the returned list is
- always empty.)</p>
+ for the fun. For external funs, the returned list is
+ always empty.</p>
</item>
</taglist>
- <p>The following elements will only be present in the list if
+ <p>The following elements are only present in the list if
<c>Fun</c> is local:</p>
<taglist>
<tag><c>{pid, Pid}</c></tag>
<item>
- <p><c>Pid</c> is the pid of the process that originally
- created the fun.</p>
+ <p><c>Pid</c> is the process identifier of the process
+ that originally created the fun.</p>
</item>
<tag><c>{index, Index}</c></tag>
<item>
- <p><c>Index</c> (an integer) is an index into the module's
+ <p><c>Index</c> (an integer) is an index into the module
fun table.</p>
</item>
<tag><c>{new_index, Index}</c></tag>
<item>
- <p><c>Index</c> (an integer) is an index into the module's
+ <p><c>Index</c> (an integer) is an index into the module
fun table.</p>
</item>
<tag><c>{new_uniq, Uniq}</c></tag>
<item>
- <p><c>Uniq</c> (a binary) is a unique value for this fun.
- It is calculated from the compiled code for the entire module.</p>
+ <p><c>Uniq</c> (a binary) is a unique value for this fun. It
+ is calculated from the compiled code for the entire module.</p>
</item>
<tag><c>{uniq, Uniq}</c></tag>
<item>
<p><c>Uniq</c> (an integer) is a unique value for this fun.
- Starting in the R15 release, this integer is calculated from
- the compiled code for the entire module. Before R15, this
- integer was based on only the body of the fun.
- </p>
+ As from OTP R15, this integer is calculated from the
+ compiled code for the entire module. Before OTP R15, this
+ integer was based on only the body of the fun.</p>
</item>
</taglist>
</desc>
</func>
+
<func>
<name name="fun_info" arity="2"/>
+ <fsummary>Information about a fun.</fsummary>
<type name="fun_info_item"/>
- <fsummary>Information about a fun</fsummary>
<desc>
<p>Returns information about <c><anno>Fun</anno></c> as specified by
- <c><anno>Item</anno></c>, in the form <c>{<anno>Item</anno>,<anno>Info</anno>}</c>.</p>
+ <c><anno>Item</anno></c>, in the form
+ <c>{<anno>Item</anno>,<anno>Info</anno>}</c>.</p>
<p>For any fun, <c><anno>Item</anno></c> can be any of the atoms
- <c>module</c>, <c>name</c>, <c>arity</c>, <c>env</c>, or <c>type</c>.</p>
- <p>For a local fun, <c><anno>Item</anno></c> can also be any of the atoms
- <c>index</c>, <c>new_index</c>, <c>new_uniq</c>,
+ <c>module</c>, <c>name</c>, <c>arity</c>, <c>env</c>, or
+ <c>type</c>.</p>
+ <p>For a local fun, <c><anno>Item</anno></c> can also be any of the
+ atoms <c>index</c>, <c>new_index</c>, <c>new_uniq</c>,
<c>uniq</c>, and <c>pid</c>. For an external fun, the value
of any of these items is always the atom <c>undefined</c>.</p>
<p>See
<seealso marker="#fun_info/1">erlang:fun_info/1</seealso>.</p>
</desc>
</func>
+
<func>
<name name="fun_to_list" arity="1"/>
- <fsummary>Text representation of a fun</fsummary>
+ <fsummary>Text representation of a fun.</fsummary>
<desc>
- <p>Returns a string which corresponds to the text
+ <p>Returns a string corresponding to the text
representation of <c><anno>Fun</anno></c>.</p>
</desc>
</func>
+
<func>
<name name="function_exported" arity="3"/>
- <fsummary>Check if a function is exported and loaded</fsummary>
+ <fsummary>Checks if a function is exported and loaded.</fsummary>
<desc>
<p>Returns <c>true</c> if the module <c><anno>Module</anno></c> is loaded
and contains an exported function <c><anno>Function</anno>/<anno>Arity</anno></c>,
or if there is a BIF (a built-in function implemented in C)
- with the given name; otherwise returns <c>false</c>.</p>
+ with the given name, otherwise returns <c>false</c>.</p>
<note><p>This function used to return false for built-in
functions before the 18.0 release.</p></note>
</desc>
</func>
+
<func>
<name name="garbage_collect" arity="0"/>
- <fsummary>Force an immediate garbage collection of the calling process</fsummary>
+ <fsummary>Forces an immediate garbage collection of the calling process.</fsummary>
<desc>
- <p>Forces an immediate garbage collection of the currently
- executing process. The function should not be used, unless
- it has been noticed -- or there are good reasons to suspect --
+ <p>Forces an immediate garbage collection of the
+ executing process. The function is not to be used unless
+ it has been noticed (or there are good reasons to suspect)
that the spontaneous garbage collection will occur too late
- or not at all. Improper use may seriously degrade system
- performance.</p>
+ or not at all.</p>
+ <warning>
+ <p>Improper use can seriously degrade system performance.</p>
+ </warning>
</desc>
</func>
+
<func>
<name name="garbage_collect" arity="1"/>
- <fsummary>Garbage collect a process</fsummary>
+ <fsummary>Garbage collects a process.</fsummary>
<desc>
<p>The same as
<seealso marker="#garbage_collect/2"><c>garbage_collect(<anno>Pid</anno>, [])</c></seealso>.</p>
</desc>
</func>
+
<func>
<name name="garbage_collect" arity="2"/>
- <fsummary>Garbage collect a process</fsummary>
+ <fsummary>Garbage collects a process.</fsummary>
<desc>
- <p>Garbage collect the node local process identified by
- <c><anno>Pid</anno></c>.</p>
- <p>Currently available <c><anno>Option</anno></c>s:</p>
+ <p>Garbage collects the node local process identified by
+ <c><anno>Pid</anno></c>.</p>
+ <p>The available <c><anno>Option</anno></c>s are as follows:</p>
<taglist>
<tag><c>{async, RequestId}</c></tag>
- <item>
- The <c>garbage_collect/2</c> function will return
+ <item>The function <c>garbage_collect/2</c> returns
the value <c>async</c> immediately after the request
has been sent. When the request has been processed, the
- process that called this function will be passed a
- message on the form:<br/>
- <c>{garbage_collect, <anno>RequestId</anno>, <anno>GCResult</anno>}</c>.
- </item>
+ process that called this function is passed a message on
+ the form <c>{garbage_collect,
+ <anno>RequestId</anno>, <anno>GCResult</anno>}</c>.
+ </item>
</taglist>
<p>If <c><anno>Pid</anno></c> equals <c>self()</c>, and
no <c>async</c> option has been passed, the garbage
- collection will be performed at once, i.e. the same as
- calling
+ collection is performed at once, that is, the same as calling
<seealso marker="#garbage_collect/0">garbage_collect/0</seealso>.
- In all other cases a request for garbage collection will
- be sent to the process identified by <c><anno>Pid</anno></c>,
+ Otherwise a request for garbage collection
+ is sent to the process identified by <c><anno>Pid</anno></c>,
and will be handled when appropriate. If no <c>async</c>
- option has been passed, the caller will block until
- <c><anno>GCResult</anno></c> is available and can be
- returned.</p>
+ option has been passed, the caller blocks until
+ <c><anno>GCResult</anno></c> is available and can be returned.</p>
<p><c><anno>GCResult</anno></c> informs about the result of
- the garbage collection request:</p>
+ the garbage collection request as follows:</p>
<taglist>
<tag><c>true</c></tag>
<item>
@@ -1485,14 +1578,13 @@ true
</item>
<tag><c>false</c></tag>
<item>
- No garbage collection was performed. This since the
+ No garbage collection was performed, as
the process identified by <c><anno>Pid</anno></c>
terminated before the request could be satisfied.
</item>
</taglist>
- <p>Note that the same caveats as for
- <seealso marker="#garbage_collect/0">garbage_collect/0</seealso>
- apply.</p>
+ <p>Notice that the same caveats apply as for
+ <seealso marker="#garbage_collect/0">garbage_collect/0</seealso>.</p>
<p>Failures:</p>
<taglist>
<tag><c>badarg</c></tag>
@@ -1501,17 +1593,18 @@ true
</item>
<tag><c>badarg</c></tag>
<item>
- If <c><anno>OptionList</anno></c> is not a valid list of options.
+ If <c><anno>OptionList</anno></c> is an invalid list of options.
</item>
</taglist>
</desc>
</func>
+
<func>
<name name="get" arity="0"/>
- <fsummary>Return the process dictionary</fsummary>
+ <fsummary>Returns the process dictionary.</fsummary>
<desc>
<p>Returns the process dictionary as a list of
- <c>{<anno>Key</anno>, <anno>Val</anno>}</c> tuples.</p>
+ <c>{<anno>Key</anno>, <anno>Val</anno>}</c> tuples, for example:</p>
<pre>
> <input>put(key1, merry),</input>
<input>put(key2, lambs),</input>
@@ -1520,13 +1613,15 @@ true
[{key1,merry},{key2,lambs},{key3,{are,playing}}]</pre>
</desc>
</func>
+
<func>
<name name="get" arity="1"/>
- <fsummary>Return a value from the process dictionary</fsummary>
+ <fsummary>Returns a value from the process dictionary.</fsummary>
<desc>
<p>Returns the value <c><anno>Val</anno></c> associated with <c><anno>Key</anno></c> in
the process dictionary, or <c>undefined</c> if <c><anno>Key</anno></c>
does not exist.</p>
+ <p>Example:</p>
<pre>
> <input>put(key1, merry),</input>
<input>put(key2, lambs),</input>
@@ -1535,14 +1630,16 @@ true
{are,playing}</pre>
</desc>
</func>
+
<func>
<name name="get_cookie" arity="0"/>
- <fsummary>Get the magic cookie of the local node</fsummary>
+ <fsummary>Gets the magic cookie of the local node.</fsummary>
<desc>
- <p>Returns the magic cookie of the local node, if the node is
- alive; otherwise the atom <c>nocookie</c>.</p>
+ <p>Returns the magic cookie of the local node if the node is
+ alive, otherwise the atom <c>nocookie</c>.</p>
</desc>
</func>
+
<func>
<name name="get_keys" arity="0"/>
<fsummary>Return a list of all keys from the process dictionary</fsummary>
@@ -1558,10 +1655,10 @@ true
</func>
<func>
<name name="get_keys" arity="1"/>
- <fsummary>Return a list of keys from the process dictionary</fsummary>
+ <fsummary>Returns a list of keys from the process dictionary.</fsummary>
<desc>
- <p>Returns a list of keys which are associated with the value
- <c><anno>Val</anno></c> in the process dictionary.</p>
+ <p>Returns a list of keys that are associated with the value
+ <c><anno>Val</anno></c> in the process dictionary, for example:</p>
<pre>
> <input>put(mary, {1, 2}),</input>
<input>put(had, {1, 2}),</input>
@@ -1573,40 +1670,40 @@ true
[mary,had,a,little,lamb]</pre>
</desc>
</func>
+
<func>
<name name="get_stacktrace" arity="0"/>
- <fsummary>Get the call stack back-trace of the last exception</fsummary>
+ <fsummary>Gets the call stack back-trace of the last exception.</fsummary>
<type name="stack_item"/>
<desc>
- <p>Get the call stack back-trace (<em>stacktrace</em>) of the last
- exception in the calling process as a list of
+ <p>Gets the call stack back-trace (<em>stacktrace</em>) of the
+ last exception in the calling process as a list of
<c>{<anno>Module</anno>,<anno>Function</anno>,<anno>Arity</anno>,<anno>Location</anno>}</c> tuples.
- The <c><anno>Arity</anno></c> field in the first tuple may be the argument
- list of that function call instead of an arity integer,
+ Field <c><anno>Arity</anno></c> in the first tuple can be the
+ argument list of that function call instead of an arity integer,
depending on the exception.</p>
<p>If there has not been any exceptions in a process, the
stacktrace is <c>[]</c>. After a code change for the process,
- the stacktrace may also be reset to [].</p>
+ the stacktrace can also be reset to <c>[]</c>.</p>
<p>The stacktrace is the same data as the <c>catch</c> operator
returns, for example:</p>
<p><c>{'EXIT',{badarg,Stacktrace}} = catch abs(x)</c></p>
- <p><c><anno>Location</anno></c> is a (possibly empty) list of two-tuples that
- may indicate the location in the source code of the function.
- The first element is an atom that describes the type of
- information in the second element. Currently the following
- items may occur:</p>
+ <p><c><anno>Location</anno></c> is a (possibly empty) list
+ of two-tuples that
+ can indicate the location in the source code of the function.
+ The first element is an atom describing the type of
+ information in the second element. The following
+ items can occur:</p>
<taglist>
<tag><c>file</c></tag>
- <item>
- <p>The second element of the tuple is a string (list of
- characters) representing the filename of the source file
- of the function.</p>
+ <item>The second element of the tuple is a string (list of
+ characters) representing the file name of the source file
+ of the function.
</item>
<tag><c>line</c></tag>
- <item>
- <p>The second element of the tuple is the line number
+ <item>The second element of the tuple is the line number
(an integer greater than zero) in the source file
- where the exception occurred or the function was called.</p>
+ where the exception occurred or the function was called.
</item>
</taglist>
<p>See also
@@ -1614,49 +1711,56 @@ true
<seealso marker="#error/2">erlang:error/2</seealso>.</p>
</desc>
</func>
+
<func>
<name name="group_leader" arity="0"/>
- <fsummary>Get the group leader for the calling process</fsummary>
+ <fsummary>Gets the group leader for the calling process.</fsummary>
<desc>
- <p>Returns the pid of the group leader for the process which
- evaluates the function.</p>
+ <p>Returns the process identifier of the group leader for the
+ process evaluating the function.</p>
<p>Every process is a member of some process group and all
- groups have a <em>group leader</em>. All IO from the group
+ groups have a <em>group leader</em>. All I/O from the group
is channeled to the group leader. When a new process is
spawned, it gets the same group leader as the spawning
process. Initially, at system start-up, <c>init</c> is both
its own group leader and the group leader of all processes.</p>
</desc>
</func>
+
<func>
<name name="group_leader" arity="2"/>
- <fsummary>Set the group leader for a process</fsummary>
+ <fsummary>Sets the group leader for a process.</fsummary>
<desc>
- <p>Sets the group leader of <c><anno>Pid</anno></c> to <c><anno>GroupLeader</anno></c>.
- Typically, this is used when a processes started from a
- certain shell should have another group leader than
+ <p>Sets the group leader of <c><anno>Pid</anno></c>
+ to <c><anno>GroupLeader</anno></c>.
+ Typically, this is used when a process started from a
+ certain shell is to have another group leader than
<c>init</c>.</p>
<p>See also
<seealso marker="#group_leader/0">group_leader/0</seealso>.</p>
</desc>
</func>
+
<func>
<name name="halt" arity="0"/>
- <fsummary>Halt the Erlang runtime system and indicate normal exit to the calling environment</fsummary>
+ <fsummary>Halts the Erlang runtime system and indicates normal exit to the calling environment.</fsummary>
<desc>
<p>The same as
<seealso marker="#halt/2"><c>halt(0, [])</c></seealso>.</p>
+ <p>Example:</p>
<pre>
> <input>halt().</input>
os_prompt% </pre>
</desc>
</func>
+
<func>
<name name="halt" arity="1"/>
- <fsummary>Halt the Erlang runtime system</fsummary>
+ <fsummary>Halts the Erlang runtime system.</fsummary>
<desc>
<p>The same as
<seealso marker="#halt/2"><c>halt(<anno>Status</anno>, [])</c></seealso>.</p>
+ <p>Example:</p>
<pre>
> <input>halt(17).</input>
os_prompt% <input>echo $?</input>
@@ -1664,178 +1768,188 @@ os_prompt% <input>echo $?</input>
os_prompt% </pre>
</desc>
</func>
+
<func>
<name name="halt" arity="2"/>
- <fsummary>Halt the Erlang runtime system</fsummary>
+ <fsummary>Halts the Erlang runtime system.</fsummary>
<desc>
<p><c><anno>Status</anno></c> must be a non-negative integer, a string,
or the atom <c>abort</c>.
Halts the Erlang runtime system. Has no return value.
- Depending on <c><anno>Status</anno></c>:
- </p>
+ Depending on <c><anno>Status</anno></c>, the following occurs:</p>
<taglist>
<tag>integer()</tag>
- <item>The runtime system exits with the integer value <c><anno>Status</anno></c>
- as status code to the calling environment (operating system).
+ <item>The runtime system exits with integer value
+ <c><anno>Status</anno></c>
+ as status code to the calling environment (OS).
</item>
<tag>string()</tag>
- <item>An erlang crash dump is produced with <c><anno>Status</anno></c> as slogan,
- and then the runtime system exits with status code <c>1</c>.
+ <item>An Erlang crash dump is produced with <c><anno>Status</anno></c>
+ as slogan. Then the runtime system exits with status code <c>1</c>.
</item>
<tag><c>abort</c></tag>
<item>
The runtime system aborts producing a core dump, if that is
- enabled in the operating system.
+ enabled in the OS.
</item>
</taglist>
- <p>Note that on many platforms, only the status codes 0-255 are
- supported by the operating system.
- </p>
- <p>For integer <c><anno>Status</anno></c> the Erlang runtime system closes all ports
- and allows async threads to finish their operations before exiting.
- To exit without such flushing use
- <c><anno>Option</anno></c> as <c>{flush,false}</c>.
- </p>
- <p>For statuses <c>string()</c> and <c>abort</c> the <c>flush</c>
- option is ignored and flushing is <em>not</em> done.
- </p>
+ <note><p>On many platforms, the OS supports only status
+ codes 0-255.</p></note>
+ <p>For integer <c><anno>Status</anno></c>, the Erlang runtime system
+ closes all ports and allows async threads to finish their
+ operations before exiting. To exit without such flushing, use
+ <c><anno>Option</anno></c> as <c>{flush,false}</c>.</p>
+ <p>For statuses <c>string()</c> and <c>abort</c>, option
+ <c>flush</c> is ignored and flushing is <em>not</em> done.</p>
</desc>
</func>
+
<func>
<name name="hash" arity="2"/>
- <fsummary>Hash function (deprecated)</fsummary>
+ <fsummary>Hash function (deprecated).</fsummary>
<desc>
<p>Returns a hash value for <c><anno>Term</anno></c> within the range
- <c>1..<anno>Range</anno></c>. The allowed range is 1..2^27-1.</p>
+ <c>1..<anno>Range</anno></c>. The maximum range is 1..2^27-1.</p>
<warning>
- <p>This BIF is deprecated as the hash value may differ on
- different architectures. Also the hash values for integer
- terms larger than 2^27 as well as large binaries are very
+ <p>This BIF is deprecated, as the hash value can differ on
+ different architectures. The hash values for integer
+ terms higher than 2^27 and large binaries are
poor. The BIF is retained for backward compatibility
- reasons (it may have been used to hash records into a file),
- but all new code should use one of the BIFs
+ reasons (it can have been used to hash records into a file),
+ but all new code is to use one of the BIFs
<c>erlang:phash/2</c> or <c>erlang:phash2/1,2</c> instead.</p>
</warning>
</desc>
</func>
+
<func>
<name name="hd" arity="1"/>
- <fsummary>Head of a list</fsummary>
+ <fsummary>Head of a list.</fsummary>
<desc>
- <p>Returns the head of <c><anno>List</anno></c>, that is, the first element.</p>
+ <p>Returns the head of <c><anno>List</anno></c>, that is,
+ the first element, for example:</p>
<pre>
> <input>hd([1,2,3,4,5]).</input>
1</pre>
<p>Allowed in guard tests.</p>
- <p>Failure: <c>badarg</c> if <c><anno>List</anno></c> is the empty list [].</p>
+ <p>Failure: <c>badarg</c> if <c><anno>List</anno></c> is the empty
+ list <c>[]</c>.</p>
</desc>
</func>
+
<func>
<name name="hibernate" arity="3"/>
- <fsummary>Hibernate a process until a message is sent to it</fsummary>
+ <fsummary>Hibernates a process until a message is sent to it.</fsummary>
<desc>
<p>Puts the calling process into a wait state where its memory
- allocation has been reduced as much as possible, which is
+ allocation has been reduced as much as possible. This is
useful if the process does not expect to receive any messages
- in the near future.</p>
- <p>The process will be awaken when a message is sent to it, and
- control will resume in <c><anno>Module</anno>:<anno>Function</anno></c> with
- the arguments given by <c><anno>Args</anno></c> with the call stack
- emptied, meaning that the process will terminate when that
- function returns. Thus <c>erlang:hibernate/3</c> will never
- return to its caller.</p>
+ soon.</p>
+ <p>The process is awaken when a message is sent to it, and control
+ resumes in <c><anno>Module</anno>:<anno>Function</anno></c> with
+ the arguments given by <c><anno>Args</anno></c> with the call
+ stack emptied, meaning that the process terminates when that
+ function returns. Thus <c>erlang:hibernate/3</c> never
+ returns to its caller.</p>
<p>If the process has any message in its message queue,
- the process will be awaken immediately in the same way as
- described above.</p>
+ the process is awakened immediately in the same way as
+ described earlier.</p>
<p>In more technical terms, what <c>erlang:hibernate/3</c> does
- is the following. It discards the call stack for the process.
- Then it garbage collects the process. After the garbage
- collection, all live data is in one continuous heap. The heap
+ is the following. It discards the call stack for the process,
+ and then garbage collects the process. After this,
+ all live data is in one continuous heap. The heap
is then shrunken to the exact same size as the live data
- which it holds (even if that size is less than the minimum
+ that it holds (even if that size is less than the minimum
heap size for the process).</p>
<p>If the size of the live data in the process is less than
the minimum heap size, the first garbage collection occurring
- after the process has been awaken will ensure that the heap
+ after the process is awakened ensures that the heap
size is changed to a size not smaller than the minimum heap
size.</p>
- <p>Note that emptying the call stack means that any surrounding
- <c>catch</c> is removed and has to be re-inserted after
+ <p>Notice that emptying the call stack means that any surrounding
+ <c>catch</c> is removed and must be reinserted after
hibernation. One effect of this is that processes started
using <c>proc_lib</c> (also indirectly, such as
- <c>gen_server</c> processes), should use
+ <c>gen_server</c> processes), are to use
<seealso marker="stdlib:proc_lib#hibernate/3">proc_lib:hibernate/3</seealso>
- instead to ensure that the exception handler continues to work
+ instead, to ensure that the exception handler continues to work
when the process wakes up.</p>
</desc>
</func>
<func>
<name name="insert_element" arity="3"/>
- <fsummary>Insert an element at index in a tuple</fsummary>
+ <fsummary>Inserts an element at index in a tuple.</fsummary>
<type_desc variable="Index">1..tuple_size(<anno>Tuple1</anno>) + 1</type_desc>
<desc>
- <p>
- Returns a new tuple with element <c><anno>Term</anno></c> insert at position
- <c><anno>Index</anno></c> in tuple <c><anno>Tuple1</anno></c>.
- All elements from position <c><anno>Index</anno></c> and upwards are subsequently
- pushed one step higher in the new tuple <c><anno>Tuple2</anno></c>.
- </p>
+ <p>Returns a new tuple with element <c><anno>Term</anno></c>
+ inserted at position
+ <c><anno>Index</anno></c> in tuple <c><anno>Tuple1</anno></c>.
+ All elements from position <c><anno>Index</anno></c> and upwards are
+ pushed one step higher in the new tuple <c><anno>Tuple2</anno></c>.</p>
+ <p>Example:</p>
<pre>
> <input>erlang:insert_element(2, {one, two, three}, new).</input>
{one,new,two,three}</pre>
</desc>
</func>
+
<func>
<name name="integer_to_binary" arity="1"/>
- <fsummary>Text representation of an integer</fsummary>
+ <fsummary>Text representation of an integer.</fsummary>
<desc>
- <p>Returns a binary which corresponds to the text
- representation of <c><anno>Integer</anno></c>.</p>
+ <p>Returns a binary corresponding to the text
+ representation of <c><anno>Integer</anno></c>, for example:</p>
<pre>
> <input>integer_to_binary(77).</input>
&lt;&lt;"77">></pre>
</desc>
</func>
+
<func>
<name name="integer_to_binary" arity="2"/>
- <fsummary>Text representation of an integer</fsummary>
+ <fsummary>Text representation of an integer.</fsummary>
<desc>
- <p>Returns a binary which corresponds to the text
- representation of <c><anno>Integer</anno></c> in base <c><anno>Base</anno></c>.</p>
+ <p>Returns a binary corresponding to the text
+ representation of <c><anno>Integer</anno></c> in base
+ <c><anno>Base</anno></c>, for example:</p>
<pre>
> <input>integer_to_binary(1023, 16).</input>
&lt;&lt;"3FF">></pre>
</desc>
</func>
+
<func>
<name name="integer_to_list" arity="1"/>
- <fsummary>Text representation of an integer</fsummary>
+ <fsummary>Text representation of an integer.</fsummary>
<desc>
- <p>Returns a string which corresponds to the text
- representation of <c><anno>Integer</anno></c>.</p>
+ <p>Returns a string corresponding to the text
+ representation of <c><anno>Integer</anno></c>, for example:</p>
<pre>
> <input>integer_to_list(77).</input>
"77"</pre>
</desc>
</func>
+
<func>
<name name="integer_to_list" arity="2"/>
- <fsummary>Text representation of an integer</fsummary>
+ <fsummary>Text representation of an integer.</fsummary>
<desc>
- <p>Returns a string which corresponds to the text
- representation of <c><anno>Integer</anno></c> in base <c><anno>Base</anno></c>.</p>
+ <p>Returns a string corresponding to the text
+ representation of <c><anno>Integer</anno></c> in base
+ <c><anno>Base</anno></c>, for example:</p>
<pre>
> <input>integer_to_list(1023, 16).</input>
"3FF"</pre>
</desc>
</func>
+
<func>
<name name="iolist_to_binary" arity="1"/>
- <fsummary>Convert an iolist to a binary</fsummary>
+ <fsummary>Converts an iolist to a binary.</fsummary>
<desc>
- <p>Returns a binary which is made from the integers and
- binaries in <c><anno>IoListOrBinary</anno></c>.</p>
+ <p>Returns a binary that is made from the integers and
+ binaries in <c><anno>IoListOrBinary</anno></c>, for example:</p>
<pre>
> <input>Bin1 = &lt;&lt;1,2,3&gt;&gt;.</input>
&lt;&lt;1,2,3&gt;&gt;
@@ -1847,278 +1961,311 @@ os_prompt% </pre>
&lt;&lt;1,2,3,1,2,3,4,5,4,6&gt;&gt;</pre>
</desc>
</func>
+
<func>
<name name="iolist_size" arity="1"/>
- <fsummary>Size of an iolist</fsummary>
+ <fsummary>Size of an iolist.</fsummary>
<desc>
- <p>Returns an integer which is the size in bytes
- of the binary that would be the result of
- <c>iolist_to_binary(<anno>Item</anno>)</c>.</p>
+ <p>Returns an integer that is the size in bytes
+ of the binary that would be the result of
+ <c>iolist_to_binary(<anno>Item</anno>)</c>, for example:</p>
<pre>
> <input>iolist_size([1,2|&lt;&lt;3,4>>]).</input>
4</pre>
</desc>
</func>
+
<func>
<name name="is_alive" arity="0"/>
- <fsummary>Check whether the local node is alive</fsummary>
+ <fsummary>Checks whether the local node is alive.</fsummary>
<desc>
- <p>Returns <c>true</c> if the local node is alive; that is, if
- the node can be part of a distributed system. Otherwise, it
- returns <c>false</c>.</p>
+ <p>Returns <c>true</c> if the local node is alive (that is, if
+ the node can be part of a distributed system), otherwise
+ <c>false</c>.</p>
</desc>
</func>
+
<func>
<name name="is_atom" arity="1"/>
- <fsummary>Check whether a term is an atom</fsummary>
+ <fsummary>Checks whether a term is an atom.</fsummary>
<desc>
- <p>Returns <c>true</c> if <c><anno>Term</anno></c> is an atom;
- otherwise returns <c>false</c>.</p>
+ <p>Returns <c>true</c> if <c><anno>Term</anno></c> is an atom,
+ otherwise <c>false</c>.</p>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="is_binary" arity="1"/>
- <fsummary>Check whether a term is a binary</fsummary>
+ <fsummary>Checks whether a term is a binary.</fsummary>
<desc>
- <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a binary;
- otherwise returns <c>false</c>.</p>
-
+ <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a binary,
+ otherwise <c>false</c>.</p>
<p>A binary always contains a complete number of bytes.</p>
-
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="is_bitstring" arity="1"/>
- <fsummary>Check whether a term is a bitstring</fsummary>
+ <fsummary>Checks whether a term is a bitstring.</fsummary>
<desc>
- <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a bitstring (including a binary);
- otherwise returns <c>false</c>.</p>
-
+ <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a
+ bitstring (including a binary), otherwise <c>false</c>.</p>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="is_boolean" arity="1"/>
- <fsummary>Check whether a term is a boolean</fsummary>
+ <fsummary>Checks whether a term is a boolean.</fsummary>
<desc>
- <p>Returns <c>true</c> if <c><anno>Term</anno></c> is
- either the atom <c>true</c> or the atom <c>false</c>
- (i.e. a boolean); otherwise returns <c>false</c>.</p>
+ <p>Returns <c>true</c> if <c><anno>Term</anno></c> is the
+ atom <c>true</c> or the atom <c>false</c> (that is, a boolean).
+ Otherwise returns <c>false</c>.</p>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="is_builtin" arity="3"/>
- <fsummary>Check if a function is a BIF implemented in C</fsummary>
+ <fsummary>Checks if a function is a BIF implemented in C.</fsummary>
<desc>
- <p>Returns <c>true</c> if <c><anno>Module</anno>:<anno>Function</anno>/<anno>Arity</anno></c> is
- a BIF implemented in C; otherwise returns <c>false</c>.
- This BIF is useful for builders of cross reference tools.</p>
+ <p>This BIF is useful for builders of cross-reference tools.</p>
+ <p>Returns <c>true</c> if
+ <c><anno>Module</anno>:<anno>Function</anno>/<anno>Arity</anno></c>
+ is a BIF implemented in C, otherwise <c>false</c>.</p>
</desc>
</func>
+
<func>
<name name="is_float" arity="1"/>
- <fsummary>Check whether a term is a float</fsummary>
+ <fsummary>Checks whether a term is a float.</fsummary>
<desc>
<p>Returns <c>true</c> if <c><anno>Term</anno></c> is a floating point
- number; otherwise returns <c>false</c>.</p>
+ number, otherwise <c>false</c>.</p>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="is_function" arity="1"/>
- <fsummary>Check whether a term is a fun</fsummary>
+ <fsummary>Checks whether a term is a fun.</fsummary>
<desc>
- <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a fun; otherwise
- returns <c>false</c>.</p>
+ <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a fun, otherwise
+ <c>false</c>.</p>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="is_function" arity="2"/>
- <fsummary>Check whether a term is a fun with a given arity</fsummary>
+ <fsummary>Checks whether a term is a fun with a given arity.</fsummary>
<desc>
<p>Returns <c>true</c> if <c><anno>Term</anno></c> is a fun that can be
- applied with <c><anno>Arity</anno></c> number of arguments; otherwise
- returns <c>false</c>.</p>
+ applied with <c><anno>Arity</anno></c> number of arguments, otherwise
+ <c>false</c>.</p>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="is_integer" arity="1"/>
- <fsummary>Check whether a term is an integer</fsummary>
+ <fsummary>Checks whether a term is an integer.</fsummary>
<desc>
- <p>Returns <c>true</c> if <c><anno>Term</anno></c> is an integer;
- otherwise returns <c>false</c>.</p>
+ <p>Returns <c>true</c> if <c><anno>Term</anno></c> is an integer,
+ otherwise <c>false</c>.</p>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="is_list" arity="1"/>
- <fsummary>Check whether a term is a list</fsummary>
+ <fsummary>Checks whether a term is a list.</fsummary>
<desc>
<p>Returns <c>true</c> if <c><anno>Term</anno></c> is a list with
- zero or more elements; otherwise returns <c>false</c>.</p>
+ zero or more elements, otherwise <c>false</c>.</p>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="is_map" arity="1"/>
- <fsummary>Check whether a term is a map</fsummary>
+ <fsummary>Checks whether a term is a map.</fsummary>
<desc>
- <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a map;
- otherwise returns <c>false</c>.</p>
+ <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a map,
+ otherwise <c>false</c>.</p>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="is_number" arity="1"/>
- <fsummary>Check whether a term is a number</fsummary>
+ <fsummary>Checks whether a term is a number.</fsummary>
<desc>
- <p>Returns <c>true</c> if <c><anno>Term</anno></c> is either an integer or a
- floating point number; otherwise returns <c>false</c>.</p>
+ <p>Returns <c>true</c> if <c><anno>Term</anno></c> is an integer or a
+ floating point number. Otherwise returns <c>false</c>.</p>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="is_pid" arity="1"/>
- <fsummary>Check whether a term is a pid</fsummary>
+ <fsummary>Checks whether a term is a process identifier.</fsummary>
<desc>
- <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a pid (process
- identifier); otherwise returns <c>false</c>.</p>
+ <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a process
+ identifier, otherwise <c>false</c>.</p>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="is_port" arity="1"/>
- <fsummary>Check whether a term is a port</fsummary>
+ <fsummary>Checks whether a term is a port.</fsummary>
<desc>
- <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a port identifier;
- otherwise returns <c>false</c>.</p>
+ <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a port identifier,
+ otherwise <c>false</c>.</p>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="is_process_alive" arity="1"/>
- <fsummary>Check whether a process is alive</fsummary>
+ <fsummary>Checks whether a process is alive.</fsummary>
<desc>
- <p>
- <c><anno>Pid</anno></c> must refer to a process at the local node.
- Returns <c>true</c> if the process exists and is alive, that
- is, is not exiting and has not exited. Otherwise, returns
+ <p><c><anno>Pid</anno></c> must refer to a process at the local node.</p>
+ <p>Returns <c>true</c> if the process exists and is alive, that
+ is, is not exiting and has not exited. Otherwise returns
<c>false</c>.
</p>
</desc>
</func>
+
<func>
<name name="is_record" arity="2"/>
- <fsummary>Check whether a term appears to be a record</fsummary>
+ <fsummary>Checks whether a term appears to be a record.</fsummary>
<desc>
- <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a tuple and its first
- element is <c><anno>RecordTag</anno></c>. Otherwise, returns <c>false</c>.</p>
+ <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a tuple and its
+ first element is <c><anno>RecordTag</anno></c>.
+ Otherwise returns <c>false</c>.</p>
<note>
<p>Normally the compiler treats calls to <c>is_record/2</c>
- specially. It emits code to verify that <c><anno>Term</anno></c> is a
- tuple, that its first element is <c><anno>RecordTag</anno></c>, and that
- the size is correct. However, if the <c><anno>RecordTag</anno></c> is
- not a literal atom, the <c>is_record/2</c> BIF will be
- called instead and the size of the tuple will not be
- verified.</p>
+ specially. It emits code to verify that <c><anno>Term</anno></c>
+ is a tuple, that its first element is
+ <c><anno>RecordTag</anno></c>, and that the
+ size is correct. However, if <c><anno>RecordTag</anno></c> is
+ not a literal atom, the BIF <c>is_record/2</c> is called
+ instead and the size of the tuple is not verified.</p>
</note>
- <p>Allowed in guard tests, if <c><anno>RecordTag</anno></c> is a literal
- atom.</p>
+ <p>Allowed in guard tests, if <c><anno>RecordTag</anno></c> is
+ a literal atom.</p>
</desc>
</func>
+
<func>
<name name="is_record" arity="3"/>
- <fsummary>Check whether a term appears to be a record</fsummary>
- <desc>
- <p><c><anno>RecordTag</anno></c> must be an atom. Returns <c>true</c> if
- <c><anno>Term</anno></c> is a tuple, its first element is <c><anno>RecordTag</anno></c>,
- and its size is <c><anno>Size</anno></c>. Otherwise, returns <c>false</c>.</p>
- <p>Allowed in guard tests, provided that <c><anno>RecordTag</anno></c> is
+ <fsummary>Checks whether a term appears to be a record.</fsummary>
+ <desc>
+ <p><c><anno>RecordTag</anno></c> must be an atom.</p>
+ <p>Returns <c>true</c> if
+ <c><anno>Term</anno></c> is a tuple,
+ its first element is <c><anno>RecordTag</anno></c>,
+ and its size is <c><anno>Size</anno></c>.
+ Otherwise returns <c>false</c>.</p>
+ <p>Allowed in guard tests if <c><anno>RecordTag</anno></c> is
a literal atom and <c>Size</c> is a literal integer.</p>
<note>
- <p>This BIF is documented for completeness. In most cases
- <c>is_record/2</c> should be used.</p>
+ <p>This BIF is documented for completeness. Usually
+ <c>is_record/2</c> is to be used.</p>
</note>
</desc>
</func>
+
<func>
<name name="is_reference" arity="1"/>
- <fsummary>Check whether a term is a reference</fsummary>
+ <fsummary>Checks whether a term is a reference.</fsummary>
<desc>
- <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a reference;
- otherwise returns <c>false</c>.</p>
+ <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a reference,
+ otherwise <c>false</c>.</p>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="is_tuple" arity="1"/>
- <fsummary>Check whether a term is a tuple</fsummary>
+ <fsummary>Checks whether a term is a tuple.</fsummary>
<desc>
- <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a tuple;
- otherwise returns <c>false</c>.</p>
+ <p>Returns <c>true</c> if <c><anno>Term</anno></c> is a tuple,
+ otherwise <c>false</c>.</p>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="length" arity="1"/>
- <fsummary>Length of a list</fsummary>
+ <fsummary>Length of a list.</fsummary>
<desc>
- <p>Returns the length of <c><anno>List</anno></c>.</p>
+ <p>Returns the length of <c><anno>List</anno></c>, for example:</p>
<pre>
> <input>length([1,2,3,4,5,6,7,8,9]).</input>
9</pre>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="link" arity="1"/>
- <fsummary>Create a link to another process (or port)</fsummary>
+ <fsummary>Creates a link to another process (or port).</fsummary>
<desc>
<p>Creates a link between the calling process and another
- process (or port) <c><anno>PidOrPort</anno></c>, if there is not such a link
+ process (or port) <c><anno>PidOrPort</anno></c>, if there is
+ not such a link
already. If a process attempts to create a link to itself,
nothing is done. Returns <c>true</c>.</p>
- <p>If <c><anno>PidOrPort</anno></c> does not exist, the behavior of the BIF depends
- on if the calling process is trapping exits or not (see
+ <p>If <c><anno>PidOrPort</anno></c> does not exist, the behavior
+ of the BIF
+ depends on if the calling process is trapping exits or not (see
<seealso marker="#process_flag/2">process_flag/2</seealso>):</p>
<list type="bulleted">
<item>If the calling process is not trapping exits, and
- checking <c><anno>PidOrPort</anno></c> is cheap -- that is, if <c><anno>PidOrPort</anno></c> is
- local -- <c>link/1</c> fails with reason <c>noproc</c>.</item>
+ checking <c><anno>PidOrPort</anno></c> is cheap
+ (that is, if <c><anno>PidOrPort</anno></c>
+ is local), <c>link/1</c> fails with reason <c>noproc</c>.</item>
<item>Otherwise, if the calling process is trapping exits,
- and/or <c><anno>PidOrPort</anno></c> is remote, <c>link/1</c> returns
- <c>true</c>, but an exit signal with reason <c>noproc</c>
+ and/or <c><anno>PidOrPort</anno></c> is remote, <c>link/1</c>
+ returns <c>true</c>, but an exit signal with reason <c>noproc</c>
is sent to the calling process.</item>
</list>
</desc>
</func>
+
<func>
<name name="list_to_atom" arity="1"/>
- <fsummary>Convert from text representation to an atom</fsummary>
- <desc>
- <p>Returns the atom whose text representation is <c><anno>String</anno></c>.</p>
- <p><c><anno>String</anno></c> may only contain ISO-latin-1
- characters (i.e. numbers below 256) as the current
- implementation does not allow unicode characters >= 256 in
- atoms. For more information on Unicode support in atoms
- see <seealso marker="erl_ext_dist#utf8_atoms">note on UTF-8 encoded atoms</seealso>
- in the chapter about the external term format in the ERTS User's Guide.</p>
+ <fsummary>Converts from text representation to an atom.</fsummary>
+ <desc>
+ <p>Returns the atom whose text representation is
+ <c><anno>String</anno></c>.</p>
+ <p><c><anno>String</anno></c> can only contain ISO-latin-1
+ characters (that is,
+ numbers less than 256) as the implementation does not
+ allow unicode characters equal to or above 256 in atoms.
+ For more information on Unicode support in atoms, see
+ <seealso marker="erl_ext_dist#utf8_atoms">note on UTF-8
+ encoded atoms</seealso>
+ in Section "External Term Format" in the User's Guide.</p>
+ <p>Example:</p>
<pre>
> <input>list_to_atom("Erlang").</input>
'Erlang'</pre>
</desc>
</func>
+
<func>
<name name="list_to_binary" arity="1"/>
- <fsummary>Convert a list to a binary</fsummary>
+ <fsummary>Converts a list to a binary.</fsummary>
<desc>
- <p>Returns a binary which is made from the integers and
- binaries in <c><anno>IoList</anno></c>.</p>
+ <p>Returns a binary that is made from the integers and
+ binaries in <c><anno>IoList</anno></c>, for example:</p>
<pre>
> <input>Bin1 = &lt;&lt;1,2,3&gt;&gt;.</input>
&lt;&lt;1,2,3&gt;&gt;
@@ -2130,40 +2277,46 @@ os_prompt% </pre>
&lt;&lt;1,2,3,1,2,3,4,5,4,6&gt;&gt;</pre>
</desc>
</func>
+
<func>
<name name="list_to_bitstring" arity="1"/>
+ <fsummary>Converts a list to a bitstring.</fsummary>
<type name="bitstring_list"/>
- <fsummary>Convert a list to a bitstring</fsummary>
<desc>
- <p>Returns a bitstring which is made from the integers and
- bitstrings in <c><anno>BitstringList</anno></c>. (The last tail in <c><anno>BitstringList</anno></c>
- is allowed to be a bitstring.)</p>
+ <p>Returns a bitstring that is made from the integers and
+ bitstrings in <c><anno>BitstringList</anno></c>. (The last tail in
+ <c><anno>BitstringList</anno></c> is allowed to be a bitstring.)</p>
+ <p>Example:</p>
<pre>
> <input>Bin1 = &lt;&lt;1,2,3&gt;&gt;.</input>
&lt;&lt;1,2,3&gt;&gt;
> <input>Bin2 = &lt;&lt;4,5&gt;&gt;.</input>
&lt;&lt;4,5&gt;&gt;
-> <input>Bin3 = &lt;&lt;6,7:4,&gt;&gt;.</input>
-&lt;&lt;6&gt;&gt;
+> <input>Bin3 = &lt;&lt;6,7:4&gt;&gt;.</input>
+&lt;&lt;6,7:4&gt;&gt;
> <input>list_to_bitstring([Bin1,1,[2,3,Bin2],4|Bin3]).</input>
-&lt;&lt;1,2,3,1,2,3,4,5,4,6,7:46&gt;&gt;</pre>
+&lt;&lt;1,2,3,1,2,3,4,5,4,6,7:4&gt;&gt;</pre>
</desc>
</func>
+
<func>
<name name="list_to_existing_atom" arity="1"/>
- <fsummary>Convert from text representation to an atom</fsummary>
+ <fsummary>Converts from text representation to an atom.</fsummary>
<desc>
- <p>Returns the atom whose text representation is <c><anno>String</anno></c>,
+ <p>Returns the atom whose text representation is
+ <c><anno>String</anno></c>,
but only if there already exists such atom.</p>
<p>Failure: <c>badarg</c> if there does not already exist an atom
whose text representation is <c><anno>String</anno></c>.</p>
</desc>
</func>
+
<func>
<name name="list_to_float" arity="1"/>
- <fsummary>Convert from text representation to a float</fsummary>
+ <fsummary>Converts from text representation to a float.</fsummary>
<desc>
- <p>Returns the float whose text representation is <c><anno>String</anno></c>.</p>
+ <p>Returns the float whose text representation is
+ <c><anno>String</anno></c>, for example:</p>
<pre>
> <input>list_to_float("2.2017764e+0").</input>
2.2017764</pre>
@@ -2171,12 +2324,13 @@ os_prompt% </pre>
representation of a float.</p>
</desc>
</func>
+
<func>
<name name="list_to_integer" arity="1"/>
- <fsummary>Convert from text representation to an integer</fsummary>
+ <fsummary>Converts from text representation to an integer.</fsummary>
<desc>
<p>Returns an integer whose text representation is
- <c><anno>String</anno></c>.</p>
+ <c><anno>String</anno></c>, for example:</p>
<pre>
> <input>list_to_integer("123").</input>
123</pre>
@@ -2184,12 +2338,14 @@ os_prompt% </pre>
representation of an integer.</p>
</desc>
</func>
+
<func>
<name name="list_to_integer" arity="2"/>
- <fsummary>Convert from text representation to an integer</fsummary>
+ <fsummary>Converts from text representation to an integer.</fsummary>
<desc>
<p>Returns an integer whose text representation in base
- <c><anno>Base</anno></c> is <c><anno>String</anno></c>.</p>
+ <c><anno>Base</anno></c> is <c><anno>String</anno></c>,
+ for example:</p>
<pre>
> <input>list_to_integer("3FF", 16).</input>
1023</pre>
@@ -2197,47 +2353,52 @@ os_prompt% </pre>
representation of an integer.</p>
</desc>
</func>
+
<func>
<name name="list_to_pid" arity="1"/>
- <fsummary>Convert from text representation to a pid</fsummary>
+ <fsummary>Converts from text representation to a pid.</fsummary>
<desc>
- <p>Returns a pid whose text representation is <c><anno>String</anno></c>.</p>
- <warning>
- <p>This BIF is intended for debugging and for use in
- the Erlang operating system. It should not be used in
- application programs.</p>
- </warning>
+ <p>Returns a process identifier whose text representation is a
+ <c><anno>String</anno></c>, for example:</p>
<pre>
> <input>list_to_pid("&lt;0.4.1>").</input>
&lt;0.4.1></pre>
<p>Failure: <c>badarg</c> if <c><anno>String</anno></c> contains a bad
- representation of a pid.</p>
+ representation of a process identifier.</p>
+ <warning>
+ <p>This BIF is intended for debugging and is not to be used
+ in application programs.</p>
+ </warning>
</desc>
</func>
+
<func>
<name name="list_to_tuple" arity="1"/>
- <fsummary>Convert a list to a tuple</fsummary>
+ <fsummary>Converts a list to a tuple.</fsummary>
<desc>
- <p>Returns a tuple which corresponds to <c><anno>List</anno></c>. <c><anno>List</anno></c>
- can contain any Erlang terms.</p>
+ <p>Returns a tuple corresponding to <c><anno>List</anno></c>,
+ for example</p>
<pre>
> <input>list_to_tuple([share, ['Ericsson_B', 163]]).</input>
{share, ['Ericsson_B', 163]}</pre>
+ <p><c><anno>List</anno></c> can contain any Erlang terms.</p>
</desc>
</func>
+
<func>
<name name="load_module" arity="2"/>
- <fsummary>Load object code for a module</fsummary>
+ <fsummary>Loads object code for a module.</fsummary>
<desc>
- <p>If <c><anno>Binary</anno></c> contains the object code for the module
- <c><anno>Module</anno></c>, this BIF loads that object code. Also, if
- the code for the module <c><anno>Module</anno></c> already exists, all
+ <p>If <c><anno>Binary</anno></c> contains the object code for module
+ <c><anno>Module</anno></c>, this BIF loads that object code. If
+ the code for module <c><anno>Module</anno></c> already exists, all
export references are replaced so they point to the newly
loaded code. The previously loaded code is kept in the system
- as old code, as there may still be processes which are
- executing that code. It returns either
- <c>{module, <anno>Module</anno>}</c>, or <c>{error, <anno>Reason</anno>}</c> if loading
- fails. <c><anno>Reason</anno></c> is one of the following:</p>
+ as old code, as there can still be processes executing
+ that code.</p>
+ <p>Returns either <c>{module, <anno>Module</anno>}</c>, or
+ <c>{error, <anno>Reason</anno>}</c> if loading fails.
+ <c><anno>Reason</anno></c> is any of the following:</p>
<taglist>
<tag><c>badfile</c></tag>
<item>
@@ -2247,118 +2408,122 @@ os_prompt% </pre>
</item>
<tag><c>not_purged</c></tag>
<item>
- <p><c><anno>Binary</anno></c> contains a module which cannot be loaded
- because old code for this module already exists.</p>
+ <p><c><anno>Binary</anno></c> contains a module that cannot be
+ loaded because old code for this module already exists.</p>
</item>
</taglist>
<warning>
<p>This BIF is intended for the code server (see
- <seealso marker="kernel:code">code(3)</seealso>) and should not be
- used elsewhere.</p>
+ <seealso marker="kernel:code">code(3)</seealso>)
+ and is not to be used elsewhere.</p>
</warning>
</desc>
</func>
+
<func>
<name name="load_nif" arity="2"/>
- <fsummary>Load NIF library</fsummary>
+ <fsummary>Loads NIF library.</fsummary>
<desc>
<note>
- <p>In releases older than OTP R14B, NIFs were an
- experimental feature. Versions of OTP older than R14B might
+ <p>Before OTP R14B, NIFs were an
+ experimental feature. Versions before OTP R14B can
have different and possibly incompatible NIF semantics and
- interfaces. For example, in R13B03 the return value on
- failure was
- <c>{error,Reason,Text}</c>.</p>
+ interfaces. For example, in OTP R13B03 the return value on
+ failure was <c>{error,Reason,Text}</c>.</p>
</note>
<p>Loads and links a dynamic library containing native
- implemented functions (NIFs) for a module. <c><anno>Path</anno></c> is a
- file path to the sharable object/dynamic library file minus
- the OS-dependent file extension (.so for Unix and .dll for
- Windows). See <seealso marker="erl_nif">erl_nif</seealso>
- on how to implement a NIF library.</p>
- <p><c><anno>LoadInfo</anno></c> can be any term. It will be passed on to
+ implemented functions (NIFs) for a module. <c><anno>Path</anno></c>
+ is a file path to the shareable object/dynamic library file minus
+ the OS-dependent file extension (<c>.so</c> for Unix and
+ <c>.dll</c> for Windows. For information on how to
+ implement a NIF library, see
+ <seealso marker="erl_nif">erl_nif</seealso>.</p>
+ <p><c><anno>LoadInfo</anno></c> can be any term. It is passed on to
the library as part of the initialization. A good practice is
to include a module version number to support future code
upgrade scenarios.</p>
<p>The call to <c>load_nif/2</c> must be made
<em>directly</em> from the Erlang code of the module that the
- NIF library belongs to.</p>
- <p>It returns either <c>ok</c>, or <c>{error,{<anno>Reason</anno>,Text}}</c>
- if loading fails. <c><anno>Reason</anno></c> is one of the atoms below,
- while <c><anno>Text</anno></c> is a human readable string that may give
- some more information about the failure.</p>
+ NIF library belongs to. It returns either <c>ok</c>, or
+ <c>{error,{<anno>Reason</anno>,Text}}</c> if loading fails.
+ <c><anno>Reason</anno></c> is one of the following atoms
+ while <c><anno>Text</anno></c> is a human readable string that
+ can give more information about the failure:</p>
<taglist>
<tag><c>load_failed</c></tag>
- <item>
- <p>The OS failed to load the NIF library.</p>
+ <item>The OS failed to load the NIF library.
</item>
<tag><c>bad_lib</c></tag>
- <item>
- <p>The library did not fulfil the requirements as a NIF
- library of the calling module.</p>
+ <item>The library did not fulfill the requirements as a NIF
+ library of the calling module.
</item>
<tag><c>load | reload | upgrade</c></tag>
- <item>
- <p>The corresponding library callback was not successful.</p>
+ <item>The corresponding library callback was unsuccessful.
</item>
<tag><c>old_code</c></tag>
- <item>
- <p>The call to <c>load_nif/2</c> was made from the old
- code of a module that has been upgraded. This is not
- allowed.</p>
+ <item>The call to <c>load_nif/2</c> was made from the old
+ code of a module that has been upgraded; this is not
+ allowed.
</item>
</taglist>
</desc>
</func>
+
<func>
<name name="loaded" arity="0"/>
- <fsummary>List of all loaded modules</fsummary>
+ <fsummary>Lists all loaded modules.</fsummary>
<desc>
- <p>Returns a list of all loaded Erlang modules (current and/or
+ <p>Returns a list of all loaded Erlang modules (current and
old code), including preloaded modules.</p>
<p>See also <seealso marker="kernel:code">code(3)</seealso>.</p>
</desc>
</func>
+
<func>
<name name="localtime" arity="0"/>
- <fsummary>Current local date and time</fsummary>
+ <fsummary>Current local date and time.</fsummary>
<desc>
- <p>Returns the current local date and time
- <c>{{Year, Month, Day}, {Hour, Minute, Second}}</c>.</p>
- <p>The time zone and daylight saving time correction depend
- on the underlying OS.</p>
+ <p>Returns the current local date and time,
+ <c>{{Year, Month, Day}, {Hour, Minute, Second}}</c>,
+ for example:</p>
<pre>
> <input>erlang:localtime().</input>
{{1996,11,6},{14,45,17}}</pre>
+ <p>The time zone and Daylight Saving Time correction depend
+ on the underlying OS.</p>
</desc>
</func>
+
<func>
<name name="localtime_to_universaltime" arity="1"/>
- <fsummary>Convert from local to Universal Time Coordinated (UTC) date and time</fsummary>
+ <fsummary>Converts from local to Universal Time Coordinated (UTC) date and time.</fsummary>
<desc>
<p>Converts local date and time to Universal Time Coordinated
- (UTC), if this is supported by the underlying OS. Otherwise,
- no conversion is done and <c><anno>Localtime</anno></c> is returned.</p>
+ (UTC), if supported by the underlying OS. Otherwise
+ no conversion is done and <c><anno>Localtime</anno></c>
+ is returned.</p>
+ <p>Example:</p>
<pre>
> <input>erlang:localtime_to_universaltime({{1996,11,6},{14,45,17}}).</input>
{{1996,11,6},{13,45,17}}</pre>
- <p>Failure: <c>badarg</c> if <c><anno>Localtime</anno></c> does not denote
- a valid date and time.</p>
+ <p>Failure: <c>badarg</c> if <c><anno>Localtime</anno></c> denotes an
+ invalid date and time.</p>
</desc>
</func>
+
<func>
<name name="localtime_to_universaltime" arity="2"/>
- <fsummary>Convert from local to Universal Time Coordinated (UTC) date and time</fsummary>
+ <fsummary>Converts from local to Universal Time Coordinated (UTC) date and time.</fsummary>
<desc>
<p>Converts local date and time to Universal Time Coordinated
- (UTC) just like <c>erlang:localtime_to_universaltime/1</c>,
- but the caller decides if daylight saving time is active or
- not.</p>
- <p>If <c><anno>IsDst</anno> == true</c> the <c><anno>Localtime</anno></c> is during
- daylight saving time, if <c><anno>IsDst</anno> == false</c> it is not,
- and if <c><anno>IsDst</anno> == undefined</c> the underlying OS may
+ (UTC) as <c>erlang:localtime_to_universaltime/1</c>,
+ but the caller decides if Daylight Saving Time is active.</p>
+ <p>If <c><anno>IsDst</anno> == true</c>, <c><anno>Localtime</anno></c> is
+ during Daylight Saving Time, if <c><anno>IsDst</anno> == false</c> it is
+ not. If <c><anno>IsDst</anno> == undefined</c>, the underlying OS can
guess, which is the same as calling
<c>erlang:localtime_to_universaltime(<anno>Localtime</anno>)</c>.</p>
+ <p>Examples:</p>
<pre>
> <input>erlang:localtime_to_universaltime({{1996,11,6},{14,45,17}}, true).</input>
{{1996,11,6},{12,45,17}}
@@ -2366,15 +2531,16 @@ os_prompt% </pre>
{{1996,11,6},{13,45,17}}
> <input>erlang:localtime_to_universaltime({{1996,11,6},{14,45,17}}, undefined).</input>
{{1996,11,6},{13,45,17}}</pre>
- <p>Failure: <c>badarg</c> if <c><anno>Localtime</anno></c> does not denote
- a valid date and time.</p>
+ <p>Failure: <c>badarg</c> if <c><anno>Localtime</anno></c> denotes an
+ invalid date and time.</p>
</desc>
</func>
+
<func>
<name name="make_ref" arity="0"/>
- <fsummary>Return a unique reference</fsummary>
+ <fsummary>Returns a unique reference.</fsummary>
<desc>
- <p>Return a <seealso marker="doc/efficiency_guide:advanced#unique_references">unique
+ <p>Returns a <seealso marker="doc/efficiency_guide:advanced#unique_references">unique
reference</seealso>. The reference is unique among
connected nodes.</p>
<warning><p>Known issue: When a node is restarted multiple
@@ -2383,200 +2549,209 @@ os_prompt% </pre>
created on an older node with the same node name.</p></warning>
</desc>
</func>
+
<func>
<name name="make_tuple" arity="2"/>
- <fsummary>Create a new tuple of a given arity</fsummary>
+ <fsummary>Creates a new tuple of a given arity.</fsummary>
<desc>
- <p>Returns a new tuple of the given <c><anno>Arity</anno></c>, where all
- elements are <c><anno>InitialValue</anno></c>.</p>
+ <p>Creates a new tuple of the given <c><anno>Arity</anno></c>, where all
+ elements are <c><anno>InitialValue</anno></c>, for example:</p>
<pre>
> <input>erlang:make_tuple(4, []).</input>
{[],[],[],[]}</pre>
</desc>
</func>
+
<func>
<name name="make_tuple" arity="3"/>
- <fsummary>Create a new tuple with given arity and contents</fsummary>
- <desc>
- <p><c>erlang:make_tuple</c> first creates a tuple of size <c><anno>Arity</anno></c>
- where each element has the value <c><anno>DefaultValue</anno></c>. It then fills
- in values from <c><anno>InitList</anno></c>. Each list element in <c><anno>InitList</anno></c>
- must be a two-tuple where the first element is a position in the
- newly created tuple and the second element is any term. If a position
- occurs more than once in the list, the term corresponding to
- last occurrence will be used.</p>
+ <fsummary>Creates a new tuple with given arity and contents.</fsummary>
+ <desc>
+ <p>Creates a tuple of size <c><anno>Arity</anno></c>, where each element
+ has value <c><anno>DefaultValue</anno></c>, and then fills in
+ values from <c><anno>InitList</anno></c>.
+ Each list element in <c><anno>InitList</anno></c>
+ must be a two-tuple, where the first element is a position in the
+ newly created tuple and the second element is any term. If a
+ position occurs more than once in the list, the term corresponding
+ to the last occurrence is used.</p>
+ <p>Example:</p>
<pre>
> <input>erlang:make_tuple(5, [], [{2,ignored},{5,zz},{2,aa}]).</input>
{{[],aa,[],[],zz}</pre>
</desc>
</func>
+
<func>
<name name="map_size" arity="1"/>
- <fsummary>Return the size of a map</fsummary>
+ <fsummary>Returns the size of a map.</fsummary>
<desc>
- <p>Returns an integer which is the number of key-value pairs in <c><anno>Map</anno></c>.</p>
+ <p>Returns an integer, which is the number of key-value pairs
+ in <c><anno>Map</anno></c>, for example:</p>
<pre>
> <input>map_size(#{a=>1, b=>2, c=>3}).</input>
3</pre>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="max" arity="2"/>
- <fsummary>Return the largest of two term</fsummary>
+ <fsummary>Returns the largest of two terms.</fsummary>
<desc>
- <p>Return the largest of <c><anno>Term1</anno></c> and <c><anno>Term2</anno></c>;
- if the terms compare equal, <c><anno>Term1</anno></c> will be returned.</p>
+ <p>Returns the largest of <c><anno>Term1</anno></c> and
+ <c><anno>Term2</anno></c>.
+ If the terms are equal, <c><anno>Term1</anno></c> is returned.</p>
</desc>
</func>
+
<func>
<name name="md5" arity="1"/>
- <fsummary>Compute an MD5 message digest</fsummary>
+ <fsummary>Computes an MD5 message digest.</fsummary>
<desc>
- <p>Computes an <c>MD5</c> message digest from <c><anno>Data</anno></c>, where
- the length of the digest is 128 bits (16 bytes). <c><anno>Data</anno></c>
+ <p>Computes an MD5 message digest from <c><anno>Data</anno></c>, where
+ the length of the digest is 128 bits (16 bytes).
+ <c><anno>Data</anno></c>
is a binary or a list of small integers and binaries.</p>
- <p>See The MD5 Message Digest Algorithm (RFC 1321) for more
- information about MD5.</p>
- <warning><p>The MD5 Message Digest Algorithm is <em>not</em> considered
- safe for code-signing or software integrity purposes.</p></warning>
+ <p>For more information about MD5, see RFC 1321 - The
+ MD5 Message-Digest Algorithm.</p>
+ <warning><p>The MD5 Message-Digest Algorithm is <em>not</em> considered
+ safe for code-signing or software-integrity purposes.</p></warning>
</desc>
</func>
+
<func>
<name name="md5_final" arity="1"/>
- <fsummary>Finish the update of an MD5 context and return the computed MD5 message digest</fsummary>
+ <fsummary>Finishes the update of an MD5 context and returns the computed MD5 message digest.</fsummary>
<desc>
<p>Finishes the update of an MD5 <c><anno>Context</anno></c> and returns
the computed <c>MD5</c> message digest.</p>
</desc>
</func>
+
<func>
<name name="md5_init" arity="0"/>
- <fsummary>Create an MD5 context</fsummary>
+ <fsummary>Creates an MD5 context.</fsummary>
<desc>
<p>Creates an MD5 context, to be used in subsequent calls to
<c>md5_update/2</c>.</p>
</desc>
</func>
+
<func>
<name name="md5_update" arity="2"/>
- <fsummary>Update an MD5 context with data, and return a new context</fsummary>
+ <fsummary>Updates an MD5 context with data and returns a new context.</fsummary>
<desc>
- <p>Updates an MD5 <c><anno>Context</anno></c> with <c><anno>Data</anno></c>, and returns
- a <c><anno>NewContext</anno></c>.</p>
+ <p>Updates an MD5 <c><anno>Context</anno></c> with
+ <c><anno>Data</anno></c> and returns a
+ <c><anno>NewContext</anno></c>.</p>
</desc>
</func>
+
<func>
<name name="memory" arity="0"/>
+ <fsummary>Information about dynamically allocated memory.</fsummary>
<type name="memory_type"/>
- <fsummary>Information about dynamically allocated memory</fsummary>
- <desc>
- <p>Returns a list containing information about memory
- dynamically allocated by the Erlang emulator. Each element of
- the list is a tuple <c>{Type, Size}</c>. The first element
- <c><anno>Type</anno></c>is an atom describing memory type. The second
- element <c><anno>Size</anno></c>is memory size in bytes. A description of
- each memory type follows:</p>
+ <desc>
+ <p>Returns a list with information about memory
+ dynamically allocated by the Erlang emulator. Each list
+ element is a tuple <c>{Type, Size}</c>. The first element
+ <c><anno>Type</anno></c> is an atom describing memory type. The second
+ element <c><anno>Size</anno></c> is the memory size in bytes.</p>
+ <p>The memory types are as follows:</p>
<taglist>
<tag><c>total</c></tag>
<item>
- <p>The total amount of memory currently allocated, which is
- the same as the sum of memory size for <c>processes</c>
+ <p>The total amount of memory currently allocated. This is
+ the same as the sum of the memory size for <c>processes</c>
and <c>system</c>.</p>
</item>
<tag><c>processes</c></tag>
<item>
- <p>The total amount of memory currently allocated by
+ <p>The total amount of memory currently allocated for
the Erlang processes.</p>
</item>
<tag><c>processes_used</c></tag>
<item>
<p>The total amount of memory currently used by the Erlang
- processes.</p>
- <p>This memory is part of the memory presented as
+ processes. This is part of the memory presented as
<c>processes</c> memory.</p>
</item>
<tag><c>system</c></tag>
<item>
- <p>The total amount of memory currently allocated by
+ <p>The total amount of memory currently allocated for
the emulator that is not directly related to any Erlang
- process.</p>
- <p>Memory presented as <c>processes</c> is not included in
- this memory.</p>
+ process. Memory presented as <c>processes</c> is not
+ included in this memory.</p>
</item>
<tag><c>atom</c></tag>
<item>
- <p>The total amount of memory currently allocated for atoms.</p>
- <p>This memory is part of the memory presented as
+ <p>The total amount of memory currently allocated for atoms.
+ This memory is part of the memory presented as
<c>system</c> memory.</p>
</item>
<tag><c>atom_used</c></tag>
<item>
- <p>The total amount of memory currently used for atoms.</p>
- <p>This memory is part of the memory presented as
+ <p>The total amount of memory currently used for atoms.
+ This memory is part of the memory presented as
<c>atom</c> memory.</p>
</item>
<tag><c>binary</c></tag>
<item>
<p>The total amount of memory currently allocated for
- binaries.</p>
- <p>This memory is part of the memory presented as
- <c>system</c> memory.</p>
+ binaries. This memory is part of the memory presented
+ as <c>system</c> memory.</p>
</item>
<tag><c>code</c></tag>
<item>
<p>The total amount of memory currently allocated for
- Erlang code.</p>
- <p>This memory is part of the memory presented as
- <c>system</c> memory.</p>
+ Erlang code. This memory is part of the memory presented
+ as <c>system</c> memory.</p>
</item>
<tag><c>ets</c></tag>
<item>
<p>The total amount of memory currently allocated for ets
- tables.</p>
- <p>This memory is part of the memory presented as
+ tables. This memory is part of the memory presented as
<c>system</c> memory.</p>
</item>
<tag><c>low</c></tag>
<item>
- <p>Only on 64-bit halfword emulator.</p>
- <p>The total amount of memory allocated in low memory areas
- that are restricted to less than 4 Gb even though
- the system may have more physical memory.</p>
- <p>May be removed in future releases of halfword emulator.</p>
+ <p>Only on 64-bit halfword emulator.
+ The total amount of memory allocated in low memory areas
+ that are restricted to less than 4 GB, although
+ the system can have more memory.</p>
+ <p>Can be removed in a future release of the halfword
+ emulator.</p>
</item>
<tag><c>maximum</c></tag>
<item>
<p>The maximum total amount of memory allocated since
- the emulator was started.</p>
- <p>This tuple is only present when the emulator is run with
- instrumentation.</p>
+ the emulator was started. This tuple is only present
+ when the emulator is run with instrumentation.</p>
<p>For information on how to run the emulator with
- instrumentation see
+ instrumentation, see
<seealso marker="tools:instrument">instrument(3)</seealso>
and/or <seealso marker="erts:erl">erl(1)</seealso>.</p>
</item>
</taglist>
<note>
<p>The <c>system</c> value is not complete. Some allocated
- memory that should be part of the <c>system</c> value are
- not.</p>
+ memory that is to be part of this value is not.</p>
<p>When the emulator is run with instrumentation,
the <c>system</c> value is more accurate, but memory
- directly allocated by <c>malloc</c> (and friends) are still
+ directly allocated for <c>malloc</c> (and friends) is still
not part of the <c>system</c> value. Direct calls to
- <c>malloc</c> are only done from OS specific runtime
- libraries and perhaps from user implemented Erlang drivers
+ <c>malloc</c> are only done from OS-specific runtime
+ libraries and perhaps from user-implemented Erlang drivers
that do not use the memory allocation functions in
the driver interface.</p>
- <p>Since the <c>total</c> value is the sum of <c>processes</c>
- and <c>system</c> the error in <c>system</c> will propagate
+ <p>As the <c>total</c> value is the sum of <c>processes</c>
+ and <c>system</c>, the error in <c>system</c> propagates
to the <c>total</c> value.</p>
<p>The different amounts of memory that are summed are
- <em>not</em> gathered atomically which also introduce
+ <em>not</em> gathered atomically, which introduces
an error in the result.</p>
</note>
- <p>The different values has the following relation to each
+ <p>The different values have the following relation to each
other. Values beginning with an uppercase letter is not part
of the result.</p>
<code type="none">
@@ -2584,69 +2759,62 @@ os_prompt% </pre>
processes = processes_used + ProcessesNotUsed
system = atom + binary + code + ets + OtherSystem
atom = atom_used + AtomNotUsed
-
RealTotal = processes + RealSystem
RealSystem = system + MissedSystem</code>
- <p>More tuples in the returned list may be added in the future.</p>
+ <p>More tuples in the returned list can be added in a
+ future release.</p>
<note>
<p>The <c>total</c> value is supposed to be the total amount
of memory dynamically allocated by the emulator. Shared
libraries, the code of the emulator itself, and
- the emulator stack(s) are not supposed to be included. That
+ the emulator stacks are not supposed to be included. That
is, the <c>total</c> value is <em>not</em> supposed to be
- equal to the total size of all pages mapped to the emulator.
- Furthermore, due to fragmentation and pre-reservation of
- memory areas, the size of the memory segments which contain
- the dynamically allocated memory blocks can be substantially
+ equal to the total size of all pages mapped to the emulator.</p>
+ <p>Furthermore, because of fragmentation and prereservation of
+ memory areas, the size of the memory segments containing
+ the dynamically allocated memory blocks can be much
larger than the total size of the dynamically allocated
memory blocks.</p>
</note>
<note>
- <p>
- Since erts version 5.6.4 <c>erlang:memory/0</c> requires that
+ <p>As from <c>ERTS</c> 5.6.4, <c>erlang:memory/0</c> requires that
all <seealso marker="erts:erts_alloc">erts_alloc(3)</seealso>
- allocators are enabled (default behaviour).
- </p>
+ allocators are enabled (default behavior).</p>
</note>
- <p>Failure:</p>
- <taglist>
- <tag><c>notsup</c></tag>
- <item>
- If an <seealso marker="erts:erts_alloc">erts_alloc(3)</seealso>
- allocator has been disabled.
- </item>
- </taglist>
+ <p>Failure: <c>notsup</c> if an
+ <seealso marker="erts:erts_alloc">erts_alloc(3)</seealso>
+ allocator has been disabled.</p>
</desc>
</func>
+
<func>
<name name="memory" arity="1" clause_i="1"/>
<name name="memory" arity="1" clause_i="2"/>
+ <fsummary>Information about dynamically allocated memory.</fsummary>
<type name="memory_type"/>
- <fsummary>Information about dynamically allocated memory</fsummary>
<desc>
<p>Returns the memory size in bytes allocated for memory of
type <c><anno>Type</anno></c>. The argument can also be given as a list
of <c>memory_type()</c> atoms, in which case a corresponding list of
<c>{memory_type(), Size :: integer >= 0}</c> tuples is returned.</p>
<note>
- <p>
- Since erts version 5.6.4 <c>erlang:memory/1</c> requires that
+ <p>As from <c>ERTS</c> version 5.6.4,
+ <c>erlang:memory/1</c> requires that
all <seealso marker="erts:erts_alloc">erts_alloc(3)</seealso>
- allocators are enabled (default behaviour).
- </p>
+ allocators are enabled (default behavior).</p>
</note>
<p>Failures:</p>
<taglist>
<tag><c>badarg</c></tag>
<item>
- If <c><anno>Type</anno></c> is not one of the memory types listed in the
- documentation of
+ If <c><anno>Type</anno></c> is not one of the memory types
+ listed in the description of
<seealso marker="#memory/0">erlang:memory/0</seealso>.
</item>
<tag><c>badarg</c></tag>
<item>
- If <c>maximum</c> is passed as <c><anno>Type</anno></c> and the emulator
- is not run in instrumented mode.
+ If <c>maximum</c> is passed as <c><anno>Type</anno></c> and
+ the emulator is not run in instrumented mode.
</item>
<tag><c>notsup</c></tag>
<item>
@@ -2658,35 +2826,39 @@ os_prompt% </pre>
<seealso marker="#memory/0">erlang:memory/0</seealso>.</p>
</desc>
</func>
+
<func>
<name name="min" arity="2"/>
- <fsummary>Return the smallest of two term</fsummary>
+ <fsummary>Returns the smallest of two terms.</fsummary>
<desc>
- <p>Return the smallest of <c><anno>Term1</anno></c> and <c><anno>Term2</anno></c>;
- if the terms compare equal, <c><anno>Term1</anno></c> will be returned.</p>
+ <p>Returns the smallest of <c><anno>Term1</anno></c> and
+ <c><anno>Term2</anno></c>.
+ If the terms are equal, <c><anno>Term1</anno></c> is returned.</p>
</desc>
</func>
+
<func>
<name name="module_loaded" arity="1"/>
- <fsummary>Check if a module is loaded</fsummary>
+ <fsummary>Checks if a module is loaded.</fsummary>
<desc>
- <p>Returns <c>true</c> if the module <c><anno>Module</anno></c> is loaded,
- otherwise returns <c>false</c>. It does not attempt to load
+ <p>Returns <c>true</c> if the module <c><anno>Module</anno></c>
+ is loaded, otherwise <c>false</c>. It does not attempt to load
the module.</p>
<warning>
<p>This BIF is intended for the code server (see
- <seealso marker="kernel:code">code(3)</seealso>) and should not be
+ <seealso marker="kernel:code">code(3)</seealso>) and is not to be
used elsewhere.</p>
</warning>
</desc>
</func>
+
<func>
<name name="monitor" arity="2" clause_i="1"/>
<name name="monitor" arity="2" clause_i="2"/>
+ <fsummary>Starts monitoring.</fsummary>
<type name="registered_name"/>
<type name="registered_process_identifier"/>
<type name="monitor_process_identifier"/>
- <fsummary>Start monitoring</fsummary>
<desc>
<p>Send a monitor request of type <c><anno>Type</anno></c> to the
entity identified by <c><anno>Item</anno></c>. The caller of
@@ -2694,15 +2866,15 @@ os_prompt% </pre>
following format if the monitored state is changed:</p>
<code type="none">{Tag, <anno>MonitorRef</anno>, <anno>Type</anno>, Object, Info}</code>
<note><p>The monitor request is an asynchronous signal. That is, it
- takes time before the signal reach its destination.</p></note>
- <p>Currently valid <c><anno>Type</anno></c>s:</p>
+ takes time before the signal reaches its destination.</p></note>
+ <p>Valid <c><anno>Type</anno></c>s:</p>
<taglist>
<tag><marker id="monitor_process"/><c>process</c></tag>
<item>
<p>Monitor the existence of the process identified by
- <c><anno>Item</anno></c>. Currently valid
+ <c><anno>Item</anno></c>. Valid
<c><anno>Item</anno></c>s in combination with the
- <c>process <anno>Type</anno></c>:</p>
+ <c>process <anno>Type</anno></c> can be any of the following:</p>
<taglist>
<tag><c>pid()</c></tag>
<item>
@@ -2721,10 +2893,10 @@ os_prompt% </pre>
will become monitored.</p>
</item>
</taglist>
- <note><p>When a process is monitored by registered name, the
- process that has the registered name at the time when the
+ <note><p>When a registered name is used, the
+ process that has the registered name when the
monitor request reach its destination will be monitored.
- The monitor will not be effected, if the registered name is
+ The monitor is not effected if the registered name is
unregistered, or unregistered and later registered on another
process.</p></note>
<p>The monitor is triggered either when the monitored process
@@ -2732,22 +2904,22 @@ os_prompt% </pre>
lost. In the case the connection to it is lost, we do not know
if it still exist or not. After this type of monitor has been
triggered, the monitor is automatically removed.</p>
- <p>When the monitor is triggered a <c>'DOWN'</c> message will
- be sent to the monitoring process. A <c>'DOWN'</c> message has
+ <p>When the monitor is triggered a <c>'DOWN'</c> message is
+ sent to the monitoring process. A <c>'DOWN'</c> message has
the following pattern:</p>
<code type="none">{'DOWN', MonitorRef, Type, Object, Info}</code>
- <p>where <c>MonitorRef</c> and <c>Type</c> are the same as
- described above, and:</p>
+ <p>Here <c>MonitorRef</c> and <c>Type</c> are the same as
+ described earlier, and:</p>
<taglist>
<tag><c>Object</c></tag>
<item>
<p>equals:</p>
<taglist>
<tag><c><anno>Item</anno></c></tag>
- <item>If <c><anno>Item</anno></c> was specified by a
- pid.</item>
+ <item>If <c><anno>Item</anno></c> is specified by a
+ process identifier.</item>
<tag><c>{RegisteredName, Node}</c></tag>
- <item>If <c><anno>Item</anno></c> was specified as
+ <item>If <c><anno>Item</anno></c> is specified as
<c>RegisteredName</c>, or <c>{RegisteredName, Node}</c>
where <c>Node</c> corresponds to the node that the
monitored process resides on.</item>
@@ -2760,26 +2932,26 @@ os_prompt% </pre>
connection to the node where the monitored process
resides).</p></item>
</taglist>
- <p>The monitoring is turned off either when the <c>'DOWN'</c>
- message is sent, or when
+ <p>The monitoring is turned off when the <c>'DOWN'</c>
+ message is sent or when
<seealso marker="#demonitor/1">demonitor/1</seealso>
is called.</p>
<p>If an attempt is made to monitor a process on an older node
- (where remote process monitoring is not implemented or one
+ (where remote process monitoring is not implemented or
where remote process monitoring by registered name is not
implemented), the call fails with <c>badarg</c>.</p>
<note>
- <p>The format of the <c>'DOWN'</c> message changed in the 5.2
- version of the emulator (OTP release R9B) for monitor
- <em>by registered name</em>. The <c>Object</c> element of
+ <p>The format of the <c>'DOWN'</c> message changed in ERTS
+ version 5.2 (OTP R9B) for monitoring
+ <em>by registered name</em>. Element <c>Object</c> of
the <c>'DOWN'</c> message could in earlier versions
- sometimes be the pid of the monitored process and sometimes
- be the registered name. Now the <c>Object</c> element is
+ sometimes be the process identifier of the monitored process and sometimes
+ be the registered name. Now element <c>Object</c> is
always a tuple consisting of the registered name and
- the node name. Processes on new nodes (emulator version 5.2
- or greater) will always get <c>'DOWN'</c> messages on
+ the node name. Processes on new nodes (ERTS version 5.2
+ or higher) always get <c>'DOWN'</c> messages on
the new format even if they are monitoring processes on old
- nodes. Processes on old nodes will always get <c>'DOWN'</c>
+ nodes. Processes on old nodes always get <c>'DOWN'</c>
messages on the old format.</p>
</note>
</item>
@@ -2807,8 +2979,8 @@ os_prompt% </pre>
<seealso marker="time_correction#Single_Time_Warp_Mode">single
time warp mode</seealso> is used. When a change from preliminary
to final time offset is made, the monitor will be triggered once
- regardless of whether the time offset value was changed due to
- the finalization or not.</p>
+ regardless of whether the time offset value was actually changed
+ or not.</p>
<p>If the runtime system is in
<seealso marker="time_correction#Multi_Time_Warp_Mode">multi
@@ -2836,7 +3008,7 @@ os_prompt% </pre>
<p>When the <c>'CHANGE'</c> message has been received you are
guaranteed not to retrieve the old time offset when calling
<seealso marker="#time_offset/0"><c>erlang:time_offset()</c></seealso>.
- Note that you may observe the change of the time offset
+ Note that you can observe the change of the time offset
when calling <c>erlang:time_offset()</c> before you
get the <c>'CHANGE'</c> message.</p>
@@ -2844,67 +3016,71 @@ os_prompt% </pre>
</taglist>
<p>Making several calls to <c>monitor/2</c> for the same
<c><anno>Item</anno></c> and/or <c><anno>Type</anno></c> is not
- an error; it results in many, completely independent,
- monitorings.</p>
+ an error; it results in as many independent monitoring instances.</p>
<p>The monitor functionality is expected to be extended. That is,
other <c><anno>Type</anno></c>s and <c><anno>Item</anno></c>s
- are expected to be supported in the future.</p>
+ are expected to be supported in a future release.</p>
<note>
- <p>If/when <c>monitor/2</c> is extended, other
- possible values for <c>Tag</c>, <c>Object</c>, and
+ <p>If or when <c>monitor/2</c> is extended, other
+ possible values for <c>Tag</c>, <c>Object</c> and
<c>Info</c> in the monitor message will be introduced.</p>
</note>
</desc>
</func>
+
<func>
<name name="monitor_node" arity="2"/>
- <fsummary>Monitor the status of a node</fsummary>
+ <fsummary>Monitors the status of a node.</fsummary>
<desc>
- <p>Monitors the status of the node <c><anno>Node</anno></c>. If <c><anno>Flag</anno></c>
- is <c>true</c>, monitoring is turned on; if <c><anno>Flag</anno></c> is
- <c>false</c>, monitoring is turned off.</p>
+ <p>Monitors the status of the node <c><anno>Node</anno></c>.
+ If <c><anno>Flag</anno></c>
+ is <c>true</c>, monitoring is turned on. If <c><anno>Flag</anno></c>
+ is <c>false</c>, monitoring is turned off.</p>
<p>Making several calls to <c>monitor_node(Node, true)</c> for
- the same <c><anno>Node</anno></c> is not an error; it results in as many,
- completely independent, monitorings.</p>
+ the same <c><anno>Node</anno></c> is not an error; it results
+ in as many independent monitoring instances.</p>
<p>If <c><anno>Node</anno></c> fails or does not exist, the message
<c>{nodedown, Node}</c> is delivered to the process. If a
process has made two calls to <c>monitor_node(Node, true)</c>
- and <c><anno>Node</anno></c> terminates, two <c>nodedown</c> messages are
- delivered to the process. If there is no connection to
- <c><anno>Node</anno></c>, there will be an attempt to create one. If this
- fails, a <c>nodedown</c> message is delivered.</p>
+ and <c><anno>Node</anno></c> terminates, two <c>nodedown</c> messages
+ are delivered to the process. If there is no connection to
+ <c><anno>Node</anno></c>, an attempt is made to create one.
+ If this fails, a <c>nodedown</c> message is delivered.</p>
<p>Nodes connected through hidden connections can be monitored
- as any other node.</p>
+ as any other nodes.</p>
<p>Failure: <c>badarg</c> if the local node is not alive.</p>
</desc>
</func>
+
<func>
<name name="monitor_node" arity="3"/>
- <fsummary>Monitor the status of a node</fsummary>
+ <fsummary>Monitors the status of a node.</fsummary>
<desc>
- <p>Behaves as <c>monitor_node/2</c> except that it allows an
+ <p>Behaves as
+ <seealso marker="#monitor_node/2">monitor_node/2</seealso>
+ except that it allows an
extra option to be given, namely <c>allow_passive_connect</c>.
- The option allows the BIF to wait the normal net connection
- timeout for the <em>monitored node</em> to connect itself,
+ This option allows the BIF to wait the normal network connection
+ time-out for the <em>monitored node</em> to connect itself,
even if it cannot be actively connected from this node
- (i.e. it is blocked). The state where this might be useful can
- only be achieved by using the kernel option
- <c>dist_auto_connect once</c>. If that kernel option is not
- used, the <c>allow_passive_connect</c> option has no
- effect.</p>
+ (that is, it is blocked). The state where this can be useful
+ can only be achieved by using the <c>Kernel</c> option
+ <c>dist_auto_connect once</c>. If that option is not
+ used, option <c>allow_passive_connect</c> has no effect.</p>
<note>
- <p>The <c>allow_passive_connect</c> option is used
+ <p>Option <c>allow_passive_connect</c> is used
internally and is seldom needed in applications where the
- network topology and the kernel options in effect is known in
- advance.</p>
+ network topology and the <c>Kernel</c> options in effect
+ are known in advance.</p>
</note>
<p>Failure: <c>badarg</c> if the local node is not alive or the
option list is malformed.</p>
</desc>
</func>
+
<func>
<name name="monotonic_time" arity="0"/>
- <fsummary>Current Erlang monotonic time</fsummary>
+ <fsummary>Current Erlang monotonic time.</fsummary>
<desc>
<p>Returns the current
<seealso marker="time_correction#Erlang_Monotonic_Time">Erlang
@@ -2917,7 +3093,7 @@ os_prompt% </pre>
<seealso marker="time_correction#Monotonically_Increasing">monotonically increasing</seealso> time, but <em>not</em> a
<seealso marker="time_correction#Strictly_Monotonically_Increasing">strictly monotonically increasing</seealso>
time. That is, consecutive calls to
- <c>erlang:monotonic_time/0</c> may produce the same result.</p>
+ <c>erlang:monotonic_time/0</c> can produce the same result.</p>
<p>Different runtime system instances will use different
unspecified points in time as base for their Erlang monotonic clocks.
@@ -2925,9 +3101,9 @@ os_prompt% </pre>
different runtime system instances. Different runtime system instances
may also place this unspecified point in time different relative
runtime system start. It may be placed in the future (time at start
- will be a negative value), the past (time at start will be a
- positive value), or the runtime system start (time at start will
- be zero). The monotonic time as of runtime system start can be
+ is a negative value), the past (time at start is a
+ positive value), or the runtime system start (time at start is
+ zero). The monotonic time at runtime system start can be
retrieved by calling
<seealso marker="#system_info_start_time"><c>erlang:system_info(start_time)</c></seealso>.</p></note>
</desc>
@@ -2949,61 +3125,68 @@ os_prompt% </pre>
</func>
<func>
<name name="nif_error" arity="1"/>
- <fsummary>Stop execution with a given reason</fsummary>
+ <fsummary>Stops execution with a given reason.</fsummary>
<desc>
<p>Works exactly like
- <seealso marker="#error/1">erlang:error/1</seealso>,
- but Dialyzer thinks that this BIF will return an arbitrary term.
- When used in a stub function for a NIF to generate an
- exception when the NIF library is not loaded, Dialyzer
- will not generate false warnings.</p>
+ <seealso marker="#error/1">erlang:error/1</seealso>, but
+ <c>Dialyzer</c> thinks that this BIF will return an arbitrary
+ term. When used in a stub function for a NIF to generate an
+ exception when the NIF library is not loaded, <c>Dialyzer</c>
+ does not generate false warnings.</p>
</desc>
</func>
+
<func>
<name name="nif_error" arity="2"/>
- <fsummary>Stop execution with a given reason</fsummary>
+ <fsummary>Stops execution with a given reason.</fsummary>
<desc>
<p>Works exactly like
- <seealso marker="#error/2">erlang:error/2</seealso>,
- but Dialyzer thinks that this BIF will return an arbitrary term.
- When used in a stub function for a NIF to generate an
- exception when the NIF library is not loaded, Dialyzer
- will not generate false warnings.</p>
+ <seealso marker="#error/2">erlang:error/2</seealso>, but
+ <c>Dialyzer</c> thinks that this BIF will return an arbitrary
+ term. When used in a stub function for a NIF to generate an
+ exception when the NIF library is not loaded, <c>Dialyzer</c>
+ does not generate false warnings.</p>
</desc>
</func>
+
<func>
<name name="node" arity="0"/>
- <fsummary>Name of the local node</fsummary>
+ <fsummary>Name of the local node.</fsummary>
<desc>
<p>Returns the name of the local node. If the node is not alive,
<c>nonode@nohost</c> is returned instead.</p>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="node" arity="1"/>
- <fsummary>At which node is a pid, port or reference located</fsummary>
+ <fsummary>At which node a pid, port, or reference originates.</fsummary>
<desc>
- <p>Returns the node where <c><anno>Arg</anno></c> is located. <c><anno>Arg</anno></c> can
- be a pid, a reference, or a port. If the local node is not
+ <p>Returns the node where <c><anno>Arg</anno></c> originates.
+ <c><anno>Arg</anno></c> can
+ be a process identifier, a reference, or a port.
+ If the local node is not
alive, <c>nonode@nohost</c> is returned.</p>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="nodes" arity="0"/>
- <fsummary>All visible nodes in the system</fsummary>
+ <fsummary>All visible nodes in the system.</fsummary>
<desc>
- <p>Returns a list of all visible nodes in the system, excluding
+ <p>Returns a list of all visible nodes in the system, except
the local node. Same as <c>nodes(visible)</c>.</p>
</desc>
</func>
+
<func>
<name name="nodes" arity="1"/>
- <fsummary>All nodes of a certain type in the system</fsummary>
+ <fsummary>All nodes of a certain type in the system.</fsummary>
<desc>
- <p>Returns a list of nodes according to argument given.
- The result returned when the argument is a list, is the list
+ <p>Returns a list of nodes according to the argument given.
+ The returned result when the argument is a list, is the list
of nodes satisfying the disjunction(s) of the list elements.</p>
<p><c><anno>NodeType</anno></c> can be any of the following:</p>
<taglist>
@@ -3025,22 +3208,26 @@ os_prompt% </pre>
</item>
<tag><c>known</c></tag>
<item>
- <p>Nodes which are known to this node, i.e., connected,
- previously connected, etc.</p>
+ <p>Nodes that are known to this node. That is, connected
+ nodes and nodes referred to by process identifiers, port
+ identifiers and references located on this node.
+ The set of known nodes is garbage collected. Notice that
+ this garbage collection can be delayed. For more
+ information, see
+ <seealso marker="erlang#system_info_delayed_node_table_gc">delayed_node_table_gc</seealso>.
+ </p>
</item>
</taglist>
<p>Some equalities: <c>[node()] = nodes(this)</c>,
<c>nodes(connected) = nodes([visible, hidden])</c>, and
<c>nodes() = nodes(visible)</c>.</p>
- <p>If the local node is not alive,
- <c>nodes(this) == nodes(known) == [nonode@nohost]</c>, for
- any other <c><anno>Arg</anno></c> the empty list [] is returned.</p>
</desc>
</func>
+
<func>
<name name="now" arity="0"/>
+ <fsummary>Elapsed time since 00:00 GMT.</fsummary>
<type name="timestamp"/>
- <fsummary>Elapsed time since 00:00 GMT</fsummary>
<desc>
<warning><p><em>This function is deprecated! Do not use it!</em>
See the users guide chapter
@@ -3050,107 +3237,101 @@ os_prompt% </pre>
section for information on what to use instead of <c>erlang:now/0</c>.
</p></warning>
<p>Returns the tuple <c>{MegaSecs, Secs, MicroSecs}</c> which is
- the elapsed time since 00:00 GMT, January 1, 1970 (zero hour)
+ the elapsed time since 00:00 GMT, January 1, 1970 (zero hour),
on the assumption that the underlying OS supports this.
- Otherwise, some other point in time is chosen. It is also
- guaranteed that subsequent calls to this BIF returns
+ Otherwise some other point in time is chosen. It is also
+ guaranteed that subsequent calls to this BIF return
continuously increasing values. Hence, the return value from
- <c>now()</c> can be used to generate unique time-stamps,
- and if it is called in a tight loop on a fast machine
+ <c>now()</c> can be used to generate unique time-stamps.
+ If it is called in a tight loop on a fast machine,
the time of the node can become skewed.</p>
- <p>It can only be used to check the local time of day if
- the time-zone info of the underlying operating system is
+ <p>Can only be used to check the local time of day if
+ the time-zone information of the underlying OS is
properly configured.</p>
</desc>
</func>
+
<func>
<name name="open_port" arity="2"/>
- <fsummary>Open a port</fsummary>
+ <fsummary>Opens a port.</fsummary>
<desc>
<p>Returns a port identifier as the result of opening a
new Erlang port. A port can be seen as an external Erlang
- process.
- </p>
+ process.</p>
<p>The name of the executable as well as the arguments
- given in <c>cd</c>, <c>env</c>, <c>args</c> and <c>arg0</c> is subject to
- Unicode file name translation if the system is running
+ given in <c>cd</c>, <c>env</c>, <c>args</c>, and <c>arg0</c> are
+ subject to Unicode file name translation if the system is running
in Unicode file name mode. To avoid
- translation or force i.e. UTF-8, supply the executable
+ translation or to force, for example UTF-8, supply the executable
and/or arguments as a binary in the correct
- encoding. See the <seealso
- marker="kernel:file">file</seealso> module, the
- <seealso marker="kernel:file#native_name_encoding/0">
- file:native_name_encoding/0</seealso> function and the
- <seealso marker="stdlib:unicode_usage">stdlib users guide
- </seealso> for details.</p>
-
- <note><p>The characters in the name (if given as a list)
- can only be &gt; 255 if the Erlang VM is started in
- Unicode file name translation mode, otherwise the name
+ encoding. For details, see the module
+ <seealso marker="kernel:file">file</seealso>, the function
+ <seealso marker="kernel:file#native_name_encoding/0">file:native_name_encoding/0</seealso>, and the
+ <seealso marker="stdlib:unicode_usage">STDLIB </seealso>
+ User's Guide.</p>
+ <note><p>The characters in the name (if given as a list) can
+ only be higher than 255 if the Erlang Virtual Machine is started
+ in Unicode file name translation mode. Otherwise the name
of the executable is limited to the ISO-latin-1
character set.</p></note>
-
- <p><c><anno>PortName</anno></c> is one of the following:</p>
+ <p><c><anno>PortName</anno></c> can be any of the following:</p>
<taglist>
<tag><c>{spawn, <anno>Command</anno>}</c></tag>
<item>
- <p>Starts an external program. <c><anno>Command</anno></c> is the name
- of the external program which will be run. <c><anno>Command</anno></c>
+ <p>Starts an external program. <c><anno>Command</anno></c>
+ is the name of the external program to be run.
+ <c><anno>Command</anno></c>
runs outside the Erlang work space unless an Erlang
- driver with the name <c><anno>Command</anno></c> is found. If found,
- that driver will be started. A driver runs in the Erlang
- workspace, which means that it is linked with the Erlang
+ driver with the name <c><anno>Command</anno></c> is found.
+ If found, that driver is started. A driver runs in the Erlang
+ work space, which means that it is linked with the Erlang
runtime system.</p>
<p>When starting external programs on Solaris, the system
call <c>vfork</c> is used in preference to <c>fork</c>
for performance reasons, although it has a history of
- being less robust. If there are problems with using
- <c>vfork</c>, setting the environment variable
- <c>ERL_NO_VFORK</c> to any value will cause <c>fork</c>
+ being less robust. If there are problems using
+ <c>vfork</c>, setting environment variable
+ <c>ERL_NO_VFORK</c> to any value causes <c>fork</c>
to be used instead.</p>
-
- <p>For external programs, the <c>PATH</c> is searched
+ <p>For external programs, <c>PATH</c> is searched
(or an equivalent method is used to find programs,
- depending on operating system). This is done by invoking
- the shell on certain platforms. The first space
- separated token of the command will be considered as the
+ depending on OS). This is done by invoking
+ the shell on certain platforms. The first space-separated
+ token of the command is considered as the
name of the executable (or driver). This (among other
things) makes this option unsuitable for running
- programs having spaces in file or directory names. Use
- {spawn_executable, <anno>Command</anno>} instead if spaces in executable
- file names is desired.</p>
+ programs having spaces in file names or directory names.
+ If spaces in executable file names are desired, use
+ <c>{spawn_executable, <anno>Command</anno>}</c> instead.</p>
</item>
<tag><c>{spawn_driver, <anno>Command</anno>}</c></tag>
<item>
<p>Works like <c>{spawn, <anno>Command</anno>}</c>, but demands the
- first (space separated) token of the command to be the name of a
+ first (space-separated) token of the command to be the name of a
loaded driver. If no driver with that name is loaded, a
<c>badarg</c> error is raised.</p>
</item>
<tag><c>{spawn_executable, <anno>FileName</anno>}</c></tag>
<item>
-
<p>Works like <c>{spawn, <anno>FileName</anno>}</c>, but only runs
- external executables. The <c><anno>FileName</anno></c> in its whole
- is used as the name of the executable, including any
- spaces. If arguments are to be passed, the
- <c>args</c> and <c>arg0</c> <c><anno>PortSettings</anno></c> can be used.</p>
-
- <p>The shell is not usually invoked to start the
- program, it's executed directly. Neither is the
- <c>PATH</c> (or equivalent) searched. To find a program
- in the PATH to execute, use <seealso
- marker="kernel:os#find_executable/1">os:find_executable/1</seealso>.</p>
+ external executables. <c><anno>FileName</anno></c> in its whole
+ is used as the name of the executable, including any spaces.
+ If arguments are to be passed, the <c><anno>PortSettings</anno></c>
+ <c>args</c> and <c>arg0</c> can be used.</p>
+ <p>The shell is usually not invoked to start the
+ program, it is executed directly. <c>PATH</c> (or
+ equivalent) is not searched. To find a program
+ in <c>PATH</c> to execute, use
+ <seealso marker="kernel:os#find_executable/1">os:find_executable/1</seealso>.</p>
<p>Only if a shell script or <c>.bat</c> file is
- executed, the appropriate command interpreter will
- implicitly be invoked, but there will still be no
- command argument expansion or implicit PATH search.</p>
-
- <p>If the <c><anno>FileName</anno></c> cannot be run, an error
- exception, with the posix error code as the reason, is
- raised. The error reason may differ between operating
- systems. Typically the error <c>enoent</c> is raised
- when one tries to run a program that is not found and
+ executed, the appropriate command interpreter is
+ invoked implicitly, but there is still no
+ command argument expansion or implicit <c>PATH</c> search.</p>
+ <p>If <c><anno>FileName</anno></c> cannot be run, an error
+ exception is raised, with the POSIX error code as the reason.
+ The error reason can differ between OSs.
+ Typically the error <c>enoent</c> is raised when an
+ attempt is made to run a program that is not found and
<c>eacces</c> is raised when the given file is not
executable.</p>
</item>
@@ -3160,19 +3341,18 @@ os_prompt% </pre>
file descriptors used by Erlang. The file descriptor
<c><anno>In</anno></c> can be used for standard input, and the file
descriptor <c><anno>Out</anno></c> for standard output. It is only
- used for various servers in the Erlang operating system
- (<c>shell</c> and <c>user</c>). Hence, its use is very
- limited.</p>
+ used for various servers in the Erlang OS (<c>shell</c>
+ and <c>user</c>). Hence, its use is limited.</p>
</item>
</taglist>
<p><c><anno>PortSettings</anno></c> is a list of settings for the port.
- Valid settings are:</p>
+ The valid settings are as follows:</p>
<taglist>
<tag><c>{packet, <anno>N</anno>}</c></tag>
<item>
<p>Messages are preceded by their length, sent in <c><anno>N</anno></c>
- bytes, with the most significant byte first. Valid values
- for <c>N</c> are 1, 2, or 4.</p>
+ bytes, with the most significant byte first. The valid values
+ for <c>N</c> are 1, 2, and 4.</p>
</item>
<tag><c>stream</c></tag>
<item>
@@ -3183,116 +3363,108 @@ os_prompt% </pre>
<tag><c>{line, <anno>L</anno>}</c></tag>
<item>
<p>Messages are delivered on a per line basis. Each line
- (delimited by the OS-dependent newline sequence) is
- delivered in one single message. The message data format
- is <c>{Flag, Line}</c>, where <c>Flag</c> is either
- <c>eol</c> or <c>noeol</c> and <c>Line</c> is the actual
- data delivered (without the newline sequence).</p>
+ (delimited by the OS-dependent new line sequence) is
+ delivered in a single message. The message data format
+ is <c>{Flag, Line}</c>, where <c>Flag</c> is
+ <c>eol</c> or <c>noeol</c>, and <c>Line</c> is the
+ data delivered (without the new line sequence).</p>
<p><c><anno>L</anno></c> specifies the maximum line length in bytes.
- Lines longer than this will be delivered in more than one
- message, with the <c>Flag</c> set to <c>noeol</c> for all
+ Lines longer than this are delivered in more than one
+ message, with <c>Flag</c> set to <c>noeol</c> for all
but the last message. If end of file is encountered
- anywhere else than immediately following a newline
- sequence, the last line will also be delivered with
- the <c>Flag</c> set to <c>noeol</c>. In all other cases,
+ anywhere else than immediately following a new line
+ sequence, the last line is also delivered with
+ <c>Flag</c> set to <c>noeol</c>. Otherwise
lines are delivered with <c>Flag</c> set to <c>eol</c>.</p>
- <p>The <c>{packet, <anno>N</anno>}</c> and <c>{line, <anno>L</anno>}</c> settings are
- mutually exclusive.</p>
+ <p>The <c>{packet, <anno>N</anno>}</c> and <c>{line,
+ <anno>L</anno>}</c> settings are mutually exclusive.</p>
</item>
<tag><c>{cd, <anno>Dir</anno>}</c></tag>
<item>
- <p>This is only valid for <c>{spawn, <anno>Command</anno>}</c> and
- <c>{spawn_executable, <anno>FileName</anno>}</c>.
+ <p>Only valid for <c>{spawn, <anno>Command</anno>}</c> and
+ <c>{spawn_executable, <anno>FileName</anno>}</c>.
The external program starts using <c><anno>Dir</anno></c> as its
- working directory. <c><anno>Dir</anno></c> must be a string.
- </p>
+ working directory. <c><anno>Dir</anno></c> must be a string.</p>
</item>
<tag><c>{env, <anno>Env</anno>}</c></tag>
<item>
- <p>This is only valid for <c>{spawn, <anno>Command</anno>}</c> and
+ <p>Only valid for <c>{spawn, <anno>Command</anno>}</c> and
<c>{spawn_executable, <anno>FileName</anno>}</c>.
The environment of the started process is extended using
the environment specifications in <c><anno>Env</anno></c>.</p>
- <p><c><anno>Env</anno></c> should be a list of tuples <c>{<anno>Name</anno>, <anno>Val</anno>}</c>,
- where <c><anno>Name</anno></c> is the name of an environment variable,
- and <c><anno>Val</anno></c> is the value it is to have in the spawned
- port process. Both <c><anno>Name</anno></c> and <c><anno>Val</anno></c> must be
- strings. The one exception is <c><anno>Val</anno></c> being the atom
+ <p><c><anno>Env</anno></c> is to be a list of tuples
+ <c>{<anno>Name</anno>, <anno>Val</anno>}</c>,
+ where <c><anno>Name</anno></c> is the name of an
+ environment variable, and <c><anno>Val</anno></c> is the
+ value it is to have in the spawned
+ port process. Both <c><anno>Name</anno></c> and
+ <c><anno>Val</anno></c> must be strings. The one
+ exception is <c><anno>Val</anno></c> being the atom
<c>false</c> (in analogy with <c>os:getenv/1</c>), which
- removes the environment variable.
- </p>
+ removes the environment variable.</p>
</item>
<tag><c>{args, [ string() | binary() ]}</c></tag>
<item>
-
- <p>This option is only valid for <c>{spawn_executable, <anno>FileName</anno>}</c>
+ <p>Only valid for <c>{spawn_executable, <anno>FileName</anno>}</c>
and specifies arguments to the executable. Each argument
is given as a separate string and (on Unix) eventually
ends up as one element each in the argument vector. On
- other platforms, similar behavior is mimicked.</p>
-
- <p>The arguments are not expanded by the shell prior to
- being supplied to the executable, most notably this
- means that file wildcard expansion will not happen. Use
- <seealso
- marker="stdlib:filelib#wildcard/1">filelib:wildcard/1</seealso>
- to expand wildcards for the arguments. Note that even if
+ other platforms, a similar behavior is mimicked.</p>
+ <p>The arguments are not expanded by the shell before
+ being supplied to the executable. Most notably this
+ means that file wild card expansion does not happen.
+ To expand wild cards for the arguments, use
+ <seealso marker="stdlib:filelib#wildcard/1">filelib:wildcard/1</seealso>.
+ Notice that even if
the program is a Unix shell script, meaning that the
- shell will ultimately be invoked, wildcard expansion
- will not happen and the script will be provided with the
- untouched arguments. On Windows&reg;, wildcard expansion
- is always up to the program itself, why this isn't an
- issue.</p>
-
- <p>Note also that the actual executable name (a.k.a. <c>argv[0]</c>)
- should not be given in this list. The proper executable name will
- automatically be used as argv[0] where applicable.</p>
-
- <p>If one, for any reason, wants to explicitly set the
- program name in the argument vector, the <c>arg0</c>
- option can be used.</p>
-
+ shell ultimately is invoked, wild card expansion
+ does not happen, and the script is provided with the
+ untouched arguments. On Windows, wild card expansion
+ is always up to the program itself, therefore this is
+ not an issue issue.</p>
+ <p>The executable name (also known as <c>argv[0]</c>)
+ is not to be given in this list. The proper executable name
+ is automatically used as argv[0], where applicable.</p>
+ <p>If you explicitly want to set the
+ program name in the argument vector, option <c>arg0</c>
+ can be used.</p>
</item>
<tag><c>{arg0, string() | binary()}</c></tag>
<item>
-
- <p>This option is only valid for <c>{spawn_executable, <anno>FileName</anno>}</c>
+ <p>Only valid for <c>{spawn_executable, <anno>FileName</anno>}</c>
and explicitly specifies the program name argument when
- running an executable. This might in some circumstances,
- on some operating systems, be desirable. How the program
- responds to this is highly system dependent and no specific
+ running an executable. This can in some circumstances,
+ on some OSs, be desirable. How the program
+ responds to this is highly system-dependent and no specific
effect is guaranteed.</p>
-
</item>
-
<tag><c>exit_status</c></tag>
<item>
- <p>This is only valid for <c>{spawn, <anno>Command</anno>}</c> where
- <c><anno>Command</anno></c> refers to an external program, and for
- <c>{spawn_executable, <anno>FileName</anno>}</c>.</p>
+ <p>Only valid for <c>{spawn, <anno>Command</anno>}</c>, where
+ <c><anno>Command</anno></c> refers to an external program, and
+ for <c>{spawn_executable, <anno>FileName</anno>}</c>.</p>
<p>When the external process connected to the port exits, a
message of the form <c>{Port,{exit_status,Status}}</c> is
sent to the connected process, where <c>Status</c> is the
exit status of the external process. If the program
- aborts, on Unix the same convention is used as the shells
- do (i.e., 128+signal).</p>
- <p>If the <c>eof</c> option has been given as well,
- the <c>eof</c> message and the <c>exit_status</c> message
- appear in an unspecified order.</p>
- <p>If the port program closes its stdout without exiting,
- the <c>exit_status</c> option will not work.</p>
+ aborts on Unix, the same convention is used as the shells
+ do (that is, 128+signal).</p>
+ <p>If option <c>eof</c> is also given, the messages <c>eof</c>
+ and <c>exit_status</c> appear in an unspecified order.</p>
+ <p>If the port program closes its <c>stdout</c> without exiting,
+ option <c>exit_status</c> does not work.</p>
</item>
<tag><c>use_stdio</c></tag>
<item>
- <p>This is only valid for <c>{spawn, <anno>Command</anno>}</c> and
+ <p>Only valid for <c>{spawn, <anno>Command</anno>}</c> and
<c>{spawn_executable, <anno>FileName</anno>}</c>. It
allows the standard input and output (file descriptors 0
- and 1) of the spawned (UNIX) process for communication
+ and 1) of the spawned (Unix) process for communication
with Erlang.</p>
</item>
<tag><c>nouse_stdio</c></tag>
<item>
- <p>The opposite of <c>use_stdio</c>. Uses file descriptors
+ <p>The opposite of <c>use_stdio</c>. It uses file descriptors
3 and 4 for communication with Erlang.</p>
</item>
<tag><c>stderr_to_stdout</c></tag>
@@ -3304,14 +3476,15 @@ os_prompt% </pre>
</item>
<tag><c>overlapped_io</c></tag>
<item>
- <p>Affects ports to external programs on Windows&reg; only.
- The standard input and standard output handles of the port program
- will, if this option is supplied, be opened with the flag
- FILE_FLAG_OVERLAPPED, so that the port program can (and has to) do
+ <p>Affects ports to external programs on Windows only. The
+ standard input and standard output handles of the port program
+ are, if this option is supplied, opened with flag
+ <c>FILE_FLAG_OVERLAPPED</c>, so that the port program can
+ (and must) do
overlapped I/O on its standard handles. This is not normally
the case for simple port programs, but an option of value for the
- experienced Windows programmer. <em>On all other platforms, this
- option is silently discarded</em>.</p>
+ experienced Windows programmer. <em>On all other platforms, this
+ option is silently discarded.</em></p>
</item>
<tag><c>in</c></tag>
<item>
@@ -3323,345 +3496,354 @@ os_prompt% </pre>
</item>
<tag><c>binary</c></tag>
<item>
- <p>All IO from the port are binary data objects as opposed
+ <p>All I/O from the port is binary data objects as opposed
to lists of bytes.</p>
</item>
<tag><c>eof</c></tag>
<item>
- <p>The port will not be closed at the end of the file and
- produce an exit signal. Instead, it will remain open and
- a <c>{Port, eof}</c> message will be sent to the process
+ <p>The port is not closed at the end of the file and does not
+ produce an exit signal. Instead, it remains open and
+ a <c>{Port, eof}</c> message is sent to the process
holding the port.</p>
</item>
<tag><c>hide</c></tag>
<item>
- <p>When running on Windows, suppress creation of a new
+ <p>When running on Windows, suppresses creation of a new
console window when spawning the port program.
(This option has no effect on other platforms.)</p>
</item>
- <tag><marker id="open_port_parallelism"><c>{parallelism, Boolean}</c></marker></tag>
+ <tag><c>{parallelism, Boolean}</c></tag>
<item>
- <p>Set scheduler hint for port parallelism. If set to <c>true</c>,
- the VM will schedule port tasks when doing so will improve
- parallelism in the system. If set to <c>false</c>, the VM will
- try to perform port tasks immediately, improving latency at the
- expense of parallelism. The default can be set on system startup
- by passing the
- <seealso marker="erl#+spp">+spp</seealso> command line argument
- to <seealso marker="erl">erl(1)</seealso>.
- </p>
+ <marker id="open_port_parallelism"></marker>
+ <p>Sets scheduler hint for port parallelism. If set to
+ <c>true</c>, the Virtual Machine schedules port tasks;
+ when doing so, it improves parallelism in the system. If set
+ to <c>false</c>, the Virtual Machine tries to
+ perform port tasks immediately, improving latency at the
+ expense of parallelism. The default can be set at system startup
+ by passing command-line argument
+ <seealso marker="erl#+spp">+spp</seealso> to <c>erl(1)</c>.</p>
</item>
</taglist>
- <p>The default is <c>stream</c> for all types of port and
+ <p>Default is <c>stream</c> for all port types and
<c>use_stdio</c> for spawned ports.</p>
<p>Failure: If the port cannot be opened, the exit reason is
- <c>badarg</c>, <c>system_limit</c>, or the Posix error code which
- most closely describes the error, or <c>einval</c> if no Posix code
- is appropriate:</p>
+ <c>badarg</c>, <c>system_limit</c>, or the POSIX error code that
+ most closely describes the error, or <c>einval</c> if no POSIX
+ code is appropriate:</p>
<taglist>
<tag><c>badarg</c></tag>
- <item>
- <p>Bad input arguments to <c>open_port</c>.</p>
+ <item>Bad input arguments to <c>open_port</c>.
</item>
<tag><c>system_limit</c></tag>
- <item>
- <p>All available ports in the Erlang emulator are in use.</p>
+ <item>All available ports in the Erlang emulator are in use.
</item>
<tag><c>enomem</c></tag>
- <item>
- <p>There was not enough memory to create the port.</p>
+ <item>Not enough memory to create the port.
</item>
<tag><c>eagain</c></tag>
- <item>
- <p>There are no more available operating system processes.</p>
+ <item>No more available OS processes.
</item>
<tag><c>enametoolong</c></tag>
- <item>
- <p>The external command given was too long.</p>
+ <item>Too long external command.
</item>
<tag><c>emfile</c></tag>
- <item>
- <p>There are no more available file descriptors (for the operating system process
- that the Erlang emulator runs in).</p>
+ <item>No more available file descriptors (for the
+ OS process that the Erlang emulator runs in).
</item>
<tag><c>enfile</c></tag>
- <item>
- <p>The file table is full (for the entire operating system).</p>
+ <item>Full file table (for the entire OS).
</item>
<tag><c>eacces</c></tag>
- <item>
- <p>The <c>Command</c> given in <c>{spawn_executable, Command}</c> does not point out an executable file.</p>
+ <item><c>Command</c> given in <c>{spawn_executable, Command}</c>
+ does not point out an executable file.
</item>
<tag><c>enoent</c></tag>
- <item>
- <p>The <c><anno>FileName</anno></c> given in <c>{spawn_executable, <anno>FileName</anno>}</c> does not point out an existing file.</p>
+ <item><c><anno>FileName</anno></c> given in
+ <c>{spawn_executable, <anno>FileName</anno>}</c>
+ does not point out an existing file.
</item>
</taglist>
<p>During use of a port opened using <c>{spawn, Name}</c>,
- <c>{spawn_driver, Name}</c> or <c>{spawn_executable, Name}</c>,
+ <c>{spawn_driver, Name}</c>, or <c>{spawn_executable, Name}</c>,
errors arising when sending messages to it are reported to
the owning process using signals of the form
- <c>{'EXIT', Port, PosixCode}</c>. See <c>file(3)</c> for
- possible values of <c>PosixCode</c>.</p>
+ <c>{'EXIT', Port, PosixCode}</c>. For the possible values of
+ <c>PosixCode</c>, see the
+ <seealso marker="kernel:file">file(3)</seealso>
+ manual page in <c>Kernel</c>.</p>
<p>The maximum number of ports that can be open at the same
- time can be configured by passing the
- <seealso marker="erl#max_ports"><c>+Q</c></seealso>
- command line flag to
- <seealso marker="erl"><c>erl(1)</c></seealso>.</p>
+ time can be configured by passing command-line flag
+ <seealso marker="erl#max_ports"><c>+Q</c></seealso> to
+ <c>erl(1)</c>.</p>
</desc>
</func>
+
<func>
<name name="phash" arity="2"/>
+ <fsummary>Portable hash function.</fsummary>
<type_desc variable="Range">Range = 1..2^32, Hash = 1..Range</type_desc>
- <fsummary>Portable hash function</fsummary>
<desc>
- <p>Portable hash function that will give the same hash for
+ <p>Portable hash function that gives the same hash for
the same Erlang term regardless of machine architecture and
- ERTS version (the BIF was introduced in ERTS 4.9.1.1). Range
- can be between 1 and 2^32, the function returns a hash value
- for <c><anno>Term</anno></c> within the range <c>1..<anno>Range</anno></c>.</p>
- <p>This BIF could be used instead of the old deprecated
- <c>erlang:hash/2</c> BIF, as it calculates better hashes for
- all data-types, but consider using <c>phash2/1,2</c> instead.</p>
+ <c>ERTS</c> version (the BIF was introduced in <c>ERTS</c> 4.9.1.1).
+ The function returns a hash value for
+ <c><anno>Term</anno></c> within the range
+ <c>1..<anno>Range</anno></c>. The maximum value for
+ <c><anno>Range</anno></c> is 2^32.</p>
+ <p>This BIF can be used instead of the old deprecated BIF
+ <c>erlang:hash/2</c>, as it calculates better hashes for
+ all data types, but consider using <c>phash2/1,2</c> instead.</p>
</desc>
</func>
+
<func>
<name name="phash2" arity="1"/>
<name name="phash2" arity="2"/>
+ <fsummary>Portable hash function.</fsummary>
<type_desc variable="Range">1..2^32</type_desc>
<type_desc variable="Hash">0..Range-1</type_desc>
- <fsummary>Portable hash function</fsummary>
<desc>
- <p>Portable hash function that will give the same hash for
+ <p>Portable hash function that gives the same hash for
the same Erlang term regardless of machine architecture and
- ERTS version (the BIF was introduced in ERTS 5.2). Range can
- be between 1 and 2^32, the function returns a hash value for
- <c><anno>Term</anno></c> within the range <c>0..<anno>Range</anno>-1</c>. When called
- without the <c><anno>Range</anno></c> argument, a value in the range
- <c>0..2^27-1</c> is returned.</p>
- <p>This BIF should always be used for hashing terms. It
+ <c>ERTS</c> version (the BIF was introduced in <c>ERTS</c> 5.2).
+ The function returns a hash value for
+ <c><anno>Term</anno></c> within the range
+ <c>0..<anno>Range</anno>-1</c>. The maximum value for
+ <c><anno>Range</anno></c> is 2^32. When without argument
+ <c><anno>Range</anno></c>, a value in the range
+ 0..2^27-1 is returned.</p>
+ <p>This BIF is always to be used for hashing terms. It
distributes small integers better than <c>phash/2</c>, and
it is faster for bignums and binaries.</p>
- <p>Note that the range <c>0..<anno>Range</anno>-1</c> is different from
- the range of <c>phash/2</c> (<c>1..<anno>Range</anno></c>).</p>
+ <p>Notice that the range <c>0..<anno>Range</anno>-1</c> is
+ different from the range of <c>phash/2</c>, which is
+ <c>1..<anno>Range</anno></c>.</p>
</desc>
</func>
+
<func>
<name name="pid_to_list" arity="1"/>
- <fsummary>Text representation of a pid</fsummary>
+ <fsummary>Text representation of a pid.</fsummary>
<desc>
- <p>Returns a string which corresponds to the text
+ <p>Returns a string corresponding to the text
representation of <c><anno>Pid</anno></c>.</p>
<warning>
- <p>This BIF is intended for debugging and for use in
- the Erlang operating system. It should not be used in
- application programs.</p>
+ <p>This BIF is intended for debugging and is not to be used
+ in application programs.</p>
</warning>
</desc>
</func>
+
<func>
<name name="port_close" arity="1"/>
- <fsummary>Close an open port</fsummary>
+ <fsummary>Closes an open port.</fsummary>
<desc>
<p>Closes an open port. Roughly the same as
- <c><anno>Port</anno> ! {self(), close}</c> except for the error behaviour
- (see below), being synchronous, and that the port does
- <em>not</em> reply with <c>{Port, closed}</c>. Any process may
+ <c><anno>Port</anno> ! {self(), close}</c> except for the error behavior
+ (see the following), being synchronous, and that the port does
+ <em>not</em> reply with <c>{Port, closed}</c>. Any process can
close a port with <c>port_close/1</c>, not only the port owner
(the connected process). If the calling process is linked to
- port identified by <c><anno>Port</anno></c>, an exit signal due
- to that link will be received by the process prior to the return
- from <c>port_close/1</c>.</p>
- <p>For comparison: <c><anno>Port</anno> ! {self(), close}</c> fails with
- <c>badarg</c> if <c><anno>Port</anno></c> cannot be sent to (i.e.,
- <c><anno>Port</anno></c> refers neither to a port nor to a process). If
- <c><anno>Port</anno></c> is a closed port nothing happens. If <c><anno>Port</anno></c>
+ the port identified by <c><anno>Port</anno></c>, the exit
+ signal from the port is guaranteed to be delivered before
+ <c>port_close/1</c> returns.</p>
+ <p>For comparison: <c><anno>Port</anno> ! {self(), close}</c>
+ only fails with <c>badarg</c> if <c><anno>Port</anno></c> does
+ not refer to a port or a process. If <c><anno>Port</anno></c>
+ is a closed port, nothing happens. If <c><anno>Port</anno></c>
is an open port and the calling process is the port owner,
- the port replies with <c>{Port, closed}</c> when all buffers
- have been flushed and the port really closes, but if
- the calling process is not the port owner the <em>port owner</em> fails with <c>badsig</c>.</p>
-
- <p>Note that any process can close a port using
- <c><anno>Port</anno> ! {PortOwner, close}</c> just as if it itself was
+ the port replies with <c>{Port, closed}</c> when all buffers
+ have been flushed and the port really closes. If the calling
+ process is not the port owner, the <em>port owner</em> fails
+ with <c>badsig</c>.</p>
+ <p>Notice that any process can close a port using
+ <c><anno>Port</anno> ! {PortOwner, close}</c> as if it itself was
the port owner, but the reply always goes to the port owner.</p>
- <p>As of OTP-R16 <c><anno>Port</anno> ! {PortOwner, close}</c> is truly
- asynchronous. Note that this operation has always been
+ <p>As from OTP R16, <c><anno>Port</anno> ! {PortOwner, close}</c> is truly
+ asynchronous. Notice that this operation has always been
documented as an asynchronous operation, while the underlying
implementation has been synchronous. <c>port_close/1</c> is
- however still fully synchronous. This due to its error
+ however still fully synchronous. This because of its error
behavior.</p>
- <p>Failure:</p>
- <taglist>
- <tag><c>badarg</c></tag>
- <item>
- If <c><anno>Port</anno></c> is not an identifier of an open
- port, or the registered name of an open port. If the calling
- process was linked to the previously open port identified by
- <c><anno>Port</anno></c>, an exit signal due to this link
- was received by the process prior to this exception.
- </item>
- </taglist>
+ <p>Failure: <c>badarg</c> if <c><anno>Port</anno></c> is not an identifier
+ of an open port, or the registered name of an open port.
+ If the calling process was previously linked to the closed
+ port, identified by <c><anno>Port</anno></c>, the exit
+ signal from the port is guaranteed to be delivered before
+ this <c>badarg</c> exception occurs.</p>
</desc>
</func>
+
<func>
<name name="port_command" arity="2"/>
- <fsummary>Send data to a port</fsummary>
+ <fsummary>Sends data to a port.</fsummary>
<desc>
<p>Sends data to a port. Same as
- <c><anno>Port</anno> ! {PortOwner, {command, Data}}</c> except for the error
- behaviour and being synchronous (see below). Any process may
- send data to a port with <c>port_command/2</c>, not only the
+ <c><anno>Port</anno> ! {PortOwner, {command, Data}}</c> except
+ for the error
+ behavior and being synchronous (see the following). Any process
+ can send data to a port with <c>port_command/2</c>, not only the
port owner (the connected process).</p>
<p>For comparison: <c><anno>Port</anno> ! {PortOwner, {command, Data}}</c>
- fails with <c>badarg</c> if <c><anno>Port</anno></c> cannot be sent to
- (i.e., <c><anno>Port</anno></c> refers neither to a port nor to a process).
- If <c><anno>Port</anno></c> is a closed port the data message disappears
+ only fails with <c>badarg</c> if <c><anno>Port</anno></c>
+ does not refer to a port or a process. If
+ <c><anno>Port</anno></c> is a closed port, the data message
+ disappears
without a sound. If <c><anno>Port</anno></c> is open and the calling
process is not the port owner, the <em>port owner</em> fails
with <c>badsig</c>. The port owner fails with <c>badsig</c>
- also if <c><anno>Data</anno></c> is not a valid IO list.</p>
- <p>Note that any process can send to a port using
- <c><anno>Port</anno> ! {PortOwner, {command, <anno>Data</anno>}}</c> just as if it
- itself was the port owner.</p>
- <p>If the port is busy, the calling process will be suspended
- until the port is not busy anymore.</p>
- <p>As of OTP-R16 <c><anno>Port</anno> ! {PortOwner, {command, Data}}</c> is
- truly asynchronous. Note that this operation has always been
+ also if <c><anno>Data</anno></c> is an invalid I/O list.</p>
+ <p>Notice that any process can send to a port using
+ <c><anno>Port</anno> ! {PortOwner, {command, <anno>Data</anno>}}</c>
+ as if it itself was the port owner.</p>
+ <p>If the port is busy, the calling process is suspended
+ until the port is not busy any more.</p>
+ <p>As from OTP-R16, <c><anno>Port</anno> ! {PortOwner, {command, Data}}</c>
+ is truly asynchronous. Notice that this operation has always been
documented as an asynchronous operation, while the underlying
implementation has been synchronous. <c>port_command/2</c> is
- however still fully synchronous. This due to its error
+ however still fully synchronous. This because of its error
behavior.</p>
<p>Failures:</p>
<taglist>
<tag><c>badarg</c></tag>
<item>
If <c><anno>Port</anno></c> is not an identifier of an open
- port, or the registered name of an open port. If the calling
- process was linked to the previously open port identified by
- <c><anno>Port</anno></c>, an exit signal due to this link
- was received by the process prior to this exception.
+ port, or the registered name of an open port. If the
+ calling process was previously linked to the closed port,
+ identified by <c><anno>Port</anno></c>, the exit signal
+ from the port is guaranteed to be delivered before this
+ <c>badarg</c> exception occurs.
</item>
<tag><c>badarg</c></tag>
<item>
- If <c><anno>Data</anno></c> is not a valid io list.
+ If <c><anno>Data</anno></c> is an invalid I/O list.
</item>
</taglist>
</desc>
</func>
+
<func>
<name name="port_command" arity="3"/>
- <fsummary>Send data to a port</fsummary>
+ <fsummary>Sends data to a port.</fsummary>
<desc>
<p>Sends data to a port. <c>port_command(Port, Data, [])</c>
equals <c>port_command(Port, Data)</c>.</p>
- <p>If the port command is aborted <c>false</c> is returned;
- otherwise, <c>true</c> is returned.</p>
- <p>If the port is busy, the calling process will be suspended
- until the port is not busy anymore.</p>
- <p>Currently the following <c><anno>Option</anno></c>s are valid:</p>
+ <p>If the port command is aborted, <c>false</c> is returned,
+ otherwise <c>true</c>.</p>
+ <p>If the port is busy, the calling process is suspended
+ until the port is not busy any more.</p>
+ <p>The following <c><anno>Option</anno></c>s are valid:</p>
<taglist>
<tag><c>force</c></tag>
- <item>The calling process will not be suspended if the port is
- busy; instead, the port command is forced through. The
- call will fail with a <c>notsup</c> exception if the
+ <item>The calling process is not suspended if the port is
+ busy, instead the port command is forced through. The
+ call fails with a <c>notsup</c> exception if the
driver of the port does not support this. For more
- information see the
- <seealso marker="driver_entry#driver_flags"><![CDATA[ERL_DRV_FLAG_SOFT_BUSY]]></seealso>
- driver flag.
+ information, see driver flag
+ <seealso marker="driver_entry#driver_flags"><![CDATA[ERL_DRV_FLAG_SOFT_BUSY]]></seealso>.
</item>
<tag><c>nosuspend</c></tag>
- <item>The calling process will not be suspended if the port is
- busy; instead, the port command is aborted and
+ <item>The calling process is not suspended if the port is
+ busy, instead the port command is aborted and
<c>false</c> is returned.
</item>
</taglist>
<note>
- <p>More options may be added in the future.</p>
+ <p>More options can be added in a future release.</p>
</note>
<p>Failures:</p>
<taglist>
<tag><c>badarg</c></tag>
<item>
If <c><anno>Port</anno></c> is not an identifier of an open
- port, or the registered name of an open port. If the calling
- process was linked to the previously open port identified by
- <c><anno>Port</anno></c>, an exit signal due to this link
- was received by the process prior to this exception.
+ port, or the registered name of an open port. If the
+ calling process was previously linked to the closed port,
+ identified by <c><anno>Port</anno></c>, the exit signal
+ from the port is guaranteed to be delivered before this
+ <c>badarg</c> exception occurs.
</item>
<tag><c>badarg</c></tag>
<item>
- If <c><anno>Data</anno></c> is not a valid io list.
+ If <c><anno>Data</anno></c> is an invalid I/O list.
</item>
<tag><c>badarg</c></tag>
<item>
- If <c><anno>OptionList</anno></c> is not a valid option list.
+ If <c><anno>OptionList</anno></c> is an invalid option list.
</item>
<tag><c>notsup</c></tag>
<item>
- If the <c>force</c> option has been passed, but the
+ If option <c>force</c> has been passed, but the
driver of the port does not allow forcing through
a busy port.
</item>
</taglist>
</desc>
</func>
+
<func>
<name name="port_connect" arity="2"/>
- <fsummary>Set the owner of a port</fsummary>
+ <fsummary>Sets the owner of a port.</fsummary>
<desc>
<p>Sets the port owner (the connected port) to <c><anno>Pid</anno></c>.
- Roughly the same as <c><anno>Port</anno> ! {Owner, {connect, <anno>Pid</anno>}}</c>
+ Roughly the same as
+ <c><anno>Port</anno> ! {Owner, {connect, <anno>Pid</anno>}}</c>
except for the following:</p>
<list type="bulleted">
<item>
- <p>The error behavior differs, see below.</p>
+ <p>The error behavior differs, see the following.</p>
</item>
<item>
<p>The port does <em>not</em> reply with
<c>{Port,connected}</c>.</p>
</item>
<item>
- <p><c>port_connect/1</c> is synchronous, see below.</p>
+ <p><c>port_connect/1</c> is synchronous, see the following.</p>
</item>
<item>
<p>The new port owner gets linked to the port.</p>
</item>
</list>
- <p>The old port owner stays linked to the port and have to call
- <c>unlink(Port)</c> if this is not desired. Any process may
+ <p>The old port owner stays linked to the port and must call
+ <c>unlink(Port)</c> if this is not desired. Any process can
set the port owner to be any process with
<c>port_connect/2</c>.</p>
- <p>For comparison: <c><anno>Port</anno> ! {self(), {connect, <anno>Pid</anno>}}</c> fails
- with <c>badarg</c> if <c><anno>Port</anno></c> cannot be sent to (i.e.,
- <c><anno>Port</anno></c> refers neither to a port nor to a process). If
- <c><anno>Port</anno></c> is a closed port nothing happens. If <c><anno>Port</anno></c>
+ <p>For comparison:
+ <c><anno>Port</anno> ! {self(), {connect, <anno>Pid</anno>}}</c>
+ only fails with <c>badarg</c> if <c><anno>Port</anno></c>
+ does not refer to a port or a process. If
+ <c><anno>Port</anno></c> is a closed port, nothing happens.
+ If <c><anno>Port</anno></c>
is an open port and the calling process is the port owner,
the port replies with <c>{Port, connected}</c> to the old
- port owner. Note that the old port owner is still linked to
- the port, and that the new is not. If <c><anno>Port</anno></c> is an open
+ port owner. Notice that the old port owner is still linked to
+ the port, while the new is not. If <c><anno>Port</anno></c> is an open
port and the calling process is not the port owner,
the <em>port owner</em> fails with <c>badsig</c>. The port
owner fails with <c>badsig</c> also if <c><anno>Pid</anno></c> is not an
- existing local pid.</p>
- <p>Note that any process can set the port owner using
- <c><anno>Port</anno> ! {PortOwner, {connect, <anno>Pid</anno>}}</c> just as if it
- itself was the port owner, but the reply always goes to
+ existing local process identifier.</p>
+ <p>Notice that any process can set the port owner using
+ <c><anno>Port</anno> ! {PortOwner, {connect, <anno>Pid</anno>}}</c>
+ as if it itself was the port owner, but the reply always goes to
the port owner.</p>
- <p>As of OTP-R16 <c><anno>Port</anno> ! {PortOwner, {connect, <anno>Pid</anno>}}</c> is
- truly asynchronous. Note that this operation has always been
+ <p>As from OTP-R16,
+ <c><anno>Port</anno> ! {PortOwner, {connect, <anno>Pid</anno>}}</c> is
+ truly asynchronous. Notice that this operation has always been
documented as an asynchronous operation, while the underlying
implementation has been synchronous. <c>port_connect/2</c> is
- however still fully synchronous. This due to its error
+ however still fully synchronous. This because of its error
behavior.</p>
<p>Failures:</p>
<taglist>
<tag><c>badarg</c></tag>
<item>
- If <c><anno>Port</anno></c> is not an identifier of an open
- port, or the registered name of an open port. If the calling
- process was linked to the previously open port identified by
- <c><anno>Port</anno></c>, an exit signal due to this link
- was received by the process prior to this exception.
+ If <c><anno>Port</anno></c> is not an identifier of an open port, or
+ the registered name of an open port. If the calling
+ process was previously linked to the closed port,
+ identified by <c><anno>Port</anno></c>, the exit signal
+ from the port is guaranteed to be delivered before this
+ <c>badarg</c> exception occurs.
</item>
<tag><c>badarg</c></tag>
<item>If process identified by <c>Pid</c> is not an existing
@@ -3669,53 +3851,75 @@ os_prompt% </pre>
</taglist>
</desc>
</func>
+
<func>
<name name="port_control" arity="3"/>
- <fsummary>Perform a synchronous control operation on a port</fsummary>
+ <fsummary>Performs a synchronous control operation on a port.</fsummary>
<desc>
<p>Performs a synchronous control operation on a port.
- The meaning of <c><anno>Operation</anno></c> and <c><anno>Data</anno></c> depends on
- the port, i.e., on the port driver. Not all port drivers
+ The meaning of <c><anno>Operation</anno></c> and
+ <c><anno>Data</anno></c> depends on
+ the port, that is, on the port driver. Not all port drivers
support this control feature.</p>
- <p>Returns: a list of integers in the range 0 through 255, or a
+ <p>Returns a list of integers in the range 0..255, or a
binary, depending on the port driver. The meaning of
the returned data also depends on the port driver.</p>
- <p>Failure: <c>badarg</c> if <c><anno>Port</anno></c> is not an open port or
- the registered name of an open port, if <c><anno>Operation</anno></c>
- cannot fit in a 32-bit integer, if the port driver does not
- support synchronous control operations, or if the port driver
- so decides for any reason (probably something wrong with
- <c><anno>Operation</anno></c> or <c><anno>Data</anno></c>).</p>
+ <p>Failures:</p>
+ <taglist>
+ <tag><c>badarg</c></tag>
+ <item>
+ If <c><anno>Port</anno></c> is not an open port or the registered
+ name of an open port.
+ </item>
+ <tag><c>badarg</c></tag>
+ <item>
+ If <c><anno>Operation</anno></c> cannot fit in a 32-bit integer.
+ </item>
+ <tag><c>badarg</c></tag>
+ <item>
+ If the port driver does not support synchronous control
+ operations.
+ </item>
+ <tag><c>badarg</c></tag>
+ <item>
+ If the port driver so decides for any reason (probably
+ something wrong with <c><anno>Operation</anno></c> or
+ <c><anno>Data</anno></c>).
+ </item>
+ </taglist>
</desc>
</func>
+
<func>
<name name="port_call" arity="3"/>
- <fsummary>Synchronous call to a port with term data</fsummary>
+ <fsummary>Performs a synchronous call to a port with term data.</fsummary>
<desc>
<p>Performs a synchronous call to a port. The meaning of
- <c><anno>Operation</anno></c> and <c><anno>Data</anno></c> depends on the port, i.e.,
+ <c><anno>Operation</anno></c> and <c><anno>Data</anno></c>
+ depends on the port, that is,
on the port driver. Not all port drivers support this feature.</p>
- <p><c><anno>Port</anno></c> is a port identifier, referring to a driver.</p>
+ <p><c><anno>Port</anno></c> is a port identifier,
+ referring to a driver.</p>
<p><c><anno>Operation</anno></c> is an integer, which is passed on to
the driver.</p>
- <p><c><anno>Data</anno></c> is any Erlang term. This data is converted to
- binary term format and sent to the port.</p>
- <p>Returns: a term from the driver. The meaning of the returned
+ <p><c><anno>Data</anno></c> is any Erlang term. This data is converted
+ to binary term format and sent to the port.</p>
+ <p>Returns a term from the driver. The meaning of the returned
data also depends on the port driver.</p>
<p>Failures:</p>
<taglist>
<tag><c>badarg</c></tag>
<item>
- If <c><anno>Port</anno></c> is not an identifier of an open
- port, or the registered name of an open port. If the calling
- process was linked to the previously open port identified by
- <c><anno>Port</anno></c>, an exit signal due to this link
- was received by the process prior to this exception.
+ If <c><anno>Port</anno></c> is not an identifier of an open port,
+ or the registered name of an open port. If the calling
+ process was previously linked to the closed port,
+ identified by <c><anno>Port</anno></c>, the exit signal
+ from the port is guaranteed to be delivered before this
+ <c>badarg</c> exception occurs.
</item>
<tag><c>badarg</c></tag>
<item>
- If <c><anno>Operation</anno></c> does not fit in a
- 32-bit integer.
+ If <c><anno>Operation</anno></c> does not fit in a 32-bit integer.
</item>
<tag><c>badarg</c></tag>
<item>
@@ -3725,171 +3929,183 @@ os_prompt% </pre>
<tag><c>badarg</c></tag>
<item>
If the port driver so decides for any reason (probably
- something wrong with <c><anno>Operation</anno></c>, or
- <c><anno>Data</anno></c>).
+ something wrong with <c><anno>Operation</anno></c>
+ or <c><anno>Data</anno></c>).
</item>
</taglist>
</desc>
</func>
+
<func>
<name name="port_info" arity="1"/>
- <fsummary>Information about a port</fsummary>
+ <fsummary>Information about a port.</fsummary>
<desc>
<p>Returns a list containing tuples with information about
- the <c><anno>Port</anno></c>, or <c>undefined</c> if the port is not open.
- The order of the tuples is not defined, nor are all the
- tuples mandatory.
- If <c>undefined</c> is returned and the calling process
- was linked to a previously open port identified by
- <c><anno>Port</anno></c>, an exit signal due to this link
- was received by the process prior to the return from
- <c>port_info/1</c>.</p>
- <p>Currently the result will containt information about the
- following <c>Item</c>s: <c>registered_name</c> (if the port has
- a registered name), <c>id</c>, <c>connected</c>, <c>links</c>,
- <c>name</c>, <c>input</c>, and <c>output</c>. For more information
- about the different <c>Item</c>s, see
+ <c><anno>Port</anno></c>, or <c>undefined</c> if the port is not open.
+ The order of the tuples is undefined, and all the
+ tuples are not mandatory.
+ If the port is closed and the calling process
+ was previously linked to the port, the exit signal from the
+ port is guaranteed to be delivered before <c>port_info/1</c>
+ returns <c>undefined</c>.</p>
+ <p>The result contains information about the following
+ <c>Item</c>s:</p>
+ <list type="bulleted">
+ <item><c>registered_name</c> (if the port has a registered
+ name)</item>
+ <item><c>id</c></item>
+ <item><c>connected</c></item>
+ <item><c>links</c></item>
+ <item><c>name</c></item>
+ <item><c>input</c></item>
+ <item><c>output</c></item>
+ </list>
+ <p>For more information about the different <c>Item</c>s, see
<seealso marker="#port_info/2">port_info/2</seealso>.</p>
<p>Failure: <c>badarg</c> if <c>Port</c> is not a local port
identifier, or an atom.</p>
</desc>
</func>
+
<func>
<name name="port_info" arity="2" clause_i="1"/>
- <fsummary>Information about the connected process of a port</fsummary>
+ <fsummary>Information about the connected process of a port.</fsummary>
<desc>
<p><c><anno>Pid</anno></c> is the process identifier of the process
connected to the port.</p>
<p>If the port identified by <c><anno>Port</anno></c> is not open,
- <c>undefined</c> is returned. If <c>undefined</c> is returned and
- the calling process was linked to a previously open port identified
- by <c><anno>Port</anno></c>, an exit signal due to this link
- was received by the process prior to the return from
- <c>port_info/2</c>.</p>
+ <c>undefined</c> is returned. If the port is closed and the
+ calling process was previously linked to the port, the exit
+ signal from the port is guaranteed to be delivered before
+ <c>port_info/2</c> returns <c>undefined</c>.</p>
<p>Failure: <c>badarg</c> if <c><anno>Port</anno></c> is not a local
port identifier, or an atom.</p>
</desc>
</func>
+
<func>
<name name="port_info" arity="2" clause_i="2"/>
- <fsummary>Information about the internal index of a port</fsummary>
+ <fsummary>Information about the internal index of a port.</fsummary>
<desc>
<p><c><anno>Index</anno></c> is the internal index of the port. This
- index may be used to separate ports.</p>
+ index can be used to separate ports.</p>
<p>If the port identified by <c><anno>Port</anno></c> is not open,
- <c>undefined</c> is returned. If <c>undefined</c> is returned and
- the calling process was linked to a previously open port identified
- by <c><anno>Port</anno></c>, an exit signal due to this link
- was received by the process prior to the return from
- <c>port_info/2</c>.</p>
+ <c>undefined</c> is returned. If the port is closed and the
+ calling process was previously linked to the port, the exit
+ signal from the port is guaranteed to be delivered before
+ <c>port_info/2</c> returns <c>undefined</c>.</p>
<p>Failure: <c>badarg</c> if <c><anno>Port</anno></c> is not a local
port identifier, or an atom.</p>
</desc>
</func>
+
<func>
<name name="port_info" arity="2" clause_i="3"/>
- <fsummary>Information about the input of a port</fsummary>
+ <fsummary>Information about the input of a port.</fsummary>
<desc>
<p><c><anno>Bytes</anno></c> is the total number of bytes
read from the port.</p>
<p>If the port identified by <c><anno>Port</anno></c> is not open,
- <c>undefined</c> is returned. If <c>undefined</c> is returned and
- the calling process was linked to a previously open port identified
- by <c><anno>Port</anno></c>, an exit signal due to this link
- was received by the process prior to the return from
- <c>port_info/2</c>.</p>
+ <c>undefined</c> is returned. If the port is closed and the
+ calling process was previously linked to the port, the exit
+ signal from the port is guaranteed to be delivered before
+ <c>port_info/2</c> returns <c>undefined</c>.</p>
<p>Failure: <c>badarg</c> if <c><anno>Port</anno></c> is not a local
port identifier, or an atom.</p>
</desc>
</func>
+
<func>
<name name="port_info" arity="2" clause_i="4"/>
- <fsummary>Information about the links of a port</fsummary>
+ <fsummary>Information about the links of a port.</fsummary>
<desc>
<p><c><anno>Pids</anno></c> is a list of the process identifiers
of the processes that the port is linked to.</p>
<p>If the port identified by <c><anno>Port</anno></c> is not open,
- <c>undefined</c> is returned. If <c>undefined</c> is returned and
- the calling process was linked to a previously open port identified
- by <c><anno>Port</anno></c>, an exit signal due to this link
- was received by the process prior to the return from
- <c>port_info/2</c>.</p>
+ <c>undefined</c> is returned. If the port is closed and the
+ calling process was previously linked to the port, the exit
+ signal from the port is guaranteed to be delivered before
+ <c>port_info/2</c> returns <c>undefined</c>.</p>
<p>Failure: <c>badarg</c> if <c><anno>Port</anno></c> is not a local
port identifier, or an atom.</p>
</desc>
</func>
+
<func>
<name name="port_info" arity="2" clause_i="5"/>
- <fsummary>Information about the locking of a port</fsummary>
+ <fsummary>Information about the locking of a port.</fsummary>
<desc>
- <p><c><anno>Locking</anno></c> is currently either <c>false</c>
- (emulator without SMP support), <c>port_level</c> (port specific
- locking), or <c>driver_level</c> (driver specific locking). Note
- that these results are highly implementation specific and might
- change in the future.</p>
+ <p><c><anno>Locking</anno></c> is one of the following:</p>
+ <list type="bulleted">
+ <item><c>false</c> (emulator without SMP support)</item>
+ <item><c>port_level</c> (port-specific locking)</item>
+ <item><c>driver_level</c> (driver-specific locking)</item>
+ </list>
+ <p>Notice that these results are highly implementation-specific
+ and can change in a future release.</p>
<p>If the port identified by <c><anno>Port</anno></c> is not open,
- <c>undefined</c> is returned. If <c>undefined</c> is returned and
- the calling process was linked to a previously open port identified
- by <c><anno>Port</anno></c>, an exit signal due to this link
- was received by the process prior to the return from
- <c>port_info/2</c>.</p>
+ <c>undefined</c> is returned. If the port is closed and the
+ calling process was previously linked to the port, the exit
+ signal from the port is guaranteed to be delivered before
+ <c>port_info/2</c> returns <c>undefined</c>.</p>
<p>Failure: <c>badarg</c> if <c><anno>Port</anno></c> is not a local
port identifier, or an atom.</p>
</desc>
</func>
+
<func>
<name name="port_info" arity="2" clause_i="6"/>
- <fsummary>Information about the memory size of a port</fsummary>
+ <fsummary>Information about the memory size of a port.</fsummary>
<desc>
- <p><c><anno>Bytes</anno></c> is the total amount of memory,
- in bytes, allocated for this port by the runtime system. Note
- that the port itself might have allocated memory which is not
+ <p><c><anno>Bytes</anno></c> is the total number of
+ bytes allocated for this port by the runtime system. The
+ port itself can have allocated memory that is not
included in <c><anno>Bytes</anno></c>.</p>
<p>If the port identified by <c><anno>Port</anno></c> is not open,
- <c>undefined</c> is returned. If <c>undefined</c> is returned and
- the calling process was linked to a previously open port identified
- by <c><anno>Port</anno></c>, an exit signal due to this link
- was received by the process prior to the return from
- <c>port_info/2</c>.</p>
+ <c>undefined</c> is returned. If the port is closed and the
+ calling process was previously linked to the port, the exit
+ signal from the port is guaranteed to be delivered before
+ <c>port_info/2</c> returns <c>undefined</c>.</p>
<p>Failure: <c>badarg</c> if <c><anno>Port</anno></c> is not a local
port identifier, or an atom.</p>
</desc>
</func>
+
<func>
<name name="port_info" arity="2" clause_i="7"/>
- <fsummary>Information about the monitors of a port</fsummary>
+ <fsummary>Information about the monitors of a port.</fsummary>
<desc>
<p><c><anno>Monitors</anno></c> represent processes that this port
- is monitoring.</p>
+ monitors.</p>
<p>If the port identified by <c><anno>Port</anno></c> is not open,
- <c>undefined</c> is returned. If <c>undefined</c> is returned and
- the calling process was linked to a previously open port identified
- by <c><anno>Port</anno></c>, an exit signal due to this link
- was received by the process prior to the return from
- <c>port_info/2</c>.</p>
+ <c>undefined</c> is returned. If the port is closed and the
+ calling process was previously linked to the port, the exit
+ signal from the port is guaranteed to be delivered before
+ <c>port_info/2</c> returns <c>undefined</c>.</p>
<p>Failure: <c>badarg</c> if <c><anno>Port</anno></c> is not a local
port identifier, or an atom.</p>
</desc>
</func>
+
<func>
<name name="port_info" arity="2" clause_i="8"/>
- <fsummary>Information about the name of a port</fsummary>
+ <fsummary>Information about the name of a port.</fsummary>
<desc>
<p><c><anno>Name</anno></c> is the command name set by
<seealso marker="#open_port/2">open_port/2</seealso>.</p>
<p>If the port identified by <c><anno>Port</anno></c> is not open,
- <c>undefined</c> is returned. If <c>undefined</c> is returned and
- the calling process was linked to a previously open port identified
- by <c><anno>Port</anno></c>, an exit signal due to this link
- was received by the process prior to the return from
- <c>port_info/2</c>.</p>
+ <c>undefined</c> is returned. If the port is closed and the
+ calling process was previously linked to the port, the exit
+ signal from the port is guaranteed to be delivered before
+ <c>port_info/2</c> returns <c>undefined</c>.</p>
<p>Failure: <c>badarg</c> if <c><anno>Port</anno></c> is not a local
port identifier, or an atom.</p>
</desc>
</func>
+
<func>
<name name="port_info" arity="2" clause_i="9"/>
- <fsummary>Information about the OS pid of a port</fsummary>
+ <fsummary>Information about the OS pid of a port.</fsummary>
<desc>
<p><c><anno>OsPid</anno></c> is the process identifier (or equivalent)
of an OS process created with
@@ -3897,432 +4113,464 @@ os_prompt% </pre>
Command}, Options)</seealso>. If the port is not the result of spawning
an OS process, the value is <c>undefined</c>.</p>
<p>If the port identified by <c><anno>Port</anno></c> is not open,
- <c>undefined</c> is returned. If <c>undefined</c> is returned and
- the calling process was linked to a previously open port identified
- by <c><anno>Port</anno></c>, an exit signal due to this link
- was received by the process prior to the return from
- <c>port_info/2</c>.</p>
+ <c>undefined</c> is returned. If the port is closed and the
+ calling process was previously linked to the port, the exit
+ signal from the port is guaranteed to be delivered before
+ <c>port_info/2</c> returns <c>undefined</c>.</p>
<p>Failure: <c>badarg</c> if <c><anno>Port</anno></c> is not a local
port identifier, or an atom.</p>
</desc>
</func>
+
<func>
<name name="port_info" arity="2" clause_i="10"/>
- <fsummary>Information about the output of a port</fsummary>
+ <fsummary>Information about the output of a port.</fsummary>
<desc>
<p><c><anno>Bytes</anno></c> is the total number of bytes written
- to the port from Erlang processes using either
+ to the port from Erlang processes using
<seealso marker="#port_command/2">port_command/2</seealso>,
<seealso marker="#port_command/3">port_command/3</seealso>,
- or <c><anno>Port</anno> ! {Owner, {command, Data}</c>.
- </p>
+ or <c><anno>Port</anno> ! {Owner, {command, Data}</c>.</p>
<p>If the port identified by <c><anno>Port</anno></c> is not open,
- <c>undefined</c> is returned. If <c>undefined</c> is returned and
- the calling process was linked to a previously open port identified
- by <c><anno>Port</anno></c>, an exit signal due to this link
- was received by the process prior to the return from
- <c>port_info/2</c>.</p>
+ <c>undefined</c> is returned. If the port is closed and the
+ calling process was previously linked to the port, the exit
+ signal from the port is guaranteed to be delivered before
+ <c>port_info/2</c> returns <c>undefined</c>.</p>
<p>Failure: <c>badarg</c> if <c><anno>Port</anno></c> is not a local
port identifier, or an atom.</p>
</desc>
</func>
+
<func>
<name name="port_info" arity="2" clause_i="11"/>
- <fsummary>Information about the parallelism hint of a port</fsummary>
+ <fsummary>Information about the parallelism hint of a port.</fsummary>
<desc>
<p><c><anno>Boolean</anno></c> corresponds to the port parallelism
- hint being used by this port. For more information see
- the <seealso marker="#open_port_parallelism">parallelism</seealso>
- option of <seealso marker="#open_port/2">open_port/2</seealso>.</p>
+ hint being used by this port. For more information, see option
+ <seealso marker="#open_port_parallelism">parallelism</seealso>
+ of <seealso marker="#open_port/2">open_port/2</seealso>.</p>
</desc>
</func>
+
<func>
<name name="port_info" arity="2" clause_i="12"/>
- <fsummary>Information about the queue size of a port</fsummary>
+ <fsummary>Information about the queue size of a port.</fsummary>
<desc>
- <p><c><anno>Bytes</anno></c> is the total amount of data,
- in bytes, queued by the port using the ERTS driver queue
+ <p><c><anno>Bytes</anno></c> is the total number
+ of bytes queued by the port using the <c>ERTS</c> driver queue
implementation.</p>
<p>If the port identified by <c><anno>Port</anno></c> is not open,
- <c>undefined</c> is returned. If <c>undefined</c> is returned and
- the calling process was linked to a previously open port identified
- by <c><anno>Port</anno></c>, an exit signal due to this link
- was received by the process prior to the return from
- <c>port_info/2</c>.</p>
+ <c>undefined</c> is returned. If the port is closed and the
+ calling process was previously linked to the port, the exit
+ signal from the port is guaranteed to be delivered before
+ <c>port_info/2</c> returns <c>undefined</c>.</p>
<p>Failure: <c>badarg</c> if <c><anno>Port</anno></c> is not a local
port identifier, or an atom.</p>
</desc>
</func>
+
<func>
<name name="port_info" arity="2" clause_i="13"/>
- <fsummary>Information about the registered name of a port</fsummary>
+ <fsummary>Information about the registered name of a port.</fsummary>
<desc>
<p><c><anno>RegisteredName</anno></c> is the registered name of
the port. If the port has no registered name, <c>[]</c> is returned.</p>
<p>If the port identified by <c><anno>Port</anno></c> is not open,
- <c>undefined</c> is returned. If <c>undefined</c> is returned and
- the calling process was linked to a previously open port identified
- by <c><anno>Port</anno></c>, an exit signal due to this link
- was received by the process prior to the return from
- <c>port_info/2</c>.</p>
+ <c>undefined</c> is returned. If the port is closed and the
+ calling process was previously linked to the port, the exit
+ signal from the port is guaranteed to be delivered before
+ <c>port_info/2</c> returns <c>undefined</c>.</p>
<p>Failure: <c>badarg</c> if <c><anno>Port</anno></c> is not a local
port identifier, or an atom.</p>
</desc>
</func>
+
<func>
<name name="port_to_list" arity="1"/>
- <fsummary>Text representation of a port identifier</fsummary>
+ <fsummary>Text representation of a port identifier.</fsummary>
<desc>
- <p>Returns a string which corresponds to the text
+ <p>Returns a string corresponding to the text
representation of the port identifier <c><anno>Port</anno></c>.</p>
<warning>
- <p>This BIF is intended for debugging and for use in
- the Erlang operating system. It should not be used in
- application programs.</p>
+ <p>This BIF is intended for debugging. It is not to be used
+ in application programs.</p>
</warning>
</desc>
</func>
+
<func>
<name name="ports" arity="0"/>
- <fsummary>All open ports</fsummary>
+ <fsummary>Lists all existing ports.</fsummary>
<desc>
<p>Returns a list of port identifiers corresponding to all the
- ports currently existing on the local node.</p>
-
- <p>Note that a port that is exiting, exists but is not open.</p>
+ ports existing on the local node.</p>
+ <p>Notice that an exiting port exists, but is not open.</p>
</desc>
</func>
+
<func>
<name name="pre_loaded" arity="0"/>
- <fsummary>List of all pre-loaded modules</fsummary>
+ <fsummary>Lists all pre-loaded modules.</fsummary>
<desc>
- <p>Returns a list of Erlang modules which are pre-loaded in
+ <p>Returns a list of Erlang modules that are preloaded in
the system. As all loading of code is done through the file
system, the file system must have been loaded previously.
- Hence, at least the module <c>init</c> must be pre-loaded.</p>
+ Hence, at least the module <c>init</c> must be preloaded.</p>
</desc>
</func>
+
<func>
<name name="process_display" arity="2"/>
- <fsummary>Write information about a local process on standard error</fsummary>
+ <fsummary>Writes information about a local process on standard error.</fsummary>
<desc>
<p>Writes information about the local process <c><anno>Pid</anno></c> on
- standard error. The currently allowed value for the atom
+ standard error. The only allowed value for the atom
<c><anno>Type</anno></c> is <c>backtrace</c>, which shows the contents of
the call stack, including information about the call chain, with
the current function printed first. The format of the output
is not further defined.</p>
</desc>
</func>
+
<func>
<name name="process_flag" arity="2" clause_i="1"/>
- <fsummary>Set process flag trap_exit for the calling process</fsummary>
+ <fsummary>Sets process flag <c>trap_exit</c> for the calling process.</fsummary>
<desc>
<p>When <c>trap_exit</c> is set to <c>true</c>, exit signals
- arriving to a process are converted to <c>{'EXIT', From, Reason}</c> messages, which can be received as ordinary
+ arriving to a process are converted to <c>{'EXIT', From, Reason}</c>
+ messages, which can be received as ordinary
messages. If <c>trap_exit</c> is set to <c>false</c>, the
process exits if it receives an exit signal other than
<c>normal</c> and the exit signal is propagated to its
- linked processes. Application processes should normally
- not trap exits.</p>
+ linked processes. Application processes are normally
+ not to trap exits.</p>
<p>Returns the old value of the flag.</p>
<p>See also <seealso marker="#exit/2">exit/2</seealso>.</p>
</desc>
</func>
+
<func>
<name name="process_flag" arity="2" clause_i="2"/>
- <fsummary>Set process flag error_handler for the calling process</fsummary>
+ <fsummary>Sets process flag <c>error_handler</c> for the calling process.</fsummary>
<desc>
- <p>This is used by a process to redefine the error handler
+ <p>Used by a process to redefine the error handler
for undefined function calls and undefined registered
- processes. Inexperienced users should not use this flag
- since code auto-loading is dependent on the correct
+ processes. Inexperienced users are not to use this flag,
+ as code auto-loading depends on the correct
operation of the error handling module.</p>
<p>Returns the old value of the flag.</p>
</desc>
</func>
+
<func>
<name name="process_flag" arity="2" clause_i="3"/>
- <fsummary>Set process flag min_heap_size for the calling process</fsummary>
+ <fsummary>Sets process flag <c>min_heap_size</c> for the calling process.</fsummary>
<desc>
- <p>This changes the minimum heap size for the calling
- process.</p>
+ <p>Changes the minimum heap size for the calling process.</p>
<p>Returns the old value of the flag.</p>
</desc>
</func>
+
<func>
<name name="process_flag" arity="2" clause_i="4"/>
- <fsummary>Set process flag min_bin_vheap_size for the calling process</fsummary>
+ <fsummary>Sets process flag <c>min_bin_vheap_size</c> for the calling process.</fsummary>
<desc>
- <p>This changes the minimum binary virtual heap size for the calling
+ <p>Changes the minimum binary virtual heap size for the calling
process.</p>
- <p>Returns the old value of the flag.</p> </desc>
+ <p>Returns the old value of the flag.</p>
+ </desc>
</func>
+
<func>
<name name="process_flag" arity="2" clause_i="5"/>
+ <fsummary>Sets process flag <c>priority</c> for the calling process.</fsummary>
<type name="priority_level"/>
- <fsummary>Set process flag priority for the calling process</fsummary>
<desc>
<p><marker id="process_flag_priority"></marker>
- This sets the process priority. <c><anno>Level</anno></c> is an atom.
- There are currently four priority levels: <c>low</c>,
- <c>normal</c>, <c>high</c>, and <c>max</c>. The default
- priority level is <c>normal</c>. <em>NOTE</em>: The
- <c>max</c> priority level is reserved for internal use in
- the Erlang runtime system, and should <em>not</em> be used
- by others.
- </p>
- <p>Internally in each priority level processes are scheduled
- in a round robin fashion.
- </p>
+ Sets the process priority. <c><anno>Level</anno></c> is an atom.
+ There are four priority levels: <c>low</c>,
+ <c>normal</c>, <c>high</c>, and <c>max</c>. Default
+ is <c>normal</c>.</p>
+ <note>
+ <p>Priority level <c>max</c> is reserved for internal use in
+ the Erlang runtime system, and is <em>not</em> to be used
+ by others.</p>
+ </note>
+ <p>Internally in each priority level, processes are scheduled
+ in a round robin fashion.</p>
<p>Execution of processes on priority <c>normal</c> and
- priority <c>low</c> will be interleaved. Processes on
- priority <c>low</c> will be selected for execution less
- frequently than processes on priority <c>normal</c>.
- </p>
- <p>When there are runnable processes on priority <c>high</c>
- no processes on priority <c>low</c>, or <c>normal</c> will
- be selected for execution. Note, however, that this does
- <em>not</em> mean that no processes on priority <c>low</c>,
- or <c>normal</c> will be able to run when there are
- processes on priority <c>high</c> running. On the runtime
- system with SMP support there might be more processes running
- in parallel than processes on priority <c>high</c>, i.e.,
- a <c>low</c>, and a <c>high</c> priority process might
- execute at the same time.
- </p>
- <p>When there are runnable processes on priority <c>max</c>
+ <c>low</c> are interleaved. Processes on priority
+ <c>low</c> are selected for execution less
+ frequently than processes on priority <c>normal</c>.</p>
+ <p>When there are runnable processes on priority <c>high</c>,
+ no processes on priority <c>low</c> or <c>normal</c> are
+ selected for execution. Notice however, that this does
+ <em>not</em> mean that no processes on priority <c>low</c>
+ or <c>normal</c> can run when there are processes
+ running on priority <c>high</c>. On the runtime
+ system with SMP support, more processes can be running
+ in parallel than processes on priority <c>high</c>, that is,
+ a <c>low</c> and a <c>high</c> priority process can
+ execute at the same time.</p>
+ <p>When there are runnable processes on priority <c>max</c>,
no processes on priority <c>low</c>, <c>normal</c>, or
- <c>high</c> will be selected for execution. As with the
- <c>high</c> priority, processes on lower priorities might
- execute in parallel with processes on priority <c>max</c>.
- </p>
+ <c>high</c> are selected for execution. As with priority
+ <c>high</c>, processes on lower priorities can
+ execute in parallel with processes on priority <c>max</c>.</p>
<p>Scheduling is preemptive. Regardless of priority, a process
- is preempted when it has consumed more than a certain amount
+ is preempted when it has consumed more than a certain number
of reductions since the last time it was selected for
- execution.
- </p>
- <p><em>NOTE</em>: You should not depend on the scheduling
+ execution.</p>
+ <note>
+ <p>Do not depend on the scheduling
to remain exactly as it is today. Scheduling, at least on
- the runtime system with SMP support, is very likely to be
- modified in the future in order to better utilize available
- processor cores.
- </p>
- <p>There is currently <em>no</em> automatic mechanism for
- avoiding priority inversion, such as priority inheritance,
- or priority ceilings. When using priorities you have
- to take this into account and handle such scenarios by
- yourself.
- </p>
+ the runtime system with SMP support, is likely to be
+ changed in a future release to use available
+ processor cores better.</p>
+ </note>
+ <p>There is <em>no</em> automatic mechanism for
+ avoiding priority inversion, such as priority inheritance
+ or priority ceilings. When using priorities,
+ take this into account and handle such scenarios by
+ yourself.</p>
<p>Making calls from a <c>high</c> priority process into code
- that you don't have control over may cause the <c>high</c>
- priority process to wait for a processes with lower
- priority, i.e., effectively decreasing the priority of the
+ that you have no control over can cause the <c>high</c>
+ priority process to wait for a process with lower
+ priority. That is, effectively decreasing the priority of the
<c>high</c> priority process during the call. Even if this
- isn't the case with one version of the code that you don't
- have under your control, it might be the case in a future
- version of it. This might, for example, happen if a
- <c>high</c> priority process triggers code loading, since
- the code server runs on priority <c>normal</c>.
- </p>
+ is not the case with one version of the code that you have no
+ control over, it can be the case in a future
+ version of it. This can, for example, occur if a
+ <c>high</c> priority process triggers code loading, as
+ the code server runs on priority <c>normal</c>.</p>
<p>Other priorities than <c>normal</c> are normally not needed.
- When other priorities are used, they need to be used
- with care, especially the <c>high</c> priority <em>must</em>
- be used with care. A process on <c>high</c> priority should
- only perform work for short periods of time. Busy looping for
- long periods of time in a <c>high</c> priority process will
- most likely cause problems, since there are important servers
- in OTP running on priority <c>normal</c>.
- </p>
+ When other priorities are used, use them with care,
+ <em>especially</em> priority <c>high</c>. A
+ process on priority <c>high</c> is only
+ to perform work for short periods. Busy looping for
+ long periods in a <c>high</c> priority process does
+ most likely cause problems, as important OTP servers
+ run on priority <c>normal</c>.</p>
<p>Returns the old value of the flag.</p>
</desc>
</func>
+
<func>
<name name="process_flag" arity="2" clause_i="6"/>
- <fsummary>Set process flag save_calls for the calling process</fsummary>
+ <fsummary>Sets process flag <c>save_calls</c> for the calling process.</fsummary>
<desc>
<p><c><anno>N</anno></c> must be an integer in the interval 0..10000.
- If <c><anno>N</anno></c> &gt; 0, call saving is made active for the
- process, which means that information about the <c><anno>N</anno></c>
- most recent global function calls, BIF calls, sends and
+ If <c><anno>N</anno></c> is greater than 0, call saving is made
+ active for the
+ process. This means that information about the <c><anno>N</anno></c>
+ most recent global function calls, BIF calls, sends, and
receives made by the process are saved in a list, which
can be retrieved with
<c>process_info(Pid, last_calls)</c>. A global function
call is one in which the module of the function is
explicitly mentioned. Only a fixed amount of information
- is saved: a tuple <c>{Module, Function, Arity}</c> for
- function calls, and the mere atoms <c>send</c>,
- <c>'receive'</c> and <c>timeout</c> for sends and receives
- (<c>'receive'</c> when a message is received and
- <c>timeout</c> when a receive times out). If <c>N</c> = 0,
+ is saved, as follows:</p>
+ <list type="bulleted">
+ <item>A tuple <c>{Module, Function, Arity}</c> for
+ function calls</item>
+ <item> The atoms <c>send</c>, <c>'receive'</c>, and
+ <c>timeout</c> for sends and receives (<c>'receive'</c>
+ when a message is received and <c>timeout</c> when a
+ receive times out)</item>
+ </list>
+ <p>If <c>N</c> = 0,
call saving is disabled for the process, which is the
default. Whenever the size of the call saving list is set,
its contents are reset.</p>
<p>Returns the old value of the flag.</p>
</desc>
</func>
+
<func>
<name name="process_flag" arity="2" clause_i="7"/>
- <fsummary>Set process flag sensitive for the calling process</fsummary>
+ <fsummary>Sets process flag <c>sensitive</c> for the calling process.</fsummary>
<desc>
- <p>Set or clear the <c>sensitive</c> flag for the current process.
+ <p>Sets or clears flag <c>sensitive</c> for the current process.
When a process has been marked as sensitive by calling
- <c>process_flag(sensitive, true)</c>, features in the run-time
- system that can be used for examining the data and/or inner working
+ <c>process_flag(sensitive, true)</c>, features in the runtime
+ system that can be used for examining the data or inner working
of the process are silently disabled.</p>
<p>Features that are disabled include (but are not limited to)
the following:</p>
- <p>Tracing: Trace flags can still be set for the process, but no
- trace messages of any kind will be generated.
- (If the <c>sensitive</c> flag is turned off, trace messages will
- again be generated if there are any trace flags set.)</p>
- <p>Sequential tracing: The sequential trace token will be propagated
- as usual, but no sequential trace messages will be generated.</p>
- <p><c>process_info/1,2</c> cannot be used to read out the message
- queue or the process dictionary (both will be returned as empty lists).</p>
+ <list type="bulleted">
+ <item>Tracing: Trace flags can still be set for the process,
+ but no trace messages of any kind are generated. (If flag
+ <c>sensitive</c> is turned off, trace messages are again
+ generated if any trace flags are set.)</item>
+ <item>Sequential tracing: The sequential trace token is
+ propagated as usual, but no sequential trace messages are
+ generated.</item>
+ </list>
+ <p><c>process_info/1,2</c> cannot be used to read out the
+ message queue or the process dictionary (both are returned
+ as empty lists).</p>
<p>Stack back-traces cannot be displayed for the process.</p>
<p>In crash dumps, the stack, messages, and the process dictionary
- will be omitted.</p>
+ are omitted.</p>
<p>If <c>{save_calls,N}</c> has been set for the process, no
- function calls will be saved to the call saving list.
- (The call saving list will not be cleared; furthermore, send, receive,
- and timeout events will still be added to the list.)</p>
+ function calls are saved to the call saving list.
+ (The call saving list is not cleared. Furthermore, send, receive,
+ and timeout events are still added to the list.)</p>
<p>Returns the old value of the flag.</p>
</desc>
</func>
+
<func>
<name name="process_flag" arity="3"/>
- <fsummary>Set process flags for a process</fsummary>
+ <fsummary>Sets process flags for a process.</fsummary>
<desc>
- <p>Sets certain flags for the process <c><anno>Pid</anno></c>, in the same
- manner as
+ <p>Sets certain flags for the process <c><anno>Pid</anno></c>,
+ in the same manner as
<seealso marker="#process_flag/2">process_flag/2</seealso>.
- Returns the old value of the flag. The allowed values for
+ Returns the old value of the flag. The valid values for
<c><anno>Flag</anno></c> are only a subset of those allowed in
- <c>process_flag/2</c>, namely: <c>save_calls</c>.</p>
- <p>Failure: <c>badarg</c> if <c><anno>Pid</anno></c> is not a local process.</p>
+ <c>process_flag/2</c>, namely <c>save_calls</c>.</p>
+ <p>Failure: <c>badarg</c> if <c><anno>Pid</anno></c>
+ is not a local process.</p>
</desc>
</func>
+
<func>
<name name="process_info" arity="1"/>
+ <fsummary>Information about a process.</fsummary>
<type name="process_info_result_item"/>
<type name="priority_level"/>
<type name="stack_item"/>
- <fsummary>Information about a process</fsummary>
<desc>
<p>Returns a list containing <c><anno>InfoTuple</anno></c>s with
miscellaneous information about the process identified by
- <c>Pid</c>, or <c>undefined</c> if the process is not alive.
- </p>
- <p>
- The order of the <c><anno>InfoTuple</anno></c>s is not defined, nor
- are all the <c><anno>InfoTuple</anno></c>s mandatory. The <c><anno>InfoTuple</anno></c>s
- part of the result may be changed without prior notice.
- Currently <c><anno>InfoTuple</anno></c>s with the following items
- are part of the result:
- <c>current_function</c>, <c>initial_call</c>, <c>status</c>,
- <c>message_queue_len</c>, <c>messages</c>, <c>links</c>,
- <c>dictionary</c>, <c>trap_exit</c>, <c>error_handler</c>,
- <c>priority</c>, <c>group_leader</c>, <c>total_heap_size</c>,
- <c>heap_size</c>, <c>stack_size</c>, <c>reductions</c>, and
- <c>garbage_collection</c>.
- If the process identified by <c><anno>Pid</anno></c> has a registered name
- also an <c><anno>InfoTuple</anno></c> with the item <c>registered_name</c>
- will appear.
- </p>
- <p>See <seealso marker="#process_info/2">process_info/2</seealso>
- for information about specific <c><anno>InfoTuple</anno></c>s.</p>
+ <c>Pid</c>, or <c>undefined</c> if the process is not alive.</p>
+ <p>The order of the <c><anno>InfoTuple</anno></c>s is undefined and
+ all <c><anno>InfoTuple</anno></c>s are not mandatory.
+ The <c><anno>InfoTuple</anno></c>s
+ part of the result can be changed without prior notice.</p>
+ <p>The <c><anno>InfoTuple</anno></c>s with the following items
+ are part of the result:</p>
+ <list type="bulleted">
+ <item><c>current_function</c></item>
+ <item><c>initial_call</c></item>
+ <item><c>status</c></item>
+ <item><c>message_queue_len</c></item>
+ <item><c>messages</c></item>
+ <item><c>links</c></item>
+ <item><c>dictionary</c></item>
+ <item><c>trap_exit</c></item>
+ <item><c>error_handler</c></item>
+ <item><c>priority</c></item>
+ <item><c>group_leader</c></item>
+ <item><c>total_heap_size</c></item>
+ <item><c>heap_size</c></item>
+ <item><c>stack_size</c></item>
+ <item><c>reductions</c></item>
+ <item><c>garbage_collection</c></item>
+ </list>
+ <p>If the process identified by <c><anno>Pid</anno></c> has a
+ registered name,
+ also an <c><anno>InfoTuple</anno></c> with item <c>registered_name</c>
+ appears.</p>
+ <p>For information about specific <c><anno>InfoTuple</anno></c>s, see
+ <seealso marker="#process_info/2">process_info/2</seealso>.</p>
<warning>
- <p>This BIF is intended for <em>debugging only</em>, use
- <seealso marker="#process_info/2">process_info/2</seealso>
- for all other purposes.
- </p>
+ <p>This BIF is intended for <em>debugging only</em>. For
+ all other purposes, use
+ <seealso marker="#process_info/2">process_info/2</seealso>.</p>
</warning>
- <p>Failure: <c>badarg</c> if <c>Pid</c> is not a local process.</p>
+ <p>Failure: <c>badarg</c> if <c><anno>Pid</anno></c> is not a
+ local process.</p>
</desc>
</func>
+
<func>
<name name="process_info" arity="2" clause_i="1"/>
<name name="process_info" arity="2" clause_i="2"/>
+ <fsummary>Information about a process.</fsummary>
<type name="process_info_item"/>
<type name="process_info_result_item"/>
<type name="stack_item"/>
<type name="priority_level"/>
- <fsummary>Information about a process</fsummary>
<desc>
- <p>Returns information about the process identified by <c><anno>Pid</anno></c>
- as specified by the <c><anno>Item</anno></c> or the <c><anno>ItemList</anno></c>, or <c>undefined</c> if the
- process is not alive.
- </p>
- <p>If the process is alive and a single <c><anno>Item</anno></c> is given,
- the returned value is the corresponding
- <c><anno>InfoTuple</anno></c> unless <c>Item =:= registered_name</c>
- and the process has no registered name. In this case
- <c>[]</c> is returned. This strange behavior is due to
- historical reasons, and is kept for backward compatibility.
- </p>
- <p>If an <c>ItemList</c> is given, the result is an
- <c><anno>InfoTupleList</anno></c>. The <c><anno>InfoTuple</anno></c>s in the
- <c><anno>InfoTupleList</anno></c> will appear with the corresponding
- <c><anno>Item</anno></c>s in the same order as the <c><anno>Item</anno></c>s appeared
- in the <c><anno>ItemList</anno></c>. Valid <c><anno>Item</anno></c>s may appear multiple
- times in the <c><anno>ItemList</anno></c>.
- </p>
- <note><p>If <c>registered_name</c> is part of an <c><anno>ItemList</anno></c>
+ <p>Returns information about the process identified by
+ <c><anno>Pid</anno></c>, as specified by
+ <c><anno>Item</anno></c> or <c><anno>ItemList</anno></c>.
+ Returns <c>undefined</c> if the process is not alive.</p>
+ <p>If the process is alive and a single <c><anno>Item</anno></c>
+ is given, the returned value is the corresponding
+ <c><anno>InfoTuple</anno></c>, unless <c>Item =:= registered_name</c>
+ and the process has no registered name. In this case,
+ <c>[]</c> is returned. This strange behavior is because of
+ historical reasons, and is kept for backward compatibility.</p>
+ <p>If <c><anno>ItemList</anno></c> is given, the result is
+ <c><anno>InfoTupleList</anno></c>.
+ The <c><anno>InfoTuple</anno></c>s in
+ <c><anno>InfoTupleList</anno></c> appear with the corresponding
+ <c><anno>Item</anno></c>s in the same order as the
+ <c><anno>Item</anno></c>s appeared
+ in <c><anno>ItemList</anno></c>. Valid <c><anno>Item</anno></c>s can
+ appear multiple times in <c><anno>ItemList</anno></c>.</p>
+ <note><p>If <c>registered_name</c> is part of <c><anno>ItemList</anno></c>
and the process has no name registered a
- <c>{registered_name, []}</c> <c><anno>InfoTuple</anno></c> <em>will</em>
- appear in the resulting <c><anno>InfoTupleList</anno></c>. This
- behavior is different than when a single
- <c>Item =:= registered_name</c> is given, and than when
- <c>process_info/1</c> is used.
- </p></note>
- <p>Currently the following <c><anno>InfoTuple</anno></c>s with corresponding
+ <c>{registered_name, []}</c>, <c><anno>InfoTuple</anno></c>
+ <em>will</em> appear in the resulting
+ <c><anno>InfoTupleList</anno></c>. This
+ behavior is different when a single
+ <c>Item =:= registered_name</c> is given, and when
+ <c>process_info/1</c> is used.</p>
+ </note>
+ <p>The following <c><anno>InfoTuple</anno></c>s with corresponding
<c><anno>Item</anno></c>s are valid:</p>
<taglist>
<tag><c>{backtrace, <anno>Bin</anno>}</c></tag>
<item>
- <p>The binary <c><anno>Bin</anno></c> contains the same information as
- the output from
+ <p>Binary <c><anno>Bin</anno></c> contains the same information
+ as the output from
<c>erlang:process_display(<anno>Pid</anno>, backtrace)</c>. Use
<c>binary_to_list/1</c> to obtain the string of characters
from the binary.</p>
</item>
<tag><c>{binary, <anno>BinInfo</anno>}</c></tag>
<item>
- <p><c><anno>BinInfo</anno></c> is a list containing miscellaneous information
- about binaries currently being referred to by this process.
- This <c><anno>InfoTuple</anno></c> may be changed or removed without prior
- notice.</p>
+ <p><c><anno>BinInfo</anno></c> is a list containing miscellaneous
+ information about binaries currently being referred to by this
+ process. This <c><anno>InfoTuple</anno></c> can be changed or
+ removed without prior notice.</p>
</item>
<tag><c>{catchlevel, <anno>CatchLevel</anno>}</c></tag>
<item>
<p><c><anno>CatchLevel</anno></c> is the number of currently active
- catches in this process. This <c><anno>InfoTuple</anno></c> may be
+ catches in this process. This <c><anno>InfoTuple</anno></c> can be
changed or removed without prior notice.</p>
</item>
- <tag><c>{current_function, {<anno>Module</anno>, <anno>Function</anno>, <anno>Arity</anno>}}</c></tag>
+ <tag><c>{current_function, {<anno>Module</anno>,
+ <anno>Function</anno>, Arity}}</c></tag>
<item>
- <p><c><anno>Module</anno></c>, <c><anno>Function</anno></c>, <c><anno>Arity</anno></c> is
+ <p><c><anno>Module</anno></c>, <c><anno>Function</anno></c>,
+ <c><anno>Arity</anno></c> is
the current function call of the process.</p>
</item>
- <tag><c>{current_location, {<anno>Module</anno>, <anno>Function</anno>, <anno>Arity</anno>, <anno>Location</anno>}}</c></tag>
+ <tag><c>{current_location, {<anno>Module</anno>,
+ <anno>Function</anno>, <anno>Arity</anno>,
+ <anno>Location</anno>}}</c></tag>
<item>
- <p><c><anno>Module</anno></c>, <c><anno>Function</anno></c>, <c><anno>Arity</anno></c> is
+ <p><c><anno>Module</anno></c>, <c><anno>Function</anno></c>,
+ <c><anno>Arity</anno></c> is
the current function call of the process.
- <c><anno>Location</anno></c> is a list of two-tuples that describes the
- location in the source code.
- </p>
+ <c><anno>Location</anno></c> is a list of two-tuples describing the
+ location in the source code.</p>
</item>
<tag><c>{current_stacktrace, <anno>Stack</anno>}</c></tag>
<item>
- <p>Return the current call stack back-trace (<em>stacktrace</em>)
+ <p>Returns the current call stack back-trace (<em>stacktrace</em>)
of the process. The stack has the same format as returned by
- <seealso marker="#get_stacktrace/0">erlang:get_stacktrace/0</seealso>.
- </p>
+ <seealso marker="#get_stacktrace/0">erlang:get_stacktrace/0</seealso>.</p>
</item>
<tag><c>{dictionary, <anno>Dictionary</anno>}</c></tag>
<item>
- <p><c><anno>Dictionary</anno></c> is the dictionary of the process.</p>
+ <p><c><anno>Dictionary</anno></c> is the process dictionary.</p>
</item>
<tag><c>{error_handler, <anno>Module</anno>}</c></tag>
<item>
@@ -4331,34 +4579,36 @@ os_prompt% </pre>
</item>
<tag><c>{garbage_collection, <anno>GCInfo</anno>}</c></tag>
<item>
- <p><c><anno>GCInfo</anno></c> is a list which contains miscellaneous
+ <p><c><anno>GCInfo</anno></c> is a list containing miscellaneous
information about garbage collection for this process.
- The content of <c><anno>GCInfo</anno></c> may be changed without
+ The content of <c><anno>GCInfo</anno></c> can be changed without
prior notice.</p>
</item>
<tag><c>{group_leader, <anno>GroupLeader</anno>}</c></tag>
<item>
- <p><c><anno>GroupLeader</anno></c> is group leader for the IO of
+ <p><c><anno>GroupLeader</anno></c> is group leader for the I/O of
the process.</p>
</item>
<tag><c>{heap_size, <anno>Size</anno>}</c></tag>
<item>
- <p><c><anno>Size</anno></c> is the size in words of youngest heap generation
- of the process. This generation currently include the stack
- of the process. This information is highly implementation
- dependent, and may change if the implementation change.
- </p>
+ <p><c><anno>Size</anno></c> is the size in words of the youngest heap
+ generation of the process. This generation includes
+ the process stack. This information is highly
+ implementation-dependent, and can change if the
+ implementation changes.</p>
</item>
- <tag><c>{initial_call, {Module, Function, Arity}}</c></tag>
+ <tag><c>{initial_call, {<anno>Module</anno>, <anno>Function</anno>,
+ <anno>Arity</anno>}}</c></tag>
<item>
- <p><c>Module</c>, <c>Function</c>, <c>Arity</c> is
+ <p><c><anno>Module</anno></c>, <c><anno>Function</anno></c>,
+ <c><anno>Arity</anno></c> is
the initial function call with which the process was
spawned.</p>
</item>
<tag><c>{links, <anno>PidsAndPorts</anno>}</c></tag>
<item>
- <p><c><anno>PidsAndPorts</anno></c> is a list of pids and
- port identifiers, with processes or ports to which the process
+ <p><c><anno>PidsAndPorts</anno></c> is a list of process identifiers
+ and port identifiers, with processes or ports to which the process
has a link.</p>
</item>
<tag><c>{last_calls, false|Calls}</c></tag>
@@ -4372,14 +4622,14 @@ os_prompt% </pre>
<tag><c>{memory, <anno>Size</anno>}</c></tag>
<item>
<p><c><anno>Size</anno></c> is the size in bytes of the process. This
- includes call stack, heap and internal structures.</p>
+ includes call stack, heap, and internal structures.</p>
</item>
<tag><c>{message_queue_len, <anno>MessageQueueLen</anno>}</c></tag>
<item>
<p><c><anno>MessageQueueLen</anno></c> is the number of messages
currently in the message queue of the process. This is
the length of the list <c><anno>MessageQueue</anno></c> returned as
- the info item <c>messages</c> (see below).</p>
+ the information item <c>messages</c> (see the following).</p>
</item>
<tag><c>{messages, <anno>MessageQueue</anno>}</c></tag>
<item>
@@ -4388,31 +4638,35 @@ os_prompt% </pre>
</item>
<tag><c>{min_heap_size, <anno>MinHeapSize</anno>}</c></tag>
<item>
- <p><c><anno>MinHeapSize</anno></c> is the minimum heap size for the process.</p>
+ <p><c><anno>MinHeapSize</anno></c> is the minimum heap size
+ for the process.</p>
</item>
<tag><c>{min_bin_vheap_size, <anno>MinBinVHeapSize</anno>}</c></tag>
<item>
- <p><c><anno>MinBinVHeapSize</anno></c> is the minimum binary virtual heap size for the process.</p>
+ <p><c><anno>MinBinVHeapSize</anno></c> is the minimum binary virtual
+ heap size for the process.</p>
</item>
<tag><c>{monitored_by, <anno>Pids</anno>}</c></tag>
<item>
- <p>A list of pids that are monitoring the process (with
+ <p>A list of process identifiers monitoring the process (with
<c>monitor/2</c>).</p>
</item>
<tag><c>{monitors, <anno>Monitors</anno>}</c></tag>
<item>
<p>A list of monitors (started by <c>monitor/2</c>)
that are active for the process. For a local process
- monitor or a remote process monitor by pid, the list item
- is <c>{process, <anno>Pid</anno>}</c>, and for a remote process
+ monitor or a remote process monitor by a process
+ identifier, the list item is <c>{process, <anno>Pid</anno>}</c>.
+ For a remote process
monitor by name, the list item is
<c>{process, {<anno>RegName</anno>, <anno>Node</anno>}}</c>.</p>
</item>
- <tag><c>{priority, Level}</c></tag>
+ <tag><c>{priority, <anno>Level</anno>}</c></tag>
<item>
<p><c><anno>Level</anno></c> is the current priority level for
- the process. For more information on priorities see
- <seealso marker="#process_flag_priority">process_flag(priority, Level)</seealso>.</p>
+ the process. For more information on priorities, see
+ <seealso marker="#process_flag_priority">process_flag(priority,
+ Level)</seealso>.</p>
</item>
<tag><c>{reductions, <anno>Number</anno>}</c></tag>
<item>
@@ -4427,166 +4681,201 @@ os_prompt% </pre>
</item>
<tag><c>{sequential_trace_token, [] | <anno>SequentialTraceToken</anno>}</c></tag>
<item>
- <p><c><anno>SequentialTraceToken</anno></c> the sequential trace token for
- the process. This <c><anno>InfoTuple</anno></c> may be changed or removed
- without prior notice.</p>
+ <p><c><anno>SequentialTraceToken</anno></c> is the sequential trace
+ token for the process. This <c><anno>InfoTuple</anno></c> can be
+ changed or removed without prior notice.</p>
</item>
<tag><c>{stack_size, <anno>Size</anno>}</c></tag>
<item>
- <p><c><anno>Size</anno></c> is the stack size of the process in words.</p>
+ <p><c><anno>Size</anno></c> is the stack size, in words,
+ of the process.</p>
</item>
<tag><c>{status, <anno>Status</anno>}</c></tag>
<item>
- <p><c><anno>Status</anno></c> is the status of the process. <c><anno>Status</anno></c>
- is <c>exiting</c>, <c>garbage_collecting</c>,
- <c>waiting</c> (for a message), <c>running</c>,
- <c>runnable</c> (ready to run, but another process is
- running), or <c>suspended</c> (suspended on a "busy" port
- or by the <c>erlang:suspend_process/[1,2]</c> BIF).</p>
+ <p><c><anno>Status</anno></c> is the status of the process and is one
+ of the following:</p>
+ <list type="bulleted">
+ <item><c>exiting</c></item>
+ <item><c>garbage_collecting</c></item>
+ <item><c>waiting</c> (for a message)</item>
+ <item><c>running</c></item>
+ <item><c>runnable</c> (ready to run, but another process is
+ running)</item>
+ <item><c>suspended</c> (suspended on a "busy" port
+ or by the BIF <c>erlang:suspend_process/[1,2]</c>)</item>
+ </list>
</item>
<tag><c>{suspending, <anno>SuspendeeList</anno>}</c></tag>
<item>
- <p><c><anno>SuspendeeList</anno></c> is a list of <c>{<anno>Suspendee</anno>,
- <anno>ActiveSuspendCount</anno>, <anno>OutstandingSuspendCount</anno>}</c> tuples.
- <c><anno>Suspendee</anno></c> is the pid of a process that have been or is to
- be suspended by the process identified by <c><anno>Pid</anno></c> via the
- <seealso marker="#suspend_process/2">erlang:suspend_process/2</seealso>
- BIF, or the
- <seealso marker="#suspend_process/1">erlang:suspend_process/1</seealso>
- BIF. <c><anno>ActiveSuspendCount</anno></c> is the number of times the
- <c><anno>Suspendee</anno></c> has been suspended by <c><anno>Pid</anno></c>.
+ <p><c><anno>SuspendeeList</anno></c> is a list of
+ <c>{<anno>Suspendee</anno>, <anno>ActiveSuspendCount</anno>,
+ <anno>OutstandingSuspendCount</anno>}</c> tuples.
+ <c><anno>Suspendee</anno></c> is the process identifier of a
+ process that has been, or is to be,
+ suspended by the process identified by <c><anno>Pid</anno></c>
+ through one of the following BIFs:</p>
+ <list type="bulleted">
+ <item>
+ <seealso marker="#suspend_process/2">erlang:suspend_process/2</seealso>
+ </item>
+ <item>
+ <seealso marker="#suspend_process/1">erlang:suspend_process/1</seealso>
+ </item>
+ </list>
+ <p><c><anno>ActiveSuspendCount</anno></c> is the number of
+ times <c><anno>Suspendee</anno></c> has been suspended by
+ <c><anno>Pid</anno></c>.
<c><anno>OutstandingSuspendCount</anno></c> is the number of not yet
- completed suspend requests sent by <c><anno>Pid</anno></c>. That is,
- if <c><anno>ActiveSuspendCount</anno> =/= 0</c>, <c><anno>Suspendee</anno></c> is
- currently in the suspended state, and if
- <c><anno>OutstandingSuspendCount</anno> =/= 0</c> the <c>asynchronous</c>
- option of <c>erlang:suspend_process/2</c> has been used and
- the suspendee has not yet been suspended by <c><anno>Pid</anno></c>.
- Note that the <c><anno>ActiveSuspendCount</anno></c> and
- <c><anno>OutstandingSuspendCount</anno></c> are not the total suspend count
- on <c><anno>Suspendee</anno></c>, only the parts contributed by <c>Pid</c>.
- </p>
+ completed suspend requests sent by <c><anno>Pid</anno></c>, that is:</p>
+ <list type="bulleted">
+ <item>If <c><anno>ActiveSuspendCount</anno> =/= 0</c>,
+ <c><anno>Suspendee</anno></c> is
+ currently in the suspended state.
+ </item>
+ <item>If <c><anno>OutstandingSuspendCount</anno> =/= 0</c>, option
+ <c>asynchronous</c> of <c>erlang:suspend_process/2</c>
+ has been used and the suspendee has not yet been
+ suspended by <c><anno>Pid</anno></c>.
+ </item>
+ </list>
+ <p>Notice that <c><anno>ActiveSuspendCount</anno></c> and
+ <c><anno>OutstandingSuspendCount</anno></c> are not the
+ total suspend count on <c><anno>Suspendee</anno></c>,
+ only the parts contributed by <c><anno>Pid</anno></c>.</p>
</item>
<tag><c>{total_heap_size, <anno>Size</anno>}</c></tag>
<item>
- <p><c><anno>Size</anno></c> is the total size in words of all heap
- fragments of the process. This currently include the stack
- of the process.
- </p>
+ <p><c><anno>Size</anno></c> is the total size, in words, of all heap
+ fragments of the process. This includes the process stack.</p>
</item>
<tag><c>{trace, <anno>InternalTraceFlags</anno>}</c></tag>
<item>
- <p><c><anno>InternalTraceFlags</anno></c> is an integer representing
- internal trace flag for this process. This <c><anno>InfoTuple</anno></c>
- may be changed or removed without prior notice.</p>
+ <p><c><anno>InternalTraceFlags</anno></c> is an integer
+ representing the internal trace flag for this process.
+ This <c><anno>InfoTuple</anno></c>
+ can be changed or removed without prior notice.</p>
</item>
<tag><c>{trap_exit, <anno>Boolean</anno>}</c></tag>
<item>
- <p><c><anno>Boolean</anno></c> is <c>true</c> if the process is trapping
- exits, otherwise it is <c>false</c>.</p>
+ <p><c><anno>Boolean</anno></c> is <c>true</c> if the process
+ is trapping exits, otherwise <c>false</c>.</p>
</item>
</taglist>
- <p>Note however, that not all implementations support every one
- of the above <c><anno>Item</anno></c>s.</p>
- <p>Failure: <c>badarg</c> if <c><anno>Pid</anno></c> is not a local process,
- or if <c><anno>Item</anno></c> is not a valid <c><anno>Item</anno></c>.</p>
+ <p>Notice that not all implementations support all
+ these <c><anno>Item</anno></c>s.</p>
+ <p>Failures:</p>
+ <taglist>
+ <tag><c>badarg</c></tag>
+ <item>If <c><anno>Pid</anno></c> is not a local process.</item>
+ <tag><c>badarg</c></tag>
+ <item>If <c><anno>Item</anno></c> is an invalid item.</item>
+ </taglist>
</desc>
</func>
+
<func>
<name name="processes" arity="0"/>
- <fsummary>All processes</fsummary>
+ <fsummary>All processes.</fsummary>
<desc>
<p>Returns a list of process identifiers corresponding to
- all the processes currently existing on the local node.
- </p>
- <p>Note that a process that is exiting, exists but is not alive, i.e.,
- <c>is_process_alive/1</c> will return <c>false</c> for a process
- that is exiting, but its process identifier will be part
- of the result returned from <c>processes/0</c>.
- </p>
+ all the processes currently existing on the local node.</p>
+ <p>Notice that an exiting process exists, but is not alive.
+ That is, <c>is_process_alive/1</c> returns <c>false</c>
+ for an exiting process, but its process identifier is part
+ of the result returned from <c>processes/0</c>.</p>
+ <p>Example:</p>
<pre>
> <input>processes().</input>
[&lt;0.0.0&gt;,&lt;0.2.0&gt;,&lt;0.4.0&gt;,&lt;0.5.0&gt;,&lt;0.7.0&gt;,&lt;0.8.0&gt;]</pre>
</desc>
</func>
+
<func>
<name name="purge_module" arity="1"/>
- <fsummary>Remove old code for a module</fsummary>
+ <fsummary>Removes old code for a module.</fsummary>
<desc>
- <p>Removes old code for <c><anno>Module</anno></c>. Before this BIF is used,
- <c>erlang:check_process_code/2</c> should be called to check
- that no processes are executing old code in the module.</p>
+ <p>Removes old code for <c><anno>Module</anno></c>.
+ Before this BIF is used,
+ <c>erlang:check_process_code/2</c> is to be called to check
+ that no processes execute old code in the module.</p>
<warning>
<p>This BIF is intended for the code server (see
- <seealso marker="kernel:code">code(3)</seealso>) and should not be
- used elsewhere.</p>
+ <seealso marker="kernel:code">code(3)</seealso>)
+ and is not to be used elsewhere.</p>
</warning>
<p>Failure: <c>badarg</c> if there is no old code for
<c><anno>Module</anno></c>.</p>
</desc>
</func>
+
<func>
<name name="put" arity="2"/>
- <fsummary>Add a new value to the process dictionary</fsummary>
- <desc>
- <p>Adds a new <c><anno>Key</anno></c> to the process dictionary, associated
- with the value <c><anno>Val</anno></c>, and returns <c>undefined</c>. If
- <c><anno>Key</anno></c> already exists, the old value is deleted and
- replaced by <c><anno>Val</anno></c> and the function returns the old value.</p>
- <note>
- <p>The values stored when <c>put</c> is evaluated within
- the scope of a <c>catch</c> will not be retracted if a
- <c>throw</c> is evaluated, or if an error occurs.</p>
- </note>
+ <fsummary>Adds a new value to the process dictionary.</fsummary>
+ <desc>
+ <p>Adds a new <c><anno>Key</anno></c> to the process dictionary,
+ associated with the value <c><anno>Val</anno></c>, and returns
+ <c>undefined</c>. If <c><anno>Key</anno></c> exists, the old
+ value is deleted and replaced by <c><anno>Val</anno></c>, and
+ the function returns the old value.</p>
+ <p>Example:</p>
<pre>
> <input>X = put(name, walrus), Y = put(name, carpenter),</input>
<input>Z = get(name),</input>
<input>{X, Y, Z}.</input>
{undefined,walrus,carpenter}</pre>
+ <note>
+ <p>The values stored when <c>put</c> is evaluated within
+ the scope of a <c>catch</c> are not retracted if a
+ <c>throw</c> is evaluated, or if an error occurs.</p>
+ </note>
</desc>
</func>
+
<func>
<name name="raise" arity="3"/>
+ <fsummary>Stops execution with an exception of given class, reason, and call stack backtrace.</fsummary>
<type name="raise_stacktrace"/>
- <fsummary>Stop execution with an exception of given class, reason and call stack backtrace</fsummary>
<desc>
<p>Stops the execution of the calling process with an
- exception of given class, reason and call stack backtrace
+ exception of given class, reason, and call stack backtrace
(<em>stacktrace</em>).</p>
<warning>
- <p>This BIF is intended for debugging and for use in
- the Erlang operating system. In general, it should
- be avoided in applications, unless you know
- very well what you are doing.</p>
+ <p>This BIF is intended for debugging. Avoid to use it in applications,
+ unless you really know what you are doing.</p>
</warning>
- <p><c><anno>Class</anno></c> is one of <c>error</c>, <c>exit</c> or
- <c>throw</c>, so if it were not for the stacktrace
- <c>erlang:raise(<anno>Class</anno>, <anno>Reason</anno>, <anno>Stacktrace</anno>)</c> is
- equivalent to <c>erlang:<anno>Class</anno>(<anno>Reason</anno>)</c>.
- <c><anno>Reason</anno></c> is any term and <c><anno>Stacktrace</anno></c> is a list as
- returned from <c>get_stacktrace()</c>, that is a list of
- 4-tuples <c>{Module, Function, Arity | Args,
- Location}</c> where <c>Module</c> and <c>Function</c>
- are atoms and the third element is an integer arity or an
- argument list. The stacktrace may also contain <c>{Fun,
- Args, Location}</c> tuples where
- <c>Fun</c> is a local fun and <c>Args</c> is an argument list.</p>
- <p>The <c>Location</c> element at the end is optional.
+ <p><c><anno>Class</anno></c> is <c>error</c>, <c>exit</c>, or
+ <c>throw</c>. So, if it were not for the stacktrace,
+ <c>erlang:raise(<anno>Class</anno>, <anno>Reason</anno>,
+ <anno>Stacktrace</anno>)</c> is
+ equivalent to <c>erlang:<anno>Class</anno>(<anno>Reason</anno>)</c>.</p>
+ <p><c><anno>Reason</anno></c> is any term.
+ <c><anno>Stacktrace</anno></c> is a list as
+ returned from <c>get_stacktrace()</c>, that is, a list of
+ four-tuples <c>{Module, Function, Arity | Args,
+ Location}</c>, where <c>Module</c> and <c>Function</c>
+ are atoms, and the third element is an integer arity or an
+ argument list. The stacktrace can also contain <c>{Fun,
+ Args, Location}</c> tuples, where <c>Fun</c> is a local
+ fun and <c>Args</c> is an argument list.</p>
+ <p>Element <c>Location</c> at the end is optional.
Omitting it is equivalent to specifying an empty list.</p>
<p>The stacktrace is used as the exception stacktrace for the
- calling process; it will be truncated to the current
+ calling process; it is truncated to the current
maximum stacktrace depth.</p>
- <p>Because evaluating this function causes the process to
- terminate, it has no return value - unless the arguments are
- invalid, in which case the function <em>returns the error reason</em>, that is <c>badarg</c>. If you want to be
- really sure not to return you can call
- <c>error(erlang:raise(<anno>Class</anno>, <anno>Reason</anno>, <anno>Stacktrace</anno>))</c>
+ <p>Since evaluating this function causes the process to
+ terminate, it has no return value unless the arguments are
+ invalid, in which case the function <em>returns the error
+ reason</em> <c>badarg</c>. If you want to be
+ sure not to return, you can call
+ <c>error(erlang:raise(<anno>Class</anno>, <anno>Reason</anno>,
+ <anno>Stacktrace</anno>))</c>
and hope to distinguish exceptions later.</p>
</desc>
</func>
+
<func>
<name name="read_timer" arity="2"/>
- <fsummary>Read the state of a timer</fsummary>
+ <fsummary>Reads the state of a timer.</fsummary>
<desc>
<p>
Read the state of a timer that has been created by either
@@ -4595,7 +4884,7 @@ os_prompt% </pre>
<c><anno>TimerRef</anno></c> identifies the timer, and
was returned by the BIF that created the timer.
</p>
- <p>Currently available <c><anno>Option</anno>s</c>:</p>
+ <p>Available <c><anno>Option</anno>s</c>:</p>
<taglist>
<tag><c>{async, Async}</c></tag>
<item>
@@ -4603,12 +4892,12 @@ os_prompt% </pre>
Asynchronous request for state information. <c>Async</c>
defaults to <c>false</c> which will cause the operation
to be performed synchronously. In this case, the <c>Result</c>
- will be returned by <c>erlang:read_timer()</c>. When
- <c>Async</c> is set to <c>true</c>, <c>erlang:read_timer()</c>
- will send an asynchronous request for the state information
- to the timer service that manages the timer, and then return
+ is returned by <c>erlang:read_timer()</c>. When
+ <c>Async</c> is <c>true</c>, <c>erlang:read_timer()</c>
+ sends an asynchronous request for the state information
+ to the timer service that manages the timer, and then returns
<c>ok</c>. A message on the format <c>{read_timer,
- <anno>TimerRef</anno>, <anno>Result</anno>}</c> will be
+ <anno>TimerRef</anno>, <anno>Result</anno>}</c> is
sent to the caller of <c>erlang:read_timer()</c> when the
operation has been processed.
</p>
@@ -4618,26 +4907,27 @@ os_prompt% </pre>
More <c><anno>Option</anno></c>s may be added in the future.
</p>
<p>
- When the <c><anno>Result</anno></c> equals <c>false</c>, a
+ If <c><anno>Result</anno></c> is an integer, it represents the
+ time in milli-seconds left until the timer expires.</p>
+ <p>
+ If <c><anno>Result</anno></c> is <c>false</c>, a
timer corresponding to <c><anno>TimerRef</anno></c> could not
- be found. This can be either because the timer had expired,
- had been canceled, or because <c><anno>TimerRef</anno></c>
- never has corresponded to a timer. If the timer has expired,
- the timeout message has been sent, but it does not tell you
- whether or not it has arrived at its destination yet. When the
- <c><anno>Result</anno></c> is an integer, it represents the
- time in milli-seconds left until the timer will expire.
+ be found. This can be because the timer had expired,
+ it had been canceled, or because <c><anno>TimerRef</anno></c>
+ never has corresponded to a timer. Even if the timer has expired,
+ it does not tell you whether or not the timeout message has
+ arrived at its destination yet.
</p>
<note>
<p>
The timer service that manages the timer may be co-located
with another scheduler than the scheduler that the calling
process is executing on. If this is the case, communication
- with the timer service will take much longer time than if it
+ with the timer service takes much longer time than if it
is located locally. If the calling process is in critical
path, and can do other things while waiting for the result
- of this operation you want to use the <c>{async, true}</c>
- option. If using the <c>{async, false}</c> option, the calling
+ of this operation, you want to use option <c>{async, true}</c>.
+ If using option <c>{async, false}</c>, the calling
process will be blocked until the operation has been
performed.
</p>
@@ -4651,70 +4941,86 @@ os_prompt% </pre>
</func>
<func>
<name name="read_timer" arity="1"/>
- <fsummary>Read the state of a timer</fsummary>
+ <fsummary>Reads the state of a timer.</fsummary>
<desc>
<p>Read the state of a timer. The same as calling
<seealso marker="#read_timer/2"><c>erlang:read_timer(TimerRef,
[])</c></seealso>.</p>
</desc>
</func>
+
<func>
<name name="ref_to_list" arity="1"/>
- <fsummary>Text representation of a reference</fsummary>
+ <fsummary>Text representation of a reference.</fsummary>
<desc>
- <p>Returns a string which corresponds to the text
+ <p>Returns a string corresponding to the text
representation of <c><anno>Ref</anno></c>.</p>
<warning>
- <p>This BIF is intended for debugging and for use in
- the Erlang operating system. It should not be used in
- application programs.</p>
+ <p>This BIF is intended for debugging and is not to be used
+ in application programs.</p>
</warning>
</desc>
</func>
+
<func>
<name name="register" arity="2"/>
- <fsummary>Register a name for a pid (or port)</fsummary>
+ <fsummary>Registers a name for a pid (or port).</fsummary>
<desc>
- <p>Associates the name <c><anno>RegName</anno></c> with a pid or a port
- identifier. <c><anno>RegName</anno></c>, which must be an atom, can be used
- instead of the pid / port identifier in the send operator
+ <p>Associates the name <c><anno>RegName</anno></c> with a process
+ identifier (pid) or a port identifier.
+ <c><anno>RegName</anno></c>, which must be an atom, can be used
+ instead of the pid or port identifier in send operator
(<c><anno>RegName</anno> ! Message</c>).</p>
+ <p>Example:</p>
<pre>
> <input>register(db, Pid).</input>
true</pre>
- <p>Failure: <c>badarg</c> if <c><anno>PidOrPort</anno></c> is not an existing,
- local process or port, if <c><anno>RegName</anno></c> is already in use,
- if the process or port is already registered (already has a
- name), or if <c><anno>RegName</anno></c> is the atom <c>undefined</c>.</p>
+ <p>Failures:</p>
+ <taglist>
+ <tag><c>badarg</c></tag>
+ <item>If <c><anno>PidOrPort</anno></c> is not an existing local
+ process or port.</item>
+ <tag><c>badarg</c></tag>
+ <item>If <c><anno>RegName</anno></c> is already in use.</item>
+ <tag><c>badarg</c></tag>
+ <item>If the process or port is already registered
+ (already has a name).</item>
+ <tag><c>badarg</c></tag>
+ <item>If <c><anno>RegName</anno></c> is the atom
+ <c>undefined</c>.</item>
+ </taglist>
</desc>
</func>
+
<func>
<name name="registered" arity="0"/>
- <fsummary>All registered names</fsummary>
+ <fsummary>All registered names.</fsummary>
<desc>
- <p>Returns a list of names which have been registered using
- <seealso marker="#register/2">register/2</seealso>.</p>
+ <p>Returns a list of names that have been registered using
+ <seealso marker="#register/2">register/2</seealso>, for
+ example:</p>
<pre>
> <input>registered().</input>
[code_server, file_server, init, user, my_db]</pre>
</desc>
</func>
+
<func>
<name name="resume_process" arity="1"/>
- <fsummary>Resume a suspended process</fsummary>
+ <fsummary>Resumes a suspended process.</fsummary>
<desc>
<p>Decreases the suspend count on the process identified by
- <c><anno>Suspendee</anno></c>. <c><anno>Suspendee</anno></c> should previously have been
- suspended via
- <seealso marker="#suspend_process/2">erlang:suspend_process/2</seealso>,
+ <c><anno>Suspendee</anno></c>. <c><anno>Suspendee</anno></c>
+ is previously to have been suspended through
+ <seealso marker="#suspend_process/2">erlang:suspend_process/2</seealso>
or
<seealso marker="#suspend_process/1">erlang:suspend_process/1</seealso>
- by the process calling <c>erlang:resume_process(<anno>Suspendee</anno>)</c>. When
- the suspend count on <c><anno>Suspendee</anno></c> reach zero, <c><anno>Suspendee</anno></c>
- will be resumed, i.e., the state of the <c>Suspendee</c> is changed
- from suspended into the state <c><anno>Suspendee</anno></c> was in before it was
- suspended.
- </p>
+ by the process calling
+ <c>erlang:resume_process(<anno>Suspendee</anno>)</c>. When the
+ suspend count on <c><anno>Suspendee</anno></c> reaches zero,
+ <c><anno>Suspendee</anno></c> is resumed, that is, its state
+ is changed from suspended into the state it had before it was
+ suspended.</p>
<warning>
<p>This BIF is intended for debugging only.</p>
</warning>
@@ -4722,7 +5028,7 @@ true</pre>
<taglist>
<tag><c>badarg</c></tag>
<item>
- If <c><anno>Suspendee</anno></c> isn't a process identifier.
+ If <c><anno>Suspendee</anno></c> is not a process identifier.
</item>
<tag><c>badarg</c></tag>
<item>
@@ -4732,58 +5038,65 @@ true</pre>
</item>
<tag><c>badarg</c></tag>
<item>
- If the process identified by <c><anno>Suspendee</anno></c> is not alive.
+ If the process identified by <c><anno>Suspendee</anno></c>
+ is not alive.
</item>
</taglist>
</desc>
</func>
+
<func>
<name name="round" arity="1"/>
- <fsummary>Return an integer by rounding a number</fsummary>
+ <fsummary>Returns an integer by rounding a number.</fsummary>
<desc>
- <p>Returns an integer by rounding <c><anno>Number</anno></c>.</p>
+ <p>Returns an integer by rounding <c><anno>Number</anno></c>,
+ for example:</p>
<pre>
-> <input>round(5.5).</input>
+<input>round(5.5).</input>
6</pre>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="self" arity="0"/>
- <fsummary>Pid of the calling process</fsummary>
+ <fsummary>Returns pid of the calling process.</fsummary>
<desc>
- <p>Returns the pid (process identifier) of the calling process.</p>
+ <p>Returns the process identifier of the calling process, for
+ example:</p>
<pre>
> <input>self().</input>
&lt;0.26.0></pre>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="send" arity="2"/>
- <fsummary>Send a message</fsummary>
+ <fsummary>Sends a message.</fsummary>
<type name="dst"/>
<desc>
- <p>Sends a message and returns <c><anno>Msg</anno></c>. This is the same as
- <c><anno>Dest</anno> ! <anno>Msg</anno></c>.</p>
- <p><c><anno>Dest</anno></c> may be a remote or local pid, a (local) port, a
- locally registered name, or a tuple <c>{<anno>RegName</anno>, <anno>Node</anno>}</c>
+ <p>Sends a message and returns <c><anno>Msg</anno></c>. This
+ is the same as <c><anno>Dest</anno> ! <anno>Msg</anno></c>.</p>
+ <p><c><anno>Dest</anno></c> can be a remote or local process identifier,
+ a (local) port, a locally registered name, or a tuple
+ <c>{<anno>RegName</anno>, <anno>Node</anno>}</c>
for a registered name at another node.</p>
</desc>
</func>
+
<func>
<name name="send" arity="3"/>
+ <fsummary>Sends a message conditionally.</fsummary>
<type name="dst"/>
- <fsummary>Send a message conditionally</fsummary>
- <desc>
- <p>Sends a message and returns <c>ok</c>, or does not send
- the message but returns something else (see below). Otherwise
- the same as
- <seealso marker="#send/2">erlang:send/2</seealso>. See
- also
- <seealso marker="#send_nosuspend/2">erlang:send_nosuspend/2,3</seealso>.
- for more detailed explanation and warnings.</p>
- <p>The possible options are:</p>
+ <desc>
+ <p>Either sends a message and returns <c>ok</c>, or does not send
+ the message but returns something else (see the following).
+ Otherwise the same as
+ <seealso marker="#send/2">erlang:send/2</seealso>.
+ For more detailed explanation and warnings, see
+ <seealso marker="#send_nosuspend/2">erlang:send_nosuspend/2,3</seealso>.</p>
+ <p>The options are as follows:</p>
<taglist>
<tag><c>nosuspend</c></tag>
<item>
@@ -4793,314 +5106,366 @@ true</pre>
<tag><c>noconnect</c></tag>
<item>
<p>If the destination node would have to be auto-connected
- before doing the send, <c>noconnect</c> is returned
+ to do the send, <c>noconnect</c> is returned
instead.</p>
</item>
</taglist>
<warning>
- <p>As with <c>erlang:send_nosuspend/2,3</c>: Use with extreme
- care!</p>
+ <p>As with <c>erlang:send_nosuspend/2,3</c>: use with extreme
+ care.</p>
</warning>
</desc>
</func>
+
<func>
<name name="send_after" arity="4"/>
<fsummary>Start a timer</fsummary>
<desc>
<p>
Starts a timer. When the timer expires, the message
- <c><anno>Msg</anno></c> will be sent to the process
- identified by <c><anno>Dest</anno></c>. Appart from
- the format of the message sent to
- <c><anno>Dest</anno></c> when the timer expires
+ <c><anno>Msg</anno></c> is sent to the process
+ identified by <c><anno>Dest</anno></c>. Apart from
+ the format of the timeout message,
<c>erlang:send_after/4</c> works exactly as
<seealso marker="#start_timer/4"><c>erlang:start_timer/4</c></seealso>.</p>
</desc>
</func>
<func>
<name name="send_after" arity="3"/>
- <fsummary>Start a timer</fsummary>
+ <fsummary>Starts a timer.</fsummary>
<desc>
<p>Starts a timer. The same as calling
<seealso marker="#send_after/4"><c>erlang:send_after(<anno>Time</anno>,
<anno>Dest</anno>, <anno>Msg</anno>, [])</c></seealso>.</p>
</desc>
</func>
+
<func>
<name name="send_nosuspend" arity="2"/>
- <fsummary>Try to send a message without ever blocking</fsummary>
+ <fsummary>Tries to send a message without ever blocking.</fsummary>
<type name="dst"/>
<desc>
<p>The same as
- <seealso marker="#send/3">erlang:send(<anno>Dest</anno>, <anno>Msg</anno>, [nosuspend])</seealso>, but returns <c>true</c> if
+ <seealso marker="#send/3">erlang:send(<anno>Dest</anno>,
+ <anno>Msg</anno>, [nosuspend])</seealso>,
+ but returns <c>true</c> if
the message was sent and <c>false</c> if the message was not
sent because the sender would have had to be suspended.</p>
- <p>This function is intended for send operations towards an
+ <p>This function is intended for send operations to an
unreliable remote node without ever blocking the sending
(Erlang) process. If the connection to the remote node
(usually not a real Erlang node, but a node written in C or
- Java) is overloaded, this function <em>will not send the message</em> but return <c>false</c> instead.</p>
- <p>The same happens, if <c><anno>Dest</anno></c> refers to a local port that
- is busy. For all other destinations (allowed for the ordinary
- send operator <c>'!'</c>) this function sends the message and
+ Java) is overloaded, this function <em>does not send the message</em>
+ and returns <c>false</c>.</p>
+ <p>The same occurs if <c><anno>Dest</anno></c> refers to a local port
+ that is busy. For all other destinations (allowed for the ordinary
+ send operator <c>'!'</c>), this function sends the message and
returns <c>true</c>.</p>
- <p>This function is only to be used in very rare circumstances
+ <p>This function is only to be used in rare circumstances
where a process communicates with Erlang nodes that can
- disappear without any trace causing the TCP buffers and
- the drivers queue to be over-full before the node will actually
- be shut down (due to tick timeouts) by <c>net_kernel</c>. The
- normal reaction to take when this happens is some kind of
+ disappear without any trace, causing the TCP buffers and
+ the drivers queue to be over-full before the node is
+ shut down (because of tick time-outs) by <c>net_kernel</c>.
+ The normal reaction to take when this occurs is some kind of
premature shutdown of the other node.</p>
- <p>Note that ignoring the return value from this function would
- result in <em>unreliable</em> message passing, which is
+ <p>Notice that ignoring the return value from this function would
+ result in an <em>unreliable</em> message passing, which is
contradictory to the Erlang programming model. The message is
<em>not</em> sent if this function returns <c>false</c>.</p>
- <p>Note also that in many systems, transient states of
+ <p>In many systems, transient states of
overloaded queues are normal. The fact that this function
- returns <c>false</c> does not in any way mean that the other
+ returns <c>false</c> does not mean that the other
node is guaranteed to be non-responsive, it could be a
- temporary overload. Also a return value of <c>true</c> does
- only mean that the message could be sent on the (TCP) channel
- without blocking, the message is not guaranteed to have
- arrived at the remote node. Also in the case of a disconnected
+ temporary overload. Also, a return value of <c>true</c> does
+ only mean that the message can be sent on the (TCP) channel
+ without blocking, the message is not guaranteed to
+ arrive at the remote node. For a disconnected
non-responsive node, the return value is <c>true</c> (mimics
- the behaviour of the <c>!</c> operator). The expected
- behaviour as well as the actions to take when the function
- returns <c>false</c> are application and hardware specific.</p>
+ the behavior of operator <c>!</c>). The expected
+ behavior and the actions to take when the function
+ returns <c>false</c> are application- and hardware-specific.</p>
<warning>
- <p>Use with extreme care!</p>
+ <p>Use with extreme care.</p>
</warning>
</desc>
</func>
+
<func>
<name name="send_nosuspend" arity="3"/>
- <fsummary>Try to send a message without ever blocking</fsummary>
+ <fsummary>Tries to send a message without ever blocking.</fsummary>
<type name="dst"/>
<desc>
<p>The same as
- <seealso marker="#send/3">erlang:send(<anno>Dest</anno>, <anno>Msg</anno>, [nosuspend | <anno>Options</anno>])</seealso>,
- but with boolean return value.</p>
+ <seealso marker="#send/3">erlang:send(<anno>Dest</anno>,
+ <anno>Msg</anno>, [nosuspend | <anno>Options</anno>])</seealso>,
+ but with a Boolean return value.</p>
<p>This function behaves like
- <seealso marker="#send_nosuspend/2">erlang:send_nosuspend/2)</seealso>,
- but takes a third parameter, a list of options. The only
- currently implemented option is <c>noconnect</c>. The option
- <c>noconnect</c> makes the function return <c>false</c> if
+ <seealso marker="#send_nosuspend/2">erlang:send_nosuspend/2</seealso>,
+ but takes a third parameter, a list of options.
+ The only option is <c>noconnect</c>, which
+ makes the function return <c>false</c> if
the remote node is not currently reachable by the local
- node. The normal behaviour is to try to connect to the node,
- which may stall the process for a shorter period. The use of
- the <c>noconnect</c> option makes it possible to be
- absolutely sure not to get even the slightest delay when
+ node. The normal behavior is to try to connect to the node,
+ which can stall the process during a short period. The use of
+ option <c>noconnect</c> makes it possible to be
+ sure not to get the slightest delay when
sending to a remote process. This is especially useful when
- communicating with nodes who expect to always be
- the connecting part (i.e. nodes written in C or Java).</p>
+ communicating with nodes that expect to always be
+ the connecting part (that is, nodes written in C or Java).</p>
<p>Whenever the function returns <c>false</c> (either when a
suspend would occur or when <c>noconnect</c> was specified and
the node was not already connected), the message is guaranteed
<em>not</em> to have been sent.</p>
<warning>
- <p>Use with extreme care!</p>
+ <p>Use with extreme care.</p>
</warning>
</desc>
</func>
+
<func>
<name name="set_cookie" arity="2"/>
- <fsummary>Set the magic cookie of a node</fsummary>
+ <fsummary>Sets the magic cookie of a node.</fsummary>
<desc>
<p>Sets the magic cookie of <c><anno>Node</anno></c> to the atom
- <c><anno>Cookie</anno></c>. If <c><anno>Node</anno></c> is the local node, the function
+ <c><anno>Cookie</anno></c>. If <c><anno>Node</anno></c> is the
+ local node, the function
also sets the cookie of all other unknown nodes to
- <c><anno>Cookie</anno></c> (see
- <seealso marker="doc/reference_manual:distributed">Distributed Erlang</seealso> in the Erlang Reference Manual).</p>
+ <c><anno>Cookie</anno></c> (see Section
+ <seealso marker="doc/reference_manual:distributed">Distributed Erlang</seealso>
+ in the Erlang Reference Manual in System Documentation).</p>
<p>Failure: <c>function_clause</c> if the local node is not
alive.</p>
</desc>
</func>
+
<func>
<name name="setelement" arity="3"/>
- <type_desc variable="Index">1..tuple_size(<anno>Tuple1</anno>)</type_desc>
- <fsummary>Set Nth element of a tuple</fsummary>
+ <fsummary>Sets the Nth element of a tuple.</fsummary>
+ <type_desc variable="Index">1..tuple_size(<anno>Tuple1</anno></type_desc>
<desc>
- <p>Returns a tuple which is a copy of the argument <c><anno>Tuple1</anno></c>
- with the element given by the integer argument <c><anno>Index</anno></c>
+ <p>Returns a tuple that is a copy of argument
+ <c><anno>Tuple1</anno></c>
+ with the element given by integer argument
+ <c><anno>Index</anno></c>
(the first element is the element with index 1) replaced by
- the argument <c><anno>Value</anno></c>.</p>
+ argument <c><anno>Value</anno></c>, for example:</p>
<pre>
> <input>setelement(2, {10, green, bottles}, red).</input>
{10,red,bottles}</pre>
</desc>
</func>
+
<func>
<name name="size" arity="1"/>
- <fsummary>Size of a tuple or binary</fsummary>
+ <fsummary>Size of a tuple or binary.</fsummary>
<desc>
- <p>Returns an integer which is the size of the argument
- <c><anno>Item</anno></c>, which must be either a tuple or a binary.</p>
+ <p>Returns the number of elements in a tuple or the number of
+ bytes in a binary or bitstring, for example:</p>
<pre>
> <input>size({morni, mulle, bwange}).</input>
-3</pre>
+3
+> <input>size(&lt;&lt;11, 22, 33&gt;&gt;).</input>
+3
+</pre>
+ <p>For bitstrings the number of whole bytes is returned. That is, if the number of bits
+ in the bitstring is not divisible by 8, the resulting
+ number of bytes is rounded <em>down</em>.</p>
<p>Allowed in guard tests.</p>
+ <p>See also
+ <seealso marker="#tuple_size/1"><c>tuple_size/1</c></seealso>,
+ <seealso marker="#byte_size/1"><c>byte_size/1</c></seealso>
+ and
+ <seealso marker="#bit_size/1"><c>bit_size/1</c></seealso>.</p>
</desc>
</func>
+
<func>
<name name="spawn" arity="1"/>
- <fsummary>Create a new process with a fun as entry point</fsummary>
+ <fsummary>Creates a new process with a fun as entry point.</fsummary>
<desc>
- <p>Returns the pid of a new process started by the application
- of <c><anno>Fun</anno></c> to the empty list <c>[]</c>. Otherwise works
- like <seealso marker="#spawn/3">spawn/3</seealso>.</p>
+ <p>Returns the process identifier of a new process started by the
+ application of <c><anno>Fun</anno></c> to the empty list
+ <c>[]</c>. Otherwise
+ works like <seealso marker="#spawn/3">spawn/3</seealso>.</p>
</desc>
</func>
+
<func>
<name name="spawn" arity="2"/>
- <fsummary>Create a new process with a fun as entry point on a given node</fsummary>
+ <fsummary>Creates a new process with a fun as entry point on a given node.</fsummary>
<desc>
- <p>Returns the pid of a new process started by the application
- of <c><anno>Fun</anno></c> to the empty list <c>[]</c> on <c><anno>Node</anno></c>. If
- <c><anno>Node</anno></c> does not exist, a useless pid is returned.
- Otherwise works like
+ <p>Returns the process identifier of a new process started
+ by the application of <c><anno>Fun</anno></c> to the
+ empty list <c>[]</c> on <c><anno>Node</anno></c>. If
+ <c><anno>Node</anno></c> does not exist, a useless pid is
+ returned. Otherwise works like
<seealso marker="#spawn/3">spawn/3</seealso>.</p>
</desc>
</func>
+
<func>
<name name="spawn" arity="3"/>
- <fsummary>Create a new process with a function as entry point</fsummary>
- <desc>
- <p>Returns the pid of a new process started by the application
- of <c><anno>Module</anno>:<anno>Function</anno></c> to <c><anno>Args</anno></c>. The new process
- created will be placed in the system scheduler queue and be
- run some time later.</p>
- <p><c>error_handler:undefined_function(<anno>Module</anno>, <anno>Function</anno>, <anno>Args</anno>)</c> is evaluated by the new process if
- <c><anno>Module</anno>:<anno>Function</anno>/Arity</c> does not exist (where
- <c>Arity</c> is the length of <c><anno>Args</anno></c>). The error handler
+ <fsummary>Creates a new process with a function as entry point.</fsummary>
+ <desc>
+ <p>Returns the process identifier of a new process started by
+ the application of <c><anno>Module</anno>:<anno>Function</anno></c>
+ to <c><anno>Args</anno></c>.</p>
+ <p><c>error_handler:undefined_function(<anno>Module</anno>,
+ <anno>Function</anno>, <anno>Args</anno>)</c>
+ is evaluated by the new process if
+ <c><anno>Module</anno>:<anno>Function</anno>/Arity</c>
+ does not exist (where <c>Arity</c> is the length of
+ <c><anno>Args</anno></c>). The error handler
can be redefined (see
<seealso marker="#process_flag/2">process_flag/2</seealso>).
If <c>error_handler</c> is undefined, or the user has
- redefined the default <c>error_handler</c> its replacement is
- undefined, a failure with the reason <c>undef</c> will occur.</p>
+ redefined the default <c>error_handler</c> and its replacement is
+ undefined, a failure with reason <c>undef</c> occurs.</p>
+ <p>Example:</p>
<pre>
> <input>spawn(speed, regulator, [high_speed, thin_cut]).</input>
&lt;0.13.1></pre>
</desc>
</func>
+
<func>
<name name="spawn" arity="4"/>
- <fsummary>Create a new process with a function as entry point on a given node</fsummary>
+ <fsummary>Creates a new process with a function as entry point on a given node.</fsummary>
<desc>
- <p>Returns the pid of a new process started by the application
- of <c><anno>Module</anno>:<anno>Function</anno></c> to <c><anno>Args</anno></c> on <c>Node</c>. If
- <c><anno>Node</anno></c> does not exists, a useless pid is returned.
+ <p>Returns the process identifier (pid) of a new process started
+ by the application
+ of <c><anno>Module</anno>:<anno>Function</anno></c>
+ to <c><anno>Args</anno></c> on <c><anno>Node</anno></c>. If
+ <c><anno>Node</anno></c> does not exist, a useless pid is returned.
Otherwise works like
<seealso marker="#spawn/3">spawn/3</seealso>.</p>
</desc>
</func>
+
<func>
<name name="spawn_link" arity="1"/>
- <fsummary>Create and link to a new process with a fun as entry point</fsummary>
+ <fsummary>Creates and links to a new process with a fun as entry point.</fsummary>
<desc>
- <p>Returns the pid of a new process started by the application
- of <c><anno>Fun</anno></c> to the empty list []. A link is created between
+ <p>Returns the process identifier of a new process started by
+ the application of <c><anno>Fun</anno></c> to the empty list
+ <c>[]</c>. A link is created between
the calling process and the new process, atomically.
Otherwise works like
<seealso marker="#spawn/3">spawn/3</seealso>.</p>
</desc>
</func>
+
<func>
<name name="spawn_link" arity="2"/>
- <fsummary>Create and link to a new process with a fun as entry point on a specified node</fsummary>
+ <fsummary>Creates and links to a new process with a fun as entry point on a specified node.</fsummary>
<desc>
- <p>Returns the pid of a new process started by the application
- of <c><anno>Fun</anno></c> to the empty list [] on <c><anno>Node</anno></c>. A link is
+ <p>Returns the process identifier (pid) of a new process started
+ by the application of <c><anno>Fun</anno></c> to the empty
+ list <c>[]</c> on <c><anno>Node</anno></c>. A link is
created between the calling process and the new process,
- atomically. If <c><anno>Node</anno></c> does not exist, a useless pid is
- returned (and due to the link, an exit signal with exit
- reason <c>noconnection</c> will be received). Otherwise works
- like <seealso marker="#spawn/3">spawn/3</seealso>.</p>
+ atomically. If <c><anno>Node</anno></c> does not exist,
+ a useless pid is returned and an exit signal with
+ reason <c>noconnection</c> is sent to the calling
+ process. Otherwise works like <seealso marker="#spawn/3">spawn/3</seealso>.</p>
</desc>
</func>
+
<func>
<name name="spawn_link" arity="3"/>
- <fsummary>Create and link to a new process with a function as entry point</fsummary>
+ <fsummary>Creates and links to a new process with a function as entry point.</fsummary>
<desc>
- <p>Returns the pid of a new process started by the application
- of <c><anno>Module</anno>:<anno>Function</anno></c> to <c><anno>Args</anno></c>. A link is created
+ <p>Returns the process identifier of a new process started by
+ the application of <c><anno>Module</anno>:<anno>Function</anno></c>
+ to <c><anno>Args</anno></c>. A link is created
between the calling process and the new process, atomically.
Otherwise works like
<seealso marker="#spawn/3">spawn/3</seealso>.</p>
</desc>
</func>
+
<func>
<name name="spawn_link" arity="4"/>
- <fsummary>Create and link to a new process with a function as entry point on a given node</fsummary>
+ <fsummary>Creates and links to a new process with a function as entry point on a given node.</fsummary>
<desc>
- <p>Returns the pid of a new process started by the application
- of <c><anno>Module</anno>:<anno>Function</anno></c> to <c><anno>Args</anno></c> on <c>Node</c>. A
+ <p>Returns the process identifier (pid) of a new process
+ started by the application
+ of <c><anno>Module</anno>:<anno>Function</anno></c>
+ to <c><anno>Args</anno></c> on <c><anno>Node</anno></c>. A
link is created between the calling process and the new
- process, atomically. If <c><anno>Node</anno></c> does not exist, a useless
- pid is returned (and due to the link, an exit signal with exit
- reason <c>noconnection</c> will be received). Otherwise works
- like <seealso marker="#spawn/3">spawn/3</seealso>.</p>
+ process, atomically. If <c><anno>Node</anno></c> does
+ not exist, a useless pid is returned and an exit signal with
+ reason <c>noconnection</c> is sent to the calling
+ process. Otherwise works like <seealso marker="#spawn/3">spawn/3</seealso>.</p>
</desc>
</func>
+
<func>
<name name="spawn_monitor" arity="1"/>
- <fsummary>Create and monitor a new process with a fun as entry point</fsummary>
+ <fsummary>Creates and monitors a new process with a fun as entry point.</fsummary>
<desc>
- <p>Returns the pid of a new process started by the application
- of <c><anno>Fun</anno></c> to the empty list [] and reference for a monitor
- created to the new process.
+ <p>Returns the process identifier of a new process, started by
+ the application of <c><anno>Fun</anno></c> to the empty list
+ <c>[]</c>,
+ and a reference for a monitor created to the new process.
Otherwise works like
<seealso marker="#spawn/3">spawn/3</seealso>.</p>
</desc>
</func>
+
<func>
<name name="spawn_monitor" arity="3"/>
- <fsummary>Create and monitor a new process with a function as entry point</fsummary>
+ <fsummary>Creates and monitors a new process with a function as entry point.</fsummary>
<desc>
<p>A new process is started by the application
- of <c><anno>Module</anno>:<anno>Function</anno></c> to <c><anno>Args</anno></c>, and the process is
- monitored at the same time. Returns the pid and a reference
- for the monitor.
- Otherwise works like
+ of <c><anno>Module</anno>:<anno>Function</anno></c>
+ to <c><anno>Args</anno></c>. The process is
+ monitored at the same time. Returns the process identifier
+ and a reference for the monitor. Otherwise works like
<seealso marker="#spawn/3">spawn/3</seealso>.</p>
</desc>
</func>
+
<func>
<name name="spawn_opt" arity="2"/>
- <type name="priority_level" />
- <fsummary>Create a new process with a fun as entry point</fsummary>
+ <fsummary>Creates a new process with a fun as entry point.</fsummary>
+ <type name="priority_level"/>
<desc>
- <p>Returns the pid of a new process started by the application
- of <c><anno>Fun</anno></c> to the empty list <c>[]</c>. Otherwise
- works like
+ <p>Returns the process identifier (pid) of a new process
+ started by the application of <c><anno>Fun</anno></c>
+ to the empty list <c>[]</c>. Otherwise works like
<seealso marker="#spawn_opt/4">spawn_opt/4</seealso>.</p>
- <p>If the option <c>monitor</c> is given, the newly created
- process will be monitored and both the pid and reference for
- the monitor will be returned.</p>
+ <p>If option <c>monitor</c> is given, the newly created
+ process is monitored, and both the pid and reference for
+ the monitor is returned.</p>
</desc>
</func>
+
<func>
<name name="spawn_opt" arity="3"/>
- <type name="priority_level" />
- <fsummary>Create a new process with a fun as entry point on a given node</fsummary>
+ <fsummary>Creates a new process with a fun as entry point on a given node.</fsummary>
+ <type name="priority_level"/>
<desc>
- <p>Returns the pid of a new process started by the application
- of <c><anno>Fun</anno></c> to the empty list <c>[]</c> on <c><anno>Node</anno></c>. If
- <c><anno>Node</anno></c> does not exist, a useless pid is returned.
- Otherwise works like
+ <p>Returns the process identifier (pid) of a new process started
+ by the application of <c><anno>Fun</anno></c> to the
+ empty list <c>[]</c> on <c><anno>Node</anno></c>. If
+ <c><anno>Node</anno></c> does not exist, a useless pid is
+ returned. Otherwise works like
<seealso marker="#spawn_opt/4">spawn_opt/4</seealso>.</p>
</desc>
</func>
+
<func>
<name name="spawn_opt" arity="4"/>
- <type name="priority_level" />
- <fsummary>Create a new process with a function as entry point</fsummary>
+ <fsummary>Creates a new process with a function as entry point.</fsummary>
+ <type name="priority_level"/>
<desc>
- <p>Works exactly like
+ <p>Works as
<seealso marker="#spawn/3">spawn/3</seealso>, except that an
extra option list is given when creating the process.</p>
- <p>If the option <c>monitor</c> is given, the newly created
- process will be monitored and both the pid and reference for
- the monitor will be returned.</p>
+ <p>If option <c>monitor</c> is given, the newly created
+ process is monitored, and both the pid and reference for
+ the monitor is returned.</p>
+ <p>The options are as follows:</p>
<taglist>
<tag><c>link</c></tag>
<item>
@@ -5109,112 +5474,123 @@ true</pre>
</item>
<tag><c>monitor</c></tag>
<item>
- <p>Monitor the new process (just like
+ <p>Monitors the new process (like
<seealso marker="#monitor/2">monitor/2</seealso> does).</p>
</item>
- <tag><c>{priority, <anno>Level</anno>}</c></tag>
+ <tag><c>{priority, <anno>Level</anno></c></tag>
<item>
<p>Sets the priority of the new process. Equivalent to
executing
- <seealso marker="#process_flag_priority">process_flag(priority, <anno>Level</anno>)</seealso> in the start function of the new process,
- except that the priority will be set before the process is
- selected for execution for the first time. For more information
- on priorities see
- <seealso marker="#process_flag_priority">process_flag(priority, Level)</seealso>.</p>
+ <seealso marker="#process_flag_priority">process_flag(priority,
+ <anno>Level</anno>)</seealso>
+ in the start function of the new process,
+ except that the priority is set before the process is
+ selected for execution for the first time. For more
+ information on priorities, see
+ <seealso marker="#process_flag_priority">process_flag(priority,
+ <anno>Level</anno>)</seealso>.</p>
</item>
<tag><c>{fullsweep_after, <anno>Number</anno>}</c></tag>
<item>
- <p>This option is only useful for performance tuning.
- In general, you should not use this option unless you
- know that there is problem with execution times and/or
- memory consumption, and you should measure to make sure
- that the option improved matters.
- </p>
+ <p>Useful only for performance tuning. Do not use this
+ option unless you
+ know that there is problem with execution times or
+ memory consumption, and ensure
+ that the option improves matters.</p>
<p>The Erlang runtime system uses a generational garbage
collection scheme, using an "old heap" for data that has
survived at least one garbage collection. When there is
no more room on the old heap, a fullsweep garbage
- collection will be done.</p>
- <p>The <c>fullsweep_after</c> option makes it possible to
+ collection is done.</p>
+ <p>Option <c>fullsweep_after</c> makes it possible to
specify the maximum number of generational collections
- before forcing a fullsweep even if there is still room on
- the old heap. Setting the number to zero effectively
- disables the general collection algorithm, meaning that
+ before forcing a fullsweep, even if there is room on
+ the old heap. Setting the number to zero
+ disables the general collection algorithm, that is,
all live data is copied at every garbage collection.</p>
- <p>Here are a few cases when it could be useful to change
- <c>fullsweep_after</c>. Firstly, if binaries that are no
- longer used should be thrown away as soon as possible.
- (Set <c><anno>Number</anno></c> to zero.) Secondly, a process that
- mostly have short-lived data will be fullsweeped seldom
- or never, meaning that the old heap will contain mostly
- garbage. To ensure a fullsweep once in a while, set
- <c><anno>Number</anno></c> to a suitable value such as 10 or 20.
- Thirdly, in embedded systems with limited amount of RAM
- and no virtual memory, one might want to preserve memory
- by setting <c><anno>Number</anno></c> to zero. (The value may be set
- globally, see
- <seealso marker="#system_flag/2">erlang:system_flag/2</seealso>.)</p>
+ <p>A few cases when it can be useful to change
+ <c>fullsweep_after</c>:</p>
+ <list type="bulleted">
+ <item>If binaries that are no longer used are to be
+ thrown away as soon as possible. (Set
+ <c><anno>Number</anno></c> to zero.)
+ </item>
+ <item>A process that mostly have short-lived data is
+ fullsweeped seldom or never, that is, the old heap
+ contains mostly garbage. To ensure a fullsweep
+ occasionally, set <c><anno>Number</anno></c> to a
+ suitable value, such as 10 or 20.
+ </item>
+ <item>In embedded systems with a limited amount of RAM
+ and no virtual memory, you might want to preserve memory
+ by setting <c><anno>Number</anno></c> to zero.
+ (The value can be set globally, see
+ <seealso marker="#system_flag/2">erlang:system_flag/2</seealso>.)
+ </item>
+ </list>
</item>
<tag><c>{min_heap_size, <anno>Size</anno>}</c></tag>
<item>
- <p>This option is only useful for performance tuning.
- In general, you should not use this option unless you
- know that there is problem with execution times and/or
- memory consumption, and you should measure to make sure
- that the option improved matters.
- </p>
- <p>Gives a minimum heap size in words. Setting this value
- higher than the system default might speed up some
+ <p>Useful only for performance tuning. Do not use this
+ option unless you know that there is problem with
+ execution times or memory consumption, and
+ ensure that the option improves matters.</p>
+ <p>Gives a minimum heap size, in words. Setting this value
+ higher than the system default can speed up some
processes because less garbage collection is done.
- Setting too high value, however, might waste memory and
- slow down the system due to worse data locality.
- Therefore, it is recommended to use this option only for
+ However, setting a too high value can waste memory and
+ slow down the system because of worse data locality.
+ Therefore, use this option only for
fine-tuning an application and to measure the execution
time with various <c><anno>Size</anno></c> values.</p>
</item>
<tag><c>{min_bin_vheap_size, <anno>VSize</anno>}</c></tag>
<item>
- <p>This option is only useful for performance tuning.
- In general, you should not use this option unless you
- know that there is problem with execution times and/or
- memory consumption, and you should measure to make sure
- that the option improved matters.
- </p>
- <p>Gives a minimum binary virtual heap size in words. Setting this value
- higher than the system default might speed up some
+ <p>Useful only for performance tuning. Do not use this
+ option unless you know that there is problem with
+ execution times or memory consumption, and
+ ensure that the option improves matters.</p>
+ <p>Gives a minimum binary virtual heap size, in words.
+ Setting this value
+ higher than the system default can speed up some
processes because less garbage collection is done.
- Setting too high value, however, might waste memory.
- Therefore, it is recommended to use this option only for
+ However, setting a too high value can waste memory.
+ Therefore, use this option only for
fine-tuning an application and to measure the execution
time with various <c><anno>VSize</anno></c> values.</p>
</item>
-
</taglist>
</desc>
</func>
+
<func>
<name name="spawn_opt" arity="5"/>
- <type name="priority_level" />
- <fsummary>Create a new process with a function as entry point on a given node</fsummary>
+ <fsummary>Creates a new process with a function as entry point on a given node.</fsummary>
+ <type name="priority_level"/>
<desc>
- <p>Returns the pid of a new process started by the application
- of <c><anno>Module</anno>:<anno>Function</anno></c> to <c><anno>Args</anno></c> on <c>Node</c>. If
+ <p>Returns the process identifier (pid) of a new process started
+ by the application
+ of <c><anno>Module</anno>:<anno>Function</anno></c> to
+ <c><anno>Args</anno></c> on <c><anno>Node</anno></c>. If
<c><anno>Node</anno></c> does not exist, a useless pid is returned.
Otherwise works like
<seealso marker="#spawn_opt/4">spawn_opt/4</seealso>.</p>
- <note><p>The <c>monitor</c> option is currently not supported by
+ <note><p>Option <c>monitor</c> is not supported by
<c>spawn_opt/5</c>.</p></note>
</desc>
</func>
+
<func>
<name name="split_binary" arity="2"/>
+ <fsummary>Splits a binary into two.</fsummary>
<type_desc variable="Pos">0..byte_size(Bin)</type_desc>
- <fsummary>Split a binary into two</fsummary>
<desc>
- <p>Returns a tuple containing the binaries which are the result
- of splitting <c><anno>Bin</anno></c> into two parts at position <c><anno>Pos</anno></c>.
+ <p>Returns a tuple containing the binaries that are the result
+ of splitting <c><anno>Bin</anno></c> into two parts at
+ position <c><anno>Pos</anno></c>.
This is not a destructive operation. After the operation,
- there will be three binaries altogether.</p>
+ there are three binaries altogether.</p>
+ <p>Example:</p>
<pre>
> <input>B = list_to_binary("0123456789").</input>
&lt;&lt;"0123456789">>
@@ -5228,31 +5604,35 @@ true</pre>
7</pre>
</desc>
</func>
+
<func>
<name name="start_timer" arity="4"/>
- <fsummary>Start a timer</fsummary>
+ <fsummary>Starts a timer.</fsummary>
<desc>
<p>
Starts a timer. When the timer expires, the message
<c>{timeout, <anno>TimerRef</anno>, <anno>Msg</anno>}</c>
- will be sent to the process identified by
+ is sent to the process identified by
<c><anno>Dest</anno></c>.
</p>
- <p>Currently available <c><anno>Option</anno></c>s:</p>
+ <p>Available <c><anno>Option</anno></c>s:</p>
<taglist>
- <tag><c>{abs, Abs}</c></tag>
+ <tag><c>{abs, false}</c></tag>
<item>
<p>
- Absolute <c><anno>Time</anno></c> value. <c>Abs</c>
- defaults to <c>false</c> which means that the
- <c><anno>Time</anno></c> value will be interpreted
- as a time in milli-seconds relative current
+ This is the default. It means the
+ <c><anno>Time</anno></c> value is interpreted
+ as a time in milli-seconds <em>relative</em> current
<seealso marker="time_correction#Erlang_Monotonic_Time">Erlang
- monotonic time</seealso>. When <c>Abs</c> is set to
- <c>true</c>, the <c><anno>Time</anno></c> value will
- be interpreted as an absolute Erlang monotonic time of
- milli-seconds
- <seealso marker="#type_time_unit">time unit</seealso>.
+ monotonic time</seealso>.
+ </p>
+ </item>
+ <tag><c>{abs, true}</c></tag>
+ <item>
+ <p>
+ Absolute <c><anno>Time</anno></c> value. The
+ <c><anno>Time</anno></c> value is interpreted as an
+ absolute Erlang monotonic time in milli-seconds.
</p>
</item>
</taglist>
@@ -5260,7 +5640,7 @@ true</pre>
More <c><anno>Option</anno></c>s may be added in the future.
</p>
<p>
- The absolute point in time that the timer is set to expire on
+ The absolute point in time, the timer is set to expire on,
has to be in the interval
<c>[</c><seealso marker="#system_info_start_time"><c>erlang:system_info(start_time)</c></seealso><c>,
</c><seealso marker="#system_info_end_time"><c>erlang:system_info(end_time)</c></seealso><c>]</c>.
@@ -5268,21 +5648,21 @@ true</pre>
is not allowed to be negative.
</p>
<p>
- If <c><anno>Dest</anno></c> is a <c>pid()</c>, it has to
+ If <c><anno>Dest</anno></c> is a <c>pid()</c>, it must
be a <c>pid()</c> of a process created on the current
runtime system instance. This process may or may not
have terminated. If <c><anno>Dest</anno></c> is an
- <c>atom()</c>, it will be interpreted as the name of a
+ <c>atom()</c>, it is interpreted as the name of a
locally registered process. The process referred to by the
name is looked up at the time of timer expiration. No error
is given if the name does not refer to a process.
</p>
<p>
- If <c><anno>Dest</anno></c> is a <c>pid()</c>, the timer will
- be automatically canceled if the process referred to by the
- <c>pid()</c> is not alive, or when the process exits. This
- feature was introduced in erts version 5.4.11. Note that
- timers will not be automatically canceled when
+ If <c><anno>Dest</anno></c> is a <c>pid()</c>, the timer is
+ automatically canceled if the process referred to by the
+ <c>pid()</c> is not alive, or if the process exits. This
+ feature was introduced in ERTS version 5.4.11. Notice that
+ timers are not automatically canceled when
<c><anno>Dest</anno></c> is an <c>atom()</c>.
</p>
<p>See also
@@ -5290,13 +5670,14 @@ true</pre>
<seealso marker="#cancel_timer/2"><c>erlang:cancel_timer/2</c></seealso>,
and
<seealso marker="#read_timer/2"><c>erlang:read_timer/2</c></seealso>.</p>
- <p>Failure: <c>badarg</c> if the arguments does not satisfy
- the requirements specified above.</p>
+ <p>Failure: <c>badarg</c> if the arguments do not satisfy
+ the requirements specified here.</p>
</desc>
</func>
+
<func>
<name name="start_timer" arity="3"/>
- <fsummary>Start a timer</fsummary>
+ <fsummary>Starts a timer.</fsummary>
<desc>
<p>Starts a timer. The same as calling
<seealso marker="#start_timer/4"><c>erlang:start_timer(<anno>Time</anno>,
@@ -5305,126 +5686,137 @@ true</pre>
</func>
<func>
<name name="statistics" arity="1" clause_i="1"/>
- <fsummary>Information about context switches</fsummary>
+ <fsummary>Information about context switches.</fsummary>
<desc>
- <p><c><anno>ContextSwitches</anno></c> is the total number of context
- switches since the system started.</p>
+ <p>Returns the total number of context switches since the
+ system started.</p>
</desc>
</func>
+
<func>
<name name="statistics" arity="1" clause_i="2"/>
- <fsummary>Information about exact reductions</fsummary>
+ <fsummary>Information about exact reductions.</fsummary>
<desc>
<marker id="statistics_exact_reductions"></marker>
- <note><p><c>statistics(exact_reductions)</c> is
- a more expensive operation than
- <seealso marker="#statistics_reductions">statistics(reductions)</seealso>
- especially on an Erlang machine with SMP support.</p>
- </note>
+ <p>Returns the number of exact reductions.</p>
+ <note><p><c>statistics(exact_reductions)</c> is
+ a more expensive operation than
+ <seealso marker="#statistics_reductions">statistics(reductions)</seealso>,
+ especially on an Erlang machine with SMP support.</p>
+ </note>
</desc>
</func>
+
<func>
<name name="statistics" arity="1" clause_i="3"/>
- <fsummary>Information about garbage collection</fsummary>
+ <fsummary>Information about garbage collection.</fsummary>
<desc>
- <p>This information may not be valid for all implementations.</p>
+ <p>Returns information about garbage collection, for example:</p>
<pre>
> <input>statistics(garbage_collection).</input>
-{85,23961,0}
-</pre>
+{85,23961,0}</pre>
+ <p>This information can be invalid for some implementations.</p>
</desc>
</func>
+
<func>
<name name="statistics" arity="1" clause_i="4"/>
- <fsummary>Information about io</fsummary>
+ <fsummary>Information about I/O.</fsummary>
<desc>
- <p><c><anno>Input</anno></c> is the total number of bytes received
- through ports, and <c><anno>Output</anno></c> is the total number of
- bytes output to ports.</p>
+ <p>Returns <c><anno>Input</anno></c>,
+ which is the total number of bytes
+ received through ports, and <c><anno>Output</anno></c>,
+ which is the total number of bytes output to ports.</p>
</desc>
</func>
+
<func>
<name name="statistics" arity="1" clause_i="5"/>
- <fsummary>Information about reductions</fsummary>
+ <fsummary>Information about reductions.</fsummary>
<desc>
<marker id="statistics_reductions"></marker>
- <note>
- <p>Since erts-5.5 (OTP release R11B)
- this value does not include reductions performed in current
- time slices of currently scheduled processes. If an
- exact value is wanted, use
- <seealso marker="#statistics_exact_reductions">statistics(exact_reductions)</seealso>.</p>
- </note>
+ <p>Returns information about reductions, for example:</p>
<pre>
> <input>statistics(reductions).</input>
-{2046,11}
-</pre>
+{2046,11}</pre>
+ <note><p>As from <c>ERTS</c> 5.5 (OTP R11B),
+ this value does not include reductions performed in current
+ time slices of currently scheduled processes. If an
+ exact value is wanted, use
+ <seealso marker="#statistics_exact_reductions">statistics(exact_reductions)</seealso>.</p>
+ </note>
</desc>
</func>
+
<func>
<name name="statistics" arity="1" clause_i="6"/>
- <fsummary>Information about the run-queue</fsummary>
+ <fsummary>Information about the run-queue.</fsummary>
<desc>
- <p>Returns the total length of the run queues, that is, the number
- of processes that are ready to run on all available run queues.</p>
+ <p>Returns the total length of run-queues, that is, the number
+ of processes that are ready to run on all available run-queues.</p>
</desc>
</func>
+
<func>
<name name="statistics" arity="1" clause_i="7"/>
- <fsummary>Information about run-time</fsummary>
+ <fsummary>Information about runtime.</fsummary>
<desc>
- <p>Note that the run-time is the sum of the run-time for all
- threads in the Erlang run-time system and may therefore be greater
- than the wall-clock time. The time is returned in milliseconds.</p>
+ <p>Returns information about runtime, in milliseconds.</p>
+ <p>This is the sum of the runtime for all threads
+ in the Erlang runtime system and can therefore be greater
+ than the wall clock time.</p>
+ <p>Example:</p>
<pre>
> <input>statistics(runtime).</input>
-{1690,1620}
-</pre>
+{1690,1620}</pre>
</desc>
</func>
+
<func>
<name name="statistics" arity="1" clause_i="8"/>
- <fsummary>Information about each schedulers work time</fsummary>
- <desc>
- <marker id="statistics_scheduler_wall_time"></marker>
- <p>
- Returns a list of tuples with <c>{<anno>SchedulerId</anno>,
- <anno>ActiveTime</anno>, <anno>TotalTime</anno>}</c>, where
- <c>SchedulerId</c> is an integer id of the scheduler, <c>ActiveTime</c> is
- the duration the scheduler has been busy, <c>TotalTime</c> is the total time duration since
- <seealso marker="#system_flag_scheduler_wall_time">scheduler_wall_time</seealso>
- activation. The time unit is not defined and may be subject to change
- between releases, operating systems and system restarts.
- <c>scheduler_wall_time</c> should only be used to calculate relative
- values for scheduler-utilization. <c>ActiveTime</c> can never exceed <c>TotalTime</c>.
- </p>
-
- <p>The definition of a busy scheduler is when it is not idle or not
- scheduling (selecting) a process or port, meaning; executing process
- code, executing linked-in-driver or NIF code, executing
- built-in-functions or any other runtime handling, garbage collecting
- or handling any other memory management. Note, a scheduler may also be
- busy even if the operating system has scheduled out the scheduler
- thread.
- </p>
-
- <p>
- Returns <c>undefined</c> if the system flag
- <seealso marker="#system_flag_scheduler_wall_time">scheduler_wall_time</seealso>
- is turned off.
- </p>
-
- <p>The list of scheduler information is unsorted and may appear in different order
- between calls.
- </p>
- <p>Using <c>scheduler_wall_time</c> to calculate scheduler utilization.</p>
+ <fsummary>Information about each schedulers work time.</fsummary>
+ <desc>
+ <marker id="statistics_scheduler_wall_time"></marker>
+ <p>Returns a list of tuples with
+ <c>{<anno>SchedulerId</anno>, <anno>ActiveTime</anno>,
+ <anno>TotalTime</anno>}</c>, where
+ <c><anno>SchedulerId</anno></c> is an integer ID of the scheduler,
+ <c><anno>ActiveTime</anno></c> is
+ the duration the scheduler has been busy, and
+ <c><anno>TotalTime</anno></c> is the total time duration since
+ <seealso marker="#system_flag_scheduler_wall_time">scheduler_wall_time</seealso>
+ activation. The time unit is undefined and can be subject
+ to change between releases, OSs, and system restarts.
+ <c>scheduler_wall_time</c> is only to be used to
+ calculate relative values for scheduler-utilization.
+ <c><anno>ActiveTime</anno></c> can never exceed
+ <c><anno>TotalTime</anno></c>.</p>
+ <p>The definition of a busy scheduler is when it is not idle
+ and is not scheduling (selecting) a process or port,
+ that is:</p>
+ <list type="bulleted">
+ <item>Executing process code</item>
+ <item>Executing linked-in-driver or NIF code</item>
+ <item>Executing built-in-functions, or any other runtime
+ handling</item>
+ <item>Garbage collecting</item>
+ <item>Handling any other memory management</item>
+ </list>
+ <p>Notice that a scheduler can also be busy even if the
+ OS has scheduled out the scheduler thread.</p>
+ <p>Returns <c>undefined</c> if system flag
+ <seealso marker="#system_flag_scheduler_wall_time">scheduler_wall_time</seealso>
+ is turned off.</p>
+ <p>The list of scheduler information is unsorted and can
+ appear in different order between calls.</p>
+ <p>Using <c>scheduler_wall_time</c> to calculate scheduler-utilization:</p>
<pre>
> <input>erlang:system_flag(scheduler_wall_time, true).</input>
false
> <input>Ts0 = lists:sort(erlang:statistics(scheduler_wall_time)), ok.</input>
-ok
-</pre>
- <p>Some time later we will take another snapshot and calculate scheduler-utilization per scheduler.</p>
+ok</pre>
+ <p>Some time later the user takes another snapshot and calculates
+ scheduler-utilization per scheduler, for example:</p>
<pre>
> <input>Ts1 = lists:sort(erlang:statistics(scheduler_wall_time)), ok.</input>
ok
@@ -5437,86 +5829,90 @@ ok
{5,0.9717956667018103},
{6,0.9739235846420741},
{7,0.973237033077876},
- {8,0.9741297293248656}]
-</pre>
- <p>Using the same snapshots to calculate a total scheduler-utilization.</p>
+ {8,0.9741297293248656}]</pre>
+ <p>Using the same snapshots to calculate a total scheduler-utilization:</p>
<pre>
> <input>{A, T} = lists:foldl(fun({{_, A0, T0}, {_, A1, T1}}, {Ai,Ti}) ->
{Ai + (A1 - A0), Ti + (T1 - T0)} end, {0, 0}, lists:zip(Ts0,Ts1)), A/T.</input>
-0.9769136803764825
-</pre>
+0.9769136803764825</pre>
<note>
- <p><c>scheduler_wall_time</c> is by default disabled. Use <c>erlang:system_flag(scheduler_wall_time, true)</c> to enable it. </p>
+ <p><c>scheduler_wall_time</c> is by default disabled. To
+ enable it, use
+ <c>erlang:system_flag(scheduler_wall_time, true)</c>.</p>
</note>
</desc>
</func>
+
<func>
<name name="statistics" arity="1" clause_i="9"/>
- <fsummary>Information about wall-clock</fsummary>
+ <fsummary>Information about wall clock.</fsummary>
<desc>
- <p><c>wall_clock</c> can be used in the same manner as
+ <p>Returns information about wall clock. <c>wall_clock</c> can
+ be used in the same manner as
<c>runtime</c>, except that real time is measured as
opposed to runtime or CPU time.</p>
</desc>
</func>
+
<func>
<name name="suspend_process" arity="2"/>
- <fsummary>Suspend a process</fsummary>
+ <fsummary>Suspends a process.</fsummary>
<desc>
<p>Increases the suspend count on the process identified by
- <c><anno>Suspendee</anno></c> and puts it in the suspended state if it isn't
- already in the suspended state. A suspended process will not be
- scheduled for execution until the process has been resumed.
- </p>
-
+ <c><anno>Suspendee</anno></c> and puts it in the suspended
+ state if it is not
+ already in that state. A suspended process will not be
+ scheduled for execution until the process has been resumed.</p>
<p>A process can be suspended by multiple processes and can
be suspended multiple times by a single process. A suspended
- process will not leave the suspended state until its suspend
- count reach zero. The suspend count of <c><anno>Suspendee</anno></c>
- is decreased when
+ process does not leave the suspended state until its suspend
+ count reaches zero. The suspend count of
+ <c><anno>Suspendee</anno></c> is decreased when
<seealso marker="#resume_process/1">erlang:resume_process(<anno>Suspendee</anno>)</seealso>
is called by the same process that called
- <c>erlang:suspend_process(<anno>Suspendee</anno>)</c>. All increased suspend
- counts on other processes acquired by a process will automatically be
+ <c>erlang:suspend_process(<anno>Suspendee</anno>)</c>.
+ All increased suspend
+ counts on other processes acquired by a process are automatically
decreased when the process terminates.</p>
-
- <p>Currently the following options (<c><anno>Opt</anno></c>s) are available:</p>
+ <p>The options (<c><anno>Opt</anno></c>s) are as follows:</p>
<taglist>
<tag><c>asynchronous</c></tag>
<item>
A suspend request is sent to the process identified by
- <c><anno>Suspendee</anno></c>. <c><anno>Suspendee</anno></c> will eventually suspend
- unless it is resumed before it was able to suspend. The caller
- of <c>erlang:suspend_process/2</c> will return immediately,
- regardless of whether the <c><anno>Suspendee</anno></c> has suspended yet
- or not. Note that the point in time when the <c><anno>Suspendee</anno></c>
- will actually suspend cannot be deduced from other events
- in the system. The only guarantee given is that the
- <c><anno>Suspendee</anno></c> will <em>eventually</em> suspend (unless it
- is resumed). If the <c>asynchronous</c> option has <em>not</em>
- been passed, the caller of <c>erlang:suspend_process/2</c> will
- be blocked until the <c><anno>Suspendee</anno></c> has actually suspended.
+ <c><anno>Suspendee</anno></c>. <c><anno>Suspendee</anno></c>
+ eventually suspends
+ unless it is resumed before it could suspend. The caller
+ of <c>erlang:suspend_process/2</c> returns immediately,
+ regardless of whether <c><anno>Suspendee</anno></c> has
+ suspended yet or not. The point in time when
+ <c><anno>Suspendee</anno></c> suspends cannot be deduced
+ from other events in the system. It is only guaranteed that
+ <c><anno>Suspendee</anno></c> <em>eventually</em> suspends
+ (unless it
+ is resumed). If option <c>asynchronous</c> has <em>not</em>
+ been passed, the caller of <c>erlang:suspend_process/2</c> is
+ blocked until <c><anno>Suspendee</anno></c> has suspended.
</item>
<tag><c>unless_suspending</c></tag>
<item>
- The process identified by <c><anno>Suspendee</anno></c> will be suspended
- unless the calling process already is suspending the
- <c><anno>Suspendee</anno></c>. If <c>unless_suspending</c> is combined
- with the <c>asynchronous</c> option, a suspend request will be
- sent unless the calling process already is suspending the
- <c><anno>Suspendee</anno></c> or if a suspend request already has been sent
- and is in transit. If the calling process already is suspending
- the <c><anno>Suspendee</anno></c>, or if combined with the <c>asynchronous</c>
- option and a send request already is in transit,
- <c>false</c> is returned and the suspend count on <c><anno>Suspendee</anno></c>
- will remain unchanged.
+ The process identified by <c><anno>Suspendee</anno></c> is
+ suspended unless the calling process already is suspending
+ <c><anno>Suspendee</anno></c>.
+ If <c>unless_suspending</c> is combined
+ with option <c>asynchronous</c>, a suspend request is
+ sent unless the calling process already is suspending
+ <c><anno>Suspendee</anno></c> or if a suspend request
+ already has been sent and is in transit. If the calling
+ process already is suspending <c><anno>Suspendee</anno></c>,
+ or if combined with option <c>asynchronous</c>
+ and a send request already is in transit,
+ <c>false</c> is returned and the suspend count on
+ <c><anno>Suspendee</anno></c> remains unchanged.
</item>
</taglist>
-
<p>If the suspend count on the process identified by
- <c><anno>Suspendee</anno></c> was increased, <c>true</c> is returned; otherwise,
- <c>false</c> is returned.</p>
-
+ <c><anno>Suspendee</anno></c> is increased, <c>true</c>
+ is returned, otherwise <c>false</c>.</p>
<warning>
<p>This BIF is intended for debugging only.</p>
</warning>
@@ -5524,310 +5920,322 @@ ok
<taglist>
<tag><c>badarg</c></tag>
<item>
- If <c><anno>Suspendee</anno></c> isn't a process identifier.
+ If <c><anno>Suspendee</anno></c> is not a process identifier.
</item>
<tag><c>badarg</c></tag>
<item>
- If the process identified by <c><anno>Suspendee</anno></c> is same the process as
- the process calling <c>erlang:suspend_process/2</c>.
+ If the process identified by <c><anno>Suspendee</anno></c>
+ is the same process
+ as the process calling <c>erlang:suspend_process/2</c>.
</item>
<tag><c>badarg</c></tag>
<item>
- If the process identified by <c><anno>Suspendee</anno></c> is not alive.
+ If the process identified by <c><anno>Suspendee</anno></c>
+ is not alive.
</item>
<tag><c>badarg</c></tag>
<item>
- If the process identified by <c><anno>Suspendee</anno></c> resides on another node.
+ If the process identified by <c><anno>Suspendee</anno></c>
+ resides on another node.
</item>
<tag><c>badarg</c></tag>
<item>
- If <c><anno>OptList</anno></c> isn't a proper list of valid <c><anno>Opt</anno></c>s.
+ If <c><anno>OptList</anno></c> is not a proper list of valid
+ <c><anno>Opt</anno></c>s.
</item>
<tag><c>system_limit</c></tag>
<item>
- If the process identified by <c><anno>Suspendee</anno></c> has been suspended more
- times by the calling process than can be represented by the
- currently used internal data structures. The current system limit
- is larger than 2 000 000 000 suspends, and it will never be less
- than that.
+ If the process identified by <c><anno>Suspendee</anno></c>
+ has been suspended
+ more times by the calling process than can be represented by the
+ currently used internal data structures. The system limit is
+ higher than 2,000,000,000 suspends and will never be lower.
</item>
</taglist>
</desc>
</func>
+
<func>
<name name="suspend_process" arity="1"/>
- <fsummary>Suspend a process</fsummary>
+ <fsummary>Suspends a process.</fsummary>
<desc>
- <p>Suspends the process identified by <c><anno>Suspendee</anno></c>. The
- same as calling
- <seealso marker="#suspend_process/2">erlang:suspend_process(<anno>Suspendee</anno>, [])</seealso>. For more information see the documentation of <seealso marker="#suspend_process/2">erlang:suspend_process/2</seealso>.
- </p>
+ <p>Suspends the process identified by
+ <c><anno>Suspendee</anno></c>. The same as calling
+ <seealso marker="#suspend_process/2">erlang:suspend_process(<anno>Suspendee</anno>,
+ [])</seealso>.</p>
<warning>
<p>This BIF is intended for debugging only.</p>
</warning>
</desc>
</func>
+
<func>
<name name="system_flag" arity="2" clause_i="1"/>
- <fsummary>Set system flag backtrace_depth</fsummary>
+ <fsummary>Sets system flag <c>backtrace_depth</c>.</fsummary>
<desc>
<p>Sets the maximum depth of call stack back-traces in the
exit reason element of <c>'EXIT'</c> tuples.</p>
<p>Returns the old value of the flag.</p>
</desc>
</func>
+
<func>
<name name="system_flag" arity="2" clause_i="2"/>
+ <fsummary>Sets system flag <c>cpu_topology</c>.</fsummary>
<type name="cpu_topology"/>
<type name="level_entry"/>
<type name="level_tag"/>
<type name="sub_level"/>
<type name="info_list"/>
- <fsummary>Set system flag cpu_topology</fsummary>
<desc>
<warning>
<p><marker id="system_flag_cpu_topology"></marker>
- This argument is <em>deprecated</em> and
- scheduled for removal in erts-5.10/OTP-R16. Instead of using
- this argument you are advised to use the <c>erl</c> command
- line argument <seealso marker="erts:erl#+sct">+sct</seealso>.
- When this argument has been removed a final CPU topology to use
- will be determined at emulator boot time.</p>
+ This argument is <em>deprecated</em> and scheduled for
+ removal in <c>ERTS</c> 5.10/OTP R16. Instead of using this
+ argument, use command-line argument
+ <seealso marker="erts:erl#+sct">+sct</seealso> in
+ <c>erl(1)</c>.</p>
+ <p>When this argument is removed, a final CPU topology
+ to use is determined at emulator boot time.</p>
</warning>
- <p>Sets the user defined <c><anno>CpuTopology</anno></c>. The user defined
- CPU topology will override any automatically detected
- CPU topology. By passing <c>undefined</c> as <c><anno>CpuTopology</anno></c>
- the system will revert back to the CPU topology automatically
+ <p>Sets the user-defined <c><anno>CpuTopology</anno></c>.
+ The user-defined
+ CPU topology overrides any automatically detected
+ CPU topology. By passing <c>undefined</c> as
+ <c><anno>CpuTopology</anno></c>,
+ the system reverts to the CPU topology automatically
detected. The returned value equals the value returned
from <c>erlang:system_info(cpu_topology)</c> before the
- change was made.
- </p>
+ change was made.</p>
<p>Returns the old value of the flag.</p>
<p>The CPU topology is used when binding schedulers to logical
processors. If schedulers are already bound when the CPU
- topology is changed, the schedulers will be sent a request
- to rebind according to the new CPU topology.
- </p>
- <p>The user defined CPU topology can also be set by passing
- the <seealso marker="erts:erl#+sct">+sct</seealso> command
- line argument to <c>erl</c>.
- </p>
- <p>For information on the <c><anno>CpuTopology</anno></c> type
- and more, see the documentation of
- <seealso marker="#system_info_cpu_topology">erlang:system_info(cpu_topology)</seealso>,
- and the <c>erl</c> <seealso marker="erts:erl#+sct">+sct</seealso>
- and <seealso marker="erts:erl#+sbt">+sbt</seealso>
- command line flags.
- </p>
+ topology is changed, the schedulers are sent a request
+ to rebind according to the new CPU topology.</p>
+ <p>The user-defined CPU topology can also be set by passing
+ command-line argument
+ <seealso marker="erts:erl#+sct">+sct</seealso> to
+ <c>erl(1)</c>.</p>
+ <p>For information on type <c><anno>CpuTopology</anno></c>
+ and more, see
+ <seealso marker="#system_info_cpu_topology">erlang:system_info(cpu_topology)</seealso>
+ as well as the command-line flags
+ <seealso marker="erts:erl#+sct">+sct</seealso> and
+ <seealso marker="erts:erl#+sbt">+sbt</seealso> in
+ <c>erl(1)</c>.</p>
</desc>
</func>
+
<func>
<name name="system_flag" arity="2" clause_i="3"/>
- <fsummary>Set system flag dirty CPU schedulers online</fsummary>
+ <fsummary>Sets <c>system_flag_dirty_cpu_schedulers_online</c>.</fsummary>
<desc>
<p><marker id="system_flag_dirty_cpu_schedulers_online"></marker>
- Sets the amount of dirty CPU schedulers online. Valid range is
- <![CDATA[1 <= DirtyCPUSchedulersOnline <= N]]> where <c>N</c> is the
- lesser of the return values of <c>erlang:system_info(dirty_cpu_schedulers)</c> and
- <c>erlang:system_info(schedulers_online)</c>.
- </p>
+ Sets the number of dirty CPU schedulers online. Range is
+ <![CDATA[1 <= DirtyCPUSchedulersOnline <= N]]>, where <c>N</c>
+ is the smallest of the return values of
+ <c>erlang:system_info(dirty_cpu_schedulers)</c> and
+ <c>erlang:system_info(schedulers_online)</c>.</p>
<p>Returns the old value of the flag.</p>
- <p>Note that the number of dirty CPU schedulers online may change if the number of
- schedulers online changes. For example, if there are 12 schedulers and all are
- online, and 6 dirty CPU schedulers, all online as well, and <c>system_flag/2</c>
- is used to set the number of schedulers online to 6, then the number of dirty
- CPU schedulers online is automatically decreased by half as well, down to 3.
- Similarly, the number of dirty CPU schedulers online increases proportionally
- to increases in the number of schedulers online.</p>
- <p><em>Note that the dirty schedulers functionality is experimental</em>, and
- that you have to enable support for dirty schedulers when building OTP in order
- to try out the functionality.</p>
- <p>For more information see
+ <p>The number of dirty CPU schedulers online can change if the
+ number of schedulers online changes. For example, if 12
+ schedulers and 6 dirty CPU schedulers are online, and
+ <c>system_flag/2</c> is used to set the number of
+ schedulers online to 6, then the number of dirty CPU
+ schedulers online is automatically decreased by half as well,
+ down to 3. Similarly, the number of dirty CPU schedulers
+ online increases proportionally to increases in the number of
+ schedulers online.</p>
+ <note><p>The dirty schedulers functionality is experimental.
+ Enable support for dirty schedulers when building OTP to
+ try out the functionality.</p>
+ </note>
+ <p>For more information, see
<seealso marker="#system_info_dirty_cpu_schedulers">erlang:system_info(dirty_cpu_schedulers)</seealso>
and
- <seealso marker="#system_info_dirty_cpu_schedulers_online">erlang:system_info(dirty_cpu_schedulers_online)</seealso>.
- </p>
+ <seealso marker="#system_info_dirty_cpu_schedulers_online">erlang:system_info(dirty_cpu_schedulers_online)</seealso>.</p>
</desc>
</func>
+
<func>
<name name="system_flag" arity="2" clause_i="4"/>
- <fsummary>Set system flag fullsweep_after</fsummary>
+ <fsummary>Sets system flag <c>fullsweep_after</c>.</fsummary>
<desc>
- <p><c><anno>Number</anno></c> is a non-negative integer which indicates
+ <p>Sets system flag <c>fullsweep_after</c>.
+ <c><anno>Number</anno></c> is a non-negative integer indicating
how many times generational garbage collections can be
done without forcing a fullsweep collection. The value
- applies to new processes; processes already running are
+ applies to new processes, while processes already running are
not affected.</p>
<p>Returns the old value of the flag.</p>
<p>In low-memory systems (especially without virtual
- memory), setting the value to 0 can help to conserve
+ memory), setting the value to <c>0</c> can help to conserve
memory.</p>
- <p>An alternative way to set this value is through the
- (operating system) environment variable
- <c>ERL_FULLSWEEP_AFTER</c>.</p>
+ <p>This value can also be set through (OS)
+ environment variable <c>ERL_FULLSWEEP_AFTER</c>.</p>
</desc>
</func>
+
<func>
<name name="system_flag" arity="2" clause_i="5"/>
- <fsummary>Set system flag min_heap_size</fsummary>
- <desc>
- <p>Sets the default minimum heap size for processes. The
- size is given in words. The new <c>min_heap_size</c> only
- effects processes spawned after the change of
- <c>min_heap_size</c> has been made.
- The <c>min_heap_size</c> can be set for individual
- processes by use of
+ <fsummary>Sets system flag <c>min_heap_size</c>.</fsummary>
+ <desc>
+ <p>Sets the default minimum heap size for processes. The size
+ is given in words. The new <c>min_heap_size</c> effects
+ only processes spawned after the change of
+ <c>min_heap_size</c> has been made. <c>min_heap_size</c>
+ can be set for individual processes by using
<seealso marker="#spawn_opt/4">spawn_opt/N</seealso> or
- <seealso marker="#process_flag/2">process_flag/2</seealso>. </p>
+ <seealso marker="#process_flag/2">process_flag/2</seealso>.</p>
<p>Returns the old value of the flag.</p>
</desc>
</func>
+
<func>
<name name="system_flag" arity="2" clause_i="6"/>
- <fsummary>Set system flag min_bin_vheap_size</fsummary>
+ <fsummary>Sets system flag <c>min_bin_vheap_size</c>.</fsummary>
<desc>
- <p>Sets the default minimum binary virtual heap size for processes. The
- size is given in words. The new <c>min_bin_vhheap_size</c> only
- effects processes spawned after the change of
+ <p>Sets the default minimum binary virtual heap size for
+ processes. The size is given in words.
+ The new <c>min_bin_vhheap_size</c> effects only
+ processes spawned after the change of
<c>min_bin_vhheap_size</c> has been made.
- The <c>min_bin_vheap_size</c> can be set for individual
- processes by use of
+ <c>min_bin_vheap_size</c> can be set for individual
+ processes by using
<seealso marker="#spawn_opt/4">spawn_opt/N</seealso> or
- <seealso marker="#process_flag/2">process_flag/2</seealso>. </p>
+ <seealso marker="#process_flag/2">process_flag/2</seealso>.</p>
<p>Returns the old value of the flag.</p>
</desc>
</func>
+
<func>
<name name="system_flag" arity="2" clause_i="7"/>
- <fsummary>Set system flag multi_scheduling</fsummary>
+ <fsummary>Sets system flag <c>multi_scheduling</c>.</fsummary>
<desc>
<p><marker id="system_flag_multi_scheduling"></marker>
If multi-scheduling is enabled, more than one scheduler
thread is used by the emulator. Multi-scheduling can be
- blocked. When multi-scheduling has been blocked, only
- one scheduler thread will schedule Erlang processes.</p>
- <p>If <c><anno>BlockState</anno> =:= block</c>, multi-scheduling will
- be blocked. If <c><anno>BlockState</anno> =:= unblock</c> and no-one
- else is blocking multi-scheduling and this process has
- only blocked one time, multi-scheduling will be unblocked.
- One process can block multi-scheduling multiple times.
- If a process has blocked multiple times, it has to
+ blocked. When multi-scheduling is blocked, only
+ one scheduler thread schedules Erlang processes.</p>
+ <p>If <c><anno>BlockState</anno> =:= block</c>, multi-scheduling is
+ blocked. If <c><anno>BlockState</anno> =:= unblock</c> and no one
+ else blocks multi-scheduling, and this process has
+ blocked only once, multi-scheduling is unblocked.</p>
+ <p>One process can block multi-scheduling multiple times.
+ If a process has blocked multiple times, it must
unblock exactly as many times as it has blocked before it
has released its multi-scheduling block. If a process that
- has blocked multi-scheduling exits, it will release its
+ has blocked multi-scheduling exits, it releases its
blocking of multi-scheduling.</p>
<p>The return values are <c>disabled</c>, <c>blocked</c>,
or <c>enabled</c>. The returned value describes the
state just after the call to
<c>erlang:system_flag(multi_scheduling, <anno>BlockState</anno>)</c>
- has been made. The return values are described in the
- documentation of <seealso marker="#system_info_multi_scheduling">erlang:system_info(multi_scheduling)</seealso>.</p>
- <p><em>NOTE</em>: Blocking of multi-scheduling should normally
- not be needed. If you feel that you need to
- block multi-scheduling, think through the
- problem at least a couple of times again.
- Blocking multi-scheduling should only be used
- as a last resort since it will most likely be
- a <em>very inefficient</em> way to solve the
- problem.</p>
- <p>See also <seealso marker="#system_info_multi_scheduling">erlang:system_info(multi_scheduling)</seealso>,
+ has been made. For information about the return values, see
+ <seealso marker="#system_info_multi_scheduling">erlang:system_info(multi_scheduling)</seealso>.</p>
+ <note><p>Blocking of multi-scheduling is normally not needed.
+ If you feel that you need to block multi-scheduling,
+ consider it a few more times again. Blocking multi-scheduling
+ is only to be used as a last resort, as it is most likely
+ a <em>very inefficient</em> way to solve the problem.</p>
+ </note>
+ <p>See also
+ <seealso marker="#system_info_multi_scheduling">erlang:system_info(multi_scheduling)</seealso>,
<seealso marker="#system_info_multi_scheduling_blockers">erlang:system_info(multi_scheduling_blockers)</seealso>, and
<seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso>.</p>
</desc>
</func>
+
<func>
<name name="system_flag" arity="2" clause_i="8"/>
+ <fsummary>Sets system flag <c>scheduler_bind_type</c>.</fsummary>
<type name="scheduler_bind_type"/>
- <fsummary>Set system flag scheduler_bind_type</fsummary>
<desc>
<warning>
<p><marker id="system_flag_scheduler_bind_type"></marker>
- This argument is <em>deprecated</em> and
- scheduled for removal in erts-5.10/OTP-R16. Instead of using
- this argument you are advised to use the <c>erl</c> command
- line argument <seealso marker="erts:erl#+sbt">+sbt</seealso>.
- When this argument has been removed a final scheduler bind type
- to use will be determined at emulator boot time.</p>
+ This argument is <em>deprecated</em> and scheduled for
+ removal in <c>ERTS</c> 5.10/OTP R16. Instead of using this
+ argument, use command-line argument
+ <seealso marker="erts:erl#+sbt">+sbt</seealso> in <c>erl(1)</c>.
+ When this argument is removed, a final scheduler bind
+ type to use is determined at emulator boot time.</p>
</warning>
<p>Controls if and how schedulers are bound to logical
processors.</p>
- <p>When <c>erlang:system_flag(scheduler_bind_type, <anno>How</anno>)</c> is
- called, an asynchronous signal is sent to all schedulers
- online which causes them to try to bind or unbind as requested.
- <em>NOTE:</em> If a scheduler fails to bind, this
- will often be silently ignored. This since it isn't always
- possible to verify valid logical processor identifiers. If
- an error is reported, it will be reported to the
- <c>error_logger</c>. If you want to verify that the
- schedulers actually have bound as requested, call
- <seealso marker="#system_info_scheduler_bindings">erlang:system_info(scheduler_bindings)</seealso>.
- </p>
- <p>Schedulers can currently only be bound on newer Linux,
+ <p>When <c>erlang:system_flag(scheduler_bind_type, <anno>How</anno>)</c>
+ is called, an asynchronous signal is sent to all schedulers
+ online, causing them to try to bind or unbind as requested.</p>
+ <note><p>If a scheduler fails to bind, this is often silently
+ ignored, as it is not always possible to verify valid
+ logical processor identifiers. If an error is reported,
+ it is reported to <c>error_logger</c>. To verify that the
+ schedulers have bound as requested, call
+ <seealso marker="#system_info_scheduler_bindings">erlang:system_info(scheduler_bindings)</seealso>.</p>
+ </note>
+ <p>Schedulers can be bound on newer Linux,
Solaris, FreeBSD, and Windows systems, but more systems will be
- supported in the future.
- </p>
+ supported in future releases.</p>
<p>In order for the runtime system to be able to bind schedulers,
- the CPU topology needs to be known. If the runtime system fails
- to automatically detect the CPU topology, it can be defined.
+ the CPU topology must be known. If the runtime system fails
+ to detect the CPU topology automatically, it can be defined.
For more information on how to define the CPU topology, see
- the <c>erl</c> <seealso marker="erts:erl#+sct">+sct</seealso> command
- line flag.
- </p>
- <p>The runtime system will by default <em>not</em> bind schedulers
- to logical processors.
- </p>
- <p><em>NOTE:</em> If the Erlang runtime system is the only
- operating system process that binds threads to logical processors,
- this improves the performance of the runtime system. However,
- if other operating system processes (as for example another Erlang
- runtime system) also bind threads to logical processors, there
- might be a performance penalty instead. In some cases this
- performance penalty might be severe. If this is the case, you
- are advised to not bind the schedulers.</p>
- <p>Schedulers can be bound in different ways. The <c><anno>How</anno></c>
- argument determines how schedulers are bound. <c><anno>How</anno></c> can
- currently be one of:</p>
+ command-line flag <seealso marker="erts:erl#+sct">+sct</seealso>
+ in <c>erl(1)</c>.</p>
+ <p>The runtime system does by default <em>not</em> bind schedulers
+ to logical processors.</p>
+ <note><p>If the Erlang runtime system is the only OS
+ process binding threads to logical processors, this
+ improves the performance of the runtime system. However,
+ if other OS processes (for example, another Erlang
+ runtime system) also bind threads to logical processors,
+ there can be a performance penalty instead. Sometimes this
+ performance penalty can be severe. If so, it is recommended
+ to not bind the schedulers.</p>
+ </note>
+ <p>Schedulers can be bound in different ways. Argument
+ <c><anno>How</anno></c> determines how schedulers are
+ bound and can be any of the following:</p>
<taglist>
<tag><c>unbound</c></tag>
- <item><p>Same as the <c>erl</c> command line argument
- <seealso marker="erts:erl#+sbt">+sbt u</seealso>.
+ <item><p>Same as command-line argument
+ <seealso marker="erts:erl#+sbt">+sbt u</seealso> in <c>erl(1)</c>.
</p></item>
<tag><c>no_spread</c></tag>
- <item><p>Same as the <c>erl</c> command line argument
- <seealso marker="erts:erl#+sbt">+sbt ns</seealso>.
+ <item><p>Same as command-line argument
+ <seealso marker="erts:erl#+sbt">+sbt ns</seealso> in <c>erl(1)</c>.
</p></item>
<tag><c>thread_spread</c></tag>
- <item><p>Same as the <c>erl</c> command line argument
- <seealso marker="erts:erl#+sbt">+sbt ts</seealso>.
+ <item><p>Same as command-line argument
+ <seealso marker="erts:erl#+sbt">+sbt ts</seealso> in <c>erl(1)</c>.
</p></item>
<tag><c>processor_spread</c></tag>
- <item><p>Same as the <c>erl</c> command line argument
- <seealso marker="erts:erl#+sbt">+sbt ps</seealso>.
+ <item><p>Same as command-line argument
+ <seealso marker="erts:erl#+sbt">+sbt ps</seealso> in <c>erl(1)</c>.
</p></item>
<tag><c>spread</c></tag>
- <item><p>Same as the <c>erl</c> command line argument
- <seealso marker="erts:erl#+sbt">+sbt s</seealso>.
+ <item><p>Same as command-line argument
+ <seealso marker="erts:erl#+sbt">+sbt s</seealso> in <c>erl(1)</c>.
</p></item>
<tag><c>no_node_thread_spread</c></tag>
- <item><p>Same as the <c>erl</c> command line argument
- <seealso marker="erts:erl#+sbt">+sbt nnts</seealso>.
+ <item><p>Same as command-line argument
+ <seealso marker="erts:erl#+sbt">+sbt nnts</seealso> in <c>erl(1)</c>.
</p></item>
<tag><c>no_node_processor_spread</c></tag>
- <item><p>Same as the <c>erl</c> command line argument
- <seealso marker="erts:erl#+sbt">+sbt nnps</seealso>.
+ <item><p>Same as command-line argument
+ <seealso marker="erts:erl#+sbt">+sbt nnps</seealso> in <c>erl(1)</c>.
</p></item>
<tag><c>thread_no_node_processor_spread</c></tag>
- <item><p>Same as the <c>erl</c> command line argument
- <seealso marker="erts:erl#+sbt">+sbt tnnps</seealso>.
+ <item><p>Same as command-line argument
+ <seealso marker="erts:erl#+sbt">+sbt tnnps</seealso> in <c>erl(1)</c>.
</p></item>
<tag><c>default_bind</c></tag>
- <item><p>Same as the <c>erl</c> command line argument
- <seealso marker="erts:erl#+sbt">+sbt db</seealso>.
+ <item><p>Same as command-line argument
+ <seealso marker="erts:erl#+sbt">+sbt db</seealso> in <c>erl(1)</c>.
</p></item>
</taglist>
- <p>The value returned equals <c><anno>How</anno></c> before the
- <c>scheduler_bind_type</c> flag was changed.</p>
- <p>Failure:</p>
+ <p>The returned value equals <c><anno>How</anno></c> before flag
+ <c>scheduler_bind_type</c> was changed.</p>
+ <p>Failures:</p>
<taglist>
<tag><c>notsup</c></tag>
<item>
@@ -5835,168 +6243,171 @@ ok
</item>
<tag><c>badarg</c></tag>
<item>
- <p>If <c>How</c> isn't one of the documented alternatives.</p>
+ <p>If <c><anno>How</anno></c> is not one of the documented
+ alternatives.</p>
</item>
<tag><c>badarg</c></tag>
<item>
- <p>If no CPU topology information is available.</p>
+ <p>If CPU topology information is unavailable.</p>
</item>
</taglist>
<p>The scheduler bind type can also be set by passing
- the <seealso marker="erts:erl#+sbt">+sbt</seealso> command
- line argument to <c>erl</c>.
- </p>
+ command-line argument
+ <seealso marker="erts:erl#+sbt">+sbt</seealso> to <c>erl(1)</c>.</p>
<p>For more information, see
<seealso marker="#system_info_scheduler_bind_type">erlang:system_info(scheduler_bind_type)</seealso>,
<seealso marker="#system_info_scheduler_bindings">erlang:system_info(scheduler_bindings)</seealso>,
- the <c>erl</c> <seealso marker="erts:erl#+sbt">+sbt</seealso>
- and <seealso marker="erts:erl#+sct">+sct</seealso> command line
- flags.
- </p>
+ as well as command-line flags
+ <seealso marker="erts:erl#+sbt">+sbt</seealso>
+ and <seealso marker="erts:erl#+sct">+sct</seealso>
+ in <c>erl(1)</c>.</p>
</desc>
</func>
+
<func>
<name name="system_flag" arity="2" clause_i="9"/>
- <fsummary>Set system flag scheduler_wall_time</fsummary>
+ <fsummary>Sets system flag <c>scheduler_wall_time</c>.</fsummary>
<desc><p><marker id="system_flag_scheduler_wall_time"></marker>
- Turns on/off scheduler wall time measurements. </p>
- <p>For more information see,
- <seealso marker="#statistics_scheduler_wall_time">erlang:statistics(scheduler_wall_time)</seealso>.
- </p>
+ Turns on or off scheduler wall time measurements.</p>
+ <p>For more information, see
+ <seealso marker="#statistics_scheduler_wall_time">erlang:statistics(scheduler_wall_time)</seealso>.</p>
</desc>
</func>
+
<func>
<name name="system_flag" arity="2" clause_i="10"/>
- <fsummary>Set system flag schedulers_online</fsummary>
+ <fsummary>Sets system flag <c>schedulers_online</c>.</fsummary>
<desc>
<p><marker id="system_flag_schedulers_online"></marker>
- Sets the amount of schedulers online. Valid range is
- <![CDATA[1 <= SchedulersOnline <= erlang:system_info(schedulers)]]>.
- </p>
+ Sets the number of schedulers online. Range is
+ <![CDATA[1 <= SchedulersOnline <= erlang:system_info(schedulers)]]>.</p>
<p>Returns the old value of the flag.</p>
- <p>Note that if the emulator was built with support for <seealso
- marker="#system_flag_dirty_cpu_schedulers_online">dirty schedulers</seealso>,
- changing the number of schedulers online can also change the number of dirty
- CPU schedulers online. For example, if there are 12 schedulers and all are
- online, and 6 dirty CPU schedulers, all online as well, and <c>system_flag/2</c>
- is used to set the number of schedulers online to 6, then the number of dirty
- CPU schedulers online is automatically decreased by half as well, down to 3.
- Similarly, the number of dirty CPU schedulers online increases proportionally
- to increases in the number of schedulers online.</p>
- <p>For more information see,
- <seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso>,
+ <p>If the emulator was built with support for
+ <seealso marker="#system_flag_dirty_cpu_schedulers_online">dirty schedulers</seealso>,
+ changing the number of schedulers online can also change the
+ number of dirty CPU schedulers online. For example, if 12
+ schedulers and 6 dirty CPU schedulers are online, and
+ <c>system_flag/2</c> is used to set the number of schedulers
+ online to 6, then the number of dirty CPU schedulers online
+ is automatically decreased by half as well, down to 3.
+ Similarly, the number of dirty CPU schedulers online increases
+ proportionally to increases in the number of schedulers online.</p>
+ <p>For more information, see
+ <seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso>
and
- <seealso marker="#system_info_schedulers_online">erlang:system_info(schedulers_online)</seealso>.
- </p>
+ <seealso marker="#system_info_schedulers_online">erlang:system_info(schedulers_online)</seealso>.</p>
</desc>
</func>
+
<func>
<name name="system_flag" arity="2" clause_i="11"/>
- <fsummary>Set system flag trace_control_word</fsummary>
+ <fsummary>Sets system flag <c>trace_control_word</c>.</fsummary>
<desc>
- <p>Sets the value of the node's trace control word to
- <c><anno>TCW</anno></c>. <c><anno>TCW</anno></c> should be an unsigned integer. For
- more information see documentation of the
+ <p>Sets the value of the node trace control word to
+ <c><anno>TCW</anno></c>, which is to be an unsigned integer.
+ For more information, see the function
<seealso marker="erts:match_spec#set_tcw">set_tcw</seealso>
- function in the match specification documentation in the
- ERTS User's Guide.</p>
+ in Section "Match Specifications in Erlang" in the
+ User's Guide.</p>
<p>Returns the old value of the flag.</p>
</desc>
</func>
- <marker id="system_flag_time_offset"/>
+
<func>
<name name="system_flag" arity="2" clause_i="12"/>
<fsummary>Finalize the Time Offset</fsummary>
<desc>
- <p>Finalizes the <seealso marker="#time_offset/0">time offset</seealso>
- when the <seealso marker="time_correction#Single_Time_Warp_Mode">single
- time warp mode</seealso> is being used. If another time warp mode than
- the "single time warp mode" is used, the time offset state will be left
- unchanged.</p>
- <p>Returns the old state identifier. That is, if:</p>
+ <p><marker id="system_flag_time_offset"></marker>
+ Finalizes the <seealso marker="#time_offset/0">time offset</seealso>
+ when <seealso marker="time_correction#Single_Time_Warp_Mode">single
+ time warp mode</seealso> is used. If another time warp mode
+ is used, the time offset state is left unchanged.</p>
+ <p>Returns the old state identifier. That is:</p>
<list>
- <item><p><c>preliminary</c> is returned, finalization was
+ <item><p>If <c>preliminary</c> is returned, finalization was
performed and the time offset is now final.</p></item>
- <item><p><c>final</c> is returned, the time offset was
- already in the final state. This either due to another
+ <item><p>If <c>final</c> is returned, the time offset was
+ already in the final state. This either because another
<c>erlang:system_flag(time_offset, finalize)</c> call, or
- due to the
- <seealso marker="time_correction#No_Time_Warp_Mode">no
- time warp mode</seealso> being used.</p></item>
+ because <seealso marker="time_correction#No_Time_Warp_Mode">no
+ time warp mode</seealso> is used.</p></item>
- <item><p><c>volatile</c> is returned, the time offset
- cannot be finalized due to the
+ <item><p>If <c>volatile</c> is returned, the time offset
+ cannot be finalized because
<seealso marker="time_correction#Multi_Time_Warp_Mode">multi
- time warp mode</seealso> being used.</p></item>
+ time warp mode</seealso> is used.</p></item>
</list>
</desc>
</func>
+
<func>
<name name="system_info" arity="1" clause_i="1"/>
<name name="system_info" arity="1" clause_i="2"/>
<name name="system_info" arity="1" clause_i="3"/>
<name name="system_info" arity="1" clause_i="4"/>
<name name="system_info" arity="1" clause_i="5"/>
+ <fsummary>Information about the system allocators.</fsummary>
<type variable="Allocator" name_i="2"/>
<type variable="Version" name_i="2"/>
<type variable="Features" name_i="2"/>
<type variable="Settings" name_i="2"/>
<type variable="Alloc" name_i="3"/>
- <fsummary>Information about the allocators of the system</fsummary>
<desc>
- <p>
- Returns various information about the
- <marker id="system_info_allocator_tags">allocators</marker> of the
+ <marker id="system_info_allocator_tags"></marker>
+ <p>Returns various information about the allocators of the
current system (emulator) as specified by
<c><anno>Item</anno></c>:</p>
+ <marker id="system_info_allocated_areas"></marker>
<taglist>
- <tag><marker id="system_info_allocated_areas"><c>allocated_areas</c></marker></tag>
+ <tag><c>allocated_areas</c></tag>
<item>
<p>Returns a list of tuples with information about
miscellaneous allocated memory areas.</p>
- <p>Each tuple contains an atom describing type of memory as
- first element and amount of allocated memory in bytes as
- second element. In those cases when there is information
- present about allocated and used memory, a third element
- is present. This third element contains the amount of
+ <p>Each tuple contains an atom describing the type of
+ memory as first element and the amount of allocated
+ memory in bytes as second element. When information
+ about allocated and used memory is present, also a
+ third element is present, containing the amount of
used memory in bytes.</p>
<p><c>erlang:system_info(allocated_areas)</c> is intended
- for debugging, and the content is highly implementation
- dependent. The content of the results will therefore
- change when needed without prior notice.</p>
- <p><em>Note:</em> The sum of these values is <em>not</em>
+ for debugging, and the content is highly
+ implementation-dependent. The content of the results
+ therefore changes when needed without prior notice.</p>
+ <p>Notice that the sum of these values is <em>not</em>
the total amount of memory allocated by the emulator.
Some values are part of other values, and some memory
- areas are not part of the result. If you are interested
- in the total amount of memory allocated by the emulator
- see <seealso marker="#memory/0">erlang:memory/0,1</seealso>.</p>
+ areas are not part of the result. For information about
+ the total amount of memory allocated by the emulator, see
+ <seealso marker="#memory/0">erlang:memory/0,1</seealso>.</p>
</item>
- <tag><marker id="system_info_allocator"><c>allocator</c></marker></tag>
+ <tag><c>allocator</c></tag>
<item>
- <p>Returns <c>{<anno>Allocator</anno>, <anno>Version</anno>, <anno>Features</anno>, <anno>Settings</anno>}.</c></p>
- <p>Explanation:</p>
+ <marker id="system_info_allocator"></marker>
+ <p>Returns <c>{<anno>Allocator</anno>, <anno>Version</anno>,
+ <anno>Features</anno>, <anno>Settings</anno></c>, where:</p>
<list type="bulleted">
<item>
- <p><c><anno>Allocator</anno></c> corresponds to the <c>malloc()</c>
- implementation used. If <c><anno>Allocator</anno></c> equals
+ <p><c><anno>Allocator</anno></c> corresponds to the
+ <c>malloc()</c> implementation used. If
+ <c><anno>Allocator</anno></c> equals
<c>undefined</c>, the <c>malloc()</c> implementation
- used could not be identified. Currently
- <c>glibc</c> can be identified.</p>
+ used cannot be identified. <c>glibc</c> can be
+ identified.</p>
</item>
<item>
- <p><c><anno>Version</anno></c> is a list of integers (but not a
- string) representing the version of
+ <p><c><anno>Version</anno></c> is a list of integers
+ (but not a string) representing the version of
the <c>malloc()</c> implementation used.</p>
</item>
<item>
- <p><c><anno>Features</anno></c> is a list of atoms representing
- allocation features used.</p>
+ <p><c><anno>Features</anno></c> is a list of atoms
+ representing the allocation features used.</p>
</item>
<item>
- <p><c><anno>Settings</anno></c> is a list of subsystems, their
- configurable parameters, and used values. Settings
- may differ between different combinations of
+ <p><c><anno>Settings</anno></c> is a list of subsystems,
+ their configurable parameters, and used values. Settings
+ can differ between different combinations of
platforms, allocators, and allocation features.
Memory sizes are given in bytes.</p>
</item>
@@ -6004,165 +6415,169 @@ ok
<p>See also "System Flags Effecting erts_alloc" in
<seealso marker="erts:erts_alloc#flags">erts_alloc(3)</seealso>.</p>
</item>
- <tag><marker id="system_info_alloc_util_allocators"><c>alloc_util_allocators</c></marker></tag>
+ <tag><c>alloc_util_allocators</c></tag>
<item>
- <p>Returns a list of the names of all allocators
- using the ERTS internal <c>alloc_util</c> framework
- as atoms. For more information see the
- <seealso marker="erts:erts_alloc#alloc_util">"the
- alloc_util framework" section in the
- erts_alloc(3)</seealso> documentation.
- </p>
+ <marker id="system_info_alloc_util_allocators"></marker>
+ <p>Returns a list of the names of all allocators using
+ the <c>ERTS</c> internal <c>alloc_util</c> framework
+ as atoms. For more information, see Section
+ <seealso marker="erts:erts_alloc#alloc_util">"The
+ alloc_util framework" in erts_alloc(3)</seealso>.</p>
</item>
- <tag><marker id="system_info_allocator_tuple"><c>{allocator, <anno>Alloc</anno>}</c></marker></tag>
+ <tag><c>{allocator, <anno>Alloc</anno>}</c></tag>
<item>
+ <marker id="system_info_allocator_tuple"></marker>
<p>Returns information about the specified allocator.
- As of erts version 5.6.1 the return value is a list
- of <c>{instance, InstanceNo, InstanceInfo}</c> tuples
+ As from <c>ERTS</c> 5.6.1, the return value is a list
+ of <c>{instance, InstanceNo, InstanceInfo}</c> tuples,
where <c>InstanceInfo</c> contains information about
- a specific instance of the allocator. As of erts version
- 5.10.4 the returned list when calling
+ a specific instance of the allocator. As from
+ <c>ERTS</c> 5.10.4, the returned list when calling
<c>erlang:system_info({allocator, mseg_alloc})</c> also
- include an <c>{erts_mmap, _}</c> tuple as one element
- in the list.
- If <c><anno>Alloc</anno></c> is not a recognized allocator,
- <c>undefined</c> is returned. If <c><anno>Alloc</anno></c> is disabled,
+ includes an <c>{erts_mmap, _}</c> tuple as one element
+ in the list. If <c><anno>Alloc</anno></c> is not a
+ recognized allocator, <c>undefined</c> is returned.
+ If <c><anno>Alloc</anno></c> is disabled,
<c>false</c> is returned.</p>
- <p><em>Note:</em> The information returned is highly
- implementation dependent and may be changed, or removed
+ <p>Notice that the information returned is highly
+ implementation-dependent and can be changed or removed
at any time without prior notice. It was initially
intended as a tool when developing new allocators, but
- since it might be of interest for others it has been
+ as it can be of interest for others it has been
briefly documented.</p>
<p>The recognized allocators are listed in
<seealso marker="erts:erts_alloc">erts_alloc(3)</seealso>.
After reading the <c>erts_alloc(3)</c> documentation,
the returned information
- should more or less speak for itself. But it can be worth
+ more or less speaks for itself, but it can be worth
explaining some things. Call counts are presented by two
- values. The first value is giga calls, and the second
- value is calls. <c>mbcs</c>, and <c>sbcs</c> are
- abbreviations for, respectively, multi-block carriers, and
- single-block carriers. Sizes are presented in bytes. When
- it is not a size that is presented, it is the amount of
- something. Sizes and amounts are often presented by three
- values, the first is current value, the second is maximum
- value since the last call to
- <c>erlang:system_info({allocator, Alloc})</c>, and
- the third is maximum value since the emulator was started.
- If only one value is present, it is the current value.
+ values, the first value is giga calls, and the second
+ value is calls. <c>mbcs</c> and <c>sbcs</c> denote
+ multi-block carriers, and single-block carriers,
+ respectively. Sizes are presented in bytes. When a
+ size is not presented, it is the amount of something.
+ Sizes and amounts are often presented by three values:</p>
+ <list type="bulleted">
+ <item>The first is the current value.</item>
+ <item>The second is the maximum value since the last call
+ to <c>erlang:system_info({allocator, Alloc})</c>.</item>
+ <item>The third is the maximum value since the emulator
+ was started.</item>
+ </list>
+ <p>If only one value is present, it is the current value.
<c>fix_alloc</c> memory block types are presented by two
- values. The first value is memory pool size and
- the second value used memory size.</p>
+ values. The first value is the memory pool size and
+ the second value is the used memory size.</p>
</item>
- <tag><marker id="system_info_allocator_sizes"><c>{allocator_sizes, <anno>Alloc</anno>}</c></marker></tag>
+ <tag><c>{allocator_sizes, <anno>Alloc</anno>}</c></tag>
<item>
+ <marker id="system_info_allocator_sizes"></marker>
<p>Returns various size information for the specified
allocator. The information returned is a subset of the
information returned by
- <seealso marker="#system_info_allocator_tuple">erlang:system_info({allocator, <anno>Alloc</anno>})</seealso>.
+ <seealso marker="#system_info_allocator_tuple"><c>erlang:system_info({allocator, <anno>Alloc</anno>})</c></seealso>.
</p>
</item>
</taglist>
</desc>
</func>
+
<func>
<name name="system_info" arity="1" clause_i="10"/>
<name name="system_info" arity="1" clause_i="11"/>
+ <fsummary>Information about the CPU topology of the system.</fsummary>
<type name="cpu_topology"/>
<type name="level_entry"/>
<type_desc name="cpu_topology">
- <marker id="system_info_cpu_topology"></marker>
All <c><anno>LevelEntry</anno></c>s of a list
must contain the same <c><anno>LevelTag</anno></c>, except
on the top level where both <c>node</c> and
- <c>processor</c> <c><anno>LevelTag</anno></c>s may co-exist.
+ <c>processor</c> <c><anno>LevelTag</anno></c>s can coexist.
</type_desc>
<type_desc name="level_entry">
- <c>{<anno>LevelTag</anno>, <anno>SubLevel</anno>} == {<anno>LevelTag</anno>, [], <anno>SubLevel</anno>}</c>
+ <c>{<anno>LevelTag</anno>,
+ <anno>SubLevel</anno>} == {<anno>LevelTag</anno>, [],
+ <anno>SubLevel</anno>}</c>
</type_desc>
<type name="level_tag"/>
<type_desc name="level_tag">
- More <c><anno>LevelTag</anno></c>s may be introduced in the future.
+ More <c><anno>LevelTag</anno></c>s can be introduced in a
+ future release.
</type_desc>
<type name="sub_level"/>
<type name="info_list"/>
<type_desc name="info_list">
- The <c>info_list()</c> may be extended in the future.
+ The <c>info_list()</c> can be extended in a future release.
</type_desc>
- <fsummary>Information about the CPU topology of the system</fsummary>
<desc>
- <p>Returns various information about the
- <marker id="system_info_cpu_topology_tags">CPU topology</marker>
- of the current system
- (emulator) as specified by <c><anno>Item</anno></c>:</p>
+ <marker id="system_info_cpu_topology_tags"></marker>
+ <marker id="system_info_cpu_topology"></marker>
+ <p>Returns various information about the CPU topology of
+ the current system (emulator) as specified by
+ <c><anno>Item</anno></c>:</p>
<taglist>
<tag><c>cpu_topology</c></tag>
<item>
- <p>Returns the <c><anno>CpuTopology</anno></c> which currently is used by the
- emulator. The CPU topology is used when binding schedulers
+ <p>Returns the <c><anno>CpuTopology</anno></c> currently used by
+ the emulator. The CPU topology is used when binding schedulers
to logical processors. The CPU topology used is the
- <seealso marker="erlang#system_info_cpu_topology_defined">user
- defined CPU topology</seealso> if such exists; otherwise, the
- <seealso marker="erlang#system_info_cpu_topology_detected">automatically
- detected CPU topology</seealso> if such exists. If no CPU topology
+ <seealso marker="erlang#system_info_cpu_topology_defined">user-defined CPU topology</seealso>,
+ if such exists, otherwise the
+ <seealso marker="erlang#system_info_cpu_topology_detected">automatically detected CPU topology</seealso>,
+ if such exists. If no CPU topology
exists, <c>undefined</c> is returned.</p>
- <p><c>node</c> refers to NUMA (non-uniform memory access)
- nodes, and <c>thread</c> refers to hardware threads
- (e.g. Intels hyper-threads).</p>
- <p>A level in the <c><anno>CpuTopology</anno></c> term can be omitted if
- only one entry exists and the <c><anno>InfoList</anno></c> is empty.
- </p>
+ <p><c>node</c> refers to Non-Uniform Memory Access (NUMA)
+ nodes. <c>thread</c> refers to hardware threads
+ (for example, Intel hyper-threads).</p>
+ <p>A level in term <c><anno>CpuTopology</anno></c> can be
+ omitted if only one entry exists and
+ <c><anno>InfoList</anno></c> is empty.</p>
<p><c>thread</c> can only be a sub level to <c>core</c>.
- <c>core</c> can be a sub level to either <c>processor</c>
- or <c>node</c>. <c>processor</c> can either be on the
+ <c>core</c> can be a sub level to <c>processor</c>
+ or <c>node</c>. <c>processor</c> can be on the
top level or a sub level to <c>node</c>. <c>node</c>
- can either be on the top level or a sub level to
+ can be on the top level or a sub level to
<c>processor</c>. That is, NUMA nodes can be processor
internal or processor external. A CPU topology can
consist of a mix of processor internal and external
- NUMA nodes, as long as each logical CPU belongs to one
- and only one NUMA node. Cache hierarchy is not part of
- the <c><anno>CpuTopology</anno></c> type yet, but will be in the
- future. Other things may also make it into the CPU
- topology in the future. In other words, expect the
- <c><anno>CpuTopology</anno></c> type to change.
- </p>
- </item>
- <tag><marker id="system_info_cpu_topology_defined"><c>{cpu_topology, defined}</c></marker></tag>
- <item>
- <p>Returns the user defined <c><anno>CpuTopology</anno></c>. For more
- information see the documentation of
- the <c>erl</c> <seealso marker="erts:erl#+sct">+sct</seealso> command
- line flag, and the documentation of the
- <seealso marker="#system_info_cpu_topology">cpu_topology</seealso>
- argument.
- </p>
- </item>
- <tag><marker id="system_info_cpu_topology_detected"><c>{cpu_topology, detected}</c></marker></tag>
- <item>
- <p>Returns the automatically detected <c><anno>CpuTopology</anno></c>. The
- emulator currently only detects the CPU topology on some newer
- Linux, Solaris, FreeBSD, and Windows systems. On Windows system with
- more than 32 logical processors the CPU topology is not detected.
- </p>
- <p>For more information see the documentation of the
- <seealso marker="#system_info_cpu_topology">cpu_topology</seealso>
- argument.
- </p>
+ NUMA nodes, as long as each logical CPU belongs to
+ <em>one</em> NUMA node. Cache hierarchy is not part of
+ the <c><anno>CpuTopology</anno></c> type, but will be in a
+ future release. Other things can also make it into the CPU
+ topology in a future release. In other words, expect the
+ <c><anno>CpuTopology</anno></c> type to change.</p>
+ </item>
+ <tag><c>{cpu_topology, defined}</c></tag>
+ <item>
+ <marker id="system_info_cpu_topology_defined"></marker>
+ <p>Returns the user-defined <c><anno>CpuTopology</anno></c>.
+ For more information, see command-line flag
+ <seealso marker="erts:erl#+sct">+sct</seealso> in
+ <c>erl(1)</c> and argument
+ <seealso marker="#system_info_cpu_topology">cpu_topology</seealso>.</p>
+ </item>
+ <tag><c>{cpu_topology, detected}</c></tag>
+ <item>
+ <marker id="system_info_cpu_topology_detected"></marker>
+ <p>Returns the automatically detected
+ <c><anno>CpuTopology</anno>y</c>. The
+ emulator detects the CPU topology on some newer
+ Linux, Solaris, FreeBSD, and Windows systems.
+ On Windows system with more than 32 logical processors,
+ the CPU topology is not detected.</p>
+ <p>For more information, see argument
+ <seealso marker="#system_info_cpu_topology">cpu_topology</seealso>.</p>
</item>
<tag><c>{cpu_topology, used}</c></tag>
<item>
- <p>Returns the <c><anno>CpuTopology</anno></c> which is used by the
- emulator. For more information see the
- documentation of the
- <seealso marker="#system_info_cpu_topology">cpu_topology</seealso>
- argument.
- </p>
+ <p>Returns <c><anno>CpuTopology</anno></c> used by the emulator.
+ For more information, see argument
+ <seealso marker="#system_info_cpu_topology">cpu_topology</seealso>.</p>
</item>
</taglist>
</desc>
</func>
+
<func>
<name name="system_info" arity="1" clause_i="6"/>
<name name="system_info" arity="1" clause_i="7"/>
@@ -6224,7 +6639,7 @@ ok
<name name="system_info" arity="1" clause_i="65"/>
<name name="system_info" arity="1" clause_i="66"/>
<name name="system_info" arity="1" clause_i="67"/>
- <fsummary>Information about the system</fsummary>
+ <fsummary>Information about the system.</fsummary>
<desc>
<p>Returns various information about the current system
(emulator) as specified by <c><anno>Item</anno></c>:</p>
@@ -6241,8 +6656,7 @@ ok
Other possible return values are <c>debug</c>, <c>purify</c>,
<c>quantify</c>, <c>purecov</c>, <c>gcov</c>, <c>valgrind</c>,
<c>gprof</c>, and <c>lcnt</c>. Possible return values
- may be added and/or removed at any time without prior notice.
- </p>
+ can be added or removed at any time without prior notice.</p>
</item>
<tag><c>c_compiler_used</c></tag>
<item>
@@ -6250,26 +6664,25 @@ ok
compiling the runtime system. The first element is an
atom describing the name of the compiler, or <c>undefined</c>
if unknown. The second element is a term describing the
- version of the compiler, or <c>undefined</c> if unknown.
- </p>
+ version of the compiler, or <c>undefined</c> if unknown.</p>
</item>
<tag><c>check_io</c></tag>
<item>
<p>Returns a list containing miscellaneous information
- regarding the emulators internal I/O checking. Note,
- the content of the returned list may vary between
- platforms and over time. The only thing guaranteed is
+ about the emulators internal I/O checking. Notice that
+ the content of the returned list can vary between
+ platforms and over time. It is only guaranteed
that a list is returned.</p>
</item>
<tag><c>compat_rel</c></tag>
<item>
<p>Returns the compatibility mode of the local node as
an integer. The integer returned represents the
- Erlang/OTP release which the current emulator has been
+ Erlang/OTP release that the current emulator has been
set to be backward compatible with. The compatibility
- mode can be configured at startup by using the command
- line flag <c>+R</c>, see
- <seealso marker="erts:erl#compat_rel">erl(1)</seealso>.</p>
+ mode can be configured at startup by using command-line flag
+ <seealso marker="erts:erl#compat_rel">+R</seealso> in
+ <c>erl(1)</c>.</p>
</item>
<tag><c>cpu_topology</c></tag>
<item>
@@ -6282,144 +6695,150 @@ ok
creation of a node is stored in process identifiers, port
identifiers, and references. This makes it (to some
extent) possible to distinguish between identifiers from
- different incarnations of a node. Currently valid
- creations are integers in the range 1..3, but this may
- (probably will) change in the future. If the node is not
- alive, 0 is returned.</p>
+ different incarnations of a node. The valid
+ creations are integers in the range 1..3, but this will
+ probably change in a future release. If the node is not
+ alive, <c>0</c> is returned.</p>
</item>
<tag><c>debug_compiled</c></tag>
<item>
<p>Returns <c>true</c> if the emulator has been debug
- compiled; otherwise, <c>false</c>.
- </p>
+ compiled, otherwise <c>false</c>.</p>
</item>
- <tag><marker id="system_info_delayed_node_table_gc"><c>delayed_node_table_gc</c></marker></tag>
+ <tag><c>delayed_node_table_gc</c></tag>
<item>
- <p>Returns the amount of time in seconds that garbage collection
- of an entry in a node table will be delayed. This limit can be set
- on startup by passing the
- <seealso marker="erts:erl#+zdntgc">+zdntgc</seealso> command line
- flag to <c>erl</c>. For more information see the documentation of the
+ <marker id="system_info_delayed_node_table_gc"></marker>
+ <p>Returns the amount of time in seconds garbage collection
+ of an entry in a node table is delayed. This limit can be set
+ on startup by passing the command line flag
+ <seealso marker="erts:erl#+zdntgc">+zdntgc</seealso>
+ to <c>erl</c>. For more information see the documentation of the
command line flag.</p>
</item>
- <tag><marker id="system_info_dirty_cpu_schedulers"><c>dirty_cpu_schedulers</c></marker></tag>
+ <tag><c>dirty_cpu_schedulers</c></tag>
<item>
+ <marker id="system_info_dirty_cpu_schedulers"></marker>
<p>Returns the number of dirty CPU scheduler threads used by
the emulator. Dirty CPU schedulers execute CPU-bound
- native functions such as NIFs, linked-in driver code, and BIFs
- that cannot be managed cleanly by the emulator's normal schedulers.
- </p>
- <p>The number of dirty CPU scheduler threads is determined at emulator
- boot time and cannot be changed after that. The number of dirty CPU
- scheduler threads online can however be changed at any time. The number of
- dirty CPU schedulers can be set on startup by passing
- the <seealso marker="erts:erl#+SDcpu">+SDcpu</seealso> or
- <seealso marker="erts:erl#+SDPcpu">+SDPcpu</seealso> command line flags,
- see <seealso marker="erts:erl#+SDcpu">erl(1)</seealso>.
- </p>
- <p><em>Note that the dirty schedulers functionality is experimental</em>, and
- that you have to enable support for dirty schedulers when building OTP in
- order to try out the functionality.</p>
- <p>See also <seealso marker="#system_flag_dirty_cpu_schedulers_online">erlang:system_flag(dirty_cpu_schedulers_online, DirtyCPUSchedulersOnline)</seealso>,
+ native functions, such as NIFs, linked-in driver code,
+ and BIFs that cannot be managed cleanly by the normal
+ emulator schedulers.</p>
+ <p>The number of dirty CPU scheduler threads is determined
+ at emulator boot time and cannot be changed after that.
+ However, the number of dirty CPU scheduler threads online
+ can be changed at any time. The number of dirty CPU
+ schedulers can be set at startup by passing
+ command-line flag
+ <seealso marker="erts:erl#+SDcpu">+SDcpu</seealso> or
+ <seealso marker="erts:erl#+SDPcpu">+SDPcpu</seealso> in
+ <c>erl(1)</c>.</p>
+ <p>Notice that the dirty schedulers functionality is
+ experimental. Enable support for dirty schedulers when
+ building OTP to try out the functionality.</p>
+ <p>See also
+ <seealso marker="#system_flag_dirty_cpu_schedulers_online">erlang:system_flag(dirty_cpu_schedulers_online, DirtyCPUSchedulersOnline)</seealso>,
<seealso marker="#system_info_dirty_cpu_schedulers_online">erlang:system_info(dirty_cpu_schedulers_online)</seealso>,
<seealso marker="#system_info_dirty_io_schedulers">erlang:system_info(dirty_io_schedulers)</seealso>,
<seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso>,
<seealso marker="#system_info_schedulers_online">erlang:system_info(schedulers_online)</seealso>, and
<seealso marker="#system_flag_schedulers_online">erlang:system_flag(schedulers_online, SchedulersOnline)</seealso>.</p>
</item>
- <tag><marker id="system_info_dirty_cpu_schedulers_online"><c>dirty_cpu_schedulers_online</c></marker></tag>
- <item>
- <p>Returns the number of dirty CPU schedulers online. The return value
- satisfies the following relationship:
- <c><![CDATA[1 <= DirtyCPUSchedulersOnline <= N]]></c>, where <c>N</c> is
- the lesser of the return values of <c>erlang:system_info(dirty_cpu_schedulers)</c> and
- <c>erlang:system_info(schedulers_online)</c>.
- </p>
- <p>The number of dirty CPU schedulers online can be set on startup by passing
- the <seealso marker="erts:erl#+SDcpu">+SDcpu</seealso> command line flag, see
- <seealso marker="erts:erl#+SDcpu">erl(1)</seealso>.
- </p>
- <p><em>Note that the dirty schedulers functionality is experimental</em>, and
- that you have to enable support for dirty schedulers when building OTP in
- order to try out the functionality.</p>
+ <tag><c>dirty_cpu_schedulers_online</c></tag>
+ <item>
+ <marker id="system_info_dirty_cpu_schedulers_online"></marker>
+ <p>Returns the number of dirty CPU schedulers online.
+ The return value satisfies
+ <c><![CDATA[1 <= DirtyCPUSchedulersOnline <= N]]></c>,
+ where <c>N</c> is the smallest of the return values of
+ <c>erlang:system_info(dirty_cpu_schedulers)</c> and
+ <c>erlang:system_info(schedulers_online)</c>.</p>
+ <p>The number of dirty CPU schedulers online can be set at
+ startup by passing command-line flag
+ <seealso marker="erts:erl#+SDcpu">+SDcpu</seealso> in
+ <c>erl(1)</c>.</p>
+ <p>Notice that the dirty schedulers functionality is
+ experimental. Enable support for dirty schedulers when
+ building OTP to try out the functionality.</p>
<p>For more information, see
<seealso marker="#system_info_dirty_cpu_schedulers">erlang:system_info(dirty_cpu_schedulers)</seealso>,
<seealso marker="#system_info_dirty_io_schedulers">erlang:system_info(dirty_io_schedulers)</seealso>,
<seealso marker="#system_info_schedulers_online">erlang:system_info(schedulers_online)</seealso>, and
- <seealso marker="#system_flag_dirty_cpu_schedulers_online">erlang:system_flag(dirty_cpu_schedulers_online, DirtyCPUSchedulersOnline)</seealso>.
- </p>
- </item>
- <tag><marker id="system_info_dirty_io_schedulers"><c>dirty_io_schedulers</c></marker></tag>
- <item>
- <p>Returns the number of dirty I/O schedulers as an integer. Dirty I/O schedulers
- execute I/O-bound native functions such as NIFs and linked-in driver code that
- cannot be managed cleanly by the emulator's normal schedulers.
- </p>
- <p>This value can be set on startup by passing
- the <seealso marker="erts:erl#+SDio">+SDio</seealso> command line flag, see
- <seealso marker="erts:erl#+SDio">erl(1)</seealso>.
- </p>
- <p><em>Note that the dirty schedulers functionality is experimental</em>, and
- that you have to enable support for dirty schedulers when building OTP in
- order to try out the functionality.</p>
+ <seealso marker="#system_flag_dirty_cpu_schedulers_online">erlang:system_flag(dirty_cpu_schedulers_online, DirtyCPUSchedulersOnline)</seealso>.</p>
+ </item>
+ <tag><c>dirty_io_schedulers</c></tag>
+ <item>
+ <marker id="system_info_dirty_io_schedulers"></marker>
+ <p>Returns the number of dirty I/O schedulers as an integer.
+ Dirty I/O schedulers execute I/O-bound native functions,
+ such as NIFs and linked-in driver code, which cannot be
+ managed cleanly by the normal emulator schedulers.</p>
+ <p>This value can be set at startup by passing command-line
+ argument <seealso marker="erts:erl#+SDio">+SDio</seealso>
+ in <c>erl(1)</c>.</p>
+ <p>Notice that the dirty schedulers functionality is
+ experimental. Enable support for dirty schedulers when
+ building OTP to try out the functionality.</p>
<p>For more information, see
<seealso marker="#system_info_dirty_cpu_schedulers">erlang:system_info(dirty_cpu_schedulers)</seealso>,
<seealso marker="#system_info_dirty_cpu_schedulers_online">erlang:system_info(dirty_cpu_schedulers_online)</seealso>, and
- <seealso marker="#system_flag_dirty_cpu_schedulers_online">erlang:system_flag(dirty_cpu_schedulers_online, DirtyCPUSchedulersOnline)</seealso>.
- </p>
+ <seealso marker="#system_flag_dirty_cpu_schedulers_online">erlang:system_flag(dirty_cpu_schedulers_online, DirtyCPUSchedulersOnline)</seealso>.</p>
</item>
<tag><c>dist</c></tag>
<item>
<p>Returns a binary containing a string of distribution
information formatted as in Erlang crash dumps. For more
- information see the <seealso marker="erts:crash_dump">"How to interpret the Erlang crash dumps"</seealso>
- chapter in the ERTS User's Guide.</p>
+ information, see Section
+ <seealso marker="erts:crash_dump">"How to interpret the Erlang crash dumps"</seealso>
+ in the User's Guide.</p>
</item>
- <tag><marker id="system_info_dist_buf_busy_limit"><c>dist_buf_busy_limit</c></marker></tag>
+ <tag><c>dist_buf_busy_limit</c></tag>
<item>
+ <marker id="system_info_dist_buf_busy_limit"></marker>
<p>Returns the value of the distribution buffer busy limit
- in bytes. This limit can be set on startup by passing the
- <seealso marker="erts:erl#+zdbbl">+zdbbl</seealso> command line
- flag to <c>erl</c>.</p>
+ in bytes. This limit can be set at startup by passing
+ command-line flag
+ <seealso marker="erts:erl#+zdbbl">+zdbbl</seealso>
+ to <c>erl</c>.</p>
</item>
<tag><c>dist_ctrl</c></tag>
<item>
<p>Returns a list of tuples
- <c>{Node, ControllingEntity}</c>, one entry for each
- connected remote node. The <c><anno>Node</anno></c> is the name of the
- node and the <c><anno>ControllingEntity</anno></c> is the port or pid
- responsible for the communication to that node. More
- specifically, the <c><anno>ControllingEntity</anno></c> for nodes
- connected via TCP/IP (the normal case) is the socket
- actually used in communication with the specific node.</p>
+ <c>{<anno>Node</anno>, <anno>ControllingEntity</anno>}</c>,
+ one entry for each connected remote node.
+ <c><anno>Node</anno></c> is the node name
+ and <c><anno>ControllingEntity</anno></c> is the port or process
+ identifier responsible for the communication to that node.
+ More specifically, <c><anno>ControllingEntity</anno></c> for
+ nodes connected through TCP/IP (the normal case) is the socket
+ used in communication with the specific node.</p>
</item>
<tag><c>driver_version</c></tag>
<item>
- <p>Returns a string containing the erlang driver version
- used by the runtime system. It will be on the form
+ <p>Returns a string containing the Erlang driver version
+ used by the runtime system. It has the form
<seealso marker="erts:erl_driver#version_management">"&lt;major ver&gt;.&lt;minor ver&gt;"</seealso>.</p>
</item>
<tag><c>dynamic_trace</c></tag>
<item>
<p>Returns an atom describing the dynamic trace framework
- compiled into the virtual machine. It can currently be either
- <c>dtrace</c>, <c>systemtap</c> or <c>none</c>. For a
- commercial or standard build, this is always <c>none</c>,
- the other return values indicate a custom configuration
- (e.g. <c>./configure --with-dynamic-trace=dtrace</c>). See
- the <seealso marker="runtime_tools:dyntrace">dyntrace
- </seealso> manual page and the
+ compiled into the virtual machine. It can be
+ <c>dtrace</c>, <c>systemtap</c>, or <c>none</c>. For a
+ commercial or standard build, it is always <c>none</c>.
+ The other return values indicate a custom configuration
+ (for example, <c>./configure --with-dynamic-trace=dtrace</c>).
+ For more information about dynamic tracing, see the
+ <seealso marker="runtime_tools:dyntrace">dyntrace</seealso>
+ manual page and the
<c>README.dtrace</c>/<c>README.systemtap</c> files in the
- Erlang source code top directory for more information
- about dynamic tracing.</p>
+ Erlang source code top directory.</p>
</item>
<tag><c>dynamic_trace_probes</c></tag>
<item>
- <p>Returns a <c>boolean()</c> indicating if dynamic trace probes
- (either dtrace or systemtap) are built into the
- emulator. This can only be <c>true</c> if the virtual
- machine was built for dynamic tracing
- (i.e. <c>system_info(dynamic_trace)</c> returns
+ <p>Returns a <c>boolean()</c> indicating if dynamic trace
+ probes (<c>dtrace</c> or <c>systemtap</c>) are built into
+ the emulator. This can only be <c>true</c> if the Virtual
+ Machine was built for dynamic tracing (that is,
+ <c>system_info(dynamic_trace)</c> returns
<c>dtrace</c> or <c>systemtap</c>).</p>
</item>
<tag><marker id="system_info_end_time"/><c>end_time</c></tag>
@@ -6433,42 +6852,43 @@ ok
<tag><c>elib_malloc</c></tag>
<item>
<p>This option will be removed in a future release.
- The return value will always be <c>false</c> since
- the elib_malloc allocator has been removed.</p>
+ The return value will always be <c>false</c>, as the
+ <c>elib_malloc</c> allocator has been removed.</p>
</item>
- <tag><marker id="system_info_eager_check_io"><c>eager_check_io</c></marker></tag>
+ <tag><marker id="system_info_eager_check_io"/><c>eager_check_io</c></tag>
<item>
<p>
- Returns the value of the <c>erl</c>
- <seealso marker="erl#+secio">+secio</seealso> command line
- flag which is either <c>true</c> or <c>false</c>. See the
+ Returns the value of the <c>erl</c> command line flag
+ <seealso marker="erl#+secio">+secio</seealso>
+ which is either <c>true</c> or <c>false</c>. See the
documentation of the command line flag for information about
the different values.
</p>
</item>
<tag><c>ets_limit</c></tag>
<item>
- <p>Returns the maximum number of ETS tables allowed. This limit
- can be increased on startup by passing the <seealso
- marker="erts:erl#+e">+e</seealso> command line flag to
- <c>erl</c> or by setting the environment variable
- <c>ERL_MAX_ETS_TABLES</c> before starting the Erlang runtime
- system.</p>
+ <p>Returns the maximum number of ETS tables allowed. This
+ limit can be increased at startup by passing
+ command-line flag
+ <seealso marker="erts:erl#+e">+e</seealso> to
+ <c>erl(1)</c> or by setting environment variable
+ <c>ERL_MAX_ETS_TABLES</c> before starting the Erlang
+ runtime system.</p>
</item>
<tag><c>fullsweep_after</c></tag>
<item>
- <p>Returns <c>{fullsweep_after, integer() >= 0}</c> which is the
- <c>fullsweep_after</c> garbage collection setting used
- by default. For more information see
- <c>garbage_collection</c> described below.</p>
+ <p>Returns <c>{fullsweep_after, integer() >= 0}</c>, which is
+ the <c>fullsweep_after</c> garbage collection setting used
+ by default. For more information, see
+ <c>garbage_collection</c> described in the following.</p>
</item>
<tag><c>garbage_collection</c></tag>
<item>
<p>Returns a list describing the default garbage collection
settings. A process spawned on the local node by a
- <c>spawn</c> or <c>spawn_link</c> will use these
+ <c>spawn</c> or <c>spawn_link</c> uses these
garbage collection settings. The default settings can be
- changed by use of
+ changed by using
<seealso marker="#system_flag/2">system_flag/2</seealso>.
<seealso marker="#spawn_opt/4">spawn_opt/4</seealso>
can spawn a process that does not use the default
@@ -6482,8 +6902,8 @@ ok
</item>
<tag><c>heap_type</c></tag>
<item>
- <p>Returns the heap type used by the current emulator.
- Currently only the following heap type exists:</p>
+ <p>Returns the heap type used by the current emulator. One
+ heap type exists:</p>
<taglist>
<tag><c>private</c></tag>
<item>
@@ -6498,51 +6918,51 @@ ok
<item>
<p>Returns a binary containing a string of miscellaneous
system information formatted as in Erlang crash dumps.
- For more information see the
- <seealso marker="erts:crash_dump">"How to interpret the Erlang crash dumps"</seealso> chapter in the ERTS
- User's Guide.</p>
+ For more information, see Section
+ <seealso marker="erts:crash_dump">"How to interpret the Erlang crash dumps"</seealso>
+ in the User's Guide.</p>
</item>
<tag><c>kernel_poll</c></tag>
<item>
<p>Returns <c>true</c> if the emulator uses some kind of
- kernel-poll implementation; otherwise, <c>false</c>.</p>
+ kernel-poll implementation, otherwise <c>false</c>.</p>
</item>
<tag><c>loaded</c></tag>
<item>
<p>Returns a binary containing a string of loaded module
information formatted as in Erlang crash dumps. For more
- information see the <seealso marker="erts:crash_dump">"How to interpret the Erlang crash dumps"</seealso> chapter
- in the ERTS User's Guide.</p>
+ information, see Section
+ <seealso marker="erts:crash_dump">"How to interpret the Erlang crash dumps"</seealso>
+ in the User's Guide.</p>
</item>
- <tag><marker id="logical_processors"><c>logical_processors</c></marker></tag>
+ <tag><c>logical_processors</c></tag>
<item>
+ <marker id="logical_processors"></marker>
<p>Returns the detected number of logical processors configured
- on the system. The return value is either an integer, or
- the atom <c>unknown</c> if the emulator wasn't able to
- detect logical processors configured.
- </p>
+ in the system. The return value is either an integer, or
+ the atom <c>unknown</c> if the emulator cannot
+ detect the configured logical processors.</p>
</item>
- <tag><marker id="logical_processors_available"><c>logical_processors_available</c></marker></tag>
+ <tag><c>logical_processors_available</c></tag>
<item>
- <p>Returns the detected number of logical processors available to
- the Erlang runtime system. The return value is either an
- integer, or the atom <c>unknown</c> if the emulator wasn't
- able to detect logical processors available. The number
- of logical processors available is less than or equal to
- the number of <seealso marker="#logical_processors_online">logical
- processors online</seealso>.
- </p>
+ <marker id="logical_processors_available"></marker>
+ <p>Returns the detected number of logical processors available
+ to the Erlang runtime system. The return value is either an
+ integer, or the atom <c>unknown</c> if the emulator
+ cannot detect the available logical processors. The number
+ of available logical processors is less than or equal to
+ the number of
+ <seealso marker="#logical_processors_online">logical processors online</seealso>.</p>
</item>
- <tag><marker id="logical_processors_online"><c>logical_processors_online</c></marker></tag>
+ <tag><c>logical_processors_online</c></tag>
<item>
+ <marker id="logical_processors_online"></marker>
<p>Returns the detected number of logical processors online on
the system. The return value is either an integer,
- or the atom <c>unknown</c> if the emulator wasn't able to
+ or the atom <c>unknown</c> if the emulator cannot
detect logical processors online. The number of logical
processors online is less than or equal to the number of
- <seealso marker="#logical_processors">logical processors
- configured</seealso>.
- </p>
+ <seealso marker="#logical_processors">logical processors configured</seealso>.</p>
</item>
<tag><c>machine</c></tag>
<item>
@@ -6550,27 +6970,30 @@ ok
</item>
<tag><c>min_heap_size</c></tag>
<item>
- <p>Returns <c>{min_heap_size, <anno>MinHeapSize</anno>}</c> where <c><anno>MinHeapSize</anno></c> is the current system wide
- minimum heap size for spawned processes.</p>
+ <p>Returns <c>{min_heap_size, <anno>MinHeapSize</anno>}</c>,
+ where <c><anno>MinHeapSize</anno></c> is the current
+ system-wide minimum heap size for spawned processes.</p>
</item>
<tag><c>min_bin_vheap_size</c></tag>
<item>
- <p>Returns <c>{min_bin_vheap_size, <anno>MinBinVHeapSize</anno>}</c> where <c><anno>MinBinVHeapSize</anno></c> is the current system wide
+ <p>Returns <c>{min_bin_vheap_size,
+ <anno>MinBinVHeapSize</anno>}</c>, where
+ <c><anno>MinBinVHeapSize</anno></c> is the current system-wide
minimum binary virtual heap size for spawned processes.</p>
</item>
<tag><c>modified_timing_level</c></tag>
<item>
- <p>Returns the modified timing level (an integer) if
- modified timing has been enabled; otherwise,
- <c>undefined</c>. See the <c>+T</c> command line flag
- in the documentation of the
- <seealso marker="erts:erl#+T">erl(1)</seealso>
- command for more information on modified timing.</p>
+ <p>Returns the modified timing-level (an integer) if
+ modified timing is enabled, otherwise, <c>undefined</c>.
+ For more information about modified timing, see
+ command-line flag
+ <seealso marker="erts:erl#+T">+T</seealso>
+ in <c>erl(1)</c></p>
</item>
- <tag><marker id="system_info_multi_scheduling"><c>multi_scheduling</c></marker></tag>
+ <tag><c>multi_scheduling</c></tag>
<item>
- <p>Returns <c>disabled</c>, <c>blocked</c>, or <c>enabled</c>.
- A description of the return values:</p>
+ <marker id="system_info_multi_scheduling"></marker>
+ <p>Returns <c>disabled</c>, <c>blocked</c>, or <c>enabled</c>:</p>
<taglist>
<tag><c>disabled</c></tag>
<item>
@@ -6581,93 +7004,99 @@ ok
<tag><c>blocked</c></tag>
<item>
<p>The emulator has more than one scheduler thread,
- but all scheduler threads but one have been blocked,
- i.e., only one scheduler thread will schedule
- Erlang processes and execute Erlang code.</p>
+ but all scheduler threads except one are blocked,
+ that is, only one scheduler thread schedules
+ Erlang processes and executes Erlang code.</p>
</item>
<tag><c>enabled</c></tag>
<item>
<p>The emulator has more than one scheduler thread,
- and no scheduler threads have been blocked, i.e.,
- all available scheduler threads will schedule
+ and no scheduler threads are blocked, that is,
+ all available scheduler threads schedule
Erlang processes and execute Erlang code.</p>
</item>
</taglist>
- <p>See also <seealso marker="#system_flag_multi_scheduling">erlang:system_flag(multi_scheduling, BlockState)</seealso>,
- <seealso marker="#system_info_multi_scheduling_blockers">erlang:system_info(multi_scheduling_blockers)</seealso>, and
+ <p>See also
+ <seealso marker="#system_flag_multi_scheduling">erlang:system_flag(multi_scheduling, BlockState)</seealso>,
+ <seealso marker="#system_info_multi_scheduling_blockers">erlang:system_info(multi_scheduling_blockers)</seealso>,
+ and
<seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso>.</p>
</item>
- <tag><marker id="system_info_multi_scheduling_blockers"><c>multi_scheduling_blockers</c></marker></tag>
+ <tag><c>multi_scheduling_blockers</c></tag>
<item>
- <p>Returns a list of <c><anno>PID</anno></c>s when multi-scheduling
- is blocked; otherwise, the empty list. The <c><anno>PID</anno></c>s
- in the list is <c><anno>PID</anno></c>s of the processes currently
- blocking multi-scheduling. A <c><anno>PID</anno></c> will only be
- present once in the list, even if the corresponding
+ <marker id="system_info_multi_scheduling_blockers"></marker>
+ <p>Returns a list of <c><anno>Pid</anno></c>s when
+ multi-scheduling is blocked, otherwise the empty list is
+ returned. The <c><anno>Pid</anno></c>s in the list
+ represent all the processes currently
+ blocking multi-scheduling. A <c><anno>Pid</anno></c> occurs
+ only once in the list, even if the corresponding
process has blocked multiple times.</p>
- <p>See also <seealso marker="#system_flag_multi_scheduling">erlang:system_flag(multi_scheduling, BlockState)</seealso>,
- <seealso marker="#system_info_multi_scheduling">erlang:system_info(multi_scheduling)</seealso>, and
+ <p>See also
+ <seealso marker="#system_flag_multi_scheduling">erlang:system_flag(multi_scheduling, BlockState)</seealso>,
+ <seealso marker="#system_info_multi_scheduling">erlang:system_info(multi_scheduling)</seealso>,
+ and
<seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso>.</p>
</item>
<tag><c>nif_version</c></tag>
<item>
- <p>Returns a string containing the erlang NIF version
- used by the runtime system. It will be on the form "&lt;major ver&gt;.&lt;minor ver&gt;".</p>
+ <p>Returns a string containing the version of the Erlang NIF interface
+ used by the runtime system. It is on the form
+ "&lt;major ver&gt;.&lt;minor ver&gt;".</p>
</item>
- <tag><marker id="system_info_otp_release"><c>otp_release</c></marker></tag>
+ <tag><c>otp_release</c></tag>
<item>
+ <marker id="system_info_otp_release"></marker>
<p>Returns a string containing the OTP release number of the
- OTP release that the currently executing ERTS application is
+ OTP release that the currently executing <c>ERTS</c> application is
part of.</p>
- <p>As of OTP release 17, the OTP release number corresponds to
- the major OTP version number. There is no
- <c>erlang:system_info()</c> argument giving the exact OTP
- version. This since the exact OTP version in the general case
- is hard to determine. For more information see
- <seealso marker="doc/system_principles:versions">the
- documentation of versions in the system principles
- guide</seealso>.</p>
+ <p>As from OTP 17, the OTP release number corresponds to
+ the major OTP version number. No
+ <c>erlang:system_info()</c> argument gives the exact OTP
+ version. This is because the exact OTP version in the general case
+ is difficult to determine. For more information, see the description
+ of versions in <seealso marker="doc/system_principles:versions">
+ System principles</seealso> in System Documentation.</p>
</item>
- <tag><marker id="system_info_os_monotonic_time_source"><c>os_monotonic_time_source</c></marker></tag>
+ <tag><marker id="system_info_os_monotonic_time_source"/><c>os_monotonic_time_source</c></tag>
<item>
<p>Returns a list containing information about the source of
<seealso marker="erts:time_correction#OS_Monotonic_Time">OS
monotonic time</seealso> that is used by the runtime system.</p>
- <p>In case <c>[]</c> is returned, no OS monotonic time is
+ <p>If <c>[]</c> is returned, no OS monotonic time is
available. The list contains two-tuples with <c>Key</c>s
as first element, and <c>Value</c>s as second element. The
- order if these tuples is undefined. Currently the following
- tuples may be part of the list, but more tuples may be
+ order of these tuples is undefined. The following
+ tuples can be part of the list, but more tuples can be
introduced in the future:</p>
<taglist>
<tag><c>{function, Function}</c></tag>
- <item><p><c>Function</c> is the name of the funcion
+ <item><p><c>Function</c> is the name of the function
used. This tuple always exist if OS monotonic time is
available to the runtime system.</p></item>
<tag><c>{clock_id, ClockId}</c></tag>
<item><p>This tuple only exist if <c>Function</c>
can be used with different clocks. <c>ClockId</c>
- corresponds to the clock identifer used when calling
+ corresponds to the clock identifier used when calling
<c>Function</c>.</p></item>
<tag><c>{resolution, OsMonotonicTimeResolution}</c></tag>
<item><p>Highest possible
<seealso marker="time_correction#Time_Resolution">resolution</seealso>
of current OS monotonic time source as parts per
- second. If no resolution information can be retreived
- from the OS, <c>OsMonotonicTimeResolution</c> will be
+ second. If no resolution information can be retrieved
+ from the OS, <c>OsMonotonicTimeResolution</c> is
set to the resolution of the time unit of
<c>Function</c>s return value. That is, the actual
- resolution may be lower than
+ resolution can be lower than
<c>OsMonotonicTimeResolution</c>. Also note that
the resolution does not say anything about the
<seealso marker="time_correction#Time_Accuracy">accuracy</seealso>,
- and that the
+ and whether the
<seealso marker="time_correction#Time_Precision">precision</seealso>
- might not align with the resolution. You do,
- however, know that the precision won't be
- better than
+ do align with the resolution. You do,
+ however, know that the precision is not better than
<c>OsMonotonicTimeResolution</c>.</p></item>
<tag><c>{extended, Extended}</c></tag>
@@ -6692,15 +7121,15 @@ ok
<seealso marker="#type_time_unit">time unit</seealso>.</p></item>
</taglist>
</item>
- <tag><marker id="system_info_os_system_time_source"><c>os_system_time_source</c></marker></tag>
+ <tag><marker id="system_info_os_system_time_source"/><c>os_system_time_source</c></tag>
<item>
<p>Returns a list containing information about the source of
<seealso marker="erts:time_correction#OS_System_Time">OS
system time</seealso> that is used by the runtime system.</p>
<p>The list contains two-tuples with <c>Key</c>s
as first element, and <c>Value</c>s as second element. The
- order if these tuples is undefined. Currently the following
- tuples may be part of the list, but more tuples may be
+ order if these tuples is undefined. The following
+ tuples can be part of the list, but more tuples can be
introduced in the future:</p>
<taglist>
<tag><c>{function, Function}</c></tag>
@@ -6710,26 +7139,25 @@ ok
<tag><c>{clock_id, ClockId}</c></tag>
<item><p>This tuple only exist if <c>Function</c>
can be used with different clocks. <c>ClockId</c>
- corresponds to the clock identifer used when calling
+ corresponds to the clock identifier used when calling
<c>Function</c>.</p></item>
<tag><c>{resolution, OsSystemTimeResolution}</c></tag>
<item><p>Highest possible
<seealso marker="time_correction#Time_Resolution">resolution</seealso>
of current OS system time source as parts per
- second. If no resolution information can be retreived
- from the OS, <c>OsSystemTimeResolution</c> will be
+ second. If no resolution information can be retrieved
+ from the OS, <c>OsSystemTimeResolution</c> is
set to the resolution of the time unit of
<c>Function</c>s return value. That is, the actual
resolution may be lower than
<c>OsSystemTimeResolution</c>. Also note that
the resolution does not say anything about the
<seealso marker="time_correction#Time_Accuracy">accuracy</seealso>,
- and that the
+ and whether the
<seealso marker="time_correction#Time_Precision">precision</seealso>
- might not align with the resolution. You do,
- however, know that the precision won't be
- better than
+ do align with the resolution. You do,
+ however, know that the precision is not better than
<c>OsSystemTimeResolution</c>.</p></item>
<tag><c>{parallel, Parallel}</c></tag>
@@ -6745,130 +7173,136 @@ ok
<seealso marker="#type_time_unit">time unit</seealso>.</p></item>
</taglist>
</item>
- <tag><marker id="system_info_port_parallelism"><c>port_parallelism</c></marker></tag>
- <item><p>Returns the default port parallelism scheduling hint used.
- For more information see the
- <seealso marker="erl#+spp">+spp</seealso> command line argument
- of <seealso marker="erl">erl(1)</seealso>.</p></item>
+ <tag><c>port_parallelism</c></tag>
+ <item>
+ <marker id="system_info_port_parallelism"></marker>
+ <p>Returns the default port parallelism scheduling hint used.
+ For more information, see command-line argument
+ <seealso marker="erl#+spp">+spp</seealso> in <c>erl(1)</c>.</p></item>
<tag><marker id="system_info_port_count"/><c>port_count</c></tag>
<item>
- <p>Returns the number of ports currently existing at
- the local node as an integer. The same value as
- <c>length(erlang:ports())</c> returns, but more efficient.</p>
+ <p>Returns the number of ports currently existing at the
+ local node. The value is given as an integer. This is
+ the same value as returned by
+ <c>length(erlang:ports())</c>, but more efficient.</p>
</item>
- <tag><marker id="system_info_port_limit"><c>port_limit</c></marker></tag>
+ <tag><c>port_limit</c></tag>
<item>
+ <marker id="system_info_port_limit"></marker>
<p>Returns the maximum number of simultaneously existing
- ports at the local node as an integer. This limit
- can be configured at startup by using the
- <seealso marker="erl#+Q">+Q</seealso>
- command line flag of
- <seealso marker="erl">erl(1)</seealso>.</p>
+ ports at the local node as an integer. This limit can be
+ configured at startup by using command-line flag
+ <seealso marker="erl#+Q">+Q</seealso> in <c>erl(1)</c>.</p>
</item>
<tag><marker id="system_info_process_count"/><c>process_count</c></tag>
<item>
- <p>Returns the number of processes currently existing at
- the local node as an integer. The same value as
- <c>length(processes())</c> returns, but more efficient.</p>
+ <p>Returns the number of processes currently existing at the
+ local node. The value is given as an integer. This is
+ the same value as returned by
+ <c>length(processes())</c>, but more efficient.</p>
</item>
- <tag><marker id="system_info_process_limit"><c>process_limit</c></marker></tag>
+ <tag><c>process_limit</c></tag>
<item>
+ <marker id="system_info_process_limit"></marker>
<p>Returns the maximum number of simultaneously existing
- processes at the local node as an integer. This limit
- can be configured at startup by using the
- <seealso marker="erl#+P">+P</seealso>
- command line flag of
- <seealso marker="erl">erl(1)</seealso>.</p>
+ processes at the local node. The value is given as an
+ integer. This limit can be configured at startup by using
+ command-line flag <seealso marker="erl#+P">+P</seealso>
+ in <c>erl(1)</c>.</p>
</item>
<tag><c>procs</c></tag>
<item>
<p>Returns a binary containing a string of process and port
information formatted as in Erlang crash dumps. For more
- information see the <seealso marker="erts:crash_dump">"How to interpret the Erlang crash dumps"</seealso> chapter
- in the ERTS User's Guide.</p>
+ information, see Section
+ <seealso marker="erts:crash_dump">"How to interpret the Erlang crash dumps"</seealso>
+ in the User's Guide.</p>
</item>
- <tag><marker id="system_info_scheduler_bind_type"><c>scheduler_bind_type</c></marker></tag>
+ <tag><c>scheduler_bind_type</c></tag>
<item>
- <p>Returns information on how user has requested
+ <marker id="system_info_scheduler_bind_type"></marker>
+ <p>Returns information about how the user has requested
schedulers to be bound or not bound.</p>
- <p><em>NOTE:</em> Even though user has requested
- schedulers to be bound, they might have silently failed
- to bind. In order to inspect actual scheduler bindings call
- <seealso marker="#system_info_scheduler_bindings">erlang:system_info(scheduler_bindings)</seealso>.
- </p>
- <p>For more information, see
- the <c>erl</c> <seealso marker="erts:erl#+sbt">+sbt</seealso>
- command line argument, and
- <seealso marker="#system_info_scheduler_bindings">erlang:system_info(scheduler_bindings)</seealso>.
- </p>
- </item>
- <tag><marker id="system_info_scheduler_bindings"><c>scheduler_bindings</c></marker></tag>
- <item>
- <p>Returns information on currently used scheduler
+ <p>Notice that even though a user has requested
+ schedulers to be bound, they can silently have failed
+ to bind. To inspect the scheduler bindings, call
+ <seealso marker="#system_info_scheduler_bindings">erlang:system_info(scheduler_bindings)</seealso>.</p>
+ <p>For more information, see command-line argument
+ <seealso marker="erts:erl#+sbt">+sbt</seealso>
+ in <c>erl(1)</c> and
+ <seealso marker="#system_info_scheduler_bindings">erlang:system_info(scheduler_bindings)</seealso>.</p>
+ </item>
+ <tag><c>scheduler_bindings</c></tag>
+ <item>
+ <marker id="system_info_scheduler_bindings"></marker>
+ <p>Returns information about the currently used scheduler
bindings.</p>
<p>A tuple of a size equal to
- <seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso> is returned. The elements of the tuple are integers
+ <seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso>
+ is returned. The tuple elements are integers
or the atom <c>unbound</c>. Logical processor identifiers
are represented as integers. The <c>N</c>th
element of the tuple equals the current binding for
the scheduler with the scheduler identifier equal to
- <c>N</c>. E.g., if the schedulers have been bound,
+ <c>N</c>. For example, if the schedulers are bound,
<c>element(erlang:system_info(scheduler_id),
- erlang:system_info(scheduler_bindings))</c> will return
+ erlang:system_info(scheduler_bindings))</c> returns
the identifier of the logical processor that the calling
- process is executing on.
- </p>
- <p>Note that only schedulers online can be bound to logical
+ process is executing on.</p>
+ <p>Notice that only schedulers online can be bound to logical
processors.</p>
- <p>For more information, see
- the <c>erl</c> <seealso marker="erts:erl#+sbt">+sbt</seealso>
- command line argument,
+ <p>For more information, see command-line argument
+ <seealso marker="erts:erl#+sbt">+sbt</seealso>
+ in <c>erl(1)</c> and
<seealso marker="#system_info_schedulers_online">erlang:system_info(schedulers_online)</seealso>.
</p>
</item>
- <tag><marker id="system_info_scheduler_id"><c>scheduler_id</c></marker></tag>
+ <tag><c>scheduler_id</c></tag>
<item>
- <p>Returns the scheduler id (<c>SchedulerId</c>) of the
+ <marker id="system_info_scheduler_id"></marker>
+ <p>Returns the scheduler ID (<c>SchedulerId</c>) of the
scheduler thread that the calling process is executing
- on. <c><anno>SchedulerId</anno></c> is a positive integer; where
- <c><![CDATA[1 <= SchedulerId <= erlang:system_info(schedulers)]]></c>. See also
+ on. <c><anno>SchedulerId</anno></c> is a positive integer,
+ where
+ <c><![CDATA[1 <= SchedulerId <= erlang:system_info(schedulers)]]></c>.
+ See also
<seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso>.</p>
</item>
- <tag><marker id="system_info_schedulers"><c>schedulers</c></marker></tag>
+ <tag><c>schedulers</c></tag>
<item>
+ <marker id="system_info_schedulers"></marker>
<p>Returns the number of scheduler threads used by
the emulator. Scheduler threads online schedules Erlang
processes and Erlang ports, and execute Erlang code
- and Erlang linked in driver code.</p>
+ and Erlang linked-in driver code.</p>
<p>The number of scheduler threads is determined at
- emulator boot time and cannot be changed after
- that. The amount of schedulers online can
- however be changed at any time.</p>
- <p>See also <seealso marker="#system_flag_schedulers_online">erlang:system_flag(schedulers_online, SchedulersOnline)</seealso>,
+ emulator boot time and cannot be changed later.
+ However, the number of schedulers online can
+ be changed at any time.</p>
+ <p>See also
+ <seealso marker="#system_flag_schedulers_online">erlang:system_flag(schedulers_online, SchedulersOnline)</seealso>,
<seealso marker="#system_info_schedulers_online">erlang:system_info(schedulers_online)</seealso>,
<seealso marker="#system_info_scheduler_id">erlang:system_info(scheduler_id)</seealso>,
<seealso marker="#system_flag_multi_scheduling">erlang:system_flag(multi_scheduling, BlockState)</seealso>,
- <seealso marker="#system_info_multi_scheduling">erlang:system_info(multi_scheduling)</seealso>, and
- and <seealso marker="#system_info_multi_scheduling_blockers">erlang:system_info(multi_scheduling_blockers)</seealso>.</p>
+ <seealso marker="#system_info_multi_scheduling">erlang:system_info(multi_scheduling)</seealso>,
+ and
+ <seealso marker="#system_info_multi_scheduling_blockers">erlang:system_info(multi_scheduling_blockers)</seealso>.</p>
</item>
- <tag><marker id="system_info_schedulers_online"><c>schedulers_online</c></marker></tag>
+ <tag><c>schedulers_online</c></tag>
<item>
- <p>Returns the amount of schedulers online. The scheduler
- identifiers of schedulers online satisfy the following
- relationship:
- <c><![CDATA[1 <= SchedulerId <= erlang:system_info(schedulers_online)]]></c>.
- </p>
+ <marker id="system_info_schedulers_online"></marker>
+ <p>Returns the number of schedulers online. The scheduler
+ identifiers of schedulers online satisfy the relationship
+ <c><![CDATA[1 <= SchedulerId <= erlang:system_info(schedulers_online)]]></c>.</p>
<p>For more information, see
- <seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso>,
+ <seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso>
and
- <seealso marker="#system_flag_schedulers_online">erlang:system_flag(schedulers_online, SchedulersOnline)</seealso>.
- </p> <name name="system_info" arity="1" clause_i="49"/>
-
+ <seealso marker="#system_flag_schedulers_online">erlang:system_flag(schedulers_online, SchedulersOnline)</seealso>.</p>
</item>
<tag><c>smp_support</c></tag>
<item>
<p>Returns <c>true</c> if the emulator has been compiled
- with smp support; otherwise, <c>false</c>.</p>
+ with SMP support, otherwise <c>false</c> is returned.</p>
</item>
<tag><marker id="system_info_start_time"/><c>start_time</c></tag>
<item><p>The <seealso marker="#monotonic_time/0">Erlang monotonic
@@ -6880,7 +7314,7 @@ ok
<tag><c>system_version</c></tag>
<item>
<p>Returns a string containing version number and
- some important properties such as the number of schedulers.</p>
+ some important properties, such as the number of schedulers.</p>
</item>
<tag><c>system_architecture</c></tag>
<item>
@@ -6890,23 +7324,28 @@ ok
<tag><c>threads</c></tag>
<item>
<p>Returns <c>true</c> if the emulator has been compiled
- with thread support; otherwise, <c>false</c> is
- returned.</p>
+ with thread support, otherwise <c>false</c> is returned.</p>
</item>
- <tag><marker id="system_info_thread_pool_size"><c>thread_pool_size</c></marker></tag>
+ <tag><c>thread_pool_size</c></tag>
<item>
+ <marker id="system_info_thread_pool_size"></marker>
<p>Returns the number of async threads in the async thread
pool used for asynchronous driver calls
- (<seealso marker="erts:erl_driver#driver_async">driver_async()</seealso>)
- as an integer.</p>
+ (<seealso marker="erts:erl_driver#driver_async">driver_async()</seealso>).
+ The value is given as an integer.</p>
</item>
- <tag><marker id="system_info_time_correction"/><c>time_correction</c></tag>
- <item><p>Returns a boolean value indicating whether
+
+ <tag><c>time_correction</c></tag>
+ <item>
+ <marker id="system_info_time_correction"></marker>
+ <p>Returns a boolean value indicating whether
<seealso marker="time_correction#Time_Correction">time correction</seealso>
is enabled or not.
</p></item>
- <tag><marker id="system_info_time_offset"/><c>time_offset</c></tag>
- <item><p>Returns the state of the time offset:</p>
+ <tag><c>time_offset</c></tag>
+ <item>
+ <marker id="system_info_time_offset"></marker>
+ <p>Returns the state of the time offset:</p>
<taglist>
<tag><c>preliminary</c></tag>
<item><p>The time offset is preliminary, and will be changed
@@ -6916,19 +7355,18 @@ ok
time warp mode</seealso>.</p></item>
<tag><c>final</c></tag>
- <item><p>The time offset is final. This
- either due to the use of the
+ <item><p>The time offset is final. This either because
<seealso marker="time_correction#No_Time_Warp_Mode">no
- time warp mode</seealso>, or due to the time offset having
- been finalized when using the
+ time warp mode</seealso> is used, or because the time
+ offset have been finalized when
<seealso marker="time_correction#Single_Time_Warp_Mode">single
- time warp mode</seealso>.</p></item>
+ time warp mode</seealso> is used.</p></item>
<tag><c>volatile</c></tag>
- <item><p>The time offset is volatile. That is, it may
- change at any time. This due to the
+ <item><p>The time offset is volatile. That is, it can
+ change at any time. This is because
<seealso marker="time_correction#Multi_Time_Warp_Mode">multi
- time warp mode</seealso> being used.</p></item>
+ time warp mode</seealso> is used.</p></item>
</taglist>
</item>
<tag><marker id="system_info_time_warp_mode"/><c>time_warp_mode</c></tag>
@@ -6938,19 +7376,20 @@ ok
<taglist>
<tag><c>no_time_warp</c></tag>
<item><p>The <seealso marker="time_correction#No_Time_Warp_Mode">no
- time warp mode</seealso> is being used.</p></item>
+ time warp mode</seealso> is used.</p></item>
<tag><c>single_time_warp</c></tag>
<item><p>The <seealso marker="time_correction#Single_Time_Warp_Mode">single
- time warp mode</seealso> is being used.</p></item>
+ time warp mode</seealso> is used.</p></item>
<tag><c>multi_time_warp</c></tag>
<item><p>The <seealso marker="time_correction#Multi_Time_Warp_Mode">multi
- time warp mode</seealso> is being used.</p></item>
+ time warp mode</seealso> is used.</p></item>
</taglist>
</item>
- <tag><marker id="system_info_tolerant_timeofday"><c>tolerant_timeofday</c></marker></tag>
+ <tag><c>tolerant_timeofday</c></tag>
<item>
+ <marker id="system_info_tolerant_timeofday"></marker>
<p>Returns whether a pre erts-7.0 backwards compatible compensation
for sudden changes of system time is <c>enabled</c> or <c>disabled</c>.
Such compensation is <c>enabled</c> when the
@@ -6961,90 +7400,92 @@ ok
</item>
<tag><c>trace_control_word</c></tag>
<item>
- <p>Returns the value of the node's trace control word.
- For more information see documentation of the function
- <c>get_tcw</c> in "Match Specifications in Erlang",
- <seealso marker="erts:match_spec#get_tcw">ERTS User's Guide</seealso>.</p>
+ <p>Returns the value of the node trace control word. For
+ more information, see function <c>get_tcw</c> in Section
+ <seealso marker="erts:match_spec#get_tcw">Match Specifications in Erlang</seealso> in the User's Guide.</p>
</item>
- <tag><marker id="update_cpu_info"><c>update_cpu_info</c></marker></tag>
+ <tag><c>update_cpu_info</c></tag>
<item>
- <p>The runtime system rereads the CPU information available and
- updates its internally stored information about the
- <seealso marker="#system_info_cpu_topology_detected">detected CPU
- topology</seealso> and the amount of logical processors
+ <marker id="update_cpu_info"></marker>
+ <p>The runtime system rereads the CPU information available
+ and updates its internally stored information about the
+ <seealso marker="#system_info_cpu_topology_detected">detected
+ CPU topology</seealso> and the number of logical processors
<seealso marker="#logical_processors">configured</seealso>,
<seealso marker="#logical_processors_online">online</seealso>, and
- <seealso marker="#logical_processors_available">available</seealso>.
- If the CPU information has changed since the last time it was read,
- the atom <c>changed</c> is returned; otherwise, the atom
- <c>unchanged</c> is returned. If the CPU information has changed
+ <seealso marker="#logical_processors_available">available</seealso>.</p>
+ <p>If the CPU information has changed since the last time
+ it was read, the atom <c>changed</c> is returned, otherwise
+ the atom <c>unchanged</c>. If the CPU information has changed,
you probably want to
- <seealso marker="#system_flag_schedulers_online">adjust the amount
- of schedulers online</seealso>. You typically want to have as
- many schedulers online as
- <seealso marker="#logical_processors_available">logical processors
- available</seealso>.
- </p>
+ <seealso marker="#system_flag_schedulers_online">adjust the
+ number of schedulers online</seealso>. You typically want
+ to have as many schedulers online as
+ <seealso marker="#logical_processors_available">logical
+ processors available</seealso>.</p>
</item>
- <tag><marker id="system_info_version"><c>version</c></marker></tag>
+ <tag><c>version</c></tag>
<item>
+ <marker id="system_info_version"></marker>
<p>Returns a string containing the version number of the
emulator.</p>
</item>
<tag><c>wordsize</c></tag>
<item>
- <p>Same as <c>{wordsize, internal}.</c></p>
+ <p>Same as <c>{wordsize, internal}</c>.</p>
</item>
<tag><c>{wordsize, internal}</c></tag>
<item>
<p>Returns the size of Erlang term words in bytes as an
- integer, i.e. on a 32-bit architecture 4 is returned,
- and on a pure 64-bit architecture 8 is returned. On a
+ integer, that is, 4 is returned on a 32-bit architecture,
+ and 8 is returned on a pure 64-bit architecture. On a
halfword 64-bit emulator, 4 is returned, as the Erlang
- terms are stored using a virtual wordsize of half the
- system's wordsize.</p>
+ terms are stored using a virtual word size of half the
+ system word size.</p>
</item>
<tag><c>{wordsize, external}</c></tag>
<item>
- <p>Returns the true wordsize of the emulator, i.e. the size
- of a pointer, in bytes as an integer. On a pure 32-bit
- architecture 4 is returned, on both a halfword and pure
+ <p>Returns the true word size of the emulator, that is,
+ the size of a pointer. The value is given in bytes
+ as an integer. On a pure 32-bit architecture, 4 is
+ returned. On both a half word and on a pure
64-bit architecture, 8 is returned.</p>
</item>
</taglist>
<note>
- <p>The <c>scheduler</c> argument has changed name to
- <c>scheduler_id</c>. This in order to avoid mixup with
- the <c>schedulers</c> argument. The <c>scheduler</c>
- argument was introduced in ERTS version 5.5 and renamed
- in ERTS version 5.5.1.</p>
+ <p>Argument <c>scheduler</c> has changed name to
+ <c>scheduler_id</c> to avoid mix up with argument
+ <c>schedulers</c>. Argument <c>scheduler</c> was
+ introduced in <c>ERTS</c> 5.5 and renamed in
+ <c>ERTS</c> 5.5.1.</p>
</note>
</desc>
</func>
<func>
<name name="system_monitor" arity="0"/>
+ <fsummary>Current system performance monitoring settings.</fsummary>
<type name="system_monitor_option"/>
- <fsummary>Current system performance monitoring settings</fsummary>
<desc>
<p>Returns the current system monitoring settings set by
<seealso marker="#system_monitor/2">erlang:system_monitor/2</seealso>
- as <c>{<anno>MonitorPid</anno>, <anno>Options</anno>}</c>, or <c>undefined</c> if there
- are no settings. The order of the options may be different
+ as <c>{<anno>MonitorPid</anno>, <anno>Options</anno>}</c>,
+ or <c>undefined</c> if there
+ are no settings. The order of the options can be different
from the one that was set.</p>
</desc>
</func>
<func>
<name name="system_monitor" arity="1"/>
+ <fsummary>Sets or clears system performance monitoring options.</fsummary>
<type name="system_monitor_option"/>
- <fsummary>Set or clear system performance monitoring options</fsummary>
<desc>
- <p>When called with the argument <c>undefined</c>, all
+ <p>When called with argument <c>undefined</c>, all
system performance monitoring settings are cleared.</p>
- <p>Calling the function with <c>{<anno>MonitorPid</anno>, <anno>Options</anno>}</c> as
- argument, is the same as calling
- <seealso marker="#system_monitor/2">erlang:system_monitor(<anno>MonitorPid</anno>, <anno>Options</anno>)</seealso>.</p>
+ <p>Calling the function with <c>{<anno>MonitorPid</anno>,
+ <anno>Options</anno>}</c> as argument is the same as calling
+ <seealso marker="#system_monitor/2"><c>erlang:system_monitor(<anno>MonitorPid</anno>, <anno>Options</anno>)</c></seealso>.</p>
<p>Returns the previous system monitor settings just like
<seealso marker="#system_monitor/0">erlang:system_monitor/0</seealso>.</p>
</desc>
@@ -7052,102 +7493,101 @@ ok
<func>
<name name="system_monitor" arity="2"/>
+ <fsummary>Sets system performance monitoring options.</fsummary>
<type name="system_monitor_option"/>
- <fsummary>Set system performance monitoring options</fsummary>
<desc>
- <p>Sets system performance monitoring options. <c><anno>MonitorPid</anno></c>
- is a local pid that will receive system monitor messages, and
- the second argument is a list of monitoring options:</p>
+ <p>Sets the system performance monitoring options.
+ <c><anno>MonitorPid</anno></c> is a local process identifier (pid)
+ receiving system monitor messages. The
+ second argument is a list of monitoring options:</p>
<taglist>
<tag><c>{long_gc, Time}</c></tag>
<item>
<p>If a garbage collection in the system takes at least
- <c>Time</c> wallclock milliseconds, a message
+ <c>Time</c> wall clock milliseconds, a message
<c>{monitor, GcPid, long_gc, Info}</c> is sent to
- <c><anno>MonitorPid</anno></c>. <c>GcPid</c> is the pid that was
- garbage collected and <c>Info</c> is a list of two-element
- tuples describing the result of the garbage collection.
- One of the tuples is <c>{timeout, GcTime}</c> where
- <c>GcTime</c> is the actual time for the garbage
+ <c><anno>MonitorPid</anno></c>. <c>GcPid</c> is the pid that
+ was garbage collected. <c>Info</c> is a list of two-element
+ tuples describing the result of the garbage collection.</p>
+ <p>One of the tuples is <c>{timeout, GcTime}</c>, where
+ <c>GcTime</c> is the time for the garbage
collection in milliseconds. The other tuples are
- tagged with <c>heap_size</c>, <c>heap_block_size</c>,
- <c>stack_size</c>, <c>mbuf_size</c>, <c>old_heap_size</c>,
- and <c>old_heap_block_size</c>. These tuples are
- explained in the documentation of the
- <seealso marker="#gc_start">gc_start</seealso>
- trace message (see
- <seealso marker="#trace/3">erlang:trace/3</seealso>).
- New tuples may be added, and the order of the tuples in
- the <c>Info</c> list may be changed at any time without prior
- notice.
- </p>
+ tagged with <c>heap_size</c>, <c>heap_block_size</c>
+ <c>stack_size</c>, <c>mbuf_size</c>, <c>old_heap_size</c>,
+ and <c>old_heap_block_size</c>. These tuples are
+ explained in the description of trace message
+ <seealso marker="#gc_start">gc_start</seealso> (see
+ <seealso marker="#trace/3">erlang:trace/3</seealso>).
+ New tuples can be added, and the order of the tuples in
+ the <c>Info</c> list can be changed at any time without
+ prior notice.</p>
</item>
<tag><c>{long_schedule, Time}</c></tag>
<item>
- <p>If a process or port in the system runs uninterrupted
+ <p>If a process or port in the system runs uninterrupted
for at least <c>Time</c> wall clock milliseconds, a
message <c>{monitor, PidOrPort, long_schedule, Info}</c>
is sent to <c>MonitorPid</c>. <c>PidOrPort</c> is the
- process or port that was running and <c>Info</c> is a
- list of two-element tuples describing the event. In case
- of a <c>pid()</c>, the tuples <c>{timeout, Millis}</c>,
- <c>{in, Location}</c> and <c>{out, Location}</c> will be
+ process or port that was running. <c>Info</c> is a
+ list of two-element tuples describing the event.</p>
+ <p>If a <c>pid()</c>, the tuples <c>{timeout, Millis}</c>,
+ <c>{in, Location}</c>, and <c>{out, Location}</c> are
present, where <c>Location</c> is either an MFA
(<c>{Module, Function, Arity}</c>) describing the
function where the process was scheduled in/out, or the
- atom <c>undefined</c>. In case of a <c>port()</c>, the
+ atom <c>undefined</c>.</p>
+ <p>If a <c>port()</c>, the
tuples <c>{timeout, Millis}</c> and <c>{port_op,Op}</c>
- will be present. <c>Op</c> will be one of <c>proc_sig</c>,
+ are present. <c>Op</c> is one of <c>proc_sig</c>,
<c>timeout</c>, <c>input</c>, <c>output</c>,
- <c>event</c> or <c>dist_cmd</c>, depending on which
- driver callback was executing. <c>proc_sig</c> is an
- internal operation and should never appear, while the
+ <c>event</c>, or <c>dist_cmd</c>, depending on which
+ driver callback was executing.</p>
+ <p><c>proc_sig</c> is an
+ internal operation and is never to appear, while the
others represent the corresponding driver callbacks
<c>timeout</c>, <c>ready_input</c>, <c>ready_output</c>,
- <c>event</c> and finally <c>outputv</c> (when the port
- is used by distribution). The <c>Millis</c> value in
- the <c>timeout</c> tuple will tell you the actual
- uninterrupted execution time of the process or port,
- which will always be <c>&gt;=</c> the <c>Time</c> value
- supplied when starting the trace. New tuples may be
- added to the <c>Info</c> list in the future, and the
- order of the tuples in the list may be changed at any
- time without prior notice.
- </p>
- <p>This can be used to detect problems with NIF's or
- drivers that take too long to execute. Generally, 1 ms
- is considered a good maximum time for a driver callback
- or a NIF. However, a time sharing system should usually
- consider everything below 100 ms as "possible" and
- fairly "normal". Schedule times above that might however
- indicate swapping or a NIF/driver that is
- misbehaving. Misbehaving NIF's and drivers could cause
- bad resource utilization and bad overall performance of
- the system.</p>
+ <c>event</c>, and <c>outputv</c> (when the port
+ is used by distribution). Value <c>Millis</c> in
+ the <c>timeout</c> tuple informs about the
+ uninterrupted execution time of the process or port, which
+ always is equal to or higher than the <c>Time</c> value
+ supplied when starting the trace. New tuples can be
+ added to the <c>Info</c> list in a future release. The
+ order of the tuples in the list can be changed at any
+ time without prior notice.</p>
+ <p>This can be used to detect problems with NIFs or
+ drivers that take too long to execute. 1 ms is
+ considered a good maximum time for a driver callback
+ or a NIF. However, a time-sharing system is usually to
+ consider everything below 100 ms as "possible" and
+ fairly "normal". However, longer schedule times can
+ indicate swapping or a misbehaving NIF/driver.
+ Misbehaving NIFs and drivers can cause bad resource
+ utilization and bad overall system performance.</p>
</item>
<tag><c>{large_heap, Size}</c></tag>
<item>
<p>If a garbage collection in the system results in
the allocated size of a heap being at least <c>Size</c>
words, a message <c>{monitor, GcPid, large_heap, Info}</c>
- is sent to <c><anno>MonitorPid</anno></c>. <c>GcPid</c> and <c>Info</c>
- are the same as for <c>long_gc</c> above, except that
- the tuple tagged with <c>timeout</c> is not present.
- <em>Note</em>: As of erts version 5.6 the monitor message
- is sent if the sum of the sizes of all memory blocks allocated
- for all heap generations is equal to or larger than <c>Size</c>.
- Previously the monitor message was sent if the memory block
- allocated for the youngest generation was equal to or larger
- than <c>Size</c>.
- </p>
+ is sent to <c><anno>MonitorPid</anno></c>.
+ <c>GcPid</c> and <c>Info</c>
+ are the same as for <c>long_gc</c> earlier, except that
+ the tuple tagged with <c>timeout</c> is not present.</p>
+ <p>As of <c>ERTS</c> 5.6, the monitor message is sent
+ if the sum of the sizes of all memory blocks allocated
+ for all heap generations is equal to or higher than <c>Size</c>.
+ Previously the monitor message was sent if the memory block
+ allocated for the youngest generation was equal to or higher
+ than <c>Size</c>.</p>
</item>
<tag><c>busy_port</c></tag>
<item>
<p>If a process in the system gets suspended because it
sends to a busy port, a message
<c>{monitor, SusPid, busy_port, Port}</c> is sent to
- <c><anno>MonitorPid</anno></c>. <c>SusPid</c> is the pid that got
- suspended when sending to <c>Port</c>.</p>
+ <c><anno>MonitorPid</anno></c>. <c>SusPid</c> is the pid
+ that got suspended when sending to <c>Port</c>.</p>
</item>
<tag><c>busy_dist_port</c></tag>
<item>
@@ -7155,8 +7595,8 @@ ok
sends to a process on a remote node whose inter-node
communication was handled by a busy port, a message
<c>{monitor, SusPid, busy_dist_port, Port}</c> is sent to
- <c><anno>MonitorPid</anno></c>. <c>SusPid</c> is the pid that got
- suspended when sending through the inter-node
+ <c><anno>MonitorPid</anno></c>. <c>SusPid</c> is the pid
+ that got suspended when sending through the inter-node
communication port <c>Port</c>.</p>
</item>
</taglist>
@@ -7165,74 +7605,76 @@ ok
<note>
<p>If a monitoring process gets so large that it itself
starts to cause system monitor messages when garbage
- collecting, the messages will enlarge the process's
+ collecting, the messages enlarge the process
message queue and probably make the problem worse.</p>
<p>Keep the monitoring process neat and do not set the system
monitor limits too tight.</p>
</note>
- <p>Failure: <c>badarg</c> if <c><anno>MonitorPid</anno></c> does not exist or is not a local process.</p>
+ <p>Failures:</p>
+ <taglist>
+ <tag><c>badarg</c></tag>
+ <item>If <c><anno>MonitorPid</anno></c> does not exist.</item>
+ <tag><c>badarg</c></tag>
+ <item>If <c><anno>MonitorPid</anno></c> is not a local process.</item>
+ </taglist>
</desc>
</func>
<func>
<name name="system_profile" arity="0"/>
+ <fsummary>Current system profiling settings.</fsummary>
<type name="system_profile_option"/>
- <fsummary>Current system profiling settings</fsummary>
<desc>
<p>Returns the current system profiling settings set by
<seealso marker="#system_profile/2">erlang:system_profile/2</seealso>
- as <c>{<anno>ProfilerPid</anno>, <anno>Options</anno>}</c>, or <c>undefined</c> if there
- are no settings. The order of the options may be different
+ as <c>{<anno>ProfilerPid</anno>, <anno>Options</anno>}</c>,
+ or <c>undefined</c> if there
+ are no settings. The order of the options can be different
from the one that was set.</p>
</desc>
</func>
<func>
<name name="system_profile" arity="2"/>
+ <fsummary>Current system profiling settings.</fsummary>
<type name="system_profile_option"/>
- <fsummary>Current system profiling settings</fsummary>
<desc>
<p>Sets system profiler options. <c><anno>ProfilerPid</anno></c>
- is a local pid or port that will receive profiling messages. The
- receiver is excluded from all profiling.
+ is a local process identifier (pid) or port receiving profiling
+ messages. The receiver is excluded from all profiling.
The second argument is a list of profiling options:</p>
<taglist>
<tag><c>exclusive</c></tag>
<item>
- <p>
- If a synchronous call to a port from a process is done, the
+ <p>If a synchronous call to a port from a process is done, the
calling process is considered not runnable during the call
runtime to the port. The calling process is notified as
- <c>inactive</c> and subsequently <c>active</c> when the port
- callback returns.
- </p>
+ <c>inactive</c>, and later <c>active</c> when the port
+ callback returns.</p>
</item>
<tag><c>runnable_procs</c></tag>
<item>
- <p>If a process is put into or removed from the run queue a message,
- <c>{profile, Pid, State, Mfa, Ts}</c>, is sent to
- <c><anno>ProfilerPid</anno></c>. Running processes that is reinserted into the
- run queue after having been preemptively scheduled out will not trigger this
- message.
- </p>
+ <p>If a process is put into or removed from the run queue, a
+ message, <c>{profile, Pid, State, Mfa, Ts}</c>, is sent to
+ <c><anno>ProfilerPid</anno></c>. Running processes that
+ are reinserted into the run queue after having been
+ preempted do not trigger this message.</p>
</item>
<tag><c>runnable_ports</c></tag>
<item>
- <p>If a port is put into or removed from the run queue a message,
- <c>{profile, Port, State, 0, Ts}</c>, is sent to
- <c><anno>ProfilerPid</anno></c>.
- </p>
+ <p>If a port is put into or removed from the run queue, a
+ message, <c>{profile, Port, State, 0, Ts}</c>, is sent to
+ <c><anno>ProfilerPid</anno></c>.</p>
</item>
<tag><c>scheduler</c></tag>
<item>
- <p>If a scheduler is put to sleep or awoken a message,
- <c>{profile, scheduler, Id, State, NoScheds, Ts}</c>, is sent
- to <c><anno>ProfilerPid</anno></c>.
- </p>
+ <p>If a scheduler is put to sleep or awoken, a message,
+ <c>{profile, scheduler, Id, State, NoScheds, Ts}</c>, is
+ sent to <c><anno>ProfilerPid</anno></c>.</p>
</item>
</taglist>
- <note><p><c>erlang:system_profile</c> is considered experimental and
- its behaviour may change in the future.</p>
+ <note><p><c>erlang:system_profile</c> is considered experimental
+ and its behavior can change in a future release.</p>
</note>
</desc>
</func>
@@ -7276,11 +7718,12 @@ ok
</func>
<func>
<name name="term_to_binary" arity="1"/>
- <fsummary>Encode a term to an Erlang external term format binary</fsummary>
+ <fsummary>Encodes a term to an Erlang external term format binary.</fsummary>
<desc>
- <p>Returns a binary data object which is the result of encoding
- <c><anno>Term</anno></c> according to the Erlang external term format.</p>
- <p>This can be used for a variety of purposes, for example
+ <p>Returns a binary data object that is the result of encoding
+ <c><anno>Term</anno></c> according to the Erlang external
+ term format.</p>
+ <p>This can be used for various purposes, for example,
writing a term to a file in an efficient way, or sending an
Erlang term to some type of communications channel not
supported by distributed Erlang.</p>
@@ -7288,67 +7731,81 @@ ok
<seealso marker="#binary_to_term/1">binary_to_term/1</seealso>.</p>
</desc>
</func>
+
<func>
<name name="term_to_binary" arity="2"/>
- <fsummary>Encode a term to en Erlang external term format binary</fsummary>
- <desc>
- <p>Returns a binary data object which is the result of encoding
- <c><anno>Term</anno></c> according to the Erlang external term format.</p>
- <p>If the option <c>compressed</c> is provided, the external
- term format will be compressed. The compressed format is
- automatically recognized by <c>binary_to_term/1</c> in R7B and later.</p>
- <p>It is also possible to specify a compression level by giving
- the option <c>{compressed, <anno>Level</anno>}</c>, where <c><anno>Level</anno></c> is an
- integer from 0 through 9. <c>0</c> means that no compression
- will be done (it is the same as not giving any <c>compressed</c> option);
- <c>1</c> will take the least time but may not compress as well as
- the higher levels; <c>9</c> will take the most time and may produce
- a smaller result. Note the "mays" in the preceding sentence; depending
- on the input term, level 9 compression may or may not produce a smaller
- result than level 1 compression.</p>
- <p>Currently, <c>compressed</c> gives the same result as
- <c>{compressed, 6}</c>.</p>
- <p>The option <c>{minor_version, <anno>Version</anno>}</c> can be use to control
- some details of the encoding. This option was
- introduced in R11B-4. Currently, the allowed values for <c><anno>Version</anno></c>
- are <c>0</c> and <c>1</c>.</p>
- <p><c>{minor_version, 1}</c> is since 17.0 the default, it forces any floats in
- the term to be encoded
- in a more space-efficient and exact way (namely in the 64-bit IEEE format,
- rather than converted to a textual representation). <c>binary_to_term/1</c>
- in R11B-4 and later is able decode this representation.</p>
- <p><c>{minor_version, 0}</c> meaning that floats
- will be encoded using a textual representation; this option is useful if
- you want to ensure that releases prior to R11B-4 can decode resulting
+ <fsummary>Encodes a term to en Erlang external term format binary.</fsummary>
+ <desc>
+ <p>Returns a binary data object that is the result of encoding
+ <c><anno>Term</anno></c> according to the Erlang external
+ term format.</p>
+ <p>If option <c>compressed</c> is provided, the external term
+ format is compressed. The compressed format is automatically
+ recognized by <c>binary_to_term/1</c> as from Erlang R7B.</p>
+ <p>A compression level can be specified by giving option
+ <c>{compressed, <anno>Level</anno>}</c>.
+ <c><anno>Level</anno></c> is an integer
+ with range 0..9, where:</p>
+ <list type="bulleted">
+ <item><c>0</c> - No compression is done (it is the same as
+ giving no <c>compressed</c> option).</item>
+ <item><c>1</c> - Takes least time but may not compress
+ as well as the higher levels.</item>
+ <item><c>6</c> - Default level when option <c>compressed</c>
+ is provided.</item>
+ <item><c>9</c> - Takes most time and tries to produce a smaller
+ result. Notice "tries" in the preceding sentence; depending
+ on the input term, level 9 compression either does or does
+ not produce a smaller result than level 1 compression.</item>
+ </list>
+ <p>Option <c>{minor_version, <anno>Version</anno>}</c>
+ can be used to control
+ some encoding details. This option was introduced in OTP R11B-4.
+ The valid values for <c><anno>Version</anno></c> are
+ <c>0</c> and <c>1</c>.</p>
+ <p>As from OTP 17.0, <c>{minor_version, 1}</c> is the default. It
+ forces any floats in the term to be encoded in a more
+ space-efficient and exact way (namely in the 64-bit IEEE format,
+ rather than converted to a textual representation).</p>
+ <p>As from OTP R11B-4, <c>binary_to_term/1</c> can decode this
+ representation.</p>
+ <p><c>{minor_version, 0}</c> means that floats are encoded
+ using a textual representation. This option is useful to
+ ensure that releases before OTP R11B-4 can decode resulting
binary.</p>
<p>See also
<seealso marker="#binary_to_term/1">binary_to_term/1</seealso>.</p>
</desc>
</func>
+
<func>
<name name="throw" arity="1"/>
- <fsummary>Throw an exception</fsummary>
+ <fsummary>Throws an exception.</fsummary>
<desc>
<p>A non-local return from a function. If evaluated within a
- <c>catch</c>, <c>catch</c> will return the value <c><anno>Any</anno></c>.</p>
+ <c>catch</c>, <c>catch</c> returns value <c><anno>Any</anno></c>.</p>
+ <p>Example:</p>
<pre>
> <input>catch throw({hello, there}).</input>
{hello,there}</pre>
<p>Failure: <c>nocatch</c> if not evaluated within a catch.</p>
</desc>
</func>
+
<func>
<name name="time" arity="0"/>
- <fsummary>Current time</fsummary>
+ <fsummary>Current time.</fsummary>
<desc>
<p>Returns the current time as <c>{Hour, Minute, Second}</c>.</p>
- <p>The time zone and daylight saving time correction depend on
+ <p>The time zone and Daylight Saving Time correction depend on
the underlying OS.</p>
+ <p>Example:</p>
<pre>
> <input>time().</input>
{9,42,44}</pre>
</desc>
</func>
+
<func>
<name name="time_offset" arity="0"/>
<fsummary>Current time offset</fsummary>
@@ -7399,14 +7856,14 @@ ok
</func>
<func>
<name name="timestamp" arity="0"/>
- <type name="timestamp"/>
<fsummary>Current Erlang System time</fsummary>
+ <type name="timestamp"/>
<desc>
<p>Returns current
<seealso marker="time_correction#Erlang_System_Time">Erlang system time</seealso>
on the format <c>{MegaSecs, Secs, MicroSecs}</c>. This format is
- the same that <seealso marker="kernel:os#timestamp/0"><c>os:timestamp/0</c></seealso>
- and the now deprecated <seealso marker="#now/0"><c>erlang:now/0</c></seealso>
+ the same as <seealso marker="kernel:os#timestamp/0"><c>os:timestamp/0</c></seealso>
+ and the deprecated <seealso marker="#now/0"><c>erlang:now/0</c></seealso>
uses. The reason for the existence of <c>erlang:timestamp()</c> is
purely to simplify usage for existing code that assumes this timestamp
format. Current Erlang system time can more efficiently be retrieved in
@@ -7420,9 +7877,9 @@ timestamp() ->
Secs = ErlangSystemTime div 1000000 - MegaSecs*1000000,
MicroSecs = ErlangSystemTime rem 1000000,
{MegaSecs, Secs, MicroSecs}.</code>
- <p>It however use a native implementation which does
- not build garbage on the heap and with slightly better
- performance.</p>
+ <p>It, however, uses a native implementation which does
+ not build garbage on the heap and with slightly better
+ performance.</p>
<note><p>This time is <em>not</em> a monotonically increasing time
in the general case. For more information, see the documentation of
@@ -7433,186 +7890,190 @@ timestamp() ->
</func>
<func>
<name name="tl" arity="1"/>
- <fsummary>Tail of a list</fsummary>
+ <fsummary>Tail of a list.</fsummary>
<desc>
- <p>Returns the tail of <c><anno>List</anno></c>, that is, the list minus
- the first element.</p>
+ <p>Returns the tail of <c><anno>List</anno></c>, that is,
+ the list minus the first element, for example:</p>
<pre>
> <input>tl([geesties, guilies, beasties]).</input>
[guilies, beasties]</pre>
<p>Allowed in guard tests.</p>
- <p>Failure: <c>badarg</c> if <c><anno>List</anno></c> is the empty list [].</p>
+ <p>Failure: <c>badarg</c> if <c><anno>List</anno></c>
+ is the empty list <c>[]</c>.</p>
</desc>
</func>
+
<func>
<name name="trace" arity="3"/>
+ <fsummary>Sets trace flags for a process or processes.</fsummary>
<type name="trace_flag"/>
- <fsummary>Set trace flags for a process or processes</fsummary>
<desc>
<p>Turns on (if <c><anno>How</anno> == true</c>) or off (if
- <c><anno>How</anno> == false</c>) the trace flags in <c><anno>FlagList</anno></c> for
- the process or processes represented by <c><anno>PidSpec</anno></c>.</p>
- <p><c><anno>PidSpec</anno></c> is either a pid for a local process, or one of
- the following atoms:</p>
+ <c><anno>How</anno> == false</c>) the trace flags in
+ <c><anno>FlagList</anno></c> for
+ the process or processes represented by
+ <c><anno>PidSpec</anno></c>.</p>
+ <p><c><anno>PidSpec</anno></c> is either a process identifier
+ (pid) for a local process, or one of the following atoms:</p>
<taglist>
<tag><c>existing</c></tag>
<item>
- <p>All processes currently existing.</p>
+ <p>All currently existing processes.</p>
</item>
<tag><c>new</c></tag>
<item>
- <p>All processes that will be created in the future.</p>
+ <p>All processes that are created in the future.</p>
</item>
<tag><c>all</c></tag>
<item>
<p>All currently existing processes and all processes that
- will be created in the future.</p>
+ are created in the future.</p>
</item>
</taglist>
- <p><c><anno>FlagList</anno></c> can contain any number of the following
- flags (the "message tags" refers to the list of messages
- following below):</p>
+ <p><c><anno>FlagList</anno></c> can contain any number of the
+ following flags (the "message tags" refers to the list of
+ <seealso marker="#trace_3_trace_messages">trace messages</seealso>):</p>
<taglist>
<tag><c>all</c></tag>
<item>
- <p>Set all trace flags except <c>{tracer, Tracer}</c> and
- <c>cpu_timestamp</c> that are in their nature different
+ <p>Sets all trace flags except <c>{tracer, Tracer}</c> and
+ <c>cpu_timestamp</c>, which are in their nature different
than the others.</p>
</item>
<tag><c>send</c></tag>
<item>
- <p>Trace sending of messages.</p>
- <p>Message tags: <c>send</c>,
+ <p>Traces sending of messages.</p>
+ <p>Message tags: <c>send</c> and
<c>send_to_non_existing_process</c>.</p>
</item>
<tag><c>'receive'</c></tag>
<item>
- <p>Trace receiving of messages.</p>
+ <p>Traces receiving of messages.</p>
<p>Message tags: <c>'receive'</c>.</p>
</item>
<tag><c>procs</c></tag>
<item>
- <p>Trace process related events.</p>
+ <p>Traces process-related events.</p>
<p>Message tags: <c>spawn</c>, <c>exit</c>,
<c>register</c>, <c>unregister</c>, <c>link</c>,
- <c>unlink</c>, <c>getting_linked</c>,
+ <c>unlink</c>, <c>getting_linked</c>, and
<c>getting_unlinked</c>.</p>
</item>
<tag><c>call</c></tag>
<item>
- <p>Trace certain function calls. Specify which function
+ <p>Traces certain function calls. Specify which function
calls to trace by calling
<seealso marker="#trace_pattern/3">erlang:trace_pattern/3</seealso>.</p>
- <p>Message tags: <c>call</c>, <c>return_from</c>.</p>
+ <p>Message tags: <c>call</c> and <c>return_from</c>.</p>
</item>
<tag><c>silent</c></tag>
<item>
- <p>Used in conjunction with the <c>call</c> trace flag.
- The <c>call</c>, <c>return_from</c> and <c>return_to</c>
- trace messages are inhibited if this flag is set,
- but if there are match specs they are executed as normal.</p>
+ <p>Used with the <c>call</c> trace flag.
+ The <c>call</c>, <c>return_from</c>, and <c>return_to</c>
+ trace messages are inhibited if this flag is set, but they
+ are executed as normal if there are match specifications.</p>
<p>Silent mode is inhibited by executing
<c>erlang:trace(_, false, [silent|_])</c>,
- or by a match spec executing the <c>{silent, false}</c>
- function.</p>
+ or by a match specification executing the function
+ <c>{silent, false}</c>.</p>
<p>The <c>silent</c> trace flag facilitates setting up
a trace on many or even all processes in the system.
- Then the interesting trace can be activated and
- deactivated using the <c>{silent,Bool}</c>
- match spec function, giving a high degree
- of control of which functions with which
- arguments that triggers the trace.</p>
- <p>Message tags: <c>call</c>, <c>return_from</c>,
+ The trace can then be activated and deactivated using the match
+ specification function <c>{silent,Bool}</c>, giving
+ a high degree of control of which functions with which
+ arguments that trigger the trace.</p>
+ <p>Message tags: <c>call</c>, <c>return_from</c>, and
<c>return_to</c>. Or rather, the absence of.</p>
</item>
<tag><c>return_to</c></tag>
<item>
- <p>Used in conjunction with the <c>call</c> trace flag.
- Trace the actual return from a traced function back to
+ <p>Used with the <c>call</c> trace flag.
+ Traces the return from a traced function back to
its caller. Only works for functions traced with
- the <c>local</c> option to
+ option <c>local</c> to
<seealso marker="#trace_pattern/3">erlang:trace_pattern/3</seealso>.</p>
<p>The semantics is that a trace message is sent when a
- call traced function actually returns, that is, when a
- chain of tail recursive calls is ended. There will be
- only one trace message sent per chain of tail recursive
- calls, why the properties of tail recursiveness for
+ call traced function returns, that is, when a
+ chain of tail recursive calls ends. Only one trace
+ message is sent per chain of tail recursive calls,
+ so the properties of tail recursiveness for
function calls are kept while tracing with this flag.
Using <c>call</c> and <c>return_to</c> trace together
makes it possible to know exactly in which function a
process executes at any time.</p>
<p>To get trace messages containing return values from
- functions, use the <c>{return_trace}</c> match_spec
- action instead.</p>
+ functions, use the <c>{return_trace}</c> match
+ specification action instead.</p>
<p>Message tags: <c>return_to</c>.</p>
</item>
<tag><c>running</c></tag>
<item>
- <p>Trace scheduling of processes.</p>
- <p>Message tags: <c>in</c>, and <c>out</c>.</p>
+ <p>Traces scheduling of processes.</p>
+ <p>Message tags: <c>in</c> and <c>out</c>.</p>
</item>
<tag><c>exiting</c></tag>
<item>
- <p>Trace scheduling of an exiting processes.</p>
+ <p>Traces scheduling of exiting processes.</p>
<p>Message tags: <c>in_exiting</c>, <c>out_exiting</c>, and
<c>out_exited</c>.</p>
</item>
<tag><c>garbage_collection</c></tag>
<item>
- <p>Trace garbage collections of processes.</p>
- <p>Message tags: <c>gc_start</c>, <c>gc_end</c>.</p>
+ <p>Traces garbage collections of processes.</p>
+ <p>Message tags: <c>gc_start</c> and <c>gc_end</c>.</p>
</item>
<tag><c>timestamp</c></tag>
<item>
- <p>Include a time stamp in all trace messages. The time
- stamp (Ts) is of the same form as returned by
+ <p>Includes a time-stamp in all trace messages. The
+ time-stamp (Ts) has the same form as returned by
<c>erlang:now()</c>.</p>
</item>
<tag><c>cpu_timestamp</c></tag>
<item>
<p>A global trace flag for the Erlang node that makes all
- trace timestamps be in CPU time, not wallclock. It is
- only allowed with <c>PidSpec==all</c>. If the host
- machine operating system does not support high resolution
+ trace time-stamps to be in CPU time, not wall clock time.
+ Only allowed with <c>PidSpec==all</c>. If the host
+ machine OS does not support high-resolution
CPU time measurements, <c>trace/3</c> exits with
- <c>badarg</c>. Note that most operating systems do
+ <c>badarg</c>. Notice that most OS do
not synchronize this value across cores, so be prepared
that time might seem to go backwards when using this option.</p>
</item>
<tag><c>arity</c></tag>
<item>
- <p>Used in conjunction with the <c>call</c> trace flag.
- <c>{M, F, Arity}</c> will be specified instead of
+ <p>Used with the <c>call</c> trace flag.
+ <c>{M, F, Arity}</c> is specified instead of
<c>{M, F, Args}</c> in call trace messages.</p>
</item>
<tag><c>set_on_spawn</c></tag>
<item>
<p>Makes any process created by a traced process inherit
- its trace flags, including the <c>set_on_spawn</c> flag.</p>
+ its trace flags, including flag <c>set_on_spawn</c>.</p>
</item>
<tag><c>set_on_first_spawn</c></tag>
<item>
<p>Makes the first process created by a traced process
- inherit its trace flags, excluding
- the <c>set_on_first_spawn</c> flag.</p>
+ inherit its trace flags, excluding flag
+ <c>set_on_first_spawn</c>.</p>
</item>
<tag><c>set_on_link</c></tag>
<item>
<p>Makes any process linked by a traced process inherit its
- trace flags, including the <c>set_on_link</c> flag.</p>
+ trace flags, including flag <c>set_on_link</c>.</p>
</item>
<tag><c>set_on_first_link</c></tag>
<item>
<p>Makes the first process linked to by a traced process
- inherit its trace flags, excluding
- the <c>set_on_first_link</c> flag.</p>
+ inherit its trace flags, excluding flag
+ <c>set_on_first_link</c>.</p>
</item>
<tag><c>{tracer, Tracer}</c></tag>
<item>
- <p>Specify where to send the trace messages. <c>Tracer</c>
- must be the pid of a local process or the port identifier
+ <p>Specifies where to send the trace messages. <c>Tracer</c>
+ must be the process identifier of a local process
+ or the port identifier
of a local port. If this flag is not given, trace
- messages will be sent to the process that called
+ messages are sent to the process that called
<c>erlang:trace/3</c>.</p>
</item>
</taglist>
@@ -7620,27 +8081,27 @@ timestamp() ->
<c>set_on_link</c> is the same as having
<c>set_on_first_link</c> alone. Likewise for
<c>set_on_spawn</c> and <c>set_on_first_spawn</c>.</p>
- <p>If the <c>timestamp</c> flag is not given, the tracing
- process will receive the trace messages described below.
- <c>Pid</c> is the pid of the traced process in which
- the traced event has occurred. The third element of the tuple
- is the message tag.</p>
- <p>If the <c>timestamp</c> flag is given, the first element of
- the tuple will be <c>trace_ts</c> instead and the timestamp
- is added last in the tuple.</p>
+ <p>The tracing process receives the <em>trace messages</em> described
+ in the following list. <c>Pid</c> is the process identifier of the
+ traced process in which the traced event has occurred. The
+ third tuple element is the message tag.</p>
+ <p>If flag <c>timestamp</c> is given, the first tuple
+ element is <c>trace_ts</c> instead, and the time-stamp
+ is added last in the message tuple.</p>
+ <marker id="trace_3_trace_messages"></marker>
<taglist>
<tag><c>{trace, Pid, 'receive', Msg}</c></tag>
<item>
- <p>When <c>Pid</c> receives the message <c>Msg</c>.</p>
+ <p>When <c>Pid</c> receives message <c>Msg</c>.</p>
</item>
<tag><c>{trace, Pid, send, Msg, To}</c></tag>
<item>
- <p>When <c>Pid</c> sends the message <c>Msg</c> to
- the process <c>To</c>.</p>
+ <p>When <c>Pid</c> sends message <c>Msg</c> to
+ process <c>To</c>.</p>
</item>
<tag><c>{trace, Pid, send_to_non_existing_process, Msg, To}</c></tag>
<item>
- <p>When <c>Pid</c> sends the message <c>Msg</c> to
+ <p>When <c>Pid</c> sends message <c>Msg</c> to
the non-existing process <c>To</c>.</p>
</item>
<tag><c>{trace, Pid, call, {M, F, Args}}</c></tag>
@@ -7648,7 +8109,7 @@ timestamp() ->
<p>When <c>Pid</c> calls a traced function. The return
values of calls are never supplied, only the call and its
arguments.</p>
- <p>Note that the trace flag <c>arity</c> can be used to
+ <p>Trace flag <c>arity</c> can be used to
change the contents of this message, so that <c>Arity</c>
is specified instead of <c>Args</c>.</p>
</item>
@@ -7656,35 +8117,34 @@ timestamp() ->
<item>
<p>When <c>Pid</c> returns <em>to</em> the specified
function. This trace message is sent if both
- the <c>call</c> and the <c>return_to</c> flags are set,
+ the flags <c>call</c> and <c>return_to</c> are set,
and the function is set to be traced on <em>local</em>
function calls. The message is only sent when returning
- from a chain of tail recursive function calls where at
+ from a chain of tail recursive function calls, where at
least one call generated a <c>call</c> trace message
- (that is, the functions match specification matched and
+ (that is, the functions match specification matched, and
<c>{message, false}</c> was not an action).</p>
</item>
<tag><c>{trace, Pid, return_from, {M, F, Arity}, ReturnValue}</c></tag>
<item>
<p>When <c>Pid</c> returns <em>from</em> the specified
- function. This trace message is sent if the <c>call</c>
- flag is set, and the function has a match specification
+ function. This trace message is sent if flag <c>call</c>
+ is set, and the function has a match specification
with a <c>return_trace</c> or <c>exception_trace</c> action.</p>
</item>
<tag><c>{trace, Pid, exception_from, {M, F, Arity}, {Class, Value}}</c></tag>
<item>
<p>When <c>Pid</c> exits <em>from</em> the specified
- function due to an exception. This trace message is sent
- if the <c>call</c> flag is set, and the function has
+ function because of an exception. This trace message is
+ sent if flag <c>call</c> is set, and the function has
a match specification with an <c>exception_trace</c> action.</p>
</item>
<tag><c>{trace, Pid, spawn, Pid2, {M, F, Args}}</c></tag>
<item>
<p>When <c>Pid</c> spawns a new process <c>Pid2</c> with
the specified function call as entry point.</p>
- <p>Note that <c>Args</c> is supposed to be the argument
- list, but may be any term in the case of an erroneous
- spawn.</p>
+ <p><c>Args</c> is supposed to be the argument list,
+ but can be any term if the spawn is erroneous.</p>
</item>
<tag><c>{trace, Pid, exit, Reason}</c></tag>
<item>
@@ -7714,148 +8174,158 @@ timestamp() ->
<tag><c>{trace, Pid, unregister, RegName}</c></tag>
<item>
<p>When <c>Pid</c> gets the name <c>RegName</c> unregistered.
- Note that this is done automatically when a registered
+ This is done automatically when a registered
process exits.</p>
</item>
<tag><c>{trace, Pid, in, {M, F, Arity} | 0}</c></tag>
<item>
- <p>When <c>Pid</c> is scheduled to run. The process will
- run in function <c>{M, F, Arity}</c>. On some rare
- occasions the current function cannot be determined, then
- the last element <c>Arity</c> is 0.</p>
+ <p>When <c>Pid</c> is scheduled to run. The process
+ runs in function <c>{M, F, Arity}</c>. On some rare
+ occasions, the current function cannot be determined,
+ then the last element <c>Arity</c> is <c>0</c>.</p>
</item>
<tag><c>{trace, Pid, out, {M, F, Arity} | 0}</c></tag>
<item>
<p>When <c>Pid</c> is scheduled out. The process was
- running in function {M, F, Arity}. On some rare occasions
+ running in function {M, F, Arity}. On some rare occasions,
the current function cannot be determined, then the last
- element <c>Arity</c> is 0.</p>
+ element <c>Arity</c> is <c>0</c>.</p>
</item>
- <tag><marker id="gc_start"><c>{trace, Pid, gc_start, Info}</c></marker></tag>
+ <tag><c>{trace, Pid, gc_start, Info}</c></tag>
<item>
+ <marker id="gc_start"></marker>
<p>Sent when garbage collection is about to be started.
<c>Info</c> is a list of two-element tuples, where
the first element is a key, and the second is the value.
- You should not depend on the tuples have any defined
- order. Currently, the following keys are defined:</p>
+ Do not depend on any order of the tuples.
+ The following keys are defined:</p>
<taglist>
<tag><c>heap_size</c></tag>
<item>The size of the used part of the heap.</item>
<tag><c>heap_block_size</c></tag>
<item>The size of the memory block used for storing
- the heap and the stack.</item>
+ the heap and the stack.</item>
<tag><c>old_heap_size</c></tag>
<item>The size of the used part of the old heap.</item>
<tag><c>old_heap_block_size</c></tag>
<item>The size of the memory block used for storing
- the old heap.</item>
+ the old heap.</item>
<tag><c>stack_size</c></tag>
- <item>The actual size of the stack.</item>
+ <item>The size of the stack.</item>
<tag><c>recent_size</c></tag>
<item>The size of the data that survived the previous garbage
- collection.</item>
+ collection.</item>
<tag><c>mbuf_size</c></tag>
<item>The combined size of message buffers associated with
- the process.</item>
-
+ the process.</item>
<tag><c>bin_vheap_size</c></tag>
- <item>The total size of unique off-heap binaries referenced from the process heap.</item>
+ <item>The total size of unique off-heap binaries referenced
+ from the process heap.</item>
<tag><c>bin_vheap_block_size</c></tag>
- <item>The total size of binaries, in words, allowed in the virtual
- heap in the process before doing a garbage collection. </item>
+ <item>The total size of binaries allowed in the virtual
+ heap in the process before doing a garbage collection.</item>
<tag><c>bin_old_vheap_size</c></tag>
- <item>The total size of unique off-heap binaries referenced from the process old heap.</item>
- <tag><c>bin_vheap_block_size</c></tag>
- <item>The total size of binaries, in words, allowed in the virtual
- old heap in the process before doing a garbage collection. </item>
-
-
+ <item>The total size of unique off-heap binaries referenced
+ from the process old heap.</item>
+ <tag><c>bin_old_vheap_block_size</c></tag>
+ <item>The total size of binaries allowed in the virtual
+ old heap in the process before doing a garbage collection.</item>
</taglist>
<p>All sizes are in words.</p>
</item>
<tag><c>{trace, Pid, gc_end, Info}</c></tag>
<item>
<p>Sent when garbage collection is finished. <c>Info</c>
- contains the same kind of list as in the <c>gc_start</c>
- message, but the sizes reflect the new sizes after
+ contains the same kind of list as in message <c>gc_start</c>,
+ but the sizes reflect the new sizes after
garbage collection.</p>
</item>
</taglist>
- <p>If the tracing process dies, the flags will be silently
+ <p>If the tracing process dies, the flags are silently
removed.</p>
- <p>Only one process can trace a particular process. For this
- reason, attempts to trace an already traced process will fail.</p>
+ <p>Only one process can trace a particular process. Therefore,
+ attempts to trace an already traced process fail.</p>
<p>Returns: A number indicating the number of processes that
- matched <c><anno>PidSpec</anno></c>. If <c><anno>PidSpec</anno></c> is a pid,
- the return value will be <c>1</c>. If <c><anno>PidSpec</anno></c> is
- <c>all</c> or <c>existing</c> the return value will be
+ matched <c><anno>PidSpec</anno></c>.
+ If <c><anno>PidSpec</anno></c> is a process
+ identifier, the return value is <c>1</c>.
+ If <c><anno>PidSpec</anno></c>
+ is <c>all</c> or <c>existing</c>, the return value is
the number of processes running, excluding tracer processes.
- If <c><anno>PidSpec</anno></c> is <c>new</c>, the return value will be
+ If <c><anno>PidSpec</anno></c> is <c>new</c>, the return value is
<c>0</c>.</p>
- <p>Failure: If specified arguments are not supported. For
- example <c>cpu_timestamp</c> is not supported on all
- platforms.</p>
+ <p>Failure: <c>badarg</c> if the specified arguments are
+ not supported. For example, <c>cpu_timestamp</c> is not
+ supported on all platforms.</p>
</desc>
</func>
+
<func>
<name name="trace_delivered" arity="1"/>
- <fsummary>Notification when trace has been delivered</fsummary>
+ <fsummary>Notification when trace has been delivered.</fsummary>
<desc>
<p>The delivery of trace messages is dislocated on the time-line
- compared to other events in the system. If you know that the
- <c><anno>Tracee</anno></c> has passed some specific point in its execution,
+ compared to other events in the system. If you know that
+ <c><anno>Tracee</anno></c> has passed some specific point
+ in its execution,
and you want to know when at least all trace messages
- corresponding to events up to this point have reached the tracer
- you can use <c>erlang:trace_delivered(<anno>Tracee</anno>)</c>. A
+ corresponding to events up to this point have reached the
+ tracer, use <c>erlang:trace_delivered(<anno>Tracee</anno>)</c>. A
<c>{trace_delivered, <anno>Tracee</anno>, <anno>Ref</anno>}</c> message is sent to
the caller of <c>erlang:trace_delivered(<anno>Tracee</anno>)</c> when it
- is guaranteed that all trace messages have been delivered to
- the tracer up to the point that the <c><anno>Tracee</anno></c> had reached
+ is guaranteed that all trace messages are delivered to
+ the tracer up to the point that <c><anno>Tracee</anno></c> reached
at the time of the call to
<c>erlang:trace_delivered(<anno>Tracee</anno>)</c>.</p>
- <p>Note that the <c>trace_delivered</c> message does <em>not</em>
- imply that trace messages have been delivered; instead, it implies
- that all trace messages that <em>should</em> be delivered have
- been delivered. It is not an error if <c><anno>Tracee</anno></c> isn't, and
- hasn't been traced by someone, but if this is the case,
- <em>no</em> trace messages will have been delivered when the
+ <p>Notice that message <c>trace_delivered</c> does <em>not</em>
+ imply that trace messages have been delivered.
+ Instead it implies that all trace messages that
+ <em>are to be delivered</em> have been delivered.
+ It is not an error if <c><anno>Tracee</anno></c> is not, and
+ has not been traced by someone, but if this is the case,
+ <em>no</em> trace messages have been delivered when the
<c>trace_delivered</c> message arrives.</p>
- <p>Note that <c><anno>Tracee</anno></c> has to refer to a process currently,
+ <p>Notice that that <c><anno>Tracee</anno></c> must refer
+ to a process currently,
or previously existing on the same node as the caller of
<c>erlang:trace_delivered(<anno>Tracee</anno>)</c> resides on.
- The special <c><anno>Tracee</anno></c> atom <c>all</c> denotes all processes
+ The special <c><anno>Tracee</anno></c> atom <c>all</c>
+ denotes all processes
that currently are traced in the node.</p>
- <p>An example: Process <c>A</c> is <c><anno>Tracee</anno></c>, port <c>B</c> is
- tracer, and process <c>C</c> is the port owner of <c>B</c>.
- <c>C</c> wants to close <c>B</c> when <c>A</c> exits. <c>C</c>
- can ensure that the trace isn't truncated by calling
- <c>erlang:trace_delivered(A)</c> when <c>A</c> exits and wait
- for the <c>{trace_delivered, A, <anno>Ref</anno>}</c> message before closing
- <c>B</c>.</p>
- <p>Failure: <c>badarg</c> if <c><anno>Tracee</anno></c> does not refer to a
+ <p>Example: Process <c>A</c> is <c><anno>Tracee</anno></c>,
+ port <c>B</c> is tracer, and process <c>C</c> is the port
+ owner of <c>B</c>. <c>C</c> wants to close <c>B</c> when
+ <c>A</c> exits. To ensure that the trace is not truncated,
+ <c>C</c> can call <c>erlang:trace_delivered(A)</c>, when
+ <c>A</c> exits, and wait for message <c>{trace_delivered, A,
+ <anno>Ref</anno>}</c> before closing <c>B</c>.</p>
+ <p>Failure: <c>badarg</c> if <c><anno>Tracee</anno></c>
+ does not refer to a
process (dead or alive) on the same node as the caller of
<c>erlang:trace_delivered(<anno>Tracee</anno>)</c> resides on.</p>
</desc>
</func>
+
<func>
<name name="trace_info" arity="2"/>
+ <fsummary>Trace information about a process or function.</fsummary>
<type name="trace_info_return"/>
<type name="trace_info_item_result"/>
<type name="trace_info_flag"/>
<type name="trace_match_spec"/>
- <fsummary>Trace information about a process or function</fsummary>
<desc>
<p>Returns trace information about a process or function.</p>
- <p>To get information about a process, <c><anno>PidOrFunc</anno></c> should
- be a pid or the atom <c>new</c>. The atom <c>new</c> means
- that the default trace state for processes to be created will
- be returned. <c><anno>Item</anno></c> must have one of the following
- values:</p>
+ <p>To get information about a process,
+ <c><anno>PidOrFunc</anno></c> is to
+ be a process identifier (pid) or the atom <c>new</c>.
+ The atom <c>new</c> means that the default trace state for
+ processes to be created is returned.</p>
+ <p>The following <c>Item</c>s are valid:</p>
<taglist>
<tag><c>flags</c></tag>
<item>
- <p>Return a list of atoms indicating what kind of traces is
- enabled for the process. The list will be empty if no
+ <p>Returns a list of atoms indicating what kind of traces is
+ enabled for the process. The list is empty if no
traces are enabled, and one or more of the followings
atoms if traces are enabled: <c>send</c>,
<c>'receive'</c>, <c>set_on_spawn</c>, <c>call</c>,
@@ -7866,337 +8336,354 @@ timestamp() ->
</item>
<tag><c>tracer</c></tag>
<item>
- <p>Return the identifier for process or port tracing this
+ <p>Returns the identifier for process or port tracing this
process. If this process is not being traced, the return
- value will be <c>[]</c>.</p>
+ value is <c>[]</c>.</p>
</item>
</taglist>
- <p>To get information about a function, <c>PidOrFunc</c> should
- be a three-element tuple: <c>{Module, Function, Arity}</c> or
- the atom <c>on_load</c>. No wildcards are allowed. Returns
- <c>undefined</c> if the function does not exist or
- <c>false</c> if the function is not traced at all. <c>Item</c>
- must have one of the following values:</p>
+ <p>To get information about a function, <c>PidOrFunc</c> is to
+ be the three-element tuple <c>{Module, Function, Arity}</c> or
+ the atom <c>on_load</c>. No wild cards are allowed. Returns
+ <c>undefined</c> if the function does not exist, or
+ <c>false</c> if the function is not traced.</p>
+ <p>The following <c>Item</c>s are valid::</p>
<taglist>
<tag><c>traced</c></tag>
<item>
- <p>Return <c>global</c> if this function is traced on
+ <p>Returns <c>global</c> if this function is traced on
global function calls, <c>local</c> if this function is
- traced on local function calls (i.e local and global
- function calls), and <c>false</c> if neither local nor
- global function calls are traced.</p>
+ traced on local function calls (that is, local and global
+ function calls), and <c>false</c> if local or
+ global function calls are not traced.</p>
</item>
<tag><c>match_spec</c></tag>
<item>
- <p>Return the match specification for this function, if it
+ <p>Returns the match specification for this function, if it
has one. If the function is locally or globally traced but
has no match specification defined, the returned value
is <c>[]</c>.</p>
</item>
<tag><c>meta</c></tag>
<item>
- <p>Return the meta trace tracer process or port for this
- function, if it has one. If the function is not meta
- traced the returned value is <c>false</c>, and if
- the function is meta traced but has once detected that
- the tracer proc is invalid, the returned value is [].</p>
+ <p>Returns the meta-trace tracer process or port for this
+ function, if it has one. If the function is not
+ meta-traced, the returned value is <c>false</c>. If
+ the function is meta-traced but has once detected that
+ the tracer process is invalid, the returned value is [].</p>
</item>
<tag><c>meta_match_spec</c></tag>
<item>
- <p>Return the meta trace match specification for this
- function, if it has one. If the function is meta traced
+ <p>Returns the meta-trace match specification for this
+ function, if it has one. If the function is meta-traced
but has no match specification defined, the returned
value is <c>[]</c>.</p>
</item>
<tag><c>call_count</c></tag>
<item>
- <p>Return the call count value for this function or
+ <p>Returns the call count value for this function or
<c>true</c> for the pseudo function <c>on_load</c> if call
- count tracing is active. Return <c>false</c> otherwise.
+ count tracing is active. Otherwise <c>false</c> is returned.
See also
<seealso marker="#trace_pattern/3">erlang:trace_pattern/3</seealso>.</p>
</item>
<tag><c>call_time</c></tag>
<item>
- <p>Return the call time values for this function or
+ <p>Returns the call time values for this function or
<c>true</c> for the pseudo function <c>on_load</c> if call
- time tracing is active. Returns <c>false</c> otherwise.
+ time tracing is active. Otherwise <c>false</c> is returned.
The call time values returned, <c>[{Pid, Count, S, Us}]</c>,
- is a list of each process that has executed the function and its specific counters.
- See also
+ is a list of each process that executed the function
+ and its specific counters. See also
<seealso marker="#trace_pattern/3">erlang:trace_pattern/3</seealso>.</p>
</item>
<tag><c>all</c></tag>
<item>
- <p>Return a list containing the <c>{<anno>Item</anno>, Value}</c> tuples
- for all other items, or return <c>false</c> if no tracing
+ <p>Returns a list containing the
+ <c>{<anno>Item</anno>, Value}</c> tuples
+ for all other items, or returns <c>false</c> if no tracing
is active for this function.</p>
</item>
</taglist>
- <p>The actual return value will be <c>{<anno>Item</anno>, Value}</c>, where
- <c>Value</c> is the requested information as described above.
+ <p>The return value is <c>{<anno>Item</anno>, Value}</c>, where
+ <c>Value</c> is the requested information as described earlier.
If a pid for a dead process was given, or the name of a
- non-existing function, <c>Value</c> will be <c>undefined</c>.</p>
- <p>If <c><anno>PidOrFunc</anno></c> is the <c>on_load</c>, the information
+ non-existing function, <c>Value</c> is <c>undefined</c>.</p>
+ <p>If <c><anno>PidOrFunc</anno></c> is <c>on_load</c>, the information
returned refers to the default value for code that will be
loaded.</p>
</desc>
</func>
+
<func>
<name name="trace_pattern" arity="2" clause_i="1"/>
+ <fsummary>Sets trace patterns for global call tracing.</fsummary>
<type name="trace_pattern_mfa"/>
<type name="trace_match_spec"/>
- <fsummary>Set trace patterns for global call tracing</fsummary>
<desc>
<p>The same as
<seealso marker="#trace_pattern/3">erlang:trace_pattern(MFA, MatchSpec, [])</seealso>,
retained for backward compatibility.</p>
</desc>
</func>
+
<func>
<name name="trace_pattern" arity="3"/>
+ <fsummary>Sets trace patterns for tracing of function calls.</fsummary>
<type name="trace_pattern_mfa"/>
<type name="trace_match_spec"/>
<type name="trace_pattern_flag"/>
- <fsummary>Set trace patterns for tracing of function calls</fsummary>
<desc>
- <p>This BIF is used to enable or disable call tracing for
- exported functions. It must be combined with
+ <p>Enables or disables call tracing for
+ one or more functions. Must be combined with
<seealso marker="#trace/3">erlang:trace/3</seealso>
to set the <c>call</c> trace flag for one or more processes.</p>
- <p>Conceptually, call tracing works like this: Inside
- the Erlang virtual machine there is a set of processes to be
- traced and a set of functions to be traced. Tracing will be
- enabled on the intersection of the set. That is, if a process
- included in the traced process set calls a function included
- in the traced function set, the trace action will be taken.
- Otherwise, nothing will happen.</p>
- <p>Use
- <seealso marker="#trace/3">erlang:trace/3</seealso> to
- add or remove one or more processes to the set of traced
- processes. Use <c>erlang:trace_pattern/2</c> to add or remove
- exported functions to the set of traced functions.</p>
- <p>The <c>erlang:trace_pattern/3</c> BIF can also add match
- specifications to an exported function. A match specification
- comprises a pattern that the arguments to the function must
- match, a guard expression which must evaluate to <c>true</c>
+ <p>Conceptually, call tracing works as follows. Inside
+ the Erlang Virtual Machine, a set of processes and
+ a set of functions are to be traced. If a traced process
+ calls a traced function, the trace action is taken.
+ Otherwise, nothing happens.</p>
+ <p>To add or remove one or more processes to the set of traced
+ processes, use
+ <seealso marker="#trace/3">erlang:trace/3</seealso>.</p>
+ <p>To add or remove functions to the set of traced
+ functions, use <c>erlang:trace_pattern/3</c>.</p>
+ <p>The BIF <c>erlang:trace_pattern/3</c> can also add match
+ specifications to a function. A match specification
+ comprises a pattern that the function arguments must
+ match, a guard expression that must evaluate to <c>true</c>,
and an action to be performed. The default action is to send a
trace message. If the pattern does not match or the guard
- fails, the action will not be executed.</p>
- <p>The <c><anno>MFA</anno></c> argument should be a tuple like
- <c>{Module, Function, Arity}</c> or the atom <c>on_load</c>
- (described below). It can be the module, function, and arity
- for an exported function (or a BIF in any module).
- The <c>'_'</c> atom can be used to mean any of that kind.
- Wildcards can be used in any of the following ways:</p>
+ fails, the action is not executed.</p>
+ <p>Argument <c><anno>MFA</anno></c> is to be a tuple, such as
+ <c>{Module, Function, Arity}</c>, or the atom <c>on_load</c>
+ (described in the following). It can be the module, function,
+ and arity for a function (or a BIF in any module).
+ The atom <c>'_'</c> can be used as a wild card in any of the
+ following ways:</p>
<taglist>
<tag><c>{Module,Function,'_'}</c></tag>
<item>
- <p>All exported functions of any arity named <c>Function</c>
+ <p>All functions of any arity named <c>Function</c>
in module <c>Module</c>.</p>
</item>
<tag><c>{Module,'_','_'}</c></tag>
<item>
- <p>All exported functions in module <c>Module</c>.</p>
+ <p>All functions in module <c>Module</c>.</p>
</item>
<tag><c>{'_','_','_'}</c></tag>
<item>
- <p>All exported functions in all loaded modules.</p>
+ <p>All functions in all loaded modules.</p>
</item>
</taglist>
<p>Other combinations, such as <c>{Module,'_',Arity}</c>, are
- not allowed. Local functions will match wildcards only if
- the <c>local</c> option is in the <c><anno>FlagList</anno></c>.</p>
- <p>If the <c><anno>MFA</anno></c> argument is the atom <c>on_load</c>,
- the match specification and flag list will be used on all
+ not allowed. Local functions match wild cards only if
+ option <c>local</c> is in <c><anno>FlagList</anno></c>.</p>
+ <p>If argument <c><anno>MFA</anno></c> is the atom <c>on_load</c>,
+ the match specification and flag list are used on all
modules that are newly loaded.</p>
- <p>The <c><anno>MatchSpec</anno></c> argument can take any of the following
- forms:</p>
+ <p>Argument <c><anno>MatchSpec</anno></c> can take the
+ following forms:</p>
<taglist>
<tag><c>false</c></tag>
<item>
- <p>Disable tracing for the matching function(s). Any match
- specification will be removed.</p>
+ <p>Disables tracing for the matching functions.
+ Any match specification is removed.</p>
</item>
<tag><c>true</c></tag>
<item>
- <p>Enable tracing for the matching function(s).</p>
+ <p>Enables tracing for the matching functions.</p>
</item>
<tag><c><anno>MatchSpecList</anno></c></tag>
<item>
<p>A list of match specifications. An empty list is
- equivalent to <c>true</c>. See the ERTS User's Guide
- for a description of match specifications.</p>
+ equivalent to <c>true</c>. For a description of match
+ specifications, see the User's Guide.</p>
</item>
<tag><c>restart</c></tag>
<item>
- <p>For the <c><anno>FlagList</anno></c> option <c>call_count</c> and <c>call_time</c>:
- restart the existing counters. The behaviour is undefined
+ <p>For the <c><anno>FlagList</anno></c> options <c>call_count</c>
+ and <c>call_time</c>: restarts
+ the existing counters. The behavior is undefined
for other <c><anno>FlagList</anno></c> options.</p>
</item>
<tag><c>pause</c></tag>
<item>
- <p>For the <c><anno>FlagList</anno></c> option <c>call_count</c> and <c>call_time</c>: pause
- the existing counters. The behaviour is undefined for
- other <c>FlagList</c> options.</p>
+ <p>For the <c><anno>FlagList</anno></c> options
+ <c>call_count</c> and <c>call_time</c>: pauses
+ the existing counters. The behavior is undefined for
+ other <c><anno>FlagList</anno></c> options.</p>
</item>
</taglist>
- <p>The <c><anno>FlagList</anno></c> parameter is a list of options.
- The following options are allowed:</p>
+ <p>Parameter <c><anno>FlagList</anno></c> is a list of options.
+ The following are the valid options:</p>
<taglist>
<tag><c>global</c></tag>
<item>
- <p>Turn on or off call tracing for global function calls
+ <p>Turns on or off call tracing for global function calls
(that is, calls specifying the module explicitly). Only
- exported functions will match and only global calls will
- generate trace messages. This is the default.</p>
+ exported functions match and only global calls
+ generate trace messages. <em>This is the default</em>.</p>
</item>
<tag><c>local</c></tag>
<item>
- <p>Turn on or off call tracing for all types of function
- calls. Trace messages will be sent whenever any of
+ <p>Turns on or off call tracing for all types of function
+ calls. Trace messages are sent whenever any of
the specified functions are called, regardless of how they
- are called. If the <c>return_to</c> flag is set for
- the process, a <c>return_to</c> message will also be sent
+ are called. If flag <c>return_to</c> is set for
+ the process, a <c>return_to</c> message is also sent
when this function returns to its caller.</p>
</item>
<tag><c>meta | {meta, <anno>Pid</anno>}</c></tag>
<item>
- <p>Turn on or off meta tracing for all types of function
- calls. Trace messages will be sent to the tracer process
+ <p>Turns on or off meta-tracing for all types of function
+ calls. Trace messages are sent to the tracer process
or port <c><anno>Pid</anno></c> whenever any of the specified
functions are called, regardless of how they are called.
- If no <c><anno>Pid</anno></c> is specified, <c>self()</c> is used as a
- default tracer process.</p>
- <p>Meta tracing traces all processes and does not care
+ If no <c><anno>Pid</anno></c> is specified,
+ <c>self()</c> is used as a default tracer process.</p>
+ <p>Meta-tracing traces all processes and does not care
about the process trace flags set by <c>trace/3</c>,
the trace flags are instead fixed to
<c>[call, timestamp]</c>.</p>
- <p>The match spec function <c>{return_trace}</c> works with
- meta trace and send its trace message to the same tracer
- process.</p>
+ <p>The match specification function <c>{return_trace}</c>
+ works with meta-trace and sends its trace message to the
+ same tracer process.</p>
</item>
<tag><c>call_count</c></tag>
<item>
<p>Starts (<c><anno>MatchSpec</anno> == true</c>) or stops
- (<c><anno>MatchSpec</anno> == false</c>) call count tracing for all
- types of function calls. For every function a counter is
+ (<c><anno>MatchSpec</anno> == false</c>)
+ call count tracing for all
+ types of function calls. For every function, a counter is
incremented when the function is called, in any process.
No process trace flags need to be activated.</p>
<p>If call count tracing is started while already running,
- the count is restarted from zero. Running counters can be
- paused with <c><anno>MatchSpec</anno> == pause</c>. Paused and running
- counters can be restarted from zero with
+ the count is restarted from zero. To pause running
+ counters, use <c><anno>MatchSpec</anno> == pause</c>.
+ Paused and running counters can be restarted from zero with
<c><anno>MatchSpec</anno> == restart</c>.</p>
- <p>The counter value can be read with
+ <p>To read the counter value, use
<seealso marker="#trace_info/2">erlang:trace_info/2</seealso>.</p>
</item>
<tag><c>call_time</c></tag>
<item>
<p>Starts (<c><anno>MatchSpec</anno> == true</c>) or stops
- (<c><anno>MatchSpec</anno> == false</c>) call time tracing for all
- types of function calls. For every function a counter is
- incremented when the function is called. Time spent in the function
- is accumulated in two other counters, seconds and micro-seconds.
+ (<c><anno>MatchSpec</anno> == false</c>) call time
+ tracing for all
+ types of function calls. For every function, a counter is
+ incremented when the function is called.
+ Time spent in the function is accumulated in
+ two other counters, seconds and microseconds.
The counters are stored for each call traced process.</p>
<p>If call time tracing is started while already running,
- the count and time is restarted from zero. Running counters can be
- paused with <c><anno>MatchSpec</anno> == pause</c>. Paused and running
- counters can be restarted from zero with
+ the count and time is restarted from zero. To pause
+ running counters, use <c><anno>MatchSpec</anno> == pause</c>.
+ Paused and running counters can be restarted from zero with
<c><anno>MatchSpec</anno> == restart</c>.</p>
- <p>The counter value can be read with
+ <p>To read the counter value, use
<seealso marker="#trace_info/2">erlang:trace_info/2</seealso>.</p>
</item>
-
</taglist>
- <p>The <c>global</c> and <c>local</c> options are mutually
- exclusive and <c>global</c> is the default (if no options are
- specified). The <c>call_count</c> and <c>meta</c> options
- perform a kind of local tracing, and can also not be combined
- with <c>global</c>. A function can be either globally or
+ <p>The options <c>global</c> and <c>local</c> are mutually
+ exclusive, and <c>global</c> is the default (if no options are
+ specified). The options <c>call_count</c> and <c>meta</c>
+ perform a kind of local tracing, and cannot be combined
+ with <c>global</c>. A function can be globally or
locally traced. If global tracing is specified for a
- specified set of functions; local, meta, call time and call count
- tracing for the matching set of local functions will be
- disabled, and vice versa.</p>
+ set of functions, then local, meta, call time, and call count
+ tracing for the matching set of local functions is
+ disabled, and conversely.</p>
<p>When disabling trace, the option must match the type of trace
- that is set on the function, so that local tracing must be
- disabled with the <c>local</c> option and global tracing with
- the <c>global</c> option (or no option at all), and so forth.</p>
- <p>There is no way to directly change part of a match
- specification list. If a function has a match specification,
- you can replace it with a completely new one. If you need to
- change an existing match specification, use the
+ set on the function. That is, local tracing must be
+ disabled with option <c>local</c> and global tracing with
+ option <c>global</c> (or no option), and so forth.</p>
+ <p>Part of a match specification list cannot be changed directly.
+ If a function has a match specification, it can be replaced
+ with a new one. To change an existing match specification,
+ use the BIF
<seealso marker="#trace_info/2">erlang:trace_info/2</seealso>
- BIF to retrieve the existing match specification.</p>
- <p>Returns the number of exported functions that matched
- the <c><anno>MFA</anno></c> argument. This will be zero if none matched at
- all.</p>
+ to retrieve the existing match specification.</p>
+ <p>Returns the number of functions matching
+ argument <c><anno>MFA</anno></c>. This is zero if none matched.</p>
</desc>
</func>
+
<func>
<name name="trunc" arity="1"/>
- <fsummary>Return an integer by the truncating a number</fsummary>
+ <fsummary>Returns an integer by truncating a number</fsummary>
<desc>
- <p>Returns an integer by the truncating <c><anno>Number</anno></c>.</p>
+ <p>Returns an integer by truncating <c><anno>Number</anno></c>,
+ for example:</p>
<pre>
> <input>trunc(5.5).</input>
5</pre>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="tuple_size" arity="1"/>
- <fsummary>Return the size of a tuple</fsummary>
+ <fsummary>Returns the size of a tuple.</fsummary>
<desc>
- <p>Returns an integer which is the number of elements in <c><anno>Tuple</anno></c>.</p>
+ <p>Returns an integer that is the number of elements in
+ <c><anno>Tuple</anno></c>, for example:</p>
<pre>
> <input>tuple_size({morni, mulle, bwange}).</input>
3</pre>
<p>Allowed in guard tests.</p>
</desc>
</func>
+
<func>
<name name="tuple_to_list" arity="1"/>
- <fsummary>Convert a tuple to a list</fsummary>
+ <fsummary>Converts a tuple to a list.</fsummary>
<desc>
- <p>Returns a list which corresponds to <c><anno>Tuple</anno></c>.
- <c><anno>Tuple</anno></c> may contain any Erlang terms.</p>
+ <p>Returns a list corresponding to <c><anno>Tuple</anno></c>.
+ <c><anno>Tuple</anno></c> can contain any Erlang terms.</p>
+ <p>Example:</p>
<pre>
> <input>tuple_to_list({share, {'Ericsson_B', 163}}).</input>
[share,{'Ericsson_B',163}]</pre>
</desc>
</func>
+
<func>
<name name="universaltime" arity="0"/>
- <fsummary>Current date and time according to Universal Time Coordinated (UTC)</fsummary>
+ <fsummary>Current date and time according to Universal Time Coordinated (UTC).</fsummary>
<desc>
<p>Returns the current date and time according to Universal
- Time Coordinated (UTC), also called GMT, in the form
+ Time Coordinated (UTC) in the form
<c>{{Year, Month, Day}, {Hour, Minute, Second}}</c> if
- supported by the underlying operating system. If not,
- <c>erlang:universaltime()</c> is equivalent to
+ supported by the underlying OS.
+ Otherwise <c>erlang:universaltime()</c> is equivalent to
<c>erlang:localtime()</c>.</p>
+ <p>Example:</p>
<pre>
> <input>erlang:universaltime().</input>
{{1996,11,6},{14,18,43}}</pre>
</desc>
</func>
+
<func>
<name name="universaltime_to_localtime" arity="1"/>
- <fsummary>Convert from Universal Time Coordinated (UTC) to local date and time</fsummary>
+ <fsummary>Converts from Universal Time Coordinated (UTC) to local date and time.</fsummary>
<desc>
<p>Converts Universal Time Coordinated (UTC) date and time to
- local date and time, if this is supported by the underlying
- OS. Otherwise, no conversion is done, and
+ local date and time in the form
+ <c>{{Year, Month, Day}, {Hour, Minute, Second}}</c> if
+ supported by the underlying OS.
+ Otherwise no conversion is done, and
<c><anno>Universaltime</anno></c> is returned.</p>
+ <p>Example:</p>
<pre>
> <input>erlang:universaltime_to_localtime({{1996,11,6},{14,18,43}}).</input>
{{1996,11,7},{15,18,43}}</pre>
- <p>Failure: <c>badarg</c> if <c>Universaltime</c> does not denote
- a valid date and time.</p>
+ <p>Failure: <c>badarg</c> if <c>Universaltime</c> denotes
+ an invalid date and time.</p>
</desc>
</func>
+
<func>
<name name="unique_integer" arity="0"/>
<fsummary>Get a unique integer value</fsummary>
@@ -8221,23 +8708,23 @@ timestamp() ->
Each integer value can of course be constructed
by other means.</p>
- <p>By default, i.e. when <c>[]</c> is passed as
+ <p>By default, when <c>[]</c> is passed as
<c><anno>ModifierList</anno></c>, both negative and
- positive integers will be returned. This is order
- to be able to utilize the range of integers that do
- not need to be heap allocated as much as possible.
+ positive integers can be returned. This in order
+ to utilize the range of integers that do
+ not need heap memory allocation as much as possible.
By default the returned integers are also only
- guaranteed to be unique, i.e., any integer returned
- may be either smaller, or larger than previously
+ guaranteed to be unique, that is, any returned integer
+ can be smaller or larger than previously
returned integers.</p>
- <p>Currently valid <c><anno>Modifier</anno></c>s:</p>
+ <p>Valid <c><anno>Modifier</anno></c>s:</p>
<taglist>
<tag>positive</tag>
<item><p>Return only positive integers.</p>
<p>Note that by passing the <c>positive</c> modifier
- you will get heap allocated integers (big-nums)
+ you will get heap allocated integers (bignums)
quicker.</p>
</item>
@@ -8249,7 +8736,7 @@ timestamp() ->
returned will always be larger than previously
returned integers on the current runtime system
instance.</p>
- <p>These values can be used when ordering events
+ <p>These values can be used to determine order between events
on the runtime system instance. That is, if both
<c>X = erlang:unique_integer([monotonic])</c> and
<c>Y = erlang:unique_integer([monotonic])</c> are
@@ -8259,21 +8746,21 @@ timestamp() ->
before <c>Y</c>.</p>
<warning><p>Strictly monotonically increasing values
are inherently quite expensive to generate and scales
- poorly. This since the values needs to be
- synchronized. That is, do not pass the <c>monotonic</c>
+ poorly. This is because the values need to be
+ synchronized between cpu cores. That is, do not pass the <c>monotonic</c>
modifier unless you really need strictly monotonically
increasing values.</p></warning>
</item>
</taglist>
- <p>All currently valid <c><anno>Modifier</anno></c>s
+ <p>All valid <c><anno>Modifier</anno></c>s
can be combined. Repeated (valid)
<c><anno>Modifier</anno></c>s in the <c>ModifierList</c>
are ignored.</p>
<note><p>Note that the set of integers returned by
- <c>unique_integer/1</c> using diffrent sets of
+ <c>unique_integer/1</c> using different sets of
<c><anno>Modifier</anno></c>s <em>will overlap</em>.
For example, by calling <c>unique_integer([monotonic])</c>,
and <c>unique_integer([positive, monotonic])</c>
@@ -8293,25 +8780,30 @@ timestamp() ->
</func>
<func>
<name name="unlink" arity="1"/>
- <fsummary>Remove a link, if there is one, to another process or port</fsummary>
+ <fsummary>Removes a link to another process or port.</fsummary>
<desc>
<p>Removes the link, if there is one, between the calling
- process and the process or port referred to by <c><anno>Id</anno></c>.</p>
+ process and the process or port referred to by
+ <c><anno>Id</anno></c>.</p>
<p>Returns <c>true</c> and does not fail, even if there is no
- link to <c><anno>Id</anno></c>, or if <c><anno>Id</anno></c> does not exist.</p>
- <p>Once <c>unlink(<anno>Id</anno>)</c> has returned it is guaranteed that
+ link to <c><anno>Id</anno></c>, or if <c><anno>Id</anno></c>
+ does not exist.</p>
+ <p>Once <c>unlink(<anno>Id</anno>)</c> has returned,
+ it is guaranteed that
the link between the caller and the entity referred to by
- <c><anno>Id</anno></c> has no effect on the caller in the future (unless
- the link is setup again). If caller is trapping exits, an
- <c>{'EXIT', <anno>Id</anno>, _}</c> message due to the link might have
- been placed in the caller's message queue prior to the call,
- though. Note, the <c>{'EXIT', <anno>Id</anno>, _}</c> message can be the
- result of the link, but can also be the result of <c><anno>Id</anno></c>
- calling <c>exit/2</c>. Therefore, it <em>may</em> be
- appropriate to cleanup the message queue when trapping exits
- after the call to <c>unlink(<anno>Id</anno>)</c>, as follow:</p>
+ <c><anno>Id</anno></c> has no effect on the caller
+ in the future (unless
+ the link is setup again). If the caller is trapping exits, an
+ <c>{'EXIT', <anno>Id</anno>, _}</c> message from the link
+ can have been placed in the caller's message queue before
+ the call.</p>
+ <p>Notice that the <c>{'EXIT', <anno>Id</anno>, _}</c>
+ message can be the
+ result of the link, but can also be the result of <c>Id</c>
+ calling <c>exit/2</c>. Therefore, it <em>can</em> be
+ appropriate to clean up the message queue when trapping exits
+ after the call to <c>unlink(<anno>Id</anno>)</c>, as follows:</p>
<code type="none">
-
unlink(Id),
receive
{'EXIT', Id, _} ->
@@ -8320,23 +8812,25 @@ timestamp() ->
true
end</code>
<note>
- <p>Prior to OTP release R11B (erts version 5.5) <c>unlink/1</c>
- behaved completely asynchronous, i.e., the link was active
+ <p>Prior to OTP release R11B (ERTS version 5.5) <c>unlink/1</c>
+ behaved completely asynchronously, i.e., the link was active
until the "unlink signal" reached the linked entity. This
- had one undesirable effect, though. You could never know when
+ had an undesirable effect, as you could never know when
you were guaranteed <em>not</em> to be effected by the link.</p>
- <p>Current behavior can be viewed as two combined operations:
+ <p>The current behavior can be viewed as two combined operations:
asynchronously send an "unlink signal" to the linked entity
and ignore any future results of the link.</p>
</note>
</desc>
</func>
+
<func>
<name name="unregister" arity="1"/>
- <fsummary>Remove the registered name for a process (or port)</fsummary>
+ <fsummary>Removes the registered name for a process (or port).</fsummary>
<desc>
- <p>Removes the registered name <c><anno>RegName</anno></c>, associated with a
- pid or a port identifier.</p>
+ <p>Removes the registered name <c><anno>RegName</anno></c>
+ associated with a
+ process identifier or a port identifier, for example:</p>
<pre>
> <input>unregister(db).</input>
true</pre>
@@ -8345,31 +8839,34 @@ true</pre>
name.</p>
</desc>
</func>
+
<func>
<name name="whereis" arity="1"/>
- <fsummary>Get the pid (or port) with a given registered name</fsummary>
+ <fsummary>Gets the pid (or port) with a given registered name.</fsummary>
<desc>
- <p>Returns the pid or port identifier with the registered name
- <c>RegName</c>. Returns <c>undefined</c> if the name is not
- registered.</p>
+ <p>Returns the process identifier or port identifier with
+ the registered name <c>RegName</c>. Returns <c>undefined</c>
+ if the name is not registered.</p>
+ <p>Example:</p>
<pre>
> <input>whereis(db).</input>
&lt;0.43.0></pre>
</desc>
</func>
+
<func>
<name name="yield" arity="0"/>
- <fsummary>Let other processes get a chance to execute</fsummary>
+ <fsummary>Lets other processes get a chance to execute.</fsummary>
<desc>
- <p>Voluntarily let other processes (if any) get a chance to
+ <p>Voluntarily lets other processes (if any) get a chance to
execute. Using <c>erlang:yield()</c> is similar to
<c>receive after 1 -> ok end</c>, except that <c>yield()</c>
is faster.</p>
<warning><p>There is seldom or never any need to use this BIF,
- especially in the SMP-emulator as other processes will have a
- chance to run in another scheduler thread anyway.
- Using this BIF without a thorough grasp of how the scheduler
- works may cause performance degradation.</p></warning>
+ especially in the SMP emulator, as other processes have a
+ chance to run in another scheduler thread anyway.
+ Using this BIF without a thorough grasp of how the scheduler
+ works can cause performance degradation.</p></warning>
</desc>
</func>
</funcs>
diff --git a/erts/doc/src/erts_alloc.xml b/erts/doc/src/erts_alloc.xml
index 376cae4a95..15b78ffa10 100644
--- a/erts/doc/src/erts_alloc.xml
+++ b/erts/doc/src/erts_alloc.xml
@@ -4,7 +4,7 @@
<cref>
<header>
<copyright>
- <year>2002</year><year>2014</year>
+ <year>2002</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -260,19 +260,19 @@
<p>The following flags are available for configuration of
<c>mseg_alloc</c>:</p>
<taglist>
- <tag><marker id="MMamcbf"><c><![CDATA[+MMamcbf <size>]]></c></marker></tag>
+ <tag><marker id="MMamcbf"/><c><![CDATA[+MMamcbf <size>]]></c></tag>
<item>
Absolute max cache bad fit (in kilobytes). A segment in the
memory segment cache is not reused if its size exceeds the
requested size with more than the value of this
parameter. Default value is 4096. </item>
- <tag><marker id="MMrmcbf"><c><![CDATA[+MMrmcbf <ratio>]]></c></marker></tag>
+ <tag><marker id="MMrmcbf"/><c><![CDATA[+MMrmcbf <ratio>]]></c></tag>
<item>
Relative max cache bad fit (in percent). A segment in the
memory segment cache is not reused if its size exceeds the
requested size with more than relative max cache bad fit
percent of the requested size. Default value is 20.</item>
- <tag><marker id="MMsco"><c><![CDATA[+MMsco true|false]]></c></marker></tag>
+ <tag><marker id="MMsco"/><c><![CDATA[+MMsco true|false]]></c></tag>
<item>
Set <seealso marker="#MMscs">super carrier</seealso> only flag. This
flag defaults to <c>true</c>. When a super carrier is used and this
@@ -292,7 +292,7 @@
disabled on halfword heap systems. This flag will be
ignored on halfword heap systems.
</item>
- <tag><marker id="MMscrfsd"><c><![CDATA[+MMscrfsd <amount>]]></c></marker></tag>
+ <tag><marker id="MMscrfsd"/><c><![CDATA[+MMscrfsd <amount>]]></c></tag>
<item>
Set <seealso marker="#MMscs">super carrier</seealso> reserved
free segment descriptors. This parameter defaults to <c>65536</c>.
@@ -305,7 +305,7 @@
<c>erts_mmap</c> tuple part of the result from calling
<seealso marker="erts:erlang#system_info_allocator_tuple">erlang:system_info({allocator, mseg_alloc})</seealso>.
</item>
- <tag><marker id="MMscrpm"><c><![CDATA[+MMscrpm true|false]]></c></marker></tag>
+ <tag><marker id="MMscrpm"/><c><![CDATA[+MMscrpm true|false]]></c></tag>
<item>
Set <seealso marker="#MMscs">super carrier</seealso> reserve physical
memory flag. This flag defaults to <c>true</c>. When this flag is
@@ -328,7 +328,7 @@
disabled on halfword heap systems. This flag will be
ignored on halfword heap systems.
</item>
- <tag><marker id="MMscs"><c><![CDATA[+MMscs <size in MB>]]></c></marker></tag>
+ <tag><marker id="MMscs"/><c><![CDATA[+MMscs <size in MB>]]></c></tag>
<item>
Set super carrier size (in MB). The super carrier size defaults to
zero; i.e, the super carrier is by default disabled. The super
@@ -343,7 +343,7 @@
disabled on halfword heap systems. This flag will be
ignored on halfword heap systems.
</item>
- <tag><marker id="MMmcs"><c><![CDATA[+MMmcs <amount>]]></c></marker></tag>
+ <tag><marker id="MMmcs"/><c><![CDATA[+MMmcs <amount>]]></c></tag>
<item>
Max cached segments. The maximum number of memory segments
stored in the memory segment cache. Valid range is
@@ -352,15 +352,15 @@
<p>The following flags are available for configuration of
<c>sys_alloc</c>:</p>
<taglist>
- <tag><marker id="MYe"><c>+MYe true</c></marker></tag>
+ <tag><marker id="MYe"/><c>+MYe true</c></tag>
<item>
Enable <c>sys_alloc</c>. Note: <c>sys_alloc</c> cannot be disabled.</item>
- <tag><marker id="MYm"><c>+MYm libc</c></marker></tag>
+ <tag><marker id="MYm"/><c>+MYm libc</c></tag>
<item>
<c>malloc</c> library to use. Currently only
<c>libc</c> is available. <c>libc</c> enables the standard
<c>libc</c> malloc implementation. By default <c>libc</c> is used.</item>
- <tag><marker id="MYtt"><c><![CDATA[+MYtt <size>]]></c></marker></tag>
+ <tag><marker id="MYtt"/><c><![CDATA[+MYtt <size>]]></c></tag>
<item>
Trim threshold size (in kilobytes). This is the maximum amount
of free memory at the top of the heap (allocated by
@@ -372,7 +372,7 @@
trim threshold is 128. <em>Note:</em> This flag will
only have any effect when the emulator has been linked with
the GNU C library, and uses its <c>malloc</c> implementation.</item>
- <tag><marker id="MYtp"><c><![CDATA[+MYtp <size>]]></c></marker></tag>
+ <tag><marker id="MYtp"/><c><![CDATA[+MYtp <size>]]></c></tag>
<item>
Top pad size (in kilobytes). This is the amount of extra
memory that will be allocated by <c>malloc</c> when
@@ -390,7 +390,7 @@
subsystem identifier, only the specific allocator identified will be
effected:</p>
<taglist>
- <tag><marker id="M_acul"><c><![CDATA[+M<S>acul <utilization>|de]]></c></marker></tag>
+ <tag><marker id="M_acul"/><c><![CDATA[+M<S>acul <utilization>|de]]></c></tag>
<item>
Abandon carrier utilization limit. A valid
<c><![CDATA[<utilization>]]></c> is an integer in the range
@@ -422,7 +422,7 @@
allocators based on the <c>alloc_util</c> framework with the
exception of <c>temp_alloc</c> (which would be pointless).
</item>
- <tag><marker id="M_as"><c><![CDATA[+M<S>as bf|aobf|aoff|aoffcbf|aoffcaobf|gf|af]]></c></marker></tag>
+ <tag><marker id="M_as"/><c><![CDATA[+M<S>as bf|aobf|aoff|aoffcbf|aoffcaobf|gf|af]]></c></tag>
<item>
Allocation strategy. Valid strategies are <c>bf</c> (best fit),
<c>aobf</c> (address order best fit), <c>aoff</c> (address order first fit),
@@ -430,7 +430,7 @@
<c>aoffcaobf</c> (address order first fit carrier address order best fit),
<c>gf</c> (good fit), and <c>af</c> (a fit). See
<seealso marker="#strategy">the description of allocation strategies</seealso> in "the <c>alloc_util</c> framework" section.</item>
- <tag><marker id="M_asbcst"><c><![CDATA[+M<S>asbcst <size>]]></c></marker></tag>
+ <tag><marker id="M_asbcst"/><c><![CDATA[+M<S>asbcst <size>]]></c></tag>
<item>
Absolute singleblock carrier shrink threshold (in
kilobytes). When a block located in an
@@ -438,23 +438,23 @@
will be left unchanged if the amount of unused memory is less
than this threshold; otherwise, the carrier will be shrunk.
See also <seealso marker="#M_rsbcst">rsbcst</seealso>.</item>
- <tag><marker id="M_e"><c><![CDATA[+M<S>e true|false]]></c></marker></tag>
+ <tag><marker id="M_e"/><c><![CDATA[+M<S>e true|false]]></c></tag>
<item>
Enable allocator <c><![CDATA[<S>]]></c>.</item>
- <tag><marker id="M_lmbcs"><c><![CDATA[+M<S>lmbcs <size>]]></c></marker></tag>
+ <tag><marker id="M_lmbcs"/><c><![CDATA[+M<S>lmbcs <size>]]></c></tag>
<item>
Largest (<c>mseg_alloc</c>) multiblock carrier size (in
kilobytes). See <seealso marker="#mseg_mbc_sizes">the description
on how sizes for mseg_alloc multiblock carriers are decided</seealso>
in "the <c>alloc_util</c> framework" section. On 32-bit Unix style OS
this limit can not be set higher than 128 megabyte.</item>
- <tag><marker id="M_mbcgs"><c><![CDATA[+M<S>mbcgs <ratio>]]></c></marker></tag>
+ <tag><marker id="M_mbcgs"/><c><![CDATA[+M<S>mbcgs <ratio>]]></c></tag>
<item>
(<c>mseg_alloc</c>) multiblock carrier growth stages. See
<seealso marker="#mseg_mbc_sizes">the description on how sizes for
mseg_alloc multiblock carriers are decided</seealso>
in "the <c>alloc_util</c> framework" section.</item>
- <tag><marker id="M_mbsd"><c><![CDATA[+M<S>mbsd <depth>]]></c></marker></tag>
+ <tag><marker id="M_mbsd"/><c><![CDATA[+M<S>mbsd <depth>]]></c></tag>
<item>
Max block search depth. This flag has effect only if the
good fit strategy has been selected for allocator
@@ -464,40 +464,40 @@
search depth sets a limit on the maximum number of blocks to
inspect in a free list during a search for suitable block
satisfying the request.</item>
- <tag><marker id="M_mmbcs"><c><![CDATA[+M<S>mmbcs <size>]]></c></marker></tag>
+ <tag><marker id="M_mmbcs"/><c><![CDATA[+M<S>mmbcs <size>]]></c></tag>
<item>
Main multiblock carrier size. Sets the size of the main
multiblock carrier for allocator <c><![CDATA[<S>]]></c>. The main
multiblock carrier is allocated via <c><![CDATA[sys_alloc]]></c> and is
never deallocated.</item>
- <tag><marker id="M_mmmbc"><c><![CDATA[+M<S>mmmbc <amount>]]></c></marker></tag>
+ <tag><marker id="M_mmmbc"/><c><![CDATA[+M<S>mmmbc <amount>]]></c></tag>
<item>
Max <c>mseg_alloc</c> multiblock carriers. Maximum number of
multiblock carriers allocated via <c>mseg_alloc</c> by
allocator <c><![CDATA[<S>]]></c>. When this limit has been reached,
new multiblock carriers will be allocated via
<c>sys_alloc</c>.</item>
- <tag><marker id="M_mmsbc"><c><![CDATA[+M<S>mmsbc <amount>]]></c></marker></tag>
+ <tag><marker id="M_mmsbc"/><c><![CDATA[+M<S>mmsbc <amount>]]></c></tag>
<item>
Max <c>mseg_alloc</c> singleblock carriers. Maximum number of
singleblock carriers allocated via <c>mseg_alloc</c> by
allocator <c><![CDATA[<S>]]></c>. When this limit has been reached,
new singleblock carriers will be allocated via
<c>sys_alloc</c>.</item>
- <tag><marker id="M_ramv"><c><![CDATA[+M<S>ramv <bool>]]></c></marker></tag>
+ <tag><marker id="M_ramv"/><c><![CDATA[+M<S>ramv <bool>]]></c></tag>
<item>
Realloc always moves. When enabled, reallocate operations will
more or less be translated into an allocate, copy, free sequence.
This often reduce memory fragmentation, but costs performance.
</item>
- <tag><marker id="M_rmbcmt"><c><![CDATA[+M<S>rmbcmt <ratio>]]></c></marker></tag>
+ <tag><marker id="M_rmbcmt"/><c><![CDATA[+M<S>rmbcmt <ratio>]]></c></tag>
<item>
Relative multiblock carrier move threshold (in percent). When
a block located in a multiblock carrier is shrunk,
the block will be moved if the ratio of the size of the returned
memory compared to the previous size is more than this threshold;
otherwise, the block will be shrunk at current location.</item>
- <tag><marker id="M_rsbcmt"><c><![CDATA[+M<S>rsbcmt <ratio>]]></c></marker></tag>
+ <tag><marker id="M_rsbcmt"/><c><![CDATA[+M<S>rsbcmt <ratio>]]></c></tag>
<item>
Relative singleblock carrier move threshold (in percent). When
a block located in a singleblock carrier is shrunk to
@@ -506,7 +506,7 @@
the block will be left unchanged in the singleblock carrier if
the ratio of unused memory is less than this threshold;
otherwise, it will be moved into a multiblock carrier. </item>
- <tag><marker id="M_rsbcst"><c><![CDATA[+M<S>rsbcst <ratio>]]></c></marker></tag>
+ <tag><marker id="M_rsbcst"/><c><![CDATA[+M<S>rsbcst <ratio>]]></c></tag>
<item>
Relative singleblock carrier shrink threshold (in
percent). When a block located in an <c>mseg_alloc</c>
@@ -514,20 +514,20 @@
unchanged if the ratio of unused memory is less than this
threshold; otherwise, the carrier will be shrunk.
See also <seealso marker="#M_asbcst">asbcst</seealso>.</item>
- <tag><marker id="M_sbct"><c><![CDATA[+M<S>sbct <size>]]></c></marker></tag>
+ <tag><marker id="M_sbct"/><c><![CDATA[+M<S>sbct <size>]]></c></tag>
<item>
Singleblock carrier threshold. Blocks larger than this
threshold will be placed in singleblock carriers. Blocks
smaller than this threshold will be placed in multiblock
carriers. On 32-bit Unix style OS this threshold can not be set higher
than 8 megabytes.</item>
- <tag><marker id="M_smbcs"><c><![CDATA[+M<S>smbcs <size>]]></c></marker></tag>
+ <tag><marker id="M_smbcs"/><c><![CDATA[+M<S>smbcs <size>]]></c></tag>
<item>
Smallest (<c>mseg_alloc</c>) multiblock carrier size (in
kilobytes). See <seealso marker="#mseg_mbc_sizes">the description
on how sizes for mseg_alloc multiblock carriers are decided</seealso>
in "the <c>alloc_util</c> framework" section.</item>
- <tag><marker id="M_t"><c><![CDATA[+M<S>t true|false]]></c></marker></tag>
+ <tag><marker id="M_t"/><c><![CDATA[+M<S>t true|false]]></c></tag>
<item>
<p>Multiple, thread specific instances of the allocator.
This option will only have any effect on the runtime system
@@ -544,20 +544,20 @@
<c>alloc_util</c>, i.e. all allocators based on <c>alloc_util</c>
will be effected:</p>
<taglist>
- <tag><marker id="Muycs"><c><![CDATA[+Muycs <size>]]></c></marker></tag>
+ <tag><marker id="Muycs"/><c><![CDATA[+Muycs <size>]]></c></tag>
<item>
<c>sys_alloc</c> carrier size. Carriers allocated via
<c>sys_alloc</c> will be allocated in sizes which are
multiples of the <c>sys_alloc</c> carrier size. This is not
true for main multiblock carriers and carriers allocated
during a memory shortage, though.</item>
- <tag><marker id="Mummc"><c><![CDATA[+Mummc <amount>]]></c></marker></tag>
+ <tag><marker id="Mummc"/><c><![CDATA[+Mummc <amount>]]></c></tag>
<item>
Max <c>mseg_alloc</c> carriers. Maximum number of carriers
placed in separate memory segments. When this limit has been
reached, new carriers will be placed in memory retrieved from
<c>sys_alloc</c>.</item>
- <tag><marker id="Musac"><c><![CDATA[+Musac <bool>]]></c></marker></tag>
+ <tag><marker id="Musac"/><c><![CDATA[+Musac <bool>]]></c></tag>
<item>
Allow <c>sys_alloc</c> carriers. By default <c>true</c>. If
set to <c>false</c>, <c>sys_alloc</c> carriers will never be
@@ -565,19 +565,19 @@
</taglist>
<p>Instrumentation flags:</p>
<taglist>
- <tag><marker id="Mim"><c>+Mim true|false</c></marker></tag>
+ <tag><marker id="Mim"/><c>+Mim true|false</c></tag>
<item>
A map over current allocations is kept by the emulator. The
allocation map can be retrieved via the <c>instrument</c>
module. <c>+Mim true</c> implies <c>+Mis true</c>.
<c>+Mim true</c> is the same as
<seealso marker="erl#instr">-instr</seealso>.</item>
- <tag><marker id="Mis"><c>+Mis true|false</c></marker></tag>
+ <tag><marker id="Mis"/><c>+Mis true|false</c></tag>
<item>
Status over allocated memory is kept by the emulator. The
allocation status can be retrieved via the <c>instrument</c>
module.</item>
- <tag><marker id="Mit"><c>+Mit X</c></marker></tag>
+ <tag><marker id="Mit"/><c>+Mit X</c></tag>
<item>
Reserved for future use. Do <em>not</em> use this flag.</item>
</taglist>
@@ -587,7 +587,7 @@
</note>
<p>Other flags:</p>
<taglist>
- <tag><marker id="Mea"><c>+Mea min|max|r9c|r10b|r11b|config</c></marker></tag>
+ <tag><marker id="Mea"/><c>+Mea min|max|r9c|r10b|r11b|config</c></tag>
<item>
<taglist>
<tag><c>min</c></tag>
@@ -617,7 +617,7 @@
</item>
</taglist>
</item>
- <tag><marker id="Mlpm"><c>+Mlpm all|no</c></marker></tag>
+ <tag><marker id="Mlpm"/><c>+Mlpm all|no</c></tag>
<item>Lock physical memory. The default value is <c>no</c>, i.e.,
no physical memory will be locked. If set to <c>all</c>, all
memory mappings made by the runtime system, will be locked into
diff --git a/erts/doc/src/escript.xml b/erts/doc/src/escript.xml
index 46110333f9..f12f76890c 100644
--- a/erts/doc/src/escript.xml
+++ b/erts/doc/src/escript.xml
@@ -4,7 +4,7 @@
<comref>
<header>
<copyright>
- <year>2007</year><year>2014</year>
+ <year>2007</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -96,8 +96,8 @@ $ <input>escript factorial 5</input> </pre>
<note><p>
The encoding specified by the above mentioned comment
applies to the script itself. The encoding of the
- I/O-server, however, has to be set explicitly like this:
-<code>io:setopts([{encoding, unicode}])</code></p>
+ I/O-server, however, has to be set explicitly like this:</p>
+<code>io:setopts([{encoding, unicode}])</code>
<p>The default encoding of the I/O-server for <c>standard_io</c>
is <c>latin1</c>
since the script runs in a non-interactive terminal
diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml
index e51cf93cf7..b4bdc5735c 100644
--- a/erts/doc/src/notes.xml
+++ b/erts/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2013</year>
+ <year>2004</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -31,8 +31,9 @@
</header>
<p>This document describes the changes made to the ERTS application.</p>
-<section><title>Erts 7.1</title>
+
+<section><title>Erts 7.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
<item>
@@ -172,6 +173,14 @@
<p>
Own Id: OTP-12942</p>
</item>
+ <item>
+ <p>
+ When tracing with <c>process_dump</c> option, the VM
+ could abort if there was an ongoing binary match
+ somewhere in the call stack of the traced process./</p>
+ <p>
+ Own Id: OTP-12968</p>
+ </item>
</list>
</section>
@@ -700,19 +709,20 @@
</item>
<item>
<p>
- Use persistent hashmaps for large Maps <p>Maps will use a
+ Use persistent hashmaps for large Maps</p>
+ <p>Maps will use a
persistent hashmap implementation when the number of
pairs in a Map becomes sufficiently large. The change
will occur when a Map reaches 33 pairs in size but this
- limit might change in the future.</p></p>
- <p>The most significant impact for the user by this
+ limit might change in the future.</p>
+ <p>The most significant impact for the user by this
change is speed, and to a lesser degree memory
consumption and introspection of Maps. Memory consumption
size is probalistic but lesser than <c>gb_trees</c> or
<c>dict</c> for instance. Any other impacts will be
transparent for the user except for the following
changes.</p>
- <p>Semantics of Maps have changed in two incompatible
+ <p>Semantics of Maps have changed in two incompatible
ways compared to the experimental implementation in OTP
17:</p> <list> <item>Hashing of maps is done different by
<c>erlang:phash2/1,2</c>, <c>erlang:phash/1</c> and
@@ -972,6 +982,26 @@
</section>
+<section><title>Erts 6.4.1.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The 'raw' socket option could not be used multiple times
+ in one call to any e.g gen_tcp function because only one
+ of the occurrences were used. This bug has been fixed,
+ and also a small bug concerning propagating error codes
+ from within inet:setopts/2.</p>
+ <p>
+ Own Id: OTP-11482 Aux Id: seq12872 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+
<section><title>Erts 6.4.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -1360,7 +1390,7 @@
<p>
Improved support for atomic memory operations provided by
the <url
- href="https://github.com/ivmai/libatomic_ops/"><c>libatomic_ops</c></url>
+ href="https://github.com/ivmai/libatomic_ops/">libatomic_ops</url>
library. Most importantly support for use of native
double word atomics when implemented by
<c>libatomic_ops</c> (for example, implemented for ARM).</p>
@@ -2327,22 +2357,28 @@
<p>
EEP43: New data type - Maps</p>
<p>
- With Maps you may for instance: <taglist> <item><c>M0 =
- #{ a =&gt; 1, b =&gt; 2}, % create
- associations</c></item> <item><c>M1 = M0#{ a := 10 }, %
- update values</c></item> <item><c>M2 = M1#{ "hi" =&gt;
- "hello"}, % add new associations</c></item> <item><c>#{
- "hi" := V1, a := V2, b := V3} = M2. % match keys with
- values</c></item> </taglist></p>
+ With Maps you may for instance:</p>
+ <taglist>
+ <tag/> <item><c>M0 = #{ a =&gt; 1, b =&gt; 2}, % create
+ associations</c></item>
+ <tag/><item><c>M1 = M0#{ a := 10 }, % update values</c></item>
+ <tag/><item><c>M2 = M1#{ "hi" =&gt;
+ "hello"}, % add new associations</c></item>
+ <tag/><item><c>#{ "hi" := V1, a := V2, b := V3} = M2.
+ % match keys with values</c></item>
+ </taglist>
<p>
For information on how to use Maps please see Map Expressions in the
<seealso marker="doc/reference_manual:expressions#map_expressions">
Reference Manual</seealso>.</p>
<p>
The current implementation is without the following
- features: <taglist> <item>No variable keys</item>
- <item>No single value access</item> <item>No map
- comprehensions</item> </taglist></p>
+ features:</p>
+ <taglist>
+ <tag/><item>No variable keys</item>
+ <tag/><item>No single value access</item>
+ <tag/><item>No map comprehensions</item>
+ </taglist>
<p>
Note that Maps is <em>experimental</em> during OTP 17.0.</p>
<p>
@@ -4502,8 +4538,7 @@
<p>
Fix erl_prim_loader errors in handling of primary
archive. The following errors have been corrected:</p>
- <p>
- <list> <item> If primary archive was named "xxx", then a
+ <list> <item> If primary archive was named "xxx", then a
file in the same directory named "xxxyyy" would be
interpreted as a file named "yyy" inside the archive.
</item> <item> erl_prim_loader did not correctly create
@@ -4518,7 +4553,8 @@
erl_prim_loader:list_dir/1 would sometimes return an
empty string inside the file list. This was a virtual
element representing the top directory of the archive.
- This has been removed. </item> </list></p>
+ This has been removed. </item>
+ </list>
<p>
Thanks to Tuncer Ayaz and Shunichi Shinohara for
reporting and co-authoring corrections.</p>
@@ -6961,12 +6997,12 @@
Own Id: OTP-8726 Aux Id: seq11617 </p>
</item>
<item>
- <p>Fix libm linking with --as-needed flag
+ <p>Fix libm linking with --as-needed flag</p>
<p>
When building with "--as-needed" linker flags on Linux
the build will fail. This has now been fixed.</p>
<p>
- (Thanks to Christian Faulhammer)</p></p>
+ (Thanks to Christian Faulhammer)</p>
<p>
Own Id: OTP-8728</p>
</item>
diff --git a/erts/doc/src/time_correction.xml b/erts/doc/src/time_correction.xml
index aed38fbb92..236fe679cb 100644
--- a/erts/doc/src/time_correction.xml
+++ b/erts/doc/src/time_correction.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1999</year><year>2014</year>
+ <year>1999</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -35,31 +35,35 @@
<section>
<title>New Extended Time Functionality</title>
- <note><p>As of OTP 18 (ERTS version 7.0) the time functionality of
- Erlang has been extended. This both includes a
+ <note><p>As of OTP 18 (<c>ERTS</c> version 7.0) the time functionality of
+ Erlang has been extended. This includes a
<seealso marker="#The_New_Time_API">new API</seealso>
- for time, as well as
+ for time and
<seealso marker="#Time_Warp_Modes">time warp
- modes</seealso> which alters the behavior of the system when
+ modes</seealso> that alter the system behavior when
system time changes.</p>
+
<p>The <seealso marker="#No_Time_Warp_Mode">default
time warp mode</seealso> has the same behavior as before, and the
- old API will still work, so you are not required to change
+ old API still works. Thus, you are not required to change
anything unless you want to. However, <em>you are strongly
encouraged to use the new API</em> instead of the old API based
on <seealso marker="erlang#now/0"><c>erlang:now/0</c></seealso>.
- <c>erlang:now/0</c> has been deprecated since it is and forever
- will be a scalability bottleneck. By using the new API you will
+ <c>erlang:now/0</c> is deprecated, as it is and
+ will be a scalability bottleneck.</p>
+
+ <p>By using the new API, you
automatically get scalability and performance improvements. This
- will also enable you to use the
- <seealso marker="#Multi_Time_Warp_Mode">multi time warp mode</seealso>
- which improves accuracy, and precision of time measurements.</p></note>
+ also enables you to use the
+ <seealso marker="#Multi_Time_Warp_Mode">multi-time warp mode</seealso>
+ that improves accuracy and precision of time measurements.</p>
+ </note>
</section>
<section>
- <title>Some Terminology</title>
- <p>In order to make it easier to understand this document we first
- define some terminology. This is a mixture of our own terminology
+ <title>Terminology</title>
+ <p>To make it easier to understand this section, some terms
+ are defined. This is a mix of our own terminology
(Erlang/OS system time, Erlang/OS monotonic time, time warp)
and globally accepted terminology.</p>
@@ -67,7 +71,7 @@
<section>
<title>Monotonically Increasing</title>
<p>In a monotonically increasing sequence of values, all values
- that have a predecessor are either larger than, or equal to its
+ that have a predecessor are either larger than or equal to its
predecessor.</p>
</section>
@@ -82,19 +86,19 @@
<marker id="UT1"/>
<section>
<title>UT1</title>
- <p>Universal Time. Based on the rotation of the earth. Conceptually
- mean solar time at 0° longitude.</p>
+ <p>Universal Time. UT1 is based on the rotation of the earth
+ and conceptually means solar time at 0° longitude.</p>
</section>
<marker id="UTC"/>
<section>
<title>UTC</title>
- <p>Coordinated Universal Time. UTC almost align with
- <seealso marker="#UT1">UT1</seealso>, however, UTC uses the
- SI definition of a second which is not exactly of the same length
+ <p>Coordinated Universal Time. UTC almost aligns with
+ <seealso marker="#UT1">UT1</seealso>. However, UTC uses the
+ SI definition of a second, which has not exactly the same length
as the second used by UT1. This means that UTC slowly drifts from
- UT1. In order to keep UTC relatively in sync with UT1, leap seconds
- are inserted, and potentially also deleted. That is, an UTC day may
+ UT1. To keep UTC relatively in sync with UT1, leap seconds
+ are inserted, and potentially also deleted. That is, an UTC day can
be 86400, 86401, or 86399 seconds long.</p>
</section>
@@ -104,14 +108,15 @@
<p>Time since
<url href="http://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap03.html#tag_21_03_00_17">Epoch</url>.
Epoch is defined to be 00:00:00 <seealso marker="#UTC">UTC</seealso>,
- January 1, 1970.
+ 1970-01-01.
<url href="http://pubs.opengroup.org/onlinepubs/009604499/basedefs/xbd_chap04.html#tag_04_14">A day in POSIX time</url>
is defined to be exactly 86400 seconds long. Strangely enough
- Epoch is defined to be a time in UTC, and UTC have another
+ Epoch is defined to be a time in UTC, and UTC has another
definition of how long a day is. Quoting the Open Group
- <url href="http://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_15">"POSIX time is therefore not necessarily UTC, despite its appearance"</url>. The effect of this is that when an UTC leap second is
+ <url href="http://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_15">"POSIX time is therefore not necessarily UTC, despite its appearance"</url>.
+ The effect of this is that when an UTC leap second is
inserted, POSIX time either stops for a second, or repeats the
- last second. If an UTC leap second would be deleted (has never
+ last second. If an UTC leap second would be deleted (which has not
happened yet), POSIX time would make a one second leap forward.</p>
</section>
@@ -125,11 +130,11 @@
<marker id="Time_Precision"/>
<section>
<title>Time Precision</title>
- <p>The shortest time interval that can be be distinguished
+ <p>The shortest time interval that can be distinguished
repeatedly and reliably when reading time values. Precision
is limited by the
<seealso marker="#Time_Resolution">resolution</seealso>, but
- resolution and precision might differ significantly.</p>
+ resolution and precision can differ significantly.</p>
</section>
<marker id="Time_Accuracy"/>
@@ -143,21 +148,23 @@
<title>Time Warp</title>
<p>A time warp is a leap forwards or backwards in time. That
is, the difference of time values taken before and after the
- time warp will not correspond to the actual elapsed time.</p>
+ time warp does not correspond to the actual elapsed time.</p>
</section>
<marker id="OS_System_Time"/>
<section>
<title>OS System Time</title>
<p>The operating systems view of
- <seealso marker="#POSIX_Time">POSIX time</seealso>. It can be
- retrieved by calling
+ <seealso marker="#POSIX_Time">POSIX time</seealso>. To
+ retrieve it, call
<seealso marker="kernel:os#system_time/0"><c>os:system_time()</c></seealso>.
This may or may not be an accurate view of POSIX time. This time
may typically be adjusted both backwards and forwards without
limitation. That is, <seealso marker="#Time_Warp">time warps</seealso>
- may be observed. You can get information about the Erlang runtime
- system's source of OS system time by calling
+ may be observed.</p>
+
+ <p>To get information about the Erlang runtime
+ system's source of OS system time, call
<seealso marker="erlang#system_info_os_system_time_source"><c>erlang:system_info(os_system_time_source)</c></seealso>.</p>
</section>
@@ -165,15 +172,17 @@
<section>
<title>OS Monotonic Time</title>
<p>A monotonically increasing time provided by the operating
- system. This time does not leap and have a relatively steady
+ system. This time does not leap and has a relatively steady
frequency although not completely correct. However, it is not
- uncommon that the OS monotonic time stops if the system is
- suspended. This time typically increase since some
+ uncommon that OS monotonic time stops if the system is
+ suspended. This time typically increases since some
unspecified point in time that is not connected to
- <seealso marker="#OS_System_Time">OS system time</seealso>. Note
- that this type of time is not necessarily provided by all
- operating systems. You can get information about the Erlang
- runtime system's source of OS monotonic time by calling
+ <seealso marker="#OS_System_Time">OS system time</seealso>.
+ This type of time is not necessarily provided by all
+ operating systems.</p>
+
+ <p>To get information about the Erlang
+ runtime system's source of OS monotonic time, call
<seealso marker="erlang#system_info_os_monotonic_time_source"><c>erlang:system_info(os_monotonic_time_source)</c></seealso>.</p>
</section>
@@ -181,14 +190,17 @@
<section>
<title>Erlang System Time</title>
<p>The Erlang runtime systems view of
- <seealso marker="#POSIX_Time">POSIX time</seealso>. It can be
- retrieved by calling
- <seealso marker="erlang#system_time/0"><c>erlang:system_time()</c></seealso>.
- This time may or may not be an accurate view of POSIX time, and may
+ <seealso marker="#POSIX_Time">POSIX time</seealso>. To
+ retrieve it, call
+ <seealso marker="erlang#system_time/0"><c>erlang:system_time()</c></seealso>.</p>
+
+ <p>This time may or may not be an accurate view of POSIX time,
+ and may
or may not align with <seealso marker="#OS_System_Time">OS system
time</seealso>. The runtime system works towards aligning the two
- system times. Depending on <seealso marker="#Time_Warp_Modes">time
- warp mode</seealso> used, this may be achieved by letting the Erlang
+ system times. Depending on the
+ <seealso marker="#Time_Warp_Modes">time warp mode</seealso> used,
+ this can be achieved by letting Erlang
system time perform a <seealso marker="#Time_Warp">time
warp</seealso>.</p>
</section>
@@ -197,35 +209,43 @@
<section>
<title>Erlang Monotonic Time</title>
<p>A monotonically increasing time provided by the
- Erlang runtime system. The Erlang monotonic time increase since
- some unspecified point in time. It can be retrieved by calling
+ Erlang runtime system. Erlang monotonic time increases since
+ some unspecified point in time. To retrieve it, call
<seealso marker="erlang#monotonic_time/0"><c>erlang:monotonic_time()</c></seealso>.
- The
- <seealso marker="#Time_Accuracy">accuracy</seealso>, and
+ </p>
+
+ <p>The <seealso marker="#Time_Accuracy">accuracy</seealso> and
<seealso marker="#Time_Precision">precision</seealso> of Erlang
- monotonic time heavily depends on the accuracy and precision of
- <seealso marker="#OS_Monotonic_Time">OS monotonic time</seealso>,
- the accuracy and precision of
- <seealso marker="#OS_System_Time">OS system time</seealso> as well
- as on the
- <seealso marker="#Time_Warp_Modes">time warp mode</seealso>
- used. On a system that is lacking OS monotonic time, the Erlang
- monotonic time can only guarantee monotonicity and can more or less
- not give any other guarantees. The frequency adjustments made to
- the Erlang monotonic time depends on the time warp mode
- used.</p>
-
- <p>Internally in the runtime system the Erlang monotonic
+ monotonic time heavily depends on the following:</p>
+
+ <list type="bulleted">
+ <item>Accuracy and precision of
+ <seealso marker="#OS_Monotonic_Time">OS monotonic time</seealso>
+ </item>
+ <item>Accuracy and precision of
+ <seealso marker="#OS_System_Time">OS system time</seealso>
+ </item>
+ <item><seealso marker="#Time_Warp_Modes">time warp mode</seealso> used
+ </item>
+ </list>
+
+ <p>On a system without OS monotonic time, Erlang monotonic
+ time guarantees monotonicity, but cannot give
+ other guarantees. The frequency adjustments made to
+ Erlang monotonic time depend on the time warp mode used.</p>
+
+ <p>Internally in the runtime system, Erlang monotonic
time is the "time engine" that is used for more or less
- everything that has anything to do with time. All timers
+ everything that has anything to do with time. All timers,
regardless of it is a <c>receive ... after</c> timer, BIF timer,
- or a timer in the <c>timer</c> module are triggered
+ or a timer in the <c>timer</c> module, are triggered
relative Erlang monotonic time. Even
<seealso marker="#Erlang_System_Time">Erlang system
time</seealso> is based on Erlang monotonic time.
By adding current Erlang monotonic time with current time
- offset you get current Erlang system time. Current time
- offset can be retrieved by calling
+ offset, you get current Erlang system time.</p>
+
+ <p>To retrieve current time offset, call
<seealso marker="erlang#time_offset/0"><c>erlang:time_offset/0</c></seealso>.
</p>
</section>
@@ -234,176 +254,169 @@
<section>
<title>Introduction</title>
-
<p>Time is vital to an Erlang program and, more importantly, <em>correct</em>
time is vital to an Erlang program. As Erlang is a language with
- soft real time properties and we have the possibility to express
- time in our programs, the Virtual Machine and the language has to be
- very careful about what is considered a correct point in time and in
+ soft real-time properties and we can express
+ time in our programs, the Virtual Machine and the language must be
+ careful about what is considered a correct time and in
how time functions behave.</p>
- <p>In the beginning, Erlang was constructed assuming that the wall
+ <p>When Erlang was designed, it was assumed that the wall
clock time in the system showed a monotonic time moving forward at
- exactly the same pace as the definition of time. That more or less
- meant that an atomic clock (or better) was expected to be attached
+ exactly the same pace as the definition of time. This more or less meant
+ that an atomic clock (or better time source) was expected to be attached
to your hardware and that the hardware was then expected to be
- locked away from any human (or unearthly) tinkering for all
- eternity. While this might be a compelling thought, it's simply
- never the case.</p>
-
- <p>A "normal" modern computer can not keep time. Not on itself and
- not unless you actually have a chip level atomic clock wired to
- it. Time, as perceived by your computer, will normally need to be
- corrected. Hence the NTP protocol that together with the ntpd
- process will do it's best to keep your computers time in sync with
- the "real" time in the universe. Between NTP corrections, usually a
+ locked away from any human tinkering forever. While this can be a
+ compelling thought, it is simply never the case.</p>
+
+ <p>A "normal" modern computer cannot keep time, not on itself and
+ not unless you have a chip-level atomic clock wired to it. Time,
+ as perceived by your computer, must normally be corrected. Hence
+ the Network Time Protocol (NTP) protocol, together with the <c>ntpd</c>
+ process, does its best to keep your computer time in sync with
+ the correct time. Between NTP corrections, usually a
less potent time-keeper than an atomic clock is used.</p>
- <p>But NTP is not fail safe. The NTP server can be unavailable, the
- ntp.conf can be wrongly configured or your computer may from time to
- time be disconnected from the internet. Furthermore you can have a
- user (or even system administrator) on your system that thinks the
- right way to handle daylight saving time is to adjust the clock one
- hour two times a year (a tip, that is not the right way to do
- it...). To further complicate things, this user fetched your
- software from the internet and has never ever thought about what's
- the correct time as perceived by a computer. The user simply does
- not care about keeping the wall clock in sync with the rest of the
- universe. The user expects your program to have omnipotent knowledge
+ <p>However, NTP is not fail-safe. The NTP server can be unavailable,
+ <c>ntp.conf</c> can be wrongly configured, or your computer may
+ sometimes be disconnected from Internet. Furthermore, you can have a
+ user (or even system administrator) who thinks the correct
+ way to handle Daylight Saving Time is to adjust the clock one
+ hour two times a year (which is the incorrect way to do it).
+ To complicate things further, this user fetched your
+ software from Internet and has not considered what
+ the correct time is as perceived by a computer. The user does
+ not care about keeping the wall clock in sync with the correct
+ time. The user expects your program to have unlimited knowledge
about the time.</p>
<p>Most programmers also expect time to be reliable, at least until
- they realize that the wall clock time on their workstation is of by
- a minute. Then they simply set it to the correct time, maybe or
- maybe not in a smooth way. Most probably not in a smooth way.</p>
+ they realize that the wall clock time on their workstation is off by
+ a minute. Then they set it to the correct time, but most probably
+ not in a smooth way.</p>
- <p>The amount of problems that arise when you expect the wall clock
- time on the system to always be correct may be immense. Therefore Erlang
+ <p>The number of problems that arise when you always expect the wall clock
+ time on the system to be correct can be immense. Erlang therefore
introduced the "corrected estimate of time", or the "time
- correction" many years ago. The time correction relies on the fact
+ correction", many years ago. The time correction relies on the fact
that most operating systems have some kind of monotonic clock,
- either a real time extension or some built in "tick counter" that is
- independent of the wall clock settings. This counter may have
- microsecond resolution or much less, but generally it has a drift
- that is not to be ignored.</p>
-
+ either a real-time extension or some built-in "tick counter" that is
+ independent of the wall clock settings. This counter can have
+ microsecond resolution or much less, but it has a drift that cannot
+ be ignored.</p>
</section>
- <marker id="Time_Correction"/>
<section>
+ <marker id="Time_Correction"/>
<title>Time Correction</title>
<p>If time correction is enabled, the Erlang runtime system
- will make use of both
+ makes use of both
<seealso marker="#OS_System_Time">OS system time</seealso>
and <seealso marker="#OS_Monotonic_Time">OS monotonic time</seealso>,
- in order to make adjustments of the frequency of the Erlang
- monotonic clock. Time correction will ensure that
+ to adjust the frequency of the Erlang
+ monotonic clock. Time correction ensures that
<seealso marker="#Erlang_Monotonic_Time">Erlang monotonic time</seealso>
- will not warp, and that the frequency is relatively accurate.
- The type of adjustments made to the frequency depends on the
- time warp mode used. This will be discussed in more details in
- the <seealso marker="#Time_Warp_Modes">time warp modes</seealso>
- section below.</p>
-
- <p>By default time correction will be enabled if support for
- it on the specific platform exist. Support for it includes
- both an OS monotonic time provided by the OS, and an
- implementation in the Erlang runtime system utilizing the
- OS monotonic time. You can check if your system has support
- for OS monotonic time by calling
- <seealso marker="erlang#system_info_os_monotonic_time_source"><c>erlang:system_info(os_monotonic_time_source)</c></seealso>,
- and you can check if time correction is enabled on your
- system by calling
+ does not warp and that the frequency is relatively accurate.
+ The type of frequency adjustments depends on the time warp mode used.
+ Section <seealso marker="#Time_Warp_Modes">Time Warp Modes</seealso>
+ provides more details.</p>
+
+ <p>By default time correction is enabled if support for
+ it exists on the specific platform. Support for it includes
+ both OS monotonic time, provided by the OS, and an
+ implementation in the Erlang runtime system using
+ OS monotonic time. To check if your system has support
+ for OS monotonic time, call
+ <seealso marker="erlang#system_info_os_monotonic_time_source"><c>erlang:system_info(os_monotonic_time_source)</c></seealso>.
+ To check if time correction is enabled on your system, call
<seealso marker="erlang#system_info_time_correction"><c>erlang:system_info(time_correction)</c></seealso>.</p>
- <p>Time correction is enabled or disabled by passing the
+ <p>To enable or disable time correction, pass command-line argument
<seealso marker="erl#+c"><c>+c [true|false]</c></seealso>
- command line argument to <c>erl</c>.</p>
+ to <c>erl</c>.</p>
<p>If time correction is disabled, Erlang monotonic time
- may warp forwards, it may stop and even freeze for extended
- periods of time, and there are no guarantees that the frequency
+ may warp forwards or stop, or even freeze for extended
+ periods of time. There are then no guarantees that the frequency
of the Erlang monotonic clock is accurate or stable.</p>
<p><em>You typically never want to disable time correction</em>.
- Previously there was a performance penalty associated with time
- correction, but nowadays it is most often the other way around.
- By disabling time correction you are likely to get bad scalability,
+ Previously a performance penalty was associated with time
+ correction, but nowadays it is usually the other way around.
+ If time correction is disabled, you probably get bad scalability,
bad performance, and bad time measurements.</p>
</section>
-
- <marker id="Time_Warp_Safe_Code"/>
<section>
+ <marker id="Time_Warp_Safe_Code"/>
<title>Time Warp Safe Code</title>
- <p>Time warp safe code is code that is able to handle
+ <p>Time warp safe code can handle
a <seealso marker="#Time_Warp">time warp</seealso> of
- <seealso marker="#Erlang_System_Time">Erlang system time</seealso>.
- </p>
+ <seealso marker="#Erlang_System_Time">Erlang system time</seealso>.</p>
<p><seealso marker="erlang#now/0"><c>erlang:now/0</c></seealso>
- behaves very bad when Erlang system time warps. When Erlang
- system time do a time warp backwards, the values returned
- from <c>erlang:now/0</c> will freeze (if you disregard the
- micro second increments made due to the actual call) until
- OS system time reach the point of the last value returned by
- <c>erlang:now/0</c>. This freeze might continue for very
- long periods of time. It might take years, decades,
- and even longer than this until the freeze stops.</p>
+ behaves bad when Erlang system time warps. When Erlang
+ system time does a time warp backwards, the values returned
+ from <c>erlang:now/0</c> freeze (if you disregard the
+ microsecond increments made because of the actual call) until
+ OS system time reaches the point of the last value returned by
+ <c>erlang:now/0</c>. This freeze can continue for a long time. It
+ can take years, decades, and even longer until the freeze stops.</p>
<p>All uses of <c>erlang:now/0</c> are not necessarily
time warp unsafe. If you do not use it to get time, it
- will be time warp safe. However <em>all uses of
+ is time warp safe. However, <em>all uses of
<c>erlang:now/0</c> are suboptimal</em> from a performance
and scalability perspective. So you really want to replace
- the usage of it with other functionality. For examples
- of how to replace the usage of <c>erlang:now/0</c>,
- see the <seealso marker="#Dos_and_Donts">Dos and Donts</seealso>
- section.</p>
+ the use of it with other functionality. For examples
+ of how to replace the use of <c>erlang:now/0</c>, see Section
+ <seealso marker="#Dos_and_Donts">How to Work with the New
+ API</seealso>.</p>
</section>
- <marker id="Time_Warp_Modes"/>
<section>
<title>Time Warp Modes</title>
-
+ <marker id="Time_Warp_Modes"/>
<p>Current <seealso marker="#Erlang_System_Time">Erlang system
time</seealso> is determined by adding current
<seealso marker="erlang#monotonic_time/0">Erlang monotonic time</seealso>
with current
<seealso marker="erlang#time_offset/0">time offset</seealso>. The
time offset is managed differently depending on which time
- warp mode you use. The time warp mode is set by passing the
+ warp mode you use.</p>
+
+ <p>To set the time warp mode, pass command-line argument
<seealso marker="erl#+C_"><c>+C
[no_time_warp|single_time_warp|multi_time_warp]</c></seealso>
- command line argument to <c>erl</c>.</p>
+ to <c>erl</c>.</p>
<marker id="No_Time_Warp_Mode"/>
<section>
<title>No Time Warp Mode</title>
<p>The time offset is determined at runtime system start
- and will after this not change. This is the default behavior.
- Not because it is the best mode (which it isn't). It is
+ and does not change later. This is the default behavior, but
+ not because it is the best mode (which it is not). It is
default <em>only</em> because this is how the runtime system
- always has behaved up until ERTS version 7.0, and you have to
- ensure that your Erlang code that may execute during a time
+ behaved until <c>ERTS</c> 7.0.
+ Ensure that your Erlang code that may execute during a time
warp is <seealso marker="#Time_Warp_Safe_Code">time warp
- safe</seealso> before you can enable other modes.</p>
+ safe</seealso> before enabling other modes.</p>
- <p>Since the time offset is not allowed to change, time
- correction needs to adjust the frequency of the Erlang
- monotonic clock in order to smoothly align Erlang system
- time with OS system time. A big downside of this approach
+ <p>As the time offset is not allowed to change, time
+ correction must adjust the frequency of the Erlang
+ monotonic clock to align Erlang system time with OS
+ system time smoothly. A significant downside of this approach
is that we on purpose will use a faulty frequency on the
Erlang monotonic clock if adjustments are needed. This
- error may be as big as 1%. This error will show up in all
+ error can be as large as 1%. This error will show up in all
time measurements in the runtime system.</p>
- <p>If time correction is not enabled, the Erlang monotonic
- time will freeze when the OS system time leap backwards.
- The freeze of the monotonic time will continue until
- OS system time catch up. The freeze may continue for
- a very long time. When OS system time leaps forwards,
- Erlang monotonic time will also leap forward.</p>
+ <p>If time correction is not enabled, Erlang monotonic
+ time freezes when OS system time leaps backwards.
+ The freeze of monotonic time continues until
+ OS system time catches up. The freeze can continue for
+ a long time. When OS system time leaps forwards,
+ Erlang monotonic time also leaps forward.</p>
</section>
<marker id="Single_Time_Warp_Mode"/>
@@ -411,26 +424,27 @@
<title>Single Time Warp Mode</title>
<p>This mode is more or less a backwards compatibility mode
as of its introduction.</p>
+
<p>On an embedded system it is not uncommon that the system
- has no power supply at all, not even a battery, when it is
- shut off. The system clock on such a system will typically
- be way off when the system boots. If the
+ has no power supply, not even a battery, when it is
+ shut off. The system clock on such a system is typically
+ way off when the system boots. If
<seealso marker="#No_Time_Warp_Mode">no time warp mode</seealso>
is used, and the Erlang runtime system is started before
- the OS system time has been corrected, the Erlang system
- time may be wrong for a very long time, even centuries or
- more.</p>
- <p>If you for some reason need to use Erlang code that
- is not
+ OS system time has been corrected, Erlang system time
+ can be wrong for a long time, centuries or even longer.</p>
+
+ <p>If you need to use Erlang code that is not
<seealso marker="#Time_Warp_Safe_Code">time warp safe</seealso>,
- and you need to start the Erlang runtime system before the OS
+ and you need to start the Erlang runtime system before OS
system time has been corrected, you may want to use the single
- time warp mode. Note that there are limitations to when you can
+ time warp mode.</p>
+
+ <note><p>There are limitations to when you can
execute time warp unsafe code using this mode. If it is possible
- to only utilize time warp safe code, it is <em>much</em> better
- to use the <seealso marker="#Multi_Time_Warp_Mode">multi time
- warp mode</seealso> instead.
- </p>
+ to use time warp safe code only, it is <em>much</em> better
+ to use the <seealso marker="#Multi_Time_Warp_Mode">multi-time
+ warp mode</seealso> instead.</p></note>
<p>Using the single time warp mode, the time offset is
handled in two phases:</p>
@@ -438,158 +452,150 @@
<taglist>
<tag>Preliminary Phase</tag>
<item>
- <p>The preliminary phase starts when the runtime
+ <p>This phase starts when the runtime
system starts. A preliminary time offset based on
- current OS system time is determined. This offset will
- from now on be fixed during the whole preliminary phase.</p>
+ current OS system time is determined. This offset is from
+ now on to be fixed during the whole preliminary phase.</p>
<p>If time correction is enabled, adjustments to the
- Erlang monotonic clock will be made to keep its
- frequency as correct as possible, but <em>no</em>
- adjustments will be made trying to align Erlang system
- time and OS system time. That is, during the preliminary
- Erlang system time and OS system time might diverge
- from each other, and no attempt to prevent this will
- be made.</p>
+ Erlang monotonic clock are made to keep its
+ frequency as correct as possible. However, <em>no</em>
+ adjustments are made trying to align Erlang system
+ time and OS system time. That is, during the preliminary phase
+ Erlang system time and OS system time can diverge
+ from each other, and no attempt is made to prevent this.</p>
<p>If time correction is disabled, changes in OS system
- time will effect the monotonic clock the same way as
+ time affects the monotonic clock the same way as
when the <seealso marker="#No_Time_Warp_Mode">no time warp
mode</seealso> is used.</p>
</item>
<tag>Final Phase</tag>
<item>
-
- <p>The final phase begin when the user finalize the time
+ <p>This phase begins when the user finalizes the time
offset by calling
<seealso marker="erlang#system_flag_time_offset"><c>erlang:system_flag(time_offset, finalize)</c></seealso>.
- The finalization can only be performed once.
- </p>
+ The finalization can only be performed once.</p>
<p>During finalization, the time offset is adjusted and
- fixated so that current Erlang system time align with
- current OS system time. Since the time offset may
- change during the finalization, the Erlang system time
- may do a time warp at this point. The time offset will
- from now on be fixed until the runtime system terminates.
+ fixated so that current Erlang system time aligns with
+ current OS system time. As the time offset can
+ change during the finalization, Erlang system time
+ can do a time warp at this point. The time offset is
+ from now on fixed until the runtime system terminates.
If time correction has been enabled, the time
- correction will from now on also make adjustments
- in order to align Erlang system time with OS system
- time. When the system is in the final phase it behaves
+ correction from now on also makes adjustments
+ to align Erlang system time with OS system
+ time. When the system is in the final phase, it behaves
exactly as in the <seealso marker="#No_Time_Warp_Mode">no
time warp mode</seealso>.</p>
-
</item>
</taglist>
- <p>In order for this to work properly there are two
- requirements that the user needs to ensure are
- satisfied:</p>
+ <p>In order for this to work properly, the user must ensure
+ that the following two requirements are satisfied:</p>
<taglist>
<tag>Forward Time Warp</tag>
<item><p>The time warp made when finalizing the time offset
can only be done forwards without encountering problems.
- This implies that the user has to ensure that the OS
+ This implies that the user must ensure that OS
system time is set to a time earlier or equal to actual
- POSIX time before starting the Erlang runtime system. If
- you are not completely sure the OS system time is correct,
+ POSIX time before starting the Erlang runtime system.</p>
+
+ <p>If you are not sure that OS system time is correct,
set it to a time that is guaranteed to be earlier than
actual POSIX time before starting the Erlang runtime
- system just to be safe.</p></item>
+ system, just to be safe.</p>
+ </item>
<tag>Finalize Correct OS System Time</tag>
- <item><p>The OS system time needs to be correct when the
- the user finalizes the time offset.</p></item>
+ <item><p>OS system time must be correct when
+ the user finalizes the time offset.</p>
+ </item>
</taglist>
<p>If these requirements are not fulfilled, the system
- may behave very bad.
- </p>
-
- <p>Assuming that the requirements above are fulfilled,
- time correction is enabled, and that the OS system time
- is adjusted using some time adjustment protocol like NTP
- or similar, only small adjustments of the Erlang monotonic
- time should be needed in order to keep system times
- aligned after finilization. As long as the system is not
- suspended, the largest adjustments needed should be for
+ may behave very bad.</p>
+
+ <p>Assuming that these requirements are fulfilled,
+ time correction is enabled, and that OS system time
+ is adjusted using a time adjustment protocol such as NTP,
+ only small adjustments of Erlang monotonic
+ time are needed to keep system times
+ aligned after finalization. As long as the system is not
+ suspended, the largest adjustments needed are for
inserted (or deleted) leap seconds.</p>
- <warning><p>In order to be able to use this mode you have
- to ensure that all Erlang code that will execute in
- both phases are
+ <warning><p>To use this mode, ensure that
+ all Erlang code that will execute in both phases are
<seealso marker="#Time_Warp_Safe_Code">time warp
safe</seealso>.</p>
- <p>Code that only execute in the final phase does not have
+ <p>Code executing only in the final phase does not have
to be able to cope with the time warp.</p></warning>
-
</section>
<marker id="Multi_Time_Warp_Mode"/>
<section>
- <title>Multi Time Warp Mode</title>
-
- <p><em>Multi time warp mode in combination with time
- correction is the preferred configuration</em>. This since,
- on almost all platforms, the Erlang runtime system will have
- better performance, will scale better, will behave better,
- and since the accuracy, and precision of time measurements
- will be better. Only Erlang runtime systems executing on
- ancient platforms will benefit from another configuration.</p>
+ <title>Multi-Time Warp Mode</title>
+ <p><em>Multi-time warp mode in combination with time
+ correction is the preferred configuration</em>. This as
+ the Erlang runtime system have better performance, scale
+ better, and behave better on almost all platforms. In
+ addition, the accuracy and precision of time measurements
+ are better. Only Erlang runtime systems executing on
+ ancient platforms benefit from another configuration.</p>
<p>The time offset may change at any time without limitations.
That is, Erlang system time may perform time warps both
- forwards and backwards at <em>any</em> time. Since we align
- the Erlang system time with the OS system time by changing
+ forwards and backwards at <em>any</em> time. As we align
+ Erlang system time with OS system time by changing
the time offset, we can enable a time correction that tries
to adjust the frequency of the Erlang monotonic clock to be as
- correct as possible. This will make time measurements using
- the Erlang monotonic time more accurate and precise.</p>
+ correct as possible. This makes time measurements using
+ Erlang monotonic time more accurate and precise.</p>
<p>If time correction is disabled, Erlang monotonic time
- will leap forward if OS system time leaps forward. If the
- OS system time leaps backwards, Erlang monotonic time will
- stop briefly but it does not freeze for extended periods
- of time. This since the time offset is changed in order to
+ leaps forward if OS system time leaps forward. If
+ OS system time leaps backwards, Erlang monotonic time
+ stops briefly, but it does not freeze for extended periods
+ of time. This as the time offset is changed to
align Erlang system time with OS system time.</p>
- <warning><p>In order to be able to use this mode you have
- to ensure that all Erlang code that will execute on the
- runtime system is
+ <warning><p>To use this mode, ensure that all
+ Erlang code that will execute on the runtime system is
<seealso marker="#Time_Warp_Safe_Code">time warp
safe</seealso>.</p></warning>
</section>
</section>
- <marker id="The_New_Time_API"/>
<section>
- <title>The New Time API</title>
-
+ <title>New Time API</title>
+ <marker id="The_New_Time_API"/>
<p>The old time API is based on
<seealso marker="erlang#now/0"><c>erlang:now/0</c></seealso>.
- The major issue with <c>erlang:now/0</c> is that it was
- intended to be used for so many unrelated things. This
- tied these unrelated operations together and unnecessarily
- caused performance, scalability as well as accuracy, and
- precision issues for operations that do not need to have
- such issues. The new API spreads different functionality
- over multiple functions in order to improve on this.</p>
-
- <p>In order to be backwards compatible <c>erlang:now/0</c> will
- remain as is, but <em>you are strongly discouraged from using
- it</em>. A lot of uses of <c>erlang:now/0</c> will also
- prevent you from using the new
- <seealso marker="#Multi_Time_Warp_Mode">multi time warp
- mode</seealso> which is an important part of this
+ <c>erlang:now/0</c> was intended to be used for many unrelated
+ things. This tied these unrelated operations together and
+ caused issues with performance, scalability, accuracy, and
+ precision for operations that did not need to have
+ such issues. To improve this, the new API spreads different
+ functionality over multiple functions.</p>
+
+ <p>To be backwards compatible, <c>erlang:now/0</c>
+ remains as is, but <em>you are strongly discouraged from using
+ it</em>. Many use cases of <c>erlang:now/0</c>
+ prevents you from using the new
+ <seealso marker="#Multi_Time_Warp_Mode">multi-time warp
+ mode</seealso>, which is an important part of this
new time functionality improvement.</p>
<p>Some of the new BIFs on some systems, perhaps surprisingly,
- return negative integer values on a newly started run time
- system. This is not a bug, but a memory usage optimization.</p>
+ return negative integer values on a newly started runtime
+ system. This is not a bug, but a memory use optimization.</p>
+
+ <p>The new API consists of the following new BIFs:</p>
- <p>The new API consists of a number of new BIFs:</p>
<list>
<item><p><seealso marker="erlang#convert_time_unit/3"><c>erlang:convert_time_unit/3</c></seealso></p></item>
<item><p><seealso marker="erlang#monotonic_time/0"><c>erlang:monotonic_time/0</c></seealso></p></item>
@@ -604,7 +610,9 @@
<item><p><seealso marker="kernel:os#system_time/0"><c>os:system_time/0</c></seealso></p></item>
<item><p><seealso marker="kernel:os#system_time/1"><c>os:system_time/1</c></seealso></p></item>
</list>
- <p>and a number of extensions of existing BIFs:</p>
+
+ <p>The new API also consists of extensions of the following existing BIFs:</p>
+
<list>
<item><p><seealso marker="erlang#monitor/2"><c>erlang:monitor(time_offset, clock_service)</c></seealso></p></item>
<item><p><seealso marker="erlang#system_flag_time_offset"><c>erlang:system_flag(time_offset, finalize)</c></seealso></p></item>
@@ -619,102 +627,99 @@
<marker id="The_New_Erlang_Monotonic_Time"/>
<section>
- <title>The New Erlang Monotonic Time</title>
- <p>The Erlang monotonic time as such is new as of ERTS
- version 7.0. It has been introduced in order to be able
- to detach time measurements such as elapsed time from
- calender time. It is very common that one is interested
- in measuring elapsed time or specifying a time relative
- to another point in time without having any need to know
- what the involved times are in UTC or any other
- globally defined time scale. By introducing a time scale
- that has a local definition of where it starts, it is
- possible to manage time that do not concern calender
- time on that time scale. Erlang monotonic time use
- such a time scale with a locally defined start.</p>
-
- <p>The introduction of Erlang monotonic time gives us
- the possibility to adjust the two Erlang times (Erlang
+ <title>New Erlang Monotonic Time</title>
+ <p>Erlang monotonic time as such is new as of <c>ERTS</c> 7.0.
+ It is introduced to detach time measurements, such as elapsed
+ time from calendar time. In many use cases there is a need to
+ measure elapsed time or specify a time relative to another point
+ in time without the need to know the involved times in UTC or
+ any other globally defined time scale. By introducing a time
+ scale with a local definition of where it starts, time that do
+ not concern calendar time can be managed on that time
+ scale. Erlang monotonic time uses such a time scale with a
+ locally defined start.</p>
+
+ <p>The introduction of Erlang monotonic time allows
+ us to adjust the two Erlang times (Erlang
monotonic time and Erlang system time) separately. By
- doing this, accuracy of elapsed time does not have to
+ doing this, the accuracy of elapsed time does not have to
suffer just because the system time happened to be
wrong at some point in time. Separate adjustments
of the two times are only performed in the time warp
modes, and only fully separated in the
- <seealso marker="#Multi_Time_Warp_Mode">multi
- time warp mode</seealso>. All other modes than the
- multi time warp mode are there for backwards
- compatibility reasons, and when using these the
- accuracy of Erlang monotonic time suffer since
+ <seealso marker="#Multi_Time_Warp_Mode">multi-time
+ warp mode</seealso>. All other modes than the
+ multi-time warp mode are for backwards
+ compatibility reasons. When using these modes, the
+ accuracy of Erlang monotonic time suffer, as
the adjustments of Erlang monotonic time in these
- modes are more or less tied to the Erlang system
- time.</p>
+ modes are more or less tied to Erlang system time.</p>
<p>The adjustment of system time could have been made
smother than using a time warp approach, but we think
- that would be a bad choice. Since we are able to
- express and measure time that aren't connected to
- calender time by the use of Erlang monotonic time, it
+ that would be a bad choice. As we can
+ express and measure time that is not connected to
+ calendar time by the use of Erlang monotonic time, it
is better to expose the change in Erlang system time
- immediately. This since it makes it possible for the
- Erlang applications executing on the system to react
- on the change in system time as soon as possible. This
- is also more or less exactly how most OSes handle this
+ immediately. This as the Erlang applications
+ executing on the system can react on the change in
+ system time as soon as possible. This is also more or
+ less exactly how most operating systems handle this
(OS monotonic time and OS system time). By adjusting
- system time smoothly we would just hide the fact that
+ system time smoothly, we would just hide the fact that
system time changed and make it harder for the Erlang
applications to react to the change in a sensible way.</p>
- <p>In order to be able to react to a change in Erlang
- system time you have to be able to detect that it
+ <p>To be able to react to a change in Erlang
+ system time, you must be able to detect that it
happened. The change in Erlang system time occurs when
current time offset is changed. We have therefore
- introduced the possibility to monitor the time offset
- using
- <seealso marker="erlang#monitor/2"><c>erlang:monitor(time_offset, clock_service)</c></seealso>. A process monitoring the time
- offset will be sent a message on the following format
+ introduced the possibility to monitor the time offset using
+ <seealso marker="erlang#monitor/2"><c>erlang:monitor(time_offset, clock_service)</c></seealso>.
+ A process monitoring the time
+ offset is sent a message on the following format
when the time offset is changed:</p>
+
<code type="none">{'CHANGE', MonitorReference, time_offset, clock_service, NewTimeOffset}</code>
</section>
<marker id="Unique_Values"/>
<section>
<title>Unique Values</title>
- <p>Besides reporting time <c>erlang:now/0</c> also
- produce unique and strictly monotonically increasing
- values. In order to detach this functionality from
- time measurements we have introduced
+ <p>Besides reporting time, <c>erlang:now/0</c> also
+ produces unique and strictly monotonically increasing
+ values. To detach this functionality from
+ time measurements, we have introduced
<seealso marker="erlang#unique_integer/1"><c>erlang:unique_integer()</c></seealso>.
</p>
</section>
<marker id="Dos_and_Donts"/>
<section>
- <title>Dos and Don'ts</title>
+ <title>How to Work with the New API</title>
<p>Previously <c>erlang:now/0</c> was the only option for doing
- quite a lot of things. We will look at a few different things
- <c>erlang:now/0</c> could be used for, and how you want to do
- this using the new API:</p>
+ many things. This section deals with some things that
+ <c>erlang:now/0</c> can be used for, and how you are to
+ these using the new API.</p>
<marker id="Dos_and_Donts_Retrieve_Erlang_System_Time"/>
<section>
<title>Retrieve Erlang System Time</title>
<dont>
<p>
- use <c>erlang:now/0</c> in order to retrieve current Erlang
- system time.
+ Use <c>erlang:now/0</c> to retrieve current Erlang system time.
</p>
</dont>
<do>
<p>
- use
+ Use
<seealso marker="erlang#system_time/1"><c>erlang:system_time/1</c></seealso>
- in order to retrieve current Erlang system time on the
+ to retrieve current Erlang system time on the
<seealso marker="erlang#type_time_unit">time unit</seealso>
of your choice.</p>
<p>If you want the same format as returned by <c>erlang:now/0</c>, use
<seealso marker="erlang#timestamp/0"><c>erlang:timestamp/0</c></seealso>.
- </p>
+ </p>
</do>
</section>
@@ -723,26 +728,27 @@
<title>Measure Elapsed Time</title>
<dont>
<p>
- take timestamps with <c>erlang:now/0</c> and calculate
+ Take timestamps with <c>erlang:now/0</c> and calculate
the difference in time with
<seealso marker="stdlib:timer#now_diff/2"><c>timer:now_diff/2</c></seealso>.
</p>
</dont>
<do>
<p>
- take timestamps with
+ Take timestamps with
<seealso marker="erlang#monotonic_time/0"><c>erlang:monotonic_time/0</c></seealso>
and calculate the time difference using ordinary subtraction.
The result will be in <c>native</c>
<seealso marker="erlang#type_time_unit">time unit</seealso>.
If you want to convert the
- result to another time unit you can do this using
+ result to another time unit, you can use
<seealso marker="erlang#convert_time_unit/3"><c>erlang:convert_time_unit/3</c></seealso>.
</p>
- <p>Another easier way of doing this is to use
+
+ <p>An easier way to do this is to use
<seealso marker="erlang#monotonic_time/1"><c>erlang:monotonic_time/1</c></seealso>
- with desired time unit. However, you may lose accuracy,
- and precision this way.
+ with the desired time unit. However, you can then lose accuracy
+ and precision.
</p>
</do>
</section>
@@ -752,16 +758,16 @@
<title>Determine Order of Events</title>
<dont>
<p>
- determine the order of events by saving a timestamp
- with <c>erlang:now/0</c> when the event happens.
+ Determine the order of events by saving a timestamp
+ with <c>erlang:now/0</c> when the event occurs.
</p>
</dont>
<do>
<p>
- determine the order of events by saving the integer
+ Determine the order of events by saving the integer
returned by
<seealso marker="erlang#unique_integer/1"><c>erlang:unique_integer([monotonic])</c></seealso>
- when the event happens. These integers will be strictly
+ when the event occurs. These integers will be strictly
monotonically ordered on current runtime system instance
corresponding to creation time.
</p>
@@ -770,40 +776,43 @@
<marker id="Dos_and_Donts_Determine_Order_of_Events_With_Time_of_the_Event"/>
<section>
- <title>Determine Order of Events With Time of the Event</title>
+ <title>Determine Order of Events with Time of the Event</title>
<dont>
<p>
- determine the order of events by saving a timestamp
- with <c>erlang:now/0</c> when the event happens.
+ Determine the order of events by saving a timestamp
+ with <c>erlang:now/0</c> when the event occurs.
</p>
</dont>
<do>
<p>
- determine the order of events by saving a tuple
- containing
+ Determine the order of events by saving a tuple containing
<seealso marker="erlang#monotonic_time/0">monotonic time</seealso>
and a <seealso marker="erlang#unique_integer/1">strictly
- monotonically increasing integer</seealso> like this:</p>
+ monotonically increasing integer</seealso> as follows:</p>
+
<code type="none">
Time = erlang:monotonic_time(),
UMI = erlang:unique_integer([monotonic]),
EventTag = {Time, UMI}</code>
+
<p>These tuples will be strictly monotonically ordered
- on the current runtime system instance according to
- creation time. Note that it is important that the
+ on current runtime system instance according to
+ creation time. It is important that the
monotonic time is in the first element (the most
significant element when comparing 2-tuples). Using
the monotonic time in the tuples, you can calculate time
between events.</p>
- <p>If you are interested in the Erlang system time at the
- time when the event occurred you can also save the time
+
+ <p>If you are interested in Erlang system time at the
+ time when the event occurred, you can also save the time
offset before or after saving the events using
<seealso marker="erlang#time_offset/0"><c>erlang:time_offset/0</c></seealso>.
Erlang monotonic time added with the time
offset corresponds to Erlang system time.</p>
+
<p>If you are executing in a mode where time offset
- may change and you want to be able to get the actual
- Erlang system time when the event occurred you can
+ can change, and you want to get the actual
+ Erlang system time when the event occurred, you can
save the time offset as a third element in the tuple
(the least significant element when comparing 3-tuples).</p>
</do>
@@ -814,16 +823,15 @@ EventTag = {Time, UMI}</code>
<title>Create a Unique Name</title>
<dont>
<p>
- use the values returned from <c>erlang:now/0</c>
- in order to create a name unique on the current
- runtime system instance.
+ Use the values returned from <c>erlang:now/0</c>
+ to create a name unique on the current runtime system instance.
</p>
</dont>
<do>
<p>
- use the value returned from
+ Use the value returned from
<seealso marker="erlang#unique_integer/0"><c>erlang:unique_integer/0</c></seealso>
- in order to create a name unique on the current runtime system
+ to create a name unique on the current runtime system
instance. If you only want positive integers, you can use
<seealso marker="erlang#unique_integer/1"><c>erlang:unique_integer([positive])</c></seealso>.
</p>
@@ -832,49 +840,63 @@ EventTag = {Time, UMI}</code>
<marker id="Dos_and_Donts_Seed_Random_Number_Generation_With_a_Unique_Value"/>
<section>
- <title>Seed Random Number Generation With a Unique Value</title>
+ <title>Seed Random Number Generation with a Unique Value</title>
<dont>
<p>
- seed random number generation using <c>erlang:now()</c>.
+ Seed random number generation using <c>erlang:now()</c>.
</p>
</dont>
<do>
<p>
- seed random number generation using a combination of
+ Seed random number generation using a combination of
<seealso marker="erlang#monotonic_time/0"><c>erlang:monotonic_time()</c></seealso>,
<seealso marker="erlang#time_offset/0"><c>erlang:time_offset()</c></seealso>,
- <seealso marker="erlang#unique_integer/0"><c>erlang:unique_integer()</c></seealso>, and other functionality.
+ <seealso marker="erlang#unique_integer/0"><c>erlang:unique_integer()</c></seealso>,
+ and other functionality.
</p>
</do>
</section>
- <p>To sum this section up: <em>Don't use <c>erlang:now/0</c>!</em></p>
+ <p>To sum up this section: <em>Do not use <c>erlang:now/0</c>.</em></p>
</section>
</section>
- <marker id="Supporting_Both_New_and_Old_OTP_Releases"/>
<section>
- <title>Supporting Both New and Old OTP Releases</title>
- <p>Your code may be required to be able to run on a variety
+ <marker id="Supporting_Both_New_and_Old_OTP_Releases"/>
+ <title>Support of Both New and Old OTP Releases</title>
+ <p>It can be required that your code must run on a variety
of OTP installations of different OTP releases. If so, you
- can not just use the new API out of the box, since it will
+ cannot use the new API out of the box, as it will
not be available on old pre OTP 18 releases. The solution
- is <em>not</em> to avoid using the new API, since your
- code then won't be able to benefit from the scalability
- and accuracy improvements made. Instead you want to use the
+ is <em>not</em> to avoid using the new API, as your
+ code then would not benefit from the scalability
+ and accuracy improvements made. Instead, use the
new API when available, and fall back on <c>erlang:now/0</c>
- when it is not available. Fortunately almost all of the new
- API can easily be implemented using existing primitives
- (except for
- <seealso marker="erlang#system_info_start_time"><c>erlang:system_info(start_time)</c></seealso>,
- <seealso marker="erlang#system_info_end_time"><c>erlang:system_info(end_time)</c></seealso>,
- <seealso marker="erlang#system_info_os_monotonic_time_source"><c>erlang:system_info(os_monotonic_time_source)</c></seealso>, and
- <seealso marker="erlang#system_info_os_system_time_source"><c>erlang:system_info(os_system_time_source)</c></seealso>).
- By wrapping the API with functions that fall back on
- <c>erlang:now/0</c> when the new API is not available,
- and using these wrappers instead of using the API directly
- the problem is solved. These wrappers can for example
+ when the new API is unavailable.</p>
+
+ <p>Fortunately most of the new API can easily be
+ implemented using existing primitives, except for:</p>
+
+ <list type="bulleted">
+ <item>
+ <seealso marker="erlang#system_info_start_time"><c>erlang:system_info(start_time)</c></seealso>
+ </item>
+ <item>
+ <seealso marker="erlang#system_info_end_time"><c>erlang:system_info(end_time)</c></seealso>
+ </item>
+ <item>
+ <seealso marker="erlang#system_info_os_monotonic_time_source"><c>erlang:system_info(os_monotonic_time_source)</c></seealso>
+ </item>
+ <item>
+ <seealso marker="erlang#system_info_os_system_time_source"><c>erlang:system_info(os_system_time_source)</c></seealso>)
+ </item>
+ </list>
+
+ <p>By wrapping the API with functions that fall back on
+ <c>erlang:now/0</c> when the new API is unavailable,
+ and using these wrappers instead of using the API directly,
+ the problem is solved. These wrappers can, for example,
be implemented as in
- <url href="time_compat.erl"><c>$ERL_TOP/erts/example/time_compat.erl</c></url>.</p>
+ <url href="time_compat.erl">$ERL_TOP/erts/example/time_compat.erl</url>.</p>
</section>
</chapter>
diff --git a/erts/emulator/beam/atom.names b/erts/emulator/beam/atom.names
index f9a2f3e33e..190e7817dc 100644
--- a/erts/emulator/beam/atom.names
+++ b/erts/emulator/beam/atom.names
@@ -321,6 +321,7 @@ atom ldflags
atom Le='=<'
atom lf
atom line
+atom line_delimiter
atom line_length
atom linked_in_driver
atom links
diff --git a/erts/emulator/beam/beam_debug.c b/erts/emulator/beam/beam_debug.c
index c774a70d4c..90985e4f53 100644
--- a/erts/emulator/beam/beam_debug.c
+++ b/erts/emulator/beam/beam_debug.c
@@ -79,7 +79,7 @@ erts_debug_breakpoint_2(BIF_ALIST_2)
{
Process* p = BIF_P;
Eterm MFA = BIF_ARG_1;
- Eterm bool = BIF_ARG_2;
+ Eterm boolean = BIF_ARG_2;
Eterm* tp;
Eterm mfa[3];
int i;
@@ -87,7 +87,7 @@ erts_debug_breakpoint_2(BIF_ALIST_2)
Eterm res;
BpFunctions f;
- if (bool != am_true && bool != am_false)
+ if (boolean != am_true && boolean != am_false)
goto error;
if (is_not_tuple(MFA)) {
@@ -124,7 +124,7 @@ erts_debug_breakpoint_2(BIF_ALIST_2)
erts_smp_thr_progress_block();
erts_bp_match_functions(&f, mfa, specified);
- if (bool == am_true) {
+ if (boolean == am_true) {
erts_set_debug_break(&f);
erts_install_breakpoints(&f);
erts_commit_staged_bp();
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c
index 4e3a1cef69..a8cc19ee1f 100644
--- a/erts/emulator/beam/bif.c
+++ b/erts/emulator/beam/bif.c
@@ -616,7 +616,7 @@ erts_queue_monitor_message(Process *p,
}
static BIF_RETTYPE
-local_pid_monitor(Process *p, Eterm target, Eterm mon_ref, int bool)
+local_pid_monitor(Process *p, Eterm target, Eterm mon_ref, int boolean)
{
BIF_RETTYPE ret;
Process *rp;
@@ -634,7 +634,7 @@ local_pid_monitor(Process *p, Eterm target, Eterm mon_ref, int bool)
if (!rp) {
erts_smp_proc_unlock(p, ERTS_PROC_LOCK_LINK);
p_locks &= ~ERTS_PROC_LOCK_LINK;
- if (bool)
+ if (boolean)
ret = am_false;
else
erts_queue_monitor_message(p, &p_locks,
@@ -643,7 +643,7 @@ local_pid_monitor(Process *p, Eterm target, Eterm mon_ref, int bool)
else {
ASSERT(rp != p);
- if (bool)
+ if (boolean)
ret = am_true;
erts_add_monitor(&ERTS_P_MONITORS(p), MON_ORIGIN, mon_ref, target, NIL);
@@ -4231,6 +4231,7 @@ BIF_RETTYPE list_to_pid_1(BIF_ALIST_1)
goto bad;
enp = erts_find_or_insert_node(dep->sysname, dep->creation);
+ ASSERT(enp != erts_this_node);
etp = (ExternalThing *) HAlloc(BIF_P, EXTERNAL_THING_HEAD_SIZE + 1);
etp->header = make_external_pid_header(1);
diff --git a/erts/emulator/beam/dist.c b/erts/emulator/beam/dist.c
index 23897a49ae..4846133aa6 100644
--- a/erts/emulator/beam/dist.c
+++ b/erts/emulator/beam/dist.c
@@ -45,6 +45,8 @@
#include "erl_thr_progress.h"
#include "dtrace-wrapper.h"
+#define DIST_CTL_DEFAULT_SIZE 64
+
/* Turn this on to get printouts of all distribution messages
* which go on the line
*/
@@ -66,9 +68,13 @@ static void bw(byte *buf, ErlDrvSizeT sz)
static void
dist_msg_dbg(ErtsDistExternal *edep, char *what, byte *buf, int sz)
{
+ ErtsHeapFactory factory;
+ DeclareTmpHeapNoproc(ctl_default,DIST_CTL_DEFAULT_SIZE);
+ Eterm* ctl = ctl_default;
byte *extp = edep->extp;
Eterm msg;
- Sint size = erts_decode_dist_ext_size(edep);
+ Sint ctl_len;
+ Sint size = ctl_len = erts_decode_dist_ext_size(edep);
if (size < 0) {
erts_fprintf(stderr,
"DIST MSG DEBUG: erts_decode_dist_ext_size(%s) failed:\n",
@@ -76,10 +82,9 @@ dist_msg_dbg(ErtsDistExternal *edep, char *what, byte *buf, int sz)
bw(buf, sz);
}
else {
- Eterm *hp;
ErlHeapFragment *mbuf = new_message_buffer(size);
- hp = mbuf->mem;
- msg = erts_decode_dist_ext(&hp, &mbuf->off_heap, edep);
+ erts_factory_static_init(&factory, ctl, ctl_len, &mbuf->off_heap);
+ msg = erts_decode_dist_ext(&factory, edep);
if (is_value(msg))
erts_fprintf(stderr, " %s: %T\n", what, msg);
else {
@@ -1136,7 +1141,6 @@ int erts_net_message(Port *prt,
byte *buf,
ErlDrvSizeT len)
{
-#define DIST_CTL_DEFAULT_SIZE 64
ErtsDistExternal ede;
byte *t;
Sint ctl_len;
@@ -1790,8 +1794,8 @@ erts_dsig_send(ErtsDSigData *dsdp, struct erts_dsig_send_context* ctx)
#ifdef ERTS_DIST_MSG_DBG
erts_fprintf(stderr, ">>%s CTL: %T\n", ctx->pass_through_size ? "P" : " ", ctx->ctl);
- if (is_value(msg))
- erts_fprintf(stderr, " MSG: %T\n", msg);
+ if (is_value(ctx->msg))
+ erts_fprintf(stderr, " MSG: %T\n", ctx->msg);
#endif
ctx->data_size = ctx->pass_through_size;
@@ -2572,7 +2576,9 @@ int distribution_info(int to, void *arg) /* Called by break handler */
}
for (dep = erts_not_connected_dist_entries; dep; dep = dep->next) {
- info_dist_entry(to, arg, dep, 0, 0);
+ if (dep != erts_this_dist_entry) {
+ info_dist_entry(to, arg, dep, 0, 0);
+ }
}
return(0);
@@ -2650,13 +2656,8 @@ BIF_RETTYPE setnode_2(BIF_ALIST_2)
if (!net_kernel)
goto error;
- /* By setting dist_entry==erts_this_dist_entry and DISTRIBUTION on
- net_kernel do_net_exist will be called when net_kernel
- is terminated !! */
- (void) ERTS_PROC_SET_DIST_ENTRY(net_kernel,
- ERTS_PROC_LOCK_MAIN,
- erts_this_dist_entry);
- erts_refc_inc(&erts_this_dist_entry->refc, 2);
+ /* By setting F_DISTRIBUTION on net_kernel,
+ * do_net_exist will be called when net_kernel is terminated !! */
net_kernel->flags |= F_DISTRIBUTION;
if (net_kernel != BIF_P)
@@ -3017,11 +3018,11 @@ BIF_RETTYPE nodes_1(BIF_ALIST_1)
erts_smp_rwmtx_rlock(&erts_dist_table_rwmtx);
- ASSERT(erts_no_of_not_connected_dist_entries >= 0);
+ ASSERT(erts_no_of_not_connected_dist_entries > 0);
ASSERT(erts_no_of_hidden_dist_entries >= 0);
ASSERT(erts_no_of_visible_dist_entries >= 0);
if(not_connected)
- length += erts_no_of_not_connected_dist_entries;
+ length += (erts_no_of_not_connected_dist_entries - 1);
if(hidden)
length += erts_no_of_hidden_dist_entries;
if(visible)
@@ -3043,8 +3044,10 @@ BIF_RETTYPE nodes_1(BIF_ALIST_1)
#endif
if(not_connected)
for(dep = erts_not_connected_dist_entries; dep; dep = dep->next) {
- result = CONS(hp, dep->sysname, result);
- hp += 2;
+ if (dep != erts_this_dist_entry) {
+ result = CONS(hp, dep->sysname, result);
+ hp += 2;
+ }
}
if(hidden)
for(dep = erts_hidden_dist_entries; dep; dep = dep->next) {
diff --git a/erts/emulator/beam/erl_alloc.c b/erts/emulator/beam/erl_alloc.c
index 55c164bf11..c3f4fe5a63 100644
--- a/erts/emulator/beam/erl_alloc.c
+++ b/erts/emulator/beam/erl_alloc.c
@@ -134,6 +134,7 @@ static ErtsAllocatorState_t binary_alloc_state;
static ErtsAllocatorState_t ets_alloc_state;
static ErtsAllocatorState_t driver_alloc_state;
static ErtsAllocatorState_t fix_alloc_state;
+static ErtsAllocatorState_t test_alloc_state;
typedef struct {
erts_smp_atomic32_t refc;
@@ -233,6 +234,7 @@ typedef struct {
struct au_init std_low_alloc;
struct au_init ll_low_alloc;
#endif
+ struct au_init test_alloc;
} erts_alc_hndl_args_init_t;
#define ERTS_AU_INIT__ {0, 0, 1, GOODFIT, DEFAULT_ALLCTR_INIT, {1,1,1,1}}
@@ -432,6 +434,33 @@ set_default_fix_alloc_opts(struct au_init *ip,
ip->init.util.acul = ERTS_ALC_DEFAULT_ACUL;
}
+static void
+set_default_test_alloc_opts(struct au_init *ip)
+{
+ SET_DEFAULT_ALLOC_OPTS(ip);
+ ip->enable = 0; /* Disabled by default */
+ ip->thr_spec = -1 * erts_no_schedulers;
+ ip->atype = AOFIRSTFIT;
+ ip->init.aoff.flavor = AOFF_BF;
+ ip->init.util.name_prefix = "test_";
+ ip->init.util.alloc_no = ERTS_ALC_A_TEST;
+ ip->init.util.mmbcs = 0; /* Main carrier size */
+ ip->init.util.ts = ERTS_ALC_MTA_TEST;
+ ip->init.util.acul = ERTS_ALC_DEFAULT_ACUL;
+
+ /* Use a constant minimal MBC size */
+#if ERTS_SA_MB_CARRIERS
+ ip->init.util.smbcs = ERTS_SACRR_UNIT_SZ;
+ ip->init.util.lmbcs = ERTS_SACRR_UNIT_SZ;
+ ip->init.util.sbct = ERTS_SACRR_UNIT_SZ;
+#else
+ ip->init.util.smbcs = 1 << 12;
+ ip->init.util.lmbcs = 1 << 12;
+ ip->init.util.sbct = 1 << 12;
+#endif
+}
+
+
#ifdef ERTS_SMP
static void
@@ -613,6 +642,7 @@ erts_alloc_init(int *argc, char **argv, ErtsAllocInitOpts *eaiop)
set_default_driver_alloc_opts(&init.driver_alloc);
set_default_fix_alloc_opts(&init.fix_alloc,
fix_type_sizes);
+ set_default_test_alloc_opts(&init.test_alloc);
if (argc && argv)
handle_args(argc, argv, &init);
@@ -772,6 +802,7 @@ erts_alloc_init(int *argc, char **argv, ErtsAllocInitOpts *eaiop)
set_au_allocator(ERTS_ALC_A_ETS, &init.ets_alloc, ncpu);
set_au_allocator(ERTS_ALC_A_DRIVER, &init.driver_alloc, ncpu);
set_au_allocator(ERTS_ALC_A_FIXED_SIZE, &init.fix_alloc, ncpu);
+ set_au_allocator(ERTS_ALC_A_TEST, &init.test_alloc, ncpu);
for (i = ERTS_ALC_A_MIN; i <= ERTS_ALC_A_MAX; i++) {
if (!erts_allctrs[i].alloc)
@@ -833,6 +864,10 @@ erts_alloc_init(int *argc, char **argv, ErtsAllocInitOpts *eaiop)
&init.fix_alloc,
&fix_alloc_state);
+ start_au_allocator(ERTS_ALC_A_TEST,
+ &init.test_alloc,
+ &test_alloc_state);
+
erts_mtrace_install_wrapper_functions();
extra_block_size += erts_instr_init(init.instr.stat, init.instr.map);
@@ -1418,6 +1453,7 @@ handle_args(int *argc, char **argv, erts_alc_hndl_args_init_t *init)
&init->fix_alloc,
&init->sl_alloc,
&init->temp_alloc
+ /* test_alloc not affected by +Mea??? or +Mu??? */
};
int aui_sz = (int) sizeof(aui)/sizeof(aui[0]);
char *arg;
@@ -1508,6 +1544,9 @@ handle_args(int *argc, char **argv, erts_alc_hndl_args_init_t *init)
case 'T':
handle_au_arg(&init->temp_alloc, &argv[i][3], argv, &i, 0);
break;
+ case 'Z':
+ handle_au_arg(&init->test_alloc, &argv[i][3], argv, &i, 0);
+ break;
case 'Y': { /* sys_alloc */
if (has_prefix("tt", param+2)) {
/* set trim threshold */
@@ -2222,11 +2261,12 @@ erts_memory(int *print_to_p, void *print_to_arg, void *proc, Eterm earg)
return am_badarg;
}
- /* All alloc_util allocators *have* to be enabled */
+ /* All alloc_util allocators *have* to be enabled, except test_alloc */
for (ai = ERTS_ALC_A_MIN; ai <= ERTS_ALC_A_MAX; ai++) {
switch (ai) {
case ERTS_ALC_A_SYSTEM:
+ case ERTS_ALC_A_TEST:
break;
default:
if (!erts_allctrs_info[ai].enabled
@@ -2267,6 +2307,8 @@ erts_memory(int *print_to_p, void *print_to_arg, void *proc, Eterm earg)
* contain any allocated memory.
*/
continue;
+ case ERTS_ALC_A_TEST:
+ continue;
case ERTS_ALC_A_EHEAP:
save = &size.processes;
break;
@@ -2675,14 +2717,17 @@ erts_alloc_util_allocators(void *proc)
/*
* Currently all allocators except sys_alloc are
* alloc_util allocators.
+ * Also hide test_alloc which is disabled by default
+ * and only intended for our own testing.
*/
- sz = ((ERTS_ALC_A_MAX + 1 - ERTS_ALC_A_MIN) - 1)*2;
+ sz = ((ERTS_ALC_A_MAX + 1 - ERTS_ALC_A_MIN) - 2)*2;
ASSERT(sz > 0);
hp = HAlloc((Process *) proc, sz);
res = NIL;
for (i = ERTS_ALC_A_MAX; i >= ERTS_ALC_A_MIN; i--) {
switch (i) {
case ERTS_ALC_A_SYSTEM:
+ case ERTS_ALC_A_TEST:
break;
default: {
char *alc_str = (char *) ERTS_ALC_A2AD(i);
@@ -3566,6 +3611,41 @@ UWord erts_alc_test(UWord op, UWord a1, UWord a2, UWord a3)
#else
case 0xf13: return (UWord) 0;
#endif
+ case 0xf14: return (UWord) erts_alloc(ERTS_ALC_T_TEST, (Uint)a1);
+
+ case 0xf15: erts_free(ERTS_ALC_T_TEST, (void*)a1); return 0;
+
+ case 0xf16: {
+ Uint extra_hdr_sz = UNIT_CEILING((Uint)a1);
+ ErtsAllocatorThrSpec_t* ts = &erts_allctr_thr_spec[ERTS_ALC_A_TEST];
+ Uint offset = ts->allctr[0]->mbc_header_size;
+ void* orig_creating_mbc = ts->allctr[0]->creating_mbc;
+ void* orig_destroying_mbc = ts->allctr[0]->destroying_mbc;
+ void* new_creating_mbc = *(void**)a2; /* inout arg */
+ void* new_destroying_mbc = *(void**)a3; /* inout arg */
+ int i;
+
+ for (i=0; i < ts->size; i++) {
+ Allctr_t* ap = ts->allctr[i];
+ if (ap->mbc_header_size != offset
+ || ap->creating_mbc != orig_creating_mbc
+ || ap->destroying_mbc != orig_destroying_mbc
+ || ap->mbc_list.first != NULL)
+ return -1;
+ }
+ for (i=0; i < ts->size; i++) {
+ ts->allctr[i]->mbc_header_size += extra_hdr_sz;
+ ts->allctr[i]->creating_mbc = new_creating_mbc;
+ ts->allctr[i]->destroying_mbc = new_destroying_mbc;
+ }
+ *(void**)a2 = orig_creating_mbc;
+ *(void**)a3 = orig_destroying_mbc;
+ return offset;
+ }
+ case 0xf17: {
+ ErtsAllocatorThrSpec_t* ts = &erts_allctr_thr_spec[ERTS_ALC_A_TEST];
+ return ts->allctr[0]->largest_mbc_size;
+ }
default:
break;
}
diff --git a/erts/emulator/beam/erl_alloc.types b/erts/emulator/beam/erl_alloc.types
index b1d511ab78..1ecebdeb07 100644
--- a/erts/emulator/beam/erl_alloc.types
+++ b/erts/emulator/beam/erl_alloc.types
@@ -112,7 +112,7 @@ allocator STANDARD_LOW false std_low_alloc
allocator BINARY true binary_alloc
allocator DRIVER true driver_alloc
-
+allocator TEST true test_alloc
# --- Class declarations -----------------------------------------------------
#
@@ -456,4 +456,7 @@ type CON_VPRINTF_BUF TEMPORARY SYSTEM con_vprintf_buf
+endif
+# This type should only be used for test
+type TEST TEST SYSTEM testing
+
# ----------------------------------------------------------------------------
diff --git a/erts/emulator/beam/erl_alloc_util.c b/erts/emulator/beam/erl_alloc_util.c
index 236ee35d18..8229a15824 100644
--- a/erts/emulator/beam/erl_alloc_util.c
+++ b/erts/emulator/beam/erl_alloc_util.c
@@ -1437,6 +1437,16 @@ erts_alcu_fix_alloc_shrink(Allctr_t *allctr, erts_aint32_t flgs)
static void dealloc_carrier(Allctr_t *allctr, Carrier_t *crr, int superaligned);
+static ERTS_INLINE void
+dealloc_mbc(Allctr_t *allctr, Carrier_t *crr)
+{
+ ASSERT(IS_MB_CARRIER(crr));
+ if (allctr->destroying_mbc)
+ allctr->destroying_mbc(allctr, crr);
+
+ dealloc_carrier(allctr, crr, 1);
+}
+
#ifdef ERTS_SMP
static ERTS_INLINE Allctr_t*
@@ -3149,7 +3159,7 @@ cpool_fetch(Allctr_t *allctr, UWord size)
cpool_entrance = sentinel;
cpdp = cpool_aint2cpd(cpool_read(&cpool_entrance->prev));
if (cpdp == sentinel)
- return NULL;
+ goto check_dc_list;
}
has_passed_sentinel = 0;
@@ -3160,18 +3170,18 @@ cpool_fetch(Allctr_t *allctr, UWord size)
if (cpool_entrance == sentinel) {
cpdp = cpool_aint2cpd(cpool_read(&cpdp->prev));
if (cpdp == sentinel)
- return NULL;
+ break;
}
i = 0; /* Last one to inspect */
}
else if (cpdp == sentinel) {
if (has_passed_sentinel) {
/* We been here before. cpool_entrance must have been removed */
- return NULL;
+ break;
}
cpdp = cpool_aint2cpd(cpool_read(&cpdp->prev));
if (cpdp == sentinel)
- return NULL;
+ break;
has_passed_sentinel = 1;
}
crr = (Carrier_t *)(((char *)cpdp) - offsetof(Carrier_t, cpool));
@@ -3195,10 +3205,12 @@ cpool_fetch(Allctr_t *allctr, UWord size)
return NULL;
}
+check_dc_list:
/* Last; check our own pending dealloc carrier list... */
crr = allctr->cpool.dc_list.last;
while (crr) {
if (erts_atomic_read_nob(&crr->cpool.max_size) >= size) {
+ Block_t* blk;
unlink_carrier(&allctr->cpool.dc_list, crr);
#ifdef ERTS_ALC_CPOOL_DEBUG
ERTS_ALC_CPOOL_ASSERT(erts_smp_atomic_xchg_nob(&crr->allctr,
@@ -3207,6 +3219,9 @@ cpool_fetch(Allctr_t *allctr, UWord size)
#else
erts_smp_atomic_set_nob(&crr->allctr, ((erts_aint_t) allctr));
#endif
+ blk = MBC_TO_FIRST_BLK(allctr, crr);
+ ASSERT(FBLK_TO_MBC(blk) == crr);
+ allctr->link_free_block(allctr, blk);
return crr;
}
crr = crr->prev;
@@ -3237,7 +3252,7 @@ check_pending_dealloc_carrier(Allctr_t *allctr,
dcrr = crr;
crr = crr->next;
- dealloc_carrier(allctr, dcrr, 1);
+ dealloc_mbc(allctr, dcrr);
i++;
} while (crr && i < ERTS_ALC_MAX_DEALLOC_CARRIER);
@@ -3268,18 +3283,20 @@ static void
schedule_dealloc_carrier(Allctr_t *allctr, Carrier_t *crr)
{
Allctr_t *orig_allctr;
+ Block_t *blk;
int check_pending_dealloc;
erts_aint_t max_size;
+ ASSERT(IS_MB_CARRIER(crr));
+
if (!ERTS_ALC_IS_CPOOL_ENABLED(allctr)) {
- dealloc_carrier(allctr, crr, 1);
+ dealloc_mbc(allctr, crr);
return;
}
orig_allctr = crr->cpool.orig_allctr;
if (allctr != orig_allctr) {
- Block_t *blk = MBC_TO_FIRST_BLK(allctr, crr);
int cinit = orig_allctr->dd.ix - allctr->dd.ix;
/*
@@ -3296,6 +3313,7 @@ schedule_dealloc_carrier(Allctr_t *allctr, Carrier_t *crr)
* since the block is an mbc block that is free and last
* in the carrier.
*/
+ blk = MBC_TO_FIRST_BLK(allctr, crr);
ERTS_ALC_CPOOL_ASSERT(IS_FREE_LAST_MBC_BLK(blk));
ERTS_ALC_CPOOL_ASSERT(IS_MBC_FIRST_ABLK(allctr, blk));
@@ -3315,11 +3333,13 @@ schedule_dealloc_carrier(Allctr_t *allctr, Carrier_t *crr)
if (crr->cpool.thr_prgr == ERTS_THR_PRGR_INVALID
|| erts_thr_progress_has_reached(crr->cpool.thr_prgr)) {
- dealloc_carrier(allctr, crr, 1);
+ dealloc_mbc(allctr, crr);
return;
}
- max_size = (erts_aint_t) allctr->largest_fblk_in_mbc(allctr, crr);
+ blk = MBC_TO_FIRST_BLK(allctr, crr);
+ ASSERT(IS_FREE_LAST_MBC_BLK(blk));
+ max_size = (erts_aint_t) MBC_FBLK_SZ(blk);
erts_atomic_set_nob(&crr->cpool.max_size, max_size);
crr->next = NULL;
@@ -3894,9 +3914,6 @@ destroy_carrier(Allctr_t *allctr, Block_t *blk, Carrier_t **busy_pcrr_pp)
}
#endif
- if (allctr->destroying_mbc)
- (*allctr->destroying_mbc)(allctr, crr);
-
#ifdef ERTS_SMP
if (busy_pcrr_pp && *busy_pcrr_pp) {
ERTS_ALC_CPOOL_ASSERT(*busy_pcrr_pp == crr);
@@ -3920,12 +3937,15 @@ destroy_carrier(Allctr_t *allctr, Block_t *blk, Carrier_t **busy_pcrr_pp)
else
#endif
STAT_SYS_ALLOC_MBC_FREE(allctr, crr_sz);
+
+ if (allctr->remove_mbc)
+ allctr->remove_mbc(allctr, crr);
}
#ifdef ERTS_SMP
schedule_dealloc_carrier(allctr, crr);
#else
- dealloc_carrier(allctr, crr, 1);
+ dealloc_mbc(allctr, crr);
#endif
}
}
@@ -6054,6 +6074,16 @@ erts_alcu_test(UWord op, UWord a1, UWord a2)
case 0x023: return (UWord) 0;
case 0x024: return (UWord) 0;
#endif
+ case 0x025: /* UMEM2BLK_TEST*/
+#ifdef DEBUG
+# ifdef HARD_DEBUG
+ return (UWord)UMEM2BLK(a1-3*sizeof(UWord));
+# else
+ return (UWord)UMEM2BLK(a1-2*sizeof(UWord));
+# endif
+#else
+ return (UWord)UMEM2BLK(a1);
+#endif
default: ASSERT(0); return ~((UWord) 0);
}
diff --git a/erts/emulator/beam/erl_alloc_util.h b/erts/emulator/beam/erl_alloc_util.h
index df1f0aa65a..f4a2ae7ff3 100644
--- a/erts/emulator/beam/erl_alloc_util.h
+++ b/erts/emulator/beam/erl_alloc_util.h
@@ -277,7 +277,7 @@ typedef struct ErtsDoubleLink_t_ {
typedef struct {
erts_atomic_t next;
erts_atomic_t prev;
- Allctr_t *orig_allctr;
+ Allctr_t *orig_allctr; /* read-only while carrier is alive */
ErtsThrPrgrVal thr_prgr;
erts_atomic_t max_size;
UWord abandon_limit;
diff --git a/erts/emulator/beam/erl_ao_firstfit_alloc.c b/erts/emulator/beam/erl_ao_firstfit_alloc.c
index 7c2a5c3323..19420af8ab 100644
--- a/erts/emulator/beam/erl_ao_firstfit_alloc.c
+++ b/erts/emulator/beam/erl_ao_firstfit_alloc.c
@@ -209,7 +209,9 @@ static Block_t* aoff_get_free_block(Allctr_t *, Uint, Block_t *, Uint);
static void aoff_link_free_block(Allctr_t *, Block_t*);
static void aoff_unlink_free_block(Allctr_t *allctr, Block_t *del);
static void aoff_creating_mbc(Allctr_t*, Carrier_t*);
+#ifdef DEBUG
static void aoff_destroying_mbc(Allctr_t*, Carrier_t*);
+#endif
static void aoff_add_mbc(Allctr_t*, Carrier_t*);
static void aoff_remove_mbc(Allctr_t*, Carrier_t*);
static UWord aoff_largest_fblk_in_mbc(Allctr_t*, Carrier_t*);
@@ -271,7 +273,11 @@ erts_aoffalc_start(AOFFAllctr_t *alc,
allctr->get_next_mbc_size = NULL;
allctr->creating_mbc = aoff_creating_mbc;
+#ifdef DEBUG
allctr->destroying_mbc = aoff_destroying_mbc;
+#else
+ allctr->destroying_mbc = NULL;
+#endif
allctr->add_mbc = aoff_add_mbc;
allctr->remove_mbc = aoff_remove_mbc;
allctr->largest_fblk_in_mbc = aoff_largest_fblk_in_mbc;
@@ -885,17 +891,18 @@ static void aoff_creating_mbc(Allctr_t *allctr, Carrier_t *carrier)
HARD_CHECK_TREE(NULL, 0, *root, 0);
}
+#define IS_CRR_IN_TREE(CRR,ROOT) \
+ ((CRR)->rbt_node.parent || (ROOT) == &(CRR)->rbt_node)
+
+#ifdef DEBUG
static void aoff_destroying_mbc(Allctr_t *allctr, Carrier_t *carrier)
{
AOFFAllctr_t *alc = (AOFFAllctr_t *) allctr;
AOFF_Carrier_t *crr = (AOFF_Carrier_t*) carrier;
- AOFF_RBTree_t *root = alc->mbc_root;
- if (crr->rbt_node.parent || &crr->rbt_node == root) {
- aoff_remove_mbc(allctr, carrier);
- }
- /*else already removed */
+ ASSERT(!IS_CRR_IN_TREE(crr, alc->mbc_root));
}
+#endif
static void aoff_add_mbc(Allctr_t *allctr, Carrier_t *carrier)
{
@@ -903,6 +910,7 @@ static void aoff_add_mbc(Allctr_t *allctr, Carrier_t *carrier)
AOFF_Carrier_t *crr = (AOFF_Carrier_t*) carrier;
AOFF_RBTree_t **root = &alc->mbc_root;
+ ASSERT(!IS_CRR_IN_TREE(crr, *root));
HARD_CHECK_TREE(NULL, 0, *root, 0);
/* Link carrier in address order tree
@@ -919,6 +927,10 @@ static void aoff_remove_mbc(Allctr_t *allctr, Carrier_t *carrier)
AOFF_RBTree_t **root = &alc->mbc_root;
ASSERT(allctr == ERTS_ALC_CARRIER_TO_ALLCTR(carrier));
+
+ if (!IS_CRR_IN_TREE(crr,*root))
+ return;
+
HARD_CHECK_TREE(NULL, 0, *root, 0);
rbt_delete(root, &crr->rbt_node);
diff --git a/erts/emulator/beam/erl_bif_port.c b/erts/emulator/beam/erl_bif_port.c
index 3ff54c7a60..e47d7bcbbb 100644
--- a/erts/emulator/beam/erl_bif_port.c
+++ b/erts/emulator/beam/erl_bif_port.c
@@ -1329,7 +1329,8 @@ BIF_RETTYPE decode_packet_3(BIF_ALIST_3)
ErlSubBin* rest;
Eterm res;
Eterm options;
- int code;
+ int code;
+ char delimiter = '\n';
if (!is_binary(BIF_ARG_2) ||
(!is_list(BIF_ARG_3) && !is_nil(BIF_ARG_3))) {
@@ -1370,6 +1371,11 @@ BIF_RETTYPE decode_packet_3(BIF_ALIST_3)
case am_line_length:
trunc_len = val;
goto next_option;
+ case am_line_delimiter:
+ if (type == TCP_PB_LINE_LF && val >= 0 && val <= 255) {
+ delimiter = (char)val;
+ goto next_option;
+ }
}
}
}
@@ -1390,7 +1396,7 @@ BIF_RETTYPE decode_packet_3(BIF_ALIST_3)
pca.aligned_ptr = bin_ptr;
}
packet_sz = packet_get_length(type, (char*)pca.aligned_ptr, pca.bin_sz,
- max_plen, trunc_len, &http_state);
+ max_plen, trunc_len, delimiter, &http_state);
if (!(packet_sz > 0 && packet_sz <= pca.bin_sz)) {
if (packet_sz < 0) {
goto error;
diff --git a/erts/emulator/beam/erl_driver.h b/erts/emulator/beam/erl_driver.h
index 6b406d069c..dbb4d719c1 100644
--- a/erts/emulator/beam/erl_driver.h
+++ b/erts/emulator/beam/erl_driver.h
@@ -696,8 +696,8 @@ EXTERN int driver_dl_close(void *);
EXTERN char *driver_dl_error(void);
/* environment */
-EXTERN int erl_drv_putenv(char *key, char *value);
-EXTERN int erl_drv_getenv(char *key, char *value, size_t *value_size);
+EXTERN int erl_drv_putenv(const char *key, char *value);
+EXTERN int erl_drv_getenv(const char *key, char *value, size_t *value_size);
#ifdef __OSE__
typedef ErlDrvUInt ErlDrvOseEventId;
diff --git a/erts/emulator/beam/erl_gc.c b/erts/emulator/beam/erl_gc.c
index d2604f1595..2f21111a2e 100644
--- a/erts/emulator/beam/erl_gc.c
+++ b/erts/emulator/beam/erl_gc.c
@@ -1237,6 +1237,7 @@ major_collection(Process* p, int need, Eterm* objv, int nobj, Uint *recl)
Uint oh_size = (char *) OLD_HTOP(p) - oh;
Uint n;
Uint new_sz;
+ int done;
/*
* Do a fullsweep GC. First figure out the size of the heap
@@ -1440,6 +1441,8 @@ major_collection(Process* p, int need, Eterm* objv, int nobj, Uint *recl)
*recl += size_before - (HEAP_TOP(p) - HEAP_START(p));
+ remove_message_buffers(p);
+
{
ErlMessage *msgp;
@@ -1458,15 +1461,21 @@ major_collection(Process* p, int need, Eterm* objv, int nobj, Uint *recl)
}
}
- adjust_after_fullsweep(p, need, objv, nobj);
-
-#ifdef HARDDEBUG
- disallow_heap_frag_ref_in_heap(p);
-#endif
- remove_message_buffers(p);
+ if (MBUF(p)) {
+ /* This is a very rare case when distributed messages copied above
+ * contained maps so big they did not fit on the heap causing the
+ * factory to create heap frags.
+ * Solution: Trigger a minor gc (without tenuring)
+ */
+ HIGH_WATER(p) = HEAP_START(p);
+ done = 0;
+ } else {
+ adjust_after_fullsweep(p, need, objv, nobj);
+ done = 1;
+ }
ErtsGcQuickSanityCheck(p);
- return 1; /* We are done. */
+ return done;
}
static void
@@ -1955,7 +1964,18 @@ collect_heap_frags(Process* p, Eterm* n_hstart, Eterm* n_htop,
if (p->dictionary != NULL) {
disallow_heap_frag_ref(p, n_htop, p->dictionary->data, p->dictionary->used);
}
- disallow_heap_frag_ref_in_heap(p);
+ /* OTP-18: Actually we do allow references from heap to heap fragments now.
+ This can happen when doing "binary_to_term" with a "fat" map contained
+ in another term. A "fat" map is a hashmap with higher heap demand than
+ first estimated by "binary_to_term" causing the factory to allocate
+ additional heap (fragments) for the hashmap tree nodes.
+ Run map_SUITE:t_gc_rare_map_overflow to provoke this.
+
+ Inverted references like this does not matter however. The copy done
+ below by move_one_area() with move markers in the fragments and the
+ sweeping done later by the GC should make everything ok in the end.
+ */
+ /***disallow_heap_frag_ref_in_heap(p);***/
#endif
/*
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c
index add4a66f90..d7a2076d85 100644
--- a/erts/emulator/beam/erl_nif.c
+++ b/erts/emulator/beam/erl_nif.c
@@ -1173,6 +1173,7 @@ ErlNifTid enif_thread_self(void) { return erl_drv_thread_self(); }
int enif_equal_tids(ErlNifTid tid1, ErlNifTid tid2) { return erl_drv_equal_tids(tid1,tid2); }
void enif_thread_exit(void *resp) { erl_drv_thread_exit(resp); }
int enif_thread_join(ErlNifTid tid, void **respp) { return erl_drv_thread_join(tid,respp); }
+int enif_getenv(const char *key, char *value, size_t *value_size) { return erl_drv_getenv(key, value, value_size); }
int enif_fprintf(void* filep, const char* format, ...)
{
diff --git a/erts/emulator/beam/erl_nif.h b/erts/emulator/beam/erl_nif.h
index 7d880126f8..5e39343e9b 100644
--- a/erts/emulator/beam/erl_nif.h
+++ b/erts/emulator/beam/erl_nif.h
@@ -48,9 +48,10 @@
** add ErlNifEntry options
** add ErlNifFunc flags
** 2.8: 18.0 add enif_has_pending_exception
+** 2.9: 18.2 enif_getenv
*/
#define ERL_NIF_MAJOR_VERSION 2
-#define ERL_NIF_MINOR_VERSION 8
+#define ERL_NIF_MINOR_VERSION 9
/*
* The emulator will refuse to load a nif-lib with a major version
@@ -231,6 +232,7 @@ typedef enum {
# define ERL_NIF_API_FUNC_DECL(RET_TYPE, NAME, ARGS) RET_TYPE (*NAME) ARGS
typedef struct {
# include "erl_nif_api_funcs.h"
+ void* erts_alc_test;
} TWinDynNifCallbacks;
extern TWinDynNifCallbacks WinDynNifCallbacks;
# undef ERL_NIF_API_FUNC_DECL
diff --git a/erts/emulator/beam/erl_nif_api_funcs.h b/erts/emulator/beam/erl_nif_api_funcs.h
index 2f2180e1aa..08b9afc6af 100644
--- a/erts/emulator/beam/erl_nif_api_funcs.h
+++ b/erts/emulator/beam/erl_nif_api_funcs.h
@@ -159,6 +159,7 @@ ERL_NIF_API_FUNC_DECL(int, enif_map_iterator_get_pair, (ErlNifEnv *env, ErlNifMa
ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_schedule_nif,(ErlNifEnv*,const char*,int,ERL_NIF_TERM (*)(ErlNifEnv*,int,const ERL_NIF_TERM[]),int,const ERL_NIF_TERM[]));
ERL_NIF_API_FUNC_DECL(int, enif_has_pending_exception, (ErlNifEnv *env, ERL_NIF_TERM* reason));
ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM, enif_raise_exception, (ErlNifEnv *env, ERL_NIF_TERM reason));
+ERL_NIF_API_FUNC_DECL(int,enif_getenv,(const char* key, char* value, size_t* value_size));
/*
** ADD NEW ENTRIES HERE (before this comment) !!!
@@ -310,6 +311,7 @@ ERL_NIF_API_FUNC_DECL(int,enif_is_on_dirty_scheduler,(ErlNifEnv*));
# define enif_schedule_nif ERL_NIF_API_FUNC_MACRO(enif_schedule_nif)
# define enif_has_pending_exception ERL_NIF_API_FUNC_MACRO(enif_has_pending_exception)
# define enif_raise_exception ERL_NIF_API_FUNC_MACRO(enif_raise_exception)
+# define enif_getenv ERL_NIF_API_FUNC_MACRO(enif_getenv)
/*
** ADD NEW ENTRIES HERE (before this comment)
diff --git a/erts/emulator/beam/erl_node_tables.c b/erts/emulator/beam/erl_node_tables.c
index 2fb790b953..a7d0511bf9 100644
--- a/erts/emulator/beam/erl_node_tables.c
+++ b/erts/emulator/beam/erl_node_tables.c
@@ -37,18 +37,18 @@ erts_smp_rwmtx_t erts_node_table_rwmtx;
DistEntry *erts_hidden_dist_entries;
DistEntry *erts_visible_dist_entries;
-DistEntry *erts_not_connected_dist_entries;
+DistEntry *erts_not_connected_dist_entries; /* including erts_this_dist_entry */
Sint erts_no_of_hidden_dist_entries;
Sint erts_no_of_visible_dist_entries;
-Sint erts_no_of_not_connected_dist_entries;
+Sint erts_no_of_not_connected_dist_entries; /* including erts_this_dist_entry */
DistEntry *erts_this_dist_entry;
ErlNode *erts_this_node;
char erts_this_node_sysname_BUFFER[256],
*erts_this_node_sysname = "uninitialized yet";
-static Uint node_entries;
-static Uint dist_entries;
+static Uint node_entries = 0;
+static Uint dist_entries = 0;
static int references_atoms_need_init = 1;
@@ -91,9 +91,6 @@ dist_table_alloc(void *dep_tmpl)
erts_smp_rwmtx_opt_t rwmtx_opt = ERTS_SMP_RWMTX_OPT_DEFAULT_INITER;
rwmtx_opt.type = ERTS_SMP_RWMTX_TYPE_FREQUENT_READ;
- if(((DistEntry *) dep_tmpl) == erts_this_dist_entry)
- return dep_tmpl;
-
sysname = ((DistEntry *) dep_tmpl)->sysname;
chnl_nr = make_small((Uint) atom_val(sysname));
dep = (DistEntry *) erts_alloc(ERTS_ALC_T_DIST_ENTRY, sizeof(DistEntry));
@@ -132,7 +129,9 @@ dist_table_alloc(void *dep_tmpl)
/* Link in */
- /* All new dist entries are "not connected" */
+ /* All new dist entries are "not connected".
+ * erts_this_dist_entry is also always included among "not connected"
+ */
dep->next = erts_not_connected_dist_entries;
if(erts_not_connected_dist_entries) {
ASSERT(erts_not_connected_dist_entries->prev == NULL);
@@ -149,9 +148,6 @@ dist_table_free(void *vdep)
{
DistEntry *dep = (DistEntry *) vdep;
- if(dep == erts_this_dist_entry)
- return;
-
ASSERT(is_nil(dep->cid));
ASSERT(dep->nlinks == NULL);
ASSERT(dep->node_links == NULL);
@@ -186,7 +182,7 @@ dist_table_free(void *vdep)
#endif
erts_free(ERTS_ALC_T_DIST_ENTRY, (void *) dep);
- ASSERT(dist_entries > 1);
+ ASSERT(dist_entries > 0);
dist_entries--;
}
@@ -306,7 +302,7 @@ static void try_delete_dist_entry(void *vdep)
* thread incremented refc twice. Once for the new reference
* and once for this thread.
*
- * If refc reach -1, noone has used the entry since we
+ * If refc reach -1, no one has used the entry since we
* set up the timer. Delete the entry.
*
* If refc reach 0, the entry is currently not in use
@@ -369,8 +365,7 @@ erts_dist_table_size(void)
ASSERT(dist_entries == (erts_no_of_visible_dist_entries
+ erts_no_of_hidden_dist_entries
- + erts_no_of_not_connected_dist_entries
- + 1 /* erts_this_dist_entry */));
+ + erts_no_of_not_connected_dist_entries));
#endif
res = (hash_table_sz(&erts_dist_table)
@@ -543,9 +538,6 @@ node_table_alloc(void *venp_tmpl)
{
ErlNode *enp;
- if(((ErlNode *) venp_tmpl) == erts_this_node)
- return venp_tmpl;
-
enp = (ErlNode *) erts_alloc(ERTS_ALC_T_NODE_ENTRY, sizeof(ErlNode));
node_entries++;
@@ -563,8 +555,7 @@ node_table_free(void *venp)
{
ErlNode *enp = (ErlNode *) venp;
- if(enp == erts_this_node)
- return;
+ ERTS_SMP_LC_ASSERT(enp != erts_this_node || erts_thr_progress_is_blocking());
erts_deref_dist_entry(enp->dist_entry);
#ifdef DEBUG
@@ -572,7 +563,7 @@ node_table_free(void *venp)
#endif
erts_free(ERTS_ALC_T_NODE_ENTRY, venp);
- ASSERT(node_entries > 1);
+ ASSERT(node_entries > 0);
node_entries--;
}
@@ -650,7 +641,7 @@ static void try_delete_node(void *venp)
* thread incremented refc twice. Once for the new reference
* and once for this thread.
*
- * If refc reach -1, noone has used the entry since we
+ * If refc reach -1, no one has used the entry since we
* set up the timer. Delete the entry.
*
* If refc reach 0, the entry is currently not in use
@@ -747,25 +738,20 @@ void erts_print_node_info(int to,
void
erts_set_this_node(Eterm sysname, Uint creation)
{
- erts_smp_rwmtx_rwlock(&erts_node_table_rwmtx);
- erts_smp_rwmtx_rwlock(&erts_dist_table_rwmtx);
+ ERTS_SMP_LC_ASSERT(erts_thr_progress_is_blocking());
+ ASSERT(erts_refc_read(&erts_this_dist_entry->refc, 2));
- (void) hash_erase(&erts_dist_table, (void *) erts_this_dist_entry);
- erts_this_dist_entry->sysname = sysname;
- erts_this_dist_entry->creation = creation;
- (void) hash_put(&erts_dist_table, (void *) erts_this_dist_entry);
+ if (erts_refc_dectest(&erts_this_node->refc, 0) == 0)
+ try_delete_node(erts_this_node);
- (void) hash_erase(&erts_node_table, (void *) erts_this_node);
- erts_this_node->sysname = sysname;
- erts_this_node->creation = creation;
- erts_this_node_sysname = erts_this_node_sysname_BUFFER;
- erts_snprintf(erts_this_node_sysname, sizeof(erts_this_node_sysname_BUFFER),
- "%T", sysname);
- (void) hash_put(&erts_node_table, (void *) erts_this_node);
+ if (erts_refc_dectest(&erts_this_dist_entry->refc, 0) == 0)
+ try_delete_dist_entry(erts_this_dist_entry);
- erts_smp_rwmtx_rwunlock(&erts_dist_table_rwmtx);
- erts_smp_rwmtx_rwunlock(&erts_node_table_rwmtx);
+ erts_this_node = NULL; /* to make sure refc is bumped for this node */
+ erts_this_node = erts_find_or_insert_node(sysname, creation);
+ erts_this_dist_entry = erts_this_node->dist_entry;
+ erts_refc_inc(&erts_this_dist_entry->refc, 2);
}
Uint
@@ -782,6 +768,7 @@ void erts_init_node_tables(int dd_sec)
{
erts_smp_rwmtx_opt_t rwmtx_opt = ERTS_SMP_RWMTX_OPT_DEFAULT_INITER;
HashFunctions f;
+ ErlNode node_tmpl;
if (dd_sec == ERTS_NODE_TAB_DELAY_GC_INFINITY)
node_tab_delete_delay = (ErtsMonotonicTime) -1;
@@ -793,16 +780,21 @@ void erts_init_node_tables(int dd_sec)
rwmtx_opt.type = ERTS_SMP_RWMTX_TYPE_FREQUENT_READ;
rwmtx_opt.lived = ERTS_SMP_RWMTX_LONG_LIVED;
+ erts_smp_rwmtx_init_opt(&erts_node_table_rwmtx, &rwmtx_opt, "node_table");
+ erts_smp_rwmtx_init_opt(&erts_dist_table_rwmtx, &rwmtx_opt, "dist_table");
+
f.hash = (H_FUN) dist_table_hash;
f.cmp = (HCMP_FUN) dist_table_cmp;
f.alloc = (HALLOC_FUN) dist_table_alloc;
f.free = (HFREE_FUN) dist_table_free;
-
- erts_this_dist_entry = erts_alloc(ERTS_ALC_T_DIST_ENTRY, sizeof(DistEntry));
- dist_entries = 1;
-
hash_init(ERTS_ALC_T_DIST_TABLE, &erts_dist_table, "dist_table", 11, f);
+ f.hash = (H_FUN) node_table_hash;
+ f.cmp = (HCMP_FUN) node_table_cmp;
+ f.alloc = (HALLOC_FUN) node_table_alloc;
+ f.free = (HFREE_FUN) node_table_free;
+ hash_init(ERTS_ALC_T_NODE_TABLE, &erts_node_table, "node_table", 11, f);
+
erts_hidden_dist_entries = NULL;
erts_visible_dist_entries = NULL;
erts_not_connected_dist_entries = NULL;
@@ -810,69 +802,23 @@ void erts_init_node_tables(int dd_sec)
erts_no_of_visible_dist_entries = 0;
erts_no_of_not_connected_dist_entries = 0;
- erts_this_dist_entry->next = NULL;
- erts_this_dist_entry->prev = NULL;
- erts_refc_init(&erts_this_dist_entry->refc, 1); /* erts_this_node */
-
- erts_smp_rwmtx_init_opt_x(&erts_this_dist_entry->rwmtx,
- &rwmtx_opt,
- "dist_entry",
- make_small(ERST_INTERNAL_CHANNEL_NO));
- erts_this_dist_entry->sysname = am_Noname;
- erts_this_dist_entry->cid = NIL;
- erts_this_dist_entry->connection_id = 0;
- erts_this_dist_entry->status = 0;
- erts_this_dist_entry->flags = 0;
- erts_this_dist_entry->version = 0;
-
- erts_smp_mtx_init_x(&erts_this_dist_entry->lnk_mtx,
- "dist_entry_links",
- make_small(ERST_INTERNAL_CHANNEL_NO));
- erts_this_dist_entry->node_links = NULL;
- erts_this_dist_entry->nlinks = NULL;
- erts_this_dist_entry->monitors = NULL;
-
- erts_smp_mtx_init_x(&erts_this_dist_entry->qlock,
- "dist_entry_out_queue",
- make_small(ERST_INTERNAL_CHANNEL_NO));
- erts_this_dist_entry->qflgs = 0;
- erts_this_dist_entry->qsize = 0;
- erts_this_dist_entry->out_queue.first = NULL;
- erts_this_dist_entry->out_queue.last = NULL;
- erts_this_dist_entry->suspended = NULL;
-
- erts_this_dist_entry->finalized_out_queue.first = NULL;
- erts_this_dist_entry->finalized_out_queue.last = NULL;
- erts_smp_atomic_init_nob(&erts_this_dist_entry->dist_cmd_scheduled, 0);
- erts_port_task_handle_init(&erts_this_dist_entry->dist_cmd);
- erts_this_dist_entry->send = NULL;
- erts_this_dist_entry->cache = NULL;
-
- (void) hash_put(&erts_dist_table, (void *) erts_this_dist_entry);
-
- f.hash = (H_FUN) node_table_hash;
- f.cmp = (HCMP_FUN) node_table_cmp;
- f.alloc = (HALLOC_FUN) node_table_alloc;
- f.free = (HFREE_FUN) node_table_free;
+ node_tmpl.sysname = am_Noname;
+ node_tmpl.creation = 0;
+ erts_this_node = hash_put(&erts_node_table, &node_tmpl);
+ /* +1 for erts_this_node */
+ erts_refc_init(&erts_this_node->refc, 1);
- hash_init(ERTS_ALC_T_NODE_TABLE, &erts_node_table, "node_table", 11, f);
+ ASSERT(erts_this_node->dist_entry != NULL);
+ erts_this_dist_entry = erts_this_node->dist_entry;
+ /* +1 for erts_this_dist_entry */
+ /* +1 for erts_this_node->dist_entry */
+ erts_refc_init(&erts_this_dist_entry->refc, 2);
- erts_this_node = erts_alloc(ERTS_ALC_T_NODE_ENTRY, sizeof(ErlNode));
- node_entries = 1;
- erts_refc_init(&erts_this_node->refc, 1); /* The system itself */
- erts_this_node->sysname = am_Noname;
- erts_this_node->creation = 0;
- erts_this_node->dist_entry = erts_this_dist_entry;
erts_this_node_sysname = erts_this_node_sysname_BUFFER;
erts_snprintf(erts_this_node_sysname, sizeof(erts_this_node_sysname_BUFFER),
"%T", erts_this_node->sysname);
- (void) hash_put(&erts_node_table, (void *) erts_this_node);
-
- erts_smp_rwmtx_init_opt(&erts_node_table_rwmtx, &rwmtx_opt, "node_table");
- erts_smp_rwmtx_init_opt(&erts_dist_table_rwmtx, &rwmtx_opt, "dist_table");
-
references_atoms_need_init = 1;
}
@@ -1410,6 +1356,10 @@ setup_reference_table(void)
SYSTEM_REF,
TUPLE2(&heap[0], AM_system, am_undefined));
+ insert_dist_entry(erts_this_dist_entry,
+ SYSTEM_REF,
+ TUPLE2(&heap[0], AM_system, am_undefined),
+ erts_this_node->creation);
UnUseTmpHeapNoproc(3);
max = erts_ptab_max(&erts_proc);
@@ -1472,12 +1422,6 @@ setup_reference_table(void)
insert_links(ERTS_P_LINKS(proc), proc->common.id);
if (ERTS_P_MONITORS(proc))
insert_monitors(ERTS_P_MONITORS(proc), proc->common.id);
- /* Insert controller */
- {
- DistEntry *dep = ERTS_PROC_GET_DIST_ENTRY(proc);
- if (dep)
- insert_dist_entry(dep, CTRL_REF, proc->common.id, 0);
- }
}
}
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c
index 3b1b593d1c..d583118e7b 100644
--- a/erts/emulator/beam/erl_process.c
+++ b/erts/emulator/beam/erl_process.c
@@ -625,11 +625,6 @@ erts_pre_init_process(void)
erts_psd_required_locks[ERTS_PSD_SCHED_ID].set_locks
= ERTS_PSD_SCHED_ID_SET_LOCKS;
- erts_psd_required_locks[ERTS_PSD_DIST_ENTRY].get_locks
- = ERTS_PSD_DIST_ENTRY_GET_LOCKS;
- erts_psd_required_locks[ERTS_PSD_DIST_ENTRY].set_locks
- = ERTS_PSD_DIST_ENTRY_SET_LOCKS;
-
erts_psd_required_locks[ERTS_PSD_CALL_TIME_BP].get_locks
= ERTS_PSD_CALL_TIME_BP_GET_LOCKS;
erts_psd_required_locks[ERTS_PSD_CALL_TIME_BP].set_locks
@@ -12373,9 +12368,7 @@ erts_continue_exit_process(Process *p)
erts_proc_dec_refc(p);
}
- dep = ((p->flags & F_DISTRIBUTION)
- ? ERTS_PROC_SET_DIST_ENTRY(p, ERTS_PROC_LOCKS_ALL, NULL)
- : NULL);
+ dep = (p->flags & F_DISTRIBUTION) ? erts_this_dist_entry : NULL;
scb = ERTS_PROC_SET_SAVED_CALLS_BUF(p, ERTS_PROC_LOCKS_ALL, NULL);
pbt = ERTS_PROC_SET_CALL_TIME(p, ERTS_PROC_LOCKS_ALL, NULL);
nif_export = ERTS_PROC_SET_NIF_TRAP_EXPORT(p, ERTS_PROC_LOCKS_ALL, NULL);
@@ -12387,8 +12380,6 @@ erts_continue_exit_process(Process *p)
if (dep) {
erts_do_net_exits(dep, reason);
- if(dep)
- erts_deref_dist_entry(dep);
}
/*
diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h
index 20ffe7ea7c..10c6fa4a67 100644
--- a/erts/emulator/beam/erl_process.h
+++ b/erts/emulator/beam/erl_process.h
@@ -801,12 +801,11 @@ erts_smp_reset_max_len(ErtsRunQueue *rq, ErtsRunQueueInfo *rqi)
#define ERTS_PSD_ERROR_HANDLER 0
#define ERTS_PSD_SAVED_CALLS_BUF 1
#define ERTS_PSD_SCHED_ID 2
-#define ERTS_PSD_DIST_ENTRY 3
-#define ERTS_PSD_CALL_TIME_BP 4
-#define ERTS_PSD_DELAYED_GC_TASK_QS 5
-#define ERTS_PSD_NIF_TRAP_EXPORT 6
+#define ERTS_PSD_CALL_TIME_BP 3
+#define ERTS_PSD_DELAYED_GC_TASK_QS 4
+#define ERTS_PSD_NIF_TRAP_EXPORT 5
-#define ERTS_PSD_SIZE 7
+#define ERTS_PSD_SIZE 6
typedef struct {
void *data[ERTS_PSD_SIZE];
@@ -824,9 +823,6 @@ typedef struct {
#define ERTS_PSD_SCHED_ID_GET_LOCKS ERTS_PROC_LOCK_STATUS
#define ERTS_PSD_SCHED_ID_SET_LOCKS ERTS_PROC_LOCK_STATUS
-#define ERTS_PSD_DIST_ENTRY_GET_LOCKS ERTS_PROC_LOCK_MAIN
-#define ERTS_PSD_DIST_ENTRY_SET_LOCKS ERTS_PROC_LOCK_MAIN
-
#define ERTS_PSD_CALL_TIME_BP_GET_LOCKS ERTS_PROC_LOCK_MAIN
#define ERTS_PSD_CALL_TIME_BP_SET_LOCKS ERTS_PROC_LOCK_MAIN
@@ -1887,11 +1883,6 @@ erts_psd_set(Process *p, ErtsProcLocks plocks, int ix, void *data)
#define ERTS_PROC_SCHED_ID(P, L, ID) \
((UWord) erts_psd_set((P), (L), ERTS_PSD_SCHED_ID, (void *) (ID)))
-#define ERTS_PROC_GET_DIST_ENTRY(P) \
- ((DistEntry *) erts_psd_get((P), ERTS_PSD_DIST_ENTRY))
-#define ERTS_PROC_SET_DIST_ENTRY(P, L, D) \
- ((DistEntry *) erts_psd_set((P), (L), ERTS_PSD_DIST_ENTRY, (void *) (D)))
-
#define ERTS_PROC_GET_SAVED_CALLS_BUF(P) \
((struct saved_calls *) erts_psd_get((P), ERTS_PSD_SAVED_CALLS_BUF))
#define ERTS_PROC_SET_SAVED_CALLS_BUF(P, L, SCB) \
diff --git a/erts/emulator/beam/erl_process_lock.h b/erts/emulator/beam/erl_process_lock.h
index 788348e613..a64c993e8f 100644
--- a/erts/emulator/beam/erl_process_lock.h
+++ b/erts/emulator/beam/erl_process_lock.h
@@ -854,9 +854,6 @@ ERTS_GLB_INLINE void erts_proc_dec_refc(Process *p)
#endif
if (!referred) {
ASSERT(ERTS_PROC_IS_EXITING(p));
- ASSERT(ERTS_AINT_NULL
- == erts_ptab_pix2intptr_ddrb(&erts_proc,
- internal_pid_index(p->common.id)));
erts_free_proc(p);
}
}
@@ -872,9 +869,6 @@ ERTS_GLB_INLINE void erts_proc_add_refc(Process *p, Sint add_refc)
#endif
if (!referred) {
ASSERT(ERTS_PROC_IS_EXITING(p));
- ASSERT(ERTS_AINT_NULL
- == erts_ptab_pix2intptr_ddrb(&erts_proc,
- internal_pid_index(p->common.id)));
erts_free_proc(p);
}
}
diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c
index c6d7e3fcc5..a85aa15403 100644
--- a/erts/emulator/beam/external.c
+++ b/erts/emulator/beam/external.c
@@ -1179,7 +1179,7 @@ typedef struct {
ErtsHeapFactory factory;
int remaining_n;
char* remaining_bytes;
- Eterm* maps_list;
+ ErtsWStack flat_maps;
ErtsPStack hamt_array;
} B2TDecodeContext;
@@ -1519,7 +1519,7 @@ static BIF_RETTYPE binary_to_term_int(Process* p, Uint32 flags, Eterm bin, Binar
ctx->u.dc.res = (Eterm) (UWord) NULL;
ctx->u.dc.next = &ctx->u.dc.res;
erts_factory_proc_prealloc_init(&ctx->u.dc.factory, p, ctx->heap_size);
- ctx->u.dc.maps_list = NULL;
+ ctx->u.dc.flat_maps.wstart = NULL;
ctx->u.dc.hamt_array.pstart = NULL;
ctx->state = B2TDecode;
/*fall through*/
@@ -2938,7 +2938,7 @@ dec_term(ErtsDistExternal *edep,
int n;
ErtsAtomEncoding char_enc;
register Eterm* hp; /* Please don't take the address of hp */
- Eterm *maps_list; /* for preprocessing of small maps */
+ DECLARE_WSTACK(flat_maps); /* for preprocessing of small maps */
Eterm* next;
SWord reds;
#ifdef DEBUG
@@ -2950,7 +2950,6 @@ dec_term(ErtsDistExternal *edep,
next = ctx->u.dc.next;
ep = ctx->u.dc.ep;
factory = &ctx->u.dc.factory;
- maps_list = ctx->u.dc.maps_list;
if (ctx->state != B2TDecode) {
int n_limit = reds;
@@ -3026,15 +3025,18 @@ dec_term(ErtsDistExternal *edep,
}
}
PSTACK_CHANGE_ALLOCATOR(hamt_array, ERTS_ALC_T_SAVED_ESTACK);
+ WSTACK_CHANGE_ALLOCATOR(flat_maps, ERTS_ALC_T_SAVED_ESTACK);
if (ctx->u.dc.hamt_array.pstart) {
PSTACK_RESTORE(hamt_array, &ctx->u.dc.hamt_array);
}
+ if (ctx->u.dc.flat_maps.wstart) {
+ WSTACK_RESTORE(flat_maps, &ctx->u.dc.flat_maps);
+ }
}
else {
reds = ERTS_SWORD_MAX;
next = objp;
*next = (Eterm) (UWord) NULL;
- maps_list = NULL;
}
hp = factory->hp;
@@ -3595,14 +3597,8 @@ dec_term_atom_common:
* vptr, last word for values
*/
- /*
- * Use thing_word to link through decoded maps.
- * The list of maps is for later validation.
- */
-
- mp->thing_word = (Eterm) COMPRESS_POINTER(maps_list);
- maps_list = (Eterm *) mp;
-
+ WSTACK_PUSH(flat_maps, (UWord)mp);
+ mp->thing_word = MAP_HEADER_FLATMAP;
mp->size = size;
mp->keys = keys;
*objp = make_flatmap(mp);
@@ -3851,7 +3847,9 @@ dec_term_atom_common:
ctx->u.dc.ep = ep;
ctx->u.dc.next = next;
ctx->u.dc.factory.hp = hp;
- ctx->u.dc.maps_list = maps_list;
+ if (!WSTACK_ISEMPTY(flat_maps)) {
+ WSTACK_SAVE(flat_maps, &ctx->u.dc.flat_maps);
+ }
if (!PSTACK_IS_EMPTY(hamt_array)) {
PSTACK_SAVE(hamt_array, &ctx->u.dc.hamt_array);
}
@@ -3865,18 +3863,6 @@ dec_term_atom_common:
}
}
- /* Iterate through all the maps and check for validity and sort keys
- * - done here for when we know it is complete.
- */
-
- while (maps_list) {
- next = (Eterm *)(EXPAND_POINTER(*maps_list));
- *maps_list = MAP_HEADER_FLATMAP;
- if (!erts_validate_and_sort_flatmap((flatmap_t*)maps_list))
- goto error;
- maps_list = next;
- }
-
ASSERT(hp <= factory->hp_end
|| (factory->mode == FACTORY_CLOSED && is_immed(*dbg_resultp)));
factory->hp = hp;
@@ -3885,20 +3871,31 @@ dec_term_atom_common:
*/
if (!PSTACK_IS_EMPTY(hamt_array)) {
- do {
- struct dec_term_hamt* hamt = PSTACK_TOP(hamt_array);
-
- *hamt->objp = erts_hashmap_from_array(factory,
- hamt->leaf_array,
- hamt->size,
- 1);
- if (is_non_value(*hamt->objp))
- goto error_hamt;
-
- (void) PSTACK_POP(hamt_array);
- } while (!PSTACK_IS_EMPTY(hamt_array));
- PSTACK_DESTROY(hamt_array);
+ do {
+ struct dec_term_hamt* hamt = PSTACK_TOP(hamt_array);
+
+ *hamt->objp = erts_hashmap_from_array(factory,
+ hamt->leaf_array,
+ hamt->size,
+ 1);
+ if (is_non_value(*hamt->objp))
+ goto error_hamt;
+
+ (void) PSTACK_POP(hamt_array);
+ } while (!PSTACK_IS_EMPTY(hamt_array));
+ PSTACK_DESTROY(hamt_array);
+ }
+
+ /* Iterate through all the (flat)maps and check for validity and sort keys
+ * - done here for when we know it is complete.
+ */
+
+ while(!WSTACK_ISEMPTY(flat_maps)) {
+ next = (Eterm *)WSTACK_POP(flat_maps);
+ if (!erts_validate_and_sort_flatmap((flatmap_t*)next))
+ goto error;
}
+ WSTACK_DESTROY(flat_maps);
ASSERT((Eterm*)EXPAND_POINTER(*dbg_resultp) != NULL);
@@ -3924,6 +3921,7 @@ error_hamt:
ctx->state = B2TDecodeFail;
ctx->reds = reds;
}
+ WSTACK_DESTROY(flat_maps);
return NULL;
}
diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c
index 900616c981..c64c8802b9 100644
--- a/erts/emulator/beam/io.c
+++ b/erts/emulator/beam/io.c
@@ -7596,15 +7596,15 @@ int null_func(void)
}
int
-erl_drv_putenv(char *key, char *value)
+erl_drv_putenv(const char *key, char *value)
{
- return erts_sys_putenv_raw(key, value);
+ return erts_sys_putenv_raw((char*)key, value);
}
int
-erl_drv_getenv(char *key, char *value, size_t *value_size)
+erl_drv_getenv(const char *key, char *value, size_t *value_size)
{
- return erts_sys_getenv_raw(key, value, value_size);
+ return erts_sys_getenv_raw((char*)key, value, value_size);
}
/* get heart_port
diff --git a/erts/emulator/beam/packet_parser.c b/erts/emulator/beam/packet_parser.c
index 2dd421a9e9..a737a86f14 100644
--- a/erts/emulator/beam/packet_parser.c
+++ b/erts/emulator/beam/packet_parser.c
@@ -256,6 +256,7 @@ int packet_get_length(enum PacketParseType htype,
const char* ptr, unsigned n, /* Bytes read so far */
unsigned max_plen, /* Max packet length, 0=no limit */
unsigned trunc_len, /* Truncate (lines) if longer, 0=no limit */
+ char delimiter, /* Line delimiting character */
int* statep) /* Protocol specific state */
{
unsigned hlen, plen;
@@ -299,9 +300,9 @@ int packet_get_length(enum PacketParseType htype,
goto remain;
case TCP_PB_LINE_LF: {
- /* TCP_PB_LINE_LF: [Data ... \n] */
+ /* TCP_PB_LINE_LF: [Data ... Delimiter] */
const char* ptr2;
- if ((ptr2 = memchr(ptr, '\n', n)) == NULL) {
+ if ((ptr2 = memchr(ptr, delimiter, n)) == NULL) {
if (n > max_plen && max_plen != 0) { /* packet full */
DEBUGF((" => packet full (no NL)=%d\r\n", n));
goto error;
diff --git a/erts/emulator/beam/packet_parser.h b/erts/emulator/beam/packet_parser.h
index ff158ff8b8..717d905fad 100644
--- a/erts/emulator/beam/packet_parser.h
+++ b/erts/emulator/beam/packet_parser.h
@@ -105,7 +105,8 @@ int packet_get_length(enum PacketParseType htype,
const char* ptr, unsigned n, /* Bytes read so far */
unsigned max_plen, /* Packet max length, 0=no limit */
unsigned trunc_len, /* Truncate (lines) if longer, 0=no limit */
- int* statep); /* Internal protocol state */
+ char delimiter, /* Line delimiting character */
+ int* statep); /* Internal protocol state */
ERTS_GLB_INLINE
void packet_get_body(enum PacketParseType htype,
diff --git a/erts/emulator/beam/sys.h b/erts/emulator/beam/sys.h
index bb871b05ba..ec94e3a596 100644
--- a/erts/emulator/beam/sys.h
+++ b/erts/emulator/beam/sys.h
@@ -634,7 +634,6 @@ Uint erts_sys_misc_mem_sz(void);
/* Io constants to erts_print and erts_putc */
#define ERTS_PRINT_STDERR (2)
#define ERTS_PRINT_STDOUT (1)
-#define ERTS_PRINT_INVALID (0) /* Don't want to use 0 since CBUF was 0 */
#define ERTS_PRINT_FILE (-1)
#define ERTS_PRINT_SBUF (-2)
#define ERTS_PRINT_SNBUF (-3)
diff --git a/erts/emulator/beam/utils.c b/erts/emulator/beam/utils.c
index e9d7c91ac9..5286391746 100644
--- a/erts/emulator/beam/utils.c
+++ b/erts/emulator/beam/utils.c
@@ -399,9 +399,6 @@ erts_print(int to, void *arg, char *format, ...)
case ERTS_PRINT_DSBUF:
res = erts_vdsprintf((erts_dsprintf_buf_t *) arg, format, arg_list);
break;
- case ERTS_PRINT_INVALID:
- res = -EINVAL;
- break;
default:
res = erts_vfdprintf((int) to, format, arg_list);
break;
diff --git a/erts/emulator/drivers/common/efile_drv.c b/erts/emulator/drivers/common/efile_drv.c
index 8aff6c1865..3b6abec25e 100644
--- a/erts/emulator/drivers/common/efile_drv.c
+++ b/erts/emulator/drivers/common/efile_drv.c
@@ -2581,7 +2581,6 @@ file_async_ready(ErlDrvData e, ErlDrvThreadData data)
case FILE_CLOSE_ON_PORT_EXIT:
/* See file_stop. However this is never invoked after the port is killed. */
free_data(data);
- EF_FREE(desc);
desc = NULL;
/* This is it for this port, so just send dtrace and return, avoid doing anything to the freed data */
DTRACE6(efile_drv_return, sched_i1, sched_i2, sched_utag,
diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c
index 89b71aa66a..89011d89ad 100644
--- a/erts/emulator/drivers/common/inet_drv.c
+++ b/erts/emulator/drivers/common/inet_drv.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1997-2013. All Rights Reserved.
+ * Copyright Ericsson AB 1997-2015. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -885,6 +885,7 @@ static int my_strncasecmp(const char *s1, const char *s2, size_t n)
#define INET_LOPT_MSGQ_LOWTRMRK 37 /* set local msgq low watermark */
#define INET_LOPT_NETNS 38 /* Network namespace pathname */
#define INET_LOPT_TCP_SHOW_ECONNRESET 39 /* tell user about incoming RST */
+#define INET_LOPT_LINE_DELIM 40 /* Line delimiting char */
/* SCTP options: a separate range, from 100: */
#define SCTP_OPT_RTOINFO 100
#define SCTP_OPT_ASSOCINFO 101
@@ -1154,6 +1155,7 @@ typedef struct {
#else
Uint32 send_oct[2]; /* number of octets sent, 64 bits */
#endif
+ char delimiter; /* Line delimiting character (def: '\n') */
unsigned long send_cnt; /* number of packets sent */
unsigned long send_max; /* maximum packet send */
double send_avg; /* average packet size sent */
@@ -6074,9 +6076,9 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len)
int arg_sz;
enum PacketParseType old_htype = desc->htype;
int old_active = desc->active;
- int propagate = 0; /* Set to 1 if failure to set this option
- should be propagated to erlang (not all
- errors can be propagated for BC reasons) */
+ int propagate; /* Set to 1 if failure to set this option
+ should be propagated to erlang (not all
+ errors can be propagated for BC reasons) */
int res;
#ifdef HAVE_SCTP
/* SCTP sockets are treated completely separately: */
@@ -6093,6 +6095,7 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len)
arg_ptr = (char*) &ival;
arg_sz = sizeof(ival);
proto = SOL_SOCKET;
+ propagate = 0;
switch(opt) {
case INET_LOPT_HEADER:
@@ -6276,6 +6279,12 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len)
}
continue;
+ case INET_LOPT_LINE_DELIM:
+ DEBUGF(("inet_set_opts(%ld): s=%d, LINE_DELIM=%d\r\n",
+ (long)desc->port, desc->s, ival));
+ desc->delimiter = (char)ival;
+ continue;
+
case INET_OPT_REUSEADDR:
#ifdef __WIN32__
continue; /* Bjorn says */
@@ -8371,6 +8380,7 @@ static ErlDrvData inet_start(ErlDrvPort port, int size, int protocol)
desc->deliver = INET_DELIVER_TERM; /* standard term format */
desc->active = INET_PASSIVE; /* start passive */
desc->active_count = 0;
+ desc->delimiter = '\n'; /* line delimiting char */
desc->oph = NULL;
desc->opt = NULL;
@@ -9882,7 +9892,7 @@ static int tcp_remain(tcp_descriptor* desc, int* len)
tlen = packet_get_length(desc->inet.htype, ptr, n,
desc->inet.psize, desc->i_bufsz,
- &desc->http_state);
+ desc->inet.delimiter, &desc->http_state);
DEBUGF(("tcp_remain(%ld): s=%d, n=%d, nfill=%d nsz=%d, tlen %d\r\n",
(long)desc->inet.port, desc->inet.s, n, nfill, nsz, tlen));
diff --git a/erts/emulator/hipe/hipe_native_bif.c b/erts/emulator/hipe/hipe_native_bif.c
index 98bda43f0e..688378b2fe 100644
--- a/erts/emulator/hipe/hipe_native_bif.c
+++ b/erts/emulator/hipe/hipe_native_bif.c
@@ -93,9 +93,6 @@ BIF_RETTYPE hipe_set_timeout(BIF_ALIST_1)
{
Process* p = BIF_P;
Eterm timeout_value = BIF_ARG_1;
-#if !defined(ARCH_64)
- Uint time_val;
-#endif
/* XXX: This should be converted to follow BEAM conventions,
* but that requires some compiler changes.
*
diff --git a/erts/emulator/hipe/hipe_x86_signal.c b/erts/emulator/hipe/hipe_x86_signal.c
index bb8a3f041f..69d4ea10c2 100644
--- a/erts/emulator/hipe/hipe_x86_signal.c
+++ b/erts/emulator/hipe/hipe_x86_signal.c
@@ -198,7 +198,7 @@ static void do_init(void)
#define INIT() do { if (!init_done()) do_init(); } while (0)
#endif /* __DARWIN__ */
-#if !defined(__GLIBC__) && !defined(__DARWIN__) && !defined(__NetBSD__)
+#if defined(__sun__)
/*
* Assume Solaris/x86 2.8.
* There is a number of sigaction() procedures in libc:
@@ -232,7 +232,34 @@ static void do_init(void)
}
#define _NSIG NSIG
#define INIT() do { if (!init_done()) do_init(); } while (0)
-#endif /* not glibc or darwin */
+#endif /* __sun__ */
+
+#if !(defined(__GLIBC__) || defined(__DARWIN__) || defined(__NetBSD__) || defined(__sun__))
+/*
+ * Unknown libc -- assume musl. Note: musl deliberately does not provide a musl-specific
+ * feature test macro, so we cannot check for it.
+ *
+ * sigaction is a weak alias for __sigaction, which is a wrapper for __libc_sigaction.
+ * There are libc-internal calls to __libc_sigaction which install handlers, so we must
+ * override __libc_sigaction rather than __sigaction.
+ */
+#include <dlfcn.h>
+static int (*__next_sigaction)(int, const struct sigaction*, struct sigaction*);
+#define init_done() (__next_sigaction != 0)
+#define __SIGACTION __libc_sigaction
+static void do_init(void)
+{
+ __next_sigaction = dlsym(RTLD_NEXT, "__libc_sigaction");
+ if (__next_sigaction != 0)
+ return;
+ perror("dlsym");
+ abort();
+}
+#ifndef _NSIG
+#define _NSIG NSIG
+#endif
+#define INIT() do { if (!init_done()) do_init(); } while (0)
+#endif /* !(__GLIBC__ || __DARWIN__ || __NetBSD__ || __sun__) */
#if !defined(__NetBSD__)
/*
diff --git a/erts/emulator/sys/common/erl_poll.h b/erts/emulator/sys/common/erl_poll.h
index 19ce582154..bd3a46ef0f 100644
--- a/erts/emulator/sys/common/erl_poll.h
+++ b/erts/emulator/sys/common/erl_poll.h
@@ -140,7 +140,7 @@ struct erts_sys_fd_type {
#endif
#define ERTS_POLL_EV_E2N(EV) \
- ((__uint32_t) (EV))
+ ((uint32_t) (EV))
#define ERTS_POLL_EV_N2E(EV) \
((ErtsPollEvents) (EV))
diff --git a/erts/emulator/sys/win32/erl_win32_sys_ddll.c b/erts/emulator/sys/win32/erl_win32_sys_ddll.c
index 9a5557e93d..7c24a77e31 100644
--- a/erts/emulator/sys/win32/erl_win32_sys_ddll.c
+++ b/erts/emulator/sys/win32/erl_win32_sys_ddll.c
@@ -52,7 +52,8 @@ void erl_sys_ddll_init(void) {
#define ERL_NIF_API_FUNC_DECL(RET,NAME,ARGS) nif_callbacks.NAME = NAME
#include "erl_nif_api_funcs.h"
#undef ERL_NIF_API_FUNC_DECL
-
+ nif_callbacks.erts_alc_test = erts_alc_test;
+
return;
}
diff --git a/erts/emulator/sys/win32/erl_win_dyn_driver.h b/erts/emulator/sys/win32/erl_win_dyn_driver.h
index 5e62320be4..baac7c903e 100644
--- a/erts/emulator/sys/win32/erl_win_dyn_driver.h
+++ b/erts/emulator/sys/win32/erl_win_dyn_driver.h
@@ -145,8 +145,8 @@ WDD_TYPEDEF(ErlDrvTid, erl_drv_thread_self, (void));
WDD_TYPEDEF(int, erl_drv_equal_tids, (ErlDrvTid tid1, ErlDrvTid tid2));
WDD_TYPEDEF(void, erl_drv_thread_exit, (void *resp));
WDD_TYPEDEF(int, erl_drv_thread_join, (ErlDrvTid, void **respp));
-WDD_TYPEDEF(int, erl_drv_putenv, (char *key, char *value));
-WDD_TYPEDEF(int, erl_drv_getenv, (char *key, char *value, size_t *value_size));
+WDD_TYPEDEF(int, erl_drv_putenv, (const char *key, char *value));
+WDD_TYPEDEF(int, erl_drv_getenv, (const char *key, char *value, size_t *value_size));
typedef struct {
WDD_FTYPE(null_func) *null_func;
diff --git a/erts/emulator/test/alloc_SUITE.erl b/erts/emulator/test/alloc_SUITE.erl
index 7c7ddde5d4..aa6a1fbcdc 100644
--- a/erts/emulator/test/alloc_SUITE.erl
+++ b/erts/emulator/test/alloc_SUITE.erl
@@ -31,7 +31,8 @@
rbtree/1,
mseg_clear_cache/1,
erts_mmap/1,
- cpool/1]).
+ cpool/1,
+ migration/1]).
-export([init_per_testcase/2, end_per_testcase/2]).
@@ -43,7 +44,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[basic, coalesce, threads, realloc_copy, bucket_index,
- bucket_mask, rbtree, mseg_clear_cache, erts_mmap, cpool].
+ bucket_mask, rbtree, mseg_clear_cache, erts_mmap, cpool, migration].
groups() ->
[].
@@ -64,7 +65,7 @@ end_per_group(_GroupName, Config) ->
init_per_testcase(Case, Config) when is_list(Config) ->
Dog = ?t:timetrap(?t:seconds(?DEFAULT_TIMETRAP_SECS)),
- [{watchdog, Dog},{testcase, Case}|Config].
+ [{watchdog, Dog}, {testcase, Case}, {debug,false} | Config].
end_per_testcase(_Case, Config) when is_list(Config) ->
Dog = ?config(watchdog, Config),
@@ -112,6 +113,14 @@ cpool(suite) -> [];
cpool(doc) -> [];
cpool(Cfg) -> ?line drv_case(Cfg).
+migration(Cfg) ->
+ case erlang:system_info(smp_support) of
+ true ->
+ drv_case(Cfg, concurrent, "+MZe true");
+ false ->
+ {skipped, "No smp"}
+ end.
+
erts_mmap(Config) when is_list(Config) ->
case {?t:os_type(), is_halfword_vm()} of
{{unix, _}, false} ->
@@ -176,18 +185,17 @@ erts_mmap_do(Config, SCO, SCRPM, SCRFSD) ->
%% %%
drv_case(Config) ->
- drv_case(Config, "").
+ drv_case(Config, one_shot, "").
-drv_case(Config, Command) when is_list(Config),
- is_list(Command) ->
+drv_case(Config, Mode, NodeOpts) when is_list(Config) ->
case ?t:os_type() of
{Family, _} when Family == unix; Family == win32 ->
- ?line {ok, Node} = start_node(Config),
+ ?line {ok, Node} = start_node(Config, NodeOpts),
?line Self = self(),
?line Ref = make_ref(),
?line spawn_link(Node,
fun () ->
- Res = run_drv_case(Config, Command),
+ Res = run_drv_case(Config, Mode),
Self ! {Ref, Res}
end),
?line Result = receive {Ref, Rslt} -> Rslt end,
@@ -199,49 +207,172 @@ drv_case(Config, Command) when is_list(Config),
| io_lib:format("~p",[SkipOs])])}
end.
-run_drv_case(Config, Command) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line CaseName = ?config(testcase,Config),
- case erl_ddll:load_driver(DataDir, CaseName) of
- ok -> ok;
- {error, Error} ->
- io:format("~s\n", [erl_ddll:format_error(Error)]),
- ?line ?t:fail()
+run_drv_case(Config, Mode) ->
+ DataDir = ?config(data_dir,Config),
+ CaseName = ?config(testcase,Config),
+ File = filename:join(DataDir, CaseName),
+ {ok,CaseName,Bin} = compile:file(File, [binary,return_errors]),
+ {module,CaseName} = erlang:load_module(CaseName,Bin),
+ print_stats(CaseName),
+ ok = CaseName:init(File),
+
+ SlaveState = slave_init(CaseName),
+ case Mode of
+ one_shot ->
+ Result = one_shot(CaseName);
+
+ concurrent ->
+ Result = concurrent(CaseName)
end,
- ?line Port = open_port({spawn, atom_to_list(CaseName)}, []),
- ?line true = is_port(Port),
- ?line Port ! {self(), {command, Command}},
- ?line Result = receive_drv_result(Port, CaseName),
- ?line Port ! {self(), close},
- ?line receive
- {Port, closed} ->
- ok
- end,
- ?line ok = erl_ddll:unload_driver(CaseName),
- ?line Result.
-
-receive_drv_result(Port, CaseName) ->
- ?line receive
- {print, Port, CaseName, Str} ->
- ?line ?t:format("~s", [Str]),
- ?line receive_drv_result(Port, CaseName);
- {'EXIT', Port, Error} ->
- ?line ?t:fail(Error);
- {'EXIT', error, Error} ->
- ?line ?t:fail(Error);
- {failed, Port, CaseName, Comment} ->
- ?line ?t:fail(Comment);
- {skipped, Port, CaseName, Comment} ->
- ?line {skipped, Comment};
- {succeeded, Port, CaseName, ""} ->
- ?line succeeded;
- {succeeded, Port, CaseName, Comment} ->
- ?line {comment, Comment}
- end.
-
-start_node(Config) ->
- start_node(Config, []).
+
+ wait_for_memory_deallocations(),
+ print_stats(CaseName),
+
+ true = erlang:delete_module(CaseName),
+ slave_end(SlaveState),
+ Result.
+
+slave_init(migration) ->
+ A0 = case application:start(sasl) of
+ ok -> [sasl];
+ _ -> []
+ end,
+ case application:start(os_mon) of
+ ok -> [os_mon|A0];
+ _ -> A0
+ end;
+slave_init(_) -> [].
+
+slave_end(Apps) ->
+ lists:foreach(fun (A) -> application:stop(A) end, Apps).
+
+wait_for_memory_deallocations() ->
+ try
+ erts_debug:set_internal_state(wait, deallocations)
+ catch
+ error:undef ->
+ erts_debug:set_internal_state(available_internal_state, true),
+ wait_for_memory_deallocations()
+ end.
+
+print_stats(migration) ->
+ {Btot,Ctot} = lists:foldl(fun({instance,Inr,Istats}, {Bacc,Cacc}) ->
+ {mbcs,MBCS} = lists:keyfind(mbcs, 1, Istats),
+ Btup = lists:keyfind(blocks, 1, MBCS),
+ Ctup = lists:keyfind(carriers, 1, MBCS),
+ io:format("{instance,~p,~p,~p}\n", [Inr, Btup, Ctup]),
+ {tuple_add(Bacc,Btup),tuple_add(Cacc,Ctup)};
+ (_, Acc) -> Acc
+ end,
+ {{blocks,0,0,0},{carriers,0,0,0}},
+ erlang:system_info({allocator,test_alloc})),
+
+ io:format("Number of blocks : ~p\n", [Btot]),
+ io:format("Number of carriers: ~p\n", [Ctot]);
+
+print_stats(_) -> ok.
+
+tuple_add(T1, T2) ->
+ list_to_tuple(lists:zipwith(fun(E1,E2) when is_number(E1), is_number(E2) ->
+ E1 + E2;
+ (A,A) ->
+ A
+ end,
+ tuple_to_list(T1), tuple_to_list(T2))).
+
+
+one_shot(CaseName) ->
+ State = CaseName:start({1, 0, erlang:system_info(build_type)}),
+ Result0 = CaseName:run(State),
+ false = (Result0 =:= continue),
+ Result1 = handle_result(State, Result0),
+ CaseName:stop(State),
+ Result1.
+
+
+many_shot(CaseName, I, Mem) ->
+ State = CaseName:start({I, Mem, erlang:system_info(build_type)}),
+ Result1 = repeat_while(fun() ->
+ Result0 = CaseName:run(State),
+ handle_result(State, Result0)
+ end,
+ 10*1000, I),
+ CaseName:stop(State),
+ flush_log(),
+ Result1.
+
+concurrent(CaseName) ->
+ NSched = erlang:system_info(schedulers),
+ Mem = (free_memory() * 3) div 4,
+ PRs = lists:map(fun(I) -> spawn_opt(fun() ->
+ many_shot(CaseName, I,
+ Mem div NSched)
+ end,
+ [monitor, {scheduler,I}])
+ end,
+ lists:seq(1, NSched)),
+ lists:foreach(fun({Pid,Ref}) ->
+ receive {'DOWN', Ref, process, Pid, Reason} ->
+ Reason
+ end
+ end,
+ PRs),
+ ok.
+
+repeat_while(Fun, Timeout, I) ->
+ TRef = erlang:start_timer(Timeout, self(), timeout),
+ R = repeat_while_loop(Fun, TRef, I),
+ erlang:cancel_timer(TRef, [{async,true},{info,false}]),
+ R.
+
+repeat_while_loop(Fun, TRef, I) ->
+ receive
+ {timeout, TRef, timeout} ->
+ io:format("~p: Timeout, enough is enough.",[I]),
+ succeeded
+ after 0 ->
+ %%io:format("~p calls fun\n", [self()]),
+ case Fun() of
+ continue -> repeat_while_loop(Fun, TRef, I);
+ R -> R
+ end
+ end.
+
+flush_log() ->
+ receive
+ {print, Str} ->
+ ?t:format("~s", [Str]),
+ flush_log()
+ after 0 ->
+ ok
+ end.
+
+handle_result(_State, Result0) ->
+ flush_log(),
+ case Result0 of
+ {'EXIT', Error} ->
+ ?line ?t:fail(Error);
+ {'EXIT', error, Error} ->
+ ?line ?t:fail(Error);
+ {failed, Comment} ->
+ ?line ?t:fail(Comment);
+ {skipped, Comment} ->
+ ?line {skipped, Comment};
+ {succeeded, ""} ->
+ ?line succeeded;
+ {succeeded, Comment} ->
+ ?line {comment, Comment};
+ continue ->
+ continue
+ end.
+
start_node(Config, Opts) when is_list(Config), is_list(Opts) ->
+ case ?config(debug,Config) of
+ true -> {ok, node()};
+ _ -> start_node_1(Config, Opts)
+ end.
+
+start_node_1(Config, Opts) ->
Pa = filename:dirname(code:which(?MODULE)),
Name = list_to_atom(atom_to_list(?MODULE)
++ "-"
@@ -252,6 +383,7 @@ start_node(Config, Opts) when is_list(Config), is_list(Opts) ->
++ integer_to_list(erlang:unique_integer([positive]))),
?t:start_node(Name, slave, [{args, Opts++" -pa "++Pa}]).
+stop_node(Node) when Node =:= node() -> ok;
stop_node(Node) ->
?t:stop_node(Node).
@@ -261,3 +393,23 @@ is_halfword_vm() ->
{4, 8} -> true;
{WS, WS} -> false
end.
+
+free_memory() ->
+ %% Free memory in MB.
+ try
+ SMD = memsup:get_system_memory_data(),
+ {value, {free_memory, Free}} = lists:keysearch(free_memory, 1, SMD),
+ TotFree = (Free +
+ case lists:keysearch(cached_memory, 1, SMD) of
+ {value, {cached_memory, Cached}} -> Cached;
+ false -> 0
+ end +
+ case lists:keysearch(buffered_memory, 1, SMD) of
+ {value, {buffered_memory, Buffed}} -> Buffed;
+ false -> 0
+ end),
+ TotFree div (1024*1024)
+ catch
+ error : undef ->
+ ?t:fail({"os_mon not built"})
+ end.
diff --git a/erts/emulator/test/alloc_SUITE_data/Makefile.src b/erts/emulator/test/alloc_SUITE_data/Makefile.src
index a441fe946b..e31de54e1b 100644
--- a/erts/emulator/test/alloc_SUITE_data/Makefile.src
+++ b/erts/emulator/test/alloc_SUITE_data/Makefile.src
@@ -25,7 +25,8 @@ TEST_DRVS = basic@dll@ \
bucket_mask@dll@ \
rbtree@dll@ \
mseg_clear_cache@dll@ \
- cpool@dll@
+ cpool@dll@ \
+ migration@dll@
CC = @CC@
LD = @LD@
diff --git a/erts/emulator/test/alloc_SUITE_data/allocator_test.h b/erts/emulator/test/alloc_SUITE_data/allocator_test.h
index 1d6b2f4907..97ee58cdad 100644
--- a/erts/emulator/test/alloc_SUITE_data/allocator_test.h
+++ b/erts/emulator/test/alloc_SUITE_data/allocator_test.h
@@ -20,9 +20,20 @@
#ifndef ALLOCATOR_TEST_H__
#define ALLOCATOR_TEST_H__
-typedef ErlDrvUInt Ulong;
+#if SIZEOF_VOID_P == SIZEOF_INT
+typedef unsigned int Ulong;
+#elif SIZEOF_VOID_P == SIZEOF_LONG
+typedef unsigned long Ulong;
+#elif SIZEOF_VOID_P == SIZEOF_LONG_LONG
+typedef unsigned long long Ulong;
+#else
+# error No pointer sized integer type found ???
+#endif
-#ifndef __WIN32__
+#ifdef __WIN32__
+typedef Ulong erts_alc_test_Fn(Ulong, Ulong, Ulong, Ulong);
+# define erts_alc_test ((erts_alc_test_Fn*)WinDynNifCallbacks.erts_alc_test)
+#else
Ulong erts_alc_test(Ulong, Ulong, Ulong, Ulong);
#endif
@@ -85,6 +96,7 @@ typedef void* erts_cond;
#define CPOOL_DELETE(A,B) ((Carrier_t *) ALC_TEST2(0x022, (A), (B)))
#define CPOOL_IS_EMPTY(A) ((int) ALC_TEST1(0x023, (A)))
#define CPOOL_IS_IN_POOL(A,B) ((int) ALC_TEST2(0x024, (A), (B)))
+#define UMEM2BLK_TEST(P) ((Block_t*) ALC_TEST1(0x025, (P)))
/* From erl_goodfit_alloc.c */
#define BKT_IX(A, S) ((Ulong) ALC_TEST2(0x100, (A), (S)))
@@ -142,5 +154,9 @@ typedef void* erts_cond;
#define THR_JOIN(T) ((void) ALC_TEST1(0xf11, (T)))
#define THR_EXIT(R) ((void) ALC_TEST1(0xf12, (R)))
#define IS_SMP_ENABLED ((int) ALC_TEST0(0xf13))
+#define ALLOC_TEST(S) ((void*) ALC_TEST1(0xf14, (S)))
+#define FREE_TEST(P) ((void) ALC_TEST1(0xf15, (P)))
+#define SET_TEST_MBC_USER_HEADER(SZ,CMBC,DMBC) ((int)ALC_TEST3(0xf16, (SZ), (CMBC), (DMBC)))
+#define GET_TEST_MBC_SIZE() ((int) ALC_TEST0(0xf17))
#endif
diff --git a/erts/emulator/test/alloc_SUITE_data/basic.c b/erts/emulator/test/alloc_SUITE_data/basic.c
index 323a24a11f..debb3d7ebe 100644
--- a/erts/emulator/test/alloc_SUITE_data/basic.c
+++ b/erts/emulator/test/alloc_SUITE_data/basic.c
@@ -60,3 +60,6 @@ testcase_cleanup(TestCaseState_t *tcs)
if (tcs->extra)
STOP_ALC((Allctr_t *) tcs->extra);
}
+
+ERL_NIF_INIT(basic, testcase_nif_funcs, testcase_nif_init,
+ NULL, NULL, NULL);
diff --git a/erts/emulator/test/alloc_SUITE_data/basic.erl b/erts/emulator/test/alloc_SUITE_data/basic.erl
new file mode 100644
index 0000000000..a018fd5582
--- /dev/null
+++ b/erts/emulator/test/alloc_SUITE_data/basic.erl
@@ -0,0 +1,10 @@
+-module(basic).
+
+-export([init/1, start/1, run/1, stop/1]).
+
+init(File) ->
+ ok = erlang:load_nif(File, 0).
+
+start(_) -> erlang:nif_error(not_loaded).
+run(_) -> erlang:nif_error(not_loaded).
+stop(_) -> erlang:nif_error(not_loaded).
diff --git a/erts/emulator/test/alloc_SUITE_data/bucket_index.c b/erts/emulator/test/alloc_SUITE_data/bucket_index.c
index c13f229049..45cb53fbf7 100644
--- a/erts/emulator/test/alloc_SUITE_data/bucket_index.c
+++ b/erts/emulator/test/alloc_SUITE_data/bucket_index.c
@@ -113,3 +113,5 @@ test_it(TestCaseState_t *tcs, unsigned sbct)
sbct ? sbct_buf : "default");
}
+ERL_NIF_INIT(bucket_index, testcase_nif_funcs, testcase_nif_init,
+ NULL, NULL, NULL);
diff --git a/erts/emulator/test/alloc_SUITE_data/bucket_index.erl b/erts/emulator/test/alloc_SUITE_data/bucket_index.erl
new file mode 100644
index 0000000000..c54f54e2f5
--- /dev/null
+++ b/erts/emulator/test/alloc_SUITE_data/bucket_index.erl
@@ -0,0 +1,10 @@
+-module(bucket_index).
+
+-export([init/1, start/1, run/1, stop/1]).
+
+init(File) ->
+ ok = erlang:load_nif(File, 0).
+
+start(_) -> erlang:nif_error(not_loaded).
+run(_) -> erlang:nif_error(not_loaded).
+stop(_) -> erlang:nif_error(not_loaded).
diff --git a/erts/emulator/test/alloc_SUITE_data/bucket_mask.c b/erts/emulator/test/alloc_SUITE_data/bucket_mask.c
index 8d6166771e..c94c265f4e 100644
--- a/erts/emulator/test/alloc_SUITE_data/bucket_mask.c
+++ b/erts/emulator/test/alloc_SUITE_data/bucket_mask.c
@@ -52,7 +52,7 @@ testcase_run(TestCaseState_t *tcs)
typedef struct linked_block {
struct linked_block* next;
}Linked;
- Linked* link;
+ Linked* link = NULL;
Linked* fence_list;
Linked* pad_list;
void* tmp;
@@ -183,3 +183,5 @@ testcase_run(TestCaseState_t *tcs)
tcs->extra = NULL;
}
+ERL_NIF_INIT(bucket_mask, testcase_nif_funcs, testcase_nif_init,
+ NULL, NULL, NULL);
diff --git a/erts/emulator/test/alloc_SUITE_data/bucket_mask.erl b/erts/emulator/test/alloc_SUITE_data/bucket_mask.erl
new file mode 100644
index 0000000000..589a50e1fa
--- /dev/null
+++ b/erts/emulator/test/alloc_SUITE_data/bucket_mask.erl
@@ -0,0 +1,10 @@
+-module(bucket_mask).
+
+-export([init/1, start/1, run/1, stop/1]).
+
+init(File) ->
+ ok = erlang:load_nif(File, 0).
+
+start(_) -> erlang:nif_error(not_loaded).
+run(_) -> erlang:nif_error(not_loaded).
+stop(_) -> erlang:nif_error(not_loaded).
diff --git a/erts/emulator/test/alloc_SUITE_data/coalesce.c b/erts/emulator/test/alloc_SUITE_data/coalesce.c
index 0a5e0c5b0e..7791409a34 100644
--- a/erts/emulator/test/alloc_SUITE_data/coalesce.c
+++ b/erts/emulator/test/alloc_SUITE_data/coalesce.c
@@ -317,3 +317,6 @@ testcase_cleanup(TestCaseState_t *tcs)
if (tcs->extra)
STOP_ALC((Allctr_t *) tcs->extra);
}
+
+ERL_NIF_INIT(coalesce, testcase_nif_funcs, testcase_nif_init,
+ NULL, NULL, NULL);
diff --git a/erts/emulator/test/alloc_SUITE_data/coalesce.erl b/erts/emulator/test/alloc_SUITE_data/coalesce.erl
new file mode 100644
index 0000000000..453c726c4e
--- /dev/null
+++ b/erts/emulator/test/alloc_SUITE_data/coalesce.erl
@@ -0,0 +1,10 @@
+-module(coalesce).
+
+-export([init/1, start/1, run/1, stop/1]).
+
+init(File) ->
+ ok = erlang:load_nif(File, 0).
+
+start(_) -> erlang:nif_error(not_loaded).
+run(_) -> erlang:nif_error(not_loaded).
+stop(_) -> erlang:nif_error(not_loaded).
diff --git a/erts/emulator/test/alloc_SUITE_data/cpool.c b/erts/emulator/test/alloc_SUITE_data/cpool.c
index 75c2bc13ae..73026cc758 100644
--- a/erts/emulator/test/alloc_SUITE_data/cpool.c
+++ b/erts/emulator/test/alloc_SUITE_data/cpool.c
@@ -86,13 +86,13 @@ thread_func(void *arg)
for (i = 0; i < (TEST_NO_CARRIERS_PER_THREAD+TEST_CARRIERS_OFFSET); i++) {
int d;
if (i < TEST_NO_CARRIERS_PER_THREAD) {
- CPOOL_INSERT(alloc, crr[i]);
+ (void) CPOOL_INSERT(alloc, crr[i]);
if ((i & 0x7) == 0)
FATAL_ASSERT(CPOOL_IS_IN_POOL(alloc, crr[i]));
}
d = i-TEST_CARRIERS_OFFSET;
if (d >= 0) {
- CPOOL_DELETE(alloc, crr[d]);
+ (void) CPOOL_DELETE(alloc, crr[d]);
if ((d & 0x7) == 0)
FATAL_ASSERT(!CPOOL_IS_IN_POOL(alloc, crr[d]));
}
@@ -129,7 +129,7 @@ testcase_run(TestCaseState_t *tcs)
for (c = 0; c < TEST_NO_CARRIERS_PER_THREAD; c++) {
Carrier_t *crr = (Carrier_t *) p;
p += zcrr_sz;
- ZERO_CRR_INIT(alloc, crr);
+ (void) ZERO_CRR_INIT(alloc, crr);
threads[t].crr[c] = crr;
}
}
@@ -156,3 +156,6 @@ testcase_run(TestCaseState_t *tcs)
ASSERT(tcs, no_threads == TEST_NO_THREADS);
}
+
+ERL_NIF_INIT(cpool, testcase_nif_funcs, testcase_nif_init,
+ NULL, NULL, NULL);
diff --git a/erts/emulator/test/alloc_SUITE_data/cpool.erl b/erts/emulator/test/alloc_SUITE_data/cpool.erl
new file mode 100644
index 0000000000..89053471fa
--- /dev/null
+++ b/erts/emulator/test/alloc_SUITE_data/cpool.erl
@@ -0,0 +1,10 @@
+-module(cpool).
+
+-export([init/1, start/1, run/1, stop/1]).
+
+init(File) ->
+ ok = erlang:load_nif(File, 0).
+
+start(_) -> erlang:nif_error(not_loaded).
+run(_) -> erlang:nif_error(not_loaded).
+stop(_) -> erlang:nif_error(not_loaded).
diff --git a/erts/emulator/test/alloc_SUITE_data/migration.c b/erts/emulator/test/alloc_SUITE_data/migration.c
new file mode 100644
index 0000000000..b006360043
--- /dev/null
+++ b/erts/emulator/test/alloc_SUITE_data/migration.c
@@ -0,0 +1,343 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2014. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+/*
+ * Test the carrier migration logic
+ */
+
+#ifndef __WIN32__
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include "testcase_driver.h"
+#include "allocator_test.h"
+
+#define FATAL_ASSERT(A) \
+ ((void) ((A) \
+ ? 1 \
+ : (fatal_assert_failed(#A, \
+ (char *) __FILE__, \
+ __LINE__), \
+ 0)))
+
+static void
+fatal_assert_failed(char* expr, char* file, int line)
+{
+ fflush(stdout);
+ fprintf(stderr, "%s:%d: Assertion failed: %s\n",
+ file, line, expr);
+ fflush(stderr);
+ abort();
+}
+
+
+char *
+testcase_name(void)
+{
+ return "migration";
+}
+
+/* Turns out random_r() is a nonstandard glibc extension.
+#define HAVE_RANDOM_R
+*/
+#ifdef HAVE_RANDOM_R
+
+typedef struct { struct random_data rnd; char rndbuf[32]; } MyRandState;
+
+static void myrand_init(MyRandState* mrs, unsigned int seed)
+{
+ int res;
+ memset(&mrs->rnd, 0, sizeof(mrs->rnd));
+ res = initstate_r(seed, mrs->rndbuf, sizeof(mrs->rndbuf), &mrs->rnd);
+ FATAL_ASSERT(res == 0);
+}
+
+static int myrand(MyRandState* mrs)
+{
+ int32_t x;
+ int res = random_r(&mrs->rnd, &x);
+ FATAL_ASSERT(res == 0);
+ return (int)x;
+}
+
+#else /* !HAVE_RANDOM_R */
+
+typedef unsigned int MyRandState;
+
+static void myrand_init(MyRandState* mrs, unsigned int seed)
+{
+ *mrs = seed;
+}
+
+static int myrand(MyRandState* mrs)
+{
+ /* Taken from rand(3) man page.
+ * Modified to return a full 31-bit value by using low half of *mrs as well.
+ */
+ *mrs = (*mrs) * 1103515245 + 12345;
+ return (int) (((*mrs >> 16) | (*mrs << 16)) & ~(1 << 31));
+}
+
+#endif /* !HAVE_RANDOM_R */
+
+#define MAX_BLOCK_PER_THR 200
+#define BLOCKS_PER_MBC 10
+#define MAX_ROUNDS 10000
+
+typedef struct MyBlock_ {
+ struct MyBlock_* next;
+ struct MyBlock_** prevp;
+} MyBlock;
+
+typedef struct {
+ MyBlock* blockv[MAX_BLOCK_PER_THR];
+ MyRandState rand_state;
+ enum { GROWING, SHRINKING, CLEANUP, DONE } phase;
+ int nblocks;
+ int goal_nblocks;
+ int round;
+ int nr_of_migrations;
+ int nr_of_carriers;
+ int max_blocks_in_mbc;
+ int block_size;
+ int max_nblocks;
+} MigrationState;
+
+typedef struct {
+ ErlNifMutex* mtx;
+ int nblocks;
+ MyBlock* first;
+ MigrationState* employer;
+} MyCrrInfo;
+
+
+static int crr_info_offset = -1;
+static void (*orig_create_mbc_fn)(Allctr_t *allctr, Carrier_t *carrier);
+static void (*orig_destroying_mbc_fn)(Allctr_t *allctr, Carrier_t *carrier);
+
+static void my_creating_mbc(Allctr_t *allctr, Carrier_t *carrier)
+{
+ MyCrrInfo* mci = (MyCrrInfo*) ((char*)carrier + crr_info_offset);
+ if (orig_create_mbc_fn)
+ orig_create_mbc_fn(allctr, carrier);
+
+ mci->mtx = enif_mutex_create("alloc_SUITE.migration");
+ mci->nblocks = 0;
+ mci->first = NULL;
+ mci->employer = NULL;
+}
+
+static void my_destroying_mbc(Allctr_t *allctr, Carrier_t *carrier)
+{
+ MyCrrInfo* mci = (MyCrrInfo*) ((char*)carrier + crr_info_offset);
+
+ FATAL_ASSERT(mci->nblocks == 0);
+ FATAL_ASSERT(mci->first == NULL);
+ enif_mutex_destroy(mci->mtx);
+
+ if (orig_destroying_mbc_fn)
+ orig_destroying_mbc_fn(allctr, carrier);
+}
+
+static int migration_init(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
+{
+ void* creating_mbc_arg = (void*)my_creating_mbc;
+ void* destroying_mbc_arg = (void*)my_destroying_mbc;
+
+ if (testcase_nif_init(env, priv_data, load_info))
+ return -1;
+
+ crr_info_offset = SET_TEST_MBC_USER_HEADER(sizeof(MyCrrInfo),
+ &creating_mbc_arg,
+ &destroying_mbc_arg);
+ FATAL_ASSERT(crr_info_offset >= 0);
+ orig_create_mbc_fn = creating_mbc_arg;
+ orig_destroying_mbc_fn = destroying_mbc_arg;
+
+ return 0;
+}
+
+static void add_block(MyBlock* p, MigrationState* state)
+{
+ MyCrrInfo* mci = (MyCrrInfo*)((char*)BLK_TO_MBC(UMEM2BLK_TEST(p)) + crr_info_offset);
+
+ enif_mutex_lock(mci->mtx);
+ if (++mci->nblocks > state->max_blocks_in_mbc)
+ state->max_blocks_in_mbc = mci->nblocks;
+ p->next = mci->first;
+ p->prevp = &mci->first;
+ mci->first = p;
+ if (p->next)
+ p->next->prevp = &p->next;
+ if (mci->employer != state) {
+ if (!mci->employer) {
+ FATAL_ASSERT(mci->nblocks == 1);
+ state->nr_of_carriers++;
+ }
+ else {
+ state->nr_of_migrations++;
+ }
+ mci->employer = state;
+ }
+ enif_mutex_unlock(mci->mtx);
+}
+
+static void remove_block(MyBlock* p)
+{
+ MyCrrInfo* mci = (MyCrrInfo*)((char*)BLK_TO_MBC(UMEM2BLK_TEST(p)) + crr_info_offset);
+
+ enif_mutex_lock(mci->mtx);
+ mci->nblocks--;
+ if (p->next)
+ p->next->prevp = p->prevp;
+ *p->prevp = p->next;
+ enif_mutex_unlock(mci->mtx);
+}
+
+static int rand_int(MigrationState* state, int low, int high)
+{
+ int x;
+ FATAL_ASSERT(high >= low);
+ x = myrand(&state->rand_state);
+ return low + (x % (high+1-low));
+}
+
+
+static void do_cleanup(TestCaseState_t *tcs, MigrationState* state)
+{
+ if (state->nblocks == 0) {
+ state->phase = DONE;
+ testcase_printf(tcs, "%d: Done %d rounds", tcs->thr_nr, state->round);
+ testcase_printf(tcs, "%d: Cleanup all blocks", tcs->thr_nr);
+ testcase_printf(tcs, "%d: Empty carriers detected = %d", tcs->thr_nr,
+ state->nr_of_carriers);
+ testcase_printf(tcs, "%d: Migrations detected = %d", tcs->thr_nr,
+ state->nr_of_migrations);
+ testcase_printf(tcs, "%d: Max blocks in carrier = %d", tcs->thr_nr,
+ state->max_blocks_in_mbc);
+ }
+ else {
+ state->nblocks--;
+ if (state->blockv[state->nblocks]) {
+ remove_block(state->blockv[state->nblocks]);
+ FREE_TEST(state->blockv[state->nblocks]);
+ }
+ }
+}
+
+
+void
+testcase_run(TestCaseState_t *tcs)
+{
+ MigrationState* state = (MigrationState*) tcs->extra;
+
+ if (!tcs->extra) {
+ if (!IS_SMP_ENABLED)
+ testcase_skipped(tcs, "No SMP support");
+
+ tcs->extra = enif_alloc(sizeof(MigrationState));
+ state = (MigrationState*) tcs->extra;
+ memset(state->blockv, 0, sizeof(state->blockv));
+ myrand_init(&state->rand_state, tcs->thr_nr);
+ state->phase = GROWING;
+ state->nblocks = 0;
+ state->round = 0;
+ state->nr_of_migrations = 0;
+ state->nr_of_carriers = 0;
+ state->max_blocks_in_mbc = 0;
+ state->block_size = GET_TEST_MBC_SIZE() / (BLOCKS_PER_MBC+1);
+ if (MAX_BLOCK_PER_THR * state->block_size < tcs->free_mem) {
+ state->max_nblocks = MAX_BLOCK_PER_THR;
+ } else {
+ state->max_nblocks = tcs->free_mem / state->block_size;
+ }
+ state->goal_nblocks = rand_int(state, 1, state->max_nblocks);
+ }
+
+ switch (state->phase) {
+ case GROWING: {
+ MyBlock* p;
+ FATAL_ASSERT(!state->blockv[state->nblocks]);
+ p = ALLOC_TEST(rand_int(state, state->block_size/2, state->block_size));
+ FATAL_ASSERT(p);
+ add_block(p, state);
+ state->blockv[state->nblocks] = p;
+ if (++state->nblocks >= state->goal_nblocks) {
+ /*testcase_printf(tcs, "%d: Grown to %d blocks", tcs->thr_nr, state->nblocks);*/
+ state->phase = SHRINKING;
+ state->goal_nblocks = rand_int(state, 0, state->goal_nblocks-1);
+ }
+ else
+ FATAL_ASSERT(!state->blockv[state->nblocks]);
+ break;
+ }
+ case SHRINKING: {
+ int ix = rand_int(state, 0, state->nblocks-1);
+ FATAL_ASSERT(state->blockv[ix]);
+ remove_block(state->blockv[ix]);
+ FREE_TEST(state->blockv[ix]);
+ state->blockv[ix] = state->blockv[--state->nblocks];
+ state->blockv[state->nblocks] = NULL;
+
+ if (state->nblocks <= state->goal_nblocks) {
+ /*testcase_printf(tcs, "%d: Shrunk to %d blocks", tcs->thr_nr, state->nblocks);*/
+ if (++state->round >= MAX_ROUNDS) {
+ state->phase = CLEANUP;
+ } else {
+ state->phase = GROWING;
+ state->goal_nblocks = rand_int(state, state->goal_nblocks+1, state->max_nblocks);
+ }
+ }
+ break;
+ }
+ case CLEANUP:
+ do_cleanup(tcs, state);
+ break;
+
+ default:
+ FATAL_ASSERT(!"Invalid phase");
+ }
+
+ if (state->phase == DONE) {
+ }
+ else {
+ testcase_continue(tcs);
+ }
+}
+
+void
+testcase_cleanup(TestCaseState_t *tcs)
+{
+ MigrationState* state = (MigrationState*) tcs->extra;
+
+ while (state->phase != DONE)
+ do_cleanup(tcs, state);
+
+ enif_free(tcs->extra);
+ tcs->extra = NULL;
+}
+
+
+ERL_NIF_INIT(migration, testcase_nif_funcs, migration_init,
+ NULL, NULL, NULL);
diff --git a/erts/emulator/test/alloc_SUITE_data/migration.erl b/erts/emulator/test/alloc_SUITE_data/migration.erl
new file mode 100644
index 0000000000..440a99becd
--- /dev/null
+++ b/erts/emulator/test/alloc_SUITE_data/migration.erl
@@ -0,0 +1,10 @@
+-module(migration).
+
+-export([init/1, start/1, run/1, stop/1]).
+
+init(File) ->
+ ok = erlang:load_nif(File, 0).
+
+start(_) -> erlang:nif_error(not_loaded).
+run(_) -> erlang:nif_error(not_loaded).
+stop(_) -> erlang:nif_error(not_loaded).
diff --git a/erts/emulator/test/alloc_SUITE_data/mseg_clear_cache.c b/erts/emulator/test/alloc_SUITE_data/mseg_clear_cache.c
index 9c03f3a331..e5df3d647f 100644
--- a/erts/emulator/test/alloc_SUITE_data/mseg_clear_cache.c
+++ b/erts/emulator/test/alloc_SUITE_data/mseg_clear_cache.c
@@ -101,3 +101,6 @@ testcase_cleanup(TestCaseState_t *tcs)
tcs->extra = NULL;
}
}
+
+ERL_NIF_INIT(mseg_clear_cache, testcase_nif_funcs, testcase_nif_init,
+ NULL, NULL, NULL);
diff --git a/erts/emulator/test/alloc_SUITE_data/mseg_clear_cache.erl b/erts/emulator/test/alloc_SUITE_data/mseg_clear_cache.erl
new file mode 100644
index 0000000000..befd6c2e8e
--- /dev/null
+++ b/erts/emulator/test/alloc_SUITE_data/mseg_clear_cache.erl
@@ -0,0 +1,10 @@
+-module(mseg_clear_cache).
+
+-export([init/1, start/1, run/1, stop/1]).
+
+init(File) ->
+ ok = erlang:load_nif(File, 0).
+
+start(_) -> erlang:nif_error(not_loaded).
+run(_) -> erlang:nif_error(not_loaded).
+stop(_) -> erlang:nif_error(not_loaded).
diff --git a/erts/emulator/test/alloc_SUITE_data/rbtree.c b/erts/emulator/test/alloc_SUITE_data/rbtree.c
index 8d4d5535a8..38bbbdf90c 100644
--- a/erts/emulator/test/alloc_SUITE_data/rbtree.c
+++ b/erts/emulator/test/alloc_SUITE_data/rbtree.c
@@ -20,7 +20,7 @@
#include "testcase_driver.h"
#include "allocator_test.h"
-#define NO_BLOCKS 100000
+int NO_BLOCKS;
#define RIGHT_VISITED (1 << 0)
#define LEFT_VISITED (1 << 1)
@@ -265,9 +265,10 @@ check_tree(TestCaseState_t *tcs, Allctr_t *alc, Ulong size)
ASSERT(tcs, curr_blacks == 0);
ASSERT(tcs, i == -1);
+ /*
testcase_printf(tcs, "Red-Black Tree OK! Max depth = %d; "
"Black depth = %d\n", max_i+1, blacks < 0 ? 0 : blacks);
-
+ */
return res;
}
@@ -468,6 +469,12 @@ testcase_run(TestCaseState_t *tcs)
Allctr_t *a;
rbtree_test_data *td;
+ NO_BLOCKS = 100*1000;
+ if (enif_is_identical(tcs->build_type,
+ enif_make_atom(tcs->curr_env,"valgrind"))) {
+ NO_BLOCKS /= 10;
+ }
+
/* Best fit... */
testcase_printf(tcs, "Setup...\n");
@@ -577,3 +584,6 @@ testcase_run(TestCaseState_t *tcs)
testcase_printf(tcs, "aoffcaobf test succeeded!\n");
}
+
+ERL_NIF_INIT(rbtree, testcase_nif_funcs, testcase_nif_init,
+ NULL, NULL, NULL);
diff --git a/erts/emulator/test/alloc_SUITE_data/rbtree.erl b/erts/emulator/test/alloc_SUITE_data/rbtree.erl
new file mode 100644
index 0000000000..f5b7120ff2
--- /dev/null
+++ b/erts/emulator/test/alloc_SUITE_data/rbtree.erl
@@ -0,0 +1,10 @@
+-module(rbtree).
+
+-export([init/1, start/1, run/1, stop/1]).
+
+init(File) ->
+ ok = erlang:load_nif(File, 0).
+
+start(_) -> erlang:nif_error(not_loaded).
+run(_) -> erlang:nif_error(not_loaded).
+stop(_) -> erlang:nif_error(not_loaded).
diff --git a/erts/emulator/test/alloc_SUITE_data/realloc_copy.c b/erts/emulator/test/alloc_SUITE_data/realloc_copy.c
index e405f06225..c4147eb00d 100644
--- a/erts/emulator/test/alloc_SUITE_data/realloc_copy.c
+++ b/erts/emulator/test/alloc_SUITE_data/realloc_copy.c
@@ -278,3 +278,5 @@ testcase_cleanup(TestCaseState_t *tcs)
STOP_ALC((Allctr_t *) tcs->extra);
}
+ERL_NIF_INIT(realloc_copy, testcase_nif_funcs, testcase_nif_init,
+ NULL, NULL, NULL);
diff --git a/erts/emulator/test/alloc_SUITE_data/realloc_copy.erl b/erts/emulator/test/alloc_SUITE_data/realloc_copy.erl
new file mode 100644
index 0000000000..cc6617bf64
--- /dev/null
+++ b/erts/emulator/test/alloc_SUITE_data/realloc_copy.erl
@@ -0,0 +1,10 @@
+-module(realloc_copy).
+
+-export([init/1, start/1, run/1, stop/1]).
+
+init(File) ->
+ ok = erlang:load_nif(File, 0).
+
+start(_) -> erlang:nif_error(not_loaded).
+run(_) -> erlang:nif_error(not_loaded).
+stop(_) -> erlang:nif_error(not_loaded).
diff --git a/erts/emulator/test/alloc_SUITE_data/testcase_driver.c b/erts/emulator/test/alloc_SUITE_data/testcase_driver.c
index bc674c56b7..7dcca544e5 100644
--- a/erts/emulator/test/alloc_SUITE_data/testcase_driver.c
+++ b/erts/emulator/test/alloc_SUITE_data/testcase_driver.c
@@ -23,141 +23,147 @@
#include <stdarg.h>
#include <setjmp.h>
#include <string.h>
+#include <limits.h>
#ifdef __WIN32__
-#undef HAVE_VSNPRINTF
-#define HAVE_VSNPRINTF 1
-#define vsnprintf _vsnprintf
+static void my_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap)
+{
+ _vsnprintf(outBuf, size, format, ap);
+ outBuf[size-1] = 0; /* be sure string is terminated */
+}
+#elif defined(HAVE_VSNPRINTF)
+# define my_vsnprintf(B,S,F,A) (void)vsnprintf(B,S,F,A)
+#else
+# warning Using unsafe 'vsprintf' without buffer overflow protection
+# define my_vsnprintf(B,S,F,A) (void)vsprintf(B,F,A)
#endif
-#ifndef HAVE_VSNPRINTF
-#define HAVE_VSNPRINTF 0
-#endif
+static void my_snprintf(char *outBuf, size_t size, const char *format, ...)
+{
+ va_list ap;
+ va_start(ap, format);
+ my_vsnprintf(outBuf, size, format, ap);
+ va_end(ap);
+}
#define COMMENT_BUF_SZ 4096
#define TESTCASE_FAILED 0
#define TESTCASE_SKIPPED 1
#define TESTCASE_SUCCEEDED 2
+#define TESTCASE_CONTINUE 3
typedef struct {
TestCaseState_t visible;
- ErlDrvPort port;
- ErlDrvTermData port_id;
int result;
- jmp_buf done_jmp_buf;
+ jmp_buf* done_jmp_buf;
char *comment;
char comment_buf[COMMENT_BUF_SZ];
} InternalTestCaseState_t;
-ErlDrvData testcase_drv_start(ErlDrvPort port, char *command);
-void testcase_drv_stop(ErlDrvData drv_data);
-void testcase_drv_run(ErlDrvData drv_data, char *buf, ErlDrvSizeT len);
-
-static ErlDrvEntry testcase_drv_entry = {
- NULL,
- testcase_drv_start,
- testcase_drv_stop,
- testcase_drv_run,
- NULL,
- NULL,
- "testcase_drv",
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- ERL_DRV_EXTENDED_MARKER,
- ERL_DRV_EXTENDED_MAJOR_VERSION,
- ERL_DRV_EXTENDED_MINOR_VERSION,
- 0,
- NULL,
- NULL,
- NULL
+ERL_NIF_TERM testcase_nif_start(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+ERL_NIF_TERM testcase_nif_stop(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+ERL_NIF_TERM testcase_nif_run(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+
+ErlNifFunc testcase_nif_funcs[] =
+{
+ {"start", 1, testcase_nif_start},
+ {"run", 1, testcase_nif_run},
+ {"stop", 1, testcase_nif_stop}
};
+static ErlNifResourceType* testcase_rt;
+static ERL_NIF_TERM print_atom;
-DRIVER_INIT(testcase_drv)
+int testcase_nif_init(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
{
- testcase_drv_entry.driver_name = testcase_name();
- return &testcase_drv_entry;
+ testcase_rt = enif_open_resource_type(env, NULL, "testcase_rt", NULL,
+ ERL_NIF_RT_CREATE, NULL);
+
+ print_atom = enif_make_atom(env, "print");
+ return 0;
}
-ErlDrvData
-testcase_drv_start(ErlDrvPort port, char *command)
-{
+ERL_NIF_TERM
+testcase_nif_start(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{ /* (ThrNr, FreeMeg, BuildType) */
+ ERL_NIF_TERM ret;
InternalTestCaseState_t *itcs = (InternalTestCaseState_t *)
- driver_alloc(sizeof(InternalTestCaseState_t));
- if (!itcs) {
- return ERL_DRV_ERROR_GENERAL;
+ enif_alloc_resource(testcase_rt, sizeof(InternalTestCaseState_t));
+ int free_megabyte;
+ const int max_megabyte = INT_MAX / (1024*1024);
+ const ERL_NIF_TERM* tpl;
+ int tpl_arity;
+
+ if (!itcs
+ || !enif_get_tuple(env, argv[0], &tpl_arity, &tpl)
+ || tpl_arity != 3
+ || !enif_get_int(env, tpl[0], &itcs->visible.thr_nr)
+ || !enif_get_int(env, tpl[1], &free_megabyte)) {
+ enif_make_badarg(env);
}
-
+ itcs->visible.free_mem = (free_megabyte < max_megabyte ?
+ free_megabyte : max_megabyte) * (1024*1024);
itcs->visible.testcase_name = testcase_name();
+ itcs->visible.build_type = tpl[2];
itcs->visible.extra = NULL;
- itcs->port = port;
- itcs->port_id = driver_mk_port(port);
itcs->result = TESTCASE_FAILED;
itcs->comment = "";
- return (ErlDrvData) itcs;
+ ret = enif_make_resource(env, itcs);
+ enif_release_resource(itcs);
+ return ret;
}
-void
-testcase_drv_stop(ErlDrvData drv_data)
+ERL_NIF_TERM
+testcase_nif_stop(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
- testcase_cleanup((TestCaseState_t *) drv_data);
- driver_free((void *) drv_data);
+ InternalTestCaseState_t *itcs;
+ if (!enif_get_resource(env, argv[0], testcase_rt, (void**)&itcs))
+ return enif_make_badarg(env);
+ testcase_cleanup(&itcs->visible);
+ return enif_make_atom(env,"ok");
}
-void
-testcase_drv_run(ErlDrvData drv_data, char *buf, ErlDrvSizeT len)
+ERL_NIF_TERM
+testcase_nif_run(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
- InternalTestCaseState_t *itcs = (InternalTestCaseState_t *) drv_data;
- ErlDrvTermData result_atom;
- ErlDrvTermData msg[12];
+ InternalTestCaseState_t *itcs;
+ const char* result_atom;
+ jmp_buf the_jmp_buf;
+
+ if (!enif_get_resource(env, argv[0], testcase_rt, (void**)&itcs))
+ return enif_make_badarg(env);
- itcs->visible.command = buf;
- itcs->visible.command_len = len;
+ itcs->visible.curr_env = env;
- if (setjmp(itcs->done_jmp_buf) == 0) {
- testcase_run((TestCaseState_t *) itcs);
+ /* For some unknown reason, first call to setjmp crashes on win64
+ * when jmp_buf is allocated as part of the resource. But it works when
+ * allocated on stack. It used to work when this was a driver.
+ */
+ itcs->done_jmp_buf = &the_jmp_buf;
+
+ if (setjmp(the_jmp_buf) == 0) {
+ testcase_run(&itcs->visible);
itcs->result = TESTCASE_SUCCEEDED;
}
switch (itcs->result) {
- case TESTCASE_SUCCEEDED:
- result_atom = driver_mk_atom("succeeded");
- break;
- case TESTCASE_SKIPPED:
- result_atom = driver_mk_atom("skipped");
- break;
- case TESTCASE_FAILED:
+ case TESTCASE_CONTINUE:
+ return enif_make_atom(env, "continue");
+
+ case TESTCASE_SUCCEEDED: result_atom = "succeeded"; break;
+ case TESTCASE_SKIPPED: result_atom = "skipped"; break;
+ case TESTCASE_FAILED: result_atom = "failed"; break;
default:
- result_atom = driver_mk_atom("failed");
- break;
+ result_atom = "failed";
+ my_snprintf(itcs->comment_buf, sizeof(itcs->comment_buf),
+ "Unexpected test result code %d.", itcs->result);
+ itcs->comment = itcs->comment_buf;
}
- msg[0] = ERL_DRV_ATOM;
- msg[1] = (ErlDrvTermData) result_atom;
-
- msg[2] = ERL_DRV_PORT;
- msg[3] = itcs->port_id;
-
- msg[4] = ERL_DRV_ATOM;
- msg[5] = driver_mk_atom(itcs->visible.testcase_name);
-
- msg[6] = ERL_DRV_STRING;
- msg[7] = (ErlDrvTermData) itcs->comment;
- msg[8] = (ErlDrvTermData) strlen(itcs->comment);
-
- msg[9] = ERL_DRV_TUPLE;
- msg[10] = (ErlDrvTermData) 4;
-
- erl_drv_output_term(itcs->port_id, msg, 11);
+ return enif_make_tuple2(env, enif_make_atom(env, result_atom),
+ enif_make_string(env, itcs->comment, ERL_NIF_LATIN1));
}
int
@@ -172,34 +178,22 @@ testcase_assertion_failed(TestCaseState_t *tcs,
void
testcase_printf(TestCaseState_t *tcs, char *frmt, ...)
{
- InternalTestCaseState_t *itcs = (InternalTestCaseState_t *) tcs;
- ErlDrvTermData msg[12];
+ InternalTestCaseState_t* itcs = (InternalTestCaseState_t*)tcs;
+ ErlNifPid pid;
+ ErlNifEnv* msg_env = enif_alloc_env();
+ ERL_NIF_TERM msg;
va_list va;
va_start(va, frmt);
-#if HAVE_VSNPRINTF
- vsnprintf(itcs->comment_buf, COMMENT_BUF_SZ, frmt, va);
-#else
- vsprintf(itcs->comment_buf, frmt, va);
-#endif
+ my_vsnprintf(itcs->comment_buf, COMMENT_BUF_SZ, frmt, va);
va_end(va);
- msg[0] = ERL_DRV_ATOM;
- msg[1] = (ErlDrvTermData) driver_mk_atom("print");
+ msg = enif_make_tuple2(msg_env, print_atom,
+ enif_make_string(msg_env, itcs->comment_buf, ERL_NIF_LATIN1));
- msg[2] = ERL_DRV_PORT;
- msg[3] = itcs->port_id;
+ enif_send(itcs->visible.curr_env, enif_self(itcs->visible.curr_env, &pid),
+ msg_env, msg);
- msg[4] = ERL_DRV_ATOM;
- msg[5] = driver_mk_atom(itcs->visible.testcase_name);
-
- msg[6] = ERL_DRV_STRING;
- msg[7] = (ErlDrvTermData) itcs->comment_buf;
- msg[8] = (ErlDrvTermData) strlen(itcs->comment_buf);
-
- msg[9] = ERL_DRV_TUPLE;
- msg[10] = (ErlDrvTermData) 4;
-
- erl_drv_output_term(itcs->port_id, msg, 11);
+ enif_free_env(msg_env);
}
@@ -208,17 +202,13 @@ void testcase_succeeded(TestCaseState_t *tcs, char *frmt, ...)
InternalTestCaseState_t *itcs = (InternalTestCaseState_t *) tcs;
va_list va;
va_start(va, frmt);
-#if HAVE_VSNPRINTF
- vsnprintf(itcs->comment_buf, COMMENT_BUF_SZ, frmt, va);
-#else
- vsprintf(itcs->comment_buf, frmt, va);
-#endif
+ my_vsnprintf(itcs->comment_buf, COMMENT_BUF_SZ, frmt, va);
va_end(va);
itcs->result = TESTCASE_SUCCEEDED;
itcs->comment = itcs->comment_buf;
- longjmp(itcs->done_jmp_buf, 1);
+ longjmp(*itcs->done_jmp_buf, 1);
}
void testcase_skipped(TestCaseState_t *tcs, char *frmt, ...)
@@ -226,17 +216,20 @@ void testcase_skipped(TestCaseState_t *tcs, char *frmt, ...)
InternalTestCaseState_t *itcs = (InternalTestCaseState_t *) tcs;
va_list va;
va_start(va, frmt);
-#if HAVE_VSNPRINTF
- vsnprintf(itcs->comment_buf, COMMENT_BUF_SZ, frmt, va);
-#else
- vsprintf(itcs->comment_buf, frmt, va);
-#endif
+ my_vsnprintf(itcs->comment_buf, COMMENT_BUF_SZ, frmt, va);
va_end(va);
itcs->result = TESTCASE_SKIPPED;
itcs->comment = itcs->comment_buf;
- longjmp(itcs->done_jmp_buf, 1);
+ longjmp(*itcs->done_jmp_buf, 1);
+}
+
+void testcase_continue(TestCaseState_t *tcs)
+{
+ InternalTestCaseState_t *itcs = (InternalTestCaseState_t *) tcs;
+ itcs->result = TESTCASE_CONTINUE;
+ longjmp(*itcs->done_jmp_buf, 1);
}
void testcase_failed(TestCaseState_t *tcs, char *frmt, ...)
@@ -246,37 +239,33 @@ void testcase_failed(TestCaseState_t *tcs, char *frmt, ...)
size_t bufsz = sizeof(buf);
va_list va;
va_start(va, frmt);
-#if HAVE_VSNPRINTF
- vsnprintf(itcs->comment_buf, COMMENT_BUF_SZ, frmt, va);
-#else
- vsprintf(itcs->comment_buf, frmt, va);
-#endif
+ my_vsnprintf(itcs->comment_buf, COMMENT_BUF_SZ, frmt, va);
va_end(va);
itcs->result = TESTCASE_FAILED;
itcs->comment = itcs->comment_buf;
- if (erl_drv_getenv("ERL_ABORT_ON_FAILURE", buf, &bufsz) == 0
+ if (enif_getenv("ERL_ABORT_ON_FAILURE", buf, &bufsz) == 0
&& strcmp("true", buf) == 0) {
fprintf(stderr, "Testcase \"%s\" failed: %s\n",
itcs->visible.testcase_name, itcs->comment);
abort();
}
- longjmp(itcs->done_jmp_buf, 1);
+ longjmp(*itcs->done_jmp_buf, 1);
}
void *testcase_alloc(size_t size)
{
- return driver_alloc(size);
+ return enif_alloc(size);
}
void *testcase_realloc(void *ptr, size_t size)
{
- return driver_realloc(ptr, size);
+ return enif_realloc(ptr, size);
}
void testcase_free(void *ptr)
{
- driver_free(ptr);
+ enif_free(ptr);
}
diff --git a/erts/emulator/test/alloc_SUITE_data/testcase_driver.h b/erts/emulator/test/alloc_SUITE_data/testcase_driver.h
index 5d17eaec64..f0ca91bd06 100644
--- a/erts/emulator/test/alloc_SUITE_data/testcase_driver.h
+++ b/erts/emulator/test/alloc_SUITE_data/testcase_driver.h
@@ -20,13 +20,15 @@
#ifndef TESTCASE_DRIVER_H__
#define TESTCASE_DRIVER_H__
-#include "erl_driver.h"
+#include "erl_nif.h"
#include <stdlib.h>
typedef struct {
+ ErlNifEnv* curr_env;
char *testcase_name;
- char *command;
- int command_len;
+ int thr_nr;
+ int free_mem; /* in bytes */
+ ERL_NIF_TERM build_type; /* opt, debug, valgrind, ... */
void *extra;
} TestCaseState_t;
@@ -34,9 +36,11 @@ typedef struct {
((void) ((B) ? 1 : testcase_assertion_failed((TCS), __FILE__, __LINE__, #B)))
+int testcase_nif_init(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info);
void testcase_printf(TestCaseState_t *tcs, char *frmt, ...);
void testcase_succeeded(TestCaseState_t *tcs, char *frmt, ...);
void testcase_skipped(TestCaseState_t *tcs, char *frmt, ...);
+void testcase_continue(TestCaseState_t *tcs);
void testcase_failed(TestCaseState_t *tcs, char *frmt, ...);
int testcase_assertion_failed(TestCaseState_t *tcs, char *file, int line,
char *assertion);
@@ -45,8 +49,11 @@ void *testcase_realloc(void *ptr, size_t size);
void testcase_free(void *ptr);
+/* Implemented by testcase: */
char *testcase_name(void);
void testcase_run(TestCaseState_t *tcs);
void testcase_cleanup(TestCaseState_t *tcs);
-#endif
+extern ErlNifFunc testcase_nif_funcs[3];
+
+#endif /* TESTCASE_DRIVER_H__ */
diff --git a/erts/emulator/test/alloc_SUITE_data/threads.c b/erts/emulator/test/alloc_SUITE_data/threads.c
index edad24ee6b..a8a6a23695 100644
--- a/erts/emulator/test/alloc_SUITE_data/threads.c
+++ b/erts/emulator/test/alloc_SUITE_data/threads.c
@@ -86,7 +86,7 @@ static void fail(int t_no, char *frmt, ...)
tc_failed = 1;
- if (erl_drv_getenv("ERL_ABORT_ON_FAILURE", buf, &bufsz) == 0
+ if (enif_getenv("ERL_ABORT_ON_FAILURE", buf, &bufsz) == 0
&& strcmp("true", buf) == 0) {
fprintf(stderr, "Testcase \"%s\" failed: %s\n",
testcase_name(), err_buf);
@@ -187,7 +187,6 @@ testcase_run(TestCaseState_t *tcs)
for(i = 1; i <= NO_OF_THREADS; i++) {
char *alc;
- int res;
threads[i].arg.no_ops_per_bl = NO_OF_OPS_PER_BL;
@@ -446,3 +445,6 @@ thread_func(void *arg)
exit_thread(td->t_no, 1);
return NULL;
}
+
+ERL_NIF_INIT(threads, testcase_nif_funcs, testcase_nif_init,
+ NULL, NULL, NULL);
diff --git a/erts/emulator/test/alloc_SUITE_data/threads.erl b/erts/emulator/test/alloc_SUITE_data/threads.erl
new file mode 100644
index 0000000000..a7b4965f5e
--- /dev/null
+++ b/erts/emulator/test/alloc_SUITE_data/threads.erl
@@ -0,0 +1,10 @@
+-module(threads).
+
+-export([init/1, start/1, run/1, stop/1]).
+
+init(File) ->
+ ok = erlang:load_nif(File, 0).
+
+start(_) -> erlang:nif_error(not_loaded).
+run(_) -> erlang:nif_error(not_loaded).
+stop(_) -> erlang:nif_error(not_loaded).
diff --git a/erts/emulator/test/distribution_SUITE_data/run.erl b/erts/emulator/test/distribution_SUITE_data/run.erl
index f5169e160c..d5ed139369 100644
--- a/erts/emulator/test/distribution_SUITE_data/run.erl
+++ b/erts/emulator/test/distribution_SUITE_data/run.erl
@@ -30,16 +30,19 @@ from(H, [_ | T]) -> from(H, T);
from(H, []) -> [].
start() ->
- net_kernel:start([fideridum,shortnames]),
- {ok, Node} = slave:start(host(), heppel),
- P = spawn(Node, a, b, []),
- B1 = term_to_binary(P),
- N1 = node(P),
- ok = net_kernel:stop(),
- N2 = node(P),
- io:format("~w~n", [N1 == N2]),
+ Result = do_it(),
+
+ %% Do GCs and node_and_dist_references
+ %% in an attempt to crash the VM (without OTP-13076 fix)
+ lists:foreach(fun(P) -> erlang:garbage_collect(P) end,
+ processes()),
+ erts_debug:set_internal_state(available_internal_state, true),
+ erts_debug:get_internal_state(node_and_dist_references),
+
+ io:format("~w~n", [Result]),
+
if
- N1 == N2 ->
+ Result ->
init:stop();
true ->
%% Make sure that the io:format/2 output is really written
@@ -47,3 +50,29 @@ start() ->
erlang:yield(),
init:stop()
end.
+
+
+do_it() ->
+ {ok, _} = net_kernel:start([fideridum,shortnames]),
+ {ok, Node} = slave:start(host(), heppel),
+ P = spawn(Node, net_kernel, stop, []),
+ B1 = term_to_binary(P),
+ N1 = node(P),
+ ok = net_kernel:stop(),
+ N2 = node(P),
+
+ %% OTP-13076
+ %% Restart distribution with same node name as previous remote node
+ %% Repeat to wrap around creation
+ Result = lists:foldl(fun(_, Acc) ->
+ timer:sleep(2), % give net_kernel:stop() time to take effect :-(
+ {ok, _} = net_kernel:start([heppel,shortnames]),
+ N3 = node(P),
+ ok = net_kernel:stop(),
+ N4 = node(P),
+ Acc and (N3 =:= N1) and (N4 =:= N1)
+ end,
+ (N2 =:= N1),
+ lists:seq(1,3)),
+
+ Result.
diff --git a/erts/emulator/test/map_SUITE.erl b/erts/emulator/test/map_SUITE.erl
index 886ae7d516..6890c42b7a 100644
--- a/erts/emulator/test/map_SUITE.erl
+++ b/erts/emulator/test/map_SUITE.erl
@@ -58,6 +58,7 @@
%% erlang
t_erlang_hash/1,
t_map_encode_decode/1,
+ t_gc_rare_map_overflow/1,
%% non specific BIF related
t_bif_build_and_check/1,
@@ -121,6 +122,7 @@ all() -> [
%% erlang
t_erlang_hash, t_map_encode_decode,
+ t_gc_rare_map_overflow,
t_map_size, t_is_map,
%% non specific BIF related
@@ -2181,7 +2183,9 @@ t_map_encode_decode(Config) when is_list(Config) ->
{<<>>, sc9}, {3.14158, sc10},
{[3.14158], sc11}, {more_atoms, sc12},
{{more_tuples}, sc13}, {self(), sc14},
- {{},{}},{[],[]}
+ {{},{}},{[],[]},
+ {map_s, #{a=>a, 2=>b, 3=>c}},
+ {map_l, maps:from_list([{I,I}||I <- lists:seq(1,74)])}
],
ok = map_encode_decode_and_match(Pairs,[],#{}),
@@ -2245,9 +2249,30 @@ t_map_encode_decode(Config) when is_list(Config) ->
%% bad size (too small) .. should fail just truncate it .. weird.
%% possibly change external format so truncated will be #{a:=1}
- #{ a:=b } =
- erlang:binary_to_term(<<131,116,0,0,0,1,100,0,1,97,100,0,1,98,97,1,97,1>>),
-
+ #{ a:=b } = erlang:binary_to_term(<<131,116,0,0,0,1,100,0,1,97,100,0,1,98,97,1,97,1>>),
+
+ %% specific fannerl (opensource app) binary_to_term error in 18.1
+
+ #{bias := {1,1,0},
+ bit_fail := 0,
+ connections := #{{2,9} := _,
+ {8,14} := _,
+ {2,12} := _,
+ {5,7} := _,
+ {11,16} := _,
+ {11,15} := _},
+ layers := {5,7,3},
+ network_type := fann_nettype_layer,
+ num_input := 5,
+ num_layers := 3,
+ num_output := 3,
+ rprop_delta_max := _,
+ rprop_delta_min := _,
+ total_connections := 66,
+ total_neurons := 17,
+ train_error_function := fann_errorfunc_tanh,
+ train_stop_function := fann_stopfunc_mse,
+ training_algorithm := fann_train_rprop} = erlang:binary_to_term(fannerl()),
ok.
map_encode_decode_and_match([{K,V}|Pairs], EncodedPairs, M0) ->
@@ -2966,3 +2991,176 @@ do_badmap_17(Config) ->
%% Use this function to avoid compile-time evaluation of an expression.
id(I) -> I.
+
+
+%% OTP-13146
+%% Provoke major GC with a lot of "fat" maps on external format in msg queue
+%% causing heap fragments to be allocated.
+t_gc_rare_map_overflow(Config) ->
+ Pa = filename:dirname(code:which(?MODULE)),
+ {ok, Node} = test_server:start_node(gc_rare_map_overflow, slave, [{args, "-pa \""++Pa++"\""}]),
+ Echo = spawn_link(Node, fun Loop() -> receive {From,Msg} -> From ! Msg
+ end,
+ Loop()
+ end),
+ FatMap = fatmap(34),
+ false = (flatmap =:= erts_internal:map_type(FatMap)),
+
+ t_gc_rare_map_overflow_do(Echo, FatMap, fun() -> erlang:garbage_collect() end),
+
+ % Repeat test for minor gc:
+ minor_collect(), % need this to make the next gc really be a minor
+ t_gc_rare_map_overflow_do(Echo, FatMap, fun() -> true = minor_collect() end),
+
+ unlink(Echo),
+ test_server:stop_node(Node).
+
+t_gc_rare_map_overflow_do(Echo, FatMap, GcFun) ->
+ Master = self(),
+ true = receive M -> false after 0 -> true end, % assert empty msg queue
+ Echo ! {Master, token},
+ repeat(1000, fun(_) -> Echo ! {Master, FatMap} end, void),
+
+ timer:sleep(100), % Wait for maps to arrive in our msg queue
+ token = receive Tok -> Tok end, % and provoke move from outer to inner msg queue
+
+ %% Do GC that will "overflow" and create heap frags due to all the fat maps
+ GcFun(),
+
+ %% Now check that all maps in msg queueu are intact
+ %% Will crash emulator in OTP-18.1
+ repeat(1000, fun(_) -> FatMap = receive FM -> FM end end, void),
+ ok.
+
+minor_collect() ->
+ minor_collect(minor_gcs()).
+
+minor_collect(Before) ->
+ After = minor_gcs(),
+ case After of
+ _ when After > Before -> true;
+ _ when After =:= Before -> minor_collect(Before);
+ 0 -> false
+ end.
+
+minor_gcs() ->
+ {garbage_collection, Info} = process_info(self(), garbage_collection),
+ {minor_gcs, GCS} = lists:keyfind(minor_gcs, 1, Info),
+ GCS.
+
+%% Generate a map with N (or N+1) keys that has an abnormal heap demand.
+%% Done by finding keys that collide in the first 32-bit hash.
+fatmap(N) ->
+ erts_debug:set_internal_state(available_internal_state, true),
+ Table = ets:new(void, [bag, private]),
+
+ Seed0 = rand:seed_s(exsplus, {4711, 3141592, 2718281}),
+ Seed1 = fatmap_populate(Table, Seed0, (1 bsl 16)),
+ Keys = fatmap_generate(Table, Seed1, N, []),
+ ets:delete(Table),
+ maps:from_list([{K,K} || K <- Keys]).
+
+fatmap_populate(_, Seed, 0) -> Seed;
+fatmap_populate(Table, Seed, N) ->
+ {I, NextSeed} = rand:uniform_s(1 bsl 48, Seed),
+ Hash = internal_hash(I),
+ ets:insert(Table, [{Hash, I}]),
+ fatmap_populate(Table, NextSeed, N-1).
+
+
+fatmap_generate(_, _, N, Acc) when N =< 0 ->
+ Acc;
+fatmap_generate(Table, Seed, N0, Acc0) ->
+ {I, NextSeed} = rand:uniform_s(1 bsl 48, Seed),
+ Hash = internal_hash(I),
+ case ets:member(Table, Hash) of
+ true ->
+ NewKeys = [I | ets:lookup_element(Table, Hash, 2)],
+ Acc1 = lists:usort(Acc0 ++ NewKeys),
+ N1 = N0 - (length(Acc1) - length(Acc0)),
+ fatmap_generate(Table, NextSeed, N1, Acc1);
+ false ->
+ fatmap_generate(Table, NextSeed, N0, Acc0)
+ end.
+
+internal_hash(Term) ->
+ erts_debug:get_internal_state({internal_hash, Term}).
+
+
+%% map external_format (fannerl).
+fannerl() ->
+ <<131,116,0,0,0,28,100,0,13,108,101,97,114,110,105,110,103,95,114,
+ 97,116,101,70,63,230,102,102,96,0,0,0,100,0,17,108,101,97,114,110,105,110,
+ 103,95,109,111,109,101,110,116,117,109,70,0,0,0,0,0,0,0,0,100,0,
+ 18,116,114,97,105,110,105,110,103,95,97,108,103,111,114,105,116,104,109,100,0,
+ 16,102,97,110,110,95,116,114,97,105,110,95,114,112,114,111,112,
+ 100,0,17,109,101,97,110,95,115,113,117,97,114,101,95,101,114,114,111,114,70,
+ 0,0,0,0,0,0,0,0,100,0,8,98,105,116,95,102,97,105,108,97,0,100,0,20,
+ 116,114,97,105,110,95,101,114,114,111,114,95,102,117,110,99,116,105,111,
+ 110,100,0,19,102,97,110,110,95,101,114,114,111,114,102,117,110,99,
+ 95,116,97,110,104,100,0,9,110,117,109,95,105,110,112,117,116,97,5,100,0,10,110,
+ 117,109,95,111,117,116,112,117,116,97,3,100,0,13,116,111,116,97,108,
+ 95,110,101,117,114,111,110,115,97,17,100,0,17,116,111,116,97,108,95,99,111,110,
+ 110,101,99,116,105,111,110,115,97,66,100,0,12,110,101,116,119,111,114,107,
+ 95,116,121,112,101,100,0,18,102,97,110,110,95,110,101,116,116,121,112,101,
+ 95,108,97,121,101,114,100,0,15,99,111,110,110,101,99,116,105,111,110,95,
+ 114,97,116,101,70,63,240,0,0,0,0,0,0,100,0,10,110,117,109,95,108,97,121,101,
+ 114,115,97,3,100,0,19,116,114,97,105,110,95,115,116,111,112,95,102,117,110,
+ 99,116,105,111,110,100,0,17,102,97,110,110,95,115,116,111,112,102,117,110,
+ 99,95,109,115,101,100,0,15,113,117,105,99,107,112,114,111,112,95,100,101,99,
+ 97,121,70,191,26,54,226,224,0,0,0,100,0,12,113,117,105,99,107,112,114,
+ 111,112,95,109,117,70,63,252,0,0,0,0,0,0,100,0,21,114,112,114,111,112,95,105,
+ 110,99,114,101,97,115,101,95,102,97,99,116,111,114,70,63,243,51,51,
+ 64,0,0,0,100,0,21,114,112,114,111,112,95,100,101,99,114,101,97,115,101,
+ 95,102,97,99,116,111,114,70,63,224,0,0,0,0,0,0,100,0,15,114,112,114,111,112,
+ 95,100,101,108,116,97,95,109,105,110,70,0,0,0,0,0,0,0,0,100,0,15,114,112,114,
+ 111,112,95,100,101,108,116,97,95,109,97,120,70,64,73,0,0,0,0,0,0,100,0,
+ 16,114,112,114,111,112,95,100,101,108,116,97,95,122,101,114,111,70,63,185,153,
+ 153,160,0,0,0,100,0,26,115,97,114,112,114,111,112,95,119,101,105,103,
+ 104,116,95,100,101,99,97,121,95,115,104,105,102,116,70,192,26,147,116,192,0,0,0,
+ 100,0,35,115,97,114,112,114,111,112,95,115,116,101,112,95,101,114,
+ 114,111,114,95,116,104,114,101,115,104,111,108,100,95,102,97,99,116,111,114,70,
+ 63,185,153,153,160,0,0,0,100,0,24,115,97,114,112,114,111,112,95,115,
+ 116,101,112,95,101,114,114,111,114,95,115,104,105,102,116,70,63,246,40,245,
+ 192,0,0,0,100,0,19,115,97,114,112,114,111,112,95,116,101,109,112,101,114,
+ 97,116,117,114,101,70,63,142,184,81,224,0,0,0,100,0,6,108,97,121,101,114,115,
+ 104,3,97,5,97,7,97,3,100,0,4,98,105,97,115,104,3,97,1,97,1,97,0,100,0,11,
+ 99,111,110,110,101,99,116,105,111,110,115,116,0,0,0,66,104,2,97,0,97,6,70,
+ 191,179,51,44,64,0,0,0,104,2,97,1,97,6,70,63,178,130,90,32,0,0,0,104,2,97,2,
+ 97,6,70,63,82,90,88,0,0,0,0,104,2,97,3,97,6,70,63,162,91,63,192,0,0,0,104,2,
+ 97,4,97,6,70,191,151,70,169,0,0,0,0,104,2,97,5,97,6,70,191,117,52,222,0,0,0,
+ 0,104,2,97,0,97,7,70,63,152,240,139,0,0,0,0,104,2,97,1,97,7,70,191,166,31,
+ 187,160,0,0,0,104,2,97,2,97,7,70,191,150,70,63,0,0,0,0,104,2,97,3,97,7,70,
+ 63,152,181,126,128,0,0,0,104,2,97,4,97,7,70,63,151,187,162,128,0,0,0,104,2,
+ 97,5,97,7,70,191,143,161,101,0,0,0,0,104,2,97,0,97,8,70,191,153,102,36,128,0,
+ 0,0,104,2,97,1,97,8,70,63,160,139,250,64,0,0,0,104,2,97,2,97,8,70,63,164,62,
+ 196,64,0,0,0,104,2,97,3,97,8,70,191,178,78,209,192,0,0,0,104,2,97,4,97,8,70,
+ 191,185,19,76,224,0,0,0,104,2,97,5,97,8,70,63,183,142,196,96,0,0,0,104,2,97,0,
+ 97,9,70,63,150,104,248,0,0,0,0,104,2,97,1,97,9,70,191,164,4,100,224,0,0,0,
+ 104,2,97,2,97,9,70,191,169,42,42,224,0,0,0,104,2,97,3,97,9,70,63,145,54,78,128,0,
+ 0,0,104,2,97,4,97,9,70,63,126,243,134,0,0,0,0,104,2,97,5,97,9,70,63,177,
+ 203,25,96,0,0,0,104,2,97,0,97,10,70,63,172,104,47,64,0,0,0,104,2,97,1,97,10,
+ 70,63,161,242,193,64,0,0,0,104,2,97,2,97,10,70,63,175,208,241,192,0,0,0,104,2,
+ 97,3,97,10,70,191,129,202,161,0,0,0,0,104,2,97,4,97,10,70,63,178,151,55,32,0,0,0,
+ 104,2,97,5,97,10,70,63,137,155,94,0,0,0,0,104,2,97,0,97,11,70,191,179,
+ 106,160,0,0,0,0,104,2,97,1,97,11,70,63,184,253,164,96,0,0,0,104,2,97,2,97,11,
+ 70,191,143,30,157,0,0,0,0,104,2,97,3,97,11,70,63,153,225,140,128,0,0,0,104,
+ 2,97,4,97,11,70,63,161,35,85,192,0,0,0,104,2,97,5,97,11,70,63,175,200,55,192,
+ 0,0,0,104,2,97,0,97,12,70,191,180,116,132,96,0,0,0,104,2,97,1,97,12,70,191,
+ 165,151,152,0,0,0,0,104,2,97,2,97,12,70,191,180,197,91,160,0,0,0,104,2,97,3,97,12,
+ 70,191,91,30,160,0,0,0,0,104,2,97,4,97,12,70,63,180,251,45,32,0,0,0,
+ 104,2,97,5,97,12,70,63,165,134,77,64,0,0,0,104,2,97,6,97,14,70,63,181,56,242,96,
+ 0,0,0,104,2,97,7,97,14,70,191,165,239,234,224,0,0,0,104,2,97,8,97,14,
+ 70,191,154,65,216,128,0,0,0,104,2,97,9,97,14,70,63,150,250,236,0,0,0,0,104,2,97,
+ 10,97,14,70,191,141,105,108,0,0,0,0,104,2,97,11,97,14,70,191,152,40,
+ 165,0,0,0,0,104,2,97,12,97,14,70,63,141,159,46,0,0,0,0,104,2,97,13,97,14,70,
+ 191,183,172,137,32,0,0,0,104,2,97,6,97,15,70,63,163,26,123,192,0,0,0,104,
+ 2,97,7,97,15,70,63,176,184,106,32,0,0,0,104,2,97,8,97,15,70,63,152,234,144,
+ 0,0,0,0,104,2,97,9,97,15,70,191,172,58,70,160,0,0,0,104,2,97,10,97,15,70,
+ 63,161,211,211,192,0,0,0,104,2,97,11,97,15,70,191,148,171,120,128,0,0,0,104,
+ 2,97,12,97,15,70,63,180,117,214,224,0,0,0,104,2,97,13,97,15,70,191,104,
+ 230,216,0,0,0,0,104,2,97,6,97,16,70,63,178,53,103,96,0,0,0,104,2,97,7,97,16,
+ 70,63,170,230,232,64,0,0,0,104,2,97,8,97,16,70,191,183,45,100,192,0,0,0,
+ 104,2,97,9,97,16,70,63,184,100,97,32,0,0,0,104,2,97,10,97,16,70,63,169,174,
+ 254,64,0,0,0,104,2,97,11,97,16,70,191,119,121,234,0,0,0,0,104,2,97,12,97,
+ 16,70,63,149,12,170,128,0,0,0,104,2,97,13,97,16,70,191,144,193,191,0,0,0,0>>.
diff --git a/erts/emulator/test/nif_SUITE_data/nif_mod.c b/erts/emulator/test/nif_SUITE_data/nif_mod.c
index 9c78c0e04d..f7e729e2b6 100644
--- a/erts/emulator/test/nif_SUITE_data/nif_mod.c
+++ b/erts/emulator/test/nif_SUITE_data/nif_mod.c
@@ -240,7 +240,7 @@ static ERL_NIF_TERM lib_version(ErlNifEnv* env, int argc, const ERL_NIF_TERM arg
static ERL_NIF_TERM get_priv_data_ptr(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
ADD_CALL("get_priv_data_ptr");
- return enif_make_ulong(env, (unsigned long)priv_data(env));
+ return enif_make_uint64(env, (ErlNifUInt64)priv_data(env));
}
static ERL_NIF_TERM make_new_resource(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
diff --git a/erts/emulator/test/process_SUITE.erl b/erts/emulator/test/process_SUITE.erl
index 4c311e1f06..97aa5e573e 100644
--- a/erts/emulator/test/process_SUITE.erl
+++ b/erts/emulator/test/process_SUITE.erl
@@ -1478,7 +1478,15 @@ processes_this_tab(doc) ->
processes_this_tab(suite) ->
[];
processes_this_tab(Config) when is_list(Config) ->
- sys_mem_cond_run(1024, fun () -> chk_processes_bif_test_res(processes_bif_test()) end).
+ Mem = case {erlang:system_info(build_type),
+ erlang:system_info(allocator)} of
+ {lcnt, {_, _Vsn, [sys_alloc], _Opts}} ->
+ %% When running +Mea min + lcnt we may need more memory
+ 1024 * 4;
+ _ ->
+ 1024
+ end,
+ sys_mem_cond_run(Mem, fun () -> chk_processes_bif_test_res(processes_bif_test()) end).
chk_processes_bif_test_res(ok) -> ok;
chk_processes_bif_test_res({comment, _} = Comment) -> Comment;
diff --git a/erts/epmd/src/epmd.c b/erts/epmd/src/epmd.c
index 132bda725c..63ec18d939 100644
--- a/erts/epmd/src/epmd.c
+++ b/erts/epmd/src/epmd.c
@@ -29,7 +29,7 @@
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif
-
+#include <time.h>
/* forward declarations */
static void usage(EpmdVars *);
diff --git a/erts/etc/common/ct_run.c b/erts/etc/common/ct_run.c
index 548514ee6c..11cec26264 100644
--- a/erts/etc/common/ct_run.c
+++ b/erts/etc/common/ct_run.c
@@ -83,7 +83,6 @@ static int eargc; /* Number of arguments in eargv. */
static void error(char* format, ...);
static char* emalloc(size_t size);
static char* strsave(char* string);
-static void push_words(char* src);
static int run_erlang(char* name, char** argv);
static char* get_default_emulator(char* progname);
#ifdef __WIN32__
@@ -152,6 +151,8 @@ int main(int argc, char** argv)
argv0 = argv;
emulator = get_default_emulator(argv[0]);
+ if (strlen(emulator) >= MAXPATHLEN)
+ error("Emulator path length is too large");
/*
* Allocate the argv vector to be used for arguments to Erlang.
@@ -163,7 +164,7 @@ int main(int argc, char** argv)
eargv_base = (char **) emalloc(eargv_size*sizeof(char*));
eargv = eargv_base;
eargc = 0;
- push_words(emulator);
+ PUSH(strsave(emulator));
eargc_base = eargc;
eargv = eargv + eargv_size/2;
eargc = 0;
@@ -294,26 +295,6 @@ int main(int argc, char** argv)
return run_erlang(eargv[0], eargv);
}
-static void
-push_words(char* src)
-{
- char sbuf[MAXPATHLEN];
- char* dst;
-
- dst = sbuf;
- while ((*dst++ = *src++) != '\0') {
- if (isspace((int)*src)) {
- *dst = '\0';
- PUSH(strsave(sbuf));
- dst = sbuf;
- do {
- src++;
- } while (isspace((int)*src));
- }
- }
- if (sbuf[0])
- PUSH(strsave(sbuf));
-}
#ifdef __WIN32__
wchar_t *make_commandline(char **argv)
{
diff --git a/erts/etc/common/dialyzer.c b/erts/etc/common/dialyzer.c
index c45626606c..cac1464bf6 100644
--- a/erts/etc/common/dialyzer.c
+++ b/erts/etc/common/dialyzer.c
@@ -65,7 +65,6 @@ static int eargc; /* Number of arguments in eargv. */
static void error(char* format, ...);
static char* emalloc(size_t size);
static char* strsave(char* string);
-static void push_words(char* src);
static int run_erlang(char* name, char** argv);
static char* get_default_emulator(char* progname);
#ifdef __WIN32__
@@ -189,7 +188,7 @@ int main(int argc, char** argv)
eargv_base = (char **) emalloc(eargv_size*sizeof(char*));
eargv = eargv_base;
eargc = 0;
- push_words(emulator);
+ PUSH(strsave(emulator));
eargc_base = eargc;
eargv = eargv + eargv_size/2;
eargc = 0;
@@ -269,27 +268,6 @@ int main(int argc, char** argv)
return run_erlang(eargv[0], eargv);
}
-static void
-push_words(char* src)
-{
- char sbuf[MAXPATHLEN];
- char* dst;
-
- dst = sbuf;
- while ((*dst++ = *src++) != '\0') {
- if (isspace((int)*src)) {
- *dst = '\0';
- PUSH(strsave(sbuf));
- dst = sbuf;
- do {
- src++;
- } while (isspace((int)*src));
- }
- }
- if (sbuf[0])
- PUSH(strsave(sbuf));
-}
-
#ifdef __WIN32__
wchar_t *make_commandline(char **argv)
{
diff --git a/erts/etc/common/erlc.c b/erts/etc/common/erlc.c
index f9d909e01c..049afc526a 100644
--- a/erts/etc/common/erlc.c
+++ b/erts/etc/common/erlc.c
@@ -200,7 +200,7 @@ int main(int argc, char** argv)
eargv_base = (char **) emalloc(eargv_size*sizeof(char*));
eargv = eargv_base;
eargc = 0;
- push_words(emulator);
+ PUSH(strsave(emulator));
eargc_base = eargc;
eargv = eargv + eargv_size/2;
eargc = 0;
@@ -330,26 +330,6 @@ process_opt(int* pArgc, char*** pArgv, int offset)
return argv[1];
}
-static void
-push_words(char* src)
-{
- char sbuf[MAXPATHLEN];
- char* dst;
-
- dst = sbuf;
- while ((*dst++ = *src++) != '\0') {
- if (isspace((int)*src)) {
- *dst = '\0';
- PUSH(strsave(sbuf));
- dst = sbuf;
- do {
- src++;
- } while (isspace((int)*src));
- }
- }
- if (sbuf[0])
- PUSH(strsave(sbuf));
-}
#ifdef __WIN32__
wchar_t *make_commandline(char **argv)
{
diff --git a/erts/etc/common/erlexec.c b/erts/etc/common/erlexec.c
index cde0b25a2a..af1c198281 100644
--- a/erts/etc/common/erlexec.c
+++ b/erts/etc/common/erlexec.c
@@ -73,6 +73,7 @@ static const char plusM_au_allocs[]= {
'R', /* driver_alloc */
'S', /* sl_alloc */
'T', /* temp_alloc */
+ 'Z', /* test_alloc */
'\0'
};
@@ -718,7 +719,7 @@ int main(int argc, char **argv)
* on itself here. We'll avoid doing that.
*/
if (strcmp(argv[i], "-make") == 0) {
- add_args("-noshell", "-noinput", "-s", "make", "all", NULL);
+ add_args("-noshell", "-noinput", "-s", "make", "all_or_nothing", NULL);
add_Eargs("-B");
haltAfterwards = 1;
i = argc; /* Skip rest of command line */
diff --git a/erts/etc/common/escript.c b/erts/etc/common/escript.c
index 7fd02ed436..a5c6d0d40b 100644
--- a/erts/etc/common/escript.c
+++ b/erts/etc/common/escript.c
@@ -74,7 +74,6 @@ static void error(char* format, ...);
static char* emalloc(size_t size);
static void efree(void *p);
static char* strsave(char* string);
-static void push_words(char* src);
static int run_erlang(char* name, char** argv);
static char* get_default_emulator(char* progname);
#ifdef __WIN32__
@@ -432,7 +431,7 @@ main(int argc, char** argv)
emulator = get_default_emulator(argv[0]);
}
- if (strlen(emulator) >= PMAX)
+ if (strlen(emulator) >= MAXPATHLEN)
error("Value of environment variable ESCRIPT_EMULATOR is too large");
/*
@@ -445,7 +444,7 @@ main(int argc, char** argv)
eargv_base = (char **) emalloc(eargv_size*sizeof(char*));
eargv = eargv_base;
eargc = 0;
- push_words(emulator);
+ PUSH(strsave(emulator));
eargc_base = eargc;
eargv = eargv + eargv_size/2;
eargc = 0;
@@ -554,26 +553,6 @@ main(int argc, char** argv)
return run_erlang(eargv[0], eargv);
}
-static void
-push_words(char* src)
-{
- char sbuf[PMAX];
- char* dst;
-
- dst = sbuf;
- while ((*dst++ = *src++) != '\0') {
- if (isspace((int)*src)) {
- *dst = '\0';
- PUSH(strsave(sbuf));
- dst = sbuf;
- do {
- src++;
- } while (isspace((int)*src));
- }
- }
- if (sbuf[0])
- PUSH(strsave(sbuf));
-}
#ifdef __WIN32__
wchar_t *make_commandline(char **argv)
{
diff --git a/erts/etc/common/heart.c b/erts/etc/common/heart.c
index 01ef840b5d..9571b83ffd 100644
--- a/erts/etc/common/heart.c
+++ b/erts/etc/common/heart.c
@@ -718,14 +718,12 @@ do_terminate(int erlin_fd, int reason) {
print_error("Would reboot. Terminating.");
else {
kill_old_erlang();
- /* suppress gcc warning with 'if' */
ret = system(command);
print_error("Executed \"%s\" -> %d. Terminating.",command, ret);
}
free_env_val(command);
} else {
kill_old_erlang();
- /* suppress gcc warning with 'if' */
ret = system((char*)&cmd[0]);
print_error("Executed \"%s\" -> %d. Terminating.",cmd, ret);
}
diff --git a/erts/etc/common/typer.c b/erts/etc/common/typer.c
index 0aa0996808..7ff8aa76e2 100644
--- a/erts/etc/common/typer.c
+++ b/erts/etc/common/typer.c
@@ -65,7 +65,6 @@ static int eargc; /* Number of arguments in eargv. */
static void error(char* format, ...);
static char* emalloc(size_t size);
static char* strsave(char* string);
-static void push_words(char* src);
static int run_erlang(char* name, char** argv);
static char* get_default_emulator(char* progname);
#ifdef __WIN32__
@@ -129,6 +128,9 @@ main(int argc, char** argv)
emulator = get_default_emulator(argv[0]);
+ if (strlen(emulator) >= MAXPATHLEN)
+ error("Emulator path length is too large");
+
/*
* Allocate the argv vector to be used for arguments to Erlang.
* Arrange for starting to pushing information in the middle of
@@ -139,7 +141,7 @@ main(int argc, char** argv)
eargv_base = (char **) emalloc(eargv_size*sizeof(char*));
eargv = eargv_base;
eargc = 0;
- push_words(emulator);
+ PUSH(strsave(emulator));
eargc_base = eargc;
eargv = eargv + eargv_size/2;
eargc = 0;
@@ -192,26 +194,6 @@ main(int argc, char** argv)
return run_erlang(eargv[0], eargv);
}
-static void
-push_words(char* src)
-{
- char sbuf[MAXPATHLEN];
- char* dst;
-
- dst = sbuf;
- while ((*dst++ = *src++) != '\0') {
- if (isspace((int)*src)) {
- *dst = '\0';
- PUSH(strsave(sbuf));
- dst = sbuf;
- do {
- src++;
- } while (isspace((int)*src));
- }
- }
- if (sbuf[0])
- PUSH(strsave(sbuf));
-}
#ifdef __WIN32__
wchar_t *make_commandline(char **argv)
{
diff --git a/erts/etc/win32/msys_tools/vc/cc.sh b/erts/etc/win32/msys_tools/vc/cc.sh
index ad05e5375b..ac89aac34e 100644
--- a/erts/etc/win32/msys_tools/vc/cc.sh
+++ b/erts/etc/win32/msys_tools/vc/cc.sh
@@ -242,7 +242,7 @@ for x in $SOURCES; do
if [ $PREPROCESSING = true ]; then
output_flag="-E"
else
- output_flag="-c -Fo`cmd //C echo ${output_filename}`"
+ output_flag="-FS -c -Fo`cmd //C echo ${output_filename}`"
fi
params="$COMMON_CFLAGS $MD $DEBUG_FLAGS $OPTIMIZE_FLAGS \
$CMD ${output_flag} $MPATH"
@@ -250,6 +250,8 @@ for x in $SOURCES; do
echo cc.sh "$SAVE" >>$CC_SH_DEBUG_LOG
echo cl.exe $params >>$CC_SH_DEBUG_LOG
fi
+ # MSYS2 (currently) converts the paths wrong, avoid it
+ export MSYS2_ARG_CONV_EXCL=-FoC
eval cl.exe $params >$MSG_FILE 2>$ERR_FILE
RES=$?
if test $PREPROCESSING = false; then
@@ -274,6 +276,7 @@ for x in $SOURCES; do
fi
rm -f $ERR_FILE $MSG_FILE
if [ $RES != 0 ]; then
+ echo Failed: cl.exe $params
rm -rf $TMPOBJDIR
exit $RES
fi
@@ -312,7 +315,10 @@ if [ $LINKING = true ]; then
stdlib="-lLIBMTD";;
esac
# And finally call the next script to do the linking...
- params="$out_spec $LINKCMD $stdlib"
+ params="$out_spec $LINKCMD $stdlib"
+ if [ "X$CC_SH_DEBUG_LOG" != "X" ]; then
+ echo ld.sh $ACCUM_OBJECTS $params
+ fi
eval ld.sh $ACCUM_OBJECTS $params
RES=$?
fi
diff --git a/erts/etc/win32/msys_tools/vc/emu_cc.sh b/erts/etc/win32/msys_tools/vc/emu_cc.sh
index 01f75b2468..10d59214ea 100644
--- a/erts/etc/win32/msys_tools/vc/emu_cc.sh
+++ b/erts/etc/win32/msys_tools/vc/emu_cc.sh
@@ -29,6 +29,7 @@ WTOOLDIR0=`win2msys_path.sh "$TOOLDIR"`
WTOOLDIR=`cmd //C echo $WTOOLDIR0`
# Do primitive 'make'
newer_exe=`find $TOOLDIR -newer $COFFIX.c -name coffix.exe -print`
+export MSYS2_ARG_CONV_EXCL="-FeC"
if [ -z $newer_exe ]; then
echo recompiling $COFFIX.exe
cl.exe -Fe${WTOOLDIR}/coffix.exe ${WTOOLDIR}/coffix.c
diff --git a/erts/etc/win32/msys_tools/vc/mc.sh b/erts/etc/win32/msys_tools/vc/mc.sh
index e9ea9ff9a9..14b5ebaa8f 100644
--- a/erts/etc/win32/msys_tools/vc/mc.sh
+++ b/erts/etc/win32/msys_tools/vc/mc.sh
@@ -80,9 +80,14 @@ if [ -n "$OUTPUT_DIRNAME" ]; then
exit $RES
fi
fi
+# MSYS2 (currently) converts the paths wrong, avoid it
+export MSYS2_ARG_CONV_EXCL=
eval $MCC "$CMD" >/tmp/mc.exe.${p}.1 2>/tmp/mc.exe.${p}.2
RES=$?
-tail +2 /tmp/mc.exe.${p}.2 >&2
+if [ $RES != 0 ]; then
+ echo Failed: $MCC "$CMD"
+fi
+tail -n +2 /tmp/mc.exe.${p}.2 >&2
cat /tmp/mc.exe.${p}.1
rm -f /tmp/mc.exe.${p}.2 /tmp/mc.exe.${p}.1
exit $RES
diff --git a/erts/etc/win32/msys_tools/vc/rc.sh b/erts/etc/win32/msys_tools/vc/rc.sh
index 1b3b1c85bd..1f8ade17cb 100644
--- a/erts/etc/win32/msys_tools/vc/rc.sh
+++ b/erts/etc/win32/msys_tools/vc/rc.sh
@@ -79,9 +79,14 @@ if [ "X$RC_SH_DEBUG_LOG" != "X" ]; then
echo rc.sh "$SAVE" >>$RC_SH_DEBUG_LOG
echo rc.exe $CMD >>$RC_SH_DEBUG_LOG
fi
+# MSYS2 (currently) converts the paths wrong, avoid it
+export MSYS2_ARG_CONV_EXCL=-Fo
eval $RCC "$CMD" >/tmp/rc.exe.${p}.1 2>/tmp/rc.exe.${p}.2
RES=$?
-tail +2 /tmp/rc.exe.${p}.2 >&2
+if [ $RES != 0 ]; then
+ echo Failed: $RCC "$CMD"
+fi
+tail -n +2 /tmp/rc.exe.${p}.2 >&2
cat /tmp/rc.exe.${p}.1
rm -f /tmp/rc.exe.${p}.2 /tmp/rc.exe.${p}.1
exit $RES
diff --git a/erts/etc/win32/nsis/Makefile b/erts/etc/win32/nsis/Makefile
index 49d835170a..64f44ff86d 100644
--- a/erts/etc/win32/nsis/Makefile
+++ b/erts/etc/win32/nsis/Makefile
@@ -42,7 +42,13 @@ include $(ERL_TOP)/make/otp_release_targets.mk
TARGET_DIR = $(RELEASE_PATH)
-ifeq ($(MSYSTEM),MINGW32)
+ifdef MSYSTEM
+ ifeq ($(MSYSTEM),$(filter $(MSYSTEM),MSYS MINGW32 MINGW64))
+ USEMSYS := true
+ endif
+endif
+
+ifeq ($(USEMSYS),true)
MAKENSISFLAGS = //V2
WTESTROOT=$(shell (msys2win_path.sh "$(RELEASE_PATH)"))
@@ -63,7 +69,7 @@ else
endif
REDIST_FILE=$(shell (sh ./find_redist.sh || echo ""))
-ifeq ($(MSYSTEM),MINGW32)
+ifeq ($(USEMSYS),true)
NICEREDISTFILE=$(shell (msys2win_path.sh -m "$(REDIST_FILE)" 2>/dev/null || echo ""))
else
NICEREDISTFILE=$(shell (cygpath -d -m "$(REDIST_FILE)" 2>/dev/null || echo ""))
diff --git a/erts/etc/win32/nsis/find_redist.sh b/erts/etc/win32/nsis/find_redist.sh
index c0895c9dd5..03e92b21c7 100755
--- a/erts/etc/win32/nsis/find_redist.sh
+++ b/erts/etc/win32/nsis/find_redist.sh
@@ -164,7 +164,7 @@ fi
#echo $BPATH_LIST
for BP in $BPATH_LIST; do
- for verdir in "sdk v2.0" "sdk v3.5" "v6.0A" "v7.0" "v7.0A" "v7.1"; do
+ for verdir in "sdk v2.0" "sdk v3.5" "v6.0A" "v7.0" "v7.0A" "v7.1" "VC redist 1033"; do
BPATH=$BP
fail=false
allow_fail=false
diff --git a/erts/include/internal/ethread.h b/erts/include/internal/ethread.h
index f9c203e97c..8964f95652 100644
--- a/erts/include/internal/ethread.h
+++ b/erts/include/internal/ethread.h
@@ -54,7 +54,8 @@
#endif
#if defined(ETHR_DEBUG) || !defined(ETHR_INLINE) || ETHR_XCHK \
- || (defined(__GNUC__) && defined(ERTS_MIXED_CYGWIN_VC))
+ || (defined(__GNUC__) && defined(ERTS_MIXED_CYGWIN_VC)) \
+ || (defined(__GNUC__) && defined(ERTS_MIXED_MSYS_VC))
# undef ETHR_INLINE
# define ETHR_INLINE
# undef ETHR_FORCE_INLINE
diff --git a/erts/preloaded/ebin/init.beam b/erts/preloaded/ebin/init.beam
index 851513b2e9..73dfb3d351 100644
--- a/erts/preloaded/ebin/init.beam
+++ b/erts/preloaded/ebin/init.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_inet.beam b/erts/preloaded/ebin/prim_inet.beam
index 5a188be3ba..8b87d1ae26 100644
--- a/erts/preloaded/ebin/prim_inet.beam
+++ b/erts/preloaded/ebin/prim_inet.beam
Binary files differ
diff --git a/erts/preloaded/src/erlang.erl b/erts/preloaded/src/erlang.erl
index 291356c7b1..7280b43502 100644
--- a/erts/preloaded/src/erlang.erl
+++ b/erts/preloaded/src/erlang.erl
@@ -1974,6 +1974,7 @@ localtime_to_universaltime(_Localtime, _IsDst) ->
%% CHECK! Why the strange very thorough specification of the error
%% condition with disallowed arity in erl_bif_types?
%% Not documented
+%% Shadowed by erl_bif_types: erlang:make_fun/3
-spec erlang:make_fun(Module, Function, Arity) -> function() when
Module :: atom(),
Function :: atom(),
@@ -2423,7 +2424,7 @@ tuple_to_list(_Tuple) ->
MinBinVHeapSize :: pos_integer()};
(modified_timing_level) -> integer() | undefined;
(multi_scheduling) -> disabled | blocked | enabled;
- (multi_scheduling_blockers) -> [PID :: pid()];
+ (multi_scheduling_blockers) -> [Pid :: pid()];
(nif_version) -> string();
(otp_release) -> string();
(os_monotonic_time_source) -> [{atom(),term()}];
diff --git a/erts/preloaded/src/init.erl b/erts/preloaded/src/init.erl
index c4e37b76f1..0ad5824ad1 100644
--- a/erts/preloaded/src/init.erl
+++ b/erts/preloaded/src/init.erl
@@ -167,7 +167,6 @@ stop(Status) -> init ! {stop,{stop,Status}}, ok.
boot(BootArgs) ->
register(init, self()),
process_flag(trap_exit, true),
- start_on_load_handler_process(),
{Start0,Flags,Args} = parse_boot_args(BootArgs),
Start = map(fun prepare_run_args/1, Start0),
Flags0 = flags_to_atoms_again(Flags),
@@ -225,6 +224,7 @@ code_path_choice() ->
end.
boot(Start,Flags,Args) ->
+ start_on_load_handler_process(),
BootPid = do_boot(Flags,Start),
State = #state{flags = Flags,
args = Args,
diff --git a/erts/preloaded/src/prim_inet.erl b/erts/preloaded/src/prim_inet.erl
index 4d04e1dacb..bd74831bb7 100644
--- a/erts/preloaded/src/prim_inet.erl
+++ b/erts/preloaded/src/prim_inet.erl
@@ -232,7 +232,7 @@ bindx(S, AddFlag, Addrs) ->
%% if timeout is given:
%% timeout < 0 -> infinity
%% 0 -> immediate connect (mostly works for loopback)
-%% > 0 -> wait for timout ms if not connected then
+%% > 0 -> wait for timeout ms if not connected then
%% return {error, timeout}
%%
%% ASYNC_CONNECT(insock(), IP, Port, Timeout) -> {ok, S, Ref} | {error, Reason}
@@ -273,7 +273,7 @@ async_connect(S, IP, Port, Time) ->
%% if timeout is given:
%% timeout < 0 -> infinity
%% 0 -> immediate accept (poll)
-%% > 0 -> wait for timout ms for accept if no accept then
+%% > 0 -> wait for timeout ms for accept if no accept then
%% return {error, timeout}
%%
%% ASYNC_ACCEPT(insock(), Timeout)
@@ -1147,6 +1147,7 @@ enc_opt(packet_size) -> ?INET_LOPT_PACKET_SIZE;
enc_opt(read_packets) -> ?INET_LOPT_READ_PACKETS;
enc_opt(netns) -> ?INET_LOPT_NETNS;
enc_opt(show_econnreset) -> ?INET_LOPT_TCP_SHOW_ECONNRESET;
+enc_opt(line_delimiter) -> ?INET_LOPT_LINE_DELIM;
enc_opt(raw) -> ?INET_OPT_RAW;
% Names of SCTP opts:
enc_opt(sctp_rtoinfo) -> ?SCTP_OPT_RTOINFO;
@@ -1205,6 +1206,7 @@ dec_opt(?INET_LOPT_PACKET_SIZE) -> packet_size;
dec_opt(?INET_LOPT_READ_PACKETS) -> read_packets;
dec_opt(?INET_LOPT_NETNS) -> netns;
dec_opt(?INET_LOPT_TCP_SHOW_ECONNRESET) -> show_econnreset;
+dec_opt(?INET_LOPT_LINE_DELIM) -> line_delimiter;
dec_opt(?INET_OPT_RAW) -> raw;
dec_opt(I) when is_integer(I) -> undefined.
@@ -1287,6 +1289,7 @@ type_opt_1(packet) ->
{httph_bin,?TCP_PB_HTTPH_BIN},
{ssl, ?TCP_PB_SSL_TLS}, % obsolete
{ssl_tls, ?TCP_PB_SSL_TLS}]};
+type_opt_1(line_delimiter) -> int;
type_opt_1(mode) ->
{enum,[{list, ?INET_MODE_LIST},
{binary, ?INET_MODE_BINARY}]};
diff --git a/lib/asn1/src/asn1rtt_ber.erl b/lib/asn1/src/asn1rtt_ber.erl
index 39fa8aaf99..e50b14941c 100644
--- a/lib/asn1/src/asn1rtt_ber.erl
+++ b/lib/asn1/src/asn1rtt_ber.erl
@@ -739,6 +739,8 @@ encode_named_bit_string([H|_]=Bits, NamedBitList, TagIn) when is_atom(H) ->
do_encode_named_bit_string(Bits, NamedBitList, TagIn);
encode_named_bit_string([{bit,_}|_]=Bits, NamedBitList, TagIn) ->
do_encode_named_bit_string(Bits, NamedBitList, TagIn);
+encode_named_bit_string([], _NamedBitList, TagIn) ->
+ encode_unnamed_bit_string(<<>>, TagIn);
encode_named_bit_string(Bits, _NamedBitList, TagIn) when is_bitstring(Bits) ->
encode_unnamed_bit_string(Bits, TagIn).
@@ -746,6 +748,8 @@ encode_named_bit_string(C, [H|_]=Bits, NamedBitList, TagIn) when is_atom(H) ->
do_encode_named_bit_string(C, Bits, NamedBitList, TagIn);
encode_named_bit_string(C, [{bit,_}|_]=Bits, NamedBitList, TagIn) ->
do_encode_named_bit_string(C, Bits, NamedBitList, TagIn);
+encode_named_bit_string(C, [], _NamedBitList, TagIn) ->
+ encode_unnamed_bit_string(C, <<>>, TagIn);
encode_named_bit_string(C, Bits, _NamedBitList, TagIn) when is_bitstring(Bits) ->
encode_unnamed_bit_string(C, Bits, TagIn).
diff --git a/lib/asn1/test/testPrimStrings.erl b/lib/asn1/test/testPrimStrings.erl
index fa778765b1..46793c6bff 100644
--- a/lib/asn1/test/testPrimStrings.erl
+++ b/lib/asn1/test/testPrimStrings.erl
@@ -123,6 +123,7 @@ bit_string(Rules, Opts) ->
%% Bs2 ::= BIT STRING {su(0), mo(1), tu(2), we(3), th(4), fr(5), sa(6) } (SIZE (7))
%%==========================================================
+ roundtrip('Bs2', []),
roundtrip('Bs2', [mo,tu,fr]),
bs_roundtrip('Bs2', <<2#0110010:7>>, [mo,tu,fr]),
bs_roundtrip('Bs2', <<2#0110011:7>>, [mo,tu,fr,sa]),
@@ -131,6 +132,7 @@ bit_string(Rules, Opts) ->
%% Bs3 ::= BIT STRING {su(0), mo(1), tu(2), we(3), th(4), fr(5), sa(6) } (SIZE (1..7))
%%==========================================================
+ roundtrip('Bs3', []),
roundtrip('Bs3', [mo,tu,fr]),
bs_roundtrip('Bs3', <<2#0110010:7>>, [mo,tu,fr]),
bs_roundtrip('Bs3', <<2#0110010:7>>, [mo,tu,fr]),
@@ -139,6 +141,13 @@ bit_string(Rules, Opts) ->
bs_roundtrip('Bs3', <<2#11:2>>, [su,mo]),
%%==========================================================
+ %% Bs4 ::= BIT STRING {su(0), mo(1), tu(2), we(3), th(4), fr(5), sa(6) }
+ %%==========================================================
+
+ roundtrip('Bs4', []),
+ roundtrip('Bs4', [mo,tu,fr,sa]),
+
+ %%==========================================================
%% Bs7 ::= BIT STRING (SIZE (24))
%%==========================================================
diff --git a/lib/common_test/src/ct_conn_log_h.erl b/lib/common_test/src/ct_conn_log_h.erl
index 2dd4fdac05..5239ec1ff8 100644
--- a/lib/common_test/src/ct_conn_log_h.erl
+++ b/lib/common_test/src/ct_conn_log_h.erl
@@ -104,18 +104,26 @@ terminate(_,#state{logs=Logs}) ->
%%%-----------------------------------------------------------------
%%% Writing reports
write_report(_Time,#conn_log{header=false,module=ConnMod}=Info,Data,GL,State) ->
- {LogType,Fd} = get_log(Info,GL,State),
- io:format(Fd,"~n~ts",[format_data(ConnMod,LogType,Data)]);
+ case get_log(Info,GL,State) of
+ {silent,_} ->
+ ok;
+ {LogType,Fd} ->
+ io:format(Fd,"~n~ts",[format_data(ConnMod,LogType,Data)])
+ end;
write_report(Time,#conn_log{module=ConnMod}=Info,Data,GL,State) ->
- {LogType,Fd} = get_log(Info,GL,State),
- io:format(Fd,"~n~ts~ts~ts",[format_head(ConnMod,LogType,Time),
- format_title(LogType,Info),
- format_data(ConnMod,LogType,Data)]).
+ case get_log(Info,GL,State) of
+ {silent,_} ->
+ ok;
+ {LogType,Fd} ->
+ io:format(Fd,"~n~ts~ts~ts",[format_head(ConnMod,LogType,Time),
+ format_title(LogType,Info),
+ format_data(ConnMod,LogType,Data)])
+ end.
write_error(Time,#conn_log{module=ConnMod}=Info,Report,GL,State) ->
case get_log(Info,GL,State) of
- {html,_} ->
+ {LogType,_} when LogType==html; LogType==silent ->
%% The error will anyway be written in the html log by the
%% sasl error handler, so don't write it again.
ok;
diff --git a/lib/common_test/src/ct_netconfc.erl b/lib/common_test/src/ct_netconfc.erl
index 0de7bf03af..05977e5649 100644
--- a/lib/common_test/src/ct_netconfc.erl
+++ b/lib/common_test/src/ct_netconfc.erl
@@ -1272,6 +1272,14 @@ set_request_timer(T) ->
{ok,TRef} = timer:send_after(T,{Ref,timeout}),
{Ref,TRef}.
+%%%-----------------------------------------------------------------
+cancel_request_timer(undefined,undefined) ->
+ ok;
+cancel_request_timer(Ref,TRef) ->
+ _ = timer:cancel(TRef),
+ receive {Ref,timeout} -> ok
+ after 0 -> ok
+ end.
%%%-----------------------------------------------------------------
client_hello(Options) when is_list(Options) ->
@@ -1404,9 +1412,9 @@ handle_error(Reason, State) ->
Pending ->
%% Assuming the first request gets the
%% first answer
- P=#pending{tref=TRef,caller=Caller} =
+ P=#pending{tref=TRef,ref=Ref,caller=Caller} =
lists:last(Pending),
- _ = timer:cancel(TRef),
+ cancel_request_timer(Ref,TRef),
Reason1 = {failed_to_parse_received_data,Reason},
ct_gen_conn:return(Caller,{error,Reason1}),
lists:delete(P,Pending)
@@ -1492,8 +1500,8 @@ decode({Tag,Attrs,_}=E, #state{connection=Connection,pending=Pending}=State) ->
{error,Reason} ->
{noreply,State#state{hello_status = {error,Reason}}}
end;
- #pending{tref=TRef,caller=Caller} ->
- _ = timer:cancel(TRef),
+ #pending{tref=TRef,ref=Ref,caller=Caller} ->
+ cancel_request_timer(Ref,TRef),
case decode_hello(E) of
{ok,SessionId,Capabilities} ->
ct_gen_conn:return(Caller,ok),
@@ -1519,9 +1527,8 @@ decode({Tag,Attrs,_}=E, #state{connection=Connection,pending=Pending}=State) ->
%% there is just one pending that matches (i.e. has
%% undefined msg_id and op)
case [P || P = #pending{msg_id=undefined,op=undefined} <- Pending] of
- [#pending{tref=TRef,
- caller=Caller}] ->
- _ = timer:cancel(TRef),
+ [#pending{tref=TRef,ref=Ref,caller=Caller}] ->
+ cancel_request_timer(Ref,TRef),
ct_gen_conn:return(Caller,E),
{noreply,State#state{pending=[]}};
_ ->
@@ -1542,8 +1549,8 @@ get_msg_id(Attrs) ->
decode_rpc_reply(MsgId,{_,Attrs,Content0}=E,#state{pending=Pending} = State) ->
case lists:keytake(MsgId,#pending.msg_id,Pending) of
- {value, #pending{tref=TRef,op=Op,caller=Caller}, Pending1} ->
- _ = timer:cancel(TRef),
+ {value, #pending{tref=TRef,ref=Ref,op=Op,caller=Caller}, Pending1} ->
+ cancel_request_timer(Ref,TRef),
Content = forward_xmlns_attr(Attrs,Content0),
{CallerReply,{ServerReply,State2}} =
do_decode_rpc_reply(Op,Content,State#state{pending=Pending1}),
@@ -1555,10 +1562,11 @@ decode_rpc_reply(MsgId,{_,Attrs,Content0}=E,#state{pending=Pending} = State) ->
%% pending that matches (i.e. has undefined msg_id and op)
case [P || P = #pending{msg_id=undefined,op=undefined} <- Pending] of
[#pending{tref=TRef,
+ ref=Ref,
msg_id=undefined,
op=undefined,
caller=Caller}] ->
- _ = timer:cancel(TRef),
+ cancel_request_timer(Ref,TRef),
ct_gen_conn:return(Caller,E),
{noreply,State#state{pending=[]}};
_ ->
diff --git a/lib/common_test/test/ct_netconfc_SUITE_data/netconfc1_SUITE.erl b/lib/common_test/test/ct_netconfc_SUITE_data/netconfc1_SUITE.erl
index 64ebfbc463..aaa0723488 100644
--- a/lib/common_test/test/ct_netconfc_SUITE_data/netconfc1_SUITE.erl
+++ b/lib/common_test/test/ct_netconfc_SUITE_data/netconfc1_SUITE.erl
@@ -73,6 +73,7 @@ all() ->
timeout_close_session,
get,
timeout_get,
+ flush_timeout_get,
get_xpath,
get_config,
get_config_xpath,
@@ -360,6 +361,28 @@ timeout_get(Config) ->
?ok = ct_netconfc:close_session(Client),
ok.
+%% Test OTP-13008 "ct_netconfc crash when receiving unknown timeout"
+%% If the timer expires "at the same time" as the rpc reply is
+%% received, the timeout message might already be sent when the timer
+%% is cancelled. This test checks that the timeout message is flushed
+%% from the message queue. If it isn't, the client crashes and the
+%% session can not be closed afterwards.
+%% Note that we can only hope that the test case triggers the problem
+%% every now and then, as it is very timing dependent...
+flush_timeout_get(Config) ->
+ DataDir = ?config(data_dir,Config),
+ {ok,Client} = open_success(DataDir),
+ Data = [{server,[{xmlns,"myns"}],[{name,[],["myserver"]}]}],
+ ?NS:expect_reply('get',{data,Data}),
+ timer:sleep(1000),
+ case ct_netconfc:get(Client,{server,[{xmlns,"myns"}],[]},1) of
+ {error,timeout} -> ok; % problem not triggered
+ {ok,Data} -> ok % problem possibly triggered
+ end,
+ ?NS:expect_do_reply('close-session',close,ok),
+ ?ok = ct_netconfc:close_session(Client),
+ ok.
+
get_xpath(Config) ->
DataDir = ?config(data_dir,Config),
{ok,Client} = open_success(DataDir),
diff --git a/lib/compiler/doc/src/notes.xml b/lib/compiler/doc/src/notes.xml
index bd85f22462..daf3bd3af9 100644
--- a/lib/compiler/doc/src/notes.xml
+++ b/lib/compiler/doc/src/notes.xml
@@ -458,22 +458,28 @@
<p>
EEP43: New data type - Maps</p>
<p>
- With Maps you may for instance: <taglist> <item><c>M0 =
- #{ a =&gt; 1, b =&gt; 2}, % create
- associations</c></item> <item><c>M1 = M0#{ a := 10 }, %
- update values</c></item> <item><c>M2 = M1#{ "hi" =&gt;
- "hello"}, % add new associations</c></item> <item><c>#{
- "hi" := V1, a := V2, b := V3} = M2. % match keys with
- values</c></item> </taglist></p>
+ With Maps you may for instance:</p>
+ <taglist>
+ <tag/> <item><c>M0 = #{ a =&gt; 1, b =&gt; 2}, % create
+ associations</c></item>
+ <tag/><item><c>M1 = M0#{ a := 10 }, % update values</c></item>
+ <tag/><item><c>M2 = M1#{ "hi" =&gt;
+ "hello"}, % add new associations</c></item>
+ <tag/><item><c>#{ "hi" := V1, a := V2, b := V3} = M2.
+ % match keys with values</c></item>
+ </taglist>
<p>
For information on how to use Maps please see Map Expressions in the
<seealso marker="doc/reference_manual:expressions#map_expressions">
Reference Manual</seealso>.</p>
<p>
The current implementation is without the following
- features: <taglist> <item>No variable keys</item>
- <item>No single value access</item> <item>No map
- comprehensions</item> </taglist></p>
+ features:</p>
+ <taglist>
+ <tag/><item>No variable keys</item>
+ <tag/><item>No single value access</item>
+ <tag/><item>No map comprehensions</item>
+ </taglist>
<p>
Note that Maps is <em>experimental</em> during OTP 17.0.</p>
<p>
diff --git a/lib/compiler/src/cerl_trees.erl b/lib/compiler/src/cerl_trees.erl
index 2c9b72a30b..58bb18e34a 100644
--- a/lib/compiler/src/cerl_trees.erl
+++ b/lib/compiler/src/cerl_trees.erl
@@ -731,8 +731,8 @@ label(T, N, Env) ->
{ann_c_map(As, M, Ts), N3};
map_pair ->
{Op, N1} = label(map_pair_op(T), N, Env),
- {Val, N2} = label(map_pair_key(T), N1, Env),
- {Key, N3} = label(map_pair_val(T), N2, Env),
+ {Key, N2} = label(map_pair_key(T), N1, Env),
+ {Val, N3} = label(map_pair_val(T), N2, Env),
{As, N4} = label_ann(T, N3),
{ann_c_map_pair(As,Op,Key,Val), N4};
'let' ->
diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl
index 27d023d067..65699ccda9 100644
--- a/lib/compiler/src/sys_core_fold.erl
+++ b/lib/compiler/src/sys_core_fold.erl
@@ -3091,12 +3091,12 @@ bsm_ensure_no_partition_2([#c_var{name=V}|Ps], N, G, Vstate, S) ->
bsm_ensure_no_partition_2([_|Ps], N, G, _, S) ->
bsm_ensure_no_partition_2(Ps, N-1, G, bin_argument_order, S).
-bsm_ensure_no_partition_after([#c_clause{pats=Ps}|Cs], Pos) ->
+bsm_ensure_no_partition_after([#c_clause{pats=Ps}=C|Cs], Pos) ->
case nth(Pos, Ps) of
#c_var{} ->
bsm_ensure_no_partition_after(Cs, Pos);
- P ->
- bsm_problem(P, bin_partition)
+ _ ->
+ bsm_problem(C, bin_partition)
end;
bsm_ensure_no_partition_after([], _) -> ok.
diff --git a/lib/compiler/test/bs_match_SUITE.erl b/lib/compiler/test/bs_match_SUITE.erl
index 6e138b0a43..b4601b0798 100644
--- a/lib/compiler/test/bs_match_SUITE.erl
+++ b/lib/compiler/test/bs_match_SUITE.erl
@@ -36,7 +36,7 @@
match_string/1,zero_width/1,bad_size/1,haystack/1,
cover_beam_bool/1,matched_out_size/1,follow_fail_branch/1,
no_partition/1,calling_a_binary/1,binary_in_map/1,
- match_string_opt/1]).
+ match_string_opt/1,map_and_binary/1]).
-export([coverage_id/1,coverage_external_ignore/2]).
@@ -62,7 +62,7 @@ groups() ->
otp_7498,match_string,zero_width,bad_size,haystack,
cover_beam_bool,matched_out_size,follow_fail_branch,
no_partition,calling_a_binary,binary_in_map,
- match_string_opt]}].
+ match_string_opt,map_and_binary]}].
init_per_suite(Config) ->
@@ -1225,6 +1225,24 @@ match_string_opt(Config) when is_list(Config) ->
do_match_string_opt({<<1>>,{v,V}}=T) ->
{x,V,T}.
+%% If 'bin_opt_info' was given the warning would lack filename
+%% and line number.
+
+map_and_binary(_Config) ->
+ {<<"10">>,<<"37">>,<<"am">>} = do_map_and_binary(<<"10:37am">>),
+ Map1 = #{time => "noon"},
+ {ok,Map1} = do_map_and_binary(Map1),
+ Map2 = #{hour => 8, min => 42},
+ {8,42,Map2} = do_map_and_binary(Map2),
+ ok.
+
+do_map_and_binary(<<Hour:2/bytes, $:, Min:2/bytes, Rest/binary>>) ->
+ {Hour, Min, Rest};
+do_map_and_binary(#{time := _} = T) ->
+ {ok, T};
+do_map_and_binary(#{hour := Hour, min := Min} = T) ->
+ {Hour, Min, T}.
+
check(F, R) ->
R = F().
diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml
index 385a583883..563a090e98 100644
--- a/lib/crypto/doc/src/crypto.xml
+++ b/lib/crypto/doc/src/crypto.xml
@@ -66,29 +66,29 @@
<section>
<title>DATA TYPES </title>
- <p><code>key_value() = integer() | binary() </code></p>
+ <code>key_value() = integer() | binary() </code>
<p>Always <c>binary()</c> when used as return value</p>
- <p><code>rsa_public() = [key_value()] = [E, N] </code></p>
+ <code>rsa_public() = [key_value()] = [E, N] </code>
<p> Where E is the public exponent and N is public modulus. </p>
- <p><code>rsa_private() = [key_value()] = [E, N, D] | [E, N, D, P1, P2, E1, E2, C] </code></p>
+ <code>rsa_private() = [key_value()] = [E, N, D] | [E, N, D, P1, P2, E1, E2, C] </code>
<p>Where E is the public exponent, N is public modulus and D is
the private exponent.The longer key format contains redundant
information that will make the calculation faster. P1,P2 are first
and second prime factors. E1,E2 are first and second exponents. C
is the CRT coefficient. Terminology is taken from <url href="http://www.ietf.org/rfc/rfc3477.txt"> RFC 3447</url>.</p>
- <p><code>dss_public() = [key_value()] = [P, Q, G, Y] </code></p>
+ <code>dss_public() = [key_value()] = [P, Q, G, Y] </code>
<p>Where P, Q and G are the dss parameters and Y is the public key.</p>
- <p><code>dss_private() = [key_value()] = [P, Q, G, X] </code></p>
+ <code>dss_private() = [key_value()] = [P, Q, G, X] </code>
<p>Where P, Q and G are the dss parameters and X is the private key.</p>
- <p><code>srp_public() = key_value() </code></p>
+ <code>srp_public() = key_value() </code>
<p>Where is <c>A</c> or <c>B</c> from <url href="http://srp.stanford.edu/design.html">SRP design</url></p>
- <p><code>srp_private() = key_value() </code></p>
+ <code>srp_private() = key_value() </code>
<p>Where is <c>a</c> or <c>b</c> from <url href="http://srp.stanford.edu/design.html">SRP design</url></p>
<p>Where Verifier is <c>v</c>, Generator is <c>g</c> and Prime is<c> N</c>, DerivedKey is <c>X</c>, and Scrambler is
@@ -96,29 +96,29 @@
Version = '3' | '6' | '6a'
</p>
- <p><code>dh_public() = key_value() </code></p>
+ <code>dh_public() = key_value() </code>
- <p><code>dh_private() = key_value() </code></p>
+ <code>dh_private() = key_value() </code>
- <p><code>dh_params() = [key_value()] = [P, G] </code></p>
+ <code>dh_params() = [key_value()] = [P, G] </code>
- <p><code>ecdh_public() = key_value() </code></p>
+ <code>ecdh_public() = key_value() </code>
- <p><code>ecdh_private() = key_value() </code></p>
+ <code>ecdh_private() = key_value() </code>
- <p><code>ecdh_params() = ec_named_curve() | ec_explicit_curve()</code></p>
+ <code>ecdh_params() = ec_named_curve() | ec_explicit_curve()</code>
- <p><code>ec_explicit_curve() =
- {ec_field(), Prime :: key_value(), Point :: key_value(), Order :: integer(), CoFactor :: none | integer()} </code></p>
+ <code>ec_explicit_curve() =
+ {ec_field(), Prime :: key_value(), Point :: key_value(), Order :: integer(), CoFactor :: none | integer()} </code>
- <p><code>ec_field() = {prime_field, Prime :: integer()} |
- {characteristic_two_field, M :: integer(), Basis :: ec_basis()}</code></p>
+ <code>ec_field() = {prime_field, Prime :: integer()} |
+ {characteristic_two_field, M :: integer(), Basis :: ec_basis()}</code>
- <p><code>ec_basis() = {tpbasis, K :: non_neg_integer()} |
+ <code>ec_basis() = {tpbasis, K :: non_neg_integer()} |
{ppbasis, K1 :: non_neg_integer(), K2 :: non_neg_integer(), K3 :: non_neg_integer()} |
- onbasis</code></p>
+ onbasis</code>
- <p><code>ec_named_curve() ->
+ <code>ec_named_curve() ->
sect571r1| sect571k1| sect409r1| sect409k1| secp521r1| secp384r1| secp224r1| secp224k1|
secp192k1| secp160r2| secp128r2| secp128r1| sect233r1| sect233k1| sect193r2| sect193r1|
sect131r2| sect131r1| sect283r1| sect283k1| sect163r2| secp256k1| secp160k1| secp160r1|
@@ -128,42 +128,42 @@
brainpoolP224t1| brainpoolP256r1| brainpoolP256t1| brainpoolP320r1| brainpoolP320t1|
brainpoolP384r1| brainpoolP384t1| brainpoolP512r1| brainpoolP512t1
</code>
- Note that the <em>sect</em> curves are GF2m (characteristic two) curves and are only supported if the
+ <p>Note that the <em>sect</em> curves are GF2m (characteristic two) curves and are only supported if the
underlying OpenSSL has support for them.
See also <seealso marker="#supports-0">crypto:supports/0</seealso>
</p>
- <p><code>stream_cipher() = rc4 | aes_ctr </code></p>
+ <code>stream_cipher() = rc4 | aes_ctr </code>
- <p><code>block_cipher() = aes_cbc128 | aes_cfb8 | aes_cfb128 | aes_ige256 | blowfish_cbc |
+ <code>block_cipher() = aes_cbc128 | aes_cfb8 | aes_cfb128 | aes_ige256 | blowfish_cbc |
blowfish_cfb64 | des_cbc | des_cfb | des3_cbc | des3_cbf
- | des_ede3 | rc2_cbc </code></p>
+ | des_ede3 | rc2_cbc </code>
- <p><code>aead_cipher() = aes_gcm | chacha20_poly1305 </code></p>
+ <code>aead_cipher() = aes_gcm | chacha20_poly1305 </code>
- <p><code>stream_key() = aes_key() | rc4_key() </code></p>
+ <code>stream_key() = aes_key() | rc4_key() </code>
- <p><code>block_key() = aes_key() | blowfish_key() | des_key()| des3_key() </code></p>
+ <code>block_key() = aes_key() | blowfish_key() | des_key()| des3_key() </code>
- <p><code>aes_key() = iodata() </code> Key length is 128, 192 or 256 bits</p>
+ <code>aes_key() = iodata() </code> <p>Key length is 128, 192 or 256 bits</p>
- <p><code>rc4_key() = iodata() </code> Variable key length from 8 bits up to 2048 bits (usually between 40 and 256)</p>
+ <code>rc4_key() = iodata() </code> <p>Variable key length from 8 bits up to 2048 bits (usually between 40 and 256)</p>
- <p><code>blowfish_key() = iodata() </code> Variable key length from 32 bits up to 448 bits</p>
+ <code>blowfish_key() = iodata() </code> <p>Variable key length from 32 bits up to 448 bits</p>
- <p><code>des_key() = iodata() </code> Key length is 64 bits (in CBC mode only 8 bits are used)</p>
+ <code>des_key() = iodata() </code> <p>Key length is 64 bits (in CBC mode only 8 bits are used)</p>
- <p><code>des3_key() = [binary(), binary(), binary()] </code> Each key part is 64 bits (in CBC mode only 8 bits are used)</p>
+ <code>des3_key() = [binary(), binary(), binary()] </code> <p>Each key part is 64 bits (in CBC mode only 8 bits are used)</p>
- <p><code>digest_type() = md5 | sha | sha224 | sha256 | sha384 | sha512</code></p>
+ <code>digest_type() = md5 | sha | sha224 | sha256 | sha384 | sha512</code>
- <p><code> hash_algorithms() = md5 | ripemd160 | sha | sha224 | sha256 | sha384 | sha512 </code> md4 is also supported for hash_init/1 and hash/2.
+ <code> hash_algorithms() = md5 | ripemd160 | sha | sha224 | sha256 | sha384 | sha512 </code> <p>md4 is also supported for hash_init/1 and hash/2.
Note that both md4 and md5 are recommended only for compatibility with existing applications.
</p>
- <p><code> cipher_algorithms() = des_cbc | des_cfb | des3_cbc | des3_cbf | des_ede3 |
- blowfish_cbc | blowfish_cfb64 | aes_cbc128 | aes_cfb8 | aes_cfb128| aes_cbc256 | aes_ige256 | aes_gcm | chacha20_poly1305 | rc2_cbc | aes_ctr| rc4 </code> </p>
- <p><code> public_key_algorithms() = rsa |dss | ecdsa | dh | ecdh | ec_gf2m</code>
- Note that ec_gf2m is not strictly a public key algorithm, but a restriction on what curves are supported
+ <code> cipher_algorithms() = des_cbc | des_cfb | des3_cbc | des3_cbf | des_ede3 |
+ blowfish_cbc | blowfish_cfb64 | aes_cbc128 | aes_cfb8 | aes_cfb128| aes_cbc256 | aes_ige256 | aes_gcm | chacha20_poly1305 | rc2_cbc | aes_ctr| rc4 </code>
+ <code> public_key_algorithms() = rsa |dss | ecdsa | dh | ecdh | ec_gf2m</code>
+ <p>Note that ec_gf2m is not strictly a public key algorithm, but a restriction on what curves are supported
with ecdsa and ecdh.
</p>
@@ -381,8 +381,8 @@
</type>
<desc>
<p>Computes a HMAC of type <c>Type</c> from <c>Data</c> using
- <c>Key</c> as the authentication key.</p> <c>MacLength</c>
- will limit the size of the resultant <c>Mac</c>.
+ <c>Key</c> as the authentication key.</p> <p><c>MacLength</c>
+ will limit the size of the resultant <c>Mac</c>.</p>
</desc>
</func>
@@ -601,8 +601,11 @@
</type>
<desc>
<p>Generates N bytes randomly uniform 0..255, and returns the
- result in a binary. Uses the <c>crypto</c> library pseudo-random
- number generator.</p>
+ result in a binary. Uses the <c>crypto</c> library pseudo-random
+ number generator.</p>
+ <p>This function is not recommended for cryptographic purposes.
+ Please use <seealso marker="#strong_rand_bytes/1">
+ strong_rand_bytes/1</seealso> instead.</p>
</desc>
</func>
@@ -617,7 +620,7 @@
RAND_seed function from openssl. Only use this if the system
you are running on does not have enough "randomness" built in.
Normally this is when <seealso marker="#strong_rand_bytes/1">
- stong_rand_bytes/1</seealso> returns <c>low_entropy</c></p>
+ strong_rand_bytes/1</seealso> returns <c>low_entropy</c></p>
</desc>
</func>
@@ -650,7 +653,7 @@
<p>Creates a digital signature.</p>
<p>Algorithm <c>dss</c> can only be used together with digest type
<c>sha</c>.</p>
- See also <seealso marker="public_key:public_key#sign-3">public_key:sign/3</seealso>
+ <p>See also <seealso marker="public_key:public_key#sign-3">public_key:sign/3</seealso>.</p>
</desc>
</func>
@@ -710,7 +713,7 @@
</type>
<desc>
<p>Initializes the state for use in streaming AES encryption using Counter mode (CTR).
- <c>Key</c> is the AES key and must be either 128, 192, or 256 bts long. <c>IVec</c> is
+ <c>Key</c> is the AES key and must be either 128, 192, or 256 bits long. <c>IVec</c> is
an arbitrary initializing vector of 128 bits (16 bytes). This state is for use with
<seealso marker="#stream_encrypt-2">stream_encrypt</seealso> and
<seealso marker="#stream_decrypt-2">stream_decrypt</seealso>.</p>
@@ -802,7 +805,7 @@
<p>Algorithm <c>dss</c> can only be used together with digest type
<c>sha</c>.</p>
- See also <seealso marker="public_key:public_key#verify-4">public_key:verify/4</seealso>
+ <p>See also <seealso marker="public_key:public_key#verify-4">public_key:verify/4</seealso>.</p>
</desc>
</func>
diff --git a/lib/debugger/doc/src/notes.xml b/lib/debugger/doc/src/notes.xml
index 4a415a538f..3eaecf86b2 100644
--- a/lib/debugger/doc/src/notes.xml
+++ b/lib/debugger/doc/src/notes.xml
@@ -34,7 +34,6 @@
application.</p>
<section><title>Debugger 4.1.1</title>
-
<section><title>Fixed Bugs and Malfunctions</title>
<list>
<item>
@@ -49,6 +48,7 @@
</section>
+
<section><title>Debugger 4.1</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/dialyzer/doc/src/notes.xml b/lib/dialyzer/doc/src/notes.xml
index 9b3a7244f1..aa29684697 100644
--- a/lib/dialyzer/doc/src/notes.xml
+++ b/lib/dialyzer/doc/src/notes.xml
@@ -447,22 +447,28 @@
<p>
EEP43: New data type - Maps</p>
<p>
- With Maps you may for instance: <taglist> <item><c>M0 =
- #{ a =&gt; 1, b =&gt; 2}, % create
- associations</c></item> <item><c>M1 = M0#{ a := 10 }, %
- update values</c></item> <item><c>M2 = M1#{ "hi" =&gt;
- "hello"}, % add new associations</c></item> <item><c>#{
- "hi" := V1, a := V2, b := V3} = M2. % match keys with
- values</c></item> </taglist></p>
+ With Maps you may for instance:</p>
+ <taglist>
+ <tag/> <item><c>M0 = #{ a =&gt; 1, b =&gt; 2}, % create
+ associations</c></item>
+ <tag/><item><c>M1 = M0#{ a := 10 }, % update values</c></item>
+ <tag/><item><c>M2 = M1#{ "hi" =&gt;
+ "hello"}, % add new associations</c></item>
+ <tag/><item><c>#{ "hi" := V1, a := V2, b := V3} = M2.
+ % match keys with values</c></item>
+ </taglist>
<p>
For information on how to use Maps please see Map Expressions in the
<seealso marker="doc/reference_manual:expressions#map_expressions">
Reference Manual</seealso>.</p>
<p>
The current implementation is without the following
- features: <taglist> <item>No variable keys</item>
- <item>No single value access</item> <item>No map
- comprehensions</item> </taglist></p>
+ features:</p>
+ <taglist>
+ <tag/><item>No variable keys</item>
+ <tag/><item>No single value access</item>
+ <tag/><item>No map comprehensions</item>
+ </taglist>
<p>
Note that Maps is <em>experimental</em> during OTP 17.0.</p>
<p>
@@ -776,19 +782,17 @@
Own Id: OTP-9731</p>
</item>
<item>
- <p>
<list> <item><p>No warnings for underspecs with remote
types</p></item> <item><p> Fix crash in Typer</p></item>
<item><p>Fix Dialyzer's warning for its own
code</p></item> <item><p>Fix Dialyzer's warnings in
HiPE</p></item> <item><p>Add file/line info in a
particular Dialyzer crash</p></item> <item><p>Update
- inets test results</p></item> </list></p>
+ inets test results</p></item> </list>
<p>
Own Id: OTP-9758</p>
</item>
<item>
- <p>
<list> <item><p>Correct callback spec in application
module</p></item> <item><p>Refine warning about callback
specs with extra ranges</p></item> <item><p>Cleanup
@@ -799,7 +803,7 @@
analysis</p></item> <item><p>Fix crash in
Dialyzer</p></item> <item><p>Variable substitution was
not generalizing any unknown variables.</p></item>
- </list></p>
+ </list>
<p>
Own Id: OTP-9776</p>
</item>
diff --git a/lib/dialyzer/test/small_SUITE_data/results/fun_arity b/lib/dialyzer/test/small_SUITE_data/results/fun_arity
new file mode 100644
index 0000000000..280f5490d0
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/results/fun_arity
@@ -0,0 +1,35 @@
+
+fun_arity.erl:100: Fun application will fail since _cor1 :: fun(() -> any()) is not a function of arity 1
+fun_arity.erl:100: Function 'Mfa_0_ko'/1 has no local return
+fun_arity.erl:104: Fun application will fail since _cor1 :: fun((_) -> any()) is not a function of arity 0
+fun_arity.erl:104: Function 'Mfa_1_ko'/1 has no local return
+fun_arity.erl:111: Fun application will fail since _cor1 :: fun(() -> any()) is not a function of arity 1
+fun_arity.erl:111: Function mFa_0_ko/1 has no local return
+fun_arity.erl:115: Fun application will fail since _cor1 :: fun((_) -> any()) is not a function of arity 0
+fun_arity.erl:115: Function mFa_1_ko/1 has no local return
+fun_arity.erl:122: Fun application will fail since _cor2 :: fun(() -> any()) is not a function of arity 1
+fun_arity.erl:122: Function 'MFa_0_ko'/2 has no local return
+fun_arity.erl:126: Fun application will fail since _cor2 :: fun((_) -> any()) is not a function of arity 0
+fun_arity.erl:126: Function 'MFa_1_ko'/2 has no local return
+fun_arity.erl:35: Fun application will fail since _cor0 :: fun(() -> 'ok') is not a function of arity 1
+fun_arity.erl:35: Function f_0_ko/0 has no local return
+fun_arity.erl:39: Fun application will fail since _cor0 :: fun((_) -> 'ok') is not a function of arity 0
+fun_arity.erl:39: Function f_1_ko/0 has no local return
+fun_arity.erl:48: Fun application will fail since _cor0 :: fun(() -> 'ok') is not a function of arity 1
+fun_arity.erl:48: Function fa_0_ko/0 has no local return
+fun_arity.erl:53: Fun application will fail since _cor0 :: fun((_) -> 'ok') is not a function of arity 0
+fun_arity.erl:53: Function fa_1_ko/0 has no local return
+fun_arity.erl:63: Fun application will fail since _cor0 :: fun(() -> any()) is not a function of arity 1
+fun_arity.erl:63: Function mfa_0_ko/0 has no local return
+fun_arity.erl:68: Fun application will fail since _cor0 :: fun((_) -> any()) is not a function of arity 0
+fun_arity.erl:68: Function mfa_1_ko/0 has no local return
+fun_arity.erl:76: Fun application will fail since _cor0 :: fun(() -> any()) is not a function of arity 1
+fun_arity.erl:76: Function mfa_ne_0_ko/0 has no local return
+fun_arity.erl:78: Function mf_ne/0 will never be called
+fun_arity.erl:81: Fun application will fail since _cor0 :: fun((_) -> any()) is not a function of arity 0
+fun_arity.erl:81: Function mfa_ne_1_ko/0 has no local return
+fun_arity.erl:83: Function mf_ne/1 will never be called
+fun_arity.erl:89: Fun application will fail since _cor0 :: fun(() -> any()) is not a function of arity 1
+fun_arity.erl:89: Function mfa_nd_0_ko/0 has no local return
+fun_arity.erl:93: Fun application will fail since _cor0 :: fun((_) -> any()) is not a function of arity 0
+fun_arity.erl:93: Function mfa_nd_1_ko/0 has no local return
diff --git a/lib/dialyzer/test/small_SUITE_data/src/fun_arity.erl b/lib/dialyzer/test/small_SUITE_data/src/fun_arity.erl
new file mode 100644
index 0000000000..850d2fd331
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/fun_arity.erl
@@ -0,0 +1,127 @@
+%%--------------------------------------------------------------------------
+%% Module which contains calls to funs of different arity.
+%%--------------------------------------------------------------------------
+-module(fun_arity).
+
+-export([f_0_ok/0, f_0_ko/0]).
+-export([f_1_ok/0, f_1_ko/0]).
+
+-export([fa_0_ok/0, fa_0_ko/0]).
+-export([fa_1_ok/0, fa_1_ko/0]).
+
+-export([mfa_0_ok/0, mfa_0_ko/0, mf/0]).
+-export([mfa_1_ok/0, mfa_1_ko/0, mf/1]).
+
+-export([mfa_ne_0_ok/0, mfa_ne_0_ko/0]).
+-export([mfa_ne_1_ok/0, mfa_ne_1_ko/0]).
+
+-export([mfa_nd_0_ok/0, mfa_nd_0_ko/0]).
+-export([mfa_nd_1_ok/0, mfa_nd_1_ko/0]).
+
+-export(['Mfa_0_ok'/1, 'Mfa_0_ko'/1]).
+-export(['Mfa_1_ok'/1, 'Mfa_1_ko'/1]).
+
+-export(['mFa_0_ok'/1, 'mFa_0_ko'/1]).
+-export(['mFa_1_ok'/1, 'mFa_1_ko'/1]).
+
+-export(['MFa_0_ok'/2, 'MFa_0_ko'/2]).
+-export(['MFa_1_ok'/2, 'MFa_1_ko'/2]).
+
+%%--------------------------------------------------------------------------
+
+%% Funs like "fun(...) -> ... end".
+
+f_0_ok() -> (fun_f_0())().
+f_0_ko() -> (fun_f_0())(1).
+fun_f_0() -> fun() -> ok end.
+
+f_1_ok() -> (fun_f_1())(1).
+f_1_ko() -> (fun_f_1())().
+fun_f_1() -> fun(_) -> ok end .
+
+%%--------------------------------------------------------------------------
+
+%% Funs like "fun F/A" when F is literal atom and A is literal
+%% non-negative integer.
+
+fa_0_ok() -> (fun_fa_0())().
+fa_0_ko() -> (fun_fa_0())(1).
+fun_fa_0() -> fun f/0.
+f() -> ok.
+
+fa_1_ok() -> (fun_fa_1())(1).
+fa_1_ko() -> (fun_fa_1())().
+fun_fa_1() -> fun f/1.
+f(_) -> ok.
+
+%%--------------------------------------------------------------------------
+
+%% Funs like "fun M:F/A" when M and F are literal atoms, A is literal
+%% non-negative integer and function is (defined and) exported.
+
+mfa_0_ok() -> (fun_mfa_0())().
+mfa_0_ko() -> (fun_mfa_0())(1).
+fun_mfa_0() -> fun ?MODULE:mf/0.
+mf() -> ok.
+
+mfa_1_ok() -> (fun_mfa_1())(1).
+mfa_1_ko() -> (fun_mfa_1())().
+fun_mfa_1() -> fun ?MODULE:mf/1.
+mf(_) -> ok.
+
+%% Funs like "fun M:F/A" when M and F are literal atoms, A is literal
+%% non-negative integer and function is defined but not exported.
+
+mfa_ne_0_ok() -> (fun_mfa_ne_0())().
+mfa_ne_0_ko() -> (fun_mfa_ne_0())(1).
+fun_mfa_ne_0() -> fun ?MODULE:mf_ne/0.
+mf_ne() -> ok.
+
+mfa_ne_1_ok() -> (fun_mfa_ne_1())(1).
+mfa_ne_1_ko() -> (fun_mfa_ne_1())().
+fun_mfa_ne_1() -> fun ?MODULE:mf_ne/1.
+mf_ne(_) -> ok.
+
+%% Funs like "fun M:F/A" when M and F are literal atoms, A is literal
+%% non-negative integer and function is not defined.
+
+mfa_nd_0_ok() -> (fun_mfa_nd_0())().
+mfa_nd_0_ko() -> (fun_mfa_nd_0())(1).
+fun_mfa_nd_0() -> fun ?MODULE:mf_nd/0.
+
+mfa_nd_1_ok() -> (fun_mfa_nd_1())(1).
+mfa_nd_1_ko() -> (fun_mfa_nd_1())().
+fun_mfa_nd_1() -> fun ?MODULE:mf_nd/1.
+
+%% Funs like "fun M:F/A" when M is variable, F is literal atoms and A
+%% is literal non-negative integer.
+
+'Mfa_0_ok'(M) -> ('fun_Mfa_0'(M))().
+'Mfa_0_ko'(M) -> ('fun_Mfa_0'(M))(1).
+'fun_Mfa_0'(M) -> fun M:f/0.
+
+'Mfa_1_ok'(M) -> ('fun_Mfa_1'(M))(1).
+'Mfa_1_ko'(M) -> ('fun_Mfa_1'(M))().
+'fun_Mfa_1'(M) -> fun M:f/1.
+
+%% Funs like "fun M:F/A" when M is literal atom, F is variable and A
+%% is literal non-negative integer.
+
+'mFa_0_ok'(F) -> ('fun_mFa_0'(F))().
+'mFa_0_ko'(F) -> ('fun_mFa_0'(F))(1).
+'fun_mFa_0'(F) -> fun ?MODULE:F/0.
+
+'mFa_1_ok'(F) -> ('fun_mFa_1'(F))(1).
+'mFa_1_ko'(F) -> ('fun_mFa_1'(F))().
+'fun_mFa_1'(F) -> fun ?MODULE:F/1.
+
+%% Funs like "fun M:F/A" when M and F are variables and A is literal
+%% non-negative integer.
+
+'MFa_0_ok'(M, F) -> ('fun_MFa_0'(M, F))().
+'MFa_0_ko'(M, F) -> ('fun_MFa_0'(M, F))(1).
+'fun_MFa_0'(M, F) -> fun M:F/0.
+
+'MFa_1_ok'(M, F) -> ('fun_MFa_1'(M, F))(1).
+'MFa_1_ko'(M, F) -> ('fun_MFa_1'(M, F))().
+'fun_MFa_1'(M, F) -> fun M:F/1.
diff --git a/lib/erl_docgen/doc/src/erl_docgen_app.xml b/lib/erl_docgen/doc/src/erl_docgen_app.xml
index c2c65a0592..58c2a24f4b 100644
--- a/lib/erl_docgen/doc/src/erl_docgen_app.xml
+++ b/lib/erl_docgen/doc/src/erl_docgen_app.xml
@@ -32,7 +32,7 @@
<description>
<p>
- The application consists of the following parts
+ The application consists of the following parts:</p>
<taglist>
<tag>XSL</tag>
<item>
@@ -59,7 +59,6 @@
</p>
</item>
</taglist>
- </p>
</description>
</appref>
diff --git a/lib/erl_docgen/priv/dtd/cites.dtd b/lib/erl_docgen/priv/dtd/cites.dtd
index 73931af009..4558947db0 100644
--- a/lib/erl_docgen/priv/dtd/cites.dtd
+++ b/lib/erl_docgen/priv/dtd/cites.dtd
@@ -30,7 +30,7 @@
<!ELEMENT cite (id, shortdef, def, resp?) >
<!ELEMENT id (#PCDATA) >
<!ELEMENT shortdef (#PCDATA) >
-<!ELEMENT def (#PCDATA|c|em)* >
+<!ELEMENT def (#PCDATA|c|i|em)* >
<!ELEMENT resp (#PCDATA) >
<!ELEMENT c (#PCDATA) >
<!ELEMENT em (#PCDATA|c)* >
diff --git a/lib/erl_docgen/priv/dtd/common.dtd b/lib/erl_docgen/priv/dtd/common.dtd
index ded16d308f..a29fc233fa 100644
--- a/lib/erl_docgen/priv/dtd/common.dtd
+++ b/lib/erl_docgen/priv/dtd/common.dtd
@@ -24,21 +24,23 @@
<!ENTITY % block "p|pre|code|list|taglist|codeinclude|
erleval" >
-<!ENTITY % inline "#PCDATA|c|em|term|cite|br|path|seealso|
- url|marker" >
+<!ENTITY % inline "#PCDATA|c|i|em|term|cite|br|path|seealso|
+ url|marker|anno" >
<!-- XXX -->
<!ELEMENT p (%inline;)* >
-<!ELEMENT pre (#PCDATA|seealso|url|input)* >
-<!ELEMENT input (#PCDATA|seealso|url)* >
-<!ELEMENT code (#PCDATA) >
+<!ELEMENT pre (#PCDATA|seealso|url|input|anno)* >
+<!ELEMENT input (#PCDATA|seealso|url|anno)* >
+<!ELEMENT code (#PCDATA|anno)* >
<!ATTLIST code type (erl|c|none) "none" >
<!ELEMENT quote (p)* >
<!ELEMENT warning (%block;|quote|br|marker)* >
<!ELEMENT note (%block;|quote|br|marker)* >
<!ELEMENT dont (%block;|quote|br|marker)* >
<!ELEMENT do (%block;|quote|br|marker)* >
-<!ELEMENT c (#PCDATA) >
-<!ELEMENT em (#PCDATA|c)* >
+<!ELEMENT c (#PCDATA|anno)* >
+<!ELEMENT i (#PCDATA|c|anno)* >
+<!ELEMENT em (#PCDATA|c|anno)* >
+<!ELEMENT anno (#PCDATA) >
<!-- XXX -->
<!ELEMENT term (termdef?) >
@@ -64,13 +66,13 @@
<!ELEMENT list (item+) >
<!ATTLIST list type (ordered|bulleted) "bulleted" >
-<!ELEMENT taglist (tag,item)+ >
-<!ELEMENT tag (#PCDATA|c|em|seealso|url|marker)* >
+<!ELEMENT taglist (tag,item+)+ >
+<!ELEMENT tag (#PCDATA|c|i|em|br|seealso|url|marker|anno)* >
<!ELEMENT item (%inline;|%block;)* >
<!-- References -->
-<!ELEMENT seealso (#PCDATA|c|em)* >
+<!ELEMENT seealso (#PCDATA|c|i|em|anno)* >
<!ATTLIST seealso marker CDATA #REQUIRED >
<!ELEMENT url (#PCDATA) >
<!ATTLIST url href CDATA #REQUIRED >
diff --git a/lib/erl_docgen/priv/dtd/common.header.dtd b/lib/erl_docgen/priv/dtd/common.header.dtd
index 71a8662572..eb27dc8f97 100644
--- a/lib/erl_docgen/priv/dtd/common.header.dtd
+++ b/lib/erl_docgen/priv/dtd/common.header.dtd
@@ -18,8 +18,8 @@
$Id$
-->
<!ELEMENT header (copyright?,legalnotice?,title,shorttitle?,
- prepared,responsible?,docno,approved?,
- checked?,date,rev,file?) >
+ prepared?,responsible?,docno?,approved?,
+ checked?,date?,rev?,file?) >
<!--
The titlestyle attribute is only defined to make all the book.xml files
diff --git a/lib/erl_docgen/priv/dtd/common.refs.dtd b/lib/erl_docgen/priv/dtd/common.refs.dtd
index f57e46a624..6889e990de 100644
--- a/lib/erl_docgen/priv/dtd/common.refs.dtd
+++ b/lib/erl_docgen/priv/dtd/common.refs.dtd
@@ -27,15 +27,16 @@
<!ELEMENT description (%block;|quote|br|marker|warning|note|dont|do)* >
<!ELEMENT funcs (func)+ >
-<!ELEMENT func (name+,type_desc*,fsummary,type?,desc?) >
+<!ELEMENT func (name+,fsummary,(type|type_desc)*,desc?) >
<!-- ELEMENT name is defined in each ref dtd -->
-<!ELEMENT fsummary (#PCDATA|c|em)* >
+<!ELEMENT fsummary (#PCDATA|c|i|em|anno)* >
<!ELEMENT type (v,d?)* >
<!ATTLIST type variable CDATA #IMPLIED
+ name CDATA #IMPLIED
name_i CDATA #IMPLIED>
-<!ELEMENT v (#PCDATA) >
-<!ELEMENT d (#PCDATA|c|em)* >
-<!ELEMENT desc (%block;|quote|br|marker|warning|note|dont|do|anno)* >
+<!ELEMENT v (#PCDATA|seealso)* >
+<!ELEMENT d (#PCDATA|c|i|em)* >
+<!ELEMENT desc (%block;|quote|br|marker|warning|note|dont|do)* >
<!ELEMENT authors (aname,email)+ >
<!ELEMENT aname (#PCDATA) >
<!ELEMENT email (#PCDATA) >
@@ -43,5 +44,6 @@
warning|note|dont|do)*) >
<!ELEMENT datatypes (datatype)+ >
<!ELEMENT datatype (name+,desc?) >
-<!ELEMENT type_desc (#PCDATA) >
-<!ATTLIST type_desc variable CDATA #REQUIRED>
+<!ELEMENT type_desc (#PCDATA|anno|c|seealso)* >
+<!ATTLIST type_desc variable CDATA #IMPLIED
+ name CDATA #IMPLIED>
diff --git a/lib/erl_docgen/priv/dtd/erlref.dtd b/lib/erl_docgen/priv/dtd/erlref.dtd
index d62e2a5fcb..835407520a 100644
--- a/lib/erl_docgen/priv/dtd/erlref.dtd
+++ b/lib/erl_docgen/priv/dtd/erlref.dtd
@@ -32,4 +32,5 @@
<!ELEMENT name (#PCDATA) >
<!ATTLIST name name CDATA #IMPLIED
arity CDATA #IMPLIED
- clause_i CDATA #IMPLIED>
+ clause_i CDATA #IMPLIED
+ n_vars CDATA #IMPLIED>
diff --git a/lib/erl_docgen/priv/dtd/terms.dtd b/lib/erl_docgen/priv/dtd/terms.dtd
index fd160b5c02..c2965eb61c 100644
--- a/lib/erl_docgen/priv/dtd/terms.dtd
+++ b/lib/erl_docgen/priv/dtd/terms.dtd
@@ -30,7 +30,7 @@
<!ELEMENT term (id, shortdef, def, resp?) >
<!ELEMENT id (#PCDATA) >
<!ELEMENT shortdef (#PCDATA) >
-<!ELEMENT def (#PCDATA|c|em)* >
+<!ELEMENT def (#PCDATA|c|i|em)* >
<!ELEMENT resp (#PCDATA) >
<!ELEMENT c (#PCDATA) >
<!ELEMENT em (#PCDATA|c)* >
diff --git a/lib/erl_docgen/priv/xsl/db_html.xsl b/lib/erl_docgen/priv/xsl/db_html.xsl
index f5ddd364d3..c2325fbee9 100644
--- a/lib/erl_docgen/priv/xsl/db_html.xsl
+++ b/lib/erl_docgen/priv/xsl/db_html.xsl
@@ -990,12 +990,15 @@
</p>
</xsl:template>
-
<!-- Inline elements -->
<xsl:template match="b">
<strong><xsl:apply-templates/></strong>
</xsl:template>
+ <xsl:template match="i">
+ <i><xsl:apply-templates/></i>
+ </xsl:template>
+
<xsl:template match="br">
<br/>
</xsl:template>
diff --git a/lib/erl_docgen/priv/xsl/db_man.xsl b/lib/erl_docgen/priv/xsl/db_man.xsl
index 120bf9880d..5201465e42 100644
--- a/lib/erl_docgen/priv/xsl/db_man.xsl
+++ b/lib/erl_docgen/priv/xsl/db_man.xsl
@@ -595,6 +595,12 @@
<xsl:text>\fR\&amp; </xsl:text>
</xsl:template>
+ <xsl:template match="i">
+ <xsl:text>\fI</xsl:text>
+ <xsl:apply-templates/>
+ <xsl:text>\fR\&amp; </xsl:text>
+ </xsl:template>
+
<xsl:template match="br">
<xsl:choose>
<xsl:when test="ancestor::head">
diff --git a/lib/erl_docgen/priv/xsl/db_pdf.xsl b/lib/erl_docgen/priv/xsl/db_pdf.xsl
index 53e202d52c..37a2d55274 100644
--- a/lib/erl_docgen/priv/xsl/db_pdf.xsl
+++ b/lib/erl_docgen/priv/xsl/db_pdf.xsl
@@ -1186,6 +1186,12 @@
</fo:inline>
</xsl:template>
+ <xsl:template match="i">
+ <fo:inline font-weight="italic">
+ <xsl:apply-templates/>
+ </fo:inline>
+ </xsl:template>
+
<xsl:template match="br">
<fo:block/>
</xsl:template>
diff --git a/lib/erl_docgen/src/docgen_edoc_xml_cb.erl b/lib/erl_docgen/src/docgen_edoc_xml_cb.erl
index 03fc161c5a..0ac7985a48 100644
--- a/lib/erl_docgen/src/docgen_edoc_xml_cb.erl
+++ b/lib/erl_docgen/src/docgen_edoc_xml_cb.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2015. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -352,8 +352,8 @@ otp_xmlify_e(#xmlElement{name=code} = E) -> % 4)
end;
otp_xmlify_e(#xmlElement{name=Tag} = E) % 5a
when Tag==h1; Tag==h2; Tag==h3; Tag==h4; Tag==h5 ->
- Content = text_and_a_name_only(E#xmlElement.content),
- [E#xmlElement{name=b, content=Content}];
+ {Name, Text} = text_and_a_name_only(E#xmlElement.content),
+ [Name, E#xmlElement{name=b, content=Text}];
otp_xmlify_e(#xmlElement{name=Tag} = E) % 5b-c)
when Tag==center;
Tag==font ->
@@ -1190,17 +1190,13 @@ get_text(#xmlElement{content=[#xmlText{value=Text}]}) ->
get_text(#xmlElement{content=[E]}) ->
get_text(E).
-%% text_and_name_only(Es) -> Ts
-text_and_a_name_only([#xmlElement{
- name = a,
- attributes = [#xmlAttribute{name=name}]} = Name|Es]) ->
- [Name|text_and_a_name_only(Es)];
-text_and_a_name_only([#xmlElement{content = Content}|Es]) ->
- text_and_a_name_only(Content) ++ text_and_a_name_only(Es);
-text_and_a_name_only([#xmlText{} = E |Es]) ->
- [E | text_and_a_name_only(Es)];
-text_and_a_name_only([]) ->
- [].
+%% text_and_name_only(Es) -> {N, Ts}
+text_and_a_name_only(Es) ->
+ [Name|_] = [Name ||
+ #xmlElement{
+ name = a,
+ attributes = [#xmlAttribute{name=name}]}=Name <- Es],
+ {Name#xmlElement{content = []}, text_only(Es)}.
%% text_only(Es) -> Ts
%% Takes a list of xmlElement and xmlText and return a lists of xmlText.
diff --git a/lib/erl_docgen/vsn.mk b/lib/erl_docgen/vsn.mk
index 2abd3d2b7e..43f5a570d7 100644
--- a/lib/erl_docgen/vsn.mk
+++ b/lib/erl_docgen/vsn.mk
@@ -1 +1 @@
-ERL_DOCGEN_VSN = 0.4
+ERL_DOCGEN_VSN = 0.4.1
diff --git a/lib/erl_interface/src/connect/ei_resolve.c b/lib/erl_interface/src/connect/ei_resolve.c
index 3f1be2b17d..6381b02393 100644
--- a/lib/erl_interface/src/connect/ei_resolve.c
+++ b/lib/erl_interface/src/connect/ei_resolve.c
@@ -601,6 +601,16 @@ struct hostent *ei_gethostbyaddr(const char *addr, int len, int type)
return gethostbyaddr(addr, len, type);
}
+/*
+ * Imprecise way to select the actually available gethostbyname_r and
+ * gethostbyaddr_r.
+ *
+ * TODO: check this properly in configure.in
+ */
+#if (defined(__linux__) || (__FreeBSD_version >= 602000) || defined(__DragonFly__))
+ #define HAVE_GETHOSTBYADDR_R_8 1
+#endif
+
struct hostent *ei_gethostbyaddr_r(const char *addr,
int length,
int type,
@@ -616,7 +626,7 @@ struct hostent *ei_gethostbyaddr_r(const char *addr,
#ifndef HAVE_GETHOSTBYNAME_R
return my_gethostbyaddr_r(addr,length,type,hostp,buffer,buflen,h_errnop);
#else
-#if (defined(__GLIBC__) || (__FreeBSD_version >= 602000) || defined(__DragonFly__))
+#ifdef HAVE_GETHOSTBYADDR_R_8
struct hostent *result;
gethostbyaddr_r(addr, length, type, hostp, buffer, buflen, &result,
@@ -643,7 +653,7 @@ struct hostent *ei_gethostbyname_r(const char *name,
#ifndef HAVE_GETHOSTBYNAME_R
return my_gethostbyname_r(name,hostp,buffer,buflen,h_errnop);
#else
-#if (defined(__GLIBC__) || (__FreeBSD_version >= 602000) || defined(__DragonFly__) || defined(__ANDROID__))
+#ifdef HAVE_GETHOSTBYADDR_R_8
struct hostent *result;
gethostbyname_r(name, hostp, buffer, buflen, &result, h_errnop);
diff --git a/lib/eunit/doc/overview.edoc b/lib/eunit/doc/overview.edoc
index df716cdeea..12ea02f442 100644
--- a/lib/eunit/doc/overview.edoc
+++ b/lib/eunit/doc/overview.edoc
@@ -885,7 +885,7 @@ the timeout is exceeded, the unfinished tests will be forced to
terminate. Note that if a timeout is set around a fixture, it includes
the time for setup and cleanup, and if the timeout is triggered, the
entire fixture is abruptly terminated (without running the
-cleanup).</dd>
+cleanup). The default timeout for an individual test is 5 seconds.</dd>
<dt>`{inorder, Tests}'</dt>
<dd>Runs the specified tests in strict order. Also see `{inparallel,
Tests}'. By default, tests are neither marked as `inorder' or
@@ -907,7 +907,6 @@ the test set is finished, regardless of the outcome (success, failures,
timeouts, etc.).
To make the descriptions simpler, we first list some definitions:
-<center>
<table border="0" cellspacing="4">
<tr>
<td>`Setup'</td><td>`() -> (R::any())'</td>
@@ -928,7 +927,6 @@ To make the descriptions simpler, we first list some definitions:
<td>`Where'</td><td>`local | spawn | {spawn, Node::atom()}'</td>
</tr>
</table>
-</center>
(these are explained in more detail further below.)
The following representations specify fixture handling for test sets:
diff --git a/lib/eunit/include/eunit.hrl b/lib/eunit/include/eunit.hrl
index 88e9d6c19b..8f678b0290 100644
--- a/lib/eunit/include/eunit.hrl
+++ b/lib/eunit/include/eunit.hrl
@@ -135,7 +135,6 @@
-define(_assertThrow(Term, Expr), ?_assertException(throw, Term, Expr)).
-define(_assertNotException(Class, Term, Expr),
?_test(?assertNotException(Class, Term, Expr))).
--define(_assertReceive(Guard, Expr), ?_test(?assertReceive(Guard, Expr))).
%% Macros for running operating system commands. (Note that these
%% require EUnit to be present at runtime, or at least eunit_lib.)
diff --git a/lib/hipe/cerl/erl_bif_types.erl b/lib/hipe/cerl/erl_bif_types.erl
index 5387edfb47..c2fb79c089 100644
--- a/lib/hipe/cerl/erl_bif_types.erl
+++ b/lib/hipe/cerl/erl_bif_types.erl
@@ -768,6 +768,18 @@ type(erlang, length, 1, Xs, Opaques) ->
%% Guard bif, needs to be here.
type(erlang, map_size, 1, Xs, Opaques) ->
strict(erlang, map_size, 1, Xs, fun (_) -> t_non_neg_integer() end, Opaques);
+type(erlang, make_fun, 3, Xs, Opaques) ->
+ strict(erlang, make_fun, 3, Xs,
+ fun ([_, _, Arity]) ->
+ case t_number_vals(Arity, Opaques) of
+ [N] ->
+ case is_integer(N) andalso 0 =< N andalso N =< 255 of
+ true -> t_fun(N, t_any());
+ false -> t_none()
+ end;
+ _Other -> t_fun()
+ end
+ end, Opaques);
type(erlang, make_tuple, 2, Xs, Opaques) ->
strict(erlang, make_tuple, 2, Xs,
fun ([Int, _]) ->
@@ -2361,6 +2373,8 @@ arg_types(erlang, length, 1) ->
%% Guard bif, needs to be here.
arg_types(erlang, map_size, 1) ->
[t_map()];
+arg_types(erlang, make_fun, 3) ->
+ [t_atom(), t_atom(), t_arity()];
arg_types(erlang, make_tuple, 2) ->
[t_non_neg_fixnum(), t_any()]; % the value 0 is OK as first argument
arg_types(erlang, make_tuple, 3) ->
diff --git a/lib/hipe/doc/src/hipe_app.xml b/lib/hipe/doc/src/hipe_app.xml
index 98fec900af..bf4bdbb3b3 100644
--- a/lib/hipe/doc/src/hipe_app.xml
+++ b/lib/hipe/doc/src/hipe_app.xml
@@ -37,15 +37,14 @@
<description>
<p>
The normal way to native-compile an Erlang module using HiPE is to include the atom native
- in the Erlang compiler options, as in:
- <code>
- 1> <input>c(my_module, [native]).</input></code>
- Options to the HiPE compiler are then passed as follows:
- <code>
- 1> <input>c(my_module, [native,{hipe,Options}]).</input></code>
- For on-line help in the Erlang shell, call <c>hipe:help()</c>.
- Details on HiPE compiler options are given by <c>hipe:help_options()</c>.
- </p>
+ in the Erlang compiler options, as in:</p>
+ <pre>
+ 1> <input>c(my_module, [native]).</input></pre>
+ <p>Options to the HiPE compiler are then passed as follows:</p>
+ <pre>
+ 1> <input>c(my_module, [native,{hipe,Options}]).</input></pre>
+ <p>For on-line help in the Erlang shell, call <c>hipe:help()</c>.
+ Details on HiPE compiler options are given by <c>hipe:help_options()</c>.</p>
</description>
<section>
<title>SEE ALSO</title>
diff --git a/lib/hipe/doc/src/notes.xml b/lib/hipe/doc/src/notes.xml
index a463b421a8..e1aec698e4 100644
--- a/lib/hipe/doc/src/notes.xml
+++ b/lib/hipe/doc/src/notes.xml
@@ -319,22 +319,28 @@
<p>
EEP43: New data type - Maps</p>
<p>
- With Maps you may for instance: <taglist> <item><c>M0 =
- #{ a =&gt; 1, b =&gt; 2}, % create
- associations</c></item> <item><c>M1 = M0#{ a := 10 }, %
- update values</c></item> <item><c>M2 = M1#{ "hi" =&gt;
- "hello"}, % add new associations</c></item> <item><c>#{
- "hi" := V1, a := V2, b := V3} = M2. % match keys with
- values</c></item> </taglist></p>
+ With Maps you may for instance:</p>
+ <taglist>
+ <tag/> <item><c>M0 = #{ a =&gt; 1, b =&gt; 2}, % create
+ associations</c></item>
+ <tag/><item><c>M1 = M0#{ a := 10 }, % update values</c></item>
+ <tag/><item><c>M2 = M1#{ "hi" =&gt;
+ "hello"}, % add new associations</c></item>
+ <tag/><item><c>#{ "hi" := V1, a := V2, b := V3} = M2.
+ % match keys with values</c></item>
+ </taglist>
<p>
For information on how to use Maps please see Map Expressions in the
<seealso marker="doc/reference_manual:expressions#map_expressions">
Reference Manual</seealso>.</p>
<p>
The current implementation is without the following
- features: <taglist> <item>No variable keys</item>
- <item>No single value access</item> <item>No map
- comprehensions</item> </taglist></p>
+ features:</p>
+ <taglist>
+ <tag/><item>No variable keys</item>
+ <tag/><item>No single value access</item>
+ <tag/><item>No map comprehensions</item>
+ </taglist>
<p>
Note that Maps is <em>experimental</em> during OTP 17.0.</p>
<p>
@@ -602,19 +608,17 @@
<section><title>Fixed Bugs and Malfunctions</title>
<list>
<item>
- <p>
<list> <item><p>No warnings for underspecs with remote
types</p></item> <item><p> Fix crash in Typer</p></item>
<item><p>Fix Dialyzer's warning for its own
code</p></item> <item><p>Fix Dialyzer's warnings in
HiPE</p></item> <item><p>Add file/line info in a
particular Dialyzer crash</p></item> <item><p>Update
- inets test results</p></item> </list></p>
+ inets test results</p></item> </list>
<p>
Own Id: OTP-9758</p>
</item>
<item>
- <p>
<list> <item><p>Correct callback spec in application
module</p></item> <item><p>Refine warning about callback
specs with extra ranges</p></item> <item><p>Cleanup
@@ -625,7 +629,7 @@
analysis</p></item> <item><p>Fix crash in
Dialyzer</p></item> <item><p>Variable substitution was
not generalizing any unknown variables.</p></item>
- </list></p>
+ </list>
<p>
Own Id: OTP-9776</p>
</item>
diff --git a/lib/hipe/rtl/Makefile b/lib/hipe/rtl/Makefile
index d2517b13fc..1bf52fe312 100644
--- a/lib/hipe/rtl/Makefile
+++ b/lib/hipe/rtl/Makefile
@@ -75,7 +75,7 @@ TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
include ../native.mk
-ERL_COMPILE_FLAGS += +inline +warn_unused_import +warn_exported_vars
+ERL_COMPILE_FLAGS += -Werror +inline +warn_unused_import +warn_exported_vars
# ----------------------------------------------------
# Targets
diff --git a/lib/hipe/rtl/hipe_rtl_binary_construct.erl b/lib/hipe/rtl/hipe_rtl_binary_construct.erl
index 40bd22aa8e..692bad7d96 100644
--- a/lib/hipe/rtl/hipe_rtl_binary_construct.erl
+++ b/lib/hipe/rtl/hipe_rtl_binary_construct.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -1192,7 +1192,10 @@ copy_little_word(Base, Offset, NewOffset, Word) ->
hipe_rtl:mk_store(Base, TmpOffset, Word, byte),
hipe_rtl:mk_alu(NewOffset, Offset, 'add', hipe_rtl:mk_imm(32))].
-copy_offset_int_big(Base, Offset, NewOffset, Size, Tmp1) when is_integer(Size) ->
+copy_offset_int_big(_Base, Offset, NewOffset, 0, _Tmp1) ->
+ [hipe_rtl:mk_move(NewOffset, Offset)];
+copy_offset_int_big(Base, Offset, NewOffset, Size, Tmp1)
+ when is_integer(Size), Size > 0 ->
Tmp2 = hipe_rtl:mk_new_reg(),
Tmp3 = hipe_rtl:mk_new_reg(),
Tmp4 = hipe_rtl:mk_new_reg(),
@@ -1203,7 +1206,7 @@ copy_offset_int_big(Base, Offset, NewOffset, Size, Tmp1) when is_integer(Size) -
Tmp9 = hipe_rtl:mk_new_reg(),
OldByte = hipe_rtl:mk_new_reg(),
TmpOffset = hipe_rtl:mk_new_reg(),
- BranchLbl = hipe_rtl:mk_new_label(),
+ BranchLbl = hipe_rtl:mk_new_label(),
BodyLbl = hipe_rtl:mk_new_label(),
EndLbl = hipe_rtl:mk_new_label(),
NextLbl = hipe_rtl:mk_new_label(),
diff --git a/lib/hipe/rtl/hipe_rtl_binary_match.erl b/lib/hipe/rtl/hipe_rtl_binary_match.erl
index 364aab1b6f..51213b71d1 100644
--- a/lib/hipe/rtl/hipe_rtl_binary_match.erl
+++ b/lib/hipe/rtl/hipe_rtl_binary_match.erl
@@ -2,7 +2,7 @@
%%%
%%% %CopyrightBegin%
%%%
-%%% Copyright Ericsson AB 2007-2013. All Rights Reserved.
+%%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
@@ -181,17 +181,20 @@ gen_rtl({bs_get_binary, Size, Flags}, [Dst, NewMs], Args,
[hipe_rtl:mk_goto(FalseLblName)];
false ->
Unsafe = unsafe(Flags),
- case Args of
- [Ms] ->
- SizeReg = hipe_rtl:mk_new_reg(),
- SizeCode = [hipe_rtl:mk_move(SizeReg, hipe_rtl:mk_imm(Size))];
- [Ms, BitsVar] ->
- {SizeCode, SizeReg} = make_size(Size, BitsVar, FalseLblName)
- end,
- InCode = get_binary(Dst, Ms, SizeReg, Unsafe,
+ {OldMs, SizeReg, SizeCode} =
+ case Args of
+ [Ms] ->
+ SzReg = hipe_rtl:mk_new_reg(),
+ SzCode = [hipe_rtl:mk_move(SzReg, hipe_rtl:mk_imm(Size))],
+ {Ms, SzReg, SzCode};
+ [Ms, BitsVar] ->
+ {SzCode, SzReg} = make_size(Size, BitsVar, FalseLblName),
+ {Ms, SzReg, SzCode}
+ end,
+ InCode = get_binary(Dst, OldMs, SizeReg, Unsafe,
TrueLblName, FalseLblName),
[hipe_rtl:mk_gctest(?SUB_BIN_WORDSIZE)] ++
- update_ms(NewMs, Ms) ++ SizeCode ++ InCode
+ update_ms(NewMs, OldMs) ++ SizeCode ++ InCode
end;
%% ----- bs_get_utf8 -----
gen_rtl(bs_get_utf8, [Dst, NewMs], [Ms], TrueLblName, FalseLblName) ->
@@ -230,14 +233,26 @@ gen_rtl({bs_skip_bits_all, Unit, _Flags}, Dst, [Ms],
skip_bits_all(Unit, Ms, TrueLblName, FalseLblName);
%% ----- bs_skip_bits -----
gen_rtl({bs_skip_bits, Bits}, Dst, [Ms|Args], TrueLblName, FalseLblName) ->
+ MaxValue = (1 bsl (hipe_rtl_arch:word_size() * ?BYTE_SIZE)),
opt_update_ms(Dst, Ms) ++
- case Args of
- [] ->
- skip_bits2(Ms, hipe_rtl:mk_imm(Bits), TrueLblName, FalseLblName);
- [Arg] ->
- {SizeCode, SizeReg} = make_size(Bits, Arg, FalseLblName),
- InCode = skip_bits2(Ms, SizeReg, TrueLblName, FalseLblName),
- SizeCode ++ InCode
+ case Bits < MaxValue of
+ true ->
+ case Args of
+ [] ->
+ skip_bits2(Ms, hipe_rtl:mk_imm(Bits), TrueLblName, FalseLblName);
+ [Arg] ->
+ {SizeCode, SizeReg} = make_size(Bits, Arg, FalseLblName),
+ InCode = skip_bits2(Ms, SizeReg, TrueLblName, FalseLblName),
+ SizeCode ++ InCode
+ end;
+ false -> % handle overflow case
+ case Args of
+ [] ->
+ [hipe_rtl:mk_goto(FalseLblName)];
+ [Arg] ->
+ [hipe_rtl:mk_branch(Arg, 'eq', hipe_tagscheme:mk_fixnum(0),
+ TrueLblName, FalseLblName, 0.5)]
+ end
end;
%% ----- bs_restore -----
gen_rtl({bs_restore, Slot}, [NewMs], [Ms], TrueLblName, _FalseLblName) ->
@@ -1086,23 +1101,47 @@ create_gcsafe_regs(0) ->
[].
first_part(Var, Register, FalseLblName) ->
- [SuccessLbl1, SuccessLbl2] = create_lbls(2),
- [hipe_tagscheme:test_fixnum(Var, hipe_rtl:label_name(SuccessLbl1),
- FalseLblName, 0.99),
- SuccessLbl1,
- hipe_tagscheme:fixnum_ge(Var, hipe_rtl:mk_imm(hipe_tagscheme:mk_fixnum(0)),
- hipe_rtl:label_name(SuccessLbl2), FalseLblName, 0.99),
- SuccessLbl2,
- hipe_tagscheme:untag_fixnum(Register, Var)].
+ [EndLbl] = create_lbls(1),
+ EndName = hipe_rtl:label_name(EndLbl),
+ first_part(Var, Register, FalseLblName, EndName, EndName, [EndLbl]).
+
+first_part(Var, Register, FalseLblName, TrueLblName, BigLblName, Tail) ->
+ [FixnumLbl, NotFixnumLbl, BignumLbl, SuccessLbl] = create_lbls(4),
+ [hipe_tagscheme:test_fixnum(Var, hipe_rtl:label_name(FixnumLbl),
+ hipe_rtl:label_name(NotFixnumLbl), 0.99),
+ FixnumLbl,
+ hipe_tagscheme:fixnum_ge(Var, hipe_rtl:mk_imm(hipe_tagscheme:mk_fixnum(0)),
+ hipe_rtl:label_name(SuccessLbl), FalseLblName,
+ 0.99),
+ SuccessLbl,
+ hipe_tagscheme:untag_fixnum(Register, Var),
+ hipe_rtl:mk_goto(TrueLblName),
+ NotFixnumLbl,
+ %% Since binaries are not allowed to be larger than 2^wordsize bits
+ %% and since bignum digits are words, we know that a bignum with an
+ %% arity larger than one can't match.
+ hipe_tagscheme:test_pos_bignum_arity(Var, 1, hipe_rtl:label_name(BignumLbl),
+ FalseLblName, 0.99),
+ BignumLbl,
+ hipe_tagscheme:unsafe_get_one_word_pos_bignum(Register, Var),
+ hipe_rtl:mk_goto(BigLblName) | Tail].
make_size(1, BitsVar, FalseLblName) ->
[DstReg] = create_regs(1),
{first_part(BitsVar, DstReg, FalseLblName), DstReg};
make_size(?BYTE_SIZE, BitsVar, FalseLblName) ->
[DstReg] = create_regs(1),
- Code =
- first_part(BitsVar, DstReg, FalseLblName) ++
- [hipe_rtl:mk_alu(DstReg, DstReg, sll, hipe_rtl:mk_imm(?BYTE_SHIFT))],
+ [FixnumLbl, BignumLbl] = create_lbls(2),
+ WordBits = hipe_rtl_arch:word_size() * ?BYTE_SIZE,
+ FixnumLblName = hipe_rtl:label_name(FixnumLbl),
+ Tail = [BignumLbl,
+ hipe_rtl:mk_branch(DstReg, 'ltu',
+ hipe_rtl:mk_imm(1 bsl (WordBits - ?BYTE_SHIFT)),
+ FixnumLblName, FalseLblName, 0.99),
+ FixnumLbl,
+ hipe_rtl:mk_alu(DstReg, DstReg, sll, hipe_rtl:mk_imm(?BYTE_SHIFT))],
+ Code = first_part(BitsVar, DstReg, FalseLblName, FixnumLblName,
+ hipe_rtl:label_name(BignumLbl), Tail),
{Code, DstReg};
make_size(UnitImm, BitsVar, FalseLblName) ->
[DstReg] = create_regs(1),
@@ -1151,12 +1190,13 @@ floorlog2(X) ->
round(math:log(X)/math:log(2)-0.5).
set_high(X) ->
- set_high(X, 0).
+ WordBits = hipe_rtl_arch:word_size() * ?BYTE_SIZE,
+ set_high(min(X, WordBits), WordBits, 0).
-set_high(0, Y) ->
+set_high(0, _, Y) ->
Y;
-set_high(X, Y) ->
- set_high(X-1, Y+(1 bsl (27-X))).
+set_high(X, WordBits, Y) ->
+ set_high(X-1, WordBits, Y+(1 bsl (WordBits-X))).
is_illegal_const(Const) ->
Const >= 1 bsl (hipe_rtl_arch:word_size() * ?BYTE_SIZE) orelse Const < 0.
diff --git a/lib/hipe/rtl/hipe_tagscheme.erl b/lib/hipe/rtl/hipe_tagscheme.erl
index 1bb4c3cc5f..d77078acb6 100644
--- a/lib/hipe/rtl/hipe_tagscheme.erl
+++ b/lib/hipe/rtl/hipe_tagscheme.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2015. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -41,7 +41,8 @@
test_any_pid/4, test_any_port/4,
test_ref/4, test_fun/4, test_fun2/5, test_matchstate/4,
test_binary/4, test_bitstr/4, test_list/4, test_map/4,
- test_integer/4, test_number/4, test_tuple_N/5]).
+ test_integer/4, test_number/4, test_tuple_N/5,
+ test_pos_bignum_arity/5]).
-export([realtag_fixnum/2, tag_fixnum/2, realuntag_fixnum/2, untag_fixnum/2]).
-export([test_two_fixnums/3, test_fixnums/4, unsafe_fixnum_add/3,
unsafe_fixnum_sub/3,
@@ -53,9 +54,10 @@
-export([unsafe_closure_element/3]).
-export([mk_fun_header/0, tag_fun/2]).
-export([unsafe_untag_float/2, unsafe_tag_float/2]).
--export([mk_sub_binary/6,mk_sub_binary/7]).
+-export([mk_sub_binary/6, mk_sub_binary/7]).
-export([unsafe_mk_big/3, unsafe_load_float/3]).
--export([bignum_sizeneed/1,bignum_sizeneed_code/2, get_one_word_pos_bignum/3]).
+-export([bignum_sizeneed/1, bignum_sizeneed_code/2, get_one_word_pos_bignum/3,
+ unsafe_get_one_word_pos_bignum/2]).
-export([test_subbinary/3, test_heap_binary/3]).
-export([create_heap_binary/3, create_refc_binary/3, create_refc_binary/4]).
-export([create_matchstate/6, convert_matchstate/1, compare_matchstate/4]).
@@ -349,6 +351,15 @@ test_pos_bignum(X, TrueLab, FalseLab, Pred) ->
mask_and_compare(Tmp, BigMask, ?TAG_HEADER_POS_BIG,
TrueLab, FalseLab, Pred)].
+test_pos_bignum_arity(X, Arity, TrueLab, FalseLab, Pred) ->
+ Tmp = hipe_rtl:mk_new_reg_gcsafe(),
+ HalfTrueLab = hipe_rtl:mk_new_label(),
+ HeaderImm = hipe_rtl:mk_imm(mk_header(Arity, ?TAG_HEADER_POS_BIG)),
+ [test_is_boxed(X, hipe_rtl:label_name(HalfTrueLab), FalseLab, Pred),
+ HalfTrueLab,
+ get_header(Tmp, X),
+ hipe_rtl:mk_branch(Tmp, 'eq', HeaderImm, TrueLab, FalseLab, Pred)].
+
test_matchstate(X, TrueLab, FalseLab, Pred) ->
Tmp = hipe_rtl:mk_new_reg_gcsafe(),
HalfTrueLab = hipe_rtl:mk_new_label(),
@@ -963,13 +974,16 @@ get_one_word_pos_bignum(USize, Size, Fail) ->
Header = hipe_rtl:mk_new_reg(),
HalfLbl = hipe_rtl:mk_new_label(),
HalfLblName = hipe_rtl:label_name(HalfLbl),
- WordSize = hipe_rtl_arch:word_size(),
PosHead = hipe_rtl:mk_imm(mk_header(1, ?TAG_HEADER_POS_BIG)),
[get_header(Header, Size),
hipe_rtl:mk_branch(Header, eq, PosHead, HalfLblName, Fail),
- HalfLbl,
- hipe_rtl:mk_load(USize, Size, hipe_rtl:mk_imm(1*WordSize
- -?TAG_PRIMARY_BOXED))].
+ HalfLbl |
+ unsafe_get_one_word_pos_bignum(USize, Size)].
+
+unsafe_get_one_word_pos_bignum(USize, Size) ->
+ WordSize = hipe_rtl_arch:word_size(),
+ Imm = hipe_rtl:mk_imm(1*WordSize-?TAG_PRIMARY_BOXED),
+ [hipe_rtl:mk_load(USize, Size, Imm)].
-spec bignum_sizeneed(non_neg_integer()) -> non_neg_integer().
diff --git a/lib/hipe/test/bs_SUITE_data/bs_construct.erl b/lib/hipe/test/bs_SUITE_data/bs_construct.erl
index 9cc9ac848c..37a54c1981 100644
--- a/lib/hipe/test/bs_SUITE_data/bs_construct.erl
+++ b/lib/hipe/test/bs_SUITE_data/bs_construct.erl
@@ -13,6 +13,7 @@ test() ->
ok = bs5(),
16#10000008 = bit_size(large_bin(1, 2, 3, 4)),
ok = bad_ones(),
+ ok = zero_width(),
ok.
%%--------------------------------------------------------------------
@@ -126,3 +127,18 @@ bad_ones() ->
Bin123 = <<1,2,3>>,
?FAIL(<<Bin123/float>>),
ok.
+
+%%--------------------------------------------------------------------
+%% Taken from the emulator bs_construct_SUITE - seg faulted till 18.1
+
+zero_width() ->
+ Z = id(0),
+ Small = id(42),
+ Big = id(1 bsl 128), % puts stuff on the heap
+ <<>> = <<Small:Z>>,
+ <<>> = <<Small:0>>,
+ <<>> = <<Big:Z>>,
+ <<>> = <<Big:0>>,
+ ok.
+
+id(X) -> X.
diff --git a/lib/hipe/test/bs_SUITE_data/bs_match.erl b/lib/hipe/test/bs_SUITE_data/bs_match.erl
index 7bc93a316b..b241ea8d35 100644
--- a/lib/hipe/test/bs_SUITE_data/bs_match.erl
+++ b/lib/hipe/test/bs_SUITE_data/bs_match.erl
@@ -1,8 +1,8 @@
%%% -*- erlang-indent-level: 2 -*-
%%%-------------------------------------------------------------------
%%% File : bs_match.erl
-%%% Author : Per Gustafsson <[email protected]>
-%%% Purpose : Performs simple matching and construction of binaries
+%%% Authors : Per Gustafsson <[email protected]>, Kostis Sagonas <[email protected]>
+%%% Purpose : Tests matching and construction of binaries
%%% TODO : Add binary and float tests
%%% Created : 20 Feb 2004
%%%-------------------------------------------------------------------
@@ -13,7 +13,7 @@
test() ->
Funs = [fun test_aligned/0, fun test_unaligned/0,
fun test_zero_tail/0, fun test_integer_matching/0,
- fun test_writable_bin/0],
+ fun test_writable_bin/0, fun test_match_huge_bin/0],
lists:foreach(fun (F) -> ok = F() end, Funs).
%%-------------------------------------------------------------------
@@ -175,6 +175,9 @@ test_dynamic_integer_matching(N) ->
<<12:N/integer-little, 0:S>> = <<12:N/integer-little, 0:S>>,
ok.
+%%-------------------------------------------------------------------
+%% Test writable bin -- added by Sverker Eriksson
+
test_writable_bin() ->
test_writable_bin(<<>>, 0),
ok.
@@ -185,3 +188,102 @@ test_writable_bin(Bin0, N) when N < 128 ->
Bin1 = <<Bin0/binary, N>>,
<<_/utf8, _/binary>> = Bin1,
test_writable_bin(Bin1, N+1).
+
+%%-------------------------------------------------------------------
+%% Test matching with a huge bin -- taken from bs_match_bin_SUITE
+
+test_match_huge_bin() ->
+ Bin = <<0:(1 bsl 27),13:8>>,
+ skip_huge_bin_1(1 bsl 27, Bin),
+ 16777216 = match_huge_bin_1(1 bsl 27, Bin),
+ %% Test overflowing the size of a binary field.
+ nomatch = overflow_huge_bin_skip_32(Bin),
+ nomatch = overflow_huge_bin_32(Bin),
+ nomatch = overflow_huge_bin_skip_64(Bin),
+ nomatch = overflow_huge_bin_64(Bin),
+ %% Size in variable
+ ok = overflow_huge_bin(Bin, lists:seq(25, 32)++lists:seq(50, 64)),
+ ok = overflow_huge_bin_unit128(Bin, lists:seq(25, 32)++lists:seq(50, 64)),
+ ok.
+
+overflow_huge_bin(Bin, [Sz0|Sizes]) ->
+ Sz = id(1 bsl Sz0),
+ case Bin of
+ <<_:Sz/binary-unit:8,0,_/binary>> ->
+ {error,Sz};
+ _ ->
+ case Bin of
+ <<NewBin:Sz/binary-unit:8,0,_/binary>> ->
+ {error,Sz,size(NewBin)};
+ _ ->
+ overflow_huge_bin(Bin, Sizes)
+ end
+ end;
+overflow_huge_bin(_, []) -> ok.
+
+overflow_huge_bin_unit128(Bin, [Sz0|Sizes]) ->
+ Sz = id(1 bsl Sz0),
+ case Bin of
+ <<_:Sz/binary-unit:128,0,_/binary>> ->
+ {error,Sz};
+ _ ->
+ case Bin of
+ <<NewBin:Sz/binary-unit:128,0,_/binary>> ->
+ {error,Sz,size(NewBin)};
+ _ ->
+ overflow_huge_bin_unit128(Bin, Sizes)
+ end
+ end;
+overflow_huge_bin_unit128(_, []) -> ok.
+
+skip_huge_bin_1(I, Bin) ->
+ <<_:I/binary-unit:1,13>> = Bin,
+ ok.
+
+match_huge_bin_1(I, Bin) ->
+ case Bin of
+ <<Val:I/binary-unit:1,13>> -> size(Val);
+ _ -> nomatch
+ end.
+
+overflow_huge_bin_skip_32(<<_:4294967296/binary,0,_/binary>>) -> 1; % 1 bsl 32
+overflow_huge_bin_skip_32(<<_:33554432/binary-unit:128,0,_/binary>>) -> 2; % 1 bsl 25
+overflow_huge_bin_skip_32(<<_:67108864/binary-unit:64,0,_/binary>>) -> 3; % 1 bsl 26
+overflow_huge_bin_skip_32(<<_:134217728/binary-unit:32,0,_/binary>>) -> 4; % 1 bsl 27
+overflow_huge_bin_skip_32(<<_:268435456/binary-unit:16,0,_/binary>>) -> 5; % 1 bsl 28
+overflow_huge_bin_skip_32(<<_:536870912/binary-unit:8,0,_/binary>>) -> 6; % 1 bsl 29
+overflow_huge_bin_skip_32(<<_:1073741824/binary-unit:8,0,_/binary>>) -> 7; % 1 bsl 30
+overflow_huge_bin_skip_32(<<_:2147483648/binary-unit:8,0,_/binary>>) -> 8; % 1 bsl 31
+overflow_huge_bin_skip_32(_) -> nomatch.
+
+overflow_huge_bin_32(<<Bin:4294967296/binary,_/binary>>) -> {1,Bin}; % 1 bsl 32
+overflow_huge_bin_32(<<Bin:33554432/binary-unit:128,0,_/binary>>) -> {2,Bin}; % 1 bsl 25
+overflow_huge_bin_32(<<Bin:67108864/binary-unit:128,0,_/binary>>) -> {3,Bin}; % 1 bsl 26
+overflow_huge_bin_32(<<Bin:134217728/binary-unit:128,0,_/binary>>) -> {4,Bin}; % 1 bsl 27
+overflow_huge_bin_32(<<Bin:268435456/binary-unit:128,0,_/binary>>) -> {5,Bin}; % 1 bsl 28
+overflow_huge_bin_32(<<Bin:536870912/binary-unit:128,0,_/binary>>) -> {6,Bin}; % 1 bsl 29
+overflow_huge_bin_32(<<Bin:1073741824/binary-unit:128,0,_/binary>>) -> {7,Bin}; % 1 bsl 30
+overflow_huge_bin_32(<<Bin:2147483648/binary-unit:128,0,_/binary>>) -> {8,Bin}; % 1 bsl 31
+overflow_huge_bin_32(_) -> nomatch.
+
+overflow_huge_bin_skip_64(<<_:18446744073709551616/binary,0,_/binary>>) -> 1; % 1 bsl 64
+overflow_huge_bin_skip_64(<<_:144115188075855872/binary-unit:128,0,_/binary>>) -> 2; % 1 bsl 57
+overflow_huge_bin_skip_64(<<_:288230376151711744/binary-unit:64,0,_/binary>>) -> 3; % 1 bsl 58
+overflow_huge_bin_skip_64(<<_:576460752303423488/binary-unit:32,0,_/binary>>) -> 4; % 1 bsl 59
+overflow_huge_bin_skip_64(<<_:1152921504606846976/binary-unit:16,0,_/binary>>) -> 5; % 1 bsl 60
+overflow_huge_bin_skip_64(<<_:2305843009213693952/binary-unit:8,0,_/binary>>) -> 6; % 1 bsl 61
+overflow_huge_bin_skip_64(<<_:4611686018427387904/binary-unit:8,0,_/binary>>) -> 7; % 1 bsl 62
+overflow_huge_bin_skip_64(<<_:9223372036854775808/binary-unit:8,_/binary>>) -> 8; % 1 bsl 63
+overflow_huge_bin_skip_64(_) -> nomatch.
+
+overflow_huge_bin_64(<<Bin:18446744073709551616/binary,_/binary>>) -> {1,Bin}; % 1 bsl 64
+overflow_huge_bin_64(<<Bin:144115188075855872/binary-unit:128,0,_/binary>>) -> {2,Bin}; % 1 bsl 57
+overflow_huge_bin_64(<<Bin:288230376151711744/binary-unit:128,0,_/binary>>) -> {3,Bin}; % 1 bsl 58
+overflow_huge_bin_64(<<Bin:576460752303423488/binary-unit:128,0,_/binary>>) -> {4,Bin}; % 1 bsl 59
+overflow_huge_bin_64(<<Bin:1152921504606846976/binary-unit:128,0,_/binary>>) -> {5,Bin}; % 1 bsl 60
+overflow_huge_bin_64(<<Bin:2305843009213693952/binary-unit:128,0,_/binary>>) -> {6,Bin}; % 1 bsl 61
+overflow_huge_bin_64(<<Bin:4611686018427387904/binary-unit:128,0,_/binary>>) -> {7,Bin}; % 1 bsl 62
+overflow_huge_bin_64(<<Bin:9223372036854775808/binary-unit:128,0,_/binary>>) -> {8,Bin}; % 1 bsl 63
+overflow_huge_bin_64(_) -> nomatch.
+
+id(I) -> I.
diff --git a/lib/inets/doc/src/http_uri.xml b/lib/inets/doc/src/http_uri.xml
index 47c40da96a..64e6c7a6cc 100644
--- a/lib/inets/doc/src/http_uri.xml
+++ b/lib/inets/doc/src/http_uri.xml
@@ -117,7 +117,8 @@
<v>Options = [Option]</v>
<v>Option = {ipv6_host_with_brackets, boolean()} |
{scheme_defaults, scheme_defaults()} |
- {fragment, boolean()}]</v>
+ {fragment, boolean()} |
+ {schema_validation_fun, fun()}]</v>
<v>Result = {Scheme, UserInfo, Host, Port, Path, Query} |
{Scheme, UserInfo, Host, Port, Path, Query, Fragment}</v>
<v>UserInfo = user_info()</v>
@@ -141,6 +142,16 @@
<p>If the fragment option is <c>true</c>, the URI fragment is returned as
part of the parsing result, otherwise it is ignored.</p>
+ <p>Scheme validation fun is to be defined as follows:
+
+ <code>
+fun(SchemeStr :: string()) ->
+ valid | {error, Reason :: term()}.
+ </code>
+
+ It is called before scheme string gets converted into scheme atom and
+ thus possible atom leak could be prevented</p>
+
<marker id="encode"></marker>
</desc>
</func>
diff --git a/lib/inets/doc/src/httpd.xml b/lib/inets/doc/src/httpd.xml
index 2a4aea41c2..0fc3cb1ce7 100644
--- a/lib/inets/doc/src/httpd.xml
+++ b/lib/inets/doc/src/httpd.xml
@@ -177,21 +177,22 @@
</item>
<marker id="prop_socket_type"></marker>
- <tag>{socket_type, ip_comm | {essl, Config::proplist()}}</tag>
+ <tag>{socket_type, ip_comm | {ip_comm, Config::proplist()} | {essl, Config::proplist()}}</tag>
<item>
+ <p>For <c>ip_comm</c> configuration options, see
+ <seealso marker="kernel:gen_tcp#listen-2">gen_tcp:listen/2</seealso>, some options
+ that are used internally by httpd can not be set.</p>
<p>For <c>SSL</c> configuration options, see
<seealso marker="ssl:ssl#listen-2">ssl:listen/2</seealso>.</p>
<p>Default is <c>ip_comm</c>.</p>
</item>
<marker id="prop_ipfamily"></marker>
- <tag>{ipfamily, inet | inet6 | inet6fb4}</tag>
+ <tag>{ipfamily, inet | inet6}</tag>
<item>
- <p>This option is only used when option
- <c>socket_type</c> has value <c>ip_comm</c>.</p>
- <p>Default is <c>inet6fb4</c>.</p>
+ <p>Default is <c>inet</c>, legacy option <c>inet6fb4</c> no longer makes sense and will be translated
+ to inet.</p>
</item>
-
<marker id="prop_minimum_bytes_per_second"></marker>
<tag>{minimum_bytes_per_second, integer()}</tag>
diff --git a/lib/inets/doc/src/httpd_custom_api.xml b/lib/inets/doc/src/httpd_custom_api.xml
index 23417900fa..d2e5441895 100644
--- a/lib/inets/doc/src/httpd_custom_api.xml
+++ b/lib/inets/doc/src/httpd_custom_api.xml
@@ -33,6 +33,20 @@
</description>
<funcs>
+ <func>
+ <name>response_default_headers() -> [Header] </name>
+ <fsummary>Provide default headers for the HTTP servers responses.</fsummary>
+ <type>
+ <v>Header = {HeaderName :: string(), HeaderValue::string()}</v>
+ <d>string:to_lower/1 will be performed on the HeaderName</d>
+ </type>
+ <desc>
+ <p>Provide default headers for the HTTP servers responses. Note that this
+ option may override built-in defaults.
+ </p>
+ </desc>
+ </func>
+
<func>
<name>response_header({HeaderName, HeaderValue}) -> {true, Header} | false </name>
<fsummary>Filter and possible alter HTTP response headers.</fsummary>
diff --git a/lib/inets/doc/src/notes.xml b/lib/inets/doc/src/notes.xml
index eb1027b028..8c4fdfdf70 100644
--- a/lib/inets/doc/src/notes.xml
+++ b/lib/inets/doc/src/notes.xml
@@ -33,7 +33,71 @@
<file>notes.xml</file>
</header>
- <section><title>Inets 6.0.1</title>
+ <section><title>Inets 6.0.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Improved error handling and gracfully termination when an
+ invalid chunked length header is encountered.</p>
+ <p>
+ Own Id: OTP-13061</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Add possibility to set socket options, such as nodelay,
+ for httpd. Also phase out legacy option value inet6bf4
+ for the ipfamily option. This value will be translated to
+ the value inet.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-13062</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Inets 6.0.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Avoid crash in mod_auth_server and mod_security_server
+ due to using an atom instead of a string when creating a
+ name.</p>
+ <p>
+ Own Id: OTP-13022</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Add function response_default_headers/0 to httpd
+ customize API, to allow user to specify default values
+ for HTTP response headers.</p>
+ <p>
+ Own Id: OTP-13013</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Inets 6.0.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/inets/src/http_client/httpc_handler.erl b/lib/inets/src/http_client/httpc_handler.erl
index 6e6cc38c06..d1c52dcc78 100644
--- a/lib/inets/src/http_client/httpc_handler.erl
+++ b/lib/inets/src/http_client/httpc_handler.erl
@@ -26,6 +26,7 @@
-include_lib("inets/src/http_lib/http_internal.hrl").
-include("httpc_internal.hrl").
+-define(IS_STREAMED(Code), ((Code =:= 200) orelse (Code =:= 206))).
%%--------------------------------------------------------------------
%% Internal Application API
@@ -163,22 +164,22 @@ info(Pid) ->
%% Request should not be streamed
stream(BodyPart, #request{stream = none} = Request, _) ->
?hcrt("stream - none", []),
- {BodyPart, Request};
+ {false, BodyPart, Request};
%% Stream to caller
stream(BodyPart, #request{stream = Self} = Request, Code)
- when ((Code =:= 200) orelse (Code =:= 206)) andalso
+ when ?IS_STREAMED(Code) andalso
((Self =:= self) orelse (Self =:= {self, once})) ->
?hcrt("stream - self", [{stream, Self}, {code, Code}]),
httpc_response:send(Request#request.from,
{Request#request.id, stream, BodyPart}),
- {<<>>, Request};
+ {true, <<>>, Request};
%% Stream to file
%% This has been moved to start_stream/3
%% We keep this for backward compatibillity...
stream(BodyPart, #request{stream = Filename} = Request, Code)
- when ((Code =:= 200) orelse (Code =:= 206)) andalso is_list(Filename) ->
+ when ?IS_STREAMED(Code) andalso is_list(Filename) ->
?hcrt("stream - filename", [{stream, Filename}, {code, Code}]),
case file:open(Filename, [write, raw, append, delayed_write]) of
{ok, Fd} ->
@@ -190,18 +191,18 @@ stream(BodyPart, #request{stream = Filename} = Request, Code)
%% Stream to file
stream(BodyPart, #request{stream = Fd} = Request, Code)
- when ((Code =:= 200) orelse (Code =:= 206)) ->
+ when ?IS_STREAMED(Code) ->
?hcrt("stream to file", [{stream, Fd}, {code, Code}]),
case file:write(Fd, BodyPart) of
ok ->
- {<<>>, Request};
+ {true, <<>>, Request};
{error, Reason} ->
exit({stream_to_file_failed, Reason})
end;
stream(BodyPart, Request,_) -> % only 200 and 206 responses can be streamed
?hcrt("stream - ignore", [{request, Request}]),
- {BodyPart, Request}.
+ {false, BodyPart, Request}.
%%====================================================================
@@ -474,18 +475,18 @@ handle_info({Proto, _Socket, Data},
{Module, whole_body, [Body, Length]} ->
?hcrd("data processed - whole body", [{length, Length}]),
{_, Code, _} = StatusLine,
- {NewBody, NewRequest} = stream(Body, Request, Code),
+ {Streamed, NewBody, NewRequest} = stream(Body, Request, Code),
%% When we stream we will not keep the already
%% streamed data, that would be a waste of memory.
NewLength =
- case Stream of
- none ->
+ case Streamed of
+ false ->
Length;
- _ ->
+ true ->
Length - size(Body)
end,
- NewState = next_body_chunk(State),
+ NewState = next_body_chunk(State, Code),
NewMFA = {Module, whole_body, [NewBody, NewLength]},
{noreply, NewState#state{mfa = NewMFA,
request = NewRequest}};
@@ -497,8 +498,8 @@ handle_info({Proto, _Socket, Data},
%% The response body is chunk-encoded. Steal decoded
%% chunks as much as possible to stream.
{_, Code, _} = StatusLine,
- {NewBody, NewRequest} = stream(BodySoFar, Request, Code),
- NewState = next_body_chunk(State),
+ {_, NewBody, NewRequest} = stream(BodySoFar, Request, Code),
+ NewState = next_body_chunk(State, Code),
NewMFA = {Module, decode_size,
[TotalChunk, HexList,
{MaxBodySize, NewBody, AccLength, MaxHeaderSize}]},
@@ -517,8 +518,8 @@ handle_info({Proto, _Socket, Data},
NewChunkSize = ChunkSize - ChunkSizeToSteal,
{_, Code, _} = StatusLine,
- {NewBody, NewRequest} = stream(StolenBody, Request, Code),
- NewState = next_body_chunk(State),
+ {_, NewBody, NewRequest} = stream(StolenBody, Request, Code),
+ NewState = next_body_chunk(State, Code),
NewMFA = {Module, decode_data,
[NewChunkSize, NewTotalChunk,
{MaxBodySize, NewBody, AccLength, MaxHeaderSize}]},
@@ -1071,13 +1072,13 @@ handle_http_msg({ChunkedHeaders, Body},
?hcrt("handle_http_msg",
[{chunked_headers, ChunkedHeaders}, {headers, Headers}]),
NewHeaders = http_chunk:handle_headers(Headers, ChunkedHeaders),
- {NewBody, NewRequest} = stream(Body, State#state.request, Code),
+ {_, NewBody, NewRequest} = stream(Body, State#state.request, Code),
handle_response(State#state{headers = NewHeaders,
body = NewBody,
request = NewRequest});
handle_http_msg(Body, #state{status_line = {_,Code, _}} = State) ->
?hcrt("handle_http_msg", [{code, Code}]),
- {NewBody, NewRequest} = stream(Body, State#state.request, Code),
+ {_, NewBody, NewRequest} = stream(Body, State#state.request, Code),
handle_response(State#state{body = NewBody, request = NewRequest}).
handle_http_body(_, #state{status = {ssl_tunnel, _},
@@ -1112,14 +1113,14 @@ handle_http_body(Body, #state{headers = Headers,
case case_insensitive_header(TransferEnc) of
"chunked" ->
?hcrt("handle_http_body - chunked", []),
- case http_chunk:decode(Body, State#state.max_body_size,
- State#state.max_header_size) of
+ try http_chunk:decode(Body, State#state.max_body_size,
+ State#state.max_header_size) of
{Module, Function, Args} ->
?hcrt("handle_http_body - new mfa",
[{module, Module},
{function, Function},
{args, Args}]),
- NewState = next_body_chunk(State),
+ NewState = next_body_chunk(State, Code),
{noreply, NewState#state{mfa =
{Module, Function, Args}}};
{ok, {ChunkedHeaders, NewBody}} ->
@@ -1133,11 +1134,18 @@ handle_http_body(Body, #state{headers = Headers,
handle_response(State#state{headers = NewHeaders,
body = NewBody});
_ ->
- {NewBody2, _NewRequest} =
+ {_, NewBody2, _} =
stream(NewBody, Request, Code),
handle_response(State#state{headers = NewHeaders,
body = NewBody2})
end
+ catch throw:{error, Reason} ->
+ NewState =
+ answer_request(Request,
+ httpc_response:error(Request,
+ Reason),
+ State),
+ {stop, normal, NewState}
end;
Enc when Enc =:= "identity"; Enc =:= undefined ->
?hcrt("handle_http_body - identity", []),
@@ -1147,12 +1155,12 @@ handle_http_body(Body, #state{headers = Headers,
true ->
case httpc_response:whole_body(Body, Length) of
{ok, Body} ->
- {NewBody, NewRequest} =
+ {_, NewBody, NewRequest} =
stream(Body, Request, Code),
handle_response(State#state{body = NewBody,
request = NewRequest});
MFA ->
- NewState = next_body_chunk(State),
+ NewState = next_body_chunk(State, Code),
{noreply, NewState#state{mfa = MFA}}
end;
false ->
@@ -1646,21 +1654,21 @@ start_stream({_Version, _Code, _ReasonPhrase}, _Headers,
{ok, Request};
start_stream({_Version, Code, _ReasonPhrase}, Headers,
#request{stream = self} = Request)
- when (Code =:= 200) orelse (Code =:= 206) ->
+ when ?IS_STREAMED(Code) ->
?hcrt("start stream - self", [{code, Code}]),
Msg = httpc_response:stream_start(Headers, Request, ignore),
httpc_response:send(Request#request.from, Msg),
{ok, Request};
start_stream({_Version, Code, _ReasonPhrase}, Headers,
#request{stream = {self, once}} = Request)
- when (Code =:= 200) orelse (Code =:= 206) ->
+ when ?IS_STREAMED(Code) ->
?hcrt("start stream - self:once", [{code, Code}]),
Msg = httpc_response:stream_start(Headers, Request, self()),
httpc_response:send(Request#request.from, Msg),
{ok, Request};
start_stream({_Version, Code, _ReasonPhrase}, _Headers,
#request{stream = Filename} = Request)
- when ((Code =:= 200) orelse (Code =:= 206)) andalso is_list(Filename) ->
+ when ?IS_STREAMED(Code) andalso is_list(Filename) ->
?hcrt("start stream", [{code, Code}, {filename, Filename}]),
case file:open(Filename, [write, raw, append, delayed_write]) of
{ok, Fd} ->
@@ -1712,13 +1720,15 @@ end_stream(SL, R) ->
next_body_chunk(#state{request = #request{stream = {self, once}},
once = once,
- session = Session} = State) ->
+ session = Session} = State,
+ Code) when ?IS_STREAMED(Code) ->
activate_once(Session),
State#state{once = inactive};
next_body_chunk(#state{request = #request{stream = {self, once}},
- once = inactive} = State) ->
+ once = inactive} = State,
+ Code) when ?IS_STREAMED(Code) ->
State; %% Wait for user to call stream_next
-next_body_chunk(#state{session = Session} = State) ->
+next_body_chunk(#state{session = Session} = State, _) ->
activate_once(Session),
State.
@@ -1817,11 +1827,13 @@ host_header(_, URI) ->
tls_upgrade(#state{status =
{ssl_tunnel,
#request{settings =
- #http_options{ssl = {_, TLSOptions} = SocketType},
- address = Address} = Request},
+ #http_options{ssl = {_, TLSOptions0} = SocketType},
+ address = {Host, _} = Address} = Request},
session = #session{socket = TCPSocket} = Session0,
options = Options} = State) ->
+ TLSOptions = maybe_add_sni(Host, TLSOptions0),
+
case ssl:connect(TCPSocket, TLSOptions) of
{ok, TLSSocket} ->
ClientClose = httpc_request:is_client_closing(Request#request.headers),
@@ -1852,6 +1864,15 @@ tls_upgrade(#state{status =
{stop, normal, State#state{request = Request}}
end.
+maybe_add_sni(Host, Options) ->
+ case http_util:is_hostname(Host) andalso
+ not lists:keymember(server_name_indication, 1, Options) of
+ true ->
+ [{server_name_indication, Host} | Options];
+ false ->
+ Options
+ end.
+
%% ---------------------------------------------------------------------
%% Session wrappers
%% ---------------------------------------------------------------------
diff --git a/lib/inets/src/http_lib/http_chunk.erl b/lib/inets/src/http_lib/http_chunk.erl
index 9476ea9f5f..7325f24809 100644
--- a/lib/inets/src/http_lib/http_chunk.erl
+++ b/lib/inets/src/http_lib/http_chunk.erl
@@ -25,7 +25,7 @@
-include("http_internal.hrl").
%% API
--export([decode/3, encode/1, encode_last/0, handle_headers/2]).
+-export([decode/3, encode/1, encode_last/0, encode_last/1, handle_headers/2]).
%% Callback API - used for example if the chunkedbody is received a
%% little at a time on a socket.
-export([decode_size/1, ignore_extensions/1, decode_data/1, decode_trailer/1]).
@@ -57,7 +57,7 @@
%%-------------------------------------------------------------------------
decode(ChunkedBody, MaxBodySize, MaxHeaderSize) ->
%% Note decode_size will call decode_data.
- decode_size([ChunkedBody, <<>>, [],
+ decode_size([ChunkedBody, <<>>, [], 0,
{MaxBodySize, <<>>, 0, MaxHeaderSize}]).
%%-------------------------------------------------------------------------
@@ -85,6 +85,11 @@ encode(Chunk) when is_list(Chunk)->
encode_last() ->
<<$0, ?CR, ?LF, ?CR, ?LF >>.
+encode_last([]) ->
+ encode_last();
+encode_last(Trailers0) ->
+ Trailers = list_to_binary(encode_trailers(Trailers0)),
+ <<$0, ?CR, ?LF, Trailers/binary>>.
%%-------------------------------------------------------------------------
%% handle_headers(HeaderRecord, ChunkedHeaders) -> NewHeaderRecord
@@ -120,65 +125,80 @@ handle_headers(ResponseHeaderRecord = #http_response_h{}, ChunkedHeaders) ->
%% Functions that may be returned during the decoding process
%% if the input data is incompleate.
-decode_size([Bin, Rest, HexList, Info]) ->
- decode_size(<<Rest/binary, Bin/binary>>, HexList, Info).
+decode_size([Bin, Rest, HexList, AccSize, Info]) ->
+ decode_size(<<Rest/binary, Bin/binary>>, HexList, AccSize, Info).
-ignore_extensions([Bin, Rest, NextFunction]) ->
- ignore_extensions(<<Rest/binary, Bin/binary>>, NextFunction).
+ignore_extensions([Bin, Rest, RemainingSize, TotalMaxHeaderSize, NextFunction]) ->
+ ignore_extensions(<<Rest/binary, Bin/binary>>, RemainingSize, TotalMaxHeaderSize, NextFunction).
decode_data([Bin, ChunkSize, TotalChunk, Info]) ->
decode_data(ChunkSize, <<TotalChunk/binary, Bin/binary>>, Info).
-decode_trailer([Bin, Rest, Header, Headers, MaxHeaderSize, Body,
- BodyLength]) ->
+decode_trailer([Bin, Rest, Header, Headers, Body,
+ BodyLength, RemainingSize, TotalMaxHeaderSize]) ->
decode_trailer(<<Rest/binary, Bin/binary>>,
- Header, Headers, MaxHeaderSize, Body, BodyLength).
+ Header, Headers, Body, BodyLength, RemainingSize, TotalMaxHeaderSize).
%%%========================================================================
%%% Internal functions
%%%========================================================================
-decode_size(<<>>, HexList, Info) ->
- {?MODULE, decode_size, [<<>>, HexList, Info]};
-decode_size(Data = <<?CR, ?LF, ChunkRest/binary>>, HexList,
+decode_size(_, _, AccHeaderSize, {_,_,_, MaxHeaderSize}) when
+ AccHeaderSize > MaxHeaderSize ->
+ throw({error, {header_too_long, {max, MaxHeaderSize}}});
+
+decode_size(<<>>, HexList, AccHeaderSize, Info) ->
+ {?MODULE, decode_size, [<<>>, HexList, AccHeaderSize, Info]};
+decode_size(Data = <<?CR, ?LF, ChunkRest/binary>>, HexList, AccHeaderSize,
{MaxBodySize, Body,
AccLength,
MaxHeaderSize}) ->
- ChunkSize = http_util:hexlist_to_integer(lists:reverse(HexList)),
- case ChunkSize of
+ try http_util:hexlist_to_integer(lists:reverse(string:strip(HexList, left))) of
0 -> % Last chunk, there was no data
- ignore_extensions(Data, {?MODULE, decode_trailer,
- [<<>>, [],[], MaxHeaderSize,
- Body,
- integer_to_list(AccLength)]});
- _ ->
+ ignore_extensions(Data, remaing_size(MaxHeaderSize, AccHeaderSize), MaxHeaderSize,
+ {?MODULE, decode_trailer,
+ [<<>>, [],[],
+ Body,
+ integer_to_list(AccLength)]});
+ ChunkSize ->
%% Note decode_data may call decode_size again if there
%% is more than one chunk, hence here is where the last parameter
%% to this function comes in.
decode_data(ChunkSize, ChunkRest, {MaxBodySize, Body,
- ChunkSize + AccLength ,
+ ChunkSize + AccLength,
MaxHeaderSize})
+ catch
+ _:_ ->
+ throw({error, {chunk_size, lists:reverse(HexList)}})
end;
-decode_size(<<";", Rest/binary>>, HexList, Info) ->
+decode_size(<<";", Rest/binary>>, HexList, AccHeaderSize, {_,_,_, MaxHeaderSize} = Info) ->
%% Note ignore_extensions will call decode_size/1 again when
%% it ignored all extensions.
- ignore_extensions(Rest, {?MODULE, decode_size, [<<>>, HexList, Info]});
-decode_size(<<?CR>> = Data, HexList, Info) ->
- {?MODULE, decode_size, [Data, HexList, Info]};
-decode_size(<<Octet, Rest/binary>>, HexList, Info) ->
- decode_size(Rest, [Octet | HexList], Info).
+ ignore_extensions(Rest, remaing_size(MaxHeaderSize, AccHeaderSize), MaxHeaderSize,
+ {?MODULE, decode_size, [<<>>, HexList, AccHeaderSize, Info]});
+decode_size(<<?CR>> = Data, HexList, AccHeaderSize, Info) ->
+ {?MODULE, decode_size, [Data, HexList, AccHeaderSize, Info]};
+decode_size(<<Octet, Rest/binary>>, HexList, AccHeaderSize, Info) ->
+ decode_size(Rest, [Octet | HexList], AccHeaderSize + 1, Info).
%% "All applications MUST ignore chunk-extension extensions they
%% do not understand.", see RFC 2616 Section 3.6.1 We don't
%% understand any extension...
-ignore_extensions(<<>>, NextFunction) ->
- {?MODULE, ignore_extensions, [<<>>, NextFunction]};
-ignore_extensions(Data = <<?CR, ?LF, _ChunkRest/binary>>,
+ignore_extensions(_, 0, TotalMaxHeaderSize, _) ->
+ throw({error, {header_too_long, {max, TotalMaxHeaderSize}}});
+ignore_extensions(<<>>, RemainingSize, TotalMaxHeaderSize, NextFunction) ->
+ {?MODULE, ignore_extensions, [<<>>, RemainingSize, TotalMaxHeaderSize, NextFunction]};
+ignore_extensions(Data = <<?CR, ?LF, _ChunkRest/binary>>, RemainingSize, TotalMaxHeaderSize,
{Module, Function, Args}) ->
- Module:Function([Data | Args]);
-ignore_extensions(<<?CR>> = Data, NextFunction) ->
- {?MODULE, ignore_extensions, [Data, NextFunction]};
-ignore_extensions(<<_Octet, Rest/binary>>, NextFunction) ->
- ignore_extensions(Rest, NextFunction).
+ case Function of
+ decode_trailer ->
+ Module:Function([Data | Args ++ [RemainingSize, TotalMaxHeaderSize]]);
+ _ ->
+ Module:Function([Data | Args])
+ end;
+ignore_extensions(<<?CR>> = Data, RemainingSize, TotalMaxHeaderSize, NextFunction) ->
+ {?MODULE, ignore_extensions, [Data, RemainingSize, TotalMaxHeaderSize, NextFunction]};
+ignore_extensions(<<_Octet, Rest/binary>>, RemainingSize, TotalMaxHeaderSize, NextFunction) ->
+ ignore_extensions(Rest, remaing_size(RemainingSize, 1), TotalMaxHeaderSize, NextFunction).
decode_data(ChunkSize, TotalChunk,
Info = {MaxBodySize, BodySoFar, AccLength, MaxHeaderSize})
@@ -190,83 +210,89 @@ decode_data(ChunkSize, TotalChunk,
%% once it ignored all extensions.
{?MODULE, ignore_extensions,
[<<>>,
- {?MODULE, decode_trailer, [<<>>, [],[], MaxHeaderSize,
+ {?MODULE, decode_trailer, [<<>>, [],[],
<<BodySoFar/binary, Data/binary>>,
integer_to_list(AccLength)]}]};
<<Data:ChunkSize/binary, ?CR, ?LF, "0", ";", Rest/binary>> ->
%% Note ignore_extensions will call decode_trailer/1
%% once it ignored all extensions.
- ignore_extensions(Rest, {?MODULE, decode_trailer,
- [<<>>, [],[], MaxHeaderSize,
+ ignore_extensions(Rest, MaxHeaderSize, MaxHeaderSize,
+ {?MODULE, decode_trailer,
+ [<<>>, [],[],
<<BodySoFar/binary, Data/binary>>,
integer_to_list(AccLength)]});
<<Data:ChunkSize/binary, ?CR, ?LF, "0", ?CR, ?LF>> ->
- {?MODULE, decode_trailer, [<<?CR, ?LF>>, [],[], MaxHeaderSize,
+ {?MODULE, decode_trailer, [<<?CR, ?LF>>, [],[],
<<BodySoFar/binary, Data/binary>>,
- integer_to_list(AccLength)]};
+ integer_to_list(AccLength), MaxHeaderSize, MaxHeaderSize]};
<<Data:ChunkSize/binary, ?CR, ?LF, "0", ?CR, ?LF, Rest/binary>> ->
- decode_trailer(<<?CR, ?LF, Rest/binary>>, [],[], MaxHeaderSize,
+ decode_trailer(<<?CR, ?LF, Rest/binary>>, [],[],
<<BodySoFar/binary, Data/binary>>,
- integer_to_list(AccLength));
- %% There are more chunks, so here we go agin...
+ integer_to_list(AccLength), MaxHeaderSize, MaxHeaderSize);
+ %% There are more chunks, so here we go again...
<<Data:ChunkSize/binary, ?CR, ?LF>> ->
NewBody = <<BodySoFar/binary, Data/binary>>,
- {?MODULE, decode_size, [<<>>, [], {MaxBodySize, NewBody, AccLength, MaxHeaderSize}]};
+ {?MODULE, decode_size, [<<>>, [], 0, {MaxBodySize, NewBody, AccLength, MaxHeaderSize}]};
<<Data:ChunkSize/binary, ?CR, ?LF, Rest/binary>>
when (AccLength < MaxBodySize) or (MaxBodySize == nolimit) ->
- decode_size(Rest, [],
+ decode_size(Rest, [], 0,
{MaxBodySize, <<BodySoFar/binary, Data/binary>>,
AccLength, MaxHeaderSize});
<<_:ChunkSize/binary, ?CR, ?LF, _/binary>> ->
- throw({error, body_too_big});
+ throw({error, {body_too_big, {max, MaxBodySize}}});
_ ->
{?MODULE, decode_data, [ChunkSize, TotalChunk, Info]}
end;
decode_data(ChunkSize, TotalChunk, Info) ->
{?MODULE, decode_data, [ChunkSize, TotalChunk, Info]}.
-decode_trailer(<<>>, Header, Headers, MaxHeaderSize, Body, BodyLength) ->
- {?MODULE, decode_trailer, [<<>>, Header, Headers, MaxHeaderSize, Body,
- BodyLength]};
-
+decode_trailer(_,_,_,_,_, 0, TotalMaxHeaderSize) ->
+ throw({error, {header_too_long, {max, TotalMaxHeaderSize}}});
+decode_trailer(<<>>, Header, Headers, Body, BodyLength, RemainingSize, TotalMaxHeaderSize) ->
+ {?MODULE, decode_trailer, [<<>>, Header, Headers, Body,
+ BodyLength, RemainingSize, TotalMaxHeaderSize]};
%% Note: If Bin is not empty it is part of a pipelined request/response.
-decode_trailer(<<?CR,?LF,?CR,?LF, Bin/binary>>, [], [], _, Body, BodyLength) ->
+decode_trailer(<<?CR,?LF,?CR,?LF, Bin/binary>>, [], [], Body, BodyLength, _, _) ->
{ok, {["content-length:" ++ BodyLength], <<Body/binary, Bin/binary>>}};
decode_trailer(<<?CR,?LF,?CR,?LF, Bin/binary>>,
- Header, Headers, MaxHeaderSize, Body, BodyLength) ->
+ Header, Headers, Body, BodyLength, _, _) ->
NewHeaders = case Header of
[] ->
Headers;
_ ->
[lists:reverse(Header) | Headers]
end,
- Length = length(NewHeaders),
- case Length > MaxHeaderSize of
- true ->
- throw({error, {header_too_long, MaxHeaderSize,
- MaxHeaderSize-Length}});
- false ->
- {ok, {["content-length:" ++ BodyLength | NewHeaders],
- <<Body/binary, Bin/binary>>}}
- end;
-decode_trailer(<<?CR,?LF,?CR>> = Data, Header, Headers, MaxHeaderSize,
- Body, BodyLength) ->
- {?MODULE, decode_trailer, [Data, Header, Headers, MaxHeaderSize, Body,
- BodyLength]};
-decode_trailer(<<?CR,?LF>> = Data, Header, Headers, MaxHeaderSize,
- Body, BodyLength) ->
- {?MODULE, decode_trailer, [Data, Header, Headers, MaxHeaderSize, Body,
- BodyLength]};
-decode_trailer(<<?CR>> = Data, Header, Headers, MaxHeaderSize,
- Body, BodyLength) ->
- {?MODULE, decode_trailer, [Data, Header, Headers, MaxHeaderSize, Body,
- BodyLength]};
-decode_trailer(<<?CR, ?LF, Rest/binary>>, Header, Headers,
- MaxHeaderSize, Body, BodyLength) ->
+ {ok, {["content-length:" ++ BodyLength | NewHeaders],
+ <<Body/binary, Bin/binary>>}};
+decode_trailer(<<?CR,?LF,?CR>> = Data, Header, Headers,
+ Body, BodyLength, RemainingSize, TotalMaxHeaderSize) ->
+ {?MODULE, decode_trailer, [Data, Header, Headers, Body,
+ BodyLength, RemainingSize, TotalMaxHeaderSize]};
+decode_trailer(<<?CR,?LF>> = Data, Header, Headers,
+ Body, BodyLength, RemainingSize, TotalMaxHeaderSize) ->
+ {?MODULE, decode_trailer, [Data, Header, Headers, Body,
+ BodyLength, RemainingSize, TotalMaxHeaderSize]};
+decode_trailer(<<?CR>> = Data, Header, Headers,
+ Body, BodyLength, RemainingSize, TotalMaxHeaderSize) ->
+ {?MODULE, decode_trailer, [Data, Header, Headers, Body,
+ BodyLength, RemainingSize, TotalMaxHeaderSize]};
+decode_trailer(<<?CR, ?LF, Rest/binary>>, Header, Headers, Body, BodyLength, RemainingSize, TotalMaxHeaderSize) ->
decode_trailer(Rest, [], [lists:reverse(Header) | Headers],
- MaxHeaderSize, Body, BodyLength);
+ Body, BodyLength, RemainingSize, TotalMaxHeaderSize);
+decode_trailer(<<Octet, Rest/binary>>, Header, Headers, Body,
+ BodyLength, RemainingSize, TotalMaxHeaderSize) ->
+ decode_trailer(Rest, [Octet | Header], Headers,
+ Body, BodyLength, remaing_size(RemainingSize, 1), TotalMaxHeaderSize).
+
+remaing_size(nolimit, _) ->
+ nolimit;
+remaing_size(Total, Consumed) ->
+ Total - Consumed.
-decode_trailer(<<Octet, Rest/binary>>, Header, Headers, MaxHeaderSize, Body,
- BodyLength) ->
- decode_trailer(Rest, [Octet | Header], Headers, MaxHeaderSize,
- Body, BodyLength).
+encode_trailers(Trailers) ->
+ encode_trailers(Trailers, "").
+
+encode_trailers([], Acc) ->
+ Acc ++ ?CRLF ++ ?CRLF;
+encode_trailers([{Header, Value} | Rest], Acc) ->
+ encode_trailers(Rest, Header ++ ":" ++ Value ++ ?CRLF ++ Acc).
diff --git a/lib/inets/src/http_lib/http_response.erl b/lib/inets/src/http_lib/http_response.erl
index 58b30c4e9e..42e5dd263d 100644
--- a/lib/inets/src/http_lib/http_response.erl
+++ b/lib/inets/src/http_lib/http_response.erl
@@ -31,16 +31,11 @@
%% Value - string()
%%
%% Description: Creates a http_response_h-record used internally to
-%% handle http-headers.
+%% handle http-headers, assumes reversed list of headers
+%% to unfold multiline headers with obs-folds
%%-------------------------------------------------------------------------
-headers([], Headers) ->
- Headers;
-
-headers([Header | Tail], Headers) ->
- {Key, [$: | Value]} =
- lists:splitwith(fun($:) -> false; (_) -> true end, Header),
- headers(Tail, headers(http_util:to_lower(string:strip(Key)),
- string:strip(Value), Headers)).
+headers(RevLines, Headers) ->
+ fill_headers(RevLines, [], Headers).
%%-------------------------------------------------------------------------
%% headers(#http_response_h{}) -> HeaderList
@@ -68,6 +63,25 @@ header_list(Headers) ->
%%%========================================================================
%%% Internal functions
%%%========================================================================
+fill_headers([], _, Headers) ->
+ Headers;
+fill_headers([[]], _, Headers) ->
+ Headers;
+fill_headers([[Ch|HeaderFold]|Tail], Folded, Headers)
+ when Ch == $\t; Ch == $\s ->
+ fill_headers(Tail, [HeaderFold|Folded], Headers);
+fill_headers([Header | Tail], Folded, Headers) ->
+ Unfolded = unfold([Header|Folded]),
+ {Key, [$: | Value]} =
+ lists:splitwith(fun($:) -> false; (_) -> true end, Unfolded),
+ fill_headers(Tail, [], headers(http_util:to_lower(string:strip(Key)),
+ string:strip(Value), Headers)).
+
+unfold([L]) ->
+ L;
+unfold(Folded) ->
+ string:join(Folded, " ").
+
headers("cache-control", Value, Headers) ->
Headers#http_response_h{'cache-control'= Value};
headers("connection", Value, Headers) ->
diff --git a/lib/inets/src/http_lib/http_transport.erl b/lib/inets/src/http_lib/http_transport.erl
index 719dc4c425..ab6afe9c6c 100644
--- a/lib/inets/src/http_lib/http_transport.erl
+++ b/lib/inets/src/http_lib/http_transport.erl
@@ -40,12 +40,6 @@
-include_lib("inets/src/inets_app/inets_internal.hrl").
-include("http_internal.hrl").
--define(SERVICE, httpl).
--define(hlri(Label, Content), ?report_important(Label, ?SERVICE, Content)).
--define(hlrv(Label, Content), ?report_verbose(Label, ?SERVICE, Content)).
--define(hlrd(Label, Content), ?report_debug(Label, ?SERVICE, Content)).
--define(hlrt(Label, Content), ?report_trace(Label, ?SERVICE, Content)).
-
%%%=========================================================================
%%% Internal application API
@@ -55,38 +49,27 @@
%% start(SocketType) -> ok | {error, Reason}
%% SocketType = ip_comm | {ssl, _}
%%
-%% Description: Makes sure inet_db or ssl is started.
+%% Description: Makes sure ssl is started.
%%-------------------------------------------------------------------------
start(ip_comm) ->
- do_start_ip_comm();
-
-%% This is just for backward compatibillity
+ ok;
+start({ip_comm, _}) ->
+ ok;
start({ssl, _}) ->
do_start_ssl();
start({essl, _}) ->
do_start_ssl().
-
-do_start_ip_comm() ->
- case inet_db:start() of
- {ok, _} ->
- ok;
- {error, {already_started, _}} ->
- ok;
- Error ->
- Error
- end.
-
do_start_ssl() ->
- case ssl:start() of
- ok ->
- ok;
- {error, {already_started,_}} ->
- ok;
- Error ->
- Error
+ try lists:foreach(fun(App) ->
+ ok = application:ensure_started(App)
+ end,
+ [crypto, asn1, public_key, ssl])
+ catch
+ _:Reason ->
+ {error, Reason}
end.
-
+
%%-------------------------------------------------------------------------
%% connect(SocketType, Address, Options, Timeout) ->
@@ -103,12 +86,8 @@ do_start_ssl() ->
connect(SocketType, Address, Opts) ->
connect(SocketType, Address, Opts, infinity).
-
-connect(ip_comm = _SocketType, {Host, Port}, Opts0, Timeout)
- when is_list(Opts0) ->
- Opts = [binary, {packet, 0}, {active, false}, {reuseaddr, true} | Opts0],
- ?hlrt("connect using gen_tcp",
- [{host, Host}, {port, Port}, {opts, Opts}, {timeout, Timeout}]),
+connect(ip_comm, {Host, Port}, Opts0, Timeout) ->
+ Opts = [binary, {packet, 0}, {active, false}, {reuseaddr, true} | Opts0 ],
try gen_tcp:connect(Host, Port, Opts, Timeout) of
{ok, _} = OK ->
OK;
@@ -127,11 +106,6 @@ connect({ssl, SslConfig}, Address, Opts, Timeout) ->
connect({essl, SslConfig}, {Host, Port}, Opts0, Timeout) ->
Opts = [binary, {active, false}, {ssl_imp, new} | Opts0] ++ SslConfig,
- ?hlrt("connect using essl",
- [{host, Host},
- {port, Port},
- {ssl_config, SslConfig},
- {timeout, Timeout}]),
case (catch ssl:connect(Host, Port, Opts, Timeout)) of
{'EXIT', Reason} ->
{error, {eoptions, Reason}};
@@ -156,29 +130,23 @@ connect({essl, SslConfig}, {Host, Port}, Opts0, Timeout) ->
%% reason for this to enable a HTTP-server not running as root to use
%% port 80.
%%-------------------------------------------------------------------------
-listen(ip_comm = _SocketType, Addr, Port, Fd, IpFamily) ->
- listen_ip_comm(Addr, Port, Fd, IpFamily);
-
+listen(ip_comm, Addr, Port, Fd, IpFamily) ->
+ listen_ip_comm(Addr, Port, [], Fd, IpFamily);
+
+listen({ip_comm, SockOpts}, Addr, Port, Fd, IpFamily) ->
+ listen_ip_comm(Addr, Port, SockOpts, Fd, IpFamily);
+
listen({essl, SSLConfig}, Addr, Port, Fd, IpFamily) ->
listen_ssl(Addr, Port, Fd, SSLConfig, IpFamily, []).
-listen(ip_comm = _SocketType, Addr, Port, IpFamily) ->
- listen_ip_comm(Addr, Port, undefined, IpFamily);
+listen(ip_comm, Addr, Port, IpFamily) ->
+ listen_ip_comm(Addr, Port, [], undefined, IpFamily);
%% Wrapper for backaward compatibillity
listen({ssl, SSLConfig}, Addr, Port, IpFamily) ->
- ?hlrt("listen (wrapper)",
- [{addr, Addr},
- {port, Port},
- {ssl_config, SSLConfig}]),
listen({?HTTP_DEFAULT_SSL_KIND, SSLConfig}, Addr, Port, IpFamily);
-
listen({essl, SSLConfig}, Addr, Port, IpFamily) ->
- ?hlrt("listen (essl)",
- [{addr, Addr},
- {port, Port},
- {ssl_config, SSLConfig}]),
{SSLConfig2, ExtraOpts} = case proplists:get_value(log_alert, SSLConfig, undefined) of
undefined ->
{SSLConfig, []};
@@ -187,83 +155,30 @@ listen({essl, SSLConfig}, Addr, Port, IpFamily) ->
end,
listen_ssl(Addr, Port, undefined, SSLConfig2, IpFamily, ExtraOpts).
-listen_ip_comm(Addr, Port, Fd, IpFamily) ->
- case (catch do_listen_ip_comm(Addr, Port, Fd, IpFamily)) of
+listen_ip_comm(Addr, Port, SockOpts, Fd, IpFamily) ->
+ case (catch do_listen_ip_comm(Addr, Port, SockOpts, Fd, IpFamily)) of
{'EXIT', Reason} ->
{error, {exit, Reason}};
Else ->
Else
end.
-do_listen_ip_comm(Addr, Port, Fd, IpFamily) ->
- {NewPort, Opts} = get_socket_info(Addr, Port, Fd),
- case IpFamily of
- inet6fb4 ->
- Opts2 = [inet6 | Opts],
- ?hlrt("try ipv6 listen", [{port, NewPort}, {opts, Opts2}]),
- case (catch gen_tcp:listen(NewPort, Opts2)) of
- {error, Reason} when ((Reason =:= nxdomain) orelse
- (Reason =:= eafnosupport)) ->
- Opts3 = [inet | Opts],
- ?hlrt("ipv6 listen failed - try ipv4 instead",
- [{reason, Reason}, {port, NewPort}, {opts, Opts3}]),
- gen_tcp:listen(NewPort, Opts3);
-
- %% This is when a given hostname has resolved to a
- %% IPv4-address. The inet6-option together with a
- %% {ip, IPv4} option results in badarg
- {'EXIT', Reason} ->
- Opts3 = [inet | Opts],
- ?hlrt("ipv6 listen exit - try ipv4 instead",
- [{reason, Reason}, {port, NewPort}, {opts, Opts3}]),
- gen_tcp:listen(NewPort, Opts3);
-
- Other ->
- ?hlrt("ipv6 listen done", [{other, Other}]),
- Other
- end;
- _ ->
- Opts2 = [IpFamily | Opts],
- ?hlrt("listen", [{port, NewPort}, {opts, Opts2}]),
- gen_tcp:listen(NewPort, Opts2)
- end.
+do_listen_ip_comm(Addr, Port, SockOpts, Fd, IpFamily) ->
+ Backlog = proplists:get_value(backlog, SockOpts, 128),
+ {NewPort, Opts} = get_socket_info(Addr, Port, Fd,
+ [{backlog, Backlog}, {reuseaddr, true} | SockOpts]),
+ Opts2 = [IpFamily | Opts],
+ gen_tcp:listen(NewPort, Opts2).
listen_ssl(Addr, Port, Fd, Opts0, IpFamily, ExtraOpts) ->
- {NewPort, SockOpt} = get_socket_info(Addr, Port, Fd),
+ Backlog = proplists:get_value(backlog, Opts0, 128),
+ {NewPort, SockOpt} = get_socket_info(Addr, Port, Fd,
+ [{backlog, Backlog}, {reuseaddr, true}]),
Opts = SockOpt ++ Opts0,
- case IpFamily of
- inet6fb4 ->
- Opts2 = [inet6 | Opts] ++ ExtraOpts,
- ?hlrt("try ipv6 listen", [{opts, Opts2}]),
- case (catch ssl:listen(Port, Opts2)) of
- {error, Reason} when ((Reason =:= nxdomain) orelse
- (Reason =:= eafnosupport)) ->
- Opts3 = [inet | Opts] ++ ExtraOpts,
- ?hlrt("ipv6 listen failed - try ipv4 instead",
- [{reason, Reason}, {opts, Opts3}]),
- ssl:listen(NewPort, Opts3);
-
- {'EXIT', Reason} ->
- Opts3 = [inet | Opts] ++ ExtraOpts,
- ?hlrt("ipv6 listen exit - try ipv4 instead",
- [{reason, Reason}, {opts, Opts3}]),
- ssl:listen(NewPort, Opts3);
-
- Other ->
- ?hlrt("ipv6 listen done", [{other, Other}]),
- Other
- end;
-
- _ ->
- Opts2 = [IpFamily | Opts],
- ?hlrt("listen", [{opts, Opts2}]),
- ssl:listen(NewPort, Opts2 ++ ExtraOpts)
- end.
+ Opts2 = [IpFamily | Opts],
+ ssl:listen(NewPort, Opts2 ++ ExtraOpts).
-
-
-get_socket_info(Addr, Port, Fd) ->
- BaseOpts = [{backlog, 128}, {reuseaddr, true}],
+get_socket_info(Addr, Port, Fd, BaseOpts) ->
%% The presence of a file descriptor takes precedence
case Fd of
undefined ->
@@ -288,6 +203,8 @@ accept(SocketType, ListenSocket) ->
accept(ip_comm, ListenSocket, Timeout) ->
gen_tcp:accept(ListenSocket, Timeout);
+accept({ip_comm, _}, ListenSocket, Timeout) ->
+ gen_tcp:accept(ListenSocket, Timeout);
%% Wrapper for backaward compatibillity
accept({ssl, SSLConfig}, ListenSocket, Timeout) ->
@@ -307,6 +224,8 @@ accept({essl, _SSLConfig}, ListenSocket, Timeout) ->
%%-------------------------------------------------------------------------
controlling_process(ip_comm, Socket, NewOwner) ->
gen_tcp:controlling_process(Socket, NewOwner);
+controlling_process({ip_comm, _}, Socket, NewOwner) ->
+ gen_tcp:controlling_process(Socket, NewOwner);
%% Wrapper for backaward compatibillity
controlling_process({ssl, SSLConfig}, Socket, NewOwner) ->
@@ -325,7 +244,8 @@ controlling_process({essl, _}, Socket, NewOwner) ->
%% gen_tcp or ssl.
%%-------------------------------------------------------------------------
setopts(ip_comm, Socket, Options) ->
- ?hlrt("ip_comm setopts", [{socket, Socket}, {options, Options}]),
+ inet:setopts(Socket, Options);
+setopts({ip_comm, _}, Socket, Options) ->
inet:setopts(Socket, Options);
%% Wrapper for backaward compatibillity
@@ -333,10 +253,7 @@ setopts({ssl, SSLConfig}, Socket, Options) ->
setopts({?HTTP_DEFAULT_SSL_KIND, SSLConfig}, Socket, Options);
setopts({essl, _}, Socket, Options) ->
- ?hlrt("[e]ssl setopts", [{socket, Socket}, {options, Options}]),
- Reason = (catch ssl:setopts(Socket, Options)),
- ?hlrt("[e]ssl setopts result", [{reason, Reason}]),
- Reason.
+ (catch ssl:setopts(Socket, Options)).
%%-------------------------------------------------------------------------
@@ -350,8 +267,10 @@ getopts(SocketType, Socket) ->
Opts = [packet, packet_size, recbuf, sndbuf, priority, tos, send_timeout],
getopts(SocketType, Socket, Opts).
+getopts({ip_comm, _}, Socket, Options) ->
+ getopts(ip_comm, Socket, Options);
+
getopts(ip_comm, Socket, Options) ->
- ?hlrt("ip_comm getopts", [{socket, Socket}, {options, Options}]),
case inet:getopts(Socket, Options) of
{ok, SocketOpts} ->
SocketOpts;
@@ -364,7 +283,6 @@ getopts({ssl, SSLConfig}, Socket, Options) ->
getopts({?HTTP_DEFAULT_SSL_KIND, SSLConfig}, Socket, Options);
getopts({essl, _}, Socket, Options) ->
- ?hlrt("essl getopts", [{socket, Socket}, {options, Options}]),
getopts_ssl(Socket, Options).
getopts_ssl(Socket, Options) ->
@@ -384,7 +302,6 @@ getopts_ssl(Socket, Options) ->
%% Description: Gets the socket stats values for the socket
%%-------------------------------------------------------------------------
getstat(ip_comm = _SocketType, Socket) ->
- ?hlrt("ip_comm getstat", [{socket, Socket}]),
case inet:getstat(Socket) of
{ok, Stats} ->
Stats;
@@ -409,6 +326,8 @@ getstat({essl, _} = _SocketType, _Socket) ->
%%-------------------------------------------------------------------------
send(ip_comm, Socket, Message) ->
gen_tcp:send(Socket, Message);
+send({ip_comm, _}, Socket, Message) ->
+ gen_tcp:send(Socket, Message);
%% Wrapper for backaward compatibillity
send({ssl, SSLConfig}, Socket, Message) ->
@@ -417,7 +336,6 @@ send({ssl, SSLConfig}, Socket, Message) ->
send({essl, _}, Socket, Message) ->
ssl:send(Socket, Message).
-
%%-------------------------------------------------------------------------
%% close(SocketType, Socket) -> ok | {error, Reason}
%% SocketType = ip_comm | {ssl, _}
@@ -427,6 +345,8 @@ send({essl, _}, Socket, Message) ->
%%-------------------------------------------------------------------------
close(ip_comm, Socket) ->
gen_tcp:close(Socket);
+close({ip_comm, []}, Socket) ->
+ gen_tcp:close(Socket);
%% Wrapper for backaward compatibillity
close({ssl, SSLConfig}, Socket) ->
@@ -448,6 +368,8 @@ close({essl, _}, Socket) ->
%%-------------------------------------------------------------------------
peername(ip_comm, Socket) ->
do_peername(inet:peername(Socket));
+peername({ip_comm, _}, Socket) ->
+ do_peername(inet:peername(Socket));
%% Wrapper for backaward compatibillity
peername({ssl, SSLConfig}, Socket) ->
@@ -480,7 +402,8 @@ do_peername({error, _}) ->
%%-------------------------------------------------------------------------
sockname(ip_comm, Socket) ->
do_sockname(inet:sockname(Socket));
-
+sockname({ip_comm, _}, Socket) ->
+ do_sockname(inet:sockname(Socket));
%% Wrapper for backaward compatibillity
sockname({ssl, SSLConfig}, Socket) ->
sockname({?HTTP_DEFAULT_SSL_KIND, SSLConfig}, Socket);
@@ -555,28 +478,13 @@ sock_opts(Opts) ->
%% -- negotiate --
negotiate(ip_comm,_,_) ->
- ?hlrt("negotiate(ip_comm)", []),
+ ok;
+negotiate({ip_comm, _},_,_) ->
ok;
negotiate({ssl, SSLConfig}, Socket, Timeout) ->
- ?hlrt("negotiate(ssl)", []),
negotiate({?HTTP_DEFAULT_SSL_KIND, SSLConfig}, Socket, Timeout);
negotiate({essl, _}, Socket, Timeout) ->
- ?hlrt("negotiate(essl)", []),
negotiate_ssl(Socket, Timeout).
negotiate_ssl(Socket, Timeout) ->
- ?hlrt("negotiate_ssl", [{socket, Socket}, {timeout, Timeout}]),
- case ssl:ssl_accept(Socket, Timeout) of
- ok ->
- ok;
- {error, Reason} ->
- ?hlrd("negotiate_ssl - accept failed", [{reason, Reason}]),
- %% Look for "valid" error reasons
- ValidReasons = [timeout, econnreset, esslaccept, esslerrssl],
- case lists:member(Reason, ValidReasons) of
- true ->
- {error, normal};
- false ->
- {error, Reason}
- end
- end.
+ ssl:ssl_accept(Socket, Timeout).
diff --git a/lib/inets/src/http_lib/http_uri.erl b/lib/inets/src/http_lib/http_uri.erl
index 79591eec29..6fe8c1776d 100644
--- a/lib/inets/src/http_lib/http_uri.erl
+++ b/lib/inets/src/http_lib/http_uri.erl
@@ -138,16 +138,33 @@ parse_scheme(AbsURI, Opts) ->
{error, no_scheme} ->
{error, no_scheme};
{SchemeStr, Rest} ->
- Scheme = list_to_atom(http_util:to_lower(SchemeStr)),
- SchemeDefaults = which_scheme_defaults(Opts),
- case lists:keysearch(Scheme, 1, SchemeDefaults) of
- {value, {Scheme, DefaultPort}} ->
- {Scheme, DefaultPort, Rest};
- false ->
- {Scheme, no_default_port, Rest}
+ case extract_scheme(SchemeStr, Opts) of
+ {error, Error} ->
+ {error, Error};
+ {ok, Scheme} ->
+ SchemeDefaults = which_scheme_defaults(Opts),
+ case lists:keysearch(Scheme, 1, SchemeDefaults) of
+ {value, {Scheme, DefaultPort}} ->
+ {Scheme, DefaultPort, Rest};
+ false ->
+ {Scheme, no_default_port, Rest}
+ end
end
end.
+extract_scheme(Str, Opts) ->
+ case lists:keysearch(scheme_validation_fun, 1, Opts) of
+ {value, {scheme_validation_fun, Fun}} when is_function(Fun) ->
+ case Fun(Str) of
+ valid ->
+ {ok, list_to_atom(http_util:to_lower(Str))};
+ {error, Error} ->
+ {error, Error}
+ end;
+ _ ->
+ {ok, list_to_atom(http_util:to_lower(Str))}
+ end.
+
parse_uri_rest(Scheme, DefaultPort, "//" ++ URIPart, Opts) ->
{Authority, PathQueryFragment} =
split_uri(URIPart, "[/?#]", {URIPart, ""}, 1, 0),
diff --git a/lib/inets/src/http_lib/http_util.erl b/lib/inets/src/http_lib/http_util.erl
index 0d07231302..aafa97afee 100644
--- a/lib/inets/src/http_lib/http_util.erl
+++ b/lib/inets/src/http_lib/http_util.erl
@@ -152,27 +152,11 @@ convert_netscapecookie_date([_D,_A,_Y, _SP,
Sec=list_to_integer([S1,S2]),
{{Year,Month,Day},{Hour,Min,Sec}}.
-hexlist_to_integer([]) ->
- empty;
-%%When the string only contains one value its eaasy done.
-%% 0-9
-hexlist_to_integer([Size]) when (Size >= 48) andalso (Size =< 57) ->
- Size - 48;
-%% A-F
-hexlist_to_integer([Size]) when (Size >= 65) andalso (Size =< 70) ->
- Size - 55;
-%% a-f
-hexlist_to_integer([Size]) when (Size >= 97) andalso (Size =< 102) ->
- Size - 87;
-hexlist_to_integer([_Size]) ->
- not_a_num;
+hexlist_to_integer(List) ->
+ list_to_integer(List, 16).
-hexlist_to_integer(Size) ->
- Len = string:span(Size, "1234567890abcdefABCDEF"),
- hexlist_to_integer2(Size, 16 bsl (4 *(Len-2)),0).
-
-integer_to_hexlist(Num)->
- integer_to_hexlist(Num, get_size(Num), []).
+integer_to_hexlist(Int) ->
+ integer_to_list(Int, 16).
convert_month("Jan") -> 1;
convert_month("Feb") -> 2;
@@ -213,51 +197,6 @@ html_encode(Chars) ->
%%%========================================================================
%%% Internal functions
%%%========================================================================
-hexlist_to_integer2([],_Pos,Sum)->
- Sum;
-hexlist_to_integer2([HexVal | HexString], Pos, Sum)
- when HexVal >= 48, HexVal =< 57 ->
- hexlist_to_integer2(HexString, Pos bsr 4, Sum + ((HexVal-48) * Pos));
-
-hexlist_to_integer2([HexVal | HexString], Pos, Sum)
- when HexVal >= 65, HexVal =<70 ->
- hexlist_to_integer2(HexString, Pos bsr 4, Sum + ((HexVal-55) * Pos));
-
-hexlist_to_integer2([HexVal | HexString], Pos, Sum)
- when HexVal>=97, HexVal=<102 ->
- hexlist_to_integer2(HexString, Pos bsr 4, Sum + ((HexVal-87) * Pos));
-
-hexlist_to_integer2(_AfterHexString, _Pos, Sum)->
- Sum.
-
-integer_to_hexlist(Num, Pot, Res) when Pot < 0 ->
- convert_to_ascii([Num | Res]);
-
-integer_to_hexlist(Num,Pot,Res) ->
- Position = (16 bsl (Pot*4)),
- PosVal = Num div Position,
- integer_to_hexlist(Num - (PosVal*Position), Pot-1, [PosVal | Res]).
-
-get_size(Num)->
- get_size(Num, 0).
-
-get_size(Num, Pot) when Num < (16 bsl(Pot *4)) ->
- Pot-1;
-
-get_size(Num, Pot) ->
- get_size(Num, Pot+1).
-
-convert_to_ascii(RevesedNum) ->
- convert_to_ascii(RevesedNum, []).
-
-convert_to_ascii([], Num)->
- Num;
-convert_to_ascii([Num | Reversed], Number)
- when (Num > -1) andalso (Num < 10) ->
- convert_to_ascii(Reversed, [Num + 48 | Number]);
-convert_to_ascii([Num | Reversed], Number)
- when (Num > 9) andalso (Num < 16) ->
- convert_to_ascii(Reversed, [Num + 55 | Number]).
char_to_html_entity(Char, Reserved) ->
case sets:is_element(Char, Reserved) of
diff --git a/lib/inets/src/http_server/Makefile b/lib/inets/src/http_server/Makefile
index b09877550d..b9f2290289 100644
--- a/lib/inets/src/http_server/Makefile
+++ b/lib/inets/src/http_server/Makefile
@@ -40,6 +40,10 @@ RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
# ----------------------------------------------------
# Target Specs
# ----------------------------------------------------
+
+BEHAVIOUR_MODULES= \
+ httpd_custom_api
+
MODULES = \
httpd \
httpd_acceptor \
@@ -86,10 +90,13 @@ MODULES = \
HRL_FILES = httpd.hrl httpd_internal.hrl mod_auth.hrl
-ERL_FILES = $(MODULES:%=%.erl)
+ERL_FILES = $(MODULES:%=%.erl)\
+ $(BEHAVIOUR_MODULES:%=%.erl)
TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+BEHAVIOUR_TARGET_FILES= $(BEHAVIOUR_MODULES:%=$(EBIN)/%.$(EMULATOR))
+
INETS_FLAGS = -D'SERVER_SOFTWARE="$(APPLICATION)/$(VSN)"'
@@ -109,11 +116,12 @@ ERL_COMPILE_FLAGS += \
# ----------------------------------------------------
# Targets
# ----------------------------------------------------
+$(TARGET_FILES): $(BEHAVIOUR_TARGET_FILES)
debug opt: $(TARGET_FILES)
clean:
- rm -f $(TARGET_FILES)
+ rm -f $(TARGET_FILES) $(BEHAVIOUR_TARGET_FILES)
rm -f core
docs:
diff --git a/lib/inets/src/http_server/httpd_conf.erl b/lib/inets/src/http_server/httpd_conf.erl
index 7d31989244..62e8a95b19 100644
--- a/lib/inets/src/http_server/httpd_conf.erl
+++ b/lib/inets/src/http_server/httpd_conf.erl
@@ -156,7 +156,7 @@ load("BindAddress " ++ Address0, []) ->
case string:tokens(Address0, [$|]) of
[Address1] ->
?hdrv("load BindAddress", [{address1, Address1}]),
- {clean_address(Address1), inet6fb4};
+ {clean_address(Address1), inet};
[Address1, IpFamilyStr] ->
?hdrv("load BindAddress",
[{address1, Address1},
@@ -353,14 +353,21 @@ clean_address(Addr) ->
make_ipfamily(IpFamilyStr) ->
- IpFamily = list_to_atom(IpFamilyStr),
- case lists:member(IpFamily, [inet, inet6, inet6fb4]) of
- true ->
- IpFamily;
- false ->
- throw({error, {bad_ipfamily, IpFamilyStr}})
- end.
-
+ validate_ipfamily(list_to_atom(IpFamilyStr)).
+
+validate_ipfamily(inet) ->
+ inet;
+validate_ipfamily(inet6) ->
+ inet6;
+%% Backwards compatibility wrapper,
+%% fallback to the default, IPV4,
+%% as it will most proably work.
+%% IPv6 standard moved away from
+%% beeing able to fallback to ipv4
+validate_ipfamily(inet6fb4) ->
+ inet;
+validate_ipfamily(IpFamilyStr) ->
+ throw({error, {bad_ipfamily, IpFamilyStr}}).
%%
%% load_mime_types/1 -> {ok, MimeTypes} | {error, Reason}
@@ -393,20 +400,16 @@ validate_properties2(Properties) ->
undefined ->
case proplists:get_value(sock_type, Properties, ip_comm) of
ip_comm ->
- case proplists:get_value(ipfamily, Properties) of
- undefined ->
- [{bind_address, any},
- {ipfamily, inet6fb4} | Properties];
- _ ->
- [{bind_address, any} | Properties]
- end;
+ add_inet_defaults(Properties);
+ {ip_comm, _} ->
+ add_inet_defaults(Properties);
_ ->
[{bind_address, any} | Properties]
end;
any ->
Properties;
Address0 ->
- IpFamily = proplists:get_value(ipfamily, Properties, inet6fb4),
+ IpFamily = proplists:get_value(ipfamily, Properties, inet),
case httpd_util:ip_address(Address0, IpFamily) of
{ok, Address} ->
Properties1 = proplists:delete(bind_address, Properties),
@@ -418,6 +421,16 @@ validate_properties2(Properties) ->
throw(Error)
end
end.
+
+add_inet_defaults(Properties) ->
+ case proplists:get_value(ipfamily, Properties) of
+ undefined ->
+ [{bind_address, any},
+ {ipfamily, inet} | Properties];
+ _ ->
+ [{bind_address, any} | Properties]
+ end.
+
check_minimum_bytes_per_second(Properties) ->
case proplists:get_value(minimum_bytes_per_second, Properties, false) of
false ->
@@ -487,12 +500,11 @@ validate_config_params([{server_tokens, Value} | _]) ->
validate_config_params([{socket_type, ip_comm} | Rest]) ->
validate_config_params(Rest);
-validate_config_params([{socket_type, Value} | Rest])
- when Value == ssl; Value == essl ->
- validate_config_params(Rest);
-
-validate_config_params([{socket_type, {Value, _}} | Rest])
- when Value == essl orelse Value == ssl ->
+validate_config_params([{socket_type, {Value, Opts}} | Rest]) when Value == ip_comm;
+ Value == ssl;
+ Value == essl ->
+ %% Make sure not to set socket values used internaly
+ validate_config_params(Opts),
validate_config_params(Rest);
validate_config_params([{socket_type, Value} | _]) ->
@@ -622,21 +634,32 @@ validate_config_params([{disable_chunked_transfer_encoding_send, Value} |
validate_config_params([{disable_chunked_transfer_encoding_send, Value} |
_ ]) ->
throw({disable_chunked_transfer_encoding_send, Value});
+validate_config_params([{Name, _} = Opt | _]) when Name == packet;
+ Name == mode;
+ Name == active;
+ Name == reuseaddr ->
+ throw({internaly_handled_opt_can_not_be_set, Opt});
validate_config_params([_| Rest]) ->
validate_config_params(Rest).
-%% It is actually pointless to check bind_address in this way since
-%% we need ipfamily to do it properly...
is_bind_address(any) ->
true;
is_bind_address(Value) ->
- case httpd_util:ip_address(Value, inet6fb4) of
+ case is_bind_address(Value, inet) of
+ false ->
+ is_bind_address(Value, inet6);
+ True ->
+ True
+ end.
+
+is_bind_address(Value, IpFamily) ->
+ case httpd_util:ip_address(Value, IpFamily) of
{ok, _} ->
true;
_ ->
false
end.
-
+
store(ConfigList0) ->
?hdrd("store", []),
try validate_config_params(ConfigList0) of
@@ -776,28 +799,6 @@ remove(ConfigDB) ->
ets:delete(ConfigDB),
ok.
-%% config(ConfigDB) ->
-%% case httpd_util:lookup(ConfigDB, socket_type, ip_comm) of
-%% ssl ->
-%% case ssl_certificate_file(ConfigDB) of
-%% undefined ->
-%% {error,
-%% "Directive SSLCertificateFile "
-%% "not found in the config file"};
-%% SSLCertificateFile ->
-%% {ssl,
-%% SSLCertificateFile++
-%% ssl_certificate_key_file(ConfigDB)++
-%% ssl_verify_client(ConfigDB)++
-%% ssl_ciphers(ConfigDB)++
-%% ssl_password(ConfigDB)++
-%% ssl_verify_depth(ConfigDB)++
-%% ssl_ca_certificate_file(ConfigDB)}
-%% end;
-%% ip_comm ->
-%% ip_comm
-%% end.
-
get_config(Address, Port, Profile) ->
Tab = httpd_util:make_name("httpd_conf", Address, Port, Profile),
@@ -836,6 +837,8 @@ lookup_socket_type(ConfigDB) ->
case httpd_util:lookup(ConfigDB, socket_type, ip_comm) of
ip_comm ->
ip_comm;
+ {ip_comm, _} = Type ->
+ Type;
{Tag, Conf} ->
{Tag, Conf};
SSL when (SSL =:= ssl) orelse (SSL =:= essl) ->
diff --git a/lib/inets/src/http_server/httpd_custom.erl b/lib/inets/src/http_server/httpd_custom.erl
index a1fe058bd1..2b9701ef75 100644
--- a/lib/inets/src/http_server/httpd_custom.erl
+++ b/lib/inets/src/http_server/httpd_custom.erl
@@ -20,16 +20,27 @@
%%
-module(httpd_custom).
--export([response_header/1, request_header/1]).
--export([customize_headers/3]).
+-export([response_header/1, request_header/1, response_default_headers/0]).
+-export([customize_headers/3, response_default_headers/1]).
--include_lib("inets/src/inets_app/inets_internal.hrl").
+-include("../inets_app/inets_internal.hrl").
+
+-behaviour(httpd_custom_api).
+
+%%--------------------------------------------------------------------
+%% Behavior API -----------------------------------
+%%--------------------------------------------------------------------
response_header(Header) ->
{true, httpify(Header)}.
request_header(Header) ->
{true, Header}.
+response_default_headers() ->
+ [].
+%%--------------------------------------------------------------------
+%% Internal API -----------------------------------
+%%--------------------------------------------------------------------
customize_headers(?MODULE, Function, Arg) ->
?MODULE:Function(Arg);
customize_headers(Module, Function, Arg) ->
@@ -43,6 +54,20 @@ customize_headers(Module, Function, Arg) ->
?MODULE:Function(Arg)
end.
+response_default_headers(?MODULE) ->
+ response_default_headers();
+response_default_headers(Module) ->
+ try Module:response_default_headers() of
+ Defaults ->
+ [{http_util:to_lower(Key), Value} || {Key, Value} <- Defaults,
+ is_list(Key), is_list(Value)]
+ catch
+ _:_ ->
+ ?MODULE:response_default_headers()
+ end.
+%%--------------------------------------------------------------------
+%% Internal functions -----------------------------------
+%%--------------------------------------------------------------------
httpify({Key0, Value}) ->
%% make sure first letter is capital (defacto standard)
Words1 = string:tokens(Key0, "-"),
diff --git a/lib/inets/src/http_server/httpd_custom_api.erl b/lib/inets/src/http_server/httpd_custom_api.erl
new file mode 100644
index 0000000000..282f3a6ee6
--- /dev/null
+++ b/lib/inets/src/http_server/httpd_custom_api.erl
@@ -0,0 +1,31 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2015-2015. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+-module(httpd_custom_api).
+
+-callback response_default_headers() ->
+ [{Key::string(), Value::string()}].
+-callback response_header({Key::string(), Value::string()}) ->
+ {true, {Key::string(), Value::string()}} | false.
+-callback request_header({Key::string(), Value::string()}) ->
+ {true, {Key::string(), Value::string()}} | false.
+
+-optional_callbacks([response_default_headers/0, response_header/1,
+ request_header/1]).
diff --git a/lib/inets/src/http_server/httpd_example.erl b/lib/inets/src/http_server/httpd_example.erl
index d729affd6d..0222487a4b 100644
--- a/lib/inets/src/http_server/httpd_example.erl
+++ b/lib/inets/src/http_server/httpd_example.erl
@@ -24,7 +24,7 @@
-export([newformat/3]).
%% These are used by the inets test-suite
--export([delay/1]).
+-export([delay/1, chunk_timeout/3]).
print(String) ->
@@ -142,3 +142,11 @@ i(F) -> i(F,[]).
i(F,A) -> io:format(F ++ "~n",A).
sleep(T) -> receive after T -> ok end.
+
+%% ------------------------------------------------------
+
+chunk_timeout(SessionID, _, StrInt) ->
+ mod_esi:deliver(SessionID, "Tranfer-Encoding:chunked/html\r\n\r\n"),
+ mod_esi:deliver(SessionID, top("Test chunk encoding timeout")),
+ timer:sleep(20000),
+ mod_esi:deliver(SessionID, footer()).
diff --git a/lib/inets/src/http_server/httpd_request_handler.erl b/lib/inets/src/http_server/httpd_request_handler.erl
index e5d006c1fd..134576059d 100644
--- a/lib/inets/src/http_server/httpd_request_handler.erl
+++ b/lib/inets/src/http_server/httpd_request_handler.erl
@@ -443,7 +443,7 @@ handle_body(#state{headers = Headers, body = Body, mod = ModData} = State,
MaxHeaderSize, MaxBodySize) ->
case Headers#http_request_h.'transfer-encoding' of
"chunked" ->
- case http_chunk:decode(Body, MaxBodySize, MaxHeaderSize) of
+ try http_chunk:decode(Body, MaxBodySize, MaxHeaderSize) of
{Module, Function, Args} ->
http_transport:setopts(ModData#mod.socket_type,
ModData#mod.socket,
@@ -455,6 +455,14 @@ handle_body(#state{headers = Headers, body = Body, mod = ModData} = State,
http_chunk:handle_headers(Headers, ChunkedHeaders),
handle_response(State#state{headers = NewHeaders,
body = NewBody})
+ catch
+ throw:Error ->
+ httpd_response:send_status(ModData, 400,
+ "Bad input"),
+ Reason = io_lib:format("Chunk decoding failed: ~p~n",
+ [Error]),
+ error_log(Reason, ModData),
+ {stop, normal, State#state{response_sent = true}}
end;
Encoding when is_list(Encoding) ->
httpd_response:send_status(ModData, 501,
@@ -622,21 +630,10 @@ decrease(N) when is_integer(N) ->
decrease(N) ->
N.
-error_log(ReasonString, Info) ->
+error_log(ReasonString, #mod{config_db = ConfigDB}) ->
Error = lists:flatten(
io_lib:format("Error reading request: ~s", [ReasonString])),
- error_log(mod_log, Info, Error),
- error_log(mod_disk_log, Info, Error).
-
-error_log(Mod, #mod{config_db = ConfigDB} = Info, String) ->
- Modules = httpd_util:lookup(ConfigDB, modules,
- [mod_get, mod_head, mod_log]),
- case lists:member(Mod, Modules) of
- true ->
- Mod:error_log(Info, String);
- _ ->
- ok
- end.
+ httpd_util:error_log(ConfigDB, Error).
%%--------------------------------------------------------------------
diff --git a/lib/inets/src/http_server/httpd_response.erl b/lib/inets/src/http_server/httpd_response.erl
index 7e73da7060..c0b5f09faf 100644
--- a/lib/inets/src/http_server/httpd_response.erl
+++ b/lib/inets/src/http_server/httpd_response.erl
@@ -20,8 +20,8 @@
%%
-module(httpd_response).
-export([generate_and_send_response/1, send_status/3, send_header/3,
- send_body/3, send_chunk/3, send_final_chunk/2, split_header/2,
- is_disable_chunked_send/1, cache_headers/2]).
+ send_body/3, send_chunk/3, send_final_chunk/2, send_final_chunk/3,
+ split_header/2, is_disable_chunked_send/1, cache_headers/2]).
-export([map_status_code/2]).
-include_lib("inets/src/inets_app/inets_internal.hrl").
@@ -89,8 +89,7 @@ traverse_modules(ModData,[Module|Rest]) ->
"~n Error: ~p"
"~n Stack trace: ~p",
[Module, T, E, ?STACK()])),
- report_error(mod_log, ModData#mod.config_db, String),
- report_error(mod_disk_log, ModData#mod.config_db, String),
+ httpd_util:error_log(ModData#mod.config_db, String),
send_status(ModData, 500, none),
done
end.
@@ -245,7 +244,6 @@ send_chunk(_, <<>>, _) ->
ok;
send_chunk(_, [], _) ->
ok;
-
send_chunk(#mod{http_version = "HTTP/1.1",
socket_type = Type, socket = Sock}, Response0, false) ->
Response = http_chunk:encode(Response0),
@@ -254,10 +252,13 @@ send_chunk(#mod{http_version = "HTTP/1.1",
send_chunk(#mod{socket_type = Type, socket = Sock} = _ModData, Response, _) ->
httpd_socket:deliver(Type, Sock, Response).
+send_final_chunk(Mod, IsDisableChunkedSend) ->
+ send_final_chunk(Mod, [], IsDisableChunkedSend).
+
send_final_chunk(#mod{http_version = "HTTP/1.1",
- socket_type = Type, socket = Sock}, false) ->
- httpd_socket:deliver(Type, Sock, http_chunk:encode_last());
-send_final_chunk(#mod{socket_type = Type, socket = Sock}, _) ->
+ socket_type = Type, socket = Sock}, Trailers, false) ->
+ httpd_socket:deliver(Type, Sock, http_chunk:encode_last(Trailers));
+send_final_chunk(#mod{socket_type = Type, socket = Sock}, _, _) ->
httpd_socket:close(Type, Sock).
is_disable_chunked_send(Db) ->
@@ -287,14 +288,21 @@ create_header(ConfigDb, KeyValueTupleHeaders) ->
Date = httpd_util:rfc1123_date(),
ContentType = "text/html",
Server = server(ConfigDb),
- Headers0 = add_default_headers([{"date", Date},
- {"content-type", ContentType}
- | if Server=="" -> [];
- true -> [{"server", Server}]
- end
- ],
- KeyValueTupleHeaders),
CustomizeCB = httpd_util:lookup(ConfigDb, customize, httpd_custom),
+
+ CustomDefaults = httpd_custom:response_default_headers(CustomizeCB),
+ SystemDefaultes = ([{"date", Date},
+ {"content-type", ContentType}
+ | if Server=="" -> [];
+ true -> [{"server", Server}]
+ end
+ ]),
+
+ %% System defaults not present in custom defaults will be added
+ %% to defaults
+ Defaults = add_default_headers(SystemDefaultes, CustomDefaults),
+
+ Headers0 = add_default_headers(Defaults, KeyValueTupleHeaders),
lists:filtermap(fun(H) ->
httpd_custom:customize_headers(CustomizeCB, response_header, H)
end,
@@ -390,16 +398,6 @@ send_response_old(#mod{socket_type = Type,
content_length(Body)->
integer_to_list(httpd_util:flatlength(Body)).
-report_error(Mod, ConfigDB, Error) ->
- Modules = httpd_util:lookup(ConfigDB, modules,
- [mod_get, mod_head, mod_log]),
- case lists:member(Mod, Modules) of
- true ->
- Mod:report_error(ConfigDB, Error);
- _ ->
- ok
- end.
-
handle_headers([], NewHeaders) ->
{ok, NewHeaders};
diff --git a/lib/inets/src/http_server/httpd_sup.erl b/lib/inets/src/http_server/httpd_sup.erl
index f0b1942e2f..bf40cedd5c 100644
--- a/lib/inets/src/http_server/httpd_sup.erl
+++ b/lib/inets/src/http_server/httpd_sup.erl
@@ -241,7 +241,7 @@ listen(Address, Port, Config) ->
case http_transport:start(SocketType) of
ok ->
{ok, Fd} = get_fd(Port),
- IpFamily = proplists:get_value(ipfamily, Config, inet6fb4),
+ IpFamily = proplists:get_value(ipfamily, Config, inet),
case http_transport:listen(SocketType, Address, Port, Fd, IpFamily) of
{ok, ListenSocket} ->
NewConfig = proplists:delete(port, Config),
@@ -286,6 +286,8 @@ socket_type(Config) ->
socket_type(ip_comm = SocketType, _) ->
SocketType;
+socket_type({ip_comm, _} = SocketType, _) ->
+ SocketType;
socket_type({essl, _} = SocketType, _) ->
SocketType;
socket_type(_, Config) ->
diff --git a/lib/inets/src/http_server/httpd_util.erl b/lib/inets/src/http_server/httpd_util.erl
index fc69baf829..ab43f0b378 100644
--- a/lib/inets/src/http_server/httpd_util.erl
+++ b/lib/inets/src/http_server/httpd_util.erl
@@ -31,7 +31,7 @@
convert_netscapecookie_date/1, enable_debug/1, valid_options/3,
modules_validate/1, module_validate/1,
dir_validate/2, file_validate/2, mime_type_validate/1,
- mime_types_validate/1, custom_date/0]).
+ mime_types_validate/1, custom_date/0, error_log/2]).
-export([encode_hex/1, decode_hex/1]).
-include_lib("kernel/include/file.hrl").
@@ -42,17 +42,7 @@ ip_address({_,_,_,_,_,_,_,_} = Address, _IpFamily) ->
{ok, Address};
ip_address(Host, IpFamily)
when ((IpFamily =:= inet) orelse (IpFamily =:= inet6)) ->
- inet:getaddr(Host, IpFamily);
-ip_address(Host, inet6fb4 = _IpFamily) ->
- Inet = case gen_tcp:listen(0, [inet6]) of
- {ok, Dummyport} ->
- gen_tcp:close(Dummyport),
- inet6;
- _ ->
- inet
- end,
- inet:getaddr(Host, Inet).
-
+ inet:getaddr(Host, IpFamily).
%% lookup
@@ -786,3 +776,17 @@ do_enable_debug([{Level,Modules}|Rest])
ok
end,
do_enable_debug(Rest).
+
+error_log(ConfigDb, Error) ->
+ error_log(mod_log, ConfigDb, Error),
+ error_log(mod_disk_log, ConfigDb, Error).
+
+error_log(Mod, ConfigDB, Error) ->
+ Modules = httpd_util:lookup(ConfigDB, modules,
+ [mod_get, mod_head, mod_log]),
+ case lists:member(Mod, Modules) of
+ true ->
+ Mod:report_error(ConfigDB, Error);
+ _ ->
+ ok
+ end.
diff --git a/lib/inets/src/http_server/mod_auth_server.erl b/lib/inets/src/http_server/mod_auth_server.erl
index 3685c2e617..7d1e1a3431 100644
--- a/lib/inets/src/http_server/mod_auth_server.erl
+++ b/lib/inets/src/http_server/mod_auth_server.erl
@@ -316,7 +316,7 @@ lookup(Db, Key) ->
make_name(Addr, Port, Profile) ->
- httpd_util:make_name(?MODULE, Addr, Port, Profile).
+ httpd_util:make_name(?MODULE_STRING, Addr, Port, Profile).
call(Name, Req) ->
diff --git a/lib/inets/src/http_server/mod_esi.erl b/lib/inets/src/http_server/mod_esi.erl
index b9a0797977..1923411449 100644
--- a/lib/inets/src/http_server/mod_esi.erl
+++ b/lib/inets/src/http_server/mod_esi.erl
@@ -376,7 +376,6 @@ erl_scheme_webpage_chunk(Mod, Func, Env, Input, ModData) ->
end),
Response = deliver_webpage_chunk(ModData, Pid),
-
process_flag(trap_exit,false),
Response.
@@ -418,7 +417,6 @@ deliver_webpage_chunk(#mod{config_db = Db} = ModData, Pid, Timeout) ->
?hdrv("deliver_webpage_chunk - timeout", []),
send_headers(ModData, 504, [{"connection", "close"}]),
httpd_socket:close(ModData#mod.socket_type, ModData#mod.socket),
- process_flag(trap_exit,false),
{proceed,[{response, {already_sent, 200, 0}} | ModData#mod.data]}
end.
@@ -446,7 +444,6 @@ send_headers(ModData, StatusCode, HTTPHeaders) ->
ExtraHeaders ++ HTTPHeaders).
handle_body(_, #mod{method = "HEAD"} = ModData, _, _, Size, _) ->
- process_flag(trap_exit,false),
{proceed, [{response, {already_sent, 200, Size}} | ModData#mod.data]};
handle_body(Pid, ModData, Body, Timeout, Size, IsDisableChunkedSend) ->
@@ -454,34 +451,54 @@ handle_body(Pid, ModData, Body, Timeout, Size, IsDisableChunkedSend) ->
httpd_response:send_chunk(ModData, Body, IsDisableChunkedSend),
receive
{esi_data, Data} when is_binary(Data) ->
- ?hdrt("handle_body - received binary data (esi)", []),
handle_body(Pid, ModData, Data, Timeout, Size + byte_size(Data),
IsDisableChunkedSend);
{esi_data, Data} ->
- ?hdrt("handle_body - received data (esi)", []),
handle_body(Pid, ModData, Data, Timeout, Size + length(Data),
IsDisableChunkedSend);
{ok, Data} ->
- ?hdrt("handle_body - received data (ok)", []),
handle_body(Pid, ModData, Data, Timeout, Size + length(Data),
IsDisableChunkedSend);
{'EXIT', Pid, normal} when is_pid(Pid) ->
- ?hdrt("handle_body - exit:normal", []),
httpd_response:send_final_chunk(ModData, IsDisableChunkedSend),
{proceed, [{response, {already_sent, 200, Size}} |
ModData#mod.data]};
{'EXIT', Pid, Reason} when is_pid(Pid) ->
- ?hdrv("handle_body - exit", [{reason, Reason}]),
- httpd_response:send_final_chunk(ModData, IsDisableChunkedSend),
- exit({mod_esi_linked_process_died, Pid, Reason})
-
+ Error = lists:flatten(io_lib:format("mod_esi process failed with reason ~p", [Reason])),
+ httpd_util:error_log(ModData#mod.config_db, Error),
+ httpd_response:send_final_chunk(ModData,
+ [{"Warning", "199 inets server - body maybe incomplete, "
+ "internal server error"}],
+ IsDisableChunkedSend),
+ done
after Timeout ->
- ?hdrv("handle_body - timeout", []),
- process_flag(trap_exit,false),
- httpd_response:send_final_chunk(ModData, IsDisableChunkedSend),
- exit({mod_esi_linked_process_timeout, Pid})
+ kill_esi_delivery_process(Pid),
+ httpd_response:send_final_chunk(ModData, [{"Warning", "199 inets server - "
+ "body maybe incomplete, timed out"}],
+ IsDisableChunkedSend),
+ done
end.
+kill_esi_delivery_process(Pid) ->
+ exit(Pid, kill),
+ receive
+ {'EXIT', Pid, killed} ->
+ %% Clean message queue
+ receive
+ {esi_data, _} ->
+ ok
+ after 0 ->
+ ok
+ end,
+ receive
+ {ok, _} ->
+ ok
+ after 0 ->
+ ok
+ end
+ end.
+
+
erl_script_timeout(Db) ->
httpd_util:lookup(Db, erl_script_timeout, ?DEFAULT_ERL_TIMEOUT).
diff --git a/lib/inets/src/http_server/mod_security_server.erl b/lib/inets/src/http_server/mod_security_server.erl
index 81561493a0..f9281b0fdc 100644
--- a/lib/inets/src/http_server/mod_security_server.erl
+++ b/lib/inets/src/http_server/mod_security_server.erl
@@ -523,10 +523,10 @@ unblock_user(Info, User, Dir, Addr, Port, Profile, ETS, DETS, CBModule) ->
ets:match_delete(ETS, {blocked_user, {User, Addr, Port, Profile, Dir, '_'}}).
make_name(Addr,Port, Profile) ->
- httpd_util:make_name(?MODULE,Addr,Port, Profile).
+ httpd_util:make_name(?MODULE_STRING, Addr, Port, Profile).
make_name(Addr,Port, Profile, Num) ->
- httpd_util:make_name(?MODULE,Addr,Port,
+ httpd_util:make_name(?MODULE_STRING, Addr,Port,
atom_to_list(Profile) ++ "__" ++ integer_to_list(Num)).
auth_fail_event(Mod,Addr,Port,Dir,User,Passwd) ->
diff --git a/lib/inets/test/http_format_SUITE.erl b/lib/inets/test/http_format_SUITE.erl
index a97b51601f..e977bd1b9b 100644
--- a/lib/inets/test/http_format_SUITE.erl
+++ b/lib/inets/test/http_format_SUITE.erl
@@ -20,26 +20,12 @@
%%
-module(http_format_SUITE).
--author('[email protected]').
-include_lib("common_test/include/ct.hrl").
--include("test_server_line.hrl").
-include("http_internal.hrl").
-%% Test server specific exports
--export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, init_per_group/2,end_per_group/2, init_per_testcase/2, end_per_testcase/2]).
-
-%% Test cases must be exported.
--export([ chunk_decode/1, chunk_encode/1,
- chunk_extensions_otp_6005/1, chunk_decode_otp_6264/1,
- chunk_decode_empty_chunk_otp_6511/1,
- chunk_decode_trailer/1,
- http_response/1, http_request/1, validate_request_line/1,
- esi_parse_headers/1, cgi_parse_headers/1,
- is_absolut_uri/1, convert_netscapecookie_date/1,
- check_content_length_encoding/1]).
-
-suite() -> [{ct_hooks,[ts_install_cth]}].
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
all() ->
[{group, chunk}, http_response, http_request,
@@ -52,7 +38,8 @@ groups() ->
[chunk_decode, chunk_encode, chunk_extensions_otp_6005,
chunk_decode_otp_6264,
chunk_decode_empty_chunk_otp_6511,
- chunk_decode_trailer]}].
+ chunk_whitespace_suffix,
+ chunk_decode_trailer, chunk_max_headersize, chunk_max_bodysize, chunk_not_hex]}].
init_per_suite(Config) ->
Config.
@@ -81,12 +68,8 @@ end_per_testcase(_, Config) ->
%% Test cases starts here.
%%-------------------------------------------------------------------------
-
-%%-------------------------------------------------------------------------
-chunk_decode(doc) ->
- ["Test http_chunk:decode/3"];
-chunk_decode(suite) ->
- [];
+chunk_decode() ->
+ [{doc, "Test http_chunk:decode/3"}].
chunk_decode(Config) when is_list(Config) ->
ReqHeaders = #http_request_h{'transfer-encoding' = "chunked"},
ChunkedBody = "A" ++ ?CRLF ++ "1234567890" ++ ?CRLF ++ "4" ++
@@ -109,15 +92,11 @@ chunk_decode(Config) when is_list(Config) ->
?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
{_, Body} = parse(Module, Function, Args, tl(NewChunkedBody)),
- "1234567890HEJ!" = binary_to_list(Body),
-
- ok.
+ "1234567890HEJ!" = binary_to_list(Body).
%%-------------------------------------------------------------------------
-chunk_extensions_otp_6005(doc) ->
- ["Make sure so called extensions are ignored"];
-chunk_extensions_otp_6005(suite) ->
- [];
+chunk_extensions_otp_6005() ->
+ [{doc, "Make sure so called extensions are ignored"}].
chunk_extensions_otp_6005(Config) when is_list(Config)->
ChunkedBody = "A;ignore this" ++ ?CRLF ++ "1234567890" ++
?CRLF ++ "4" ++ ?CRLF ++ "HEJ!"++ ?CRLF ++ "0" ++
@@ -136,14 +115,11 @@ chunk_extensions_otp_6005(Config) when is_list(Config)->
?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
{_, NewBody} = parse(Module1, Function1, Args1, tl(ChunkedBody1)),
- "1234567890HEJ!" = binary_to_list(NewBody),
- ok.
+ "1234567890HEJ!" = binary_to_list(NewBody).
%%-------------------------------------------------------------------------
-chunk_decode_otp_6264(doc) ->
- ["Check that 0 in the body does not count as the last chunk"];
-chunk_decode_otp_6264(suite) ->
- [];
+chunk_decode_otp_6264() ->
+ [{doc, "Check that 0 in the body does not count as the last chunk"}].
chunk_decode_otp_6264(Config) when is_list(Config)->
ChunkedBody = "A;ignore this" ++ ?CRLF ++ "1234567890" ++
?CRLF ++ "4" ++ ?CRLF ++ "0123"++ ?CRLF ++ "0" ++
@@ -173,27 +149,33 @@ chunk_decode_otp_6264(Config) when is_list(Config)->
?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
{_, NewBody} = parse(Module1, Function1, Args1, tl(NewChunkedBody1)),
- "12345678900" = binary_to_list(NewBody),
-
- ok.
+ "12345678900" = binary_to_list(NewBody).
%%-------------------------------------------------------------------------
-chunk_decode_empty_chunk_otp_6511(doc) ->
- [""];
-chunk_decode_empty_chunk_otp_6511(suite) ->
- [];
chunk_decode_empty_chunk_otp_6511(Config) when is_list(Config) ->
ChunkedBody = "0" ++ ?CRLF ++ ?CRLF,
{ok,{["content-length:0"],<<>>}} =
http_chunk:decode(list_to_binary(ChunkedBody),
- ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
- ok.
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE).
%%-------------------------------------------------------------------------
-chunk_decode_trailer(doc) ->
- ["Make sure trailers are handled correctly. Trailers should"
- "become new headers"];
-chunk_decode_trailer(suite) ->
- [];
+chunk_whitespace_suffix() ->
+ [{doc, "Test whitespace after chunked length header"}].
+chunk_whitespace_suffix(Config) when is_list(Config) ->
+ ChunkedBody = "1a ; ignore-stuff-here" ++ ?CRLF ++
+ "abcdefghijklmnopqrstuvwxyz" ++ ?CRLF ++ "10 " ++ ?CRLF
+ ++ "1234567890abcdef" ++ ?CRLF ++ "0 " ++ ?CRLF
+ ++ "some-footer:some-value" ++ ?CRLF
+ ++ "another-footer:another-value" ++ ?CRLF ++ ?CRLF,
+ {ok, {["content-length:42", "another-footer:another-value",
+ "some-footer:some-value", ""],
+ <<"abcdefghijklmnopqrstuvwxyz1234567890abcdef">>}} =
+ http_chunk:decode(list_to_binary(ChunkedBody),
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE).
+
+%%-------------------------------------------------------------------------
+chunk_decode_trailer() ->
+ [{doc,"Make sure trailers are handled correctly. Trailers should"
+ "become new headers"}].
chunk_decode_trailer(Config) when is_list(Config)->
ChunkedBody = "1a; ignore-stuff-here" ++ ?CRLF ++
"abcdefghijklmnopqrstuvwxyz" ++ ?CRLF ++ "10" ++ ?CRLF
@@ -249,30 +231,79 @@ chunk_decode_trailer(Config) when is_list(Config)->
?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
{_, NewBody} = parse(Module1, Function1, Args1, tl(ChunkedBody3)),
- "abcdefghijklmnopqrstuvwxyz1234567890abcdef" = binary_to_list(NewBody),
-
- ok.
+ "abcdefghijklmnopqrstuvwxyz1234567890abcdef" = binary_to_list(NewBody).
%%-------------------------------------------------------------------------
-chunk_encode(doc) ->
- ["Test http_chunk:encode/1 & http_chunk:encode_last/0"];
-chunk_encode(suite) ->
- [];
+chunk_encode() ->
+ [{doc, "Test http_chunk:encode/1 & http_chunk:encode_last/0"}].
chunk_encode(Config) when is_list(Config) ->
<<54, ?CR, ?LF, 102,111,111,98,97,114, ?CR, ?LF>> =
http_chunk:encode(list_to_binary("foobar")),
["6", ?CR, ?LF,"foobar", ?CR, ?LF] = http_chunk:encode("foobar"),
- <<$0, ?CR, ?LF, ?CR, ?LF >> = http_chunk:encode_last(),
- ok.
-
+ <<$0, ?CR, ?LF, ?CR, ?LF >> = http_chunk:encode_last().
+%%-------------------------------------------------------------------------
+chunk_max_headersize() ->
+ [{doc, "Test max header limit"}].
+chunk_max_headersize(Config) when is_list(Config) ->
+ ChunkedBody = "1a; ignore-stuff-here" ++ ?CRLF ++
+ "abcdefghijklmnopqrstuvwxyz" ++ ?CRLF ++ "10" ++ ?CRLF
+ ++ "1234567890abcdef" ++ ?CRLF ++ "0" ++ ?CRLF
+ ++ "some-footer:some-value" ++ ?CRLF
+ ++ "another-footer:another-value" ++ ?CRLF ++ ?CRLF,
+
+ {ok, {_, _}} =
+ http_chunk:decode(list_to_binary(ChunkedBody),
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
+
+ %% Too long in length header
+ {error,{header_too_long, {max, 1}}} =
+ (catch http_chunk:decode(list_to_binary(ChunkedBody),
+ ?HTTP_MAX_BODY_SIZE, 1)),
+
+ %% Too long in extension field
+ {error,{header_too_long, {max, 10}}} =
+ (catch http_chunk:decode(list_to_binary(ChunkedBody),
+ ?HTTP_MAX_BODY_SIZE, 10)),
+
+ %% Too long in trailer
+ {error,{header_too_long, {max, 30}}} =
+ (catch http_chunk:decode(list_to_binary(ChunkedBody),
+ ?HTTP_MAX_BODY_SIZE, 30)).
+%%-------------------------------------------------------------------------
+chunk_not_hex() ->
+ [{doc, "Test bad chunked length header"}].
+chunk_not_hex(Config) when is_list(Config) ->
+ ChunkedBody = "åäö; ignore-stuff-here" ++ ?CRLF ++
+ "abcdefghijklmnopqrstuvwxyz" ++ ?CRLF ++ "10" ++ ?CRLF
+ ++ "1234567890abcdef" ++ ?CRLF ++ "0" ++ ?CRLF
+ ++ "some-footer:some-value" ++ ?CRLF
+ ++ "another-footer:another-value" ++ ?CRLF ++ ?CRLF,
+ {error,{chunk_size, "åäö"}} =
+ (catch http_chunk:decode(list_to_binary(ChunkedBody),
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE)).
+%%-------------------------------------------------------------------------
+chunk_max_bodysize() ->
+ [{doc, "Test max body limit"}].
+chunk_max_bodysize(Config) when is_list(Config) ->
+ ChunkedBody = "1a; ignore-stuff-here" ++ ?CRLF ++
+ "abcdefghijklmnopqrstuvwxyz" ++ ?CRLF ++ "10" ++ ?CRLF
+ ++ "1234567890abcdef" ++ ?CRLF ++ "0" ++ ?CRLF
+ ++ "some-footer:some-value" ++ ?CRLF
+ ++ "another-footer:another-value" ++ ?CRLF ++ ?CRLF,
+ {ok, {_, _}} =
+ http_chunk:decode(list_to_binary(ChunkedBody),
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
+
+ %% Too long body
+ {error,{body_too_big, {max, 10}}} =
+ (catch http_chunk:decode(list_to_binary(ChunkedBody),
+ 10, ?HTTP_MAX_HEADER_SIZE)).
%%-------------------------------------------------------------------------
-http_response(doc) ->
- ["Test httpc_response:parse*. This test case will simulate that the "
+http_response() ->
+ [{doc, "Test httpc_response:parse*. This test case will simulate that the "
"message will be recived a little at the time on a socket and the "
- "package may be broken up into smaller parts at arbitrary point."];
-http_response(suite) ->
- [];
+ "package may be broken up into smaller parts at arbitrary point."}].
http_response(Config) when is_list(Config) ->
HttpHead1 = ["HTTP", "/1.1 ", "20", "0 ", "ok", [?CR, ?LF],
@@ -340,12 +371,10 @@ http_response(Config) when is_list(Config) ->
[<<>>,Length1], HttpBody1)),
ok.
%%-------------------------------------------------------------------------
-http_request(doc) ->
- ["Test httpd_request:parse* This test case will simulate that the "
+http_request() ->
+ [{doc, "Test httpd_request:parse* This test case will simulate that the "
"message will be recived a little at the time on a socket and the "
- "package may be broken up into smaller parts at arbitrary point."];
-http_request(suite) ->
- [];
+ "package may be broken up into smaller parts at arbitrary point."}].
http_request(Config) when is_list(Config) ->
HttpHead = ["GE", "T ", "http://www.erlang", ".org ", "HTTP",
@@ -407,15 +436,12 @@ http_request(Config) when is_list(Config) ->
NewBody1 =
binary_to_list(parse
(httpd_request, whole_body,
- [<<>>, Length1], HttpBody1)),
- ok.
+ [<<>>, Length1], HttpBody1)).
%%-------------------------------------------------------------------------
-validate_request_line(doc) ->
- ["Test httpd_request:validate/3. Makes sure you can not get past"
+validate_request_line() ->
+ [{doc, "Test httpd_request:validate/3. Makes sure you can not get past"
" the server_root and that the request is recognized by the server"
- " and protcol version." ];
-validate_request_line(suite) ->
- [];
+ " and protcol version."}].
validate_request_line(Config) when is_list(Config) ->
%% HTTP/0.9 only has GET requests
@@ -468,16 +494,12 @@ validate_request_line(Config) when is_list(Config) ->
NewForbiddenUri1 =
"http://127.0.0.1:8888/../home/ingela/test.html",
{error, {bad_request, {forbidden, NewForbiddenUri1}}} =
- httpd_request:validate("GET", NewForbiddenUri1, "HTTP/1.1"),
-
- ok.
+ httpd_request:validate("GET", NewForbiddenUri1, "HTTP/1.1").
%%-------------------------------------------------------------------------
-check_content_length_encoding(doc) ->
- ["Test http_request:headers/2. Check that the content-length is"
- " encoded even when it is zero." ];
-check_content_length_encoding(suite) ->
- [];
+check_content_length_encoding() ->
+ [{doc, "Test http_request:headers/2. Check that the content-length is"
+ " encoded even when it is zero."}].
check_content_length_encoding(Config) when is_list(Config) ->
%% Check that the content-length is preserved.
@@ -486,16 +508,12 @@ check_content_length_encoding(Config) when is_list(Config) ->
true = (string:str(Header1, "content-length: 123\r\n") > 0),
%% Check that content-length=0 is handled correctly.
Header2 = http_request:http_headers(#http_request_h{'content-length'="0"}),
- true = (string:str(Header2, "content-length: 0\r\n") > 0),
-
- ok.
+ true = (string:str(Header2, "content-length: 0\r\n") > 0).
%%-------------------------------------------------------------------------
-esi_parse_headers(doc) ->
- ["Test httpd_esi:*. All header values are received in the same"
- " erlang message."];
-esi_parse_headers(suite) ->
- [];
+esi_parse_headers() ->
+ [{doc, "Test httpd_esi:*. All header values are received in the same"
+ " erlang message."}].
esi_parse_headers(Config) when is_list(Config) ->
ESIResult = "content-type:text/html\r\ndate:Thu, 28 Oct 2004 07:57:43 "
@@ -522,16 +540,14 @@ esi_parse_headers(Config) when is_list(Config) ->
httpd_esi:handle_headers(Headers2),
{proceed,"/foo/bar.html"} =
- httpd_esi:handle_headers("location:/foo/bar.html\r\n"),
- ok.
+ httpd_esi:handle_headers("location:/foo/bar.html\r\n").
%%--------------------------------------------------------------------
-cgi_parse_headers(doc) ->
- ["Test httpd_cgi:*. This test case will simulate that the "
+cgi_parse_headers() ->
+ [{doc, "Test httpd_cgi:*. This test case will simulate that the "
"message will be recived a little at the time on a socket and the "
- "package may be broken up into smaller parts at arbitrary point."];
-cgi_parse_headers(suite) ->
- [];
+ "package may be broken up into smaller parts at arbitrary point."}].
+
cgi_parse_headers(Config) when is_list(Config) ->
CGIResult = ["content-type:text", "/html\ndate:Thu, 28 Oct 2004 07:57:43 "
@@ -567,26 +583,18 @@ cgi_parse_headers(Config) when is_list(Config) ->
{ok,[{"content-type","text/html"},
{"connection","close"},
{"content-language","en"},
- {"age","4711"}], {200,"ok"}} = httpd_cgi:handle_headers(Headers3),
-
- ok.
-
+ {"age","4711"}], {200,"ok"}} = httpd_cgi:handle_headers(Headers3).
%%-------------------------------------------------------------------------
-is_absolut_uri(doc) ->
- ["Test http_request:is_absolut_uri/1."];
-is_absolut_uri(suite) ->
- [];
+is_absolut_uri() ->
+ [{doc, "Test http_request:is_absolut_uri/1."}].
is_absolut_uri(Config) when is_list(Config) ->
true = http_request:is_absolut_uri("http://www.erlang.org"),
true = http_request:is_absolut_uri("https://www.erlang.org"),
false = http_request:is_absolut_uri("index.html").
-
%%-------------------------------------------------------------------------
-convert_netscapecookie_date(doc) ->
- ["Test http_util:convert_netscapecookie_date/1."];
-convert_netscapecookie_date(suite) ->
- [];
+convert_netscapecookie_date() ->
+ [{doc, "Test http_util:convert_netscapecookie_date/1."}].
convert_netscapecookie_date(Config) when is_list(Config) ->
{{2006,1,6},{8,59,38}} =
http_util:convert_netscapecookie_date("Mon, 06-Jan-2006 08:59:38 GMT"),
@@ -619,9 +627,7 @@ convert_netscapecookie_date(Config) when is_list(Config) ->
{{2006,12,12},{8,59,38}} =
http_util:convert_netscapecookie_date("Sun 12-Dec-06 08:59:38 GMT"),
{{2036,1,1},{8,0,1}} =
- http_util:convert_netscapecookie_date("Tue Jan 01 08:00:01 2036 GMT"),
- ok.
-
+ http_util:convert_netscapecookie_date("Tue Jan 01 08:00:01 2036 GMT").
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
diff --git a/lib/inets/test/httpc_SUITE.erl b/lib/inets/test/httpc_SUITE.erl
index 5b40d08859..c6c59ab1af 100644
--- a/lib/inets/test/httpc_SUITE.erl
+++ b/lib/inets/test/httpc_SUITE.erl
@@ -98,13 +98,17 @@ only_simulated() ->
stream_once,
stream_single_chunk,
stream_no_length,
+ not_streamed_once,
+ stream_large_not_200_or_206,
no_content_204,
tolerate_missing_CR,
userinfo,
bad_response,
internal_server_error,
invalid_http,
+ invalid_chunk_size,
headers_dummy,
+ headers_with_obs_fold,
empty_response_header,
remote_socket_close,
remote_socket_close_async,
@@ -407,6 +411,21 @@ stream_no_length(Config) when is_list(Config) ->
stream_test(Request1, {stream, self}),
Request2 = {url(group_name(Config), "/http_1_0_no_length_multiple.html", Config), []},
stream_test(Request2, {stream, self}).
+%%-------------------------------------------------------------------------
+stream_large_not_200_or_206() ->
+ [{doc, "Test the option stream for large responses with status codes "
+ "other than 200 or 206" }].
+stream_large_not_200_or_206(Config) when is_list(Config) ->
+ Request = {url(group_name(Config), "/large_404_response.html", Config), []},
+ {404, _} = not_streamed_test(Request, {stream, self}).
+%%-------------------------------------------------------------------------
+not_streamed_once() ->
+ [{doc, "Test not streamed responses with once streaming"}].
+not_streamed_once(Config) when is_list(Config) ->
+ Request0 = {url(group_name(Config), "/404.html", Config), []},
+ {404, _} = not_streamed_test(Request0, {stream, {self, once}}),
+ Request1 = {url(group_name(Config), "/404_chunked.html", Config), []},
+ {404, _} = not_streamed_test(Request1, {stream, {self, once}}).
%%-------------------------------------------------------------------------
@@ -747,6 +766,22 @@ invalid_http(Config) when is_list(Config) ->
ct:print("Parse error: ~p ~n", [Reason]).
%%-------------------------------------------------------------------------
+
+invalid_chunk_size(doc) ->
+ ["Test parse error of HTTP chunk size"];
+invalid_chunk_size(suite) ->
+ [];
+invalid_chunk_size(Config) when is_list(Config) ->
+
+ URL = url(group_name(Config), "/invalid_chunk_size.html", Config),
+
+ {error, {chunk_size, _} = Reason} =
+ httpc:request(get, {URL, []}, [], []),
+
+ ct:print("Parse error: ~p ~n", [Reason]).
+
+%%-------------------------------------------------------------------------
+
emulate_lower_versions(doc) ->
[{doc, "Perform request as 0.9 and 1.0 clients."}];
emulate_lower_versions(Config) when is_list(Config) ->
@@ -893,6 +928,13 @@ headers_dummy(Config) when is_list(Config) ->
%%-------------------------------------------------------------------------
+headers_with_obs_fold(Config) when is_list(Config) ->
+ Request = {url(group_name(Config), "/obs_folded_headers.html", Config), []},
+ {ok, {{_,200,_}, Headers, [_|_]}} = httpc:request(get, Request, [], []),
+ "a b" = proplists:get_value("folded", Headers).
+
+%%-------------------------------------------------------------------------
+
invalid_headers(Config) ->
Request = {url(group_name(Config), "/dummy.html", Config), [{"cookie", undefined}]},
{error, _} = httpc:request(get, Request, [], []).
@@ -1109,6 +1151,19 @@ stream_test(Request, To) ->
Body = binary_to_list(StreamedBody).
+not_streamed_test(Request, To) ->
+ {ok, {{_,Code,_}, [_ | _], Body}} =
+ httpc:request(get, Request, [], [{body_format, binary}]),
+ {ok, RequestId} =
+ httpc:request(get, Request, [], [{body_format, binary}, {sync, false}, To]),
+
+ receive
+ {http, {RequestId, {{_, Code, _}, _Headers, Body}}} ->
+ {Code, binary_to_list(Body)};
+ {http, Msg} ->
+ ct:fail(Msg)
+ end.
+
url(http, End, Config) ->
Port = ?config(port, Config),
{ok,Host} = inet:gethostname(),
@@ -1640,6 +1695,11 @@ handle_uri(_,"/307.html",Port,_,Socket,_) ->
"Content-Length:" ++ integer_to_list(length(Body))
++ "\r\n\r\n" ++ Body;
+handle_uri(_,"/404.html",_,_,_,_) ->
+ "HTTP/1.1 404 not found\r\n" ++
+ "Content-Length:14\r\n\r\n" ++
+ "Page not found";
+
handle_uri(_,"/500.html",_,_,_,_) ->
"HTTP/1.1 500 Internal Server Error\r\n" ++
"Content-Length:47\r\n\r\n" ++
@@ -1713,6 +1773,13 @@ handle_uri(_,"/dummy_headers.html",_,_,Socket,_) ->
send(Socket, http_chunk:encode("obar</BODY></HTML>")),
http_chunk:encode_last();
+handle_uri(_,"/obs_folded_headers.html",_,_,_,_) ->
+ "HTTP/1.1 200 ok\r\n"
+ "Content-Length:5\r\n"
+ "Folded: a\r\n"
+ " b\r\n\r\n"
+ "Hello";
+
handle_uri(_,"/capital_transfer_encoding.html",_,_,Socket,_) ->
Head = "HTTP/1.1 200 ok\r\n" ++
"Transfer-Encoding:Chunked\r\n\r\n",
@@ -1768,6 +1835,15 @@ handle_uri(_,"/once_chunked.html",_,_,Socket,_) ->
http_chunk:encode("obar</BODY></HTML>")),
http_chunk:encode_last();
+handle_uri(_,"/404_chunked.html",_,_,Socket,_) ->
+ Head = "HTTP/1.1 404 not found\r\n" ++
+ "Transfer-Encoding:Chunked\r\n\r\n",
+ send(Socket, Head),
+ send(Socket, http_chunk:encode("<HTML><BODY>Not ")),
+ send(Socket,
+ http_chunk:encode("found</BODY></HTML>")),
+ http_chunk:encode_last();
+
handle_uri(_,"/single_chunk.html",_,_,Socket,_) ->
Chunk = "HTTP/1.1 200 ok\r\n" ++
"Transfer-Encoding:Chunked\r\n\r\n" ++
@@ -1792,6 +1868,17 @@ handle_uri(_,"/http_1_0_no_length_multiple.html",_,_,Socket,_) ->
send(Socket, string:copies("other multiple packets ", 200)),
close(Socket);
+handle_uri(_,"/large_404_response.html",_,_,Socket,_) ->
+ %% long body to make sure it will be sent in multiple tcp packets
+ Body = string:copies("other multiple packets ", 200),
+ Head = io_lib:format("HTTP/1.1 404 not found\r\n"
+ "Content-length: ~B\r\n"
+ "Content-type: text/plain\r\n\r\n",
+ [length(Body)]),
+ send(Socket, Head),
+ send(Socket, Body),
+ close(Socket);
+
handle_uri(_,"/once.html",_,_,Socket,_) ->
Head = "HTTP/1.1 200 ok\r\n" ++
"Content-Length:32\r\n\r\n",
@@ -1806,6 +1893,10 @@ handle_uri(_,"/invalid_http.html",_,_,_,_) ->
"HTTP/1.1 301\r\nDate:Sun, 09 Dec 2007 13:04:18 GMT\r\n" ++
"Transfer-Encoding:chunked\r\n\r\n";
+handle_uri(_,"/invalid_chunk_size.html",_,_,_,_) ->
+ "HTTP/1.1 200 ok\r\n" ++
+ "Transfer-Encoding:chunked\r\n\r\nåäö\r\n";
+
handle_uri(_,"/missing_reason_phrase.html",_,_,_,_) ->
"HTTP/1.1 200\r\n" ++
"Content-Length: 32\r\n\r\n"
diff --git a/lib/inets/test/httpd_1_1.erl b/lib/inets/test/httpd_1_1.erl
index dd9d21bbfc..db6def9d17 100644
--- a/lib/inets/test/httpd_1_1.erl
+++ b/lib/inets/test/httpd_1_1.erl
@@ -24,7 +24,7 @@
-include_lib("kernel/include/file.hrl").
-export([host/4, chunked/4, expect/4, range/4, if_test/5, trace/4,
- head/4, mod_cgi_chunked_encoding_test/5]).
+ head/4, mod_cgi_chunked_encoding_test/5, mod_esi_chunk_timeout/4]).
%% -define(all_keys_lower_case,true).
-ifndef(all_keys_lower_case).
@@ -274,6 +274,15 @@ mod_cgi_chunked_encoding_test(Type, Port, Host, Node, [Request| Rest])->
[{statuscode, 200}]),
mod_cgi_chunked_encoding_test(Type, Port, Host, Node, Rest).
+
+mod_esi_chunk_timeout(Type, Port, Host, Node) ->
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /cgi-bin/erl/httpd_example/chunk_timeout?input=20000 HTTP/1.1\r\n"
+ "Host:"++ Host ++"\r\n"
+ "\r\n",
+ [{statuscode, 200},
+ {header, "warning"}]).
+
%%--------------------------------------------------------------------
%% Internal functions
%%--------------------------------------------------------------------
diff --git a/lib/inets/test/httpd_SUITE.erl b/lib/inets/test/httpd_SUITE.erl
index a6236f828a..1d8a603981 100644
--- a/lib/inets/test/httpd_SUITE.erl
+++ b/lib/inets/test/httpd_SUITE.erl
@@ -97,7 +97,7 @@ groups() ->
{https_reload, [], [{group, reload}]},
{http_mime_types, [], [alias_1_1, alias_1_0, alias_0_9]},
{limit, [], [max_clients_1_1, max_clients_1_0, max_clients_0_9]},
- {custom, [], [customize]},
+ {custom, [], [customize, add_default]},
{reload, [], [non_disturbing_reconfiger_dies,
disturbing_reconfiger_dies,
non_disturbing_1_1,
@@ -117,7 +117,7 @@ groups() ->
{htaccess, [], [htaccess_1_1, htaccess_1_0, htaccess_0_9]},
{security, [], [security_1_1, security_1_0]}, %% Skip 0.9 as causes timing issus in test code
{http_1_1, [], [host, chunked, expect, cgi, cgi_chunked_encoding_test,
- trace, range, if_modified_since] ++ http_head() ++ http_get() ++ load()},
+ trace, range, if_modified_since, mod_esi_chunk_timeout] ++ http_head() ++ http_get() ++ load()},
{http_1_0, [], [host, cgi, trace] ++ http_head() ++ http_get() ++ load()},
{http_0_9, [], http_head() ++ http_get() ++ load()}
].
@@ -757,6 +757,13 @@ esi(Config) when is_list(Config) ->
Config, [{statuscode, 200},
{no_header, "cache-control"}]).
%%-------------------------------------------------------------------------
+mod_esi_chunk_timeout(Config) when is_list(Config) ->
+ ok = httpd_1_1:mod_esi_chunk_timeout(?config(type, Config),
+ ?config(port, Config),
+ ?config(host, Config),
+ ?config(node, Config)).
+
+%%-------------------------------------------------------------------------
cgi() ->
[{doc, "Test mod_cgi"}].
@@ -1003,10 +1010,23 @@ customize(Config) when is_list(Config) ->
{no_header, "Server"},
{version, Version}]).
-response_header({"server", _}) ->
- false;
-response_header(Header) ->
- {true, Header}.
+add_default() ->
+ [{doc, "Test adding default header with custom callback"}].
+
+add_default(Config) when is_list(Config) ->
+ Version = "HTTP/1.1",
+ Host = ?config(host, Config),
+ Type = ?config(type, Config),
+ ok = httpd_test_lib:verify_request(?config(type, Config), Host,
+ ?config(port, Config),
+ transport_opts(Type, Config),
+ ?config(node, Config),
+ http_request("GET /index.html ", Version, Host),
+ [{statuscode, 200},
+ {header, "Content-Type", "text/html"},
+ {header, "Date", "Override-date"},
+ {header, "X-Frame-Options"},
+ {version, Version}]).
%%-------------------------------------------------------------------------
max_header() ->
@@ -1421,13 +1441,15 @@ server_config(http_reload, Config) ->
server_config(https_reload, Config) ->
[{keep_alive_timeout, 2}] ++ server_config(https, Config);
server_config(http_limit, Config) ->
- [{max_clients, 1},
- %% Make sure option checking code is run
- {max_content_length, 100000002}] ++ server_config(http, Config);
+ Conf = [{max_clients, 1},
+ %% Make sure option checking code is run
+ {max_content_length, 100000002}] ++ server_config(http, Config),
+ ct:pal("Received message ~p~n", [Conf]),
+ Conf;
server_config(http_custom, Config) ->
- [{custom, ?MODULE}] ++ server_config(http, Config);
+ [{customize, ?MODULE}] ++ server_config(http, Config);
server_config(https_custom, Config) ->
- [{custom, ?MODULE}] ++ server_config(https, Config);
+ [{customize, ?MODULE}] ++ server_config(https, Config);
server_config(https_limit, Config) ->
[{max_clients, 1}] ++ server_config(https, Config);
server_config(http_basic_auth, Config) ->
@@ -1473,6 +1495,7 @@ server_config(http_mime_types, Config0) ->
server_config(http, Config) ->
ServerRoot = ?config(server_root, Config),
[{port, 0},
+ {socket_type, {ip_comm, [{nodelay, true}]}},
{server_name,"httpd_test"},
{server_root, ServerRoot},
{document_root, ?config(doc_root, Config)},
@@ -1494,13 +1517,14 @@ server_config(http, Config) ->
server_config(https, Config) ->
PrivDir = ?config(priv_dir, Config),
[{socket_type, {essl,
- [{cacertfile,
- filename:join(PrivDir, "public_key_cacert.pem")},
- {certfile,
- filename:join(PrivDir, "public_key_cert.pem")},
- {keyfile,
- filename:join(PrivDir, "public_key_cert_key.pem")}
- ]}}] ++ server_config(http, Config).
+ [{nodelay, true},
+ {cacertfile,
+ filename:join(PrivDir, "public_key_cacert.pem")},
+ {certfile,
+ filename:join(PrivDir, "public_key_cert.pem")},
+ {keyfile,
+ filename:join(PrivDir, "public_key_cert_key.pem")}
+ ]}}] ++ proplists:delete(socket_type, server_config(http, Config)).
init_httpd(Group, Config0) ->
Config1 = proplists:delete(port, Config0),
@@ -2030,3 +2054,14 @@ typestr(ip_comm) ->
"tcp";
typestr(_) ->
"ssl".
+
+response_header({"server", _}) ->
+ false;
+response_header(Header) ->
+ {true, Header}.
+
+response_default_headers() ->
+ [%% Add new header
+ {"X-Frame-Options", "SAMEORIGIN"},
+ %% Override built-in default
+ {"Date", "Override-date"}].
diff --git a/lib/inets/test/httpd_test_lib.erl b/lib/inets/test/httpd_test_lib.erl
index cb2e86c81e..c58966ce10 100644
--- a/lib/inets/test/httpd_test_lib.erl
+++ b/lib/inets/test/httpd_test_lib.erl
@@ -235,11 +235,17 @@ validate(RequestStr, #state{status_line = {Version, StatusCode, _},
_ ->
ok
end,
- do_validate(http_response:header_list(Headers), Options, N, P),
- check_body(RequestStr, StatusCode,
- Headers#http_response_h.'content-type',
- list_to_integer(Headers#http_response_h.'content-length'),
- Body).
+ HList = http_response:header_list(Headers),
+ do_validate(HList, Options, N, P),
+ case lists:keysearch("warning", 1, HList) of
+ {value, _} ->
+ ok;
+ _ ->
+ check_body(RequestStr, StatusCode,
+ Headers#http_response_h.'content-type',
+ list_to_integer(Headers#http_response_h.'content-length'),
+ Body)
+ end.
%--------------------------------------------------------------------
%% Internal functions
@@ -294,9 +300,9 @@ do_validate(Header, [{header, HeaderField, Value}|Rest],N,P) ->
{value, {LowerHeaderField, Value}} ->
ok;
false ->
- ct:fail({wrong_header_field_value, LowerHeaderField, Header});
+ ct:fail({wrong_header_field_value, LowerHeaderField, Header, Value});
_ ->
- ct:fail({wrong_header_field_value, LowerHeaderField, Header})
+ ct:fail({wrong_header_field_value, LowerHeaderField, Header, Value})
end,
do_validate(Header, Rest, N, P);
do_validate(Header,[{no_header, HeaderField}|Rest],N,P) ->
diff --git a/lib/inets/test/uri_SUITE.erl b/lib/inets/test/uri_SUITE.erl
index bfcd7bd339..2642b8fd4e 100644
--- a/lib/inets/test/uri_SUITE.erl
+++ b/lib/inets/test/uri_SUITE.erl
@@ -49,7 +49,8 @@ all() ->
queries,
fragments,
escaped,
- hexed_query
+ hexed_query,
+ scheme_validation
].
%%--------------------------------------------------------------------
@@ -175,6 +176,26 @@ hexed_query(Config) when is_list(Config) ->
verify_uri(URI2, Verify2),
verify_uri(URI3, Verify3).
+scheme_validation(Config) when is_list(Config) ->
+ {ok, {http,[],"localhost",80,"/",""}} =
+ http_uri:parse("http://localhost#fragment"),
+
+ ValidationFun =
+ fun("http") -> valid;
+ (_) -> {error, bad_scheme}
+ end,
+
+ {ok, {http,[],"localhost",80,"/",""}} =
+ http_uri:parse("http://localhost#fragment",
+ [{scheme_validation_fun, ValidationFun}]),
+ {error, bad_scheme} =
+ http_uri:parse("https://localhost#fragment",
+ [{scheme_validation_fun, ValidationFun}]),
+ %% non-fun scheme_validation_fun works as no option passed
+ {ok, {https,[],"localhost",443,"/",""}} =
+ http_uri:parse("https://localhost#fragment",
+ [{scheme_validation_fun, none}]).
+
%%--------------------------------------------------------------------
%% Internal Functions ------------------------------------------------
diff --git a/lib/inets/vsn.mk b/lib/inets/vsn.mk
index a6aeedfe12..7cc95fa6d3 100644
--- a/lib/inets/vsn.mk
+++ b/lib/inets/vsn.mk
@@ -19,6 +19,6 @@
# %CopyrightEnd%
APPLICATION = inets
-INETS_VSN = 6.0.1
+INETS_VSN = 6.0.3
PRE_VSN =
APP_VSN = "$(APPLICATION)-$(INETS_VSN)$(PRE_VSN)"
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpInputStream.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpInputStream.java
index 35280f9571..fa0815fbf0 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpInputStream.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpInputStream.java
@@ -1243,6 +1243,9 @@ public class OtpInputStream extends ByteArrayInputStream {
case OtpExternal.funTag:
return new OtpErlangFun(this);
+ case OtpExternal.externalFunTag:
+ return new OtpErlangExternalFun(this);
+
default:
throw new OtpErlangDecodeException("Uknown data type: " + tag);
}
diff --git a/lib/kernel/doc/src/app.xml b/lib/kernel/doc/src/app.xml
index 1591d589af..d6d6167923 100644
--- a/lib/kernel/doc/src/app.xml
+++ b/lib/kernel/doc/src/app.xml
@@ -191,7 +191,7 @@ RTDeps [ApplicationVersion] []
start phases must be a subset of the set of phases defined
for the primary application. Refer to <em>OTP Design Principles</em> for more information.</p>
</item>
- <tag><marker id="runtime_dependencies"><c>runtime_dependencies</c></marker></tag>
+ <tag><marker id="runtime_dependencies"></marker><c>runtime_dependencies</c></tag>
<item><p>A list of application versions that the application
depends on. An example of such an application version is
<c>"kernel-3.0"</c>. Application versions specified as runtime
diff --git a/lib/kernel/doc/src/application.xml b/lib/kernel/doc/src/application.xml
index 0fe774a73f..4d8e6ce94b 100644
--- a/lib/kernel/doc/src/application.xml
+++ b/lib/kernel/doc/src/application.xml
@@ -60,8 +60,9 @@
</datatype>
<datatype>
<!-- Parameterized opaque types are NYI: -->
- <name><marker id="type-tuple_of">tuple_of(T)</marker></name>
- <desc><p>A tuple where the elements are of type <c>T</c>.</p></desc>
+ <name>tuple_of(T)</name>
+ <desc><p><marker id="type-tuple_of"/>
+ A tuple where the elements are of type <c>T</c>.</p></desc>
</datatype>
</datatypes>
<funcs>
diff --git a/lib/kernel/doc/src/auth.xml b/lib/kernel/doc/src/auth.xml
index 9ebc6f8f1a..71b1863e96 100644
--- a/lib/kernel/doc/src/auth.xml
+++ b/lib/kernel/doc/src/auth.xml
@@ -50,7 +50,7 @@
be established in this case. Returns <c>no</c> if <c><anno>Node</anno></c>
does not exist or communication is not authorized (it has
another cookie than <c>auth</c> thinks it has).</p>
- <p>Use <seealso marker="net_adm#ping/1">net_adm:ping(<anno>Node</anno>)</seealso>
+ <p>Use <seealso marker="net_adm#ping/1">net_adm:ping(<c><anno>Node</anno></c>)</seealso>
instead.</p>
</desc>
</func>
@@ -71,7 +71,7 @@
</type_desc>
<desc>
<p>Use
- <seealso marker="erts:erlang#erlang:set_cookie/2">erlang:set_cookie(node(), <anno>Cookie</anno>)</seealso>
+ <seealso marker="erts:erlang#erlang:set_cookie/2">erlang:set_cookie(node(), <c><anno>Cookie</anno></c>)</seealso>
instead.</p>
</desc>
</func>
@@ -94,8 +94,8 @@
<p>Sets the magic cookie of <c><anno>Node</anno></c> to <c><anno>Cookie</anno></c>, and
verifies the status of the authorization.
Equivalent to calling
- <seealso marker="erts:erlang#erlang:set_cookie/2">erlang:set_cookie(<anno>Node</anno>, <anno>Cookie</anno>)</seealso>, followed by
- <seealso marker="#is_auth/1">auth:is_auth(<anno>Node</anno>)</seealso>.</p>
+ <seealso marker="erts:erlang#erlang:set_cookie/2">erlang:set_cookie(<c><anno>Node</anno></c>, <c><anno>Cookie</anno>)</c></seealso>, followed by
+ <seealso marker="#is_auth/1">auth:is_auth(<c><anno>Node</anno></c>)</seealso>.</p>
</desc>
</func>
</funcs>
diff --git a/lib/kernel/doc/src/code.xml b/lib/kernel/doc/src/code.xml
index 7cdedfa0ba..eb0f4b7a06 100644
--- a/lib/kernel/doc/src/code.xml
+++ b/lib/kernel/doc/src/code.xml
@@ -180,7 +180,7 @@
example, the call
<c>erl_prim_loader:list_dir( "/otp/root/lib/mnesia-4.4.7.ez/mnesia-4.4.7/examples/bench)"</c>
would list the contents of a directory inside an archive.
- See <seealso marker="erts:erl_prim_loader">erl_prim_loader(3)</seealso></p>.
+ See <seealso marker="erts:erl_prim_loader">erl_prim_loader(3)</seealso>.</p>
<p>An application archive file and a regular application directory
may coexist. This may be useful when there is a need of having
@@ -230,7 +230,7 @@
<c>-code_path_choice Choice</c>. If the flag is set to <c>relaxed</c>,
the code server will instead choose a suitable directory
depending on the actual file structure. If there exists a regular
- application ebin directory,situation it will be chosen. But if it does
+ application ebin directory, it will be chosen. But if it does
not exist, the ebin directory in the archive is chosen if it
exists. If neither of them exists the original directory will be
chosen.</p>
@@ -242,7 +242,7 @@
particular useful to set the flag to <c>relaxed</c> when you want
to elaborate with code loading from archives without editing the
<c>boot script</c>. The default is <c>relaxed</c>. See <seealso
- marker="erts:init">init(3)</seealso></p> </section>
+ marker="erts:init">init(3)</seealso></p></section>
<section>
@@ -282,9 +282,9 @@
<p>From the R12B release, functions in this module will generally fail with an
exception if they are passed an incorrect type (for instance, an integer or a tuple
- where an atom was expected). An error tuple will be returned if type of argument
+ where an atom was expected). An error tuple will be returned if the type of the argument
was correct, but there was some other error (for instance, a non-existing directory
- given to <c>set_path/1</c>.</p>
+ was given to <c>set_path/1</c>).</p>
</section>
<datatypes>
diff --git a/lib/kernel/doc/src/disk_log.xml b/lib/kernel/doc/src/disk_log.xml
index 32488a9f01..7d4a9687ea 100644
--- a/lib/kernel/doc/src/disk_log.xml
+++ b/lib/kernel/doc/src/disk_log.xml
@@ -233,11 +233,11 @@
<func>
<name name="alog" arity="2"/>
<name name="balog" arity="2"/>
+ <fsummary>Asynchronously log an item onto a disk log.</fsummary>
<type variable="Log"/>
<type variable="Term" name_i="1"/>
<type variable="Bytes"/>
<type name="notify_ret"/>
- <fsummary>Asynchronously log an item onto a disk log.</fsummary>
<desc>
<p>The <c>alog/2</c> and <c>balog/2</c> functions asynchronously
append an item to a disk log. The function <c>alog/2</c> is
@@ -288,8 +288,8 @@
<func>
<name name="block" arity="1"/>
<name name="block" arity="2"/>
- <type name="block_error_rsn"/>
<fsummary>Block a disk log.</fsummary>
+ <type name="block_error_rsn"/>
<desc>
<p>With a call to <c>block/1,2</c> a process can block a log.
If the blocking process is not an owner of the log, a temporary
@@ -663,8 +663,8 @@
<func>
<name name="lclose" arity="1"/>
<name name="lclose" arity="2"/>
- <type name="lclose_error_rsn"/>
<fsummary>Close a disk log on one node.</fsummary>
+ <type name="lclose_error_rsn"/>
<desc>
<p>The function <c>lclose/1</c> closes a local log or an
individual distributed log on the current node.
@@ -744,6 +744,7 @@
</func>
<func>
<name name="open" arity="1"/>
+ <fsummary>Open a disk log file.</fsummary>
<type name="dlog_options"/>
<type name="dlog_option"/>
<type name="open_ret"/>
@@ -753,7 +754,6 @@
<type name="open_error_rsn"/>
<type name="dlog_optattr"/>
<type name="dlog_size"/>
- <fsummary>Open a disk log file.</fsummary>
<desc>
<p>The <c><anno>ArgL</anno></c> parameter is a list of options which have
the following meanings:</p>
@@ -1043,8 +1043,8 @@ If
</func>
<func>
<name name="sync" arity="1"/>
- <type name="sync_error_rsn"/>
<fsummary>Flush the contents of a disk log to the disk.</fsummary>
+ <type name="sync_error_rsn"/>
<desc>
<p>The <c>sync/1</c> function ensures that the contents of the
log are actually written to the disk.
@@ -1086,8 +1086,8 @@ If
</func>
<func>
<name name="unblock" arity="1"/>
- <type name="unblock_error_rsn"/>
<fsummary>Unblock a disk log.</fsummary>
+ <type name="unblock_error_rsn"/>
<desc>
<p>The <c>unblock/1</c> function unblocks a log.
A log can only be unblocked by the blocking process.
diff --git a/lib/kernel/doc/src/erl_ddll.xml b/lib/kernel/doc/src/erl_ddll.xml
index d622725ba0..8d71883cf4 100644
--- a/lib/kernel/doc/src/erl_ddll.xml
+++ b/lib/kernel/doc/src/erl_ddll.xml
@@ -388,14 +388,14 @@
remove a monitor.</p>
<p>The function accepts the following parameters:</p>
<taglist>
- <tag><em><anno>Tag</anno></em></tag>
+ <tag><em><c><anno>Tag</anno></c></em></tag>
<item>
<p>The monitor tag is always <c>driver</c> as this function
can only be used to create driver monitors. In the future,
driver monitors will be integrated with process monitors,
why this parameter has to be given for consistence.</p>
</item>
- <tag><em><anno>Item</anno></em></tag>
+ <tag><em><c><anno>Item</anno></c></em></tag>
<item>
<p>The <c><anno>Item</anno></c> parameter specifies which driver one
wants to monitor (the name of the driver) as well as
@@ -642,7 +642,7 @@
</note>
<p>The function accepts the following parameters:</p>
<taglist>
- <tag><em><anno>Path</anno></em></tag>
+ <tag><em><c><anno>Path</anno></c></em></tag>
<item>
<p>The filesystem path to the directory where the driver
object file is situated. The filename of the object file
@@ -665,7 +665,7 @@
to have <em>only one loader</em> of a driver one wants to
upgrade in a running system! </p>
</item>
- <tag><em><anno>Name</anno></em></tag>
+ <tag><em><c><anno>Name</anno></c></em></tag>
<item>
<p>The name parameter is the name of the driver to be used
in subsequent calls to <seealso marker="erts:erlang#open_port/2">open_port</seealso>. The
@@ -678,14 +678,14 @@
with this <c><anno>Name</anno></c> parameter, much as a beam-file's
module name much correspond to its filename.</p>
</item>
- <tag><em><anno>OptionList</anno></em></tag>
+ <tag><em><c><anno>OptionList</anno></c></em></tag>
<item>
<p>A number of options can be specified to control the
loading operation. The options are given as a list of
two-tuples, the tuples having the following values and
meanings:</p>
<taglist>
- <tag><em>{driver_options, <anno>DriverOptionList</anno>}</em></tag>
+ <tag><em>{driver_options, <c><anno>DriverOptionList</anno></c>}</em></tag>
<item>
<p>This option is to provide options that will change
its general behavior and will "stick" to the driver
@@ -701,7 +701,7 @@
when the last <seealso marker="#users">user</seealso> calls <seealso marker="#try_unload/2">try_unload/2</seealso>, or
the last process having loaded the driver exits.</p>
</item>
- <tag><em>{monitor, <anno>MonitorOption</anno>}</em></tag>
+ <tag><em>{monitor, <c><anno>MonitorOption</anno></c>}</em></tag>
<item>
<p>A <c><anno>MonitorOption</anno></c> tells <c>try_load/3</c> to
trigger a driver monitor under certain
@@ -732,7 +732,7 @@
<c>{monitor, pending_driver}</c> in production
code (see the monitor discussion above). </p>
</item>
- <tag><em>{reload,<anno>ReloadOption</anno>}</em></tag>
+ <tag><em>{reload, <c><anno>ReloadOption</anno></c>}</em></tag>
<item>
<p>This option is used when one wants to
<em>reload</em> a driver from disk, most often in a
@@ -910,13 +910,13 @@
</taglist>
<p>The function accepts the following parameters:</p>
<taglist>
- <tag><em><anno>Name</anno></em></tag>
+ <tag><em><c><anno>Name</anno></c></em></tag>
<item>
<p>The name parameter is the name of the driver to be
unloaded. The name can be specified either as an
<c>iolist()</c> or as an <c>atom()</c>. </p>
</item>
- <tag><em><anno>OptionList</anno></em></tag>
+ <tag><em><c><anno>OptionList</anno></c></em></tag>
<item>
<p>The <c><anno>OptionList</anno></c> argument can be used to specify
certain behavior regarding ports as well as triggering
@@ -934,7 +934,7 @@
unloads, one should use the driver option
<c>kill_ports</c> when loading the driver instead.</p>
</item>
- <tag><em>{monitor, <anno>MonitorOption</anno>}</em></tag>
+ <tag><em>{monitor, <c><anno>MonitorOption</anno></c>}</em></tag>
<item>
<p>This option creates a driver monitor if the condition
given in <c><anno>MonitorOption</anno></c> is true. The valid
diff --git a/lib/kernel/doc/src/error_logger.xml b/lib/kernel/doc/src/error_logger.xml
index f83fe53084..92e14c2bef 100644
--- a/lib/kernel/doc/src/error_logger.xml
+++ b/lib/kernel/doc/src/error_logger.xml
@@ -299,12 +299,12 @@ ok</pre>
<name name="logfile" arity="1" clause_i="1"/>
<name name="logfile" arity="1" clause_i="2"/>
<name name="logfile" arity="1" clause_i="3"/>
+ <fsummary>Enable or disable error printouts to a file</fsummary>
<type variable="Filename"/>
<type variable="OpenReason" name_i="1"/>
<type variable="CloseReason" name_i="2"/>
<type variable="FilenameReason" name_i="3"/>
<type name="open_error"/>
- <fsummary>Enable or disable error printouts to a file</fsummary>
<desc>
<p>Enables or disables printout of standard events to a file.</p>
<p>This is done by adding or deleting the standard event handler
diff --git a/lib/kernel/doc/src/file.xml b/lib/kernel/doc/src/file.xml
index 4954568086..831ef1c22a 100644
--- a/lib/kernel/doc/src/file.xml
+++ b/lib/kernel/doc/src/file.xml
@@ -87,9 +87,10 @@
<name name="deep_list"/>
</datatype>
<datatype>
- <name><marker id="type-fd">fd()</marker></name>
+ <name>fd()</name>
<desc>
- <p>A file descriptor representing a file opened in <seealso
+ <p><marker id="type-fd"/>
+ A file descriptor representing a file opened in <seealso
marker="#raw">raw</seealso> mode.</p>
</desc>
</datatype>
@@ -491,7 +492,7 @@
<name name="list_dir" arity="1"/>
<fsummary>List files in a directory</fsummary>
<desc>
- <p>Lists all files in a directory, <b>except</b> files
+ <p>Lists all files in a directory, <em>except</em> files
with "raw" names. Returns
<c>{ok, <anno>Filenames</anno>}</c> if successful.
Otherwise, it returns <c>{error, <anno>Reason</anno>}</c>.
@@ -1193,8 +1194,8 @@
and <c>read_line/1</c> are the only ways to read from a file
opened in raw mode (although they work for normally opened
files, too).</p>
- <p>For files where <c>encoding</c> is set to something else than <c>latin1</c>, one character might be represented by more than one byte on the file. The parameter <c>Number</c> always denotes the number of <em>characters</em> read from the file, why the position in the file might be moved a lot more than this number when reading a Unicode file.</p>
- <p>Also if <c>encoding</c> is set to something else than <c>latin1</c>, the <c>read/3</c> call will fail if the data contains characters larger than 255, why the <seealso marker="stdlib:io">io(3)</seealso> module is to be preferred when reading such a file.</p>
+ <p>For files where <c>encoding</c> is set to something else than <c>latin1</c>, one character might be represented by more than one byte on the file. The parameter <c>Number</c> always denotes the number of <em>characters</em> read from the file, while the position in the file might be moved much more than this number when reading a Unicode file.</p>
+ <p>Also, if <c>encoding</c> is set to something else than <c>latin1</c>, the <c>read/3</c> call will fail if the data contains characters larger than 255, which is why the <seealso marker="stdlib:io">io(3)</seealso> module is to be preferred when reading such a file.</p>
<p>The function returns:</p>
<taglist>
<tag><c>{ok, <anno>Data</anno>}</c></tag>
@@ -1307,15 +1308,15 @@
<item>
<p>The current system access to the file.</p>
</item>
- <tag><c>atime = <seealso marker="#type-date_time">date_time()</seealso> | integer() >= 0</c></tag>
+ <tag><c>atime = </c><seealso marker="#type-date_time">date_time()</seealso><c> | integer() >= 0</c></tag>
<item>
<p>The last time the file was read.</p>
</item>
- <tag><c>mtime = <seealso marker="#type-date_time">date_time()</seealso> | integer() >= 0</c></tag>
+ <tag><c>mtime = </c><seealso marker="#type-date_time">date_time()</seealso><c> | integer() >= 0</c></tag>
<item>
<p>The last time the file was written.</p>
</item>
- <tag><c>ctime = <seealso marker="#type-date_time">date_time()</seealso> | integer() >=0</c></tag>
+ <tag><c>ctime = </c><seealso marker="#type-date_time">date_time()</seealso><c> | integer() >=0</c></tag>
<item>
<p>The interpretation of this time field depends on
the operating system. On Unix, it is the last time
@@ -1745,7 +1746,7 @@
See <seealso marker="gen_tcp#controlling_process-2">gen_tcp:controlling_process/2</seealso></p>
<p>If the OS used does not support sendfile, an Erlang fallback
using file:read and gen_tcp:send is used.</p>
- <p>The option list can contain the following options:
+ <p>The option list can contain the following options:</p>
<taglist>
<tag><c>chunk_size</c></tag>
<item>The chunk size used by the erlang fallback to send
@@ -1760,7 +1761,6 @@
the sendfile call will return <c>{error,einval}</c>.
Introduced in Erlang/OTP 17.0. Default is false.</item>
</taglist>
- </p>
</desc>
</func>
<func>
@@ -1851,22 +1851,21 @@
Type <c>local</c> will interpret the time set as local, <c>universal</c> will
interpret it as universal time and <c>posix</c> must be seconds since
or before unix time epoch which is 1970-01-01 00:00 UTC.
- Default is <c>{time, local}</c>.
+ Default is <c>{time, local}</c>.</p>
<p>If the <c>raw</c> option is set, the file server will not be called
and only informations about local files will be returned.</p>
- </p>
<p>The following fields are used from the record, if they are
given.</p>
<taglist>
- <tag><c>atime = <seealso marker="#type-date_time">date_time()</seealso> | integer() >= 0</c></tag>
+ <tag><c>atime = </c><seealso marker="#type-date_time">date_time()</seealso><c> | integer() >= 0</c></tag>
<item>
<p>The last time the file was read.</p>
</item>
- <tag><c>mtime = <seealso marker="#type-date_time">date_time()</seealso> | integer() >= 0</c></tag>
+ <tag><c>mtime = </c><seealso marker="#type-date_time">date_time()</seealso><c> | integer() >= 0</c></tag>
<item>
<p>The last time the file was written.</p>
</item>
- <tag><c>ctime = <seealso marker="#type-date_time">date_time()</seealso> | integer() >= 0</c></tag>
+ <tag><c>ctime = </c><seealso marker="#type-date_time">date_time()</seealso><c> | integer() >= 0</c></tag>
<item>
<p>On Unix, any value give for this field will be ignored
(the "ctime" for the file will be set to the current
diff --git a/lib/kernel/doc/src/gen_sctp.xml b/lib/kernel/doc/src/gen_sctp.xml
index b704d90613..456108a2fe 100644
--- a/lib/kernel/doc/src/gen_sctp.xml
+++ b/lib/kernel/doc/src/gen_sctp.xml
@@ -77,9 +77,10 @@
<datatypes>
<datatype>
- <name><marker id="type-assoc_id">assoc_id()</marker></name>
+ <name>assoc_id()</name>
<desc>
- <p>An opaque term returned in for example #sctp_paddr_change{}
+ <p><marker id="type-assoc_id"/>
+ An opaque term returned in for example #sctp_paddr_change{}
that identifies an association for an SCTP socket. The term
is opaque except for the special value <c>0</c> that has a
meaning such as "the whole endpoint" or "all future associations".
@@ -98,9 +99,10 @@
<desc><marker id="type-sctp_socket"></marker></desc>
</datatype>
<datatype>
- <name><marker id="type-sctp_socket">sctp_socket()</marker></name>
+ <name>sctp_socket()</name>
<desc>
- <p>Socket identifier returned from <c>open/*</c>.</p>
+ <p><marker id="type-sctp_socket"/>
+ Socket identifier returned from <c>open/*</c>.</p>
<marker id="exports"></marker>
</desc>
</datatype>
@@ -146,7 +148,7 @@
<c><anno>Addr</anno></c> and <c><anno>Port</anno></c>. The <c><anno>Timeout</anno></c>,
is expressed in milliseconds. A socket can be associated with multiple peers.</p>
- <p><b>WARNING:</b>Using a value of <c><anno>Timeout</anno></c> less than
+ <p><em>WARNING:</em>Using a value of <c><anno>Timeout</anno></c> less than
the maximum time taken by the OS to establish an association (around 4.5 minutes
if the default values from RFC 4960 are used) can result in
inconsistent or incorrect return values. This is especially
@@ -170,7 +172,7 @@
<p>The number of outbound and inbound streams can be set by
giving an <c>sctp_initmsg</c> option to <c>connect</c>
as in:</p>
-<pre> connect(<anno>Socket</anno>, Ip, <anno>Port</anno>,
+<pre> connect(Socket, Ip, Port>,
[{sctp_initmsg,#sctp_initmsg{num_ostreams=OutStreams,
max_instreams=MaxInStreams}}]) </pre>
<p>All options <c><anno>Opt</anno></c> are set on the socket before the
diff --git a/lib/kernel/doc/src/gen_tcp.xml b/lib/kernel/doc/src/gen_tcp.xml
index 8d9f09cea7..6a19e76c4f 100644
--- a/lib/kernel/doc/src/gen_tcp.xml
+++ b/lib/kernel/doc/src/gen_tcp.xml
@@ -78,9 +78,10 @@ do_recv(Sock, Bs) ->
<name name="listen_option"/>
</datatype>
<datatype>
- <name><marker id="type-socket">socket()</marker></name>
+ <name>socket()</name>
<desc>
- <p>As returned by accept/1,2 and connect/3,4.</p>
+ <p><marker id="type-socket"/>
+ As returned by accept/1,2 and connect/3,4.</p>
<marker id="connect"></marker>
</desc>
</datatype>
diff --git a/lib/kernel/doc/src/gen_udp.xml b/lib/kernel/doc/src/gen_udp.xml
index 6f34aba43c..79cd87dcef 100644
--- a/lib/kernel/doc/src/gen_udp.xml
+++ b/lib/kernel/doc/src/gen_udp.xml
@@ -43,9 +43,9 @@
<name name="option_name"/>
</datatype>
<datatype>
- <name><marker id="type-socket">socket()</marker></name>
+ <name>socket()</name>
<desc>
- <p>As returned by open/1,2.</p>
+ <p><marker id="type-socket"/>As returned by open/1,2.</p>
</desc>
</datatype>
</datatypes>
diff --git a/lib/kernel/doc/src/inet.xml b/lib/kernel/doc/src/inet.xml
index e5d7ce048a..088d78c1d6 100644
--- a/lib/kernel/doc/src/inet.xml
+++ b/lib/kernel/doc/src/inet.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1997</year><year>2013</year>
+ <year>1997</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -117,8 +117,9 @@ fe80::204:acff:fe17:bf38
</desc>
</datatype>
<datatype>
- <name><marker id="type-socket">socket()</marker></name>
- <desc><p>See <seealso marker="gen_tcp#type-socket">gen_tcp(3)</seealso>
+ <name>socket()</name>
+ <desc><p><marker id="type-socket"></marker>
+ See <seealso marker="gen_tcp#type-socket">gen_tcp(3)</seealso>
and <seealso marker="gen_udp#type-socket">gen_udp(3)</seealso>.</p>
</desc>
</datatype>
@@ -222,7 +223,7 @@ fe80::204:acff:fe17:bf38
</p>
<p>
Do not rely too much on the order of <c><anno>Flag</anno></c> atoms or
- <c><anno>Ifopt</anno></c> tuples. There are some rules, though:
+ <c><anno>Ifopt</anno></c> tuples. There are some rules, though:</p>
<list>
<item>
Immediately after <c>{addr,_}</c> follows <c>{netmask,_}</c>
@@ -238,7 +239,6 @@ fe80::204:acff:fe17:bf38
tuple concerns that address.
</item>
</list>
- </p>
<p>
The <c>{hwaddr,_}</c> tuple is not returned on Solaris since the
hardware address historically belongs to the link layer and only
@@ -379,14 +379,14 @@ fe80::204:acff:fe17:bf38
<name name="ntoa" arity="1" />
<fsummary>Convert IPv6 / IPV4 adress to ascii</fsummary>
<desc>
- <p>Parses an <a href="#type-ip_address">ip_address()</a> and returns an IPv4 or IPv6 address string.</p>
+ <p>Parses an <seealso marker="#type-ip_address">ip_address()</seealso> and returns an IPv4 or IPv6 address string.</p>
</desc>
</func>
<func>
<name name="parse_ipv4_address" arity="1" />
<fsummary>Parse an IPv4 address</fsummary>
<desc>
- <p>Parses an IPv4 address string and returns an <a href="#type-ip4_address">ip4_address()</a>.
+ <p>Parses an IPv4 address string and returns an <seealso marker="#type-ip4_address">ip4_address()</seealso>.
Accepts a shortened IPv4 shortened address string.</p>
</desc>
</func>
@@ -394,14 +394,14 @@ fe80::204:acff:fe17:bf38
<name name="parse_ipv4strict_address" arity="1" />
<fsummary>Parse an IPv4 address strict.</fsummary>
<desc>
- <p>Parses an IPv4 address string containing four fields, i.e <b>not</b> shortened, and returns an <a href="#type-ip4_adress">ip4_address()</a>.</p>
+ <p>Parses an IPv4 address string containing four fields, i.e <em>not</em> shortened, and returns an <seealso marker="#type-ip4_address">ip4_address()</seealso>.</p>
</desc>
</func>
<func>
<name name="parse_ipv6_address" arity="1" />
<fsummary>Parse an IPv6 address</fsummary>
<desc>
- <p>Parses an IPv6 address string and returns an <a href="#type-ip6_address">ip6_address()</a>.
+ <p>Parses an IPv6 address string and returns an <seealso marker="#type-ip6_address">ip6_address()</seealso>.
If an IPv4 address string is passed, an IPv4-mapped IPv6 address is returned.</p>
</desc>
</func>
@@ -409,22 +409,22 @@ fe80::204:acff:fe17:bf38
<name name="parse_ipv6strict_address" arity="1" />
<fsummary>Parse an IPv6 address strict.</fsummary>
<desc>
- <p>Parses an IPv6 address string and returns an <a href="#type-ip6_address">ip6_address()</a>.
- Does <b>not</b> accept IPv4 adresses.</p>
+ <p>Parses an IPv6 address string and returns an <seealso marker="#type-ip6_address">ip6_address()</seealso>.
+ Does <em>not</em> accept IPv4 adresses.</p>
</desc>
</func>
<func>
<name name="parse_address" arity="1" />
<fsummary>Parse an IPv4 or IPv6 address.</fsummary>
<desc>
- <p>Parses an IPv4 or IPv6 address string and returns an <a href="#type-ip4_address">ip4_address()</a> or <a href="#type-ip6_address">ip6_address()</a>. Accepts a shortened IPv4 address string.</p>
+ <p>Parses an IPv4 or IPv6 address string and returns an <seealso marker="#type-ip4_address">ip4_address()</seealso> or <seealso marker="#type-ip6_address">ip6_address()</seealso>. Accepts a shortened IPv4 address string.</p>
</desc>
</func>
<func>
<name name="parse_strict_address" arity="1" />
<fsummary>Parse an IPv4 or IPv6 address strict.</fsummary>
<desc>
- <p>Parses an IPv4 or IPv6 address string and returns an <a href="#type-ip4_address">ip4_address()</a> or <a href="#type-ip6_adress">ip6_address()</a>. Does <b>not</b> accept a shortened IPv4 address string.</p>
+ <p>Parses an IPv4 or IPv6 address string and returns an <seealso marker="#type-ip4_address">ip4_address()</seealso> or <seealso marker="#type-ip6_address">ip6_address()</seealso>. Does <em>not</em> accept a shortened IPv4 address string.</p>
</desc>
</func>
<func>
@@ -862,10 +862,10 @@ fe80::204:acff:fe17:bf38
<c>CAP_SYS_ADMIN</c> according to the documentation for setns(2).
However, during testing also <c>CAP_SYS_PTRACE</c>
and <c>CAP_DAC_READ_SEARCH</c> has proven to be necessary.
- Example:<code>
+ Example:</p><code>
setcap cap_sys_admin,cap_sys_ptrace,cap_dac_read_search+epi beam.smp
</code>
- Note also that the filesystem containing the virtual machine
+ <p>Note also that the filesystem containing the virtual machine
executable (<c>beam.smp</c> in the example above) has to be local,
mounted without the <c>nosetuid</c> flag,
support extended attributes and that
@@ -981,6 +981,11 @@ setcap cap_sys_admin,cap_sys_ptrace,cap_dac_read_search+epi beam.smp
indicated length are accepted and not considered invalid due
to internal buffer limitations.</p>
</item>
+ <tag><c>{line_delimiter, Char}</c>(TCP/IP sockets)</tag>
+ <item>
+ <p>Sets the line delimiting character for line oriented protocols
+ (<c>line</c>). Default value is <c>$\n</c>.</p>
+ </item>
<tag><c>{priority, Priority}</c></tag>
<item> <p>Set the protocol-defined priority for all packets to be sent
diff --git a/lib/kernel/doc/src/inet_res.xml b/lib/kernel/doc/src/inet_res.xml
index 6a2c9b1955..851a36aba9 100644
--- a/lib/kernel/doc/src/inet_res.xml
+++ b/lib/kernel/doc/src/inet_res.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2009</year><year>2013</year>
+ <year>2009</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -77,8 +77,11 @@
query is tried for the <c>alt_nameservers</c>.</p>
</section>
+ <section>
+ <title>Resolver Types</title>
+ <p>The following data types concern the resolver:</p>
+ </section>
<datatypes>
- <p>Resolver types:</p>
<datatype>
<name name="res_option"/>
</datatype>
@@ -88,8 +91,13 @@
<datatype>
<name name="res_error"/>
</datatype>
-
- <p><marker id="dns_types"/>DNS types:</p>
+ </datatypes>
+ <section>
+ <title>DNS Types</title>
+ <p><marker id="dns_types"/>
+ The following data types concern the DNS client:</p>
+ </section>
+ <datatypes>
<datatype>
<name name="dns_name"/>
<desc><p>A string with no adjacent dots.</p></desc>
@@ -106,7 +114,7 @@
<p>This is the start of a hiearchy of opaque data structures
that can be examined with access functions in inet_dns that
return lists of {Field,Value} tuples. The arity 2 functions
- just return the value for a given field.
+ just return the value for a given field.</p>
<pre>
dns_msg() = DnsMsg
inet_dns:msg(DnsMsg) ->
@@ -154,18 +162,19 @@ dns_rr() = DnsRr
| {version, integer()}
| {z, integer()}
| {data, dns_data()} ]
- inet_dns:rr(DnsRr, Field) -> Value
+ inet_dns:rr(DnsRr, Field) -> Value</pre>
-There is an info function for the types above:
+<p>There is an info function for the types above:</p>
+<pre>
inet_dns:record_type(dns_msg()) -> msg;
inet_dns:record_type(dns_header()) -> header;
inet_dns:record_type(dns_query()) -> dns_query;
inet_dns:record_type(dns_rr()) -> rr;
-inet_dns:record_type(_) -> undefined.
+inet_dns:record_type(_) -> undefined.</pre>
-So; inet_dns:(inet_dns:record_type(X))(X) will convert
-any of these data structures into a {Field,Value} list.</pre></p>
+<p>So; inet_dns:(inet_dns:record_type(X))(X) will convert
+any of these data structures into a {Field,Value} list.</p>
</desc>
</datatype>
<datatype>
@@ -272,7 +281,7 @@ any of these data structures into a {Field,Value} list.</pre></p>
<p>Resolve a DNS record of the given type and class for the given name.
The returned <c>dns_msg()</c> can be examined using
access functions in <c>inet_db</c> as described
- in <seealso marker="#dns_types">DNS types</seealso>.
+ in <seealso marker="#dns_types">DNS Types</seealso>.
</p><p>
If <c><anno>Name</anno></c> is an <c>ip_address()</c>, the domain name
to query for is generated as the standard reverse
diff --git a/lib/kernel/doc/src/net_adm.xml b/lib/kernel/doc/src/net_adm.xml
index 1072be44a5..4ef9d361f6 100644
--- a/lib/kernel/doc/src/net_adm.xml
+++ b/lib/kernel/doc/src/net_adm.xml
@@ -89,8 +89,8 @@
<func>
<name name="world" arity="0"/>
<name name="world" arity="1"/>
- <type name="verbosity"/>
<fsummary>Lookup and connect to all nodes at all hosts in <c>.hosts.erlang</c></fsummary>
+ <type name="verbosity"/>
<desc>
<p>This function calls <c>names(Host)</c> for all hosts which
are specified in the Erlang host file <c>.hosts.erlang</c>,
@@ -110,8 +110,8 @@
<func>
<name name="world_list" arity="1"/>
<name name="world_list" arity="2"/>
- <type name="verbosity"/>
<fsummary>Lookup and connect to all nodes at specified hosts</fsummary>
+ <type name="verbosity"/>
<desc>
<p>As <c>world/0,1</c>, but the hosts are given as argument
instead of being read from <c>.hosts.erlang</c>.</p>
diff --git a/lib/kernel/doc/src/notes.xml b/lib/kernel/doc/src/notes.xml
index 76db0c201f..d02c3e8ad2 100644
--- a/lib/kernel/doc/src/notes.xml
+++ b/lib/kernel/doc/src/notes.xml
@@ -185,6 +185,22 @@
</section>
+<section><title>Kernel 3.2.0.1</title>
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>The 'raw' socket option could not be used multiple times
+ in one call to any e.g gen_tcp function because only one
+ of the occurrences were used. This bug has been fixed,
+ and also a small bug concerning propagating error codes
+ from within inet:setopts/2.</p>
+ <p>Own Id: OTP-11482 Aux Id: seq12872 </p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+
<section><title>Kernel 3.2</title>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -1218,7 +1234,7 @@
</item>
<item>
<p> Fix returned error from gen_tcp:accept/1,2 when
- running out of ports
+ running out of ports.</p>
<p>
The {error, enfile} return value is badly misleading and
confusing for this case, since the Posix ENFILE errno
@@ -1227,7 +1243,7 @@
{error, system_limit}, which is consistent with e.g.
various file(3) functions. inet:format_error/1 has also
been updated to support system_limit in the same manner
- as file:format_error/1. (Thanks to Per Hedeland)</p></p>
+ as file:format_error/1. (Thanks to Per Hedeland)</p>
<p>
Own Id: OTP-9990</p>
</item>
@@ -1422,7 +1438,6 @@
Own Id: OTP-9764</p>
</item>
<item>
- <p>
<list> <item><p>Correct callback spec in application
module</p></item> <item><p>Refine warning about callback
specs with extra ranges</p></item> <item><p>Cleanup
@@ -1433,7 +1448,7 @@
analysis</p></item> <item><p>Fix crash in
Dialyzer</p></item> <item><p>Variable substitution was
not generalizing any unknown variables.</p></item>
- </list></p>
+ </list>
<p>
Own Id: OTP-9776</p>
</item>
diff --git a/lib/kernel/doc/src/os.xml b/lib/kernel/doc/src/os.xml
index 2d2a690fea..682d4a2eac 100644
--- a/lib/kernel/doc/src/os.xml
+++ b/lib/kernel/doc/src/os.xml
@@ -171,8 +171,8 @@ DirOut = os:cmd("dir"), % on Win32 platform</code>
</func>
<func>
<name name="timestamp" arity="0"/>
- <type_desc variable="Timestamp">Timestamp = {MegaSecs, Secs, MicroSecs}</type_desc>
<fsummary>Current OS system time on the erlang:timestamp/0 format</fsummary>
+ <type_desc variable="Timestamp">Timestamp = {MegaSecs, Secs, MicroSecs}</type_desc>
<desc>
<p>Returns current
<seealso marker="erts:time_correction#OS_System_Time">OS system time</seealso>
@@ -205,7 +205,7 @@ format_utc_timestamp() ->
29 Apr 2009 9:55:30.051711
</pre>
<p>OS system time can also be retreived by
- <c><seealso marker="#system_time/0"><c>os:system_time/0</c></seealso></c>,
+ <seealso marker="#system_time/0"><c>os:system_time/0</c></seealso>,
and <seealso marker="#system_time/1"><c>os:system_time/1</c></seealso>.</p>
</desc>
</func>
diff --git a/lib/kernel/src/file_io_server.erl b/lib/kernel/src/file_io_server.erl
index bf8b9e2747..deb7b315b1 100644
--- a/lib/kernel/src/file_io_server.erl
+++ b/lib/kernel/src/file_io_server.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2015. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -206,8 +206,8 @@ io_reply(From, ReplyAs, Reply) ->
file_request({advise,Offset,Length,Advise},
#state{handle=Handle}=State) ->
case ?PRIM_FILE:advise(Handle, Offset, Length, Advise) of
- {error,_}=Reply ->
- {stop,normal,Reply,State};
+ {error,Reason}=Reply ->
+ {stop,Reason,Reply,State};
Reply ->
{reply,Reply,State}
end;
@@ -215,62 +215,91 @@ file_request({allocate, Offset, Length},
#state{handle = Handle} = State) ->
Reply = ?PRIM_FILE:allocate(Handle, Offset, Length),
{reply, Reply, State};
+file_request({pread,At,Sz}, State)
+ when At =:= cur;
+ At =:= {cur,0} ->
+ case get_chars(Sz, latin1, State) of
+ {reply,Reply,NewState}
+ when is_list(Reply);
+ is_binary(Reply) ->
+ {reply,{ok,Reply},NewState};
+ Other ->
+ Other
+ end;
file_request({pread,At,Sz},
- #state{handle=Handle,buf=Buf,read_mode=ReadMode}=State) ->
+ #state{handle=Handle,buf=Buf}=State) ->
case position(Handle, At, Buf) of
- {ok,_Offs} ->
- case ?PRIM_FILE:read(Handle, Sz) of
- {ok,Bin} when ReadMode =:= list ->
- std_reply({ok,binary_to_list(Bin)}, State);
- Reply ->
- std_reply(Reply, State)
- end;
- Reply ->
- std_reply(Reply, State)
+ {error,_} = Reply ->
+ {error,Reply,State};
+ _ ->
+ case get_chars(Sz, latin1, State#state{buf= <<>>}) of
+ {reply,Reply,NewState}
+ when is_list(Reply);
+ is_binary(Reply) ->
+ {reply,{ok,Reply},NewState};
+ Other ->
+ Other
+ end
end;
+file_request({pwrite,At,Data},
+ #state{buf= <<>>}=State)
+ when At =:= cur;
+ At =:= {cur,0} ->
+ put_chars(Data, latin1, State);
file_request({pwrite,At,Data},
#state{handle=Handle,buf=Buf}=State) ->
case position(Handle, At, Buf) of
- {ok,_Offs} ->
- std_reply(?PRIM_FILE:write(Handle, Data), State);
- Reply ->
- std_reply(Reply, State)
+ {error,_} = Reply ->
+ {error,Reply,State};
+ _ ->
+ put_chars(Data, latin1, State)
end;
file_request(datasync,
#state{handle=Handle}=State) ->
case ?PRIM_FILE:datasync(Handle) of
- {error,_}=Reply ->
- {stop,normal,Reply,State};
+ {error,Reason}=Reply ->
+ {stop,Reason,Reply,State};
Reply ->
{reply,Reply,State}
end;
file_request(sync,
#state{handle=Handle}=State) ->
case ?PRIM_FILE:sync(Handle) of
- {error,_}=Reply ->
- {stop,normal,Reply,State};
+ {error,Reason}=Reply ->
+ {stop,Reason,Reply,State};
Reply ->
{reply,Reply,State}
end;
file_request(close,
#state{handle=Handle}=State) ->
- {stop,normal,?PRIM_FILE:close(Handle),State#state{buf= <<>>}};
+ case ?PRIM_FILE:close(Handle) of
+ {error,Reason}=Reply ->
+ {stop,Reason,Reply,State#state{buf= <<>>}};
+ Reply ->
+ {stop,normal,Reply,State#state{buf= <<>>}}
+ end;
file_request({position,At},
#state{handle=Handle,buf=Buf}=State) ->
- std_reply(position(Handle, At, Buf), State);
+ case position(Handle, At, Buf) of
+ {error,_} = Reply ->
+ {error,Reply,State};
+ Reply ->
+ std_reply(Reply, State)
+ end;
file_request(truncate,
#state{handle=Handle}=State) ->
case ?PRIM_FILE:truncate(Handle) of
- {error,_Reason}=Reply ->
- {stop,normal,Reply,State#state{buf= <<>>}};
+ {error,Reason}=Reply ->
+ {stop,Reason,Reply,State#state{buf= <<>>}};
Reply ->
- {reply,Reply,State}
+ std_reply(Reply, State)
end;
file_request(Unknown,
#state{}=State) ->
Reason = {request, Unknown},
{error,{error,Reason},State}.
+%% Standard reply and clear buffer
std_reply({error,_}=Reply, State) ->
{error,Reply,State#state{buf= <<>>}};
std_reply(Reply, State) ->
@@ -286,8 +315,8 @@ io_request({put_chars, Enc, Chars},
io_request({put_chars, Enc, Chars},
#state{handle=Handle,buf=Buf}=State) ->
case position(Handle, cur, Buf) of
- {error,_}=Reply ->
- {stop,normal,Reply,State#state{buf= <<>>}};
+ {error,Reason}=Reply ->
+ {stop,Reason,Reply,State};
_ ->
put_chars(Chars, Enc, State#state{buf= <<>>})
end;
@@ -368,23 +397,27 @@ io_request_loop([Request|Tail],
%% I/O request put_chars
%%
put_chars(Chars, latin1, #state{handle=Handle, unic=latin1}=State) ->
+ NewState = State#state{buf = <<>>},
case ?PRIM_FILE:write(Handle, Chars) of
- {error,_}=Reply ->
- {stop,normal,Reply,State};
+ {error,Reason}=Reply ->
+ {stop,Reason,Reply,NewState};
Reply ->
- {reply,Reply,State}
+ {reply,Reply,NewState}
end;
put_chars(Chars, InEncoding, #state{handle=Handle, unic=OutEncoding}=State) ->
+ NewState = State#state{buf = <<>>},
case unicode:characters_to_binary(Chars,InEncoding,OutEncoding) of
Bin when is_binary(Bin) ->
case ?PRIM_FILE:write(Handle, Bin) of
- {error,_}=Reply ->
- {stop,normal,Reply,State};
+ {error,Reason}=Reply ->
+ {stop,Reason,Reply,NewState};
Reply ->
- {reply,Reply,State}
+ {reply,Reply,NewState}
end;
{error,_,_} ->
- {stop,normal,{error,{no_translation, InEncoding, OutEncoding}},State}
+ {stop,no_translation,
+ {error,{no_translation, InEncoding, OutEncoding}},
+ NewState}
end.
get_line(S, {<<>>, Cont}, OutEnc,
@@ -884,11 +917,14 @@ cbv({utf32,little},_) ->
%% Compensates ?PRIM_FILE:position/2 for the number of bytes
%% we have buffered
-
-position(Handle, cur, Buf) ->
- position(Handle, {cur, 0}, Buf);
-position(Handle, {cur, Offs}, Buf) when is_binary(Buf) ->
- ?PRIM_FILE:position(Handle, {cur, Offs-byte_size(Buf)});
-position(Handle, At, _Buf) ->
- ?PRIM_FILE:position(Handle, At).
-
+position(Handle, At, Buf) ->
+ ?PRIM_FILE:position(
+ Handle,
+ case At of
+ cur ->
+ {cur, -byte_size(Buf)};
+ {cur, Offs} ->
+ {cur, Offs-byte_size(Buf)};
+ _ ->
+ At
+ end).
diff --git a/lib/kernel/src/inet.erl b/lib/kernel/src/inet.erl
index da7f04089d..b573112445 100644
--- a/lib/kernel/src/inet.erl
+++ b/lib/kernel/src/inet.erl
@@ -671,7 +671,7 @@ stats() ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
connect_options() ->
[tos, priority, reuseaddr, keepalive, linger, sndbuf, recbuf, nodelay,
- header, active, packet, packet_size, buffer, mode, deliver,
+ header, active, packet, packet_size, buffer, mode, deliver, line_delimiter,
exit_on_close, high_watermark, low_watermark, high_msgq_watermark,
low_msgq_watermark, send_timeout, send_timeout_close, delay_send, raw,
show_econnreset].
@@ -692,6 +692,7 @@ connect_options(Opts, Family) ->
case con_opt(Opts, BaseOpts, connect_options()) of
{ok, R} ->
{ok, R#connect_opts {
+ opts = lists:reverse(R#connect_opts.opts),
ifaddr = translate_ip(R#connect_opts.ifaddr, Family)
}};
Error -> Error
@@ -721,6 +722,8 @@ con_opt([Opt | Opts], #connect_opts{} = R, As) ->
{active,N} when is_integer(N), N < 32768, N >= -32768 ->
NOpts = lists:keydelete(active, 1, R#connect_opts.opts),
con_opt(Opts, R#connect_opts { opts = [{active,N}|NOpts] }, As);
+ {line_delimiter,C} when is_integer(C), C >= 0, C =< 255 ->
+ con_add(line_delimiter, C, R, Opts, As);
{Name,Val} when is_atom(Name) -> con_add(Name, Val, R, Opts, As);
_ -> {error, badarg}
end;
@@ -760,6 +763,7 @@ listen_options(Opts, Family) ->
case list_opt(Opts, BaseOpts, listen_options()) of
{ok, R} ->
{ok, R#listen_opts {
+ opts = lists:reverse(R#listen_opts.opts),
ifaddr = translate_ip(R#listen_opts.ifaddr, Family)
}};
Error -> Error
@@ -818,6 +822,7 @@ udp_options(Opts, Family) ->
case udp_opt(Opts, #udp_opts { }, udp_options()) of
{ok, R} ->
{ok, R#udp_opts {
+ opts = lists:reverse(R#udp_opts.opts),
ifaddr = translate_ip(R#udp_opts.ifaddr, Family)
}};
Error -> Error
@@ -891,9 +896,12 @@ sctp_options() ->
sctp_options(Opts, Mod) ->
case sctp_opt(Opts, Mod, #sctp_opts{}, sctp_options()) of
{ok,#sctp_opts{ifaddr=undefined}=SO} ->
- {ok,SO#sctp_opts{ifaddr=Mod:translate_ip(?SCTP_DEF_IFADDR)}};
- {ok,_}=OK ->
- OK;
+ {ok,
+ SO#sctp_opts{
+ opts=lists:reverse(SO#sctp_opts.opts),
+ ifaddr=Mod:translate_ip(?SCTP_DEF_IFADDR)}};
+ {ok,SO} ->
+ {ok,SO#sctp_opts{opts=lists:reverse(SO#sctp_opts.opts)}};
Error -> Error
end.
@@ -965,6 +973,8 @@ add_opt(Name, Val, Opts, As) ->
case lists:member(Name, As) of
true ->
case prim_inet:is_sockopt_val(Name, Val) of
+ true when Name =:= raw ->
+ {ok, [{Name,Val} | Opts]};
true ->
Opts1 = lists:keydelete(Name, 1, Opts),
{ok, [{Name,Val} | Opts1]};
diff --git a/lib/kernel/src/inet6_tcp.erl b/lib/kernel/src/inet6_tcp.erl
index 2ea017285c..1978307b3c 100644
--- a/lib/kernel/src/inet6_tcp.erl
+++ b/lib/kernel/src/inet6_tcp.erl
@@ -25,10 +25,29 @@
-export([controlling_process/2]).
-export([fdopen/2]).
+-export([family/0, mask/2, parse_address/1]).
-export([getserv/1, getaddr/1, getaddr/2, getaddrs/1, getaddrs/2]).
-include("inet_int.hrl").
+%% my address family
+family() -> inet6.
+
+%% Apply netmask on address
+mask({M1,M2,M3,M4,M5,M6,M7,M8}, {IP1,IP2,IP3,IP4,IP5,IP6,IP7,IP8}) ->
+ {M1 band IP1,
+ M2 band IP2,
+ M3 band IP3,
+ M4 band IP4,
+ M5 band IP5,
+ M6 band IP6,
+ M7 band IP7,
+ M8 band IP8 }.
+
+%% Parse address string
+parse_address(Host) ->
+ inet_parse:ipv6strict_address(Host).
+
%% inet_tcp port lookup
getserv(Port) when is_integer(Port) -> {ok, Port};
getserv(Name) when is_atom(Name) -> inet:getservbyname(Name,tcp).
diff --git a/lib/kernel/src/inet6_tcp_dist.erl b/lib/kernel/src/inet6_tcp_dist.erl
index a74a4916ba..3ab7f269bb 100644
--- a/lib/kernel/src/inet6_tcp_dist.erl
+++ b/lib/kernel/src/inet6_tcp_dist.erl
@@ -24,28 +24,6 @@
-export([listen/1, accept/1, accept_connection/5,
setup/5, close/1, select/1, is_node_name/1]).
-%% internal exports
-
--export([accept_loop/2,do_accept/6,do_setup/6, getstat/1,tick/1]).
-
--import(error_logger,[error_msg/2]).
-
--include("net_address.hrl").
-
-
-
--define(to_port(Socket, Data, Opts),
- case inet6_tcp:send(Socket, Data, Opts) of
- {error, closed} ->
- self() ! {tcp_closed, Socket},
- {error, closed};
- R ->
- R
- end).
-
-
--include("dist.hrl").
--include("dist_util.hrl").
%% ------------------------------------------------------------
%% Select this protocol based on node name
@@ -53,14 +31,7 @@
%% ------------------------------------------------------------
select(Node) ->
- case split_node(atom_to_list(Node), $@, []) of
- [_, Host] ->
- case inet:getaddr(Host,inet6) of
- {ok,_} -> true;
- _ -> false
- end;
- _ -> false
- end.
+ inet_tcp_dist:gen_select(inet6_tcp, Node).
%% ------------------------------------------------------------
%% Create the listen socket, i.e. the port that this erlang
@@ -68,59 +39,14 @@ select(Node) ->
%% ------------------------------------------------------------
listen(Name) ->
- case inet6_tcp:listen(0, [{active, false}, {packet,2}]) of
- {ok, Socket} ->
- TcpAddress = get_tcp_address(Socket),
- {_,Port} = TcpAddress#net_address.address,
- case erl_epmd:register_node(Name, Port) of
- {ok, Creation} ->
- {ok, {Socket, TcpAddress, Creation}};
- Error ->
- Error
- end;
- Error ->
- Error
- end.
+ inet_tcp_dist:gen_listen(inet6_tcp, Name).
%% ------------------------------------------------------------
%% Accepts new connection attempts from other Erlang nodes.
%% ------------------------------------------------------------
accept(Listen) ->
- spawn_opt(?MODULE, accept_loop, [self(), Listen], [link, {priority, max}]).
-
-accept_loop(Kernel, Listen) ->
- case inet6_tcp:accept(Listen) of
- {ok, Socket} ->
- Kernel ! {accept,self(),Socket,inet6,tcp},
- _ = controller(Kernel, Socket),
- accept_loop(Kernel, Listen);
- Error ->
- exit(Error)
- end.
-
-controller(Kernel, Socket) ->
- receive
- {Kernel, controller, Pid} ->
- flush_controller(Pid, Socket),
- inet6_tcp:controlling_process(Socket, Pid),
- flush_controller(Pid, Socket),
- Pid ! {self(), controller};
- {Kernel, unsupported_protocol} ->
- exit(unsupported_protocol)
- end.
-
-flush_controller(Pid, Socket) ->
- receive
- {tcp, Socket, Data} ->
- Pid ! {tcp, Socket, Data},
- flush_controller(Pid, Socket);
- {tcp_closed, Socket} ->
- Pid ! {tcp_closed, Socket},
- flush_controller(Pid, Socket)
- after 0 ->
- ok
- end.
+ inet_tcp_dist:gen_accept(inet6_tcp, Listen).
%% ------------------------------------------------------------
%% Accepts a new connection attempt from another Erlang node.
@@ -128,85 +54,7 @@ flush_controller(Pid, Socket) ->
%% ------------------------------------------------------------
accept_connection(AcceptPid, Socket, MyNode, Allowed, SetupTime) ->
- spawn_opt(?MODULE, do_accept,
- [self(), AcceptPid, Socket, MyNode, Allowed, SetupTime],
- [link, {priority, max}]).
-
-do_accept(Kernel, AcceptPid, Socket, MyNode, Allowed, SetupTime) ->
- receive
- {AcceptPid, controller} ->
- Timer = dist_util:start_timer(SetupTime),
- case check_ip(Socket) of
- true ->
- HSData = #hs_data{
- kernel_pid = Kernel,
- this_node = MyNode,
- socket = Socket,
- timer = Timer,
- this_flags = 0,
- allowed = Allowed,
- f_send = fun(S,D) -> inet6_tcp:send(S,D) end,
- f_recv = fun(S,N,T) -> inet6_tcp:recv(S,N,T)
- end,
- f_setopts_pre_nodeup =
- fun(S) ->
- inet:setopts(S,
- [{active, false},
- {packet, 4},
- nodelay()])
- end,
- f_setopts_post_nodeup =
- fun(S) ->
- inet:setopts(S,
- [{active, true},
- {deliver, port},
- {packet, 4},
- nodelay()])
- end,
- f_getll = fun(S) ->
- inet:getll(S)
- end,
- f_address = fun get_remote_id/2,
- mf_tick = fun ?MODULE:tick/1,
- mf_getstat = fun ?MODULE:getstat/1
- },
- dist_util:handshake_other_started(HSData);
- {false,IP} ->
- error_msg("** Connection attempt from "
- "disallowed IP ~w ** ~n", [IP]),
- ?shutdown(no_node)
- end
- end.
-
-
-%% we may not always want the nodelay behaviour
-%% for performance reasons
-
-nodelay() ->
- case application:get_env(kernel, dist_nodelay) of
- undefined ->
- {nodelay, true};
- {ok, true} ->
- {nodelay, true};
- {ok, false} ->
- {nodelay, false};
- _ ->
- {nodelay, true}
- end.
-
-
-%% ------------------------------------------------------------
-%% Get remote information about a Socket.
-%% ------------------------------------------------------------
-
-get_remote_id(Socket, Node) ->
- {ok, Address} = inet:peername(Socket),
- [_, Host] = split_node(atom_to_list(Node), $@, []),
- #net_address {
- address = Address,
- host = Host,
- protocol = tcp,
- family = inet6 }.
+ inet_tcp_dist:gen_accept_connection(inet6_tcp, AcceptPid, Socket, MyNode, Allowed, SetupTime).
%% ------------------------------------------------------------
%% Setup a new connection to another Erlang node.
@@ -214,214 +62,13 @@ get_remote_id(Socket, Node) ->
%% ------------------------------------------------------------
setup(Node, Type, MyNode, LongOrShortNames,SetupTime) ->
- spawn_opt(?MODULE, do_setup,
- [self(), Node, Type, MyNode, LongOrShortNames, SetupTime],
- [link, {priority, max}]).
-
-do_setup(Kernel, Node, Type, MyNode, LongOrShortNames,SetupTime) ->
- ?trace("~p~n",[{?MODULE,self(),setup,Node}]),
- [Name, Address] = splitnode(Node, LongOrShortNames),
- case inet:getaddr(Address, inet6) of
- {ok, Ip} ->
- Timer = dist_util:start_timer(SetupTime),
- case erl_epmd:port_please(Name, Ip) of
- {port, TcpPort, Version} ->
- ?trace("port_please(~p) -> version ~p~n",
- [Node,Version]),
- dist_util:reset_timer(Timer),
- case inet6_tcp:connect(Ip, TcpPort,
- [{active, false},
- {packet,2}]) of
- {ok, Socket} ->
- HSData = #hs_data{
- kernel_pid = Kernel,
- other_node = Node,
- this_node = MyNode,
- socket = Socket,
- timer = Timer,
- this_flags = 0,
- other_version = Version,
- f_send = fun inet6_tcp:send/2,
- f_recv = fun inet6_tcp:recv/3,
- f_setopts_pre_nodeup =
- fun(S) ->
- inet:setopts
- (S,
- [{active, false},
- {packet, 4},
- nodelay()])
- end,
- f_setopts_post_nodeup =
- fun(S) ->
- inet:setopts
- (S,
- [{active, true},
- {deliver, port},
- {packet, 4},
- nodelay()])
- end,
- f_getll = fun inet:getll/1,
- f_address =
- fun(_,_) ->
- #net_address {
- address = {Ip,TcpPort},
- host = Address,
- protocol = tcp,
- family = inet6}
- end,
- mf_tick = fun ?MODULE:tick/1,
- mf_getstat = fun ?MODULE:getstat/1,
- request_type = Type
- },
- dist_util:handshake_we_started(HSData);
- _ ->
- %% Other Node may have closed since
- %% port_please !
- ?trace("other node (~p) "
- "closed since port_please.~n",
- [Node]),
- ?shutdown(Node)
- end;
- _ ->
- ?trace("port_please (~p) "
- "failed.~n", [Node]),
- ?shutdown(Node)
- end;
- __Other ->
- ?trace("inet_getaddr(~p) "
- "failed (~p).~n", [Node,__Other]),
- ?shutdown(Node)
- end.
+ inet_tcp_dist:gen_setup(inet6_tcp, Node, Type, MyNode, LongOrShortNames, SetupTime).
%%
%% Close a socket.
%%
close(Socket) ->
inet6_tcp:close(Socket).
-
-
-%% If Node is illegal terminate the connection setup!!
-splitnode(Node, LongOrShortNames) ->
- case split_node(atom_to_list(Node), $@, []) of
- [Name|Tail] when Tail =/= [] ->
- Host = lists:append(Tail),
- case split_node(Host, $., []) of
- [_] when LongOrShortNames =:= longnames ->
- case inet_parse:ipv6strict_address(Host) of
- {ok, _} ->
- [Name, Host];
- _ ->
- error_msg("** System running to use "
- "fully qualified "
- "hostnames **~n"
- "** Hostname ~s is illegal **~n",
- [Host]),
- ?shutdown(Node)
- end;
- L when length(L) > 1, LongOrShortNames =:= shortnames ->
- error_msg("** System NOT running to use fully qualified "
- "hostnames **~n"
- "** Hostname ~s is illegal **~n",
- [Host]),
- ?shutdown(Node);
- _ ->
- [Name, Host]
- end;
- [_] ->
- error_msg("** Nodename ~p illegal, no '@' character **~n",
- [Node]),
- ?shutdown(Node);
- _ ->
- error_msg("** Nodename ~p illegal **~n", [Node]),
- ?shutdown(Node)
- end.
-
-split_node([Chr|T], Chr, Ack) -> [lists:reverse(Ack)|split_node(T, Chr, [])];
-split_node([H|T], Chr, Ack) -> split_node(T, Chr, [H|Ack]);
-split_node([], _, Ack) -> [lists:reverse(Ack)].
-
-%% ------------------------------------------------------------
-%% Fetch local information about a Socket.
-%% ------------------------------------------------------------
-get_tcp_address(Socket) ->
- {ok, Address} = inet:sockname(Socket),
- {ok, Host} = inet:gethostname(),
- #net_address {
- address = Address,
- host = Host,
- protocol = tcp,
- family = inet6
- }.
-
-%% ------------------------------------------------------------
-%% Do only accept new connection attempts from nodes at our
-%% own LAN, if the check_ip environment parameter is true.
-%% ------------------------------------------------------------
-check_ip(Socket) ->
- case application:get_env(check_ip) of
- {ok, true} ->
- case get_ifs(Socket) of
- {ok, IFs, IP} ->
- check_ip(IFs, IP);
- _ ->
- ?shutdown(no_node)
- end;
- _ ->
- true
- end.
-
-get_ifs(Socket) ->
- case inet:peername(Socket) of
- {ok, {IP, _}} ->
- case inet:getif(Socket) of
- {ok, IFs} -> {ok, IFs, IP};
- Error -> Error
- end;
- Error ->
- Error
- end.
-
-check_ip([{OwnIP, _, Netmask}|IFs], PeerIP) ->
- case {mask(Netmask, PeerIP), mask(Netmask, OwnIP)} of
- {M, M} -> true;
- _ -> check_ip(IFs, PeerIP)
- end;
-check_ip([], PeerIP) ->
- {false, PeerIP}.
-mask({M1,M2,M3,M4,M5,M6,M7,M8}, {IP1,IP2,IP3,IP4,IP5,IP6,IP7,IP8}) ->
- {M1 band IP1,
- M2 band IP2,
- M3 band IP3,
- M4 band IP4,
- M5 band IP5,
- M6 band IP6,
- M7 band IP7,
- M8 band IP8 }.
-
is_node_name(Node) when is_atom(Node) ->
- case split_node(atom_to_list(Node), $@, []) of
- [_,_Host] -> true;
- _ -> false
- end;
-is_node_name(_Node) ->
- false.
-tick(Sock) ->
- ?to_port(Sock,[],[force]).
-getstat(Socket) ->
- case inet:getstat(Socket, [recv_cnt, send_cnt, send_pend]) of
- {ok, Stat} ->
- split_stat(Stat,0,0,0);
- Error ->
- Error
- end.
-
-split_stat([{recv_cnt, R}|Stat], _, W, P) ->
- split_stat(Stat, R, W, P);
-split_stat([{send_cnt, W}|Stat], R, _, P) ->
- split_stat(Stat, R, W, P);
-split_stat([{send_pend, P}|Stat], R, W, _) ->
- split_stat(Stat, R, W, P);
-split_stat([], R, W, P) ->
- {ok, R, W, P}.
-
+ inet_tcp_dist:is_node_name(Node).
diff --git a/lib/kernel/src/inet_db.erl b/lib/kernel/src/inet_db.erl
index 1621efbfd7..108a803610 100644
--- a/lib/kernel/src/inet_db.erl
+++ b/lib/kernel/src/inet_db.erl
@@ -633,20 +633,22 @@ make_hostent(Name, Datas, Aliases, Type) ->
hostent_by_domain(Domain, Type) ->
?dbg("hostent_by_domain: ~p~n", [Domain]),
- hostent_by_domain(stripdot(Domain), [], Type).
+ hostent_by_domain(stripdot(Domain), [], [], Type).
-hostent_by_domain(Domain, Aliases, Type) ->
+hostent_by_domain(Domain, Aliases, LAliases, Type) ->
case lookup_type(Domain, Type) of
[] ->
case lookup_cname(Domain) of
[] ->
{error, nxdomain};
[CName | _] ->
- case lists:member(CName, [Domain | Aliases]) of
+ LDomain = tolower(Domain),
+ case lists:member(CName, [LDomain | LAliases]) of
true ->
{error, nxdomain};
false ->
- hostent_by_domain(CName, [Domain | Aliases], Type)
+ hostent_by_domain(CName, [Domain | Aliases],
+ [LDomain | LAliases], Type)
end
end;
Addrs ->
@@ -671,24 +673,26 @@ lookup_rr(Domain, Class, Type) ->
%% match data field directly and cache RRs.
%%
res_hostent_by_domain(Domain, Type, Rec) ->
- res_cache_answer(Rec),
- RRs = Rec#dns_rec.anlist,
+ RRs = lists:map(fun lower_rr/1, Rec#dns_rec.anlist),
+ res_cache_answer(Rec#dns_rec{anlist = RRs}),
?dbg("res_hostent_by_domain: ~p - ~p~n", [Domain, RRs]),
- res_hostent_by_domain(stripdot(Domain), [], Type, RRs).
+ res_hostent_by_domain(stripdot(Domain), [], [], Type, RRs).
-res_hostent_by_domain(Domain, Aliases, Type, RRs) ->
- case res_lookup_type(Domain, Type, RRs) of
+res_hostent_by_domain(Domain, Aliases, LAliases, Type, RRs) ->
+ LDomain = tolower(Domain),
+ case res_lookup_type(LDomain, Type, RRs) of
[] ->
- case res_lookup_type(Domain, ?S_CNAME, RRs) of
+ case res_lookup_type(LDomain, ?S_CNAME, RRs) of
[] ->
{error, nxdomain};
[CName | _] ->
- case lists:member(CName, [Domain | Aliases]) of
+ case lists:member(tolower(CName), [LDomain | LAliases]) of
true ->
{error, nxdomain};
false ->
res_hostent_by_domain(CName, [Domain | Aliases],
- Type, RRs)
+ [LDomain | LAliases], Type,
+ RRs)
end
end;
Addrs ->
@@ -721,7 +725,8 @@ gethostbyaddr(IP) ->
%%
res_gethostbyaddr(IP, Rec) ->
{ok, {IP1, HType, HLen}} = dnt(IP),
- res_cache_answer(Rec),
+ RRs = lists:map(fun lower_rr/1, Rec#dns_rec.anlist),
+ res_cache_answer(Rec#dns_rec{anlist = RRs}),
ent_gethostbyaddr(Rec#dns_rec.anlist, IP1, HType, HLen).
ent_gethostbyaddr(RRs, IP, AddrType, Length) ->
@@ -1378,7 +1383,7 @@ times() ->
%% lookup and remove old entries
do_lookup_rr(Domain, Class, Type) ->
- match_rr(#dns_rr{domain = Domain, class = Class,type = Type,
+ match_rr(#dns_rr{domain = tolower(Domain), class = Class,type = Type,
cnt = '_', tm = '_', ttl = '_',
bm = '_', func = '_', data = '_'}).
@@ -1400,6 +1405,11 @@ filter_rr([RR | RRs], Time) ->
[RR | filter_rr(RRs, Time)];
filter_rr([], _Time) -> [].
+%% Lower case the domain name before storage.
+%%
+lower_rr(#dns_rr{domain=Domain}=RR) when is_list(Domain) ->
+ RR#dns_rr { domain = tolower(Domain) };
+lower_rr(RR) -> RR.
%%
%% Case fold upper-case to lower-case according to RFC 4343
diff --git a/lib/kernel/src/inet_dns_record_adts.pl b/lib/kernel/src/inet_dns_record_adts.pl
index 657d2b9d35..6d719d836e 100644
--- a/lib/kernel/src/inet_dns_record_adts.pl
+++ b/lib/kernel/src/inet_dns_record_adts.pl
@@ -57,7 +57,8 @@ while(<DATA>) {
$" = ',';
$\ = "\n";
-while( my ($Name, $r) = each(%Names)) {
+foreach my $Name (sort keys %Names) {
+ my $r = $Names{$Name};
# Create substitutions for this Name
my ($Record, @Fields) = @{ $r };
my @FieldMatchValues;
@@ -110,7 +111,8 @@ while( my ($Name, $r) = each(%Names)) {
for my $i ( 0 .. $#INDEX ) {
my $line = $INDEX[$i];
if ($line =~ s/^[*]//) {
- while( my ($Name, $r) = each(%Names)) {
+ foreach my $Name (sort keys %Names) {
+ my $r = $Names{$Name};
my ($Record) = @{ $r };
$_ = $line;
s/Name\b/$Name/g;
diff --git a/lib/kernel/src/inet_int.hrl b/lib/kernel/src/inet_int.hrl
index bfe4c9ec8c..e7c6cf8ae2 100644
--- a/lib/kernel/src/inet_int.hrl
+++ b/lib/kernel/src/inet_int.hrl
@@ -149,6 +149,7 @@
-define(INET_LOPT_MSGQ_LOWTRMRK, 37).
-define(INET_LOPT_NETNS, 38).
-define(INET_LOPT_TCP_SHOW_ECONNRESET, 39).
+-define(INET_LOPT_LINE_DELIM, 40).
% Specific SCTP options: separate range:
-define(SCTP_OPT_RTOINFO, 100).
-define(SCTP_OPT_ASSOCINFO, 101).
diff --git a/lib/kernel/src/inet_tcp.erl b/lib/kernel/src/inet_tcp.erl
index b5c758c02c..f551af9709 100644
--- a/lib/kernel/src/inet_tcp.erl
+++ b/lib/kernel/src/inet_tcp.erl
@@ -27,11 +27,25 @@
-export([controlling_process/2]).
-export([fdopen/2]).
+-export([family/0, mask/2, parse_address/1]).
-export([getserv/1, getaddr/1, getaddr/2, getaddrs/1, getaddrs/2]).
-
-include("inet_int.hrl").
+%% my address family
+family() -> inet.
+
+%% Apply netmask on address
+mask({M1,M2,M3,M4}, {IP1,IP2,IP3,IP4}) ->
+ {M1 band IP1,
+ M2 band IP2,
+ M3 band IP3,
+ M4 band IP4}.
+
+%% Parse address string
+parse_address(Host) ->
+ inet_parse:ipv4strict_address(Host).
+
%% inet_tcp port lookup
getserv(Port) when is_integer(Port) -> {ok, Port};
getserv(Name) when is_atom(Name) -> inet:getservbyname(Name,tcp).
diff --git a/lib/kernel/src/inet_tcp_dist.erl b/lib/kernel/src/inet_tcp_dist.erl
index 1bdc1c9ed8..64b28bb49b 100644
--- a/lib/kernel/src/inet_tcp_dist.erl
+++ b/lib/kernel/src/inet_tcp_dist.erl
@@ -24,9 +24,13 @@
-export([listen/1, accept/1, accept_connection/5,
setup/5, close/1, select/1, is_node_name/1]).
+%% Generalized dist API
+-export([gen_listen/2, gen_accept/2, gen_accept_connection/6,
+ gen_setup/6, gen_select/2]).
+
%% internal exports
--export([accept_loop/2,do_accept/6,do_setup/6,getstat/1,tick/1]).
+-export([accept_loop/3,do_accept/7,do_setup/7,getstat/1]).
-import(error_logger,[error_msg/2]).
@@ -34,15 +38,6 @@
--define(to_port(Socket, Data, Opts),
- case inet_tcp:send(Socket, Data, Opts) of
- {error, closed} ->
- self() ! {tcp_closed, Socket},
- {error, closed};
- R ->
- R
- end).
-
-include("dist.hrl").
-include("dist_util.hrl").
@@ -53,8 +48,15 @@
%% ------------------------------------------------------------
select(Node) ->
+ gen_select(inet_tcp, Node).
+
+gen_select(Driver, Node) ->
case split_node(atom_to_list(Node), $@, []) of
- [_,_Host] -> true;
+ [_, Host] ->
+ case inet:getaddr(Host, Driver:family()) of
+ {ok,_} -> true;
+ _ -> false
+ end;
_ -> false
end.
@@ -64,9 +66,12 @@ select(Node) ->
%% ------------------------------------------------------------
listen(Name) ->
- case do_listen([{active, false}, {packet,2}, {reuseaddr, true}]) of
+ gen_listen(inet_tcp, Name).
+
+gen_listen(Driver, Name) ->
+ case do_listen(Driver, [{active, false}, {packet,2}, {reuseaddr, true}]) of
{ok, Socket} ->
- TcpAddress = get_tcp_address(Socket),
+ TcpAddress = get_tcp_address(Driver, Socket),
{_,Port} = TcpAddress#net_address.address,
case erl_epmd:register_node(Name, Port) of
{ok, Creation} ->
@@ -78,7 +83,7 @@ listen(Name) ->
Error
end.
-do_listen(Options) ->
+do_listen(Driver, Options) ->
{First,Last} = case application:get_env(kernel,inet_dist_listen_min) of
{ok,N} when is_integer(N) ->
case application:get_env(kernel,
@@ -91,14 +96,14 @@ do_listen(Options) ->
_ ->
{0,0}
end,
- do_listen(First, Last, listen_options([{backlog,128}|Options])).
+ do_listen(Driver, First, Last, listen_options([{backlog,128}|Options])).
-do_listen(First,Last,_) when First > Last ->
+do_listen(_Driver, First,Last,_) when First > Last ->
{error,eaddrinuse};
-do_listen(First,Last,Options) ->
- case inet_tcp:listen(First, Options) of
+do_listen(Driver, First,Last,Options) ->
+ case Driver:listen(First, Options) of
{error, eaddrinuse} ->
- do_listen(First+1,Last,Options);
+ do_listen(Driver, First+1,Last,Options);
Other ->
Other
end.
@@ -124,23 +129,26 @@ listen_options(Opts0) ->
%% ------------------------------------------------------------
accept(Listen) ->
- spawn_opt(?MODULE, accept_loop, [self(), Listen], [link, {priority, max}]).
+ gen_accept(inet_tcp, Listen).
-accept_loop(Kernel, Listen) ->
- case inet_tcp:accept(Listen) of
+gen_accept(Driver, Listen) ->
+ spawn_opt(?MODULE, accept_loop, [Driver, self(), Listen], [link, {priority, max}]).
+
+accept_loop(Driver, Kernel, Listen) ->
+ case Driver:accept(Listen) of
{ok, Socket} ->
- Kernel ! {accept,self(),Socket,inet,tcp},
- _ = controller(Kernel, Socket),
- accept_loop(Kernel, Listen);
+ Kernel ! {accept,self(),Socket,Driver:family(),tcp},
+ _ = controller(Driver, Kernel, Socket),
+ accept_loop(Driver, Kernel, Listen);
Error ->
exit(Error)
end.
-controller(Kernel, Socket) ->
+controller(Driver, Kernel, Socket) ->
receive
{Kernel, controller, Pid} ->
flush_controller(Pid, Socket),
- inet_tcp:controlling_process(Socket, Pid),
+ Driver:controlling_process(Socket, Pid),
flush_controller(Pid, Socket),
Pid ! {self(), controller};
{Kernel, unsupported_protocol} ->
@@ -165,15 +173,18 @@ flush_controller(Pid, Socket) ->
%% ------------------------------------------------------------
accept_connection(AcceptPid, Socket, MyNode, Allowed, SetupTime) ->
+ gen_accept_connection(inet_tcp, AcceptPid, Socket, MyNode, Allowed, SetupTime).
+
+gen_accept_connection(Driver, AcceptPid, Socket, MyNode, Allowed, SetupTime) ->
spawn_opt(?MODULE, do_accept,
- [self(), AcceptPid, Socket, MyNode, Allowed, SetupTime],
+ [Driver, self(), AcceptPid, Socket, MyNode, Allowed, SetupTime],
[link, {priority, max}]).
-do_accept(Kernel, AcceptPid, Socket, MyNode, Allowed, SetupTime) ->
+do_accept(Driver, Kernel, AcceptPid, Socket, MyNode, Allowed, SetupTime) ->
receive
{AcceptPid, controller} ->
Timer = dist_util:start_timer(SetupTime),
- case check_ip(Socket) of
+ case check_ip(Driver, Socket) of
true ->
HSData = #hs_data{
kernel_pid = Kernel,
@@ -182,9 +193,8 @@ do_accept(Kernel, AcceptPid, Socket, MyNode, Allowed, SetupTime) ->
timer = Timer,
this_flags = 0,
allowed = Allowed,
- f_send = fun(S,D) -> inet_tcp:send(S,D) end,
- f_recv = fun(S,N,T) -> inet_tcp:recv(S,N,T)
- end,
+ f_send = fun Driver:send/2,
+ f_recv = fun Driver:recv/3,
f_setopts_pre_nodeup =
fun(S) ->
inet:setopts(S,
@@ -203,8 +213,8 @@ do_accept(Kernel, AcceptPid, Socket, MyNode, Allowed, SetupTime) ->
f_getll = fun(S) ->
inet:getll(S)
end,
- f_address = fun get_remote_id/2,
- mf_tick = fun ?MODULE:tick/1,
+ f_address = fun(S, Node) -> get_remote_id(Driver, S, Node) end,
+ mf_tick = fun(S) -> tick(Driver, S) end,
mf_getstat = fun ?MODULE:getstat/1
},
dist_util:handshake_other_started(HSData);
@@ -235,13 +245,13 @@ nodelay() ->
%% ------------------------------------------------------------
%% Get remote information about a Socket.
%% ------------------------------------------------------------
-get_remote_id(Socket, Node) ->
+get_remote_id(Driver, Socket, Node) ->
case inet:peername(Socket) of
{ok,Address} ->
case split_node(atom_to_list(Node), $@, []) of
[_,Host] ->
#net_address{address=Address,host=Host,
- protocol=tcp,family=inet};
+ protocol=tcp,family=Driver:family()};
_ ->
%% No '@' or more than one '@' in node name.
?shutdown(no_node)
@@ -256,14 +266,18 @@ get_remote_id(Socket, Node) ->
%% ------------------------------------------------------------
setup(Node, Type, MyNode, LongOrShortNames,SetupTime) ->
+ gen_setup(inet_tcp, Node, Type, MyNode, LongOrShortNames, SetupTime).
+
+gen_setup(Driver, Node, Type, MyNode, LongOrShortNames, SetupTime) ->
spawn_opt(?MODULE, do_setup,
- [self(), Node, Type, MyNode, LongOrShortNames, SetupTime],
+ [Driver, self(), Node, Type, MyNode, LongOrShortNames, SetupTime],
[link, {priority, max}]).
-do_setup(Kernel, Node, Type, MyNode, LongOrShortNames,SetupTime) ->
+do_setup(Driver, Kernel, Node, Type, MyNode, LongOrShortNames, SetupTime) ->
?trace("~p~n",[{inet_tcp_dist,self(),setup,Node}]),
- [Name, Address] = splitnode(Node, LongOrShortNames),
- case inet:getaddr(Address, inet) of
+ [Name, Address] = splitnode(Driver, Node, LongOrShortNames),
+ AddressFamily = Driver:family(),
+ case inet:getaddr(Address, AddressFamily) of
{ok, Ip} ->
Timer = dist_util:start_timer(SetupTime),
case erl_epmd:port_please(Name, Ip) of
@@ -272,7 +286,7 @@ do_setup(Kernel, Node, Type, MyNode, LongOrShortNames,SetupTime) ->
[Node,Version]),
dist_util:reset_timer(Timer),
case
- inet_tcp:connect(
+ Driver:connect(
Ip, TcpPort,
connect_options([{active, false}, {packet, 2}]))
of
@@ -285,8 +299,8 @@ do_setup(Kernel, Node, Type, MyNode, LongOrShortNames,SetupTime) ->
timer = Timer,
this_flags = 0,
other_version = Version,
- f_send = fun inet_tcp:send/2,
- f_recv = fun inet_tcp:recv/3,
+ f_send = fun Driver:send/2,
+ f_recv = fun Driver:recv/3,
f_setopts_pre_nodeup =
fun(S) ->
inet:setopts
@@ -311,9 +325,9 @@ do_setup(Kernel, Node, Type, MyNode, LongOrShortNames,SetupTime) ->
address = {Ip,TcpPort},
host = Address,
protocol = tcp,
- family = inet}
+ family = AddressFamily}
end,
- mf_tick = fun ?MODULE:tick/1,
+ mf_tick = fun(S) -> tick(Driver, S) end,
mf_getstat = fun ?MODULE:getstat/1,
request_type = Type
},
@@ -353,18 +367,23 @@ close(Socket) ->
%% If Node is illegal terminate the connection setup!!
-splitnode(Node, LongOrShortNames) ->
+splitnode(Driver, Node, LongOrShortNames) ->
case split_node(atom_to_list(Node), $@, []) of
[Name|Tail] when Tail =/= [] ->
Host = lists:append(Tail),
case split_node(Host, $., []) of
[_] when LongOrShortNames =:= longnames ->
- error_msg("** System running to use "
- "fully qualified "
- "hostnames **~n"
- "** Hostname ~s is illegal **~n",
- [Host]),
- ?shutdown(Node);
+ case Driver:parse_address(Host) of
+ {ok, _} ->
+ [Name, Host];
+ _ ->
+ error_msg("** System running to use "
+ "fully qualified "
+ "hostnames **~n"
+ "** Hostname ~s is illegal **~n",
+ [Host]),
+ ?shutdown(Node)
+ end;
L when length(L) > 1, LongOrShortNames =:= shortnames ->
error_msg("** System NOT running to use fully qualified "
"hostnames **~n"
@@ -390,26 +409,26 @@ split_node([], _, Ack) -> [lists:reverse(Ack)].
%% ------------------------------------------------------------
%% Fetch local information about a Socket.
%% ------------------------------------------------------------
-get_tcp_address(Socket) ->
+get_tcp_address(Driver, Socket) ->
{ok, Address} = inet:sockname(Socket),
{ok, Host} = inet:gethostname(),
#net_address {
address = Address,
host = Host,
protocol = tcp,
- family = inet
+ family = Driver:family()
}.
%% ------------------------------------------------------------
%% Do only accept new connection attempts from nodes at our
%% own LAN, if the check_ip environment parameter is true.
%% ------------------------------------------------------------
-check_ip(Socket) ->
+check_ip(Driver, Socket) ->
case application:get_env(check_ip) of
{ok, true} ->
case get_ifs(Socket) of
{ok, IFs, IP} ->
- check_ip(IFs, IP);
+ check_ip(Driver, IFs, IP);
_ ->
?shutdown(no_node)
end;
@@ -428,20 +447,14 @@ get_ifs(Socket) ->
Error
end.
-check_ip([{OwnIP, _, Netmask}|IFs], PeerIP) ->
- case {mask(Netmask, PeerIP), mask(Netmask, OwnIP)} of
+check_ip(Driver, [{OwnIP, _, Netmask}|IFs], PeerIP) ->
+ case {Driver:mask(Netmask, PeerIP), Driver:mask(Netmask, OwnIP)} of
{M, M} -> true;
- _ -> check_ip(IFs, PeerIP)
+ _ -> check_ip(Driver, IFs, PeerIP)
end;
-check_ip([], PeerIP) ->
+check_ip(_Driver, [], PeerIP) ->
{false, PeerIP}.
-mask({M1,M2,M3,M4}, {IP1,IP2,IP3,IP4}) ->
- {M1 band IP1,
- M2 band IP2,
- M3 band IP3,
- M4 band IP4}.
-
is_node_name(Node) when is_atom(Node) ->
case split_node(atom_to_list(Node), $@, []) of
[_, _Host] -> true;
@@ -450,8 +463,14 @@ is_node_name(Node) when is_atom(Node) ->
is_node_name(_Node) ->
false.
-tick(Sock) ->
- ?to_port(Sock,[],[force]).
+tick(Driver, Socket) ->
+ case Driver:send(Socket, [], [force]) of
+ {error, closed} ->
+ self() ! {tcp_closed, Socket},
+ {error, closed};
+ R ->
+ R
+ end.
getstat(Socket) ->
case inet:getstat(Socket, [recv_cnt, send_cnt, send_pend]) of
diff --git a/lib/kernel/test/bif_SUITE.erl b/lib/kernel/test/bif_SUITE.erl
index c3840f3d16..dd3010567a 100644
--- a/lib/kernel/test/bif_SUITE.erl
+++ b/lib/kernel/test/bif_SUITE.erl
@@ -33,6 +33,7 @@
spawn_failures/1,
run_fun/1,
+ decode_packet_delim/1,
wilderness/1]).
-export([init_per_testcase/2, end_per_testcase/2]).
@@ -516,6 +517,15 @@ fetch_proc_vals(Pid) ->
{value,{heap_size,HS}} = lists:keysearch(heap_size, 1, PI),
?line {Ls, P, FA, HS}.
+decode_packet_delim(doc) ->
+ ["Test erlang:packet_delim/3 with {line_delimiter,0} option"];
+decode_packet_delim(suite) ->
+ [];
+decode_packet_delim(Config) when is_list(Config) ->
+ {ok,<<"abc",0>>,<<"efg",0>>} =
+ erlang:decode_packet(line, <<"abc",0,"efg",0>>, [{line_delimiter, 0}]),
+ {more, undefined} = erlang:decode_packet(line, <<"abc",0,"efg",0>>, []).
+
% This testcase should probably be moved somewhere else
wilderness(doc) ->
["Test that memory allocation command line options affecting the"
diff --git a/lib/kernel/test/file_SUITE.erl b/lib/kernel/test/file_SUITE.erl
index 8856be31c2..09d9a45197 100644
--- a/lib/kernel/test/file_SUITE.erl
+++ b/lib/kernel/test/file_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -48,7 +48,7 @@
-export([cur_dir_0/1, cur_dir_1/1, make_del_dir/1,
list_dir/1,list_dir_error/1,
untranslatable_names/1, untranslatable_names_error/1,
- pos1/1, pos2/1]).
+ pos1/1, pos2/1, pos3/1]).
-export([close/1, consult1/1, path_consult/1, delete/1]).
-export([ eval1/1, path_eval/1, script1/1, path_script/1,
open1/1,
@@ -80,6 +80,7 @@
-export([interleaved_read_write/1]).
+-export([unicode/1]).
-export([altname/1]).
-export([large_file/1, large_write/1]).
@@ -114,7 +115,7 @@
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [altname, read_write_file, {group, dirs},
+ [unicode, altname, read_write_file, {group, dirs},
{group, files}, delete, rename, names, {group, errors},
{group, compression}, {group, links}, copy,
delayed_write, read_ahead, segment_read, segment_write,
@@ -136,7 +137,7 @@ groups() ->
[open1, old_modes, new_modes, path_open, close, access,
read_write, pread_write, append, open_errors,
exclusive]},
- {pos, [], [pos1, pos2]},
+ {pos, [], [pos1, pos2, pos3]},
{file_info, [],
[file_info_basic_file, file_info_basic_directory,
file_info_bad, file_info_times, file_write_file_info]},
@@ -1370,6 +1371,27 @@ pos2(Config) when is_list(Config) ->
?line test_server:timetrap_cancel(Dog),
ok.
+pos3(suite) -> [];
+pos3(doc) -> ["When it does not use raw mode, file:position had a bug."];
+pos3(Config) when is_list(Config) ->
+ ?line Dog = test_server:timetrap(test_server:seconds(5)),
+ ?line RootDir = ?config(data_dir, Config),
+ ?line Name = filename:join(RootDir, "realmen.html.gz"),
+
+ ?line {ok, Fd} = ?FILE_MODULE:open(Name, [read, binary]),
+ ?line {ok, _} = ?FILE_MODULE:read(Fd, 5),
+ ?line {error, einval} = ?FILE_MODULE:position(Fd, {bof, -1}),
+
+ %% Here ok had returned =(
+ ?line {error, einval} = ?FILE_MODULE:position(Fd, {cur, -10}),
+ %% That test is actually questionable since file:position/2
+ %% is documented to leave the file position undefined after
+ %% it has returned an error. But on Posix systems the position
+ %% is guaranteed to be unchanged after an error return. On e.g
+ %% Windows there is nothing stated about this in the documentation.
+
+ ?line test_server:timetrap_cancel(Dog),
+ ok.
file_info_basic_file(suite) -> [];
file_info_basic_file(doc) -> [];
@@ -2761,6 +2783,40 @@ compress_async_crash_loop(N, Path, ExpectedData) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+unicode(Config) when is_list(Config) ->
+ Dir = ?config(priv_dir, Config),
+ Name = filename:join(Dir, "data-utf8.txt"),
+ Txt = lists:seq(128, 255),
+ D = unicode:characters_to_binary(Txt, latin1, latin1),
+ {ok,Fd1} =
+ ?FILE_MODULE:open(Name, [write,read,binary,{encoding,unicode}]),
+ ok = ?FILE_MODULE:truncate(Fd1),
+ ok = ?FILE_MODULE:write(Fd1, Txt),
+ {ok,0} = ?FILE_MODULE:position(Fd1, bof),
+ {ok,D} = ?FILE_MODULE:read(Fd1, 129),
+ {ok,0} = ?FILE_MODULE:position(Fd1, bof),
+ {ok,D1} = ?FILE_MODULE:read(Fd1, 64),
+ {ok,Pos} = ?FILE_MODULE:position(Fd1, cur),
+ {ok,D2} = ?FILE_MODULE:pread(Fd1, {cur,0}, 65),
+ D = <<D1/binary, D2/binary>>,
+ {ok,D1} = ?FILE_MODULE:pread(Fd1, bof, 64),
+ {ok,Pos} = ?FILE_MODULE:position(Fd1, Pos),
+ {ok,D2} = ?FILE_MODULE:read(Fd1, 64),
+ ok = ?FILE_MODULE:close(Fd1),
+ %%
+ RawD = unicode:characters_to_binary(Txt, latin1, unicode),
+ {ok,RawD} = ?FILE_MODULE:read_file(Name),
+ %%
+ {ok,Fd2} = ?FILE_MODULE:open(Name, [read,{encoding,unicode}]),
+ {ok,Txt} = ?FILE_MODULE:read(Fd2, 129),
+ {Txt1,Txt2} = lists:split(64, Txt),
+ {ok,Txt2} = ?FILE_MODULE:pread(Fd2, Pos, 65),
+ {ok,0} = ?FILE_MODULE:position(Fd2, bof),
+ {ok,Txt1} = ?FILE_MODULE:read(Fd2, 64),
+ ok = ?FILE_MODULE:close(Fd2).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
altname(doc) ->
"Test the file:altname/1 function";
altname(suite) ->
diff --git a/lib/kernel/test/gen_tcp_api_SUITE.erl b/lib/kernel/test/gen_tcp_api_SUITE.erl
index a051d504b2..962471c20c 100644
--- a/lib/kernel/test/gen_tcp_api_SUITE.erl
+++ b/lib/kernel/test/gen_tcp_api_SUITE.erl
@@ -31,7 +31,7 @@
init_per_testcase/2, end_per_testcase/2,
t_connect_timeout/1, t_accept_timeout/1,
t_connect_bad/1,
- t_recv_timeout/1, t_recv_eof/1,
+ t_recv_timeout/1, t_recv_eof/1, t_recv_delim/1,
t_shutdown_write/1, t_shutdown_both/1, t_shutdown_error/1,
t_shutdown_async/1,
t_fdopen/1, t_fdconnect/1, t_implicit_inet6/1]).
@@ -48,7 +48,7 @@ all() ->
groups() ->
[{t_accept, [], [t_accept_timeout]},
{t_connect, [], [t_connect_timeout, t_connect_bad]},
- {t_recv, [], [t_recv_timeout, t_recv_eof]}].
+ {t_recv, [], [t_recv_timeout, t_recv_eof, t_recv_delim]}].
@@ -131,6 +131,21 @@ t_recv_eof(Config) when is_list(Config) ->
?line {error, closed} = gen_tcp:recv(Client, 0),
ok.
+t_recv_delim(doc) -> "Test using message delimiter $X";
+t_recv_delim(suite) -> [];
+t_recv_delim(Config) when is_list(Config) ->
+ {ok, L} = gen_tcp:listen(0, []),
+ {ok, Port} = inet:port(L),
+ Opts = [{active,false},{packet,line},{line_delimiter,$X}],
+ {ok, Client} = gen_tcp:connect(localhost, Port, Opts),
+ {ok, A} = gen_tcp:accept(L),
+ ok = gen_tcp:send(A, "abcXefgX"),
+ {ok, "abcX"} = gen_tcp:recv(Client, 0, 0),
+ {ok, "efgX"} = gen_tcp:recv(Client, 0, 0),
+ ok = gen_tcp:close(Client),
+ ok = gen_tcp:close(A),
+ ok.
+
%%% gen_tcp:shutdown/2
t_shutdown_write(Config) when is_list(Config) ->
diff --git a/lib/kernel/test/inet_sockopt_SUITE.erl b/lib/kernel/test/inet_sockopt_SUITE.erl
index 1262f36fae..cb522c8abe 100644
--- a/lib/kernel/test/inet_sockopt_SUITE.erl
+++ b/lib/kernel/test/inet_sockopt_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -52,6 +52,7 @@
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2,
simple/1, loop_all/1, simple_raw/1, simple_raw_getbin/1,
+ multiple_raw/1, multiple_raw_getbin/1,
doc_examples_raw/1,doc_examples_raw_getbin/1,
large_raw/1,large_raw_getbin/1,combined/1,combined_getbin/1,
ipv6_v6only_udp/1, ipv6_v6only_tcp/1, ipv6_v6only_sctp/1,
@@ -65,6 +66,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[simple, loop_all, simple_raw, simple_raw_getbin,
+ multiple_raw, multiple_raw_getbin,
doc_examples_raw, doc_examples_raw_getbin, large_raw,
large_raw_getbin, combined, combined_getbin,
ipv6_v6only_udp, ipv6_v6only_tcp, ipv6_v6only_sctp,
@@ -185,6 +187,84 @@ nintbin2int(<<Int:16/native>>) -> Int;
nintbin2int(<<Int:8/native>>) -> Int;
nintbin2int(<<>>) -> 0.
+
+
+multiple_raw(suite) -> [];
+multiple_raw(doc) -> "Test setopt/getopt of multiple raw options.";
+multiple_raw(Config) when is_list(Config) ->
+ do_multiple_raw(Config,false).
+multiple_raw_getbin(suite) -> [];
+multiple_raw_getbin(doc) -> "Test setopt/getopt of multiple raw options, "
+ "with binaries in getopt.";
+multiple_raw_getbin(Config) when is_list(Config) ->
+ do_multiple_raw(Config,true).
+
+do_multiple_raw(Config, Binary) ->
+ Port = start_helper(Config),
+ SolSocket = ask_helper(Port, ?C_GET_SOL_SOCKET),
+ SoKeepalive = ask_helper(Port, ?C_GET_SO_KEEPALIVE),
+ SoKeepaliveTrue = {raw,SolSocket,SoKeepalive,<<1:32/native>>},
+ SoKeepaliveFalse = {raw,SolSocket,SoKeepalive,<<0:32/native>>},
+ SoReuseaddr = ask_helper(Port, ?C_GET_SO_REUSEADDR),
+ SoReuseaddrTrue = {raw,SolSocket,SoReuseaddr,<<1:32/native>>},
+ SoReuseaddrFalse = {raw,SolSocket,SoReuseaddr,<<0:32/native>>},
+ {S1,S2} =
+ create_socketpair(
+ [SoReuseaddrFalse,SoKeepaliveTrue],
+ [SoKeepaliveFalse,SoReuseaddrTrue]),
+ {ok,[{reuseaddr,false},{keepalive,true}]} =
+ inet:getopts(S1, [reuseaddr,keepalive]),
+ {ok,
+ [{raw,SolSocket,SoReuseaddr,S1R1},
+ {raw,SolSocket,SoKeepalive,S1K1}]} =
+ inet:getopts(
+ S1,
+ [{raw,SolSocket,SoReuseaddr,binarify(4, Binary)},
+ {raw,SolSocket,SoKeepalive,binarify(4, Binary)}]),
+ true = nintbin2int(S1R1) =:= 0,
+ true = nintbin2int(S1K1) =/= 0,
+ {ok,[{keepalive,false},{reuseaddr,true}]} =
+ inet:getopts(S2, [keepalive,reuseaddr]),
+ {ok,
+ [{raw,SolSocket,SoKeepalive,S2K1},
+ {raw,SolSocket,SoReuseaddr,S2R1}]} =
+ inet:getopts(
+ S2,
+ [{raw,SolSocket,SoKeepalive,binarify(4, Binary)},
+ {raw,SolSocket,SoReuseaddr,binarify(4, Binary)}]),
+ true = nintbin2int(S2K1) =:= 0,
+ true = nintbin2int(S2R1) =/= 0,
+ %%
+ ok = inet:setopts(
+ S1, [SoReuseaddrTrue,SoKeepaliveFalse]),
+ ok = inet:setopts(
+ S2, [SoKeepaliveTrue,SoReuseaddrFalse]),
+ {ok,
+ [{raw,SolSocket,SoReuseaddr,S1R2},
+ {raw,SolSocket,SoKeepalive,S1K2}]} =
+ inet:getopts(
+ S1,
+ [{raw,SolSocket,SoReuseaddr,binarify(4, Binary)},
+ {raw,SolSocket,SoKeepalive,binarify(4, Binary)}]),
+ true = nintbin2int(S1R2) =/= 0,
+ true = nintbin2int(S1K2) =:= 0,
+ {ok,
+ [{raw,SolSocket,SoKeepalive,S2K2},
+ {raw,SolSocket,SoReuseaddr,S2R2}]} =
+ inet:getopts(
+ S2,
+ [{raw,SolSocket,SoKeepalive,binarify(4, Binary)},
+ {raw,SolSocket,SoReuseaddr,binarify(4, Binary)}]),
+ true = nintbin2int(S2K2) =/= 0,
+ true = nintbin2int(S2R2) =:= 0,
+ %%
+ gen_tcp:close(S1),
+ gen_tcp:close(S2),
+ stop_helper(Port),
+ ok.
+
+
+
doc_examples_raw(suite) -> [];
doc_examples_raw(doc) -> "Test that the example code from the documentation "
"works";
diff --git a/lib/mnesia/doc/src/notes.xml b/lib/mnesia/doc/src/notes.xml
index 3b35a9879b..8650e03a60 100644
--- a/lib/mnesia/doc/src/notes.xml
+++ b/lib/mnesia/doc/src/notes.xml
@@ -39,7 +39,23 @@
thus constitutes one section in this document. The title of each
section is the version number of Mnesia.</p>
- <section><title>Mnesia 4.13.1</title>
+ <section><title>Mnesia 4.13.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fixed a process and file descriptor leak in
+ mnesia:restore/2.</p>
+ <p>
+ Own Id: OTP-13025 Aux Id: seq12957 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Mnesia 4.13.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/mnesia/src/mnesia_bup.erl b/lib/mnesia/src/mnesia_bup.erl
index 0e653f2bc4..1f150ae38b 100644
--- a/lib/mnesia/src/mnesia_bup.erl
+++ b/lib/mnesia/src/mnesia_bup.erl
@@ -157,10 +157,11 @@ fallback_to_schema(Fname) ->
read_schema(Mod, Opaque) ->
R = #restore{bup_module = Mod, bup_data = Opaque},
try read_schema_section(R) of
- {_, {_Header, Schema, _}} -> Schema
+ {R2, {_Header, Schema, _}} ->
+ close_read(R2),
+ Schema
catch throw:{error,_} = Error ->
Error
- after close_read(R)
end.
%% Open backup media and extract schema
@@ -173,8 +174,13 @@ read_schema_section(R) ->
do_read_schema_section(R) ->
R2 = safe_apply(R, open_read, [R#restore.bup_data]),
- {R3, RawSchema} = safe_apply(R2, read, [R2#restore.bup_data]),
- do_read_schema_section(R3, verify_header(RawSchema), []).
+ try
+ {R3, RawSchema} = safe_apply(R2, read, [R2#restore.bup_data]),
+ do_read_schema_section(R3, verify_header(RawSchema), [])
+ catch T:E ->
+ close_read(R2),
+ erlang:raise(T,E,erlang:get_stacktrace())
+ end.
do_read_schema_section(R, {ok, B, C, []}, Acc) ->
case safe_apply(R, read, [R#restore.bup_data]) of
diff --git a/lib/mnesia/test/mnesia_evil_backup.erl b/lib/mnesia/test/mnesia_evil_backup.erl
index 89f2861661..e605fa7926 100644
--- a/lib/mnesia/test/mnesia_evil_backup.erl
+++ b/lib/mnesia/test/mnesia_evil_backup.erl
@@ -232,7 +232,13 @@ restore(Config, Op) ->
Res21 = [{Tab2, N, N+1} || N <- lists:seq(1, 11)],
Res31 = [[{Tab3, N, N+1}, {Tab3, N, N+44}] || N <- lists:seq(1, 10)],
-
+ Check = fun() ->
+ [disk_log:pid2name(X) ||
+ X <- processes(), Data <- [process_info(X, [current_function])],
+ Data =/= undefined,
+ element(1, element(2, lists:keyfind(current_function, 1, Data)))=:= disk_log]
+ end,
+ Before = Check(),
?match({atomic, [Tab1]}, Restore(File1, [{Op, [Tab1]},
{skip_tables, Tabs -- [Tab1]}])),
case Op of
@@ -319,6 +325,8 @@ restore(Config, Op) ->
end,
?match(ok, file:delete(File1)),
?match(ok, file:delete(File2)),
+ ?match([], Check() -- Before),
+
?verify_mnesia(Nodes, []).
diff --git a/lib/mnesia/vsn.mk b/lib/mnesia/vsn.mk
index e27045e16f..0fe5b5db8b 100644
--- a/lib/mnesia/vsn.mk
+++ b/lib/mnesia/vsn.mk
@@ -1 +1 @@
-MNESIA_VSN = 4.13.1
+MNESIA_VSN = 4.13.2
diff --git a/lib/observer/src/cdv_ets_cb.erl b/lib/observer/src/cdv_ets_cb.erl
index 9e6e72e08d..bac8b56fc3 100644
--- a/lib/observer/src/cdv_ets_cb.erl
+++ b/lib/observer/src/cdv_ets_cb.erl
@@ -97,7 +97,7 @@ info_fields() ->
[{"Id", id},
{"Name", name},
{"Slot", slot},
- {"Owner", owner},
+ {"Owner", pid},
{"Data Structure", data_type}
]},
{"Settings",
diff --git a/lib/observer/src/crashdump_viewer.erl b/lib/observer/src/crashdump_viewer.erl
index f2ce51b2af..b66b4d59c9 100644
--- a/lib/observer/src/crashdump_viewer.erl
+++ b/lib/observer/src/crashdump_viewer.erl
@@ -1572,7 +1572,7 @@ get_etsinfo(Fd,EtsTable = #ets_table{details=Ds},WS) ->
get_etsinfo(Fd,EtsTable#ets_table{details=Ds#{fixed=>Val}},WS);
"Type" ->
Val = val(Fd),
- get_etsinfo(Fd,EtsTable#ets_table{details=Ds#{data_type=>Val}},WS);
+ get_etsinfo(Fd,EtsTable#ets_table{data_type=Val},WS);
"Protection" ->
Val = val(Fd),
get_etsinfo(Fd,EtsTable#ets_table{details=Ds#{protection=>Val}},WS);
diff --git a/lib/observer/src/observer_sys_wx.erl b/lib/observer/src/observer_sys_wx.erl
index d6183d0249..dfd15380f2 100644
--- a/lib/observer/src/observer_sys_wx.erl
+++ b/lib/observer/src/observer_sys_wx.erl
@@ -83,11 +83,11 @@ update_syspage(#sys_wx_state{node = Node, fields=Fields, sizer=Sizer}) ->
info_fields() ->
Info = [{"System and Architecture",
[{"System Version", otp_release},
- {"Erts Version", version},
+ {"ERTS Version", version},
{"Compiled for", system_architecture},
{"Emulator Wordsize", wordsize_external},
{"Process Wordsize", wordsize_internal},
- {"Smp Support", smp_support},
+ {"SMP Support", smp_support},
{"Thread Support", threads},
{"Async thread pool size", thread_pool_size}
]},
@@ -106,7 +106,7 @@ info_fields() ->
{"Atoms", {bytes, atom}},
{"Binaries", {bytes, binary}},
{"Code", {bytes, code}},
- {"Ets", {bytes, ets}}
+ {"ETS", {bytes, ets}}
]},
{"Statistics", right,
[{"Up time", {time_ms, uptime}},
diff --git a/lib/os_mon/doc/src/cpu_sup.xml b/lib/os_mon/doc/src/cpu_sup.xml
index 524426ce86..51e1a4c9d6 100644
--- a/lib/os_mon/doc/src/cpu_sup.xml
+++ b/lib/os_mon/doc/src/cpu_sup.xml
@@ -63,7 +63,7 @@
measure.</p>
<p>A server which receives just enough requests to never become
idle will score a CPU utilization of 100%. If the server receives
- 50% more requests, it will still scores 100%. When the system load
+ 50% more requests, it will still score 100%. When the system load
is calculated with the percentage formula shown previously,
the load will increase from 80% to 87%.</p>
<p>The <c>avg1/0</c>, <c>avg5/0</c>, and <c>avg15/0</c> functions
diff --git a/lib/parsetools/doc/src/leex.xml b/lib/parsetools/doc/src/leex.xml
index 7ee0633dac..85680f58a6 100644
--- a/lib/parsetools/doc/src/leex.xml
+++ b/lib/parsetools/doc/src/leex.xml
@@ -47,7 +47,7 @@ Token = tuple()</code>
<v>LeexRet = {ok, Scannerfile}
| {ok, Scannerfile, Warnings}
| error
- | {error, Warnings, Errors}</v>
+ | {error, Errors, Warnings}</v>
<v>Scannerfile = filename()</v>
<v>Warnings = Errors = [{filename(), [ErrorInfo]}]</v>
<v>ErrorInfo = {ErrorLine, module(), Reason}</v>
diff --git a/lib/parsetools/doc/src/yecc.xml b/lib/parsetools/doc/src/yecc.xml
index 8c356099e7..87fdfcdaef 100644
--- a/lib/parsetools/doc/src/yecc.xml
+++ b/lib/parsetools/doc/src/yecc.xml
@@ -52,7 +52,7 @@
<v>Grammarfile = filename()</v>
<v>Options = Option | [Option]</v>
<v>Option =&nbsp;-&nbsp;see below&nbsp;-</v>
- <v>YeccRet = {ok, Parserfile} | {ok, Parserfile, Warnings} | error | {error, Warnings, Errors}</v>
+ <v>YeccRet = {ok, Parserfile} | {ok, Parserfile, Warnings} | error | {error, Errors, Warnings}</v>
<v>Parserfile = filename()</v>
<v>Warnings = Errors = [{filename(), [ErrorInfo]}]</v>
<v>ErrorInfo = {ErrorLine, module(), Reason}</v>
diff --git a/lib/public_key/doc/src/public_key.xml b/lib/public_key/doc/src/public_key.xml
index b247618efc..258e7cd1b9 100644
--- a/lib/public_key/doc/src/public_key.xml
+++ b/lib/public_key/doc/src/public_key.xml
@@ -299,6 +299,37 @@
</desc>
</func>
+ <func>
+ <name>dh_gex_group(MinSize, SuggestedSize, MaxSize, Groups) -> {ok, {Size,Group}} | {error,Error}</name>
+ <fsummary>Selects a group for Diffie-Hellman key exchange</fsummary>
+ <type>
+ <v>MinSize = positive_integer()</v>
+ <v>SuggestedSize = positive_integer()</v>
+ <v>MaxSize = positive_integer()</v>
+ <v>Groups = undefined | [{Size,[{G,P}]}]</v>
+ <v>Size = positive_integer()</v>
+ <v>Group = {G,P}</v>
+ <v>G = positive_integer()</v>
+ <v>P = positive_integer()</v>
+ </type>
+ <desc>
+ <p>Selects a group for Diffie-Hellman key exchange with the key size in the range <c>MinSize...MaxSize</c>
+ and as close to <c>SuggestedSize</c> as possible. If <c>Groups == undefined</c> a default set will be
+ used, otherwise the group is selected from <c>Groups</c>.</p>
+ <p>First a size, as close as possible to SuggestedSize, is selected. Then one group with that key size
+ is randomly selected from the specified set of groups. If no size within the limits of <c>MinSize</c>
+ and <c>MaxSize</c> is available, <c>{error,no_group_found}</c> is returned.</p>
+ <p>The default set of groups is listed in <c>lib/public_key/priv/moduli</c>. This file may be regenerated like this:</p>
+ <pre>
+ $> cd $ERL_TOP/lib/public_key/priv/
+ $> generate
+ ---- wait until all background jobs has finished. It may take several days !
+ $> cat moduli-* > moduli
+ $> cd ..; make
+ </pre>
+ </desc>
+ </func>
+
<func>
<name>encrypt_private(PlainText, Key) -> binary()</name>
<fsummary>Public-key encryption using the private key.</fsummary>
diff --git a/lib/public_key/priv/convert.escript b/lib/public_key/priv/convert.escript
new file mode 100755
index 0000000000..c7ea48c686
--- /dev/null
+++ b/lib/public_key/priv/convert.escript
@@ -0,0 +1,50 @@
+#!/usr/bin/env escript
+%% -*- erlang -*-
+
+main([InFile,OutFile]) ->
+ {ok,In} = file:open(InFile,read),
+ {ok,Out} = file:open(OutFile,write),
+ write_file(Out, read_file(In)),
+ file:close(In),
+ file:close(Out).
+
+write_file(D, {ok,Ms}) ->
+ io:format(D,'-define(dh_default_groups,~n ~p~n ).~n',[Ms]).
+
+one_line(Line, Acc) when is_binary(Line) ->
+ one_line(binary_to_list(Line), Acc);
+one_line("#"++_, Acc) ->
+ Acc;
+one_line(Line, Acc) when is_list(Line) ->
+ try
+ [_Time,_Type,_Tests,_Tries,Size,G,P] = string:tokens(Line," \r\n"),
+ [{list_to_integer(Size),
+ {list_to_integer(G), list_to_integer(P,16)}
+ } | Acc]
+ catch
+ _:_ -> io:format("*** skip line ~p",[Line]),
+ Acc
+ end.
+
+
+collect_per_size(L) ->
+ lists:foldr(
+ fun({Sz,GP}, [{Sz,GPs}|Acc]) -> [{Sz,[GP|GPs]}|Acc];
+ ({Sz,GP}, Acc) -> [{Sz,[GP]}|Acc]
+ end, [], lists:sort(L)).
+
+
+read_file(D) ->
+ read_file(D, []).
+
+read_file(D, Acc) ->
+ case io:get_line(D,"") of
+ {error,Error} ->
+ {error,Error};
+ eof ->
+ {ok, collect_per_size(Acc)};
+ Data ->
+ read_file(D, one_line(Data,Acc))
+ end.
+
+
diff --git a/lib/public_key/priv/generate b/lib/public_key/priv/generate
new file mode 100755
index 0000000000..fd185bfd52
--- /dev/null
+++ b/lib/public_key/priv/generate
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+# Generate ssh moduli files for the sizes in $moduli
+
+moduli="1024 1536 2048 3072 4096 6144 7168 8192"
+
+# In arg 1: size
+# Out: a file "moduli-$1" (for example: $1=2048 -> file "moduli.2048"
+function one_modulus() {
+ candidates=candidate-$1
+ ssh-keygen -G $candidates -b $1
+ ssh-keygen -T moduli-$1 -f $candidates
+ rm $candidates
+}
+
+
+# Generate in background
+for m in $moduli
+do
+ one_modulus $m &
+done
+
+# When all files moduli-* are generated, do:
+# cat moduli-* > moduli
+
diff --git a/lib/public_key/priv/moduli b/lib/public_key/priv/moduli
new file mode 100644
index 0000000000..446f4b8bf4
--- /dev/null
+++ b/lib/public_key/priv/moduli
@@ -0,0 +1,193 @@
+20151021104105 2 6 100 1023 5 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9D182EB7
+20151021104106 2 6 100 1023 5 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9D27F94F
+20151021104107 2 6 100 1023 5 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9D398EB7
+20151021104108 2 6 100 1023 5 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9D4B850F
+20151021104108 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9D4BF35B
+20151021104108 2 6 100 1023 5 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9D5031DF
+20151021104109 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9D5A4933
+20151021104110 2 6 100 1023 5 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9D6434BF
+20151021104111 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9D70676B
+20151021104111 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9D7235E3
+20151021104113 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9D963493
+20151021104114 2 6 100 1023 5 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9DAABAA7
+20151021104115 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9DC2E333
+20151021104116 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9DE16A7B
+20151021104117 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9DE2C5D3
+20151021104118 2 6 100 1023 5 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9DFF382F
+20151021104119 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9E158F13
+20151021104122 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9E4D9FEB
+20151021104123 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9E5C1FDB
+20151021104126 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9E9BB69B
+20151021104126 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9E9F62D3
+20151021104127 2 6 100 1023 5 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9EAA1C27
+20151021104128 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9EBC3313
+20151021104129 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9EC0733B
+20151021104130 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9EDB7AD3
+20151021104132 2 6 100 1023 5 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9EF56457
+20151021104132 2 6 100 1023 5 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9EF5A9CF
+20151021104133 2 6 100 1023 2 CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9F13CBB3
+20151021104218 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17BAAFFDF
+20151021104222 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17BCB6D93
+20151021104225 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17BE660BB
+20151021104226 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17BE676C3
+20151021104229 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17BF3E23B
+20151021104230 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17BF95757
+20151021104241 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17C59BEA7
+20151021104242 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17C6231B3
+20151021104244 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17C6879BF
+20151021104250 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17C9B678F
+20151021104252 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17CA66A4B
+20151021104253 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17CAB5543
+20151021104256 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17CB96933
+20151021104300 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17CDA8493
+20151021104308 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17D18C0C7
+20151021104310 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17D1DA5BF
+20151021104318 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17D4AB15F
+20151021104325 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17D7DE42F
+20151021104329 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17DA03D3B
+20151021104335 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17DD88BFF
+20151021104338 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17DE82B5F
+20151021104342 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17E07AF43
+20151021104343 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17E091E6F
+20151021104346 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17E28B90F
+20151021104347 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17E2A24F3
+20151021104401 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17EB074A7
+20151021104403 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17EC01B0F
+20151021104406 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17ED2186F
+20151021104407 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17ED55AAB
+20151021104411 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17EF58773
+20151021104414 2 6 100 1535 5 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17F0B3267
+20151021104423 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17F4DF61B
+20151021104434 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17F9BBB0B
+20151021104442 2 6 100 1535 2 CA8FA8EC4B042248C2F4430EE03A77F23899363D2D20972D2BA94033EF18619FD18260B0903BA8B8F385791338369E285FEF46A7FAFF6B02B6888E9810A9C02A3C6FF7F7F85C81205FBE5A387E8A8AA2F42782671F0F86E1C68D3718D03FD517AE44C99FDCD955EF4C762E6245FBA81A9AB492A107A1E72A0FE6A4FE179B00986C4614F66805F921AE05185D52679F3E262B2A0B41812638C7F0421AEDF59BED23860E3FB5A521A11EA2A1E4D483132C857ED7328B9852BB4437C0D17FDD6AFB
+20151021104350 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE5E381EF
+20151021104414 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE641C193
+20151021104422 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE659F523
+20151021104427 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE660E217
+20151021104438 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE6842F73
+20151021104441 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE689683B
+20151021104455 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE6C41E3B
+20151021104512 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE71E3BFF
+20151021104525 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE75C804F
+20151021104527 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE75DC48B
+20151021104535 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE7738983
+20151021104543 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE787027B
+20151021104610 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE8075A1B
+20151021104625 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE84F79B3
+20151021104628 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE859F617
+20151021104641 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE8948E2F
+20151021104646 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE8A571B3
+20151021104659 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE8CEA637
+20151021104705 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE8E590FF
+20151021104707 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE8E7943F
+20151021104731 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE95A975F
+20151021104741 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE985F923
+20151021104745 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE996E20B
+20151021104806 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE9FACFD7
+20151021104827 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BEA562C43
+20151021104839 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BEA8F25E3
+20151021104939 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BEBB1DA0B
+20151021104941 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BEBB86153
+20151021105002 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BEC1B8883
+20151021105019 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BEC71316F
+20151021105035 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BECB1D113
+20151021105042 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BECC3F3AB
+20151021105045 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BECCC109B
+20151021105101 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BED16353B
+20151021105106 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BED24854F
+20151021105109 2 6 100 2047 2 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BED2AE4B3
+20151021105116 2 6 100 2047 5 F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BED472CF7
+20151021104612 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E360CD0C3
+20151021104628 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3620FBE7
+20151021104701 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E36490F57
+20151021105014 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E377ACADB
+20151021105125 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E37E6DE07
+20151021105320 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E38C2387F
+20151021105649 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3A61E46B
+20151021105815 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3B0A6A4B
+20151021105848 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3B47D2C3
+20151021105948 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3BBBB953
+20151021110011 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3BE3B83B
+20151021110036 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3C0A3F1B
+20151021110201 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3CB1970F
+20151021110208 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3CB70C2B
+20151021110235 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3CE4E4DF
+20151021110424 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3DB68CD7
+20151021110525 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3E290717
+20151021110655 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3ED6DA83
+20151021110731 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3F14C563
+20151021110831 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E3F85477F
+20151021111418 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E420DE56B
+20151021111430 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E421DBA2F
+20151021111624 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E42F39A93
+20151021111916 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E44302363
+20151021112222 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E4585795F
+20151021112245 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E45A1DAFF
+20151021112339 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E4601674F
+20151021112437 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E46691977
+20151021112521 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E46AF3AD3
+20151021112532 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E46BCAE97
+20151021112708 2 6 100 3071 2 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E476520D3
+20151021112724 2 6 100 3071 5 EF9230A29EC5925FD89310E8F3002A60977FBF02543B6BE08667D8E970AD2468FF1B0892B7310073860FA7145250E6FE7A3902CBE70CC7DB0776031A0868780D47644BD8CD714E41B2AC2D744A51ECA4877FE3D2F496D8E6FC03F2F05B29284DA8682F9BCC93CC16846DF724BFAB53FAAC8492CFBFDCBA92A2F12C221E7FAFC4D8AF54156F649C44869592721FDC2AA65BEDC19DCD2CDD9E14F147F18F900A90B48D6D83197BBFE501FC4F19AE7C16D70DDCE3C757970D1CAFB474A0EA215E747E45C05E90935B721058DDF1BFE23C603A367E66C7E096547952663AFFC9A2B8F6292E12E81A6A61A47D032F7EF62DF4A9998D7B21A7917CC89BA68EB1D40BD9625087754618DC06AA486258DBEAA4B177A82ED0D9E2D9442C89D5354B04712F5159CE4EC6EDD608A5BB25700D24EA16E49A20931891C796B53227698132B5E9321905B81BBB7303BAE12DAB4C864A7B305FE9D6B196921F4890229171DE6DF09FA4D1067255F9D0F05F72DDAA6EB55E73F93EEA17B31A46CB33662E477B3317
+20151021105143 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156BA7321EB
+20151021105537 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156BB3AF34B
+20151021105816 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156BBC51883
+20151021110444 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156BD1A86C7
+20151021111341 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156BEDB7BBB
+20151021111438 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156BF0297AB
+20151021111935 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156BFF381FF
+20151021113820 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156C433A1BF
+20151021113833 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156C43B426B
+20151021113900 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156C45007D3
+20151021113921 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156C45D8C3B
+20151021113941 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156C4685D5F
+20151021114203 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156C4F95D97
+20151021114417 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156C57ED2FF
+20151021114645 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156C612EC33
+20151021114825 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156C67219F7
+20151021114922 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156C6A942BB
+20151021115945 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156C91E14DB
+20151021120515 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156CA5F5DB3
+20151021120715 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156CAD0D497
+20151021121027 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156CB8F9D6F
+20151021121241 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156CC0F677F
+20151021121518 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156CC9CC647
+20151021121600 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156CCC0ADC3
+20151021121734 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156CD1BC68B
+20151021121759 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156CD2A7DBF
+20151021122003 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156CDA3D323
+20151021122542 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156CED8D107
+20151021122856 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156CF8DFEE7
+20151021123548 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156D11CAC4F
+20151021123633 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156D1426BBB
+20151021124201 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156D2A62F0B
+20151021124454 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156D353F0FB
+20151021124620 2 6 100 4095 5 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156D3AE526F
+20151021125224 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156D535C4CB
+20151021130254 2 6 100 4095 2 C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156D7B5CA43
+20151021111833 2 6 100 6143 5 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B239959D5A7
+20151021112931 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B239A078C1B
+20151021123021 2 6 100 6143 5 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B239EC676DF
+20151021131523 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23A2B9FC6B
+20151021141029 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23A7BD762B
+20151021143421 2 6 100 6143 5 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23A9C3EFDF
+20151021144912 2 6 100 6143 5 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23AB1077AF
+20151021145200 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23AB49943B
+20151021145825 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23ABE06353
+20151021150910 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23ACDA0223
+20151021153131 2 6 100 6143 5 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23AE91738F
+20151021154038 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23AF40D013
+20151021154300 2 6 100 6143 5 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23AF75AD97
+20151021155008 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23B01C9553
+20151021162240 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23B319431B
+20151021162649 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23B35A3D2B
+20151021163640 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23B439E263
+20151021171004 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23B748B983
+20151021172144 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23B8609B5B
+20151021173002 2 6 100 6143 5 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23B9021E9F
+20151021182612 2 6 100 6143 2 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23BE0C1EDB
+20151021190053 2 6 100 6143 5 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23C120FF97
+20151021192934 2 6 100 6143 5 FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23C3BEB637
+20151021113847 2 6 100 8191 2 DC61EF13E4F3FC10CC946EEABC33F83EFCB35E0F47E4EC25C1CCBB2C7B502B2EFB0691AA231C8476DD51BA73204E6EA10B1A970FE2CF14AF01E72E1AEA87519A91D00D1499189F94A6CDA9E29C05F11F17FE74A4919A710A2787E180744465DF81C62AA65662FDA46FA6175E8A31E5B29E66DED6701C8FC4217E91D733FE94380F046680967D4CEA7BAC8F3916CDF96AA2C474FAD9650F48403FD0B5B756D34667D36A07767FA33027AE55484D0F701C3CA16632F413A14E4B8645AFAF15B78978C19A7661EDC569BEC72394B1204B166A48FCD5F56BE29840C7794CA6D3440356F15858CDCA9B429C7EA92E17242893FDC8C9C63841A382C32F20CFAB121B4BCAFD7BF9EF07FBF7CDFFECA0CEF3A49C3E2B24FA836F3318435255655E1B281071F62D5E4CD63361299B7828F72936E3FEA9E8044562A6F6ADD5321187C3101E4669C6271598FE1A866C93FE2870A4CEB9254BA32A4719E439317EA42200A335B5CFFA7946A7D0F1BD1A69AA11288B73C71C80B77FE3707CB077DDDEA5CA36A449FAB230C9625A0B12F8275D3FF82F5DA380E7A3F11B6F155FE7E91AC960BD95D9B13F7423AB9B15CC3C4DC34EF296033F009468EA16A721AD659F56C18516025050749ABF05E6D3EBD9778142A530979291F46DAA399A86B7BCDF09CC3E6EEF101419762A306DB45AEFC96C64E83F28338D55905F6A387E0F515E580C3A9B35330E21C32198CDEE3AFB355967A098F635FCA7C49CB4E1E82464B2B390EF1F259E40B9A06235C0273F76284FE6BD534EF3AF7CB01A4A5252B8B94CADC2850B2E56D53F9A31D7C029DF967D0A30C05BC64E119BED6076818FABC8CDD93F3255693E14EFC1A740A5D63A5E847FFE87BAB1DDE0506E1762EA61EFA9F9756151ECCCADD91B98A961A901A2D8B01ABDDD29EC804E8C8D28214BBA26048F924CA66316696E51A49D02FF034D20E44914B1115339CAD3819E0CB1640F0084886FEDDE5E28C29DC48ED30A8C3D789734338F5A9DF42584326E536FD1CF30BC85B8DCBD6120D127C98FE4B3614074F13C2CA4854E6D794156C185C40EB3DA7619CE96ADAF0941BD5499848B034C2B11DFECC0BDFA81C594241F759EF53FC7CDE7F2DE4F23CF81A5A0B7D62E31DABB9198D40307F7824DD130B7D1B80E9B6D322FEEDB5ACE34944F0BFB7D016762A9B2E173BFDD69303766AFBAB45FAB75D05430B4A3515858C4B7F04E23414E4AD03842CB0A20D8FF4B59B7C852BA9A5BE982A8ADA5CB70C36CE2A4D2C31A7015C9F3275E43D192C1B2924424088907A057DA7F2D32A2149922AB2E33F2147D637A3508911CB3FEA5E1AAB4525BACF27B6DD7A3E0AFA978FC3A39DE8882FB22688C3CCC92B6E69ACB0BBF575AB3368E51A2F6A20C414C6F146727CC0045F29061E695D29F7C030CE6929EB3AD11A5CBD0CDEE37347869A3
+20151021133636 2 6 100 8191 2 DC61EF13E4F3FC10CC946EEABC33F83EFCB35E0F47E4EC25C1CCBB2C7B502B2EFB0691AA231C8476DD51BA73204E6EA10B1A970FE2CF14AF01E72E1AEA87519A91D00D1499189F94A6CDA9E29C05F11F17FE74A4919A710A2787E180744465DF81C62AA65662FDA46FA6175E8A31E5B29E66DED6701C8FC4217E91D733FE94380F046680967D4CEA7BAC8F3916CDF96AA2C474FAD9650F48403FD0B5B756D34667D36A07767FA33027AE55484D0F701C3CA16632F413A14E4B8645AFAF15B78978C19A7661EDC569BEC72394B1204B166A48FCD5F56BE29840C7794CA6D3440356F15858CDCA9B429C7EA92E17242893FDC8C9C63841A382C32F20CFAB121B4BCAFD7BF9EF07FBF7CDFFECA0CEF3A49C3E2B24FA836F3318435255655E1B281071F62D5E4CD63361299B7828F72936E3FEA9E8044562A6F6ADD5321187C3101E4669C6271598FE1A866C93FE2870A4CEB9254BA32A4719E439317EA42200A335B5CFFA7946A7D0F1BD1A69AA11288B73C71C80B77FE3707CB077DDDEA5CA36A449FAB230C9625A0B12F8275D3FF82F5DA380E7A3F11B6F155FE7E91AC960BD95D9B13F7423AB9B15CC3C4DC34EF296033F009468EA16A721AD659F56C18516025050749ABF05E6D3EBD9778142A530979291F46DAA399A86B7BCDF09CC3E6EEF101419762A306DB45AEFC96C64E83F28338D55905F6A387E0F515E580C3A9B35330E21C32198CDEE3AFB355967A098F635FCA7C49CB4E1E82464B2B390EF1F259E40B9A06235C0273F76284FE6BD534EF3AF7CB01A4A5252B8B94CADC2850B2E56D53F9A31D7C029DF967D0A30C05BC64E119BED6076818FABC8CDD93F3255693E14EFC1A740A5D63A5E847FFE87BAB1DDE0506E1762EA61EFA9F9756151ECCCADD91B98A961A901A2D8B01ABDDD29EC804E8C8D28214BBA26048F924CA66316696E51A49D02FF034D20E44914B1115339CAD3819E0CB1640F0084886FEDDE5E28C29DC48ED30A8C3D789734338F5A9DF42584326E536FD1CF30BC85B8DCBD6120D127C98FE4B3614074F13C2CA4854E6D794156C185C40EB3DA7619CE96ADAF0941BD5499848B034C2B11DFECC0BDFA81C594241F759EF53FC7CDE7F2DE4F23CF81A5A0B7D62E31DABB9198D40307F7824DD130B7D1B80E9B6D322FEEDB5ACE34944F0BFB7D016762A9B2E173BFDD69303766AFBAB45FAB75D05430B4A3515858C4B7F04E23414E4AD03842CB0A20D8FF4B59B7C852BA9A5BE982A8ADA5CB70C36CE2A4D2C31A7015C9F3275E43D192C1B2924424088907A057DA7F2D32A2149922AB2E33F2147D637A3508911CB3FEA5E1AAB4525BACF27B6DD7A3E0AFA978FC3A39DE8882FB22688C3CCC92B6E69ACB0BBF575AB3368E51A2F6A20C414C6F146727CC0045F29061E695D29F7C030CE6929EB3AD11A5CBD0CDEE373914ECA3
+20151021140108 2 6 100 8191 5 DC61EF13E4F3FC10CC946EEABC33F83EFCB35E0F47E4EC25C1CCBB2C7B502B2EFB0691AA231C8476DD51BA73204E6EA10B1A970FE2CF14AF01E72E1AEA87519A91D00D1499189F94A6CDA9E29C05F11F17FE74A4919A710A2787E180744465DF81C62AA65662FDA46FA6175E8A31E5B29E66DED6701C8FC4217E91D733FE94380F046680967D4CEA7BAC8F3916CDF96AA2C474FAD9650F48403FD0B5B756D34667D36A07767FA33027AE55484D0F701C3CA16632F413A14E4B8645AFAF15B78978C19A7661EDC569BEC72394B1204B166A48FCD5F56BE29840C7794CA6D3440356F15858CDCA9B429C7EA92E17242893FDC8C9C63841A382C32F20CFAB121B4BCAFD7BF9EF07FBF7CDFFECA0CEF3A49C3E2B24FA836F3318435255655E1B281071F62D5E4CD63361299B7828F72936E3FEA9E8044562A6F6ADD5321187C3101E4669C6271598FE1A866C93FE2870A4CEB9254BA32A4719E439317EA42200A335B5CFFA7946A7D0F1BD1A69AA11288B73C71C80B77FE3707CB077DDDEA5CA36A449FAB230C9625A0B12F8275D3FF82F5DA380E7A3F11B6F155FE7E91AC960BD95D9B13F7423AB9B15CC3C4DC34EF296033F009468EA16A721AD659F56C18516025050749ABF05E6D3EBD9778142A530979291F46DAA399A86B7BCDF09CC3E6EEF101419762A306DB45AEFC96C64E83F28338D55905F6A387E0F515E580C3A9B35330E21C32198CDEE3AFB355967A098F635FCA7C49CB4E1E82464B2B390EF1F259E40B9A06235C0273F76284FE6BD534EF3AF7CB01A4A5252B8B94CADC2850B2E56D53F9A31D7C029DF967D0A30C05BC64E119BED6076818FABC8CDD93F3255693E14EFC1A740A5D63A5E847FFE87BAB1DDE0506E1762EA61EFA9F9756151ECCCADD91B98A961A901A2D8B01ABDDD29EC804E8C8D28214BBA26048F924CA66316696E51A49D02FF034D20E44914B1115339CAD3819E0CB1640F0084886FEDDE5E28C29DC48ED30A8C3D789734338F5A9DF42584326E536FD1CF30BC85B8DCBD6120D127C98FE4B3614074F13C2CA4854E6D794156C185C40EB3DA7619CE96ADAF0941BD5499848B034C2B11DFECC0BDFA81C594241F759EF53FC7CDE7F2DE4F23CF81A5A0B7D62E31DABB9198D40307F7824DD130B7D1B80E9B6D322FEEDB5ACE34944F0BFB7D016762A9B2E173BFDD69303766AFBAB45FAB75D05430B4A3515858C4B7F04E23414E4AD03842CB0A20D8FF4B59B7C852BA9A5BE982A8ADA5CB70C36CE2A4D2C31A7015C9F3275E43D192C1B2924424088907A057DA7F2D32A2149922AB2E33F2147D637A3508911CB3FEA5E1AAB4525BACF27B6DD7A3E0AFA978FC3A39DE8882FB22688C3CCC92B6E69ACB0BBF575AB3368E51A2F6A20C414C6F146727CC0045F29061E695D29F7C030CE6929EB3AD11A5CBD0CDEE373A17959F
diff --git a/lib/public_key/src/Makefile b/lib/public_key/src/Makefile
index 621cedadcd..786f244f85 100644
--- a/lib/public_key/src/Makefile
+++ b/lib/public_key/src/Makefile
@@ -50,7 +50,7 @@ MODULES = \
HRL_FILES = $(INCLUDE)/public_key.hrl
-INTERNAL_HRL_FILES =
+INTERNAL_HRL_FILES = pubkey_moduli.hrl
ERL_FILES = $(MODULES:%=%.erl)
@@ -86,6 +86,11 @@ ERL_COMPILE_FLAGS += $(PUB_KEY_ERL_FLAGS) \
debug opt: $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) $(HRL_FILES)
+$(EBIN)/pubkey_ssh.$(EMULATOR): pubkey_moduli.hrl
+
+pubkey_moduli.hrl: ../priv/moduli
+ escript ../priv/convert.escript $< $@
+
clean:
rm -f $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET)
rm -f core
diff --git a/lib/public_key/src/pubkey_moduli.hrl b/lib/public_key/src/pubkey_moduli.hrl
new file mode 100644
index 0000000000..e4beecc12a
--- /dev/null
+++ b/lib/public_key/src/pubkey_moduli.hrl
@@ -0,0 +1,395 @@
+-define(dh_default_groups,
+ [{1023,
+ [{2,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840821904219},
+ {2,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840822843699},
+ {2,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840824293227},
+ {2,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840824411619},
+ {2,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840826770579},
+ {2,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840829698867},
+ {2,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840831699579},
+ {2,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840831788499},
+ {2,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840835116819},
+ {2,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840838791147},
+ {2,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840839741403},
+ {2,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840843908763},
+ {2,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840844149459},
+ {2,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840846037779},
+ {2,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840846316347},
+ {2,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840848087763},
+ {2,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840851778483},
+ {5,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840818511543},
+ {5,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840819546447},
+ {5,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840820698807},
+ {5,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840821875983},
+ {5,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840822182367},
+ {5,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840823493823},
+ {5,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840828115623},
+ {5,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840833652783},
+ {5,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840844852263},
+ {5,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840849785943},
+ {5,
+ 145775197456487668749161655795234893413202527697104473695831577761647854852108768430387864189919819365658842431613137268371680467610991509847733954019734973873643148023271112285230508466838215139872267855676600969961870846186166681894080056503367717025795010132090088184706677576861830882312093982840849803727}]},
+ {1535,
+ [{2,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891121581459},
+ {2,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891123347643},
+ {2,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891123353283},
+ {2,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891124232763},
+ {2,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891131462067},
+ {2,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891135933003},
+ {2,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891136255299},
+ {2,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891137177907},
+ {2,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891139347603},
+ {2,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891152305467},
+ {2,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891159084867},
+ {2,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891161343219},
+ {2,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891172563627},
+ {2,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891174672243},
+ {2,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891180467739},
+ {2,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891185564427},
+ {2,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891189869307},
+ {5,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891119456223},
+ {5,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891124590423},
+ {5,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891130908327},
+ {5,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891131873727},
+ {5,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891135211407},
+ {5,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891143426247},
+ {5,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891143747007},
+ {5,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891146699103},
+ {5,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891150054447},
+ {5,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891155995647},
+ {5,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891157019487},
+ {5,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891159178863},
+ {5,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891161250063},
+ {5,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891170145447},
+ {5,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891171171087},
+ {5,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891172350063},
+ {5,
+ 1907170736023124811736411458785042542925115668082539810200109305735683587893811083066646767750558659131374424885053147631157680241645866111036024727506041045267916677127337026486727329498794109266986160904622741269220273376068857149157352410555723198695322554668593076155279812272319710239217381596287633268687131658367273821116604691564975255858007378139664922713363377579390448226123206847441877045380881530736814422784905045609836858066127174749699891176092263}]},
+ {2047,
+ [{2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127673160083},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127674746147},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127677513587},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127677855803},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127681703483},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127691773067},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127693199747},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127694475899},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127702886939},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127707613619},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127713247667},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127727962403},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127729070603},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127741606979},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127745340899},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127764392459},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127764820307},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127771318403},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127781167379},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127782355883},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127782887579},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127787746619},
+ {2,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127789102259},
+ {5,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127666983407},
+ {5,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127675200023},
+ {5,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127687609343},
+ {5,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127691690063},
+ {5,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127708300823},
+ {5,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127712140847},
+ {5,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127715948087},
+ {5,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127717449983},
+ {5,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127717581887},
+ {5,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127725119327},
+ {5,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127735619543},
+ {5,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127776932207},
+ {5,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127788684623},
+ {5,
+ 31232761562882516094884070611630050950237146275890833609093891047897843797997552232718257871173954549538774751038496595396925563385404720255716837933677220581287383288516914691172469244029925326629700819138694871356510866851914242889526314963319760427147424913618697965734069376105953045113129440174661252504850768513753786509136822851125652952326518541742866669959696723616260017966174003560432807987735744247115916855658422620715728754034819398357826714599804921184478793666674492366199879602022266103884178166633701002913239714329019644011011091883511432521179210877235289776043130356321939953141370575127790955767}]},
+ {3071,
+ [{2,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199506260163},
+ {2,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199530244827},
+ {2,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199578944619},
+ {2,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199589988939},
+ {2,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199594013379},
+ {2,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199601609043},
+ {2,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199604230203},
+ {2,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199606755099},
+ {2,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199618079787},
+ {2,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199653718659},
+ {2,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199657776483},
+ {2,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199707657579},
+ {2,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199722711699},
+ {2,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199743456099},
+ {2,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199785339603},
+ {2,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199797260499},
+ {5,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199507581927},
+ {5,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199510208343},
+ {5,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199537327623},
+ {5,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199551703167},
+ {5,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199617722127},
+ {5,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199621084383},
+ {5,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199634824407},
+ {5,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199642326807},
+ {5,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199665149823},
+ {5,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199708695087},
+ {5,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199765825887},
+ {5,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199767685887},
+ {5,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199773947727},
+ {5,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199780743543},
+ {5,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199786221207},
+ {5,
+ 5436771231278176260464207572014249237436628003751950430443256176419437109283409279325055179822137303309588375578210454771206339795059466564724705882357808020147943371370952376862400031959913112146741735409727429098983569717815170493079969998376532776669142518838712137720503257349411673630616846814922326748760377074686267404617800626017790893617723327526800481821613452766006640701474488365374399399907853664959711238779541522615905232982411502798277910194792404145749492189947629774082615011566526902465295439792626194825661087612449173617161800099003448528272624654517679417559537997833575275437573873218238645979906696208545848771753496507149936213366692226040978858284500769836334638725943292501159483097128028975365907974867494222456802766986272374880246378778326493320216426233834650917807239104899121676291950634433590565261175675893968032464664959347175273331523630462401583678513811133107339834284448366199798706967}]},
+ {4095,
+ [{2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328641094123},
+ {2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328654189387},
+ {2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328663242883},
+ {2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328715041723},
+ {2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328717604779},
+ {2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328805204587},
+ {2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328806565843},
+ {2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328807451707},
+ {2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328836115507},
+ {2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328845968059},
+ {2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328887178459},
+ {2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328908234163},
+ {2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328948166083},
+ {2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328954136203},
+ {2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328963052323},
+ {2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024329023777723},
+ {2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024329047093003},
+ {2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024329058480379},
+ {2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024329090057419},
+ {2,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024329132001859},
+ {5,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328685618887},
+ {5,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328733393407},
+ {5,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328804704703},
+ {5,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328808160607},
+ {5,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328817663383},
+ {5,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328826409727},
+ {5,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328842353143},
+ {5,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328915670167},
+ {5,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328928173423},
+ {5,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328936548223},
+ {5,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328945813063},
+ {5,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328955100607},
+ {5,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328983302407},
+ {5,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024328995176167},
+ {5,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024329021303887},
+ {5,
+ 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024329064403567}]},
+ {6143,
+ [{2,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255204878912539},
+ {2,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205024824427},
+ {2,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205108938283},
+ {2,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205168452667},
+ {2,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205178336083},
+ {2,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205194695203},
+ {2,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205234987027},
+ {2,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205249389907},
+ {2,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205299503899},
+ {2,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205303762219},
+ {2,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205318419043},
+ {2,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205369723267},
+ {2,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205388065627},
+ {2,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205483192027},
+ {5,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255204867528103},
+ {5,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255204958533343},
+ {5,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205142917087},
+ {5,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205164709807},
+ {5,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205223494543},
+ {5,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205238451607},
+ {5,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205398650527},
+ {5,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205534891927},
+ {5,
+ 33437583241773200736998306224385528803766612787425393970240448895665693432965804079937003812356294308539203151272072972277375104789647202046031197278230667153631409232762771720006125219920706956123725594446372009116332714804701277193618508630316668034287884909832516041233220775901611206642660372233947390606274902141826658826141733970432621047550484555565916575805826057191334266474445170275718783081560666447409216535181360674632456526571101451968821169633558969474691730611539132286052022835952896201555123627380799302110683026529909820807288537680562845821392314996440379370705723540964585839337801927778062852215686895319024767481042895138442976855163068747380166531199300232551267526017036164413600564815784019785977970949693984340717238729942561030179919817420833573731051545887599723662578148436252999801801184946912344055039296858955344284666098693644023712197329293309829111260795234865981993976990661827891668714260305572784933890804266304027991177237933956448650403587826112875783795940606993503972135788451776288043780405914188427059396997568948159052168252857826777287128664074216861215783789478700515409553239441062015685435438583826256963919799489374587339208720501219592669600392307850331252795823771544828155101319705650241344450112892458324477254048023146580514471110326358407290566960742849415447980366665653434043627949138890739742819993505594819520369919793246819138042045825632762369551350013672323292476735446079801969860131404566127284762569608997426987715169971180098109830736446816299192620247945607493820377482306775990092969824710142555863464957556013639252952281232650874597306442373552573476420189325342908686488322042941568296395918651660523487617863085692837653979094810691084612642444899086069505869007138363971482049103042831515780578797971864682660432869186605371682266108433970938695484953644215301255205578782263}]},
+ {8191,
+ [{2,
+ 938991641448887958659860711024139841840373070892857314837350127283993531354468803860225599873491818506054401963417489724433963777795696041544477412963807403300832656512849715212168703537706302853428971073305304224008208665300028518281475780493382070018498379488833882168221853720545474425047940975435356027594634176129712250061883354535324982741923143373986406603949677080360223989497048086447454366625852264609369284140522273595340921542019308988041920995057608746115976973659704188342646944998285431473302075966106608530908140377765357842459486869512398523240695806503711124427370056638597159539032058092571318621818616699716647464298881944582194013388150591419588422793657857267906072494480713650129757905856314362270238621284311461743652666256381611674809565144562467655186251867429369336740018623120262859220669942243740953355278814789244133782043857008487446798345197999966787658254507117076710455244182794239065255535191498857182705725985655379455993825553257619502588673174759329362518373537685585117537004065137523099625519490356398330532110250061129576411957409731201790054967354938147031111368166150009421041430118523249245874882140875551501824754839814848195806919150975076831338899823813371473496616326897054534509843640848822974414341233324307292275820287661792887177523563243279340678632061899626115667671047274195425889742755327012266774742591229119994211561599405909368902449776535330722644597809098307346948888547387746758109319767106289995123864514603259977184876246412673772519845777697496361969177346826245108557971745523905955370437517039028495325595180934057507336816903052766590118820327869839202378278312909402987412274414739124292902164277499512007446916921747463997761815820546816791093343347969046462095463611789365326128045878985464594892022442144072282717352526544915821855299863549245012366815543939396712522935345161074836470227392836664033041735035699615758782980717425699108612161567924880267630103820215946940542401779795959759774248414245436455737309858403883625882609790799283421857564831362243562647683958370353023343221966296655134926556805244483888769178095889844741765908328185625663202823312608064683035802724504683124396450612201783060593269112984065572954508643688374585823409316161924407053191442613988480926581084892323451281350937867676271858142177713557970909833234285545964647506859724327822527317869059455132036566677244407755994867168874825546516623190701762311472512591018622127119388239627852234680483324150442403},
+ {2,
+ 938991641448887958659860711024139841840373070892857314837350127283993531354468803860225599873491818506054401963417489724433963777795696041544477412963807403300832656512849715212168703537706302853428971073305304224008208665300028518281475780493382070018498379488833882168221853720545474425047940975435356027594634176129712250061883354535324982741923143373986406603949677080360223989497048086447454366625852264609369284140522273595340921542019308988041920995057608746115976973659704188342646944998285431473302075966106608530908140377765357842459486869512398523240695806503711124427370056638597159539032058092571318621818616699716647464298881944582194013388150591419588422793657857267906072494480713650129757905856314362270238621284311461743652666256381611674809565144562467655186251867429369336740018623120262859220669942243740953355278814789244133782043857008487446798345197999966787658254507117076710455244182794239065255535191498857182705725985655379455993825553257619502588673174759329362518373537685585117537004065137523099625519490356398330532110250061129576411957409731201790054967354938147031111368166150009421041430118523249245874882140875551501824754839814848195806919150975076831338899823813371473496616326897054534509843640848822974414341233324307292275820287661792887177523563243279340678632061899626115667671047274195425889742755327012266774742591229119994211561599405909368902449776535330722644597809098307346948888547387746758109319767106289995123864514603259977184876246412673772519845777697496361969177346826245108557971745523905955370437517039028495325595180934057507336816903052766590118820327869839202378278312909402987412274414739124292902164277499512007446916921747463997761815820546816791093343347969046462095463611789365326128045878985464594892022442144072282717352526544915821855299863549245012366815543939396712522935345161074836470227392836664033041735035699615758782980717425699108612161567924880267630103820215946940542401779795959759774248414245436455737309858403883625882609790799283421857564831362243562647683958370353023343221966296655134926556805244483888769178095889844741765908328185625663202823312608064683035802724504683124396450612201783060593269112984065572954508643688374585823409316161924407053191442613988480926581084892323451281350937867676271858142177713557970909833234285545964647506859724327822527317869059455132036566677244407755994867168874825546516623190701762311472512591018622127119388239627852234680483324227808419},
+ {5,
+ 938991641448887958659860711024139841840373070892857314837350127283993531354468803860225599873491818506054401963417489724433963777795696041544477412963807403300832656512849715212168703537706302853428971073305304224008208665300028518281475780493382070018498379488833882168221853720545474425047940975435356027594634176129712250061883354535324982741923143373986406603949677080360223989497048086447454366625852264609369284140522273595340921542019308988041920995057608746115976973659704188342646944998285431473302075966106608530908140377765357842459486869512398523240695806503711124427370056638597159539032058092571318621818616699716647464298881944582194013388150591419588422793657857267906072494480713650129757905856314362270238621284311461743652666256381611674809565144562467655186251867429369336740018623120262859220669942243740953355278814789244133782043857008487446798345197999966787658254507117076710455244182794239065255535191498857182705725985655379455993825553257619502588673174759329362518373537685585117537004065137523099625519490356398330532110250061129576411957409731201790054967354938147031111368166150009421041430118523249245874882140875551501824754839814848195806919150975076831338899823813371473496616326897054534509843640848822974414341233324307292275820287661792887177523563243279340678632061899626115667671047274195425889742755327012266774742591229119994211561599405909368902449776535330722644597809098307346948888547387746758109319767106289995123864514603259977184876246412673772519845777697496361969177346826245108557971745523905955370437517039028495325595180934057507336816903052766590118820327869839202378278312909402987412274414739124292902164277499512007446916921747463997761815820546816791093343347969046462095463611789365326128045878985464594892022442144072282717352526544915821855299863549245012366815543939396712522935345161074836470227392836664033041735035699615758782980717425699108612161567924880267630103820215946940542401779795959759774248414245436455737309858403883625882609790799283421857564831362243562647683958370353023343221966296655134926556805244483888769178095889844741765908328185625663202823312608064683035802724504683124396450612201783060593269112984065572954508643688374585823409316161924407053191442613988480926581084892323451281350937867676271858142177713557970909833234285545964647506859724327822527317869059455132036566677244407755994867168874825546516623190701762311472512591018622127119388239627852234680483324244759967}]}]
+ ).
diff --git a/lib/public_key/src/pubkey_ssh.erl b/lib/public_key/src/pubkey_ssh.erl
index 7680d0ce59..9b281aa482 100644
--- a/lib/public_key/src/pubkey_ssh.erl
+++ b/lib/public_key/src/pubkey_ssh.erl
@@ -20,10 +20,17 @@
-module(pubkey_ssh).
-include("public_key.hrl").
+-include("pubkey_moduli.hrl").
--export([decode/2, encode/2]).
+
+-export([decode/2, encode/2,
+ dh_gex_group/4,
+ dh_gex_group_sizes/0
+ ]).
-define(UINT32(X), X:32/unsigned-big-integer).
+-define(STRING(X), ?UINT32((size(X))), (X)/binary).
+
%% Max encoded line length is 72, but conformance examples use 68
%% Comment from rfc 4716: "The following are some examples of public
%% key files that are compliant (note that the examples all wrap
@@ -31,13 +38,16 @@
%% are still compliant.)" So we choose to use 68 also.
-define(ENCODED_LINE_LENGTH, 68).
+
%%====================================================================
%% Internal application API
%%====================================================================
%%--------------------------------------------------------------------
-spec decode(binary(), public_key | public_key:ssh_file()) ->
- [{public_key:public_key(), Attributes::list()}].
+ [{public_key:public_key(), Attributes::list()}]
+ ; (binary(), ssh2_pubkey) -> public_key:public_key()
+ .
%%
%% Description: Decodes a ssh file-binary.
%%--------------------------------------------------------------------
@@ -50,21 +60,71 @@ decode(Bin, public_key)->
end;
decode(Bin, rfc4716_public_key) ->
rfc4716_decode(Bin);
+decode(Bin, ssh2_pubkey) ->
+ ssh2_pubkey_decode(Bin);
decode(Bin, Type) ->
openssh_decode(Bin, Type).
%%--------------------------------------------------------------------
-spec encode([{public_key:public_key(), Attributes::list()}], public_key:ssh_file()) ->
- binary().
+ binary()
+ ; (public_key:public_key(), ssh2_pubkey) -> binary()
+ .
%%
%% Description: Encodes a list of ssh file entries.
%%--------------------------------------------------------------------
+encode(Bin, ssh2_pubkey) ->
+ ssh2_pubkey_encode(Bin);
encode(Entries, Type) ->
iolist_to_binary(lists:map(fun({Key, Attributes}) ->
do_encode(Type, Key, Attributes)
end, Entries)).
%%--------------------------------------------------------------------
+-spec dh_gex_group(integer(), integer(), integer(),
+ undefined | [{integer(),[{integer(),integer()}]}]) ->
+ {ok,{integer(),{integer(),integer()}}} | {error,any()} .
+%%
+%% Description: Returns Generator and Modulus given MinSize, WantedSize
+%% and MaxSize
+%%--------------------------------------------------------------------
+dh_gex_group(Min, N, Max, undefined) ->
+ dh_gex_group(Min, N, Max, ?dh_default_groups);
+dh_gex_group(Min, N, Max, Groups) ->
+ case select_by_keylen(Min-10, N, Max+10, Groups) of
+ {ok,{Sz,GPs}} ->
+ {ok, {Sz,lists:nth(crypto:rand_uniform(1, 1+length(GPs)), GPs)}};
+ Other ->
+ Other
+ end.
+
+dh_gex_group_sizes()->
+ [KeyLen || {KeyLen,_} <- ?dh_default_groups].
+
+%% Select the one with K closest to N but within the interval [Min,Max]
+
+select_by_keylen(Min, N, Max, [{K,_Gs}|Groups]) when K < Min ->
+ select_by_keylen(Min, N, Max, Groups);
+select_by_keylen(Min, N, Max, [{K,Gs}|Groups]) when K =< Max ->
+ {ok, select_by_keylen(Min, N, Max, Groups, {K,Gs})};
+select_by_keylen(_Min, _N, _Max, _) ->
+ {error,no_group_found}.
+
+select_by_keylen(_Min, _N, Max, [{K,_Gs}|_Groups], GPprev) when K > Max ->
+ GPprev;
+select_by_keylen(Min, N, Max, [{K,Gs}|Groups], {Kprev,GsPrev}) ->
+ if
+ N == K -> {K,Gs};
+ N > K -> select_by_keylen(Min, N, Max, Groups, {K,Gs});
+ N < K, (K-N) < (N-Kprev) -> {K,Gs};
+ N < K -> {Kprev,GsPrev}
+ end;
+select_by_keylen(_Min, _N, _Max, [],GPprev) ->
+ %% is between Min and Max
+ GPprev.
+
+
+%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
begin_marker() ->
@@ -130,7 +190,12 @@ rfc4716_pubkey_decode(<<?UINT32(Len), Type:Len/binary,
{erlint(SizeY, Y),
#'Dss-Parms'{p = erlint(SizeP, P),
q = erlint(SizeQ, Q),
- g = erlint(SizeG, G)}}.
+ g = erlint(SizeG, G)}};
+rfc4716_pubkey_decode(<<?UINT32(Len), ECDSA_SHA2_etc:Len/binary,
+ ?UINT32(SizeId), Id:SizeId/binary,
+ ?UINT32(SizeQ), Q:SizeQ/binary>>) ->
+ <<"ecdsa-sha2-", Id/binary>> = ECDSA_SHA2_etc,
+ {#'ECPoint'{point = Q}, {namedCurve,public_key:ssh_curvename2oid(Id)}}.
openssh_decode(Bin, FileType) ->
Lines = binary:split(Bin, <<"\n">>, [global]),
@@ -184,46 +249,42 @@ do_openssh_decode(known_hosts = FileType, [Line | Lines], Acc) ->
end;
do_openssh_decode(openssh_public_key = FileType, [Line | Lines], Acc) ->
- case split_n(2, Line, []) of
- [KeyType, Base64Enc] when KeyType == <<"ssh-rsa">>;
- KeyType == <<"ssh-dss">> ->
+ [KeyType, Base64Enc | Comment0] = split_n(2, Line, []),
+ KnownKeyType =
+ case KeyType of
+ <<"ssh-rsa">> -> true;
+ <<"ssh-dss">> -> true;
+ <<"ecdsa-sha2-",Curve/binary>> -> is_ssh_curvename(Curve);
+ _ -> false
+ end,
+
+ case Comment0 of
+ [] when KnownKeyType==true ->
do_openssh_decode(FileType, Lines,
[{openssh_pubkey_decode(KeyType, Base64Enc),
[]} | Acc]);
- [KeyType, Base64Enc | Comment0] when KeyType == <<"ssh-rsa">>;
- KeyType == <<"ssh-dss">> ->
+ _ when KnownKeyType==true ->
Comment = string:strip(string_decode(iolist_to_binary(Comment0)), right, $\n),
do_openssh_decode(FileType, Lines,
[{openssh_pubkey_decode(KeyType, Base64Enc),
[{comment, Comment}]} | Acc])
end.
+
decode_comment([]) ->
[];
decode_comment(Comment) ->
[{comment, string_decode(iolist_to_binary(Comment))}].
-openssh_pubkey_decode(<<"ssh-rsa">>, Base64Enc) ->
- <<?UINT32(StrLen), _:StrLen/binary,
- ?UINT32(SizeE), E:SizeE/binary,
- ?UINT32(SizeN), N:SizeN/binary>>
- = base64:mime_decode(Base64Enc),
- #'RSAPublicKey'{modulus = erlint(SizeN, N),
- publicExponent = erlint(SizeE, E)};
-openssh_pubkey_decode(<<"ssh-dss">>, Base64Enc) ->
- <<?UINT32(StrLen), _:StrLen/binary,
- ?UINT32(SizeP), P:SizeP/binary,
- ?UINT32(SizeQ), Q:SizeQ/binary,
- ?UINT32(SizeG), G:SizeG/binary,
- ?UINT32(SizeY), Y:SizeY/binary>>
- = base64:mime_decode(Base64Enc),
- {erlint(SizeY, Y),
- #'Dss-Parms'{p = erlint(SizeP, P),
- q = erlint(SizeQ, Q),
- g = erlint(SizeG, G)}};
-openssh_pubkey_decode(KeyType, Base64Enc) ->
- {KeyType, base64:mime_decode(Base64Enc)}.
+openssh_pubkey_decode(Type, Base64Enc) ->
+ try
+ ssh2_pubkey_decode(Type, base64:mime_decode(Base64Enc))
+ catch
+ _:_ ->
+ {Type, base64:mime_decode(Base64Enc)}
+ end.
+
erlint(MPIntSize, MPIntValue) ->
Bits= MPIntSize * 8,
@@ -347,10 +408,9 @@ line_end("") ->
line_end(Comment) ->
[" ", Comment, "\n"].
-key_type(#'RSAPublicKey'{}) ->
- <<"ssh-rsa">>;
-key_type({_, #'Dss-Parms'{}}) ->
- <<"ssh-dss">>.
+key_type(#'RSAPublicKey'{}) -> <<"ssh-rsa">>;
+key_type({_, #'Dss-Parms'{}}) -> <<"ssh-dss">>;
+key_type({#'ECPoint'{}, {namedCurve,Curve}}) -> <<"ecdsa-sha2-", (public_key:oid2ssh_curvename(Curve))/binary>>.
comma_list_encode([Option], []) ->
Option;
@@ -380,20 +440,49 @@ ssh2_pubkey_encode({Y, #'Dss-Parms'{p = P, q = Q, g = G}}) ->
PBin/binary,
QBin/binary,
GBin/binary,
- YBin/binary>>.
-
-is_key_field(<<"ssh-dss">>) ->
- true;
-is_key_field(<<"ssh-rsa">>) ->
- true;
-is_key_field(<<"ecdsa-sha2-nistp256">>) ->
- true;
-is_key_field(<<"ecdsa-sha2-nistp384">>) ->
- true;
-is_key_field(<<"ecdsa-sha2-nistp521">>) ->
- true;
-is_key_field(_) ->
- false.
+ YBin/binary>>;
+ssh2_pubkey_encode(Key={#'ECPoint'{point = Q}, {namedCurve,OID}}) ->
+ TypeStr = key_type(Key),
+ StrLen = size(TypeStr),
+ IdB = public_key:oid2ssh_curvename(OID),
+ <<?UINT32(StrLen), TypeStr:StrLen/binary,
+ (string(IdB))/binary,
+ (string(Q))/binary>>.
+
+
+ssh2_pubkey_decode(Bin = <<?UINT32(Len), Type:Len/binary, _/binary>>) ->
+ ssh2_pubkey_decode(Type, Bin).
+
+ssh2_pubkey_decode(<<"ssh-rsa">>,
+ <<?UINT32(Len), _:Len/binary,
+ ?UINT32(SizeE), E:SizeE/binary,
+ ?UINT32(SizeN), N:SizeN/binary>>) ->
+ #'RSAPublicKey'{modulus = erlint(SizeN, N),
+ publicExponent = erlint(SizeE, E)};
+
+ssh2_pubkey_decode(<<"ssh-dss">>,
+ <<?UINT32(Len), _:Len/binary,
+ ?UINT32(SizeP), P:SizeP/binary,
+ ?UINT32(SizeQ), Q:SizeQ/binary,
+ ?UINT32(SizeG), G:SizeG/binary,
+ ?UINT32(SizeY), Y:SizeY/binary>>) ->
+ {erlint(SizeY, Y),
+ #'Dss-Parms'{p = erlint(SizeP, P),
+ q = erlint(SizeQ, Q),
+ g = erlint(SizeG, G)}};
+ssh2_pubkey_decode(<<"ecdsa-sha2-",Id/binary>>,
+ <<?UINT32(Len), ECDSA_SHA2_etc:Len/binary,
+ ?UINT32(SizeId), Id:SizeId/binary,
+ ?UINT32(SizeQ), Q:SizeQ/binary>>) ->
+ <<"ecdsa-sha2-", Id/binary>> = ECDSA_SHA2_etc,
+ {#'ECPoint'{point = Q}, {namedCurve,public_key:ssh_curvename2oid(Id)}}.
+
+
+
+is_key_field(<<"ssh-dss">>) -> true;
+is_key_field(<<"ssh-rsa">>) -> true;
+is_key_field(<<"ecdsa-sha2-",Id/binary>>) -> is_ssh_curvename(Id);
+is_key_field(_) -> false.
is_bits_field(Part) ->
try list_to_integer(binary_to_list(Part)) of
@@ -507,3 +596,14 @@ int_to_bin_neg(-1, Ds=[MSB|_]) when MSB >= 16#80 ->
list_to_binary(Ds);
int_to_bin_neg(X,Ds) ->
int_to_bin_neg(X bsr 8, [(X band 255)|Ds]).
+
+
+string(X) when is_binary(X) ->
+ << ?STRING(X) >>;
+string(X) ->
+ << ?STRING(list_to_binary(X)) >>.
+
+is_ssh_curvename(Id) -> try public_key:ssh_curvename2oid(Id) of _ -> true
+ catch _:_ -> false
+ end.
+
diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl
index 2f4cc64c2a..a79badef24 100644
--- a/lib/public_key/src/public_key.erl
+++ b/lib/public_key/src/public_key.erl
@@ -35,6 +35,8 @@
decrypt_private/2, decrypt_private/3,
encrypt_public/2, encrypt_public/3,
decrypt_public/2, decrypt_public/3,
+ dh_gex_group/4,
+ dh_gex_group_sizes/0,
sign/3, verify/4,
generate_key/1,
compute_key/2, compute_key/3,
@@ -47,6 +49,7 @@
pkix_normalize_name/1,
pkix_path_validation/3,
ssh_decode/2, ssh_encode/2,
+ ssh_curvename2oid/1, oid2ssh_curvename/1,
pkix_crls_validate/3,
pkix_dist_point/1,
pkix_dist_points/1,
@@ -372,6 +375,13 @@ encrypt_private(PlainText,
crypto:private_encrypt(rsa, PlainText, format_rsa_private_key(Key), Padding).
%%--------------------------------------------------------------------
+dh_gex_group_sizes() ->
+ pubkey_ssh:dh_gex_group_sizes().
+
+dh_gex_group(Min, N, Max, Groups) ->
+ pubkey_ssh:dh_gex_group(Min, N, Max, Groups).
+
+%%--------------------------------------------------------------------
-spec generate_key(#'DHParameter'{} | {namedCurve, Name ::oid()} |
#'ECParameters'{}) -> {Public::binary(), Private::binary()} |
#'ECPrivateKey'{}.
@@ -711,7 +721,9 @@ pkix_crls_validate(OtpCert, DPAndCRLs0, Options) ->
%%--------------------------------------------------------------------
--spec ssh_decode(binary(), public_key | ssh_file()) -> [{public_key(), Attributes::list()}].
+-spec ssh_decode(binary(), public_key | ssh_file()) -> [{public_key(), Attributes::list()}]
+ ; (binary(), ssh2_pubkey) -> public_key()
+ .
%%
%% Description: Decodes a ssh file-binary. In the case of know_hosts
%% or auth_keys the binary may include one or more lines of the
@@ -724,12 +736,15 @@ ssh_decode(SshBin, Type) when is_binary(SshBin),
Type == rfc4716_public_key;
Type == openssh_public_key;
Type == auth_keys;
- Type == known_hosts ->
+ Type == known_hosts;
+ Type == ssh2_pubkey ->
pubkey_ssh:decode(SshBin, Type).
%%--------------------------------------------------------------------
--spec ssh_encode([{public_key(), Attributes::list()}], ssh_file()) ->
- binary().
+-spec ssh_encode([{public_key(), Attributes::list()}], ssh_file()) -> binary()
+ ; (public_key(), ssh2_pubkey) -> binary()
+ .
+%%
%% Description: Encodes a list of ssh file entries (public keys and
%% attributes) to a binary. Possible attributes depends on the file
%% type.
@@ -738,10 +753,30 @@ ssh_encode(Entries, Type) when is_list(Entries),
Type == rfc4716_public_key;
Type == openssh_public_key;
Type == auth_keys;
- Type == known_hosts ->
+ Type == known_hosts;
+ Type == ssh2_pubkey ->
pubkey_ssh:encode(Entries, Type).
%%--------------------------------------------------------------------
+-spec ssh_curvename2oid(binary()) -> oid().
+
+%% Description: Converts from the ssh name of elliptic curves to
+%% the OIDs.
+%%--------------------------------------------------------------------
+ssh_curvename2oid(<<"nistp256">>) -> ?'secp256r1';
+ssh_curvename2oid(<<"nistp384">>) -> ?'secp384r1';
+ssh_curvename2oid(<<"nistp521">>) -> ?'secp521r1'.
+
+%%--------------------------------------------------------------------
+-spec oid2ssh_curvename(oid()) -> binary().
+
+%% Description: Converts from elliptic curve OIDs to the ssh name.
+%%--------------------------------------------------------------------
+oid2ssh_curvename(?'secp256r1') -> <<"nistp256">>;
+oid2ssh_curvename(?'secp384r1') -> <<"nistp384">>;
+oid2ssh_curvename(?'secp521r1') -> <<"nistp521">>.
+
+%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
do_verify(DigestOrPlainText, DigestType, Signature,
diff --git a/lib/public_key/test/public_key_SUITE.erl b/lib/public_key/test/public_key_SUITE.erl
index 6f142c951c..5e677f31d6 100644
--- a/lib/public_key/test/public_key_SUITE.erl
+++ b/lib/public_key/test/public_key_SUITE.erl
@@ -49,8 +49,10 @@ groups() ->
[{pem_decode_encode, [], [dsa_pem, rsa_pem, encrypted_pem,
dh_pem, cert_pem, pkcs7_pem, pkcs10_pem]},
{ssh_public_key_decode_encode, [],
- [ssh_rsa_public_key, ssh_dsa_public_key, ssh_rfc4716_rsa_comment,
- ssh_rfc4716_dsa_comment, ssh_rfc4716_rsa_subject, ssh_known_hosts,
+ [ssh_rsa_public_key, ssh_dsa_public_key, ssh_ecdsa_public_key,
+ ssh_rfc4716_rsa_comment, ssh_rfc4716_dsa_comment,
+ ssh_rfc4716_rsa_subject,
+ ssh_known_hosts,
ssh_auth_keys, ssh1_known_hosts, ssh1_auth_keys, ssh_openssh_public_key_with_comment,
ssh_openssh_public_key_long_header]},
{sign_verify, [], [rsa_sign_verify, dsa_sign_verify]}
@@ -291,6 +293,32 @@ ssh_dsa_public_key(Config) when is_list(Config) ->
public_key:ssh_decode(EncodedOpenSsh, public_key).
%%--------------------------------------------------------------------
+
+ssh_ecdsa_public_key() ->
+ [{doc, "ssh ecdsa public key decode/encode"}].
+ssh_ecdsa_public_key(Config) when is_list(Config) ->
+ Datadir = ?config(data_dir, Config),
+
+ {ok, ECDSARawSsh2} = file:read_file(filename:join(Datadir, "ssh2_ecdsa_pub")),
+ [{PubKey, Attributes1}] = public_key:ssh_decode(ECDSARawSsh2, public_key),
+ [{PubKey, Attributes1}] = public_key:ssh_decode(ECDSARawSsh2, rfc4716_public_key),
+
+ {ok, ECDSARawOpenSsh} = file:read_file(filename:join(Datadir, "openssh_ecdsa_pub")),
+ [{PubKey, Attributes2}] = public_key:ssh_decode(ECDSARawOpenSsh, public_key),
+ [{PubKey, Attributes2}] = public_key:ssh_decode(ECDSARawOpenSsh, openssh_public_key),
+
+ %% Can not check EncodedSSh == ECDSARawSsh2 and EncodedOpenSsh
+ %% = ECDSARawOpenSsh as line breakpoints may differ
+
+ EncodedSSh = public_key:ssh_encode([{PubKey, Attributes1}], rfc4716_public_key),
+ EncodedOpenSsh = public_key:ssh_encode([{PubKey, Attributes2}], openssh_public_key),
+
+ [{PubKey, Attributes1}] =
+ public_key:ssh_decode(EncodedSSh, public_key),
+ [{PubKey, Attributes2}] =
+ public_key:ssh_decode(EncodedOpenSsh, public_key).
+
+%%--------------------------------------------------------------------
ssh_rfc4716_rsa_comment() ->
[{doc, "Test comment header and rsa key"}].
ssh_rfc4716_rsa_comment(Config) when is_list(Config) ->
diff --git a/lib/public_key/test/public_key_SUITE_data/openssh_ecdsa_pub b/lib/public_key/test/public_key_SUITE_data/openssh_ecdsa_pub
new file mode 100644
index 0000000000..a49b4264b8
--- /dev/null
+++ b/lib/public_key/test/public_key_SUITE_data/openssh_ecdsa_pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIJrVlKYIT+MlxxRx5BFXisHHkcGMAAKv2dguUeOsutsYyzs9JAczvl6c+Sypra5+qOi2LHPXw6GGluuXcOssOM= uabhnil@elxadlj3q32
diff --git a/lib/public_key/test/public_key_SUITE_data/ssh2_ecdsa_pub b/lib/public_key/test/public_key_SUITE_data/ssh2_ecdsa_pub
new file mode 100644
index 0000000000..702e5c4fde
--- /dev/null
+++ b/lib/public_key/test/public_key_SUITE_data/ssh2_ecdsa_pub
@@ -0,0 +1,6 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+Comment: "256-bit ECDSA, converted by uabhnil@elxadlj3q32 from OpenSSH"
+AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIJrVlKYIT+MlxxRx5
+BFXisHHkcGMAAKv2dguUeOsutsYyzs9JAczvl6c+Sypra5+qOi2LHPXw6GGluuXcOssOM=
+
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/public_key/vsn.mk b/lib/public_key/vsn.mk
index f762473a58..d5ffe6ca35 100644
--- a/lib/public_key/vsn.mk
+++ b/lib/public_key/vsn.mk
@@ -1 +1 @@
-PUBLIC_KEY_VSN = 1.0.1
+PUBLIC_KEY_VSN = 1.1
diff --git a/lib/runtime_tools/doc/src/dbg.xml b/lib/runtime_tools/doc/src/dbg.xml
index 1a11806211..2065627026 100644
--- a/lib/runtime_tools/doc/src/dbg.xml
+++ b/lib/runtime_tools/doc/src/dbg.xml
@@ -1030,9 +1030,9 @@ hello</pre>
<fsummary>Stop the <c>dbg</c>server and the tracing of all processes.</fsummary>
<desc>
<p>Stops the <c>dbg</c> server and clears all trace flags for
- all processes and all trace patterns for all functions. Also
+ all processes and all local trace patterns for all functions. Also
shuts down all trace clients and closes all trace ports.</p>
- <p>Note that no trace patterns are affected by this
+ <p>Note that no global trace patterns are affected by this
function.</p>
</desc>
</func>
@@ -1040,8 +1040,7 @@ hello</pre>
<name>stop_clear() -> ok</name>
<fsummary>Stop the <c>dbg</c>server and the tracing of all processes, and clears trace patterns.</fsummary>
<desc>
- <p>Same as stop/0, but also clears all trace patterns on local
- and global functions calls.</p>
+ <p>Same as stop/0, but also clears all trace patterns on global functions calls.</p>
</desc>
</func>
</funcs>
diff --git a/lib/snmp/doc/src/snmp_advanced_agent.xml b/lib/snmp/doc/src/snmp_advanced_agent.xml
index 717f7426c6..b17246438d 100644
--- a/lib/snmp/doc/src/snmp_advanced_agent.xml
+++ b/lib/snmp/doc/src/snmp_advanced_agent.xml
@@ -340,7 +340,7 @@
SEQUENCE {
empDepNo INTEGER,
empName DisplayString,
- empTelNo DisplayString
+ empTelNo DisplayString,
empStatus RowStatus
}
</code>
diff --git a/lib/snmp/doc/src/snmp_agent_netif.xml b/lib/snmp/doc/src/snmp_agent_netif.xml
index 769fd23115..9583f1f521 100644
--- a/lib/snmp/doc/src/snmp_agent_netif.xml
+++ b/lib/snmp/doc/src/snmp_agent_netif.xml
@@ -76,8 +76,7 @@
<c>{Domain, Addr}</c> tuple where <c>Domain</c> is
<c>transportDomainUdpIpv4</c> or <c>transportDomainUdpIpv4</c>,
and <c>Addr</c> is an
- <c>{<seealso marker="kernel:inet#type-ip_address">IpAddr</seealso>,
- IpPort}</c> tuple.</p>
+ <c>{</c><seealso marker="kernel:inet#type-ip_address"><c>IpAddr</c></seealso><c>,IpPort}</c> tuple.</p>
<section>
<marker id="outgoing_messages"></marker>
diff --git a/lib/snmp/doc/src/snmp_app.xml b/lib/snmp/doc/src/snmp_app.xml
index 234a076eda..39aac8e7d7 100644
--- a/lib/snmp/doc/src/snmp_app.xml
+++ b/lib/snmp/doc/src/snmp_app.xml
@@ -135,16 +135,16 @@
<marker id="agent_opts_and_types"></marker>
<p>Agent specific config options and types:</p>
<taglist>
- <marker id="agent_type"></marker>
- <tag><c><![CDATA[agent_type() = master | sub <optional>]]></c></tag>
+ <tag><marker id="agent_type"></marker>
+ <c><![CDATA[agent_type() = master | sub <optional>]]></c></tag>
<item>
<p>If <c>master</c>, one master agent is
started. Otherwise, no agents are started. </p>
<p>Default is <c>master</c>.</p>
</item>
- <marker id="agent_disco"></marker>
- <tag><c><![CDATA[agent_discovery() = [agent_discovery_opt()] <optional>]]></c></tag>
+ <tag><marker id="agent_disco"></marker>
+ <c><![CDATA[agent_discovery() = [agent_discovery_opt()] <optional>]]></c></tag>
<item>
<p><c>agent_discovery_opt() =
{terminating, agent_terminating_discovery_opts()} |
@@ -156,8 +156,8 @@
<p>For defaults see the options in <c>agent_discovery_opt()</c>.</p>
</item>
- <marker id="agent_term_disco_opts"></marker>
- <tag><c><![CDATA[agent_terminating_discovery_opts() = [agent_terminating_discovery_opt()] <optional>]]></c></tag>
+ <tag><marker id="agent_term_disco_opts"></marker>
+ <c><![CDATA[agent_terminating_discovery_opts() = [agent_terminating_discovery_opt()] <optional>]]></c></tag>
<item>
<p><c>agent_terminating_discovery_opt() =
{enable, boolean()} |
@@ -174,8 +174,8 @@
</list>
</item>
- <marker id="agent_orig_disco_opts"></marker>
- <tag><c><![CDATA[agent_originating_discovery_opts() = [agent_originating_discovery_opt()] <optional>]]></c></tag>
+ <tag><marker id="agent_orig_disco_opts"></marker>
+ <c><![CDATA[agent_originating_discovery_opts() = [agent_originating_discovery_opt()] <optional>]]></c></tag>
<item>
<p><c>agent_originating_discovery_opt() =
{enable, boolean()}</c></p>
@@ -188,38 +188,39 @@
</list>
</item>
- <marker id="agent_mt"></marker>
- <tag><c><![CDATA[multi_threaded() = bool() <optional>]]></c></tag>
+ <tag><marker id="agent_mt"></marker>
+ <c><![CDATA[multi_threaded() = bool() <optional>]]></c></tag>
<item>
<p>If <c>true</c>, the agent is multi-threaded, with one
thread for each get request. </p>
<p>Default is <c>false</c>.</p>
</item>
- <marker id="agent_data_dir"></marker>
- <tag><c><![CDATA[db_dir() = string() <mandatory>]]></c></tag>
+ <tag><marker id="agent_data_dir"></marker>
+ <c><![CDATA[db_dir() = string() <mandatory>]]></c></tag>
<item>
<p>Defines where the SNMP agent internal db files are stored.</p>
</item>
- <marker id="agent_gb_max_vbs"></marker>
- <tag><c><![CDATA[gb_max_vbs() = pos_integer() | infinity <optional>]]></c></tag>
+
+ <tag><marker id="agent_gb_max_vbs"></marker>
+ <c><![CDATA[gb_max_vbs() = pos_integer() | infinity <optional>]]></c></tag>
<item>
<p>Defines the maximum number of varbinds allowed
in a Get-BULK response.</p>
<p>Default is <c>1000</c>.</p>
</item>
- <marker id="agent_local_db"></marker>
- <tag><c><![CDATA[local_db() = [local_db_opt()] <optional>]]></c></tag>
+ <tag><marker id="agent_local_db"></marker>
+ <c><![CDATA[local_db() = [local_db_opt()] <optional>]]></c></tag>
<item>
<p><c>local_db_opt() = {repair, agent_repair()} | {auto_save, agent_auto_save()} | {verbosity, verbosity()}</c></p>
<p>Defines options specific for the SNMP agent local database.</p>
<p>For defaults see the options in <c>local_db_opt()</c>.</p>
</item>
- <marker id="agent_ldb_repair"></marker>
- <tag><c><![CDATA[agent_repair() = false | true | force <optional>]]></c></tag>
+ <tag><marker id="agent_ldb_repair"></marker>
+ <c><![CDATA[agent_repair() = false | true | force <optional>]]></c></tag>
<item>
<p>When starting snmpa_local_db it always tries to open an
existing database. If <c>false</c>, and some errors occur, a new
@@ -229,16 +230,16 @@
<p>Default is <c>true</c>.</p>
</item>
- <marker id="agent_ldb_auto_save"></marker>
- <tag><c><![CDATA[agent_auto_save() = integer() | infinity <optional>]]></c></tag>
+ <tag><marker id="agent_ldb_auto_save"></marker>
+ <c><![CDATA[agent_auto_save() = integer() | infinity <optional>]]></c></tag>
<item>
<p>The auto save interval. The table is flushed to disk
whenever not accessed for this amount of time.</p>
<p>Default is <c>5000</c>.</p>
</item>
- <marker id="agent_net_if"></marker>
- <tag><c><![CDATA[agent_net_if() = [agent_net_if_opt()] <optional>]]></c></tag>
+ <tag><marker id="agent_net_if"></marker>
+ <c><![CDATA[agent_net_if() = [agent_net_if_opt()] <optional>]]></c></tag>
<item>
<p><c>agent_net_if_opt() = {module, agent_net_if_module()} | {verbosity, verbosity()} | {options, agent_net_if_options()}</c></p>
<p>Defines options specific for the SNMP agent network interface
@@ -246,8 +247,8 @@
<p>For defaults see the options in <c>agent_net_if_opt()</c>.</p>
</item>
- <marker id="agent_ni_module"></marker>
- <tag><c><![CDATA[agent_net_if_module() = atom() <optional>]]></c></tag>
+ <tag><marker id="agent_ni_module"></marker>
+ <c><![CDATA[agent_net_if_module() = atom() <optional>]]></c></tag>
<item>
<p>Module which handles the network interface part for the
SNMP agent. Must implement the
@@ -255,8 +256,8 @@
<p>Default is <c>snmpa_net_if</c>.</p>
</item>
- <marker id="agent_ni_opts"></marker>
- <tag><c><![CDATA[agent_net_if_options() = [agent_net_if_option()] <optional>]]></c></tag>
+ <tag><marker id="agent_ni_opts"></marker>
+ <c><![CDATA[agent_net_if_options() = [agent_net_if_option()] <optional>]]></c></tag>
<item>
<p><c>agent_net_if_option() = {bind_to, bind_to()} |
{sndbuf, sndbuf()} |
@@ -270,15 +271,15 @@
<p>For defaults see the options in <c>agent_net_if_option()</c>.</p>
</item>
- <marker id="agent_ni_req_limit"></marker>
- <tag><c><![CDATA[req_limit() = integer() | infinity <optional>]]></c></tag>
+ <tag><marker id="agent_ni_req_limit"></marker>
+ <c><![CDATA[req_limit() = integer() | infinity <optional>]]></c></tag>
<item>
<p>Max number of simultaneous requests handled by the agent.</p>
<p>Default is <c>infinity</c>.</p>
</item>
- <marker id="agent_ni_filter_opts"></marker>
- <tag><c><![CDATA[agent_net_if_filter_options() = [agent_net_if_filter_option()] <optional>]]></c></tag>
+ <tag><marker id="agent_ni_filter_opts"></marker>
+ <c><![CDATA[agent_net_if_filter_options() = [agent_net_if_filter_option()] <optional>]]></c></tag>
<item>
<p><c>agent_net_if_filter_option() = {module, agent_net_if_filter_module()}</c></p>
<p>These options are actually specific to the used module.
@@ -288,8 +289,8 @@
<c>agent_net_if_filter_option()</c>.</p>
</item>
- <marker id="agent_ni_filter_module"></marker>
- <tag><c><![CDATA[agent_net_if_filter_module() = atom() <optional>]]></c></tag>
+ <tag><marker id="agent_ni_filter_module"></marker>
+ <c><![CDATA[agent_net_if_filter_module() = atom() <optional>]]></c></tag>
<item>
<p>Module which handles the network interface filter part for the
SNMP agent. Must implement the
@@ -297,8 +298,8 @@
<p>Default is <c>snmpa_net_if_filter</c>.</p>
</item>
- <marker id="agent_mibs"></marker>
- <tag><c><![CDATA[agent_mibs() = [string()] <optional>]]></c></tag>
+ <tag><marker id="agent_mibs"></marker>
+ <c><![CDATA[agent_mibs() = [string()] <optional>]]></c></tag>
<item>
<p>Specifies a list of MIBs (including path) that defines which MIBs
are initially loaded into the SNMP master agent. </p>
@@ -312,8 +313,8 @@
<p>Default is <c>[]</c>.</p>
</item>
- <marker id="agent_mib_storage"></marker>
- <tag><c><![CDATA[mib_storage() = [mib_storage_opt()] <optional>]]></c></tag>
+ <tag><marker id="agent_mib_storage"></marker>
+ <c><![CDATA[mib_storage() = [mib_storage_opt()] <optional>]]></c></tag>
<item>
<p><c>mib_storage_opt() = {module, mib_storage_module()} | {options, mib_storage_options()}</c></p>
<p>This option specifies how basic mib data is stored.
@@ -322,8 +323,8 @@
<p>Default is <c>[{module, snmpa_mib_storage_ets}]</c>. </p>
</item>
- <marker id="agent_mst_module"></marker>
- <tag><c><![CDATA[mib_storage_module() = snmpa_mib_data_ets | snmpa_mib_data_dets | snmpa_mib_data_mnesia | module()]]></c></tag>
+ <tag><marker id="agent_mst_module"></marker>
+ <c><![CDATA[mib_storage_module() = snmpa_mib_data_ets | snmpa_mib_data_dets | snmpa_mib_data_mnesia | module()]]></c></tag>
<item>
<p>Defines the mib storage module of the SNMP agent as defined by the
<seealso marker="snmpa_mib_storage">snmpa_mib_storage</seealso>
@@ -337,8 +338,8 @@
<p>Default module is <c>snmpa_mib_storage_ets</c>. </p>
</item>
- <marker id="agent_mst_options"></marker>
- <tag><c><![CDATA[mib_storage_options() = list() <optional>]]></c></tag>
+ <tag><marker id="agent_mst_options"></marker>
+ <c><![CDATA[mib_storage_options() = list() <optional>]]></c></tag>
<item>
<p>This is implementattion depended. That is, it depends on the
module. For each module a specific set of options are valid.
@@ -427,16 +428,16 @@
</list>
</item>
- <marker id="agent_mib_server"></marker>
- <tag><c><![CDATA[mib_server() = [mib_server_opt()] <optional>]]></c></tag>
+ <tag><marker id="agent_mib_server"></marker>
+ <c><![CDATA[mib_server() = [mib_server_opt()] <optional>]]></c></tag>
<item>
<p><c>mib_server_opt() = {mibentry_override, mibentry_override()} | {trapentry_override, trapentry_override()} | {verbosity, verbosity()} | {cache, mibs_cache()} | {data_module, mib_server_data_module()}</c></p>
<p>Defines options specific for the SNMP agent mib server. </p>
<p>For defaults see the options in <c>mib_server_opt()</c>.</p>
</item>
- <marker id="agent_ms_meo"></marker>
- <tag><c><![CDATA[mibentry_override() = bool() <optional>]]></c></tag>
+ <tag><marker id="agent_ms_meo"></marker>
+ <c><![CDATA[mibentry_override() = bool() <optional>]]></c></tag>
<item>
<p>If this value is false, then when loading a mib each mib-
entry is checked prior to installation of the mib.
@@ -445,8 +446,8 @@
<p>Default is <c>false</c>.</p>
</item>
- <marker id="agent_ms_teo"></marker>
- <tag><c><![CDATA[trapentry_override() = bool() <optional>]]></c></tag>
+ <tag><marker id="agent_ms_teo"></marker>
+ <c><![CDATA[trapentry_override() = bool() <optional>]]></c></tag>
<item>
<p>If this value is false, then when loading a mib each trap
is checked prior to installation of the mib.
@@ -455,11 +456,12 @@
<p>Default is <c>false</c>.</p>
</item>
- <marker id="agent_ms_data_module"></marker>
<!--
- <tag><c><![CDATA[mib_server_data_module() = snmpa_mib_data_tttn | snmpa_mib_data_ttln | module() <optional>]]></c></tag>
+ <tag><marker id="agent_ms_data_module"></marker>
+ <c><![CDATA[mib_server_data_module() = snmpa_mib_data_tttn | snmpa_mib_data_ttln | module() <optional>]]></c></tag>
-->
- <tag><c><![CDATA[mib_server_data_module() = snmpa_mib_data_tttn | module() <optional>]]></c></tag>
+ <tag><marker id="agent_ms_data_module"></marker>
+ <c><![CDATA[mib_server_data_module() = snmpa_mib_data_tttn | module() <optional>]]></c></tag>
<item>
<p>Defines the backend data module of the SNMP agent mib-server as
defined by the
@@ -476,24 +478,24 @@
<p>Default module is <c>snmpa_mib_data_tttn</c>. </p>
</item>
- <marker id="agent_ms_cache"></marker>
- <tag><c><![CDATA[mibs_cache() = bool() | mibs_cache_opts() <optional>]]></c></tag>
+ <tag><marker id="agent_ms_cache"></marker>
+ <c><![CDATA[mibs_cache() = bool() | mibs_cache_opts() <optional>]]></c></tag>
<item>
<p>Shall the agent utilize the mib server lookup cache or not.</p>
<p>Default is <c>true</c> (in which case the <c>mibs_cache_opts()</c>
default values apply).</p>
</item>
- <marker id="agent_ms_cache_opts"></marker>
- <tag><c><![CDATA[mibs_cache_opts() = [mibs_cache_opt()] <optional>]]></c></tag>
+ <tag><marker id="agent_ms_cache_opts"></marker>
+ <c><![CDATA[mibs_cache_opts() = [mibs_cache_opt()] <optional>]]></c></tag>
<item>
<p><c>mibs_cache_opt() = {autogc, mibs_cache_autogc()} | {gclimit, mibs_cache_gclimit()} | {age, mibs_cache_age()}</c></p>
<p>Defines options specific for the SNMP agent mib server cache. </p>
<p>For defaults see the options in <c>mibs_cache_opt()</c>.</p>
</item>
- <marker id="agent_ms_cache_autogc"></marker>
- <tag><c><![CDATA[mibs_cache_autogc() = bool() <optional>]]></c></tag>
+ <tag><marker id="agent_ms_cache_autogc"></marker>
+ <c><![CDATA[mibs_cache_autogc() = bool() <optional>]]></c></tag>
<item>
<p>Defines if the mib server shall perform cache gc automatically or
leave it to the user (see
@@ -501,8 +503,8 @@
<p>Default is <c>true</c>.</p>
</item>
- <marker id="agent_ms_cache_age"></marker>
- <tag><c><![CDATA[mibs_cache_age() = integer() > 0 <optional>]]></c></tag>
+ <tag><marker id="agent_ms_cache_age"></marker>
+ <c><![CDATA[mibs_cache_age() = integer() > 0 <optional>]]></c></tag>
<item>
<p>Defines how old the entries in the cache will be allowed
to become before they are GC'ed (assuming GC is performed).
@@ -511,8 +513,8 @@
<p>Default is <c>10 timutes</c>.</p>
</item>
- <marker id="agent_ms_cache_gclimit"></marker>
- <tag><c><![CDATA[mibs_cache_gclimit() = integer() > 0 | infinity <optional>]]></c></tag>
+ <tag><marker id="agent_ms_cache_gclimit"></marker>
+ <c><![CDATA[mibs_cache_gclimit() = integer() > 0 | infinity <optional>]]></c></tag>
<item>
<p>When performing a GC, this is the max number of cache entries
that will be deleted from the cache. </p>
@@ -522,8 +524,8 @@
<p>Default is <c>100</c>.</p>
</item>
- <marker id="agent_error_report_mod"></marker>
- <tag><c><![CDATA[error_report_mod() = atom() <optional>]]></c></tag>
+ <tag><marker id="agent_error_report_mod"></marker>
+ <c><![CDATA[error_report_mod() = atom() <optional>]]></c></tag>
<item>
<p>Defines an error report module, implementing the
<seealso marker="snmpa_error_report">snmpa_error_report</seealso>
@@ -532,38 +534,38 @@
<p>Default is <c>snmpa_error_logger</c>.</p>
</item>
- <marker id="agent_symbolic_store"></marker>
- <tag><c>symbolic_store() = [symbolic_store_opt()]</c></tag>
+ <tag><marker id="agent_symbolic_store"></marker>
+ <c>symbolic_store() = [symbolic_store_opt()]</c></tag>
<item>
<p><c>symbolic_store_opt() = {verbosity, verbosity()}</c></p>
<p>Defines options specific for the SNMP agent symbolic store. </p>
<p>For defaults see the options in <c>symbolic_store_opt()</c>.</p>
</item>
- <marker id="agent_target_cache"></marker>
- <tag><c>target_cache() = [target_cache_opt()]</c></tag>
+ <tag><marker id="agent_target_cache"></marker>
+ <c>target_cache() = [target_cache_opt()]</c></tag>
<item>
<p><c>target_cache_opt() = {verbosity, verbosity()}</c></p>
<p>Defines options specific for the SNMP agent target cache. </p>
<p>For defaults see the options in <c>target_cache_opt()</c>.</p>
</item>
- <marker id="agent_config"></marker>
- <tag><c><![CDATA[agent_config() = [agent_config_opt()] <mandatory>]]></c></tag>
+ <tag><marker id="agent_config"></marker>
+ <c><![CDATA[agent_config() = [agent_config_opt()] <mandatory>]]></c></tag>
<item>
<p><c>agent_config_opt() = {dir, agent_config_dir()} | {force_load, force_load()} | {verbosity, verbosity()}</c></p>
<p>Defines specific config related options for the SNMP agent. </p>
<p>For defaults see the options in <c>agent_config_opt()</c>.</p>
</item>
- <marker id="agent_config_dir"></marker>
- <tag><c><![CDATA[agent_config_dir = dir() <mandatory>]]></c></tag>
+ <tag><marker id="agent_config_dir"></marker>
+ <c><![CDATA[agent_config_dir = dir() <mandatory>]]></c></tag>
<item>
<p>Defines where the SNMP agent configuration files are stored.</p>
</item>
- <marker id="agent_force_load"></marker>
- <tag><c><![CDATA[force_load() = bool() <optional>]]></c></tag>
+ <tag><marker id="agent_force_load"></marker>
+ <c><![CDATA[force_load() = bool() <optional>]]></c></tag>
<item>
<p>If <c>true</c> the configuration files are re-read
during start-up, and the contents of the configuration
@@ -577,16 +579,16 @@
<marker id="manager_opts_and_types"></marker>
<p>Manager specific config options and types:</p>
<taglist>
- <marker id="manager_server"></marker>
- <tag><c><![CDATA[server() = [server_opt()] <optional>]]></c></tag>
+ <tag><marker id="manager_server"></marker>
+ <c><![CDATA[server() = [server_opt()] <optional>]]></c></tag>
<item>
<p><c>server_opt() = {timeout, server_timeout()} | {verbosity, verbosity()}</c></p>
<p>Specifies the options for the manager server process.</p>
<p>Default is <c>silence</c>.</p>
</item>
- <marker id="manager_server_timeout"></marker>
- <tag><c><![CDATA[server_timeout() = integer() <optional>]]></c></tag>
+ <tag><marker id="manager_server_timeout"></marker>
+ <c><![CDATA[server_timeout() = integer() <optional>]]></c></tag>
<item>
<p>Asynchronous request cleanup time. For every requests,
some info is stored internally, in order to be able to
@@ -606,44 +608,44 @@
<p>Default is <c>30000</c>.</p>
</item>
- <marker id="manager_config"></marker>
- <tag><c><![CDATA[manager_config() = [manager_config_opt()] <mandatory>]]></c></tag>
+ <tag><marker id="manager_config"></marker>
+ <c><![CDATA[manager_config() = [manager_config_opt()] <mandatory>]]></c></tag>
<item>
<p><c>manager_config_opt() = {dir, manager_config_dir()} | {db_dir, manager_db_dir()} | {db_init_error, db_init_error()} | {repair, manager_repair()} | {auto_save, manager_auto_save()} | {verbosity, verbosity()}</c></p>
<p>Defines specific config related options for the SNMP manager. </p>
<p>For defaults see the options in <c>manager_config_opt()</c>.</p>
</item>
- <marker id="manager_config_dir"></marker>
- <tag><c><![CDATA[manager_config_dir = dir() <mandatory>]]></c></tag>
+ <tag><marker id="manager_config_dir"></marker>
+ <c><![CDATA[manager_config_dir = dir() <mandatory>]]></c></tag>
<item>
<p>Defines where the SNMP manager configuration files are stored.</p>
</item>
- <marker id="manager_config_db_dir"></marker>
- <tag><c><![CDATA[manager_db_dir = dir() <mandatory>]]></c></tag>
+ <tag><marker id="manager_config_db_dir"></marker>
+ <c><![CDATA[manager_db_dir = dir() <mandatory>]]></c></tag>
<item>
<p>Defines where the SNMP manager store persistent data.</p>
</item>
- <marker id="manager_config_repair"></marker>
- <tag><c><![CDATA[manager_repair() = false | true | force <optional>]]></c></tag>
+ <tag><marker id="manager_config_repair"></marker>
+ <c><![CDATA[manager_repair() = false | true | force <optional>]]></c></tag>
<item>
<p>Defines the repair option for the persistent database (if
and how the table is repaired when opened). </p>
<p>Default is <c>true</c>.</p>
</item>
- <marker id="manager_config_auto_save"></marker>
- <tag><c><![CDATA[manager_auto_save() = integer() | infinity <optional>]]></c></tag>
+ <tag><marker id="manager_config_auto_save"></marker>
+ <c><![CDATA[manager_auto_save() = integer() | infinity <optional>]]></c></tag>
<item>
<p>The auto save interval. The table is flushed to disk
whenever not accessed for this amount of time.</p>
<p>Default is <c>5000</c>.</p>
</item>
- <marker id="manager_irb"></marker>
- <tag><c><![CDATA[manager_irb() = auto | user | {user, integer()} <optional>]]></c></tag>
+ <tag><marker id="manager_irb"></marker>
+ <c><![CDATA[manager_irb() = auto | user | {user, integer()} <optional>]]></c></tag>
<item>
<p>This option defines how the manager will handle the sending of
response (acknowledgment) to received inform-requests. </p>
@@ -672,16 +674,16 @@
<p>Default is <c>auto</c>.</p>
</item>
- <marker id="manager_mibs"></marker>
- <tag><c><![CDATA[manager_mibs() = [string()] <optional>]]></c></tag>
+ <tag><marker id="manager_mibs"></marker>
+ <c><![CDATA[manager_mibs() = [string()] <optional>]]></c></tag>
<item>
<p>Specifies a list of MIBs (including path) and defines which MIBs
are initially loaded into the SNMP manager. </p>
<p>Default is <c>[]</c>.</p>
</item>
- <marker id="manager_net_if"></marker>
- <tag><c><![CDATA[manager_net_if() = [manager_net_if_opt()] <optional>]]></c></tag>
+ <tag><marker id="manager_net_if"></marker>
+ <c><![CDATA[manager_net_if() = [manager_net_if_opt()] <optional>]]></c></tag>
<item>
<p><c>manager_net_if_opt() = {module, manager_net_if_module()} |
{verbosity, verbosity()} |
@@ -691,8 +693,8 @@
<p>For defaults see the options in <c>manager_net_if_opt()</c>.</p>
</item>
- <marker id="manager_ni_opts"></marker>
- <tag><c><![CDATA[manager_net_if_options() = [manager_net_if_option()] <optional>]]></c></tag>
+ <tag><marker id="manager_ni_opts"></marker>
+ <c><![CDATA[manager_net_if_options() = [manager_net_if_option()] <optional>]]></c></tag>
<item>
<p><c>manager_net_if_option() = {bind_to, bind_to()} |
{sndbuf, sndbuf()} |
@@ -705,8 +707,8 @@
<p>For defaults see the options in <c>manager_net_if_option()</c>.</p>
</item>
- <marker id="manager_ni_module"></marker>
- <tag><c><![CDATA[manager_net_if_module() = atom() <optional>]]></c></tag>
+ <tag><marker id="manager_ni_module"></marker>
+ <c><![CDATA[manager_net_if_module() = atom() <optional>]]></c></tag>
<item>
<p>The module which handles the network interface part for the
SNMP manager. It must implement the
@@ -714,8 +716,8 @@
<p>Default is <c>snmpm_net_if</c>.</p>
</item>
- <marker id="manager_ni_filter_opts"></marker>
- <tag><c><![CDATA[manager_net_if_filter_options() = [manager_net_if_filter_option()] <optional>]]></c></tag>
+ <tag><marker id="manager_ni_filter_opts"></marker>
+ <c><![CDATA[manager_net_if_filter_options() = [manager_net_if_filter_option()] <optional>]]></c></tag>
<item>
<p><c>manager_net_if_filter_option() = {module, manager_net_if_filter_module()}</c></p>
<p>These options are actually specific to the used module.
@@ -725,8 +727,8 @@
<c>manager_net_if_filter_option()</c>.</p>
</item>
- <marker id="manager_ni_filter_module"></marker>
- <tag><c><![CDATA[manager_net_if_filter_module() = atom() <optional>]]></c></tag>
+ <tag><marker id="manager_ni_filter_module"></marker>
+ <c><![CDATA[manager_net_if_filter_module() = atom() <optional>]]></c></tag>
<item>
<p>Module which handles the network interface filter part for the
SNMP manager. Must implement the
@@ -734,16 +736,16 @@
<p>Default is <c>snmpm_net_if_filter</c>.</p>
</item>
- <marker id="manager_def_user_module"></marker>
- <tag><c><![CDATA[def_user_module() = atom() <optional>]]></c></tag>
+ <tag><marker id="manager_def_user_module"></marker>
+ <c><![CDATA[def_user_module() = atom() <optional>]]></c></tag>
<item>
<p>The module implementing the default user. See the
<seealso marker="snmpm_user">snmpm_user</seealso> behaviour.</p>
<p>Default is <c>snmpm_user_default</c>.</p>
</item>
- <marker id="manager_def_user_data"></marker>
- <tag><c><![CDATA[def_user_data() = term() <optional>]]></c></tag>
+ <tag><marker id="manager_def_user_data"></marker>
+ <c><![CDATA[def_user_data() = term() <optional>]]></c></tag>
<item>
<p>Data for the default user. Passed to the user module when
calling the callback functions.</p>
@@ -754,8 +756,8 @@
<marker id="common_types"></marker>
<p>Common config types:</p>
<taglist>
- <marker id="restart_type"></marker>
- <tag><c>restart_type() = permanent | transient | temporary</c></tag>
+ <tag><marker id="restart_type"></marker>
+ <c>restart_type() = permanent | transient | temporary</c></tag>
<item>
<p>See <seealso marker="stdlib:supervisor#child_spec">supervisor</seealso>
documentation for more info.</p>
@@ -763,8 +765,8 @@
for the manager.</p>
</item>
- <marker id="db_init_error"></marker>
- <tag><c>db_init_error() = terminate | create | create_db_and_dir</c></tag>
+ <tag><marker id="db_init_error"></marker>
+ <c>db_init_error() = terminate | create | create_db_and_dir</c></tag>
<item>
<p>Defines what to do if the agent or manager is unable to open an
existing database file. <c>terminate</c> means that the
@@ -776,31 +778,31 @@
<p>Default is <c>terminate</c>.</p>
</item>
- <marker id="prio"></marker>
- <tag><c><![CDATA[priority() = atom() <optional>]]></c></tag>
+ <tag><marker id="prio"></marker>
+ <c><![CDATA[priority() = atom() <optional>]]></c></tag>
<item>
<p>Defines the Erlang priority for all SNMP processes.</p>
<p>Default is <c>normal</c>.</p>
</item>
- <marker id="versions"></marker>
- <tag><c><![CDATA[versions() = [version()] <optional>]]></c></tag>
+ <tag><marker id="versions"></marker>
+ <c><![CDATA[versions() = [version()] <optional>]]></c></tag>
<item>
<p><c>version() = v1 | v2 | v3</c></p>
<p>Which SNMP versions shall be accepted/used.</p>
<p>Default is <c>[v1,v2,v3]</c>.</p>
</item>
- <marker id="verbosity"></marker>
- <tag><c><![CDATA[verbosity() = silence | info | log | debug | trace <optional>]]></c></tag>
+ <tag><marker id="verbosity"></marker>
+ <c><![CDATA[verbosity() = silence | info | log | debug | trace <optional>]]></c></tag>
<item>
<p>Verbosity for a SNMP process. This specifies now much debug info
is printed.</p>
<p>Default is <c>silence</c>.</p>
</item>
- <marker id="bind_to"></marker>
- <tag><c><![CDATA[bind_to() = bool() <optional>]]></c></tag>
+ <tag><marker id="bind_to"></marker>
+ <c><![CDATA[bind_to() = bool() <optional>]]></c></tag>
<item>
<p>If <c>true</c>, net_if binds to the IP address.
If <c>false</c>, net_if listens on any IP address on the host
@@ -808,8 +810,8 @@
<p>Default is <c>false</c>.</p>
</item>
- <marker id="no_reuse"></marker>
- <tag><c><![CDATA[no_reuse() = bool() <optional>]]></c></tag>
+ <tag><marker id="no_reuse"></marker>
+ <c><![CDATA[no_reuse() = bool() <optional>]]></c></tag>
<item>
<p>If <c>true</c>, net_if does not specify that the IP
and port address should be reusable. If <c>false</c>,
@@ -817,30 +819,30 @@
<p>Default is <c>false</c>.</p>
</item>
- <marker id="recbuf"></marker>
- <tag><c><![CDATA[recbuf() = integer() <optional>]]></c></tag>
+ <tag><marker id="recbuf"></marker>
+ <c><![CDATA[recbuf() = integer() <optional>]]></c></tag>
<item>
<p>Receive buffer size. </p>
<p>Default value is defined by <c>gen_udp</c>.</p>
</item>
- <marker id="sndbuf"></marker>
- <tag><c><![CDATA[sndbuf() = integer() <optional>]]></c></tag>
+ <tag><marker id="sndbuf"></marker>
+ <c><![CDATA[sndbuf() = integer() <optional>]]></c></tag>
<item>
<p>Send buffer size. </p>
<p>Default value is defined by <c>gen_udp</c>.</p>
</item>
- <marker id="note_store"></marker>
- <tag><c><![CDATA[note_store() = [note_store_opt()] <optional>]]></c></tag>
+ <tag><marker id="note_store"></marker>
+ <c><![CDATA[note_store() = [note_store_opt()] <optional>]]></c></tag>
<item>
<p><c>note_store_opt() = {timeout, note_store_timeout()} | {verbosity, verbosity()}</c></p>
<p>Specifies the start-up verbosity for the SNMP note store.</p>
<p>For defaults see the options in <c>note_store_opt()</c>.</p>
</item>
- <marker id="ns_timeout"></marker>
- <tag><c><![CDATA[note_store_timeout() = integer() <optional>]]></c></tag>
+ <tag><marker id="ns_timeout"></marker>
+ <c><![CDATA[note_store_timeout() = integer() <optional>]]></c></tag>
<item>
<p>Note cleanup time. When storing a note in the note store,
each note is given lifetime. Every <c>timeout</c> the note_store
@@ -850,8 +852,8 @@
</item>
- <marker id="audit_trail_log"></marker>
- <tag><c><![CDATA[audit_trail_log() = [audit_trail_log_opt()] <optional>]]></c></tag>
+ <tag><marker id="audit_trail_log"></marker>
+ <c><![CDATA[audit_trail_log() = [audit_trail_log_opt()] <optional>]]></c></tag>
<item>
<p><c>audit_trail_log_opt() = {type, atl_type()} | {dir, atl_dir()} | {size, atl_size()} | {repair, atl_repair()} | {seqno, atl_seqno()}</c></p>
<p>If present, this option specifies the options for the
@@ -861,8 +863,8 @@
<p>If not present, audit trail logging is not used.</p>
</item>
- <marker id="atl_type"></marker>
- <tag><c><![CDATA[atl_type() = read | write | read_write <optional>]]></c></tag>
+ <tag><marker id="atl_type"></marker>
+ <c><![CDATA[atl_type() = read | write | read_write <optional>]]></c></tag>
<item>
<p>Specifies what type of an audit trail log should be used.
The effect of the type is actually different for the the agent
@@ -883,16 +885,16 @@
<p>Default is <c>read_write</c>.</p>
</item>
- <marker id="atl_dir"></marker>
- <tag><c><![CDATA[atl_dir = dir() <mandatory>]]></c></tag>
+ <tag><marker id="atl_dir"></marker>
+ <c><![CDATA[atl_dir = dir() <mandatory>]]></c></tag>
<item>
<p>Specifies where the audit trail log should be stored.</p>
<p>If <c>audit_trail_log</c> specifies that logging should take
place, this parameter <em>must</em> be defined.</p>
</item>
- <marker id="atl_size"></marker>
- <tag><c><![CDATA[atl_size() = {integer(), integer()} <mandatory>]]></c></tag>
+ <tag><marker id="atl_size"></marker>
+ <c><![CDATA[atl_size() = {integer(), integer()} <mandatory>]]></c></tag>
<item>
<p>Specifies the size of the audit
trail log. This parameter is sent to <c>disk_log</c>. </p>
@@ -900,8 +902,8 @@
take place, this parameter <em>must</em> be defined.</p>
</item>
- <marker id="atl_repair"></marker>
- <tag><c><![CDATA[atl_repair() = true | false | truncate | snmp_repair <optional>]]></c></tag>
+ <tag><marker id="atl_repair"></marker>
+ <c><![CDATA[atl_repair() = true | false | truncate | snmp_repair <optional>]]></c></tag>
<item>
<p>Specifies if and how the audit trail log shall be repaired
when opened. Unless this parameter has the value <c>snmp_repair</c>
@@ -913,8 +915,8 @@
<p>Default is <c>true</c>.</p>
</item>
- <marker id="atl_seqno"></marker>
- <tag><c><![CDATA[atl_seqno() = true | false <optional>]]></c></tag>
+ <tag><marker id="atl_seqno"></marker>
+ <c><![CDATA[atl_seqno() = true | false <optional>]]></c></tag>
<item>
<p>Specifies if the audit trail log entries will be (sequence)
numbered or not. The range of the sequence numbers are according
diff --git a/lib/snmp/doc/src/snmp_config.xml b/lib/snmp/doc/src/snmp_config.xml
index f10574a2a9..a085252d90 100644
--- a/lib/snmp/doc/src/snmp_config.xml
+++ b/lib/snmp/doc/src/snmp_config.xml
@@ -130,16 +130,16 @@
<marker id="agent_opts_and_types"></marker>
<p>Agent specific config options and types:</p>
<taglist>
- <marker id="agent_type"></marker>
- <tag><c><![CDATA[agent_type() = master | sub <optional>]]></c></tag>
+ <tag><marker id="agent_type"></marker>
+ <c><![CDATA[agent_type() = master | sub <optional>]]></c></tag>
<item>
<p>If <c>master</c>, one master agent is
started. Otherwise, no agents are started. </p>
<p>Default is <c>master</c>.</p>
</item>
- <marker id="agent_disco"></marker>
- <tag><c><![CDATA[agent_discovery() = [agent_discovery_opt()] <optional>]]></c></tag>
+ <tag><marker id="agent_disco"></marker>
+ <c><![CDATA[agent_discovery() = [agent_discovery_opt()] <optional>]]></c></tag>
<item>
<p><c>agent_discovery_opt() =
{terminating, agent_terminating_discovery_opts()} |
@@ -151,8 +151,8 @@
<p>For defaults see the options in <c>agent_discovery_opt()</c>.</p>
</item>
- <marker id="agent_term_disco_opts"></marker>
- <tag><c><![CDATA[agent_terminating_discovery_opts() = [agent_terminating_discovery_opt()] <optional>]]></c></tag>
+ <tag><marker id="agent_term_disco_opts"></marker>
+ <c><![CDATA[agent_terminating_discovery_opts() = [agent_terminating_discovery_opt()] <optional>]]></c></tag>
<item>
<p><c>agent_terminating_discovery_opt() =
{enable, boolean()} |
@@ -169,8 +169,8 @@
</list>
</item>
- <marker id="agent_orig_disco_opts"></marker>
- <tag><c><![CDATA[agent_originating_discovery_opts() = [agent_originating_discovery_opt()] <optional>]]></c></tag>
+ <tag><marker id="agent_orig_disco_opts"></marker>
+ <c><![CDATA[agent_originating_discovery_opts() = [agent_originating_discovery_opt()] <optional>]]></c></tag>
<item>
<p><c>agent_originating_discovery_opt() =
{enable, boolean()}</c></p>
@@ -183,38 +183,38 @@
</list>
</item>
- <marker id="agent_mt"></marker>
- <tag><c><![CDATA[multi_threaded() = bool() <optional>]]></c></tag>
+ <tag><marker id="agent_mt"></marker>
+ <c><![CDATA[multi_threaded() = bool() <optional>]]></c></tag>
<item>
<p>If <c>true</c>, the agent is multi-threaded, with one
thread for each get request. </p>
<p>Default is <c>false</c>.</p>
</item>
- <marker id="agent_data_dir"></marker>
- <tag><c><![CDATA[db_dir() = string() <mandatory>]]></c></tag>
+ <tag><marker id="agent_data_dir"></marker>
+ <c><![CDATA[db_dir() = string() <mandatory>]]></c></tag>
<item>
<p>Defines where the SNMP agent internal db files are stored.</p>
</item>
- <marker id="agent_gb_max_vbs"></marker>
- <tag><c><![CDATA[gb_max_vbs() = pos_integer() | infinity <optional>]]></c></tag>
+ <tag><marker id="agent_gb_max_vbs"></marker>
+ <c><![CDATA[gb_max_vbs() = pos_integer() | infinity <optional>]]></c></tag>
<item>
<p>Defines the maximum number of varbinds allowed
in a Get-BULK response.</p>
<p>Default is <c>1000</c>.</p>
</item>
- <marker id="agent_local_db"></marker>
- <tag><c><![CDATA[local_db() = [local_db_opt()] <optional>]]></c></tag>
+ <tag><marker id="agent_local_db"></marker>
+ <c><![CDATA[local_db() = [local_db_opt()] <optional>]]></c></tag>
<item>
<p><c>local_db_opt() = {repair, agent_repair()} | {auto_save, agent_auto_save()} | {verbosity, verbosity()}</c></p>
<p>Defines options specific for the SNMP agent local database.</p>
<p>For defaults see the options in <c>local_db_opt()</c>.</p>
</item>
- <marker id="agent_ldb_repair"></marker>
- <tag><c><![CDATA[agent_repair() = false | true | force <optional>]]></c></tag>
+ <tag><marker id="agent_ldb_repair"></marker>
+ <c><![CDATA[agent_repair() = false | true | force <optional>]]></c></tag>
<item>
<p>When starting snmpa_local_db it always tries to open an
existing database. If <c>false</c>, and some errors occur, a new
@@ -224,16 +224,16 @@
<p>Default is <c>true</c>.</p>
</item>
- <marker id="agent_ldb_auto_save"></marker>
- <tag><c><![CDATA[agent_auto_save() = integer() | infinity <optional>]]></c></tag>
+ <tag><marker id="agent_ldb_auto_save"></marker>
+ <c><![CDATA[agent_auto_save() = integer() | infinity <optional>]]></c></tag>
<item>
<p>The auto save interval. The table is flushed to disk
whenever not accessed for this amount of time.</p>
<p>Default is <c>5000</c>.</p>
</item>
- <marker id="agent_net_if"></marker>
- <tag><c><![CDATA[agent_net_if() = [agent_net_if_opt()] <optional>]]></c></tag>
+ <tag><marker id="agent_net_if"></marker>
+ <c><![CDATA[agent_net_if() = [agent_net_if_opt()] <optional>]]></c></tag>
<item>
<p><c>agent_net_if_option() = {module, agent_net_if_module()} |
{verbosity, verbosity()} |
@@ -243,8 +243,8 @@
<p>For defaults see the options in <c>agent_net_if_opt()</c>.</p>
</item>
- <marker id="agent_ni_module"></marker>
- <tag><c><![CDATA[agent_net_if_module() = atom() <optional>]]></c></tag>
+ <tag><marker id="agent_ni_module"></marker>
+ <c><![CDATA[agent_net_if_module() = atom() <optional>]]></c></tag>
<item>
<p>Module which handles the network interface part for the
SNMP agent. Must implement the
@@ -252,8 +252,8 @@
<p>Default is <c>snmpa_net_if</c>.</p>
</item>
- <marker id="agent_ni_opts"></marker>
- <tag><c><![CDATA[agent_net_if_options() = [agent_net_if_option()] <optional>]]></c></tag>
+ <tag><marker id="agent_ni_opts"></marker>
+ <c><![CDATA[agent_net_if_options() = [agent_net_if_option()] <optional>]]></c></tag>
<item>
<p><c>agent_net_if_option() = {bind_to, bind_to()} |
{sndbuf, sndbuf()} |
@@ -267,15 +267,15 @@
<p>For defaults see the options in <c>agent_net_if_option()</c>.</p>
</item>
- <marker id="agent_ni_req_limit"></marker>
- <tag><c><![CDATA[req_limit() = integer() | infinity <optional>]]></c></tag>
+ <tag><marker id="agent_ni_req_limit"></marker>
+ <c><![CDATA[req_limit() = integer() | infinity <optional>]]></c></tag>
<item>
<p>Max number of simultaneous requests handled by the agent.</p>
<p>Default is <c>infinity</c>.</p>
</item>
- <marker id="agent_ni_filter_opts"></marker>
- <tag><c><![CDATA[agent_net_if_filter_options() = [agent_net_if_filter_option()] <optional>]]></c></tag>
+ <tag><marker id="agent_ni_filter_opts"></marker>
+ <c><![CDATA[agent_net_if_filter_options() = [agent_net_if_filter_option()] <optional>]]></c></tag>
<item>
<p><c><![CDATA[agent_net_if_filter_option() = {module, agent_net_if_filter_module()}]]></c></p>
<p>These options are actually specific to the used module.
@@ -284,8 +284,8 @@
<p>For defaults see the options in <c>agent_net_if_filter_option()</c>.</p>
</item>
- <marker id="agent_ni_filter_module"></marker>
- <tag><c><![CDATA[agent_net_if_filter_module() = atom() <optional>]]></c></tag>
+ <tag><marker id="agent_ni_filter_module"></marker>
+ <c><![CDATA[agent_net_if_filter_module() = atom() <optional>]]></c></tag>
<item>
<p>Module which handles the network interface filter part for the
SNMP agent. Must implement the
@@ -294,8 +294,8 @@
<p>Default is <c>snmpa_net_if_filter</c>.</p>
</item>
- <marker id="agent_mibs"></marker>
- <tag><c><![CDATA[agent_mibs() = [string()] <optional>]]></c></tag>
+ <tag><marker id="agent_mibs"></marker>
+ <c><![CDATA[agent_mibs() = [string()] <optional>]]></c></tag>
<item>
<p>Specifies a list of MIBs (including path) that defines which MIBs
are initially loaded into the SNMP master agent. </p>
@@ -309,8 +309,8 @@
<p>Default is <c>[]</c>.</p>
</item>
- <marker id="agent_mib_storage"></marker>
- <tag><c><![CDATA[mib_storage() = [mib_storage_opt()] <optional>]]></c></tag>
+ <tag><marker id="agent_mib_storage"></marker>
+ <c><![CDATA[mib_storage() = [mib_storage_opt()] <optional>]]></c></tag>
<item>
<p><c>mib_storage_opt() = {module, mib_storage_module()} | {options, mib_storage_options()}</c></p>
<p>This option specifies how basic mib data is stored.
@@ -319,8 +319,8 @@
<p>Default is <c>[{module, snmpa_mib_storage_ets}]</c>. </p>
</item>
- <marker id="agent_mst_module"></marker>
- <tag><c><![CDATA[mib_storage_module() = snmpa_mib_data_ets | snmpa_mib_data_dets | snmpa_mib_data_mnesia | module()]]></c></tag>
+ <tag><marker id="agent_mst_module"></marker>
+ <c><![CDATA[mib_storage_module() = snmpa_mib_data_ets | snmpa_mib_data_dets | snmpa_mib_data_mnesia | module()]]></c></tag>
<item>
<p>Defines the mib storage module of the SNMP agent as defined by the
<seealso marker="snmpa_mib_storage">snmpa_mib_storage</seealso>
@@ -334,8 +334,8 @@
<p>Default module is <c>snmpa_mib_storage_ets</c>. </p>
</item>
- <marker id="agent_mst_options"></marker>
- <tag><c><![CDATA[mib_storage_options() = list() <optional>]]></c></tag>
+ <tag><marker id="agent_mst_options"></marker>
+ <c><![CDATA[mib_storage_options() = list() <optional>]]></c></tag>
<item>
<p>This is implementattion depended. That is, it depends on the
module. For each module a specific set of options are valid.
@@ -429,8 +429,8 @@
This is the old format which is "supported", but not documented,
in so far as it will be converted to the new format if found.
- <marker id="agent_mib_storage"></marker>
- <tag><c><![CDATA[mib_storage() = ets | {ets, Dir} | {ets, Dir, Action} | dets | {dets, Dir} | {dets, Dir, Action} | mnesia | {mnesia, Nodes} | {mnesia, Nodes, Action} <optional>]]></c></tag>
+ <tag><marker id="agent_mib_storage"></marker>
+ <c><![CDATA[mib_storage() = ets | {ets, Dir} | {ets, Dir, Action} | dets | {dets, Dir} | {dets, Dir, Action} | mnesia | {mnesia, Nodes} | {mnesia, Nodes, Action} <optional>]]></c></tag>
<item>
<p>Specifies how info retrieved from the mibs will be stored.</p>
<p>If <c>mib_storage</c> is <c>{ets, Dir}</c>, the table will also be
@@ -456,16 +456,16 @@ in so far as it will be converted to the new format if found.
</item>
-->
- <marker id="agent_mib_server"></marker>
- <tag><c><![CDATA[mib_server() = [mib_server_opt()] <optional>]]></c></tag>
+ <tag><marker id="agent_mib_server"></marker>
+ <c><![CDATA[mib_server() = [mib_server_opt()] <optional>]]></c></tag>
<item>
<p><c>mib_server_opt() = {mibentry_override, mibentry_override()} | {trapentry_override, trapentry_override()} | {verbosity, verbosity()} | {cache, mibs_cache()} | {data_module, mib_server_data_module()}</c></p>
<p>Defines options specific for the SNMP agent mib server. </p>
<p>For defaults see the options in <c>mib_server_opt()</c>.</p>
</item>
- <marker id="agent_ms_meo"></marker>
- <tag><c><![CDATA[mibentry_override() = bool() <optional>]]></c></tag>
+ <tag><marker id="agent_ms_meo"></marker>
+ <c><![CDATA[mibentry_override() = bool() <optional>]]></c></tag>
<item>
<p>If this value is false, then when loading a mib each mib-
entry is checked prior to installation of the mib.
@@ -474,8 +474,8 @@ in so far as it will be converted to the new format if found.
<p>Default is <c>false</c>.</p>
</item>
- <marker id="agent_ms_teo"></marker>
- <tag><c><![CDATA[trapentry_override() = bool() <optional>]]></c></tag>
+ <tag><marker id="agent_ms_teo"></marker>
+ <c><![CDATA[trapentry_override() = bool() <optional>]]></c></tag>
<item>
<p>If this value is false, then when loading a mib each trap
is checked prior to installation of the mib.
@@ -484,11 +484,13 @@ in so far as it will be converted to the new format if found.
<p>Default is <c>false</c>.</p>
</item>
- <marker id="agent_ms_data_module"></marker>
+
<!--
- <tag><c><![CDATA[mib_server_data_module() = snmpa_mib_data_tttn | snmpa_mib_data_ttln | module() <optional>]]></c></tag>
+ <tag><marker id="agent_ms_data_module"></marker>
+ <c><![CDATA[mib_server_data_module() = snmpa_mib_data_tttn | snmpa_mib_data_ttln | module() <optional>]]></c></tag>
-->
- <tag><c><![CDATA[mib_server_data_module() = snmpa_mib_data_tttn | module() <optional>]]></c></tag>
+ <tag><marker id="agent_ms_data_module"></marker>
+ <c><![CDATA[mib_server_data_module() = snmpa_mib_data_tttn | module() <optional>]]></c></tag>
<item>
<p>Defines the backend data module of the SNMP agent mib-server as
defined by the
@@ -505,24 +507,24 @@ in so far as it will be converted to the new format if found.
<p>Default module is <c>snmpa_mib_data_tttn</c>. </p>
</item>
- <marker id="agent_ms_cache"></marker>
- <tag><c><![CDATA[mibs_cache() = bool() | mibs_cache_opts() <optional>]]></c></tag>
+ <tag><marker id="agent_ms_cache"></marker>
+ <c><![CDATA[mibs_cache() = bool() | mibs_cache_opts() <optional>]]></c></tag>
<item>
<p>Shall the agent utilize the mib server lookup cache or not.</p>
<p>Default is <c>true</c> (in which case the <c>mibs_cache_opts()</c>
default values apply).</p>
</item>
- <marker id="agent_ms_cache_opts"></marker>
- <tag><c><![CDATA[mibs_cache_opts() = [mibs_cache_opt()] <optional>]]></c></tag>
+ <tag><marker id="agent_ms_cache_opts"></marker>
+ <c><![CDATA[mibs_cache_opts() = [mibs_cache_opt()] <optional>]]></c></tag>
<item>
<p><c>mibs_cache_opt() = {autogc, mibs_cache_autogc()} | {gclimit, mibs_cache_gclimit()} | {age, mibs_cache_age()}</c></p>
<p>Defines options specific for the SNMP agent mib server cache. </p>
<p>For defaults see the options in <c>mibs_cache_opt()</c>.</p>
</item>
- <marker id="agent_ms_cache_autogc"></marker>
- <tag><c><![CDATA[mibs_cache_autogc() = bool() <optional>]]></c></tag>
+ <tag><marker id="agent_ms_cache_autogc"></marker>
+ <c><![CDATA[mibs_cache_autogc() = bool() <optional>]]></c></tag>
<item>
<p>Defines if the mib server shall perform cache gc automatically or
leave it to the user (see
@@ -530,8 +532,8 @@ in so far as it will be converted to the new format if found.
<p>Default is <c>true</c>.</p>
</item>
- <marker id="agent_ms_cache_age"></marker>
- <tag><c><![CDATA[mibs_cache_age() = integer() > 0 <optional>]]></c></tag>
+ <tag><marker id="agent_ms_cache_age"></marker>
+ <c><![CDATA[mibs_cache_age() = integer() > 0 <optional>]]></c></tag>
<item>
<p>Defines how old the entries in the cache will be allowed
to become before they are GC'ed (assuming GC is performed).
@@ -540,8 +542,8 @@ in so far as it will be converted to the new format if found.
<p>Default is <c>10 timutes</c>.</p>
</item>
- <marker id="agent_ms_cache_gclimit"></marker>
- <tag><c><![CDATA[mibs_cache_gclimit() = integer() > 0 | infinity <optional>]]></c></tag>
+ <tag><marker id="agent_ms_cache_gclimit"></marker>
+ <c><![CDATA[mibs_cache_gclimit() = integer() > 0 | infinity <optional>]]></c></tag>
<item>
<p>When performing a GC, this is the max number of cache entries
that will be deleted from the cache. </p>
@@ -551,8 +553,8 @@ in so far as it will be converted to the new format if found.
<p>Default is <c>100</c>.</p>
</item>
- <marker id="agent_error_report_mod"></marker>
- <tag><c><![CDATA[error_report_mod() = atom() <optional>]]></c></tag>
+ <tag><marker id="agent_error_report_mod"></marker>
+ <c><![CDATA[error_report_mod() = atom() <optional>]]></c></tag>
<item>
<p>Defines an error report module, implementing the
<seealso marker="snmpa_error_report">snmpa_error_report</seealso>
@@ -561,38 +563,38 @@ in so far as it will be converted to the new format if found.
<p>Default is <c>snmpa_error_logger</c>.</p>
</item>
- <marker id="agent_symbolic_store"></marker>
- <tag><c>symbolic_store() = [symbolic_store_opt()]</c></tag>
+ <tag><marker id="agent_symbolic_store"></marker>
+ <c>symbolic_store() = [symbolic_store_opt()]</c></tag>
<item>
<p><c>symbolic_store_opt() = {verbosity, verbosity()}</c></p>
<p>Defines options specific for the SNMP agent symbolic store. </p>
<p>For defaults see the options in <c>symbolic_store_opt()</c>.</p>
</item>
- <marker id="agent_target_cache"></marker>
- <tag><c>target_cache() = [target_cache_opt()]</c></tag>
+ <tag><marker id="agent_target_cache"></marker>
+ <c>target_cache() = [target_cache_opt()]</c></tag>
<item>
<p><c>target_cache_opt() = {verbosity, verbosity()}</c></p>
<p>Defines options specific for the SNMP agent target cache. </p>
<p>For defaults see the options in <c>target_cache_opt()</c>.</p>
</item>
- <marker id="agent_config"></marker>
- <tag><c><![CDATA[agent_config() = [agent_config_opt()] <mandatory>]]></c></tag>
+ <tag><marker id="agent_config"></marker>
+ <c><![CDATA[agent_config() = [agent_config_opt()] <mandatory>]]></c></tag>
<item>
<p><c>agent_config_opt() = {dir, agent_config_dir()} | {force_load, force_load()} | {verbosity, verbosity()}</c></p>
<p>Defines specific config related options for the SNMP agent. </p>
<p>For defaults see the options in <c>agent_config_opt()</c>.</p>
</item>
- <marker id="agent_config_dir"></marker>
- <tag><c><![CDATA[agent_config_dir = dir() <mandatory>]]></c></tag>
+ <tag><marker id="agent_config_dir"></marker>
+ <c><![CDATA[agent_config_dir = dir() <mandatory>]]></c></tag>
<item>
<p>Defines where the SNMP agent configuration files are stored.</p>
</item>
- <marker id="agent_force_load"></marker>
- <tag><c><![CDATA[force_load() = bool() <optional>]]></c></tag>
+ <tag><marker id="agent_force_load"></marker>
+ <c><![CDATA[force_load() = bool() <optional>]]></c></tag>
<item>
<p>If <c>true</c> the configuration files are re-read
during start-up, and the contents of the configuration
@@ -606,16 +608,16 @@ in so far as it will be converted to the new format if found.
<marker id="manager_opts_and_types"></marker>
<p>Manager specific config options and types:</p>
<taglist>
- <marker id="manager_server"></marker>
- <tag><c><![CDATA[server() = [server_opt()] <optional>]]></c></tag>
+ <tag><marker id="manager_server"></marker>
+ <c><![CDATA[server() = [server_opt()] <optional>]]></c></tag>
<item>
<p><c>server_opt() = {timeout, server_timeout()} | {verbosity, verbosity()}</c></p>
<p>Specifies the options for the manager server process.</p>
<p>Default is <c>silence</c>.</p>
</item>
- <marker id="manager_server_timeout"></marker>
- <tag><c><![CDATA[server_timeout() = integer() <optional>]]></c></tag>
+ <tag><marker id="manager_server_timeout"></marker>
+ <c><![CDATA[server_timeout() = integer() <optional>]]></c></tag>
<item>
<p>Asynchronous request cleanup time. For every requests,
some info is stored internally, in order to be able to
@@ -635,44 +637,44 @@ in so far as it will be converted to the new format if found.
<p>Default is <c>30000</c>.</p>
</item>
- <marker id="manager_config"></marker>
- <tag><c><![CDATA[manager_config() = [manager_config_opt()] <mandatory>]]></c></tag>
+ <tag><marker id="manager_config"></marker>
+ <c><![CDATA[manager_config() = [manager_config_opt()] <mandatory>]]></c></tag>
<item>
<p><c>manager_config_opt() = {dir, manager_config_dir()} | {db_dir, manager_db_dir()} | {db_init_error, db_init_error()} | {repair, manager_repair()} | {auto_save, manager_auto_save()} | {verbosity, verbosity()}</c></p>
<p>Defines specific config related options for the SNMP manager. </p>
<p>For defaults see the options in <c>manager_config_opt()</c>.</p>
</item>
- <marker id="manager_config_dir"></marker>
- <tag><c><![CDATA[manager_config_dir = dir() <mandatory>]]></c></tag>
+ <tag><marker id="manager_config_dir"></marker>
+ <c><![CDATA[manager_config_dir = dir() <mandatory>]]></c></tag>
<item>
<p>Defines where the SNMP manager configuration files are stored.</p>
</item>
- <marker id="manager_config_db_dir"></marker>
- <tag><c><![CDATA[manager_db_dir = dir() <mandatory>]]></c></tag>
+ <tag><marker id="manager_config_db_dir"></marker>
+ <c><![CDATA[manager_db_dir = dir() <mandatory>]]></c></tag>
<item>
<p>Defines where the SNMP manager store persistent data.</p>
</item>
- <marker id="manager_config_repair"></marker>
- <tag><c><![CDATA[manager_repair() = false | true | force <optional>]]></c></tag>
+ <tag><marker id="manager_config_repair"></marker>
+ <c><![CDATA[manager_repair() = false | true | force <optional>]]></c></tag>
<item>
<p>Defines the repair option for the persistent database (if
and how the table is repaired when opened). </p>
<p>Default is <c>true</c>.</p>
</item>
- <marker id="manager_config_auto_save"></marker>
- <tag><c><![CDATA[manager_auto_save() = integer() | infinity <optional>]]></c></tag>
+ <tag><marker id="manager_config_auto_save"></marker>
+ <c><![CDATA[manager_auto_save() = integer() | infinity <optional>]]></c></tag>
<item>
<p>The auto save interval. The table is flushed to disk
whenever not accessed for this amount of time.</p>
<p>Default is <c>5000</c>.</p>
</item>
- <marker id="manager_irb"></marker>
- <tag><c><![CDATA[manager_irb() = auto | user | {user, integer()} <optional>]]></c></tag>
+ <tag><marker id="manager_irb"></marker>
+ <c><![CDATA[manager_irb() = auto | user | {user, integer()} <optional>]]></c></tag>
<item>
<p>This option defines how the manager will handle the sending of
response (acknowledgment) to received inform-requests. </p>
@@ -701,16 +703,16 @@ in so far as it will be converted to the new format if found.
<p>Default is <c>auto</c>.</p>
</item>
- <marker id="manager_mibs"></marker>
- <tag><c><![CDATA[manager_mibs() = [string()] <optional>]]></c></tag>
+ <tag><marker id="manager_mibs"></marker>
+ <c><![CDATA[manager_mibs() = [string()] <optional>]]></c></tag>
<item>
<p>Specifies a list of MIBs (including path) and defines which MIBs
are initially loaded into the SNMP manager. </p>
<p>Default is <c>[]</c>.</p>
</item>
- <marker id="manager_net_if"></marker>
- <tag><c><![CDATA[manager_net_if() = [manager_net_if_opt()] <optional>]]></c></tag>
+ <tag><marker id="manager_net_if"></marker>
+ <c><![CDATA[manager_net_if() = [manager_net_if_opt()] <optional>]]></c></tag>
<item>
<p><c>manager_net_if_opt() = {module, manager_net_if_module()} |
{verbosity, verbosity()} |
@@ -720,8 +722,8 @@ in so far as it will be converted to the new format if found.
<p>For defaults see the options in <c>manager_net_if_opt()</c>.</p>
</item>
- <marker id="manager_ni_opts"></marker>
- <tag><c><![CDATA[manager_net_if_options() = [manager_net_if_option()] <optional>]]></c></tag>
+ <tag><marker id="manager_ni_opts"></marker>
+ <c><![CDATA[manager_net_if_options() = [manager_net_if_option()] <optional>]]></c></tag>
<item>
<p><c>manager_net_if_option() = {bind_to, bind_to()} |
{sndbuf, sndbuf()} |
@@ -734,8 +736,8 @@ in so far as it will be converted to the new format if found.
<p>For defaults see the options in <c>manager_net_if_option()</c>.</p>
</item>
- <marker id="manager_ni_module"></marker>
- <tag><c><![CDATA[manager_net_if_module() = atom() <optional>]]></c></tag>
+ <tag><marker id="manager_ni_module"></marker>
+ <c><![CDATA[manager_net_if_module() = atom() <optional>]]></c></tag>
<item>
<p>The module which handles the network interface part for the
SNMP manager. It must implement the
@@ -743,8 +745,8 @@ in so far as it will be converted to the new format if found.
<p>Default is <c>snmpm_net_if</c>. </p>
</item>
- <marker id="manager_ni_filter_opts"></marker>
- <tag><c><![CDATA[manager_net_if_filter_options() = [manager_net_if_filter_option()] <optional>]]></c></tag>
+ <tag><marker id="manager_ni_filter_opts"></marker>
+ <c><![CDATA[manager_net_if_filter_options() = [manager_net_if_filter_option()] <optional>]]></c></tag>
<item>
<p><c>manager_net_if_filter_option() = {module, manager_net_if_filter_module()}</c></p>
<p>These options are actually specific to the used module.
@@ -754,8 +756,8 @@ in so far as it will be converted to the new format if found.
<c>manager_net_if_filter_option()</c>.</p>
</item>
- <marker id="manager_ni_filter_module"></marker>
- <tag><c><![CDATA[manager_net_if_filter_module() = atom() <optional>]]></c></tag>
+ <tag><marker id="manager_ni_filter_module"></marker>
+ <c><![CDATA[manager_net_if_filter_module() = atom() <optional>]]></c></tag>
<item>
<p>Module which handles the network interface filter part for the
SNMP manager. Must implement the
@@ -763,16 +765,16 @@ in so far as it will be converted to the new format if found.
<p>Default is <c>snmpm_net_if_filter</c>.</p>
</item>
- <marker id="manager_def_user_module"></marker>
- <tag><c><![CDATA[def_user_module() = atom() <optional>]]></c></tag>
+ <tag><marker id="manager_def_user_module"></marker>
+ <c><![CDATA[def_user_module() = atom() <optional>]]></c></tag>
<item>
<p>The module implementing the default user. See the
<seealso marker="snmpm_user">snmpm_user</seealso> behaviour.</p>
<p>Default is <c>snmpm_user_default</c>.</p>
</item>
- <marker id="manager_def_user_data"></marker>
- <tag><c><![CDATA[def_user_data() = term() <optional>]]></c></tag>
+ <tag><marker id="manager_def_user_data"></marker>
+ <c><![CDATA[def_user_data() = term() <optional>]]></c></tag>
<item>
<p>Data for the default user. Passed to the user when calling
the callback functions.</p>
@@ -783,8 +785,8 @@ in so far as it will be converted to the new format if found.
<marker id="common_types"></marker>
<p>Common config types:</p>
<taglist>
- <marker id="restart_type"></marker>
- <tag><c>restart_type() = permanent | transient | temporary</c></tag>
+ <tag><marker id="restart_type"></marker>
+ <c>restart_type() = permanent | transient | temporary</c></tag>
<item>
<p>See <seealso marker="stdlib:supervisor#child_spec">supervisor</seealso>
documentation for more info.</p>
@@ -792,8 +794,8 @@ in so far as it will be converted to the new format if found.
for the manager.</p>
</item>
- <marker id="db_init_error"></marker>
- <tag><c>db_init_error() = terminate | create | create_db_and_dir</c></tag>
+ <tag><marker id="db_init_error"></marker>
+ <c>db_init_error() = terminate | create | create_db_and_dir</c></tag>
<item>
<p>Defines what to do if the agent is unable to open an
existing database file. <c>terminate</c> means that the
@@ -805,31 +807,31 @@ in so far as it will be converted to the new format if found.
<p>Default is <c>terminate</c>.</p>
</item>
- <marker id="prio"></marker>
- <tag><c><![CDATA[priority() = atom() <optional>]]></c></tag>
+ <tag><marker id="prio"></marker>
+ <c><![CDATA[priority() = atom() <optional>]]></c></tag>
<item>
<p>Defines the Erlang priority for all SNMP processes.</p>
<p>Default is <c>normal</c>.</p>
</item>
- <marker id="versions"></marker>
- <tag><c><![CDATA[versions() = [version()] <optional>]]></c></tag>
+ <tag><marker id="versions"></marker>
+ <c><![CDATA[versions() = [version()] <optional>]]></c></tag>
<item>
<p><c>version() = v1 | v2 | v3</c></p>
<p>Which SNMP versions shall be accepted/used.</p>
<p>Default is <c>[v1,v2,v3]</c>.</p>
</item>
- <marker id="verbosity"></marker>
- <tag><c><![CDATA[verbosity() = silence | info | log | debug | trace <optional>]]></c></tag>
+ <tag><marker id="verbosity"></marker>
+ <c><![CDATA[verbosity() = silence | info | log | debug | trace <optional>]]></c></tag>
<item>
<p>Verbosity for a SNMP process. This specifies now much debug info
is printed.</p>
<p>Default is <c>silence</c>.</p>
</item>
- <marker id="bind_to"></marker>
- <tag><c><![CDATA[bind_to() = bool() <optional>]]></c></tag>
+ <tag><marker id="bind_to"></marker>
+ <c><![CDATA[bind_to() = bool() <optional>]]></c></tag>
<item>
<p>If <c>true</c>, net_if binds to the IP address.
If <c>false</c>, net_if listens on any IP address on the host
@@ -837,8 +839,8 @@ in so far as it will be converted to the new format if found.
<p>Default is <c>false</c>.</p>
</item>
- <marker id="no_reuse"></marker>
- <tag><c><![CDATA[no_reuse() = bool() <optional>]]></c></tag>
+ <tag><marker id="no_reuse"></marker>
+ <c><![CDATA[no_reuse() = bool() <optional>]]></c></tag>
<item>
<p>If <c>true</c>, net_if does not specify that the IP
and port address should be reusable. If <c>false</c>,
@@ -846,30 +848,30 @@ in so far as it will be converted to the new format if found.
<p>Default is <c>false</c>.</p>
</item>
- <marker id="recbuf"></marker>
- <tag><c><![CDATA[recbuf() = integer() <optional>]]></c></tag>
+ <tag><marker id="recbuf"></marker>
+ <c><![CDATA[recbuf() = integer() <optional>]]></c></tag>
<item>
<p>Receive buffer size. </p>
<p>Default value is defined by <c>gen_udp</c>.</p>
</item>
- <marker id="sndbuf"></marker>
- <tag><c><![CDATA[sndbuf() = integer() <optional>]]></c></tag>
+ <tag><marker id="sndbuf"></marker>
+ <c><![CDATA[sndbuf() = integer() <optional>]]></c></tag>
<item>
<p>Send buffer size. </p>
<p>Default value is defined by <c>gen_udp</c>.</p>
</item>
- <marker id="note_store"></marker>
- <tag><c><![CDATA[note_store() = [note_store_opt()] <optional>]]></c></tag>
+ <tag><marker id="note_store"></marker>
+ <c><![CDATA[note_store() = [note_store_opt()] <optional>]]></c></tag>
<item>
<p><c>note_store_opt() = {timeout, note_store_timeout()} | {verbosity, verbosity()}</c></p>
<p>Specifies the options for the SNMP note store.</p>
<p>For defaults see the options in <c>note_store_opt()</c>.</p>
</item>
- <marker id="ns_timeout"></marker>
- <tag><c><![CDATA[note_store_timeout() = integer() <optional>]]></c></tag>
+ <tag><marker id="ns_timeout"></marker>
+ <c><![CDATA[note_store_timeout() = integer() <optional>]]></c></tag>
<item>
<p>Note cleanup time. When storing a note in the note store,
each note is given lifetime. Every <c>timeout</c> the note_store
@@ -878,8 +880,8 @@ in so far as it will be converted to the new format if found.
<p>Default is <c>30000</c>.</p>
</item>
- <marker id="audit_trail_log"></marker>
- <tag><c><![CDATA[audit_trail_log() [audit_trail_log_opt()] <optional>]]></c></tag>
+ <tag><marker id="audit_trail_log"></marker>
+ <c><![CDATA[audit_trail_log() [audit_trail_log_opt()] <optional>]]></c></tag>
<item>
<p><c>audit_trail_log_opt() = {type, atl_type()} | {dir, atl_dir()} | {size, atl_size()} | {repair, atl_repair()} | {seqno, atl_seqno()}</c></p>
<p>If present, this option specifies the options for the
@@ -889,8 +891,8 @@ in so far as it will be converted to the new format if found.
<p>If not present, audit trail logging is not used.</p>
</item>
- <marker id="atl_type"></marker>
- <tag><c><![CDATA[atl_type() = read | write | read_write <optional>]]></c></tag>
+ <tag><marker id="atl_type"></marker>
+ <c><![CDATA[atl_type() = read | write | read_write <optional>]]></c></tag>
<item>
<p>Specifies what type of an audit trail log should be used.
The effect of the type is actually different for the the agent
@@ -911,16 +913,16 @@ in so far as it will be converted to the new format if found.
<p>Default is <c>read_write</c>.</p>
</item>
- <marker id="atl_dir"></marker>
- <tag><c><![CDATA[atl_dir = dir() <mandatory>]]></c></tag>
+ <tag><marker id="atl_dir"></marker>
+ <c><![CDATA[atl_dir = dir() <mandatory>]]></c></tag>
<item>
<p>Specifies where the audit trail log should be stored.</p>
<p>If <c>audit_trail_log</c> specifies that logging should take
place, this parameter <em>must</em> be defined.</p>
</item>
- <marker id="atl_size"></marker>
- <tag><c><![CDATA[atl_size() = {integer(), integer()} <mandatory>]]></c></tag>
+ <tag><marker id="atl_size"></marker>
+ <c><![CDATA[atl_size() = {integer(), integer()} <mandatory>]]></c></tag>
<item>
<p>Specifies the size of the audit
trail log. This parameter is sent to <c>disk_log</c>. </p>
@@ -928,8 +930,8 @@ in so far as it will be converted to the new format if found.
take place, this parameter <em>must</em> be defined.</p>
</item>
- <marker id="atl_repair"></marker>
- <tag><c><![CDATA[atl_repair() = true | false | truncate | snmp_repair <optional>]]></c></tag>
+ <tag><marker id="atl_repair"></marker>
+ <c><![CDATA[atl_repair() = true | false | truncate | snmp_repair <optional>]]></c></tag>
<item>
<p>Specifies if and how the audit trail log shall be repaired
when opened. Unless this parameter has the value <c>snmp_repair</c>
@@ -941,8 +943,8 @@ in so far as it will be converted to the new format if found.
<p>Default is <c>true</c>.</p>
</item>
- <marker id="atl_seqno"></marker>
- <tag><c><![CDATA[atl_seqno() = true | false <optional>]]></c></tag>
+ <tag><marker id="atl_seqno"></marker>
+ <c><![CDATA[atl_seqno() = true | false <optional>]]></c></tag>
<item>
<p>Specifies if the audit trail log entries will be (sequence)
numbered or not. The range of the sequence numbers are according
diff --git a/lib/snmp/doc/src/snmp_manager_netif.xml b/lib/snmp/doc/src/snmp_manager_netif.xml
index 8454d03b17..98d4e7fd96 100644
--- a/lib/snmp/doc/src/snmp_manager_netif.xml
+++ b/lib/snmp/doc/src/snmp_manager_netif.xml
@@ -75,8 +75,7 @@
<p>In this section a <c>Domain</c> field is the transport domain i.e
one of <c>transportDomainUdpIpv4</c> or <c>transportDomainUdpIpv6</c>,
and an <c>Addr</c> field is an
- <c>{<seealso marker="kernel:inet#type-ip_address">IpAddr</seealso>,
- IpPort}</c> tuple.</p>
+ <c>{</c><seealso marker="kernel:inet#type-ip_address"><c>IpAddr</c></seealso><c>,IpPort}</c> tuple.</p>
<p>Net if must send the following message when it receives an
SNMP PDU from the network that is aimed for the MasterAgent:
diff --git a/lib/snmp/doc/src/snmpa.xml b/lib/snmp/doc/src/snmpa.xml
index f205af6e88..c84eeec524 100644
--- a/lib/snmp/doc/src/snmpa.xml
+++ b/lib/snmp/doc/src/snmpa.xml
@@ -622,12 +622,12 @@ notification_delivery_info() = #snmpa_notification_delivery_info{}
<p>Converts an Audit Trail Log to a readable format and
prints it on stdio.
<c>LogName</c> defaults to "snmpa_log".
- <c>LogFile</c> defaults to "snmpa.log".
+ <c>LogFile</c> defaults to "snmpa.log".</p>
<p>The <c>Block</c> option indicates if the log should be blocked
during conversion. This could be usefull when converting large
logs (when otherwise the log could wrap during conversion).
Defaults to <c>true</c>. </p>
- See <seealso marker="snmp#log_to_io">snmp:log_to_io</seealso>
+ <p>See <seealso marker="snmp#log_to_io">snmp:log_to_io</seealso>
for more info.</p>
<marker id="change_log_size"></marker>
diff --git a/lib/snmp/doc/src/snmpm.xml b/lib/snmp/doc/src/snmpm.xml
index b14c0e6afd..ab288fd020 100644
--- a/lib/snmp/doc/src/snmpm.xml
+++ b/lib/snmp/doc/src/snmpm.xml
@@ -1241,12 +1241,12 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1
<p>Converts an Audit Trail Log to a readable text file.
<c>OutFile</c> defaults to "./snmpm_log.txt".
<c>LogName</c> defaults to "snmpm_log".
- <c>LogFile</c> defaults to "snmpm.log".
+ <c>LogFile</c> defaults to "snmpm.log".</p>
<p>The <c>Block</c> argument indicates if the log should be blocked
during conversion. This could be usefull when converting large
logs (when otherwise the log could wrap during conversion).
Defaults to <c>true</c>. </p>
- See <seealso marker="snmp#log_to_txt">snmp:log_to_txt</seealso>
+ <p>See <seealso marker="snmp#log_to_txt">snmp:log_to_txt</seealso>
for more info.</p>
<marker id="log_to_io"></marker>
@@ -1280,12 +1280,12 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1
<p>Converts an Audit Trail Log to a readable format and
prints it on stdio.
<c>LogName</c> defaults to "snmpm_log".
- <c>LogFile</c> defaults to "snmpm.log".
+ <c>LogFile</c> defaults to "snmpm.log".</p>
<p>The <c>Block</c> argument indicates if the log should be blocked
during conversion. This could be usefull when converting large
logs (when otherwise the log could wrap during conversion).
Defaults to <c>true</c>. </p>
- See <seealso marker="snmp#log_to_io">snmp:log_to_io</seealso>
+ <p>See <seealso marker="snmp#log_to_io">snmp:log_to_io</seealso>
for more info.</p>
<marker id="change_log_size"></marker>
diff --git a/lib/snmp/src/app/snmp.appup.src b/lib/snmp/src/app/snmp.appup.src
index 6632d29457..f2936c0c1d 100644
--- a/lib/snmp/src/app/snmp.appup.src
+++ b/lib/snmp/src/app/snmp.appup.src
@@ -29,6 +29,7 @@
%% {update, snmpa_local_db, soft, soft_purge, soft_purge, []}
%% {add_module, snmpm_net_if_mt}
[
+ {"5.3", [{load_module, snmp_conf, soft_purge, soft_purge, []}]},
{"5.1.2", [ % Only runtime dependencies change
]},
{"5.1.1", [{restart_application, snmp}]},
diff --git a/lib/snmp/src/misc/snmp_conf.erl b/lib/snmp/src/misc/snmp_conf.erl
index 0364613f8e..6264d79cec 100644
--- a/lib/snmp/src/misc/snmp_conf.erl
+++ b/lib/snmp/src/misc/snmp_conf.erl
@@ -1005,6 +1005,8 @@ check_imask(IMask) when is_list(IMask) ->
do_check_imask(IMask),
{ok, IMask}.
+do_check_imask([]) ->
+ ok;
do_check_imask([0|IMask]) ->
do_check_imask(IMask);
do_check_imask([1|IMask]) ->
diff --git a/lib/ssh/doc/src/notes.xml b/lib/ssh/doc/src/notes.xml
index 368bb0f552..010b1b15c7 100644
--- a/lib/ssh/doc/src/notes.xml
+++ b/lib/ssh/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2014</year>
+ <year>2004</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -30,6 +30,54 @@
<file>notes.xml</file>
</header>
+<section><title>Ssh 4.1.3</title>
+
+ <section><title>Known Bugs and Problems</title>
+ <list>
+ <item>
+ <p>
+ SSH_MSG_KEX_DH_GEX_REQUEST_OLD implemented to make PuTTY
+ work with erl server.</p>
+ <p>
+ Own Id: OTP-13140</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.1.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Add a 1024 group to the list of key group-exchange groups</p>
+ <p>
+ Own Id: OTP-13046</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.1.1</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ A new option <c>max_channels</c> limits the number of
+ channels with active server-side subsystems that are
+ accepted.</p>
+ <p>
+ Own Id: OTP-13036</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Ssh 4.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -184,9 +232,9 @@
<p>
Thanks to Simon Cornish</p>
<p>
- Own Id: OTP-12760 Aux Id: <a
+ Own Id: OTP-12760 Aux Id: <url
href="https://github.com/erlang/otp/pull/715">pull req
- 715</a> </p>
+ 715</url> </p>
</item>
<item>
<p>
@@ -352,13 +400,13 @@
</item>
<item>
<p>
- Made Codenomicon Defensics test suite pass: <list>
+ Made Codenomicon Defensics test suite pass:</p> <list>
<item>limit number of algorithms in kexinit
message</item> <item>check 'e' and 'f' parameters in
kexdh</item> <item>implement 'keyboard-interactive' user
authentication on server side</item> <item> return plain
text message to bad version exchange message</item>
- </list></p>
+ </list>
<p>
Own Id: OTP-12784</p>
</item>
diff --git a/lib/ssh/doc/src/ssh.xml b/lib/ssh/doc/src/ssh.xml
index cf5e8f1aff..b3f850fc38 100644
--- a/lib/ssh/doc/src/ssh.xml
+++ b/lib/ssh/doc/src/ssh.xml
@@ -32,28 +32,33 @@
<modulesummary>Main API of the ssh application</modulesummary>
<description>
<p>Interface module for the <c>ssh</c> application.</p>
+ <p>See <seealso marker="ssh:SSH_app#supported">ssh(6)</seealso> for details of supported version,
+ algorithms and unicode support.</p>
</description>
- <section>
- <title>SSH</title>
- <marker id="supported"/>
- <list type="bulleted">
- <item>For application dependencies see <seealso marker="SSH_app"> ssh(6)</seealso> </item>
- <item>Supported SSH version is 2.0.</item>
- <item>Supported public key algorithms: ssh-rsa and ssh-dss.</item>
- <item>Supported MAC algorithms: hmac-sha2-256 and hmac-sha1.</item>
- <item>Supported encryption algorithms: aes128-ctr, aes128-cb and 3des-cbc.</item>
- <item>Supported key exchange algorithms: diffie-hellman-group1-sha1, diffie-hellman-group14-sha1, diffie-hellman-group-exchange-sha1 and diffie-hellman-group-exchange-sha256.</item>
- <item>Supported compression algorithms: none, zlib, [email protected],</item>
- <item>Supports unicode filenames if the emulator and the underlaying OS support it.
- See section DESCRIPTION in the
- <seealso marker="kernel:file">file</seealso> manual page in <c>kernel</c>
- for information about this subject.</item>
- <item>Supports unicode in shell and CLI.</item>
- </list>
-
+ <section>
+ <title>OPTIONS</title>
+ <p>The exact behaviour of some functions can be adjusted with the use of options which are documented together
+ with the functions. Generally could each option be used at most one time in each function call. If given two or more
+ times, the effect is not predictable unless explicitly documented.</p>
+ <p>The options are of different kinds:</p>
+ <taglist>
+ <tag>Limits</tag>
+ <item><p>which alters limits in the system, for example number of simultaneous login attempts.</p></item>
+
+ <tag>Timeouts</tag>
+ <item><p>which give some defined behaviour if too long time elapses before a given event or action,
+ for example time to wait for an answer.</p></item>
+
+ <tag>Callbacks</tag>
+ <item><p>which gives the caller of the function the possibility to execute own code on some events,
+ for example calling an own logging function or to perform an own login function</p></item>
+
+ <tag>Behaviour</tag>
+ <item><p>which changes the systems behaviour.</p></item>
+ </taglist>
</section>
-
+
<section>
<title>DATA TYPES</title>
<p>Type definitions that are used more than once in
@@ -80,6 +85,15 @@
<item><p><c>atom()</c> - Name of the Erlang module
implementing the subsystem using the <c>ssh_channel</c> behavior, see
<seealso marker="ssh_channel">ssh_channel(3)</seealso></p></item>
+ <tag><c>key_cb() =</c></tag>
+ <item>
+ <p><c>atom() | {atom(), list()}</c></p>
+ <p><c>atom()</c> - Name of the erlang module implementing the behaviours
+ <seealso marker="ssh_client_key_api">ssh_client_key_api</seealso> or
+ <seealso marker="ssh_client_key_api">ssh_client_key_api</seealso> as the
+ case maybe.</p>
+ <p><c>list()</c> - List of options that can be passed to the callback module.</p>
+ </item>
<tag><c>channel_init_args() =</c></tag>
<item><p><c>list()</c></p></item>
@@ -192,26 +206,25 @@
<tag><c><![CDATA[{public_key_alg, 'ssh-rsa' | 'ssh-dss'}]]></c></tag>
<item>
<note>
- <p>This option is kept for compatibility. It is ignored if the <c>preferred_algorithms</c>
- option is used. The equivalence of <c>{public_key_alg,'ssh-dss'}</c> is
- <c>{preferred_algorithms, [{public_key,['ssh-dss','ssh-rsa']}]}</c>.</p>
+ <p>This option will be removed in OTP 20, but is kept for compatibility. It is ignored if
+ the preferred <c>pref_public_key_algs</c> option is used.</p>
</note>
<p>Sets the preferred public key algorithm to use for user
authentication. If the preferred algorithm fails,
- the other algorithm is tried. The default is
- to try <c><![CDATA['ssh-rsa']]></c> first.</p>
+ the other algorithm is tried. If <c>{public_key_alg, 'ssh-rsa'}</c> is set, it is translated
+ to <c>{pref_public_key_algs, ['ssh-rsa','ssh-dss']}</c>. If it is
+ <c>{public_key_alg, 'ssh-dss'}</c>, it is translated
+ to <c>{pref_public_key_algs, ['ssh-dss','ssh-rsa']}</c>.
+ </p>
</item>
<tag><c><![CDATA[{pref_public_key_algs, list()}]]></c></tag>
<item>
- <note>
- <p>This option is kept for compatibility. It is ignored if the <c>preferred_algorithms</c>
- option is used. The equivalence of <c>{pref_public_key_algs,['ssh-dss']}</c> is
- <c>{preferred_algorithms, [{public_key,['ssh-dss']}]}</c>.</p>
- </note>
- <p>List of public key algorithms to try to use.
- <c>'ssh-rsa'</c> and <c>'ssh-dss'</c> are available.
- Overrides <c><![CDATA[{public_key_alg, 'ssh-rsa' | 'ssh-dss'}]]></c></p>
+ <p>List of user (client) public key algorithms to try to use.</p>
+ <p>The default value is
+ <c><![CDATA[['ssh-rsa','ssh-dss','ecdsa-sha2-nistp256','ecdsa-sha2-nistp384','ecdsa-sha2-nistp521'] ]]></c>
+ </p>
+ <p>If there is no public key of a specified type available, the corresponding entry is ignored.</p>
</item>
<tag><c><![CDATA[{preferred_algorithms, algs_list()}]]></c></tag>
@@ -219,6 +232,7 @@
<p>List of algorithms to use in the algorithm negotiation. The default <c>algs_list()</c> can
be obtained from <seealso marker="#default_algorithms/0">default_algorithms/0</seealso>.
</p>
+ <p>If an alg_entry() is missing in the algs_list(), the default value is used for that entry.</p>
<p>Here is an example of this option:</p>
<code>
{preferred_algorithms,
@@ -229,9 +243,9 @@
{compression,[none,zlib]}
}
</code>
- <p>The example specifies different algorithms in the two directions (client2server and server2client), for cipher but specifies the same
-algorithms for mac and compression in both directions. The kex (key exchange) and public key algorithms are set to their default values,
-kex is implicit but public_key is set explicitly.</p>
+ <p>The example specifies different algorithms in the two directions (client2server and server2client),
+ for cipher but specifies the same algorithms for mac and compression in both directions.
+ The kex (key exchange) is implicit but public_key is set explicitly.</p>
<warning>
<p>Changing the values can make a connection less secure. Do not change unless you
@@ -243,7 +257,7 @@ kex is implicit but public_key is set explicitly.</p>
<tag><c><![CDATA[{dh_gex_limits,{Min=integer(),I=integer(),Max=integer()}}]]></c></tag>
<item>
<p>Sets the three diffie-hellman-group-exchange parameters that guides the connected server in choosing a group.
- See RFC 4419 for the function of thoose. The default value is <c>{512, 1024, 4096}</c>.
+ See RFC 4419 for the function of thoose. The default value is <c>{1024, 6144, 8192}</c>.
</p>
</item>
@@ -267,11 +281,13 @@ kex is implicit but public_key is set explicitly.</p>
password, if the password authentication method is
attempted.</p>
</item>
- <tag><c><![CDATA[{key_cb, atom()}]]></c></tag>
+ <tag><c><![CDATA[{key_cb, key_cb()}]]></c></tag>
<item>
- <p>Module implementing the behaviour
- <seealso marker="ssh_client_key_api">ssh_client_key_api</seealso>.
- Can be used to customize the handling of public keys.
+ <p>Module implementing the behaviour <seealso
+ marker="ssh_client_key_api">ssh_client_key_api</seealso>. Can be used to
+ customize the handling of public keys. If callback options are provided
+ along with the module name, they are made available to the callback
+ module via the options passed to it under the key 'key_cb_private'.
</p>
</item>
<tag><c><![CDATA[{quiet_mode, atom() = boolean()}]]></c></tag>
@@ -435,6 +451,7 @@ kex is implicit but public_key is set explicitly.</p>
<p>List of algorithms to use in the algorithm negotiation. The default <c>algs_list()</c> can
be obtained from <seealso marker="#default_algorithms/0">default_algorithms/0</seealso>.
</p>
+ <p>If an alg_entry() is missing in the algs_list(), the default value is used for that entry.</p>
<p>Here is an example of this option:</p>
<code>
{preferred_algorithms,
@@ -445,9 +462,9 @@ kex is implicit but public_key is set explicitly.</p>
{compression,[none,zlib]}
}
</code>
- <p>The example specifies different algorithms in the two directions (client2server and server2client), for cipher but specifies the same
-algorithms for mac and compression in both directions. The kex (key exchange) and public key algorithms are set to their default values,
-kex is implicit but public_key is set explicitly.</p>
+ <p>The example specifies different algorithms in the two directions (client2server and server2client),
+ for cipher but specifies the same algorithms for mac and compression in both directions.
+ The kex (key exchange) is implicit but public_key is set explicitly.</p>
<warning>
<p>Changing the values can make a connection less secure. Do not change unless you
@@ -456,21 +473,82 @@ kex is implicit but public_key is set explicitly.</p>
</warning>
</item>
- <tag><c><![CDATA[{dh_gex_groups, [{Size=integer(),G=integer(),P=integer()}] | {file,filename()} }]]></c></tag>
+ <tag><c><![CDATA[{dh_gex_groups, [{Size=integer(),G=integer(),P=integer()}] | {file,filename()} {ssh_moduli_file,filename()} }]]></c></tag>
+ <item>
+ <p>Defines the groups the server may choose among when diffie-hellman-group-exchange is negotiated.
+ See RFC 4419 for details. The three variants of this option are:
+ </p>
+ <taglist>
+ <tag><c>{Size=integer(),G=integer(),P=integer()}</c></tag>
+ <item>The groups are given explicitly in this list. There may be several elements with the same <c>Size</c>.
+ In such a case, the server will choose one randomly in the negotiated Size.
+ </item>
+ <tag><c>{file,filename()}</c></tag>
+ <item>The file must have one or more three-tuples <c>{Size=integer(),G=integer(),P=integer()}</c>
+ terminated by a dot. The file is read when the daemon starts.
+ </item>
+ <tag><c>{ssh_moduli_file,filename()}</c></tag>
+ <item>The file must be in
+ <seealso marker="public_key:public_key#dh_gex_group/4">ssh-keygen moduli file format</seealso>.
+ The file is read when the daemon starts.
+ </item>
+ </taglist>
+ <p>The default list is fetched from the
+ <seealso marker="public_key:public_key#dh_gex_group/4">public_key</seealso> application.
+ </p>
+ </item>
+
+ <tag><c><![CDATA[{dh_gex_limits,{Min=integer(),Max=integer()}}]]></c></tag>
<item>
- <p>Sets the groups that the server may choose among when diffie-hellman-group-exchange is negotiated.
- See RFC 4419 for details.
+ <p>Limits what a client can ask for in diffie-hellman-group-exchange.
+ The limits will be
+ <c>{MaxUsed = min(MaxClient,Max), MinUsed = max(MinClient,Min)}</c> where <c>MaxClient</c> and
+ <c>MinClient</c> are the values proposed by a connecting client.
</p>
- <p>If the parameter is <c>{file,filename()}</c>, the file must exist and have one or more three-tuples terminated by a dot. The interpretation is as if the tuples had been given directly in the option. The file is read when the daemon starts.
+ <p>The default value is <c>{0,infinity}</c>.
</p>
+ <p>If <c>MaxUsed &lt; MinUsed</c> in a key exchange, it will fail with a disconnect.
+ </p>
+ <p>See RFC 4419 for the function of the Max and Min values.</p>
</item>
- <tag><c><![CDATA[{pwdfun, fun(User::string(), password::string()) -> boolean()}]]></c></tag>
+ <tag><c><![CDATA[{pwdfun, fun(User::string(), Password::string(), PeerAddress::{ip_adress(),port_number()}, State::any()) -> boolean() | disconnect | {boolean(),any()} }]]></c></tag>
+ <item>
+ <p>Provides a function for password validation. This could used for calling an external system or if
+ passwords should be stored as a hash. The fun returns:
+ <list type="bulleted">
+ <item><c>true</c> if the user and password is valid and</item>
+ <item><c>false</c> otherwise.</item>
+ </list>
+ </p>
+ <p>This fun can also be used to make delays in authentication tries for example by calling
+ <seealso marker="stdlib:timer#sleep/1">timer:sleep/1</seealso>. To facilitate counting of failed tries
+ the <c>State</c> variable could be used. This state is per connection only. The first time the pwdfun
+ is called for a connection, the <c>State</c> variable has the value <c>undefined</c>.
+ The pwdfun can return - in addition to the values above - a new state
+ as:
+ <list type="bulleted">
+ <item><c>{true, NewState:any()}</c> if the user and password is valid or</item>
+ <item><c>{false, NewState:any()}</c> if the user or password is invalid</item>
+ </list>
+ </p>
+ <p>A third usage is to block login attempts from a missbehaving peer. The <c>State</c> described above
+ can be used for this. In addition to the responses above, the following return value is introduced:
+ <list type="bulleted">
+ <item><c>disconnect</c> if the connection should be closed immediately after sending a SSH_MSG_DISCONNECT
+ message.</item>
+ </list>
+ </p>
+ </item>
+
+ <tag><c><![CDATA[{pwdfun, fun(User::string(), Password::string()) -> boolean()}]]></c></tag>
<item>
<p>Provides a function for password validation. This function is called
with user and password as strings, and returns
<c><![CDATA[true]]></c> if the password is valid and
<c><![CDATA[false]]></c> otherwise.</p>
+ <p>This option (<c>{pwdfun,fun/2}</c>) is the same as a subset of the previous
+ (<c>{pwdfun,fun/4}</c>). It is kept for compatibility.</p>
</item>
<tag><c><![CDATA[{negotiation_timeout, integer()}]]></c></tag>
@@ -501,6 +579,15 @@ kex is implicit but public_key is set explicitly.</p>
</p>
</item>
+ <tag><c><![CDATA[{max_channels, pos_integer()}]]></c></tag>
+ <item>
+ <p>The maximum number of channels with active remote subsystem that are accepted for
+ each connection to this daemon</p>
+ <p>By default, this option is not set. This means that the number is not limited.
+ </p>
+ </item>
+
+
<tag><c><![CDATA[{parallel_login, boolean()}]]></c></tag>
<item>
<p>If set to false (the default value), only one login is handled at a time.
@@ -532,11 +619,13 @@ kex is implicit but public_key is set explicitly.</p>
</p>
</item>
- <tag><c><![CDATA[{key_cb, atom()}]]></c></tag>
+ <tag><c><![CDATA[{key_cb, key_cb()}]]></c></tag>
<item>
- <p>Module implementing the behaviour
- <seealso marker="ssh_server_key_api">ssh_server_key_api</seealso>.
- Can be used to customize the handling of public keys.
+ <p>Module implementing the behaviour <seealso
+ marker="ssh_server_key_api">ssh_server_key_api</seealso>. Can be used to
+ customize the handling of public keys. If callback options are provided
+ along with the module name, they are made available to the callback
+ module via the options passed to it under the key 'key_cb_private'.
</p>
</item>
diff --git a/lib/ssh/doc/src/ssh_app.xml b/lib/ssh/doc/src/ssh_app.xml
index 4c85585820..79dd1e210e 100644
--- a/lib/ssh/doc/src/ssh_app.xml
+++ b/lib/ssh/doc/src/ssh_app.xml
@@ -41,15 +41,18 @@
<section>
<title>DEPENDENCIES</title>
- <p>The <c>ssh</c> application uses the applications <c>public_key</c> and
- <c>crypto</c> to handle public keys and encryption. Hence, these
+ <p>The <c>ssh</c> application uses the applications
+ <seealso marker="public_key:public_key">public_key</seealso> and
+ <seealso marker="crypto:crypto">crypto</seealso>
+ to handle public keys and encryption. Hence, these
applications must be loaded for the <c>ssh</c> application to work. In
an embedded environment this means that they must be started with
- <c>application:start/[1,2]</c> before the <c>ssh</c> application is started.
+ <seealso marker="kernel:application#start/1">application:start/1,2</seealso> before the
+ <c>ssh</c> application is started.
</p>
</section>
- <section>
+ <section>
<title>CONFIGURATION</title>
<p>The <c>ssh</c> application does not have an application-
@@ -62,10 +65,13 @@
<item><c>authorized_keys2</c></item>
<item><c>id_dsa</c></item>
<item><c>id_rsa</c></item>
+ <item><c>id_ecdsa</c></item>
<item><c>ssh_host_dsa_key</c></item>
<item><c>ssh_host_rsa_key</c></item>
+ <item><c>ssh_host_ecdsa_key</c></item>
</list>
<p>By default, <c>ssh</c> looks for <c>id_dsa</c>, <c>id_rsa</c>,
+ <c>id_ecdsa_key</c>,
<c>known_hosts</c>, and <c>authorized_keys</c> in ~/.ssh,
and for the host key files in <c>/etc/ssh</c>. These locations can be changed
by the options <c>user_dir</c> and <c>system_dir</c>.
@@ -79,7 +85,7 @@
</section>
<section>
<title>Public Keys</title>
- <p><c>id_dsa</c> and <c>id_rsa</c> are the users private key files.
+ <p><c>id_dsa</c>, <c>id_rsa</c> and <c>id_ecdsa</c> are the users private key files.
Notice that the public key is part of the private key so the <c>ssh</c>
application does not use the <c>id_&lt;*>.pub</c> files. These are
for the user's convenience when it is needed to convey the user's
@@ -104,8 +110,8 @@
<section>
<title>Host Keys</title>
<p>RSA and DSA host keys are supported and are
- expected to be found in files named <c>ssh_host_rsa_key</c> and
- <c>ssh_host_dsa_key</c>.
+ expected to be found in files named <c>ssh_host_rsa_key</c>,
+ <c>ssh_host_dsa_key</c> and <c>ssh_host_ecdsa_key</c>.
</p>
</section>
<section>
@@ -114,6 +120,197 @@
</section>
<section>
+ <marker id="supported"/>
+ <title>SUPPORTED SPECIFICATIONS AND STANDARDS</title>
+ <p>The supported SSH version is 2.0.</p>
+ </section>
+ <section>
+ <title>Algorithms</title>
+ <p>The actual set of algorithms may vary depending on which OpenSSL crypto library that is installed on the machine.
+ For the list on a particular installation, use the command
+ <seealso marker="ssh:ssh#default_algorithms/0">ssh:default_algorithms/0</seealso>.
+ The user may override the default algorithm configuration both on the server side and the client side.
+ See the option <c>preferred_algorithms</c> in the <seealso marker="ssh:ssh#daemon/1">ssh:daemon/1,2,3</seealso> and
+ <seealso marker="ssh:ssh#connect/3">ssh:connect/3,4</seealso> functions.
+ </p>
+
+ <p>Supported algorithms are:</p>
+
+ <taglist>
+ <tag>Key exchange algorithms</tag>
+ <item>
+ <list type="bulleted">
+ <item>ecdh-sha2-nistp256</item>
+ <item>ecdh-sha2-nistp384</item>
+ <item>ecdh-sha2-nistp521</item>
+ <item>diffie-hellman-group-exchange-sha1</item>
+ <item>diffie-hellman-group-exchange-sha256</item>
+ <item>diffie-hellman-group14-sha1</item>
+ <item>diffie-hellman-group1-sha1</item>
+ </list>
+ </item>
+
+ <tag>Public key algorithms</tag>
+ <item>
+ <list type="bulleted">
+ <item>ecdsa-sha2-nistp256</item>
+ <item>ecdsa-sha2-nistp384</item>
+ <item>ecdsa-sha2-nistp521</item>
+ <item>ssh-rsa</item>
+ <item>ssh-dss</item>
+ </list>
+ </item>
+
+ <tag>MAC algorithms</tag>
+ <item>
+ <list type="bulleted">
+ <item>hmac-sha2-256</item>
+ <item>hmac-sha2-512</item>
+ <item>hmac-sha1</item>
+ </list>
+ </item>
+
+ <tag>Encryption algorithms (ciphers)</tag>
+ <item>
+ <list type="bulleted">
+ <item>[email protected] (AEAD_AES_128_GCM)</item>
+ <item>[email protected] (AEAD_AES_256_GCM)</item>
+ <item>aes128-ctr</item>
+ <item>aes192-ctr</item>
+ <item>aes256-ctr</item>
+ <item>aes128-cbc</item>
+ <item>3des-cbc</item>
+ </list>
+ <p>Following the internet de-facto standard, the cipher and mac algorithm AEAD_AES_128_GCM is selected when the
+ cipher [email protected] is negotiated. The cipher and mac algorithm AEAD_AES_256_GCM is selected when the
+ cipher [email protected] is negotiated.
+ </p>
+ <p>See the text at the description of <seealso marker="#rfc5647_note">the rfc 5647 further down</seealso>
+ for more information.
+ </p>
+ </item>
+
+ <tag>Compression algorithms</tag>
+ <item>
+ <list type="bulleted">
+ <item>none</item>
+ <item>[email protected]</item>
+ <item>zlib</item>
+ </list>
+ </item>
+ </taglist>
+ </section>
+ <section>
+ <title>Unicode support</title>
+ <p>Unicode filenames are supported if the emulator and the underlaying OS support it. See section DESCRIPTION in the
+ <seealso marker="kernel:file">file</seealso> manual page in <c>kernel</c> for information about this subject.
+ </p>
+ <p>The shell and the cli both support unicode.
+ </p>
+ </section>
+
+ <section>
+ <title>Rfcs</title>
+ <p>The following rfc:s are supported:</p>
+ <list type="bulleted">
+ <item><url href="https://tools.ietf.org/html/rfc4251">RFC 4251</url>, The Secure Shell (SSH) Protocol Architecture.
+ <p>Except
+ <list type="bulleted">
+ <item>9.4.6 Host-Based Authentication</item>
+ <item>9.5.2 Proxy Forwarding</item>
+ <item>9.5.3 X11 Forwarding</item>
+ </list>
+ </p>
+ </item>
+
+ <item><url href="https://tools.ietf.org/html/rfc4252">RFC 4252</url>, The Secure Shell (SSH) Authentication Protocol.
+ <p>Except
+ <list type="bulleted">
+ <item>9. Host-Based Authentication: "hostbased"</item>
+ </list>
+ </p>
+ </item>
+
+ <item><url href="https://tools.ietf.org/html/rfc4253">RFC 4253</url>, The Secure Shell (SSH) Transport Layer Protocol.
+ <p></p>
+ </item>
+
+ <item><url href="https://tools.ietf.org/html/rfc4254">RFC 4254</url>, The Secure Shell (SSH) Connection Protocol.
+ <p>Except
+ <list type="bulleted">
+ <item>6.3. X11 Forwarding</item>
+ <item>7. TCP/IP Port Forwarding</item>
+ </list>
+ </p>
+ </item>
+
+ <item><url href="https://tools.ietf.org/html/rfc4256">RFC 4256</url>, Generic Message Exchange Authentication for
+ the Secure Shell Protocol (SSH).
+ <p>Except
+ <list type="bulleted">
+ <item><c>num-prompts > 1</c></item>
+ <item>password changing</item>
+ <item>other identification methods than userid-password</item>
+ </list>
+ </p>
+ </item>
+
+ <item><url href="https://tools.ietf.org/html/rfc4419">RFC 4419</url>, Diffie-Hellman Group Exchange for
+ the Secure Shell (SSH) Transport Layer Protocol.
+ <p></p>
+ </item>
+
+ <item><url href="https://tools.ietf.org/html/rfc4716">RFC 4716</url>, The Secure Shell (SSH) Public Key File Format.
+ <p></p>
+ </item>
+
+ <item><url href="https://tools.ietf.org/html/rfc5647">RFC 5647</url>, AES Galois Counter Mode for
+ the Secure Shell Transport Layer Protocol.
+ <p><marker id="rfc5647_note"/>There is an ambiguity in the synchronized selection of cipher and mac algorithm.
+ This is resolved by OpenSSH in the ciphers [email protected] and [email protected] which are implemented.
+ If the explicit ciphers and macs AEAD_AES_128_GCM or AEAD_AES_256_GCM are needed,
+ they could be enabled with the option preferred_algorithms.
+ <warning>
+ If the client or the server is not Erlang/OTP, it is the users responsibility to check that
+ other implementation has the same interpretation of AEAD_AES_*_GCM as the Erlang/OTP SSH before
+ enabling them. The aes*[email protected] variants are always safe to use since they lack the
+ ambiguity.
+ </warning>
+ </p>
+ <p>The second paragraph in section 5.1 is resolved as:
+ <list type="ordered">
+ <item>If the negotiated cipher is AEAD_AES_128_GCM, the mac algorithm is set to AEAD_AES_128_GCM.</item>
+ <item>If the negotiated cipher is AEAD_AES_256_GCM, the mac algorithm is set to AEAD_AES_256_GCM.</item>
+ <item>If the mac algorithm is AEAD_AES_128_GCM, the cipher is set to AEAD_AES_128_GCM.</item>
+ <item>If the mac algorithm is AEAD_AES_256_GCM, the cipher is set to AEAD_AES_256_GCM.</item>
+ </list>
+ The first rule that matches when read in order from the top is applied
+ </p>
+ </item>
+
+ <item><url href="https://tools.ietf.org/html/rfc5656">RFC 5656</url>, Elliptic Curve Algorithm Integration in
+ the Secure Shell Transport Layer.
+ <p>Except
+ <list type="bulleted">
+ <item>5. ECMQV Key Exchange</item>
+ <item>6.4. ECMQV Key Exchange and Verification Method Name</item>
+ <item>7.2. ECMQV Message Numbers</item>
+ <item>10.2. Recommended Curves</item>
+ </list>
+ </p>
+ </item>
+
+ <item><url href="https://tools.ietf.org/html/rfc6668">RFC 6668</url>, SHA-2 Data Integrity Verification for
+ the Secure Shell (SSH) Transport Layer Protocol
+ <p>Comment: Defines hmac-sha2-256 and hmac-sha2-512
+ </p>
+ </item>
+
+ </list>
+
+ </section>
+
+ <section>
<title>SEE ALSO</title>
<p><seealso marker="kernel:application">application(3)</seealso></p>
</section>
diff --git a/lib/ssh/doc/src/ssh_connection.xml b/lib/ssh/doc/src/ssh_connection.xml
index 9a7bb09b12..064a623eb6 100644
--- a/lib/ssh/doc/src/ssh_connection.xml
+++ b/lib/ssh/doc/src/ssh_connection.xml
@@ -373,6 +373,9 @@
<desc>
<p>Is to be called by client- and server-channel processes to send data to each other.
</p>
+ <p>The function <seealso marker="ssh:ssh_connection#subsystem/4">subsystem/4</seealso> and subsequent
+ calls of <c>send/3,4,5</c> must be executed in the same process.
+ </p>
</desc>
</func>
@@ -454,6 +457,9 @@
<p>Is to be called by a client-channel process for requesting to execute a predefined
subsystem on the server.
</p>
+ <p>The function <c>subsystem/4</c> and subsequent calls of
+ <seealso marker="ssh:ssh_connection#send/3">send/3,4,5</seealso> must be executed in the same process.
+ </p>
</desc>
</func>
diff --git a/lib/ssh/doc/src/using_ssh.xml b/lib/ssh/doc/src/using_ssh.xml
index 91185a0f6e..6826f20fb3 100644
--- a/lib/ssh/doc/src/using_ssh.xml
+++ b/lib/ssh/doc/src/using_ssh.xml
@@ -234,7 +234,7 @@
<title>SFTP Client with TAR Compression and Encryption</title>
<p>Example of writing and then reading a tar file follows:</p>
- <code type="erlang">
+ <code type="erl">
{ok,HandleWrite} = ssh_sftp:open_tar(ChannelPid, ?tar_file_name, [write]),
ok = erl_tar:add(HandleWrite, .... ),
ok = erl_tar:add(HandleWrite, .... ),
@@ -249,10 +249,10 @@
</code>
<p>The previous write and read example can be extended with encryption and decryption as follows:</p>
- <code type="erlang">
+ <code type="erl">
%% First three parameters depending on which crypto type we select:
Key = &lt;&lt;"This is a 256 bit key. abcdefghi">>,
-Ivec0 = crypto:rand_bytes(16),
+Ivec0 = crypto:strong_rand_bytes(16),
DataSize = 1024, % DataSize rem 16 = 0 for aes_cbc
%% Initialization of the CryptoState, in this case it is the Ivector.
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-architecture-15.2.ps b/lib/ssh/doc/standard/draft-ietf-secsh-architecture-15.2.ps
deleted file mode 100644
index d766a933b4..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-architecture-15.2.ps
+++ /dev/null
@@ -1,3315 +0,0 @@
-%!PS-Adobe-3.0
-%%BoundingBox: 75 0 595 747
-%%Title: Enscript Output
-%%For: Magnus Thoang
-%%Creator: GNU enscript 1.6.1
-%%CreationDate: Fri Oct 31 13:31:26 2003
-%%Orientation: Portrait
-%%Pages: 15 0
-%%DocumentMedia: A4 595 842 0 () ()
-%%DocumentNeededResources: (atend)
-%%EndComments
-%%BeginProlog
-%%BeginProcSet: PStoPS 1 15
-userdict begin
-[/showpage/erasepage/copypage]{dup where{pop dup load
- type/operatortype eq{1 array cvx dup 0 3 index cvx put
- bind def}{pop}ifelse}{pop}ifelse}forall
-[/letter/legal/executivepage/a4/a4small/b5/com10envelope
- /monarchenvelope/c5envelope/dlenvelope/lettersmall/note
- /folio/quarto/a5]{dup where{dup wcheck{exch{}put}
- {pop{}def}ifelse}{pop}ifelse}forall
-/setpagedevice {pop}bind 1 index where{dup wcheck{3 1 roll put}
- {pop def}ifelse}{def}ifelse
-/PStoPSmatrix matrix currentmatrix def
-/PStoPSxform matrix def/PStoPSclip{clippath}def
-/defaultmatrix{PStoPSmatrix exch PStoPSxform exch concatmatrix}bind def
-/initmatrix{matrix defaultmatrix setmatrix}bind def
-/initclip[{matrix currentmatrix PStoPSmatrix setmatrix
- [{currentpoint}stopped{$error/newerror false put{newpath}}
- {/newpath cvx 3 1 roll/moveto cvx 4 array astore cvx}ifelse]
- {[/newpath cvx{/moveto cvx}{/lineto cvx}
- {/curveto cvx}{/closepath cvx}pathforall]cvx exch pop}
- stopped{$error/errorname get/invalidaccess eq{cleartomark
- $error/newerror false put cvx exec}{stop}ifelse}if}bind aload pop
- /initclip dup load dup type dup/operatortype eq{pop exch pop}
- {dup/arraytype eq exch/packedarraytype eq or
- {dup xcheck{exch pop aload pop}{pop cvx}ifelse}
- {pop cvx}ifelse}ifelse
- {newpath PStoPSclip clip newpath exec setmatrix} bind aload pop]cvx def
-/initgraphics{initmatrix newpath initclip 1 setlinewidth
- 0 setlinecap 0 setlinejoin []0 setdash 0 setgray
- 10 setmiterlimit}bind def
-end
-%%EndProcSet
-%%BeginResource: procset Enscript-Prolog 1.6 1
-%
-% Procedures.
-%
-
-/_S { % save current state
- /_s save def
-} def
-/_R { % restore from saved state
- _s restore
-} def
-
-/S { % showpage protecting gstate
- gsave
- showpage
- grestore
-} bind def
-
-/MF { % fontname newfontname -> - make a new encoded font
- /newfontname exch def
- /fontname exch def
-
- /fontdict fontname findfont def
- /newfont fontdict maxlength dict def
-
- fontdict {
- exch
- dup /FID eq {
- % skip FID pair
- pop pop
- } {
- % copy to the new font dictionary
- exch newfont 3 1 roll put
- } ifelse
- } forall
-
- newfont /FontName newfontname put
-
- % insert only valid encoding vectors
- encoding_vector length 256 eq {
- newfont /Encoding encoding_vector put
- } if
-
- newfontname newfont definefont pop
-} def
-
-/SF { % fontname width height -> - set a new font
- /height exch def
- /width exch def
-
- findfont
- [width 0 0 height 0 0] makefont setfont
-} def
-
-/SUF { % fontname width height -> - set a new user font
- /height exch def
- /width exch def
-
- /F-gs-user-font MF
- /F-gs-user-font width height SF
-} def
-
-/M {moveto} bind def
-/s {show} bind def
-
-/Box { % x y w h -> - define box path
- /d_h exch def /d_w exch def /d_y exch def /d_x exch def
- d_x d_y moveto
- d_w 0 rlineto
- 0 d_h rlineto
- d_w neg 0 rlineto
- closepath
-} def
-
-/bgs { % x y height blskip gray str -> - show string with bg color
- /str exch def
- /gray exch def
- /blskip exch def
- /height exch def
- /y exch def
- /x exch def
-
- gsave
- x y blskip sub str stringwidth pop height Box
- gray setgray
- fill
- grestore
- x y M str s
-} def
-
-% Highlight bars.
-/highlight_bars { % nlines lineheight output_y_margin gray -> -
- gsave
- setgray
- /ymarg exch def
- /lineheight exch def
- /nlines exch def
-
- % This 2 is just a magic number to sync highlight lines to text.
- 0 d_header_y ymarg sub 2 sub translate
-
- /cw d_output_w cols div def
- /nrows d_output_h ymarg 2 mul sub lineheight div cvi def
-
- % for each column
- 0 1 cols 1 sub {
- cw mul /xp exch def
-
- % for each rows
- 0 1 nrows 1 sub {
- /rn exch def
- rn lineheight mul neg /yp exch def
- rn nlines idiv 2 mod 0 eq {
- % Draw highlight bar. 4 is just a magic indentation.
- xp 4 add yp cw 8 sub lineheight neg Box fill
- } if
- } for
- } for
-
- grestore
-} def
-
-% Line highlight bar.
-/line_highlight { % x y width height gray -> -
- gsave
- /gray exch def
- Box gray setgray fill
- grestore
-} def
-
-% Column separator lines.
-/column_lines {
- gsave
- .1 setlinewidth
- 0 d_footer_h translate
- /cw d_output_w cols div def
- 1 1 cols 1 sub {
- cw mul 0 moveto
- 0 d_output_h rlineto stroke
- } for
- grestore
-} def
-
-% Column borders.
-/column_borders {
- gsave
- .1 setlinewidth
- 0 d_footer_h moveto
- 0 d_output_h rlineto
- d_output_w 0 rlineto
- 0 d_output_h neg rlineto
- closepath stroke
- grestore
-} def
-
-% Do the actual underlay drawing
-/draw_underlay {
- ul_style 0 eq {
- ul_str true charpath stroke
- } {
- ul_str show
- } ifelse
-} def
-
-% Underlay
-/underlay { % - -> -
- gsave
- 0 d_page_h translate
- d_page_h neg d_page_w atan rotate
-
- ul_gray setgray
- ul_font setfont
- /dw d_page_h dup mul d_page_w dup mul add sqrt def
- ul_str stringwidth pop dw exch sub 2 div ul_h_ptsize -2 div moveto
- draw_underlay
- grestore
-} def
-
-/user_underlay { % - -> -
- gsave
- ul_x ul_y translate
- ul_angle rotate
- ul_gray setgray
- ul_font setfont
- 0 0 ul_h_ptsize 2 div sub moveto
- draw_underlay
- grestore
-} def
-
-% Page prefeed
-/page_prefeed { % bool -> -
- statusdict /prefeed known {
- statusdict exch /prefeed exch put
- } {
- pop
- } ifelse
-} def
-
-% Wrapped line markers
-/wrapped_line_mark { % x y charwith charheight type -> -
- /type exch def
- /h exch def
- /w exch def
- /y exch def
- /x exch def
-
- type 2 eq {
- % Black boxes (like TeX does)
- gsave
- 0 setlinewidth
- x w 4 div add y M
- 0 h rlineto w 2 div 0 rlineto 0 h neg rlineto
- closepath fill
- grestore
- } {
- type 3 eq {
- % Small arrows
- gsave
- .2 setlinewidth
- x w 2 div add y h 2 div add M
- w 4 div 0 rlineto
- x w 4 div add y lineto stroke
-
- x w 4 div add w 8 div add y h 4 div add M
- x w 4 div add y lineto
- w 4 div h 8 div rlineto stroke
- grestore
- } {
- % do nothing
- } ifelse
- } ifelse
-} def
-
-% EPSF import.
-
-/BeginEPSF {
- /b4_Inc_state save def % Save state for cleanup
- /dict_count countdictstack def % Count objects on dict stack
- /op_count count 1 sub def % Count objects on operand stack
- userdict begin
- /showpage { } def
- 0 setgray 0 setlinecap
- 1 setlinewidth 0 setlinejoin
- 10 setmiterlimit [ ] 0 setdash newpath
- /languagelevel where {
- pop languagelevel
- 1 ne {
- false setstrokeadjust false setoverprint
- } if
- } if
-} bind def
-
-/EndEPSF {
- count op_count sub { pos } repeat % Clean up stacks
- countdictstack dict_count sub { end } repeat
- b4_Inc_state restore
-} bind def
-
-% Check PostScript language level.
-/languagelevel where {
- pop /gs_languagelevel languagelevel def
-} {
- /gs_languagelevel 1 def
-} ifelse
-%%EndResource
-%%BeginResource: procset Enscript-Encoding-88591 1.6 1
-/encoding_vector [
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/space /exclam /quotedbl /numbersign
-/dollar /percent /ampersand /quoteright
-/parenleft /parenright /asterisk /plus
-/comma /hyphen /period /slash
-/zero /one /two /three
-/four /five /six /seven
-/eight /nine /colon /semicolon
-/less /equal /greater /question
-/at /A /B /C
-/D /E /F /G
-/H /I /J /K
-/L /M /N /O
-/P /Q /R /S
-/T /U /V /W
-/X /Y /Z /bracketleft
-/backslash /bracketright /asciicircum /underscore
-/quoteleft /a /b /c
-/d /e /f /g
-/h /i /j /k
-/l /m /n /o
-/p /q /r /s
-/t /u /v /w
-/x /y /z /braceleft
-/bar /braceright /tilde /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/space /exclamdown /cent /sterling
-/currency /yen /brokenbar /section
-/dieresis /copyright /ordfeminine /guillemotleft
-/logicalnot /hyphen /registered /macron
-/degree /plusminus /twosuperior /threesuperior
-/acute /mu /paragraph /bullet
-/cedilla /onesuperior /ordmasculine /guillemotright
-/onequarter /onehalf /threequarters /questiondown
-/Agrave /Aacute /Acircumflex /Atilde
-/Adieresis /Aring /AE /Ccedilla
-/Egrave /Eacute /Ecircumflex /Edieresis
-/Igrave /Iacute /Icircumflex /Idieresis
-/Eth /Ntilde /Ograve /Oacute
-/Ocircumflex /Otilde /Odieresis /multiply
-/Oslash /Ugrave /Uacute /Ucircumflex
-/Udieresis /Yacute /Thorn /germandbls
-/agrave /aacute /acircumflex /atilde
-/adieresis /aring /ae /ccedilla
-/egrave /eacute /ecircumflex /edieresis
-/igrave /iacute /icircumflex /idieresis
-/eth /ntilde /ograve /oacute
-/ocircumflex /otilde /odieresis /divide
-/oslash /ugrave /uacute /ucircumflex
-/udieresis /yacute /thorn /ydieresis
-] def
-%%EndResource
-%%EndProlog
-%%BeginSetup
-%%IncludeResource: font Courier-Bold
-%%IncludeResource: font Courier
-/HFpt_w 10 def
-/HFpt_h 10 def
-/Courier-Bold /HF-gs-font MF
-/HF /HF-gs-font findfont [HFpt_w 0 0 HFpt_h 0 0] makefont def
-/Courier /F-gs-font MF
-/F-gs-font 10 10 SF
-/#copies 1 def
-/d_page_w 520 def
-/d_page_h 747 def
-/d_header_x 0 def
-/d_header_y 747 def
-/d_header_w 520 def
-/d_header_h 0 def
-/d_footer_x 0 def
-/d_footer_y 0 def
-/d_footer_w 520 def
-/d_footer_h 0 def
-/d_output_w 520 def
-/d_output_h 747 def
-/cols 1 def
-userdict/PStoPSxform PStoPSmatrix matrix currentmatrix
- matrix invertmatrix matrix concatmatrix
- matrix invertmatrix put
-%%EndSetup
-%%Page: (0,1) 1
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 1 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 701 M
-(Network Working Group T. Ylonen) s
-5 690 M
-(Internet-Draft SSH Communications Security Corp) s
-5 679 M
-(Expires: March 31, 2004 D. Moffat, Ed.) s
-5 668 M
-( Sun Microsystems, Inc) s
-5 657 M
-( Oct 2003) s
-5 624 M
-( SSH Protocol Architecture) s
-5 613 M
-( draft-ietf-secsh-architecture-15.txt) s
-5 591 M
-(Status of this Memo) s
-5 569 M
-( This document is an Internet-Draft and is in full conformance with) s
-5 558 M
-( all provisions of Section 10 of RFC2026.) s
-5 536 M
-( Internet-Drafts are working documents of the Internet Engineering) s
-5 525 M
-( Task Force \(IETF\), its areas, and its working groups. Note that other) s
-5 514 M
-( groups may also distribute working documents as Internet-Drafts.) s
-5 492 M
-( Internet-Drafts are draft documents valid for a maximum of six months) s
-5 481 M
-( and may be updated, replaced, or obsoleted by other documents at any) s
-5 470 M
-( time. It is inappropriate to use Internet-Drafts as reference) s
-5 459 M
-( material or to cite them other than as "work in progress.") s
-5 437 M
-( The list of current Internet-Drafts can be accessed at http://) s
-5 426 M
-( www.ietf.org/ietf/1id-abstracts.txt.) s
-5 404 M
-( The list of Internet-Draft Shadow Directories can be accessed at) s
-5 393 M
-( http://www.ietf.org/shadow.html.) s
-5 371 M
-( This Internet-Draft will expire on March 31, 2004.) s
-5 349 M
-(Copyright Notice) s
-5 327 M
-( Copyright \(C\) The Internet Society \(2003\). All Rights Reserved.) s
-5 305 M
-(Abstract) s
-5 283 M
-( SSH is a protocol for secure remote login and other secure network) s
-5 272 M
-( services over an insecure network. This document describes the) s
-5 261 M
-( architecture of the SSH protocol, as well as the notation and) s
-5 250 M
-( terminology used in SSH protocol documents. It also discusses the SSH) s
-5 239 M
-( algorithm naming system that allows local extensions. The SSH) s
-5 228 M
-( protocol consists of three major components: The Transport Layer) s
-5 217 M
-( Protocol provides server authentication, confidentiality, and) s
-5 206 M
-( integrity with perfect forward secrecy. The User Authentication) s
-5 195 M
-( Protocol authenticates the client to the server. The Connection) s
-5 184 M
-( Protocol multiplexes the encrypted tunnel into several logical) s
-5 173 M
-( channels. Details of these protocols are described in separate) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 1]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 2 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( documents.) s
-5 668 M
-(Table of Contents) s
-5 646 M
-( 1. Contributors . . . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 635 M
-( 2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 624 M
-( 3. Specification of Requirements . . . . . . . . . . . . . . . 3) s
-5 613 M
-( 4. Architecture . . . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 602 M
-( 4.1 Host Keys . . . . . . . . . . . . . . . . . . . . . . . . . 4) s
-5 591 M
-( 4.2 Extensibility . . . . . . . . . . . . . . . . . . . . . . . 5) s
-5 580 M
-( 4.3 Policy Issues . . . . . . . . . . . . . . . . . . . . . . . 5) s
-5 569 M
-( 4.4 Security Properties . . . . . . . . . . . . . . . . . . . . 6) s
-5 558 M
-( 4.5 Packet Size and Overhead . . . . . . . . . . . . . . . . . . 6) s
-5 547 M
-( 4.6 Localization and Character Set Support . . . . . . . . . . . 7) s
-5 536 M
-( 5. Data Type Representations Used in the SSH Protocols . . . . 8) s
-5 525 M
-( 6. Algorithm Naming . . . . . . . . . . . . . . . . . . . . . . 10) s
-5 514 M
-( 7. Message Numbers . . . . . . . . . . . . . . . . . . . . . . 11) s
-5 503 M
-( 8. IANA Considerations . . . . . . . . . . . . . . . . . . . . 11) s
-5 492 M
-( 9. Security Considerations . . . . . . . . . . . . . . . . . . 12) s
-5 481 M
-( 9.1 Pseudo-Random Number Generation . . . . . . . . . . . . . . 12) s
-5 470 M
-( 9.2 Transport . . . . . . . . . . . . . . . . . . . . . . . . . 13) s
-5 459 M
-( 9.2.1 Confidentiality . . . . . . . . . . . . . . . . . . . . . . 13) s
-5 448 M
-( 9.2.2 Data Integrity . . . . . . . . . . . . . . . . . . . . . . . 16) s
-5 437 M
-( 9.2.3 Replay . . . . . . . . . . . . . . . . . . . . . . . . . . . 16) s
-5 426 M
-( 9.2.4 Man-in-the-middle . . . . . . . . . . . . . . . . . . . . . 17) s
-5 415 M
-( 9.2.5 Denial-of-service . . . . . . . . . . . . . . . . . . . . . 19) s
-5 404 M
-( 9.2.6 Covert Channels . . . . . . . . . . . . . . . . . . . . . . 19) s
-5 393 M
-( 9.2.7 Forward Secrecy . . . . . . . . . . . . . . . . . . . . . . 20) s
-5 382 M
-( 9.3 Authentication Protocol . . . . . . . . . . . . . . . . . . 20) s
-5 371 M
-( 9.3.1 Weak Transport . . . . . . . . . . . . . . . . . . . . . . . 21) s
-5 360 M
-( 9.3.2 Debug messages . . . . . . . . . . . . . . . . . . . . . . . 21) s
-5 349 M
-( 9.3.3 Local security policy . . . . . . . . . . . . . . . . . . . 21) s
-5 338 M
-( 9.3.4 Public key authentication . . . . . . . . . . . . . . . . . 22) s
-5 327 M
-( 9.3.5 Password authentication . . . . . . . . . . . . . . . . . . 22) s
-5 316 M
-( 9.3.6 Host based authentication . . . . . . . . . . . . . . . . . 23) s
-5 305 M
-( 9.4 Connection protocol . . . . . . . . . . . . . . . . . . . . 23) s
-5 294 M
-( 9.4.1 End point security . . . . . . . . . . . . . . . . . . . . . 23) s
-5 283 M
-( 9.4.2 Proxy forwarding . . . . . . . . . . . . . . . . . . . . . . 23) s
-5 272 M
-( 9.4.3 X11 forwarding . . . . . . . . . . . . . . . . . . . . . . . 24) s
-5 261 M
-( Normative References . . . . . . . . . . . . . . . . . . . . 24) s
-5 250 M
-( Informative References . . . . . . . . . . . . . . . . . . . 25) s
-5 239 M
-( Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 27) s
-5 228 M
-( Intellectual Property and Copyright Statements . . . . . . . 28) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 2]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (2,3) 2
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 3 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-(1. Contributors) s
-5 668 M
-( The major original contributors of this document were: Tatu Ylonen,) s
-5 657 M
-( Tero Kivinen, Timo J. Rinne, Sami Lehtinen \(all of SSH Communications) s
-5 646 M
-( Security Corp\), and Markku-Juhani O. Saarinen \(University of) s
-5 635 M
-( Jyvaskyla\)) s
-5 613 M
-( The document editor is: [email protected]. Comments on this) s
-5 602 M
-( internet draft should be sent to the IETF SECSH working group,) s
-5 591 M
-( details at: http://ietf.org/html.charters/secsh-charter.html) s
-5 569 M
-(2. Introduction) s
-5 547 M
-( SSH is a protocol for secure remote login and other secure network) s
-5 536 M
-( services over an insecure network. It consists of three major) s
-5 525 M
-( components:) s
-5 514 M
-( o The Transport Layer Protocol [SSH-TRANS] provides server) s
-5 503 M
-( authentication, confidentiality, and integrity. It may optionally) s
-5 492 M
-( also provide compression. The transport layer will typically be) s
-5 481 M
-( run over a TCP/IP connection, but might also be used on top of any) s
-5 470 M
-( other reliable data stream.) s
-5 459 M
-( o The User Authentication Protocol [SSH-USERAUTH] authenticates the) s
-5 448 M
-( client-side user to the server. It runs over the transport layer) s
-5 437 M
-( protocol.) s
-5 426 M
-( o The Connection Protocol [SSH-CONNECT] multiplexes the encrypted) s
-5 415 M
-( tunnel into several logical channels. It runs over the user) s
-5 404 M
-( authentication protocol.) s
-5 382 M
-( The client sends a service request once a secure transport layer) s
-5 371 M
-( connection has been established. A second service request is sent) s
-5 360 M
-( after user authentication is complete. This allows new protocols to) s
-5 349 M
-( be defined and coexist with the protocols listed above.) s
-5 327 M
-( The connection protocol provides channels that can be used for a wide) s
-5 316 M
-( range of purposes. Standard methods are provided for setting up) s
-5 305 M
-( secure interactive shell sessions and for forwarding \("tunneling"\)) s
-5 294 M
-( arbitrary TCP/IP ports and X11 connections.) s
-5 272 M
-(3. Specification of Requirements) s
-5 250 M
-( All documents related to the SSH protocols shall use the keywords) s
-5 239 M
-( "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",) s
-5 228 M
-( "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" to describe) s
-5 217 M
-( requirements. They are to be interpreted as described in [RFC2119].) s
-5 195 M
-(4. Architecture) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 3]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 4 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-(4.1 Host Keys) s
-5 668 M
-( Each server host SHOULD have a host key. Hosts MAY have multiple) s
-5 657 M
-( host keys using multiple different algorithms. Multiple hosts MAY) s
-5 646 M
-( share the same host key. If a host has keys at all, it MUST have at) s
-5 635 M
-( least one key using each REQUIRED public key algorithm \(DSS) s
-5 624 M
-( [FIPS-186]\).) s
-5 602 M
-( The server host key is used during key exchange to verify that the) s
-5 591 M
-( client is really talking to the correct server. For this to be) s
-5 580 M
-( possible, the client must have a priori knowledge of the server's) s
-5 569 M
-( public host key.) s
-5 547 M
-( Two different trust models can be used:) s
-5 536 M
-( o The client has a local database that associates each host name \(as) s
-5 525 M
-( typed by the user\) with the corresponding public host key. This) s
-5 514 M
-( method requires no centrally administered infrastructure, and no) s
-5 503 M
-( third-party coordination. The downside is that the database of) s
-5 492 M
-( name-to-key associations may become burdensome to maintain.) s
-5 481 M
-( o The host name-to-key association is certified by some trusted) s
-5 470 M
-( certification authority. The client only knows the CA root key,) s
-5 459 M
-( and can verify the validity of all host keys certified by accepted) s
-5 448 M
-( CAs.) s
-5 426 M
-( The second alternative eases the maintenance problem, since) s
-5 415 M
-( ideally only a single CA key needs to be securely stored on the) s
-5 404 M
-( client. On the other hand, each host key must be appropriately) s
-5 393 M
-( certified by a central authority before authorization is possible.) s
-5 382 M
-( Also, a lot of trust is placed on the central infrastructure.) s
-5 360 M
-( The protocol provides the option that the server name - host key) s
-5 349 M
-( association is not checked when connecting to the host for the first) s
-5 338 M
-( time. This allows communication without prior communication of host) s
-5 327 M
-( keys or certification. The connection still provides protection) s
-5 316 M
-( against passive listening; however, it becomes vulnerable to active) s
-5 305 M
-( man-in-the-middle attacks. Implementations SHOULD NOT normally allow) s
-5 294 M
-( such connections by default, as they pose a potential security) s
-5 283 M
-( problem. However, as there is no widely deployed key infrastructure) s
-5 272 M
-( available on the Internet yet, this option makes the protocol much) s
-5 261 M
-( more usable during the transition time until such an infrastructure) s
-5 250 M
-( emerges, while still providing a much higher level of security than) s
-5 239 M
-( that offered by older solutions \(e.g. telnet [RFC-854] and rlogin) s
-5 228 M
-( [RFC-1282]\).) s
-5 206 M
-( Implementations SHOULD try to make the best effort to check host) s
-5 195 M
-( keys. An example of a possible strategy is to only accept a host key) s
-5 184 M
-( without checking the first time a host is connected, save the key in) s
-5 173 M
-( a local database, and compare against that key on all future) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 4]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (4,5) 3
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 5 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( connections to that host.) s
-5 668 M
-( Implementations MAY provide additional methods for verifying the) s
-5 657 M
-( correctness of host keys, e.g. a hexadecimal fingerprint derived from) s
-5 646 M
-( the SHA-1 hash of the public key. Such fingerprints can easily be) s
-5 635 M
-( verified by using telephone or other external communication channels.) s
-5 613 M
-( All implementations SHOULD provide an option to not accept host keys) s
-5 602 M
-( that cannot be verified.) s
-5 580 M
-( We believe that ease of use is critical to end-user acceptance of) s
-5 569 M
-( security solutions, and no improvement in security is gained if the) s
-5 558 M
-( new solutions are not used. Thus, providing the option not to check) s
-5 547 M
-( the server host key is believed to improve the overall security of) s
-5 536 M
-( the Internet, even though it reduces the security of the protocol in) s
-5 525 M
-( configurations where it is allowed.) s
-5 503 M
-(4.2 Extensibility) s
-5 481 M
-( We believe that the protocol will evolve over time, and some) s
-5 470 M
-( organizations will want to use their own encryption, authentication) s
-5 459 M
-( and/or key exchange methods. Central registration of all extensions) s
-5 448 M
-( is cumbersome, especially for experimental or classified features.) s
-5 437 M
-( On the other hand, having no central registration leads to conflicts) s
-5 426 M
-( in method identifiers, making interoperability difficult.) s
-5 404 M
-( We have chosen to identify algorithms, methods, formats, and) s
-5 393 M
-( extension protocols with textual names that are of a specific format.) s
-5 382 M
-( DNS names are used to create local namespaces where experimental or) s
-5 371 M
-( classified extensions can be defined without fear of conflicts with) s
-5 360 M
-( other implementations.) s
-5 338 M
-( One design goal has been to keep the base protocol as simple as) s
-5 327 M
-( possible, and to require as few algorithms as possible. However, all) s
-5 316 M
-( implementations MUST support a minimal set of algorithms to ensure) s
-5 305 M
-( interoperability \(this does not imply that the local policy on all) s
-5 294 M
-( hosts would necessary allow these algorithms\). The mandatory) s
-5 283 M
-( algorithms are specified in the relevant protocol documents.) s
-5 261 M
-( Additional algorithms, methods, formats, and extension protocols can) s
-5 250 M
-( be defined in separate drafts. See Section Algorithm Naming \(Section) s
-5 239 M
-( 6\) for more information.) s
-5 217 M
-(4.3 Policy Issues) s
-5 195 M
-( The protocol allows full negotiation of encryption, integrity, key) s
-5 184 M
-( exchange, compression, and public key algorithms and formats.) s
-5 173 M
-( Encryption, integrity, public key, and compression algorithms can be) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 5]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 6 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( different for each direction.) s
-5 668 M
-( The following policy issues SHOULD be addressed in the configuration) s
-5 657 M
-( mechanisms of each implementation:) s
-5 646 M
-( o Encryption, integrity, and compression algorithms, separately for) s
-5 635 M
-( each direction. The policy MUST specify which is the preferred) s
-5 624 M
-( algorithm \(e.g. the first algorithm listed in each category\).) s
-5 613 M
-( o Public key algorithms and key exchange method to be used for host) s
-5 602 M
-( authentication. The existence of trusted host keys for different) s
-5 591 M
-( public key algorithms also affects this choice.) s
-5 580 M
-( o The authentication methods that are to be required by the server) s
-5 569 M
-( for each user. The server's policy MAY require multiple) s
-5 558 M
-( authentication for some or all users. The required algorithms MAY) s
-5 547 M
-( depend on the location where the user is trying to log in from.) s
-5 536 M
-( o The operations that the user is allowed to perform using the) s
-5 525 M
-( connection protocol. Some issues are related to security; for) s
-5 514 M
-( example, the policy SHOULD NOT allow the server to start sessions) s
-5 503 M
-( or run commands on the client machine, and MUST NOT allow) s
-5 492 M
-( connections to the authentication agent unless forwarding such) s
-5 481 M
-( connections has been requested. Other issues, such as which TCP/) s
-5 470 M
-( IP ports can be forwarded and by whom, are clearly issues of local) s
-5 459 M
-( policy. Many of these issues may involve traversing or bypassing) s
-5 448 M
-( firewalls, and are interrelated with the local security policy.) s
-5 426 M
-(4.4 Security Properties) s
-5 404 M
-( The primary goal of the SSH protocol is improved security on the) s
-5 393 M
-( Internet. It attempts to do this in a way that is easy to deploy,) s
-5 382 M
-( even at the cost of absolute security.) s
-5 371 M
-( o All encryption, integrity, and public key algorithms used are) s
-5 360 M
-( well-known, well-established algorithms.) s
-5 349 M
-( o All algorithms are used with cryptographically sound key sizes) s
-5 338 M
-( that are believed to provide protection against even the strongest) s
-5 327 M
-( cryptanalytic attacks for decades.) s
-5 316 M
-( o All algorithms are negotiated, and in case some algorithm is) s
-5 305 M
-( broken, it is easy to switch to some other algorithm without) s
-5 294 M
-( modifying the base protocol.) s
-5 272 M
-( Specific concessions were made to make wide-spread fast deployment) s
-5 261 M
-( easier. The particular case where this comes up is verifying that) s
-5 250 M
-( the server host key really belongs to the desired host; the protocol) s
-5 239 M
-( allows the verification to be left out \(but this is NOT RECOMMENDED\).) s
-5 228 M
-( This is believed to significantly improve usability in the short) s
-5 217 M
-( term, until widespread Internet public key infrastructures emerge.) s
-5 195 M
-(4.5 Packet Size and Overhead) s
-5 173 M
-( Some readers will worry about the increase in packet size due to new) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 6]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (6,7) 4
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 7 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( headers, padding, and MAC. The minimum packet size is in the order) s
-5 679 M
-( of 28 bytes \(depending on negotiated algorithms\). The increase is) s
-5 668 M
-( negligible for large packets, but very significant for one-byte) s
-5 657 M
-( packets \(telnet-type sessions\). There are, however, several factors) s
-5 646 M
-( that make this a non-issue in almost all cases:) s
-5 635 M
-( o The minimum size of a TCP/IP header is 32 bytes. Thus, the) s
-5 624 M
-( increase is actually from 33 to 51 bytes \(roughly\).) s
-5 613 M
-( o The minimum size of the data field of an Ethernet packet is 46) s
-5 602 M
-( bytes [RFC-894]. Thus, the increase is no more than 5 bytes. When) s
-5 591 M
-( Ethernet headers are considered, the increase is less than 10) s
-5 580 M
-( percent.) s
-5 569 M
-( o The total fraction of telnet-type data in the Internet is) s
-5 558 M
-( negligible, even with increased packet sizes.) s
-5 536 M
-( The only environment where the packet size increase is likely to have) s
-5 525 M
-( a significant effect is PPP [RFC-1134] over slow modem lines \(PPP) s
-5 514 M
-( compresses the TCP/IP headers, emphasizing the increase in packet) s
-5 503 M
-( size\). However, with modern modems, the time needed to transfer is in) s
-5 492 M
-( the order of 2 milliseconds, which is a lot faster than people can) s
-5 481 M
-( type.) s
-5 459 M
-( There are also issues related to the maximum packet size. To) s
-5 448 M
-( minimize delays in screen updates, one does not want excessively) s
-5 437 M
-( large packets for interactive sessions. The maximum packet size is) s
-5 426 M
-( negotiated separately for each channel.) s
-5 404 M
-(4.6 Localization and Character Set Support) s
-5 382 M
-( For the most part, the SSH protocols do not directly pass text that) s
-5 371 M
-( would be displayed to the user. However, there are some places where) s
-5 360 M
-( such data might be passed. When applicable, the character set for the) s
-5 349 M
-( data MUST be explicitly specified. In most places, ISO 10646 with) s
-5 338 M
-( UTF-8 encoding is used [RFC-2279]. When applicable, a field is also) s
-5 327 M
-( provided for a language tag [RFC-3066].) s
-5 305 M
-( One big issue is the character set of the interactive session. There) s
-5 294 M
-( is no clear solution, as different applications may display data in) s
-5 283 M
-( different formats. Different types of terminal emulation may also be) s
-5 272 M
-( employed in the client, and the character set to be used is) s
-5 261 M
-( effectively determined by the terminal emulation. Thus, no place is) s
-5 250 M
-( provided for directly specifying the character set or encoding for) s
-5 239 M
-( terminal session data. However, the terminal emulation type \(e.g.) s
-5 228 M
-( "vt100"\) is transmitted to the remote site, and it implicitly) s
-5 217 M
-( specifies the character set and encoding. Applications typically use) s
-5 206 M
-( the terminal type to determine what character set they use, or the) s
-5 195 M
-( character set is determined using some external means. The terminal) s
-5 184 M
-( emulation may also allow configuring the default character set. In) s
-5 173 M
-( any case, the character set for the terminal session is considered) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 7]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 8 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( primarily a client local issue.) s
-5 668 M
-( Internal names used to identify algorithms or protocols are normally) s
-5 657 M
-( never displayed to users, and must be in US-ASCII.) s
-5 635 M
-( The client and server user names are inherently constrained by what) s
-5 624 M
-( the server is prepared to accept. They might, however, occasionally) s
-5 613 M
-( be displayed in logs, reports, etc. They MUST be encoded using ISO) s
-5 602 M
-( 10646 UTF-8, but other encodings may be required in some cases. It) s
-5 591 M
-( is up to the server to decide how to map user names to accepted user) s
-5 580 M
-( names. Straight bit-wise binary comparison is RECOMMENDED.) s
-5 558 M
-( For localization purposes, the protocol attempts to minimize the) s
-5 547 M
-( number of textual messages transmitted. When present, such messages) s
-5 536 M
-( typically relate to errors, debugging information, or some externally) s
-5 525 M
-( configured data. For data that is normally displayed, it SHOULD be) s
-5 514 M
-( possible to fetch a localized message instead of the transmitted) s
-5 503 M
-( message by using a numerical code. The remaining messages SHOULD be) s
-5 492 M
-( configurable.) s
-5 470 M
-(5. Data Type Representations Used in the SSH Protocols) s
-5 459 M
-( byte) s
-5 437 M
-( A byte represents an arbitrary 8-bit value \(octet\) [RFC-1700].) s
-5 426 M
-( Fixed length data is sometimes represented as an array of bytes,) s
-5 415 M
-( written byte[n], where n is the number of bytes in the array.) s
-5 393 M
-( boolean) s
-5 371 M
-( A boolean value is stored as a single byte. The value 0) s
-5 360 M
-( represents FALSE, and the value 1 represents TRUE. All non-zero) s
-5 349 M
-( values MUST be interpreted as TRUE; however, applications MUST NOT) s
-5 338 M
-( store values other than 0 and 1.) s
-5 316 M
-( uint32) s
-5 294 M
-( Represents a 32-bit unsigned integer. Stored as four bytes in the) s
-5 283 M
-( order of decreasing significance \(network byte order\). For) s
-5 272 M
-( example, the value 699921578 \(0x29b7f4aa\) is stored as 29 b7 f4) s
-5 261 M
-( aa.) s
-5 239 M
-( uint64) s
-5 217 M
-( Represents a 64-bit unsigned integer. Stored as eight bytes in) s
-5 206 M
-( the order of decreasing significance \(network byte order\).) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 8]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (8,9) 5
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 9 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( string) s
-5 668 M
-( Arbitrary length binary string. Strings are allowed to contain) s
-5 657 M
-( arbitrary binary data, including null characters and 8-bit) s
-5 646 M
-( characters. They are stored as a uint32 containing its length) s
-5 635 M
-( \(number of bytes that follow\) and zero \(= empty string\) or more) s
-5 624 M
-( bytes that are the value of the string. Terminating null) s
-5 613 M
-( characters are not used.) s
-5 591 M
-( Strings are also used to store text. In that case, US-ASCII is) s
-5 580 M
-( used for internal names, and ISO-10646 UTF-8 for text that might) s
-5 569 M
-( be displayed to the user. The terminating null character SHOULD) s
-5 558 M
-( NOT normally be stored in the string.) s
-5 536 M
-( For example, the US-ASCII string "testing" is represented as 00 00) s
-5 525 M
-( 00 07 t e s t i n g. The UTF8 mapping does not alter the encoding) s
-5 514 M
-( of US-ASCII characters.) s
-5 492 M
-( mpint) s
-5 470 M
-( Represents multiple precision integers in two's complement format,) s
-5 459 M
-( stored as a string, 8 bits per byte, MSB first. Negative numbers) s
-5 448 M
-( have the value 1 as the most significant bit of the first byte of) s
-5 437 M
-( the data partition. If the most significant bit would be set for a) s
-5 426 M
-( positive number, the number MUST be preceded by a zero byte.) s
-5 415 M
-( Unnecessary leading bytes with the value 0 or 255 MUST NOT be) s
-5 404 M
-( included. The value zero MUST be stored as a string with zero) s
-5 393 M
-( bytes of data.) s
-5 371 M
-( By convention, a number that is used in modular computations in) s
-5 360 M
-( Z_n SHOULD be represented in the range 0 <= x < n.) s
-5 338 M
-( Examples:) s
-5 327 M
-( value \(hex\) representation \(hex\)) s
-5 316 M
-( ---------------------------------------------------------------) s
-5 305 M
-( 0 00 00 00 00) s
-5 294 M
-( 9a378f9b2e332a7 00 00 00 08 09 a3 78 f9 b2 e3 32 a7) s
-5 283 M
-( 80 00 00 00 02 00 80) s
-5 272 M
-( -1234 00 00 00 02 ed cc) s
-5 261 M
-( -deadbeef 00 00 00 05 ff 21 52 41 11) s
-5 217 M
-( name-list) s
-5 195 M
-( A string containing a comma separated list of names. A name list) s
-5 184 M
-( is represented as a uint32 containing its length \(number of bytes) s
-5 173 M
-( that follow\) followed by a comma-separated list of zero or more) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 9]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 10 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( names. A name MUST be non-zero length, and it MUST NOT contain a) s
-5 679 M
-( comma \(','\). Context may impose additional restrictions on the) s
-5 668 M
-( names; for example, the names in a list may have to be valid) s
-5 657 M
-( algorithm identifier \(see Algorithm Naming below\), or [RFC-3066]) s
-5 646 M
-( language tags. The order of the names in a list may or may not be) s
-5 635 M
-( significant, also depending on the context where the list is is) s
-5 624 M
-( used. Terminating NUL characters are not used, neither for the) s
-5 613 M
-( individual names, nor for the list as a whole.) s
-5 591 M
-( Examples:) s
-5 580 M
-( value representation \(hex\)) s
-5 569 M
-( ---------------------------------------) s
-5 558 M
-( \(\), the empty list 00 00 00 00) s
-5 547 M
-( \("zlib"\) 00 00 00 04 7a 6c 69 62) s
-5 536 M
-( \("zlib", "none"\) 00 00 00 09 7a 6c 69 62 2c 6e 6f 6e 65) s
-5 481 M
-(6. Algorithm Naming) s
-5 459 M
-( The SSH protocols refer to particular hash, encryption, integrity,) s
-5 448 M
-( compression, and key exchange algorithms or protocols by names.) s
-5 437 M
-( There are some standard algorithms that all implementations MUST) s
-5 426 M
-( support. There are also algorithms that are defined in the protocol) s
-5 415 M
-( specification but are OPTIONAL. Furthermore, it is expected that) s
-5 404 M
-( some organizations will want to use their own algorithms.) s
-5 382 M
-( In this protocol, all algorithm identifiers MUST be printable) s
-5 371 M
-( US-ASCII non-empty strings no longer than 64 characters. Names MUST) s
-5 360 M
-( be case-sensitive.) s
-5 338 M
-( There are two formats for algorithm names:) s
-5 327 M
-( o Names that do not contain an at-sign \(@\) are reserved to be) s
-5 316 M
-( assigned by IETF consensus \(RFCs\). Examples include `3des-cbc',) s
-5 305 M
-( `sha-1', `hmac-sha1', and `zlib' \(the quotes are not part of the) s
-5 294 M
-( name\). Names of this format MUST NOT be used without first) s
-5 283 M
-( registering them. Registered names MUST NOT contain an at-sign) s
-5 272 M
-( \(@\) or a comma \(,\).) s
-5 261 M
-( o Anyone can define additional algorithms by using names in the) s
-5 250 M
-( format name@domainname, e.g. "[email protected]". The) s
-5 239 M
-( format of the part preceding the at sign is not specified; it MUST) s
-5 228 M
-( consist of US-ASCII characters except at-sign and comma. The part) s
-5 217 M
-( following the at-sign MUST be a valid fully qualified internet) s
-5 206 M
-( domain name [RFC-1034] controlled by the person or organization) s
-5 195 M
-( defining the name. It is up to each domain how it manages its) s
-5 184 M
-( local namespace.) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 10]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (10,11) 6
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 11 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-(7. Message Numbers) s
-5 668 M
-( SSH packets have message numbers in the range 1 to 255. These numbers) s
-5 657 M
-( have been allocated as follows:) s
-5 624 M
-( Transport layer protocol:) s
-5 602 M
-( 1 to 19 Transport layer generic \(e.g. disconnect, ignore, debug,) s
-5 591 M
-( etc.\)) s
-5 580 M
-( 20 to 29 Algorithm negotiation) s
-5 569 M
-( 30 to 49 Key exchange method specific \(numbers can be reused for) s
-5 558 M
-( different authentication methods\)) s
-5 536 M
-( User authentication protocol:) s
-5 514 M
-( 50 to 59 User authentication generic) s
-5 503 M
-( 60 to 79 User authentication method specific \(numbers can be) s
-5 492 M
-( reused for different authentication methods\)) s
-5 470 M
-( Connection protocol:) s
-5 448 M
-( 80 to 89 Connection protocol generic) s
-5 437 M
-( 90 to 127 Channel related messages) s
-5 415 M
-( Reserved for client protocols:) s
-5 393 M
-( 128 to 191 Reserved) s
-5 371 M
-( Local extensions:) s
-5 349 M
-( 192 to 255 Local extensions) s
-5 305 M
-(8. IANA Considerations) s
-5 283 M
-( The initial state of the IANA registry is detailed in [SSH-NUMBERS].) s
-5 261 M
-( Allocation of the following types of names in the SSH protocols is) s
-5 250 M
-( assigned by IETF consensus:) s
-5 239 M
-( o SSH encryption algorithm names,) s
-5 228 M
-( o SSH MAC algorithm names,) s
-5 217 M
-( o SSH public key algorithm names \(public key algorithm also implies) s
-5 206 M
-( encoding and signature/encryption capability\),) s
-5 195 M
-( o SSH key exchange method names, and) s
-5 184 M
-( o SSH protocol \(service\) names.) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 11]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 12 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( These names MUST be printable US-ASCII strings, and MUST NOT contain) s
-5 679 M
-( the characters at-sign \('@'\), comma \(','\), or whitespace or control) s
-5 668 M
-( characters \(ASCII codes 32 or less\). Names are case-sensitive, and) s
-5 657 M
-( MUST NOT be longer than 64 characters.) s
-5 635 M
-( Names with the at-sign \('@'\) in them are allocated by the owner of) s
-5 624 M
-( DNS name after the at-sign \(hierarchical allocation in [RFC-2343]\),) s
-5 613 M
-( otherwise the same restrictions as above.) s
-5 591 M
-( Each category of names listed above has a separate namespace.) s
-5 580 M
-( However, using the same name in multiple categories SHOULD be avoided) s
-5 569 M
-( to minimize confusion.) s
-5 547 M
-( Message numbers \(see Section Message Numbers \(Section 7\)\) in the) s
-5 536 M
-( range of 0..191 are allocated via IETF consensus; message numbers in) s
-5 525 M
-( the 192..255 range \(the "Local extensions" set\) are reserved for) s
-5 514 M
-( private use.) s
-5 492 M
-(9. Security Considerations) s
-5 470 M
-( In order to make the entire body of Security Considerations more) s
-5 459 M
-( accessible, Security Considerations for the transport,) s
-5 448 M
-( authentication, and connection documents have been gathered here.) s
-5 426 M
-( The transport protocol [1] provides a confidential channel over an) s
-5 415 M
-( insecure network. It performs server host authentication, key) s
-5 404 M
-( exchange, encryption, and integrity protection. It also derives a) s
-5 393 M
-( unique session id that may be used by higher-level protocols.) s
-5 371 M
-( The authentication protocol [2] provides a suite of mechanisms which) s
-5 360 M
-( can be used to authenticate the client user to the server.) s
-5 349 M
-( Individual mechanisms specified in the in authentication protocol use) s
-5 338 M
-( the session id provided by the transport protocol and/or depend on) s
-5 327 M
-( the security and integrity guarantees of the transport protocol.) s
-5 305 M
-( The connection protocol [3] specifies a mechanism to multiplex) s
-5 294 M
-( multiple streams [channels] of data over the confidential and) s
-5 283 M
-( authenticated transport. It also specifies channels for accessing an) s
-5 272 M
-( interactive shell, for 'proxy-forwarding' various external protocols) s
-5 261 M
-( over the secure transport \(including arbitrary TCP/IP protocols\), and) s
-5 250 M
-( for accessing secure 'subsystems' on the server host.) s
-5 228 M
-(9.1 Pseudo-Random Number Generation) s
-5 206 M
-( This protocol binds each session key to the session by including) s
-5 195 M
-( random, session specific data in the hash used to produce session) s
-5 184 M
-( keys. Special care should be taken to ensure that all of the random) s
-5 173 M
-( numbers are of good quality. If the random data here \(e.g., DH) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 12]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (12,13) 7
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 13 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( parameters\) are pseudo-random then the pseudo-random number generator) s
-5 679 M
-( should be cryptographically secure \(i.e., its next output not easily) s
-5 668 M
-( guessed even when knowing all previous outputs\) and, furthermore,) s
-5 657 M
-( proper entropy needs to be added to the pseudo-random number) s
-5 646 M
-( generator. RFC 1750 [1750] offers suggestions for sources of random) s
-5 635 M
-( numbers and entropy. Implementors should note the importance of) s
-5 624 M
-( entropy and the well-meant, anecdotal warning about the difficulty in) s
-5 613 M
-( properly implementing pseudo-random number generating functions.) s
-5 591 M
-( The amount of entropy available to a given client or server may) s
-5 580 M
-( sometimes be less than what is required. In this case one must) s
-5 569 M
-( either resort to pseudo-random number generation regardless of) s
-5 558 M
-( insufficient entropy or refuse to run the protocol. The latter is) s
-5 547 M
-( preferable.) s
-5 525 M
-(9.2 Transport) s
-5 503 M
-(9.2.1 Confidentiality) s
-5 481 M
-( It is beyond the scope of this document and the Secure Shell Working) s
-5 470 M
-( Group to analyze or recommend specific ciphers other than the ones) s
-5 459 M
-( which have been established and accepted within the industry. At the) s
-5 448 M
-( time of this writing, ciphers commonly in use include 3DES, ARCFOUR,) s
-5 437 M
-( twofish, serpent and blowfish. AES has been accepted by The) s
-5 426 M
-( published as a US Federal Information Processing Standards [FIPS-197]) s
-5 415 M
-( and the cryptographic community as being acceptable for this purpose) s
-5 404 M
-( as well has accepted AES. As always, implementors and users should) s
-5 393 M
-( check current literature to ensure that no recent vulnerabilities) s
-5 382 M
-( have been found in ciphers used within products. Implementors should) s
-5 371 M
-( also check to see which ciphers are considered to be relatively) s
-5 360 M
-( stronger than others and should recommend their use to users over) s
-5 349 M
-( relatively weaker ciphers. It would be considered good form for an) s
-5 338 M
-( implementation to politely and unobtrusively notify a user that a) s
-5 327 M
-( stronger cipher is available and should be used when a weaker one is) s
-5 316 M
-( actively chosen.) s
-5 294 M
-( The "none" cipher is provided for debugging and SHOULD NOT be used) s
-5 283 M
-( except for that purpose. It's cryptographic properties are) s
-5 272 M
-( sufficiently described in RFC 2410, which will show that its use does) s
-5 261 M
-( not meet the intent of this protocol.) s
-5 239 M
-( The relative merits of these and other ciphers may also be found in) s
-5 228 M
-( current literature. Two references that may provide information on) s
-5 217 M
-( the subject are [SCHNEIER] and [KAUFMAN,PERLMAN,SPECINER]. Both of) s
-5 206 M
-( these describe the CBC mode of operation of certain ciphers and the) s
-5 195 M
-( weakness of this scheme. Essentially, this mode is theoretically) s
-5 184 M
-( vulnerable to chosen cipher-text attacks because of the high) s
-5 173 M
-( predictability of the start of packet sequence. However, this attack) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 13]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 14 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( is still deemed difficult and not considered fully practicable) s
-5 679 M
-( especially if relatively longer block sizes are used.) s
-5 657 M
-( Additionally, another CBC mode attack may be mitigated through the) s
-5 646 M
-( insertion of packets containing SSH_MSG_IGNORE. Without this) s
-5 635 M
-( technique, a specific attack may be successful. For this attack) s
-5 624 M
-( \(commonly known as the Rogaway attack) s
-5 613 M
-( [ROGAWAY],[DAI],[BELLARE,KOHNO,NAMPREMPRE]\) to work, the attacker) s
-5 602 M
-( would need to know the IV of the next block that is going to be) s
-5 591 M
-( encrypted. In CBC mode that is the output of the encryption of the) s
-5 580 M
-( previous block. If the attacker does not have any way to see the) s
-5 569 M
-( packet yet \(i.e it is in the internal buffers of the ssh) s
-5 558 M
-( implementation or even in the kernel\) then this attack will not work.) s
-5 547 M
-( If the last packet has been sent out to the network \(i.e the attacker) s
-5 536 M
-( has access to it\) then he can use the attack.) s
-5 514 M
-( In the optimal case an implementor would need to add an extra packet) s
-5 503 M
-( only if the packet has been sent out onto the network and there are) s
-5 492 M
-( no other packets waiting for transmission. Implementors may wish to) s
-5 481 M
-( check to see if there are any unsent packets awaiting transmission,) s
-5 470 M
-( but unfortunately it is not normally easy to obtain this information) s
-5 459 M
-( from the kernel or buffers. If there are not, then a packet) s
-5 448 M
-( containing SSH_MSG_IGNORE SHOULD be sent. If a new packet is added) s
-5 437 M
-( to the stream every time the attacker knows the IV that is supposed) s
-5 426 M
-( to be used for the next packet, then the attacker will not be able to) s
-5 415 M
-( guess the correct IV, thus the attack will never be successfull.) s
-5 393 M
-( As an example, consider the following case:) s
-5 360 M
-( Client Server) s
-5 349 M
-( ------ ------) s
-5 338 M
-( TCP\(seq=x, len=500\) ->) s
-5 327 M
-( contains Record 1) s
-5 305 M
-( [500 ms passes, no ACK]) s
-5 283 M
-( TCP\(seq=x, len=1000\) ->) s
-5 272 M
-( contains Records 1,2) s
-5 250 M
-( ACK) s
-5 217 M
-( 1. The Nagle algorithm + TCP retransmits mean that the two records) s
-5 206 M
-( get coalesced into a single TCP segment) s
-5 195 M
-( 2. Record 2 is *not* at the beginning of the TCP segment and never) s
-5 184 M
-( will be, since it gets ACKed.) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 14]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (14,15) 8
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 15 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( 3. Yet, the attack is possible because Record 1 has already been) s
-5 679 M
-( seen.) s
-5 657 M
-( As this example indicates, it's totally unsafe to use the existence) s
-5 646 M
-( of unflushed data in the TCP buffers proper as a guide to whether you) s
-5 635 M
-( need an empty packet, since when you do the second write\(\), the) s
-5 624 M
-( buffers will contain the un-ACKed Record 1.) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 15]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 16 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( On the other hand, it's perfectly safe to have the following) s
-5 679 M
-( situation:) s
-5 646 M
-( Client Server) s
-5 635 M
-( ------ ------) s
-5 624 M
-( TCP\(seq=x, len=500\) ->) s
-5 613 M
-( contains SSH_MSG_IGNORE) s
-5 591 M
-( TCP\(seq=y, len=500\) ->) s
-5 580 M
-( contains Data) s
-5 558 M
-( Provided that the IV for second SSH Record is fixed after the data for) s
-5 547 M
-( the Data packet is determined -i.e. you do:) s
-5 536 M
-( read from user) s
-5 525 M
-( encrypt null packet) s
-5 514 M
-( encrypt data packet) s
-5 481 M
-(9.2.2 Data Integrity) s
-5 459 M
-( This protocol does allow the Data Integrity mechanism to be disabled.) s
-5 448 M
-( Implementors SHOULD be wary of exposing this feature for any purpose) s
-5 437 M
-( other than debugging. Users and administrators SHOULD be explicitly) s
-5 426 M
-( warned anytime the "none" MAC is enabled.) s
-5 404 M
-( So long as the "none" MAC is not used, this protocol provides data) s
-5 393 M
-( integrity.) s
-5 371 M
-( Because MACs use a 32 bit sequence number, they might start to leak) s
-5 360 M
-( information after 2**32 packets have been sent. However, following) s
-5 349 M
-( the rekeying recommendations should prevent this attack. The) s
-5 338 M
-( transport protocol [1] recommends rekeying after one gigabyte of) s
-5 327 M
-( data, and the smallest possible packet is 16 bytes. Therefore,) s
-5 316 M
-( rekeying SHOULD happen after 2**28 packets at the very most.) s
-5 294 M
-(9.2.3 Replay) s
-5 272 M
-( The use of a MAC other than 'none' provides integrity and) s
-5 261 M
-( authentication. In addition, the transport protocol provides a) s
-5 250 M
-( unique session identifier \(bound in part to pseudo-random data that) s
-5 239 M
-( is part of the algorithm and key exchange process\) that can be used) s
-5 228 M
-( by higher level protocols to bind data to a given session and prevent) s
-5 217 M
-( replay of data from prior sessions. For example, the authentication) s
-5 206 M
-( protocol uses this to prevent replay of signatures from previous) s
-5 195 M
-( sessions. Because public key authentication exchanges are) s
-5 184 M
-( cryptographically bound to the session \(i.e., to the initial key) s
-5 173 M
-( exchange\) they cannot be successfully replayed in other sessions.) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 16]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (16,17) 9
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 17 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( Note that the session ID can be made public without harming the) s
-5 679 M
-( security of the protocol.) s
-5 657 M
-( If two session happen to have the same session ID [hash of key) s
-5 646 M
-( exchanges] then packets from one can be replayed against the other.) s
-5 635 M
-( It must be stressed that the chances of such an occurrence are,) s
-5 624 M
-( needless to say, minimal when using modern cryptographic methods.) s
-5 613 M
-( This is all the more so true when specifying larger hash function) s
-5 602 M
-( outputs and DH parameters.) s
-5 580 M
-( Replay detection using monotonically increasing sequence numbers as) s
-5 569 M
-( input to the MAC, or HMAC in some cases, is described in [RFC2085] />) s
-5 558 M
-( [RFC2246], [RFC2743], [RFC1964], [RFC2025], and [RFC1510]. The) s
-5 547 M
-( underlying construct is discussed in [RFC2104]. Essentially a) s
-5 536 M
-( different sequence number in each packet ensures that at least this) s
-5 525 M
-( one input to the MAC function will be unique and will provide a) s
-5 514 M
-( nonrecurring MAC output that is not predictable to an attacker. If) s
-5 503 M
-( the session stays active long enough, however, this sequence number) s
-5 492 M
-( will wrap. This event may provide an attacker an opportunity to) s
-5 481 M
-( replay a previously recorded packet with an identical sequence number) s
-5 470 M
-( but only if the peers have not rekeyed since the transmission of the) s
-5 459 M
-( first packet with that sequence number. If the peers have rekeyed,) s
-5 448 M
-( then the replay will be detected as the MAC check will fail. For) s
-5 437 M
-( this reason, it must be emphasized that peers MUST rekey before a) s
-5 426 M
-( wrap of the sequence numbers. Naturally, if an attacker does attempt) s
-5 415 M
-( to replay a captured packet before the peers have rekeyed, then the) s
-5 404 M
-( receiver of the duplicate packet will not be able to validate the MAC) s
-5 393 M
-( and it will be discarded. The reason that the MAC will fail is) s
-5 382 M
-( because the receiver will formulate a MAC based upon the packet) s
-5 371 M
-( contents, the shared secret, and the expected sequence number. Since) s
-5 360 M
-( the replayed packet will not be using that expected sequence number) s
-5 349 M
-( \(the sequence number of the replayed packet will have already been) s
-5 338 M
-( passed by the receiver\) then the calculated MAC will not match the) s
-5 327 M
-( MAC received with the packet.) s
-5 305 M
-(9.2.4 Man-in-the-middle) s
-5 283 M
-( This protocol makes no assumptions nor provisions for an) s
-5 272 M
-( infrastructure or means for distributing the public keys of hosts. It) s
-5 261 M
-( is expected that this protocol will sometimes be used without first) s
-5 250 M
-( verifying the association between the server host key and the server) s
-5 239 M
-( host name. Such usage is vulnerable to man-in-the-middle attacks.) s
-5 228 M
-( This section describes this and encourages administrators and users) s
-5 217 M
-( to understand the importance of verifying this association before any) s
-5 206 M
-( session is initiated.) s
-5 184 M
-( There are three cases of man-in-the-middle attacks to consider. The) s
-5 173 M
-( first is where an attacker places a device between the client and the) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 17]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 18 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( server before the session is initiated. In this case, the attack) s
-5 679 M
-( device is trying to mimic the legitimate server and will offer its) s
-5 668 M
-( public key to the client when the client initiates a session. If it) s
-5 657 M
-( were to offer the public key of the server, then it would not be able) s
-5 646 M
-( to decrypt or sign the transmissions between the legitimate server) s
-5 635 M
-( and the client unless it also had access to the private-key of the) s
-5 624 M
-( host. The attack device will also, simultaneously to this, initiate) s
-5 613 M
-( a session to the legitimate server masquerading itself as the client.) s
-5 602 M
-( If the public key of the server had been securely distributed to the) s
-5 591 M
-( client prior to that session initiation, the key offered to the) s
-5 580 M
-( client by the attack device will not match the key stored on the) s
-5 569 M
-( client. In that case, the user SHOULD be given a warning that the) s
-5 558 M
-( offered host key does not match the host key cached on the client.) s
-5 547 M
-( As described in Section 3.1 of [ARCH], the user may be free to accept) s
-5 536 M
-( the new key and continue the session. It is RECOMMENDED that the) s
-5 525 M
-( warning provide sufficient information to the user of the client) s
-5 514 M
-( device so they may make an informed decision. If the user chooses to) s
-5 503 M
-( continue the session with the stored public-key of the server \(not) s
-5 492 M
-( the public-key offered at the start of the session\), then the session) s
-5 481 M
-( specific data between the attacker and server will be different) s
-5 470 M
-( between the client-to-attacker session and the attacker-to-server) s
-5 459 M
-( sessions due to the randomness discussed above. From this, the) s
-5 448 M
-( attacker will not be able to make this attack work since the attacker) s
-5 437 M
-( will not be able to correctly sign packets containing this session) s
-5 426 M
-( specific data from the server since he does not have the private key) s
-5 415 M
-( of that server.) s
-5 393 M
-( The second case that should be considered is similar to the first) s
-5 382 M
-( case in that it also happens at the time of connection but this case) s
-5 371 M
-( points out the need for the secure distribution of server public) s
-5 360 M
-( keys. If the server public keys are not securely distributed then) s
-5 349 M
-( the client cannot know if it is talking to the intended server. An) s
-5 338 M
-( attacker may use social engineering techniques to pass off server) s
-5 327 M
-( keys to unsuspecting users and may then place a man-in-the-middle) s
-5 316 M
-( attack device between the legitimate server and the clients. If this) s
-5 305 M
-( is allowed to happen then the clients will form client-to-attacker) s
-5 294 M
-( sessions and the attacker will form attacker-to-server sessions and) s
-5 283 M
-( will be able to monitor and manipulate all of the traffic between the) s
-5 272 M
-( clients and the legitimate servers. Server administrators are) s
-5 261 M
-( encouraged to make host key fingerprints available for checking by) s
-5 250 M
-( some means whose security does not rely on the integrity of the) s
-5 239 M
-( actual host keys. Possible mechanisms are discussed in Section 3.1) s
-5 228 M
-( of [SSH-ARCH] and may also include secured Web pages, physical pieces) s
-5 217 M
-( of paper, etc. Implementors SHOULD provide recommendations on how) s
-5 206 M
-( best to do this with their implementation. Because the protocol is) s
-5 195 M
-( extensible, future extensions to the protocol may provide better) s
-5 184 M
-( mechanisms for dealing with the need to know the server's host key) s
-5 173 M
-( before connecting. For example, making the host key fingerprint) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 18]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (18,19) 10
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 19 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( available through a secure DNS lookup, or using kerberos over gssapi) s
-5 679 M
-( during key exchange to authenticate the server are possibilities.) s
-5 657 M
-( In the third man-in-the-middle case, attackers may attempt to) s
-5 646 M
-( manipulate packets in transit between peers after the session has) s
-5 635 M
-( been established. As described in the Replay part of this section, a) s
-5 624 M
-( successful attack of this nature is very improbable. As in the) s
-5 613 M
-( Replay section, this reasoning does assume that the MAC is secure and) s
-5 602 M
-( that it is infeasible to construct inputs to a MAC algorithm to give) s
-5 591 M
-( a known output. This is discussed in much greater detail in Section) s
-5 580 M
-( 6 of RFC 2104. If the MAC algorithm has a vulnerability or is weak) s
-5 569 M
-( enough, then the attacker may be able to specify certain inputs to) s
-5 558 M
-( yield a known MAC. With that they may be able to alter the contents) s
-5 547 M
-( of a packet in transit. Alternatively the attacker may be able to) s
-5 536 M
-( exploit the algorithm vulnerability or weakness to find the shared) s
-5 525 M
-( secret by reviewing the MACs from captured packets. In either of) s
-5 514 M
-( those cases, an attacker could construct a packet or packets that) s
-5 503 M
-( could be inserted into an SSH stream. To prevent that, implementors) s
-5 492 M
-( are encouraged to utilize commonly accepted MAC algorithms and) s
-5 481 M
-( administrators are encouraged to watch current literature and) s
-5 470 M
-( discussions of cryptography to ensure that they are not using a MAC) s
-5 459 M
-( algorithm that has a recently found vulnerability or weakness.) s
-5 437 M
-( In summary, the use of this protocol without a reliable association) s
-5 426 M
-( of the binding between a host and its host keys is inherently) s
-5 415 M
-( insecure and is NOT RECOMMENDED. It may however be necessary in) s
-5 404 M
-( non-security critical environments, and will still provide protection) s
-5 393 M
-( against passive attacks. Implementors of protocols and applications) s
-5 382 M
-( running on top of this protocol should keep this possibility in mind.) s
-5 360 M
-(9.2.5 Denial-of-service) s
-5 338 M
-( This protocol is designed to be used over a reliable transport. If) s
-5 327 M
-( transmission errors or message manipulation occur, the connection is) s
-5 316 M
-( closed. The connection SHOULD be re-established if this occurs.) s
-5 305 M
-( Denial of service attacks of this type \("wire cutter"\) are almost) s
-5 294 M
-( impossible to avoid.) s
-5 272 M
-( In addition, this protocol is vulnerable to Denial of Service attacks) s
-5 261 M
-( because an attacker can force the server to go through the CPU and) s
-5 250 M
-( memory intensive tasks of connection setup and key exchange without) s
-5 239 M
-( authenticating. Implementors SHOULD provide features that make this) s
-5 228 M
-( more difficult. For example, only allowing connections from a subset) s
-5 217 M
-( of IPs known to have valid users.) s
-5 195 M
-(9.2.6 Covert Channels) s
-5 173 M
-( The protocol was not designed to eliminate covert channels. For) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 19]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 20 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( example, the padding, SSH_MSG_IGNORE messages, and several other) s
-5 679 M
-( places in the protocol can be used to pass covert information, and) s
-5 668 M
-( the recipient has no reliable way to verify whether such information) s
-5 657 M
-( is being sent.) s
-5 635 M
-(9.2.7 Forward Secrecy) s
-5 613 M
-( It should be noted that the Diffie-Hellman key exchanges may provide) s
-5 602 M
-( perfect forward secrecy \(PFS\). PFS is essentially defined as the) s
-5 591 M
-( cryptographic property of a key-establishment protocol in which the) s
-5 580 M
-( compromise of a session key or long-term private key after a given) s
-5 569 M
-( session does not cause the compromise of any earlier session. [ANSI) s
-5 558 M
-( T1.523-2001] SSHv2 sessions resulting from a key exchange using) s
-5 547 M
-( diffie-hellman-group1-sha1 are secure even if private keying/) s
-5 536 M
-( authentication material is later revealed, but not if the session) s
-5 525 M
-( keys are revealed. So, given this definition of PFS, SSHv2 does have) s
-5 514 M
-( PFS. It is hoped that all other key exchange mechanisms proposed and) s
-5 503 M
-( used in the future will also provide PFS. This property is not) s
-5 492 M
-( commuted to any of the applications or protocols using SSH as a) s
-5 481 M
-( transport however. The transport layer of SSH provides) s
-5 470 M
-( confidentiality for password authentication and other methods that) s
-5 459 M
-( rely on secret data.) s
-5 437 M
-( Of course, if the DH private parameters for the client and server are) s
-5 426 M
-( revealed then the session key is revealed, but these items can be) s
-5 415 M
-( thrown away after the key exchange completes. It's worth pointing) s
-5 404 M
-( out that these items should not be allowed to end up on swap space) s
-5 393 M
-( and that they should be erased from memory as soon as the key) s
-5 382 M
-( exchange completes.) s
-5 360 M
-(9.3 Authentication Protocol) s
-5 338 M
-( The purpose of this protocol is to perform client user) s
-5 327 M
-( authentication. It assumes that this run over a secure transport) s
-5 316 M
-( layer protocol, which has already authenticated the server machine,) s
-5 305 M
-( established an encrypted communications channel, and computed a) s
-5 294 M
-( unique session identifier for this session.) s
-5 272 M
-( Several authentication methods with different security) s
-5 261 M
-( characteristics are allowed. It is up to the server's local policy) s
-5 250 M
-( to decide which methods \(or combinations of methods\) it is willing to) s
-5 239 M
-( accept for each user. Authentication is no stronger than the weakest) s
-5 228 M
-( combination allowed.) s
-5 206 M
-( The server may go into a "sleep" period after repeated unsuccessful) s
-5 195 M
-( authentication attempts to make key search more difficult for) s
-5 184 M
-( attackers. Care should be taken so that this doesn't become a) s
-5 173 M
-( self-denial of service vector.) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 20]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (20,21) 11
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 21 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-(9.3.1 Weak Transport) s
-5 668 M
-( If the transport layer does not provide confidentiality,) s
-5 657 M
-( authentication methods that rely on secret data SHOULD be disabled.) s
-5 646 M
-( If it does not provide strong integrity protection, requests to) s
-5 635 M
-( change authentication data \(e.g. a password change\) SHOULD be) s
-5 624 M
-( disabled to prevent an attacker from modifying the ciphertext) s
-5 613 M
-( without being noticed, or rendering the new authentication data) s
-5 602 M
-( unusable \(denial of service\).) s
-5 580 M
-( The assumption as stated above that the Authentication Protocol only) s
-5 569 M
-( run over a secure transport that has previously authenticated the) s
-5 558 M
-( server is very important to note. People deploying SSH are reminded) s
-5 547 M
-( of the consequences of man-in-the-middle attacks if the client does) s
-5 536 M
-( not have a very strong a priori association of the server with the) s
-5 525 M
-( host key of that server. Specifically for the case of the) s
-5 514 M
-( Authentication Protocol the client may form a session to a) s
-5 503 M
-( man-in-the-middle attack device and divulge user credentials such as) s
-5 492 M
-( their username and password. Even in the cases of authentication) s
-5 481 M
-( where no user credentials are divulged, an attacker may still gain) s
-5 470 M
-( information they shouldn't have by capturing key-strokes in much the) s
-5 459 M
-( same way that a honeypot works.) s
-5 437 M
-(9.3.2 Debug messages) s
-5 415 M
-( Special care should be taken when designing debug messages. These) s
-5 404 M
-( messages may reveal surprising amounts of information about the host) s
-5 393 M
-( if not properly designed. Debug messages can be disabled \(during) s
-5 382 M
-( user authentication phase\) if high security is required.) s
-5 371 M
-( Administrators of host machines should make all attempts to) s
-5 360 M
-( compartmentalize all event notification messages and protect them) s
-5 349 M
-( from unwarranted observation. Developers should be aware of the) s
-5 338 M
-( sensitive nature of some of the normal event messages and debug) s
-5 327 M
-( messages and may want to provide guidance to administrators on ways) s
-5 316 M
-( to keep this information away from unauthorized people. Developers) s
-5 305 M
-( should consider minimizing the amount of sensitive information) s
-5 294 M
-( obtainable by users during the authentication phase in accordance) s
-5 283 M
-( with the local policies. For this reason, it is RECOMMENDED that) s
-5 272 M
-( debug messages be initially disabled at the time of deployment and) s
-5 261 M
-( require an active decision by an administrator to allow them to be) s
-5 250 M
-( enabled. It is also RECOMMENDED that a message expressing this) s
-5 239 M
-( concern be presented to the administrator of a system when the action) s
-5 228 M
-( is taken to enable debugging messages.) s
-5 206 M
-(9.3.3 Local security policy) s
-5 184 M
-( Implementer MUST ensure that the credentials provided validate the) s
-5 173 M
-( professed user and also MUST ensure that the local policy of the) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 21]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 22 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( server permits the user the access requested. In particular, because) s
-5 679 M
-( of the flexible nature of the SSH connection protocol, it may not be) s
-5 668 M
-( possible to determine the local security policy, if any, that should) s
-5 657 M
-( apply at the time of authentication because the kind of service being) s
-5 646 M
-( requested is not clear at that instant. For example, local policy) s
-5 635 M
-( might allow a user to access files on the server, but not start an) s
-5 624 M
-( interactive shell. However, during the authentication protocol, it is) s
-5 613 M
-( not known whether the user will be accessing files or attempting to) s
-5 602 M
-( use an interactive shell, or even both. In any event, where local) s
-5 591 M
-( security policy for the server host exists, it MUST be applied and) s
-5 580 M
-( enforced correctly.) s
-5 558 M
-( Implementors are encouraged to provide a default local policy and) s
-5 547 M
-( make its parameters known to administrators and users. At the) s
-5 536 M
-( discretion of the implementors, this default policy may be along the) s
-5 525 M
-( lines of 'anything goes' where there are no restrictions placed upon) s
-5 514 M
-( users, or it may be along the lines of 'excessively restrictive' in) s
-5 503 M
-( which case the administrators will have to actively make changes to) s
-5 492 M
-( this policy to meet their needs. Alternatively, it may be some) s
-5 481 M
-( attempt at providing something practical and immediately useful to) s
-5 470 M
-( the administrators of the system so they don't have to put in much) s
-5 459 M
-( effort to get SSH working. Whatever choice is made MUST be applied) s
-5 448 M
-( and enforced as required above.) s
-5 426 M
-(9.3.4 Public key authentication) s
-5 404 M
-( The use of public-key authentication assumes that the client host has) s
-5 393 M
-( not been compromised. It also assumes that the private-key of the) s
-5 382 M
-( server host has not been compromised.) s
-5 360 M
-( This risk can be mitigated by the use of passphrases on private keys;) s
-5 349 M
-( however, this is not an enforceable policy. The use of smartcards,) s
-5 338 M
-( or other technology to make passphrases an enforceable policy is) s
-5 327 M
-( suggested.) s
-5 305 M
-( The server could require both password and public-key authentication,) s
-5 294 M
-( however, this requires the client to expose its password to the) s
-5 283 M
-( server \(see section on password authentication below.\)) s
-5 261 M
-(9.3.5 Password authentication) s
-5 239 M
-( The password mechanism as specified in the authentication protocol) s
-5 228 M
-( assumes that the server has not been compromised. If the server has) s
-5 217 M
-( been compromised, using password authentication will reveal a valid) s
-5 206 M
-( username / password combination to the attacker, which may lead to) s
-5 195 M
-( further compromises.) s
-5 173 M
-( This vulnerability can be mitigated by using an alternative form of) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 22]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (22,23) 12
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 23 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( authentication. For example, public-key authentication makes no) s
-5 679 M
-( assumptions about security on the server.) s
-5 657 M
-(9.3.6 Host based authentication) s
-5 635 M
-( Host based authentication assumes that the client has not been) s
-5 624 M
-( compromised. There are no mitigating strategies, other than to use) s
-5 613 M
-( host based authentication in combination with another authentication) s
-5 602 M
-( method.) s
-5 580 M
-(9.4 Connection protocol) s
-5 558 M
-(9.4.1 End point security) s
-5 536 M
-( End point security is assumed by the connection protocol. If the) s
-5 525 M
-( server has been compromised, any terminal sessions, port forwarding,) s
-5 514 M
-( or systems accessed on the host are compromised. There are no) s
-5 503 M
-( mitigating factors for this.) s
-5 481 M
-( If the client end point has been compromised, and the server fails to) s
-5 470 M
-( stop the attacker at the authentication protocol, all services) s
-5 459 M
-( exposed \(either as subsystems or through forwarding\) will be) s
-5 448 M
-( vulnerable to attack. Implementors SHOULD provide mechanisms for) s
-5 437 M
-( administrators to control which services are exposed to limit the) s
-5 426 M
-( vulnerability of other services.) s
-5 404 M
-( These controls might include controlling which machines and ports can) s
-5 393 M
-( be target in 'port-forwarding' operations, which users are allowed to) s
-5 382 M
-( use interactive shell facilities, or which users are allowed to use) s
-5 371 M
-( exposed subsystems.) s
-5 349 M
-(9.4.2 Proxy forwarding) s
-5 327 M
-( The SSH connection protocol allows for proxy forwarding of other) s
-5 316 M
-( protocols such as SNMP, POP3, and HTTP. This may be a concern for) s
-5 305 M
-( network administrators who wish to control the access of certain) s
-5 294 M
-( applications by users located outside of their physical location.) s
-5 283 M
-( Essentially, the forwarding of these protocols may violate site) s
-5 272 M
-( specific security policies as they may be undetectably tunneled) s
-5 261 M
-( through a firewall. Implementors SHOULD provide an administrative) s
-5 250 M
-( mechanism to control the proxy forwarding functionality so that site) s
-5 239 M
-( specific security policies may be upheld.) s
-5 217 M
-( In addition, a reverse proxy forwarding functionality is available,) s
-5 206 M
-( which again can be used to bypass firewall controls.) s
-5 184 M
-( As indicated above, end-point security is assumed during proxy) s
-5 173 M
-( forwarding operations. Failure of end-point security will compromise) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 23]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 24 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( all data passed over proxy forwarding.) s
-5 668 M
-(9.4.3 X11 forwarding) s
-5 646 M
-( Another form of proxy forwarding provided by the ssh connection) s
-5 635 M
-( protocol is the forwarding of the X11 protocol. If end-point) s
-5 624 M
-( security has been compromised, X11 forwarding may allow attacks) s
-5 613 M
-( against the X11 server. Users and administrators should, as a matter) s
-5 602 M
-( of course, use appropriate X11 security mechanisms to prevent) s
-5 591 M
-( unauthorized use of the X11 server. Implementors, administrators and) s
-5 580 M
-( users who wish to further explore the security mechanisms of X11 are) s
-5 569 M
-( invited to read [SCHEIFLER] and analyze previously reported problems) s
-5 558 M
-( with the interactions between SSH forwarding and X11 in CERT) s
-5 547 M
-( vulnerabilities VU#363181 and VU#118892 [CERT].) s
-5 525 M
-( X11 display forwarding with SSH, by itself, is not sufficient to) s
-5 514 M
-( correct well known problems with X11 security [VENEMA]. However, X11) s
-5 503 M
-( display forwarding in SSHv2 \(or other, secure protocols\), combined) s
-5 492 M
-( with actual and pseudo-displays which accept connections only over) s
-5 481 M
-( local IPC mechanisms authorized by permissions or ACLs, does correct) s
-5 470 M
-( many X11 security problems as long as the "none" MAC is not used. It) s
-5 459 M
-( is RECOMMENDED that X11 display implementations default to allowing) s
-5 448 M
-( display opens only over local IPC. It is RECOMMENDED that SSHv2) s
-5 437 M
-( server implementations that support X11 forwarding default to) s
-5 426 M
-( allowing display opens only over local IPC. On single-user systems) s
-5 415 M
-( it might be reasonable to default to allowing local display opens) s
-5 404 M
-( over TCP/IP.) s
-5 382 M
-( Implementors of the X11 forwarding protocol SHOULD implement the) s
-5 371 M
-( magic cookie access checking spoofing mechanism as described in) s
-5 360 M
-( [ssh-connect] as an additional mechanism to prevent unauthorized use) s
-5 349 M
-( of the proxy.) s
-5 327 M
-(Normative References) s
-5 305 M
-( [SSH-ARCH]) s
-5 294 M
-( Ylonen, T., "SSH Protocol Architecture", I-D) s
-5 283 M
-( draft-ietf-architecture-15.txt, Oct 2003.) s
-5 261 M
-( [SSH-TRANS]) s
-5 250 M
-( Ylonen, T., "SSH Transport Layer Protocol", I-D) s
-5 239 M
-( draft-ietf-transport-17.txt, Oct 2003.) s
-5 217 M
-( [SSH-USERAUTH]) s
-5 206 M
-( Ylonen, T., "SSH Authentication Protocol", I-D) s
-5 195 M
-( draft-ietf-userauth-18.txt, Oct 2003.) s
-5 173 M
-( [SSH-CONNECT]) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 24]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (24,25) 13
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 25 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( Ylonen, T., "SSH Connection Protocol", I-D) s
-5 679 M
-( draft-ietf-connect-18.txt, Oct 2003.) s
-5 657 M
-( [SSH-NUMBERS]) s
-5 646 M
-( Lehtinen, S. and D. Moffat, "SSH Protocol Assigned) s
-5 635 M
-( Numbers", I-D draft-ietf-secsh-assignednumbers-05.txt, Oct) s
-5 624 M
-( 2003.) s
-5 602 M
-( [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate) s
-5 591 M
-( Requirement Levels", BCP 14, RFC 2119, March 1997.) s
-5 569 M
-(Informative References) s
-5 547 M
-( [FIPS-186]) s
-5 536 M
-( Federal Information Processing Standards Publication,) s
-5 525 M
-( "FIPS PUB 186, Digital Signature Standard", May 1994.) s
-5 503 M
-( [FIPS-197]) s
-5 492 M
-( National Institue of Standards and Technology, "FIPS 197,) s
-5 481 M
-( Specification for the Advanced Encryption Standard",) s
-5 470 M
-( November 2001.) s
-5 448 M
-( [ANSI T1.523-2001]) s
-5 437 M
-( American National Standards Insitute, Inc., "Telecom) s
-5 426 M
-( Glossary 2000", February 2001.) s
-5 404 M
-( [SCHEIFLER]) s
-5 393 M
-( Scheifler, R., "X Window System : The Complete Reference) s
-5 382 M
-( to Xlib, X Protocol, Icccm, Xlfd, 3rd edition.", Digital) s
-5 371 M
-( Press ISBN 1555580882, Feburary 1992.) s
-5 349 M
-( [RFC0854] Postel, J. and J. Reynolds, "Telnet Protocol) s
-5 338 M
-( Specification", STD 8, RFC 854, May 1983.) s
-5 316 M
-( [RFC0894] Hornig, C., "Standard for the transmission of IP datagrams) s
-5 305 M
-( over Ethernet networks", STD 41, RFC 894, April 1984.) s
-5 283 M
-( [RFC1034] Mockapetris, P., "Domain names - concepts and facilities",) s
-5 272 M
-( STD 13, RFC 1034, November 1987.) s
-5 250 M
-( [RFC1134] Perkins, D., "Point-to-Point Protocol: A proposal for) s
-5 239 M
-( multi-protocol transmission of datagrams over) s
-5 228 M
-( Point-to-Point links", RFC 1134, November 1989.) s
-5 206 M
-( [RFC1282] Kantor, B., "BSD Rlogin", RFC 1282, December 1991.) s
-5 184 M
-( [RFC1510] Kohl, J. and B. Neuman, "The Kerberos Network) s
-5 173 M
-( Authentication Service \(V5\)", RFC 1510, September 1993.) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 25]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 26 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( [RFC1700] Reynolds, J. and J. Postel, "Assigned Numbers", RFC 1700,) s
-5 679 M
-( October 1994.) s
-5 657 M
-( [RFC1750] Eastlake, D., Crocker, S. and J. Schiller, "Randomness) s
-5 646 M
-( Recommendations for Security", RFC 1750, December 1994.) s
-5 624 M
-( [RFC3066] Alvestrand, H., "Tags for the Identification of) s
-5 613 M
-( Languages", BCP 47, RFC 3066, January 2001.) s
-5 591 M
-( [RFC1964] Linn, J., "The Kerberos Version 5 GSS-API Mechanism", RFC) s
-5 580 M
-( 1964, June 1996.) s
-5 558 M
-( [RFC2025] Adams, C., "The Simple Public-Key GSS-API Mechanism) s
-5 547 M
-( \(SPKM\)", RFC 2025, October 1996.) s
-5 525 M
-( [RFC2085] Oehler, M. and R. Glenn, "HMAC-MD5 IP Authentication with) s
-5 514 M
-( Replay Prevention", RFC 2085, February 1997.) s
-5 492 M
-( [RFC2104] Krawczyk, H., Bellare, M. and R. Canetti, "HMAC:) s
-5 481 M
-( Keyed-Hashing for Message Authentication", RFC 2104,) s
-5 470 M
-( February 1997.) s
-5 448 M
-( [RFC2246] Dierks, T., Allen, C., Treese, W., Karlton, P., Freier, A.) s
-5 437 M
-( and P. Kocher, "The TLS Protocol Version 1.0", RFC 2246,) s
-5 426 M
-( January 1999.) s
-5 404 M
-( [RFC2279] Yergeau, F., "UTF-8, a transformation format of ISO) s
-5 393 M
-( 10646", RFC 2279, January 1998.) s
-5 371 M
-( [RFC2410] Glenn, R. and S. Kent, "The NULL Encryption Algorithm and) s
-5 360 M
-( Its Use With IPsec", RFC 2410, November 1998.) s
-5 338 M
-( [RFC2434] Narten, T. and H. Alvestrand, "Guidelines for Writing an) s
-5 327 M
-( IANA Considerations Section in RFCs", BCP 26, RFC 2434,) s
-5 316 M
-( October 1998.) s
-5 294 M
-( [RFC2743] Linn, J., "Generic Security Service Application Program) s
-5 283 M
-( Interface Version 2, Update 1", RFC 2743, January 2000.) s
-5 261 M
-( [SCHNEIER]) s
-5 250 M
-( Schneier, B., "Applied Cryptography Second Edition:) s
-5 239 M
-( protocols algorithms and source in code in C", 1996.) s
-5 217 M
-( [KAUFMAN,PERLMAN,SPECINER]) s
-5 206 M
-( Kaufman, C., Perlman, R. and M. Speciner, "Network) s
-5 195 M
-( Security: PRIVATE Communication in a PUBLIC World", 1995.) s
-5 173 M
-( [CERT] CERT Coordination Center, The., "http://www.cert.org/nav/) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 26]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (26,27) 14
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 27 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( index_red.html".) s
-5 668 M
-( [VENEMA] Venema, W., "Murphy's Law and Computer Security",) s
-5 657 M
-( Proceedings of 6th USENIX Security Symposium, San Jose CA) s
-5 646 M
-( http://www.usenix.org/publications/library/proceedings/) s
-5 635 M
-( sec96/venema.html, July 1996.) s
-5 613 M
-( [ROGAWAY] Rogaway, P., "Problems with Proposed IP Cryptography",) s
-5 602 M
-( Unpublished paper http://www.cs.ucdavis.edu/~rogaway/) s
-5 591 M
-( papers/draft-rogaway-ipsec-comments-00.txt, 1996.) s
-5 569 M
-( [DAI] Dai, W., "An attack against SSH2 protocol", Email to the) s
-5 558 M
-( SECSH Working Group [email protected] ftp://) s
-5 547 M
-( ftp.ietf.org/ietf-mail-archive/secsh/2002-02.mail, Feb) s
-5 536 M
-( 2002.) s
-5 514 M
-( [BELLARE,KOHNO,NAMPREMPRE]) s
-5 503 M
-( Bellaire, M., Kohno, T. and C. Namprempre, "Authenticated) s
-5 492 M
-( Encryption in SSH: Fixing the SSH Binary Packet Protocol",) s
-5 481 M
-( , Sept 2002.) s
-5 448 M
-(Authors' Addresses) s
-5 426 M
-( Tatu Ylonen) s
-5 415 M
-( SSH Communications Security Corp) s
-5 404 M
-( Fredrikinkatu 42) s
-5 393 M
-( HELSINKI FIN-00100) s
-5 382 M
-( Finland) s
-5 360 M
-( EMail: [email protected]) s
-5 327 M
-( Darren J. Moffat \(editor\)) s
-5 316 M
-( Sun Microsystems, Inc) s
-5 305 M
-( 17 Network Circle) s
-5 294 M
-( Menlo Park CA 94025) s
-5 283 M
-( USA) s
-5 261 M
-( EMail: [email protected]) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 27]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 28 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-(Intellectual Property Statement) s
-5 668 M
-( The IETF takes no position regarding the validity or scope of any) s
-5 657 M
-( intellectual property or other rights that might be claimed to) s
-5 646 M
-( pertain to the implementation or use of the technology described in) s
-5 635 M
-( this document or the extent to which any license under such rights) s
-5 624 M
-( might or might not be available; neither does it represent that it) s
-5 613 M
-( has made any effort to identify any such rights. Information on the) s
-5 602 M
-( IETF's procedures with respect to rights in standards-track and) s
-5 591 M
-( standards-related documentation can be found in BCP-11. Copies of) s
-5 580 M
-( claims of rights made available for publication and any assurances of) s
-5 569 M
-( licenses to be made available, or the result of an attempt made to) s
-5 558 M
-( obtain a general license or permission for the use of such) s
-5 547 M
-( proprietary rights by implementors or users of this specification can) s
-5 536 M
-( be obtained from the IETF Secretariat.) s
-5 514 M
-( The IETF invites any interested party to bring to its attention any) s
-5 503 M
-( copyrights, patents or patent applications, or other proprietary) s
-5 492 M
-( rights which may cover technology that may be required to practice) s
-5 481 M
-( this standard. Please address the information to the IETF Executive) s
-5 470 M
-( Director.) s
-5 448 M
-( The IETF has been notified of intellectual property rights claimed in) s
-5 437 M
-( regard to some or all of the specification contained in this) s
-5 426 M
-( document. For more information consult the online list of claimed) s
-5 415 M
-( rights.) s
-5 382 M
-(Full Copyright Statement) s
-5 360 M
-( Copyright \(C\) The Internet Society \(2003\). All Rights Reserved.) s
-5 338 M
-( This document and translations of it may be copied and furnished to) s
-5 327 M
-( others, and derivative works that comment on or otherwise explain it) s
-5 316 M
-( or assist in its implementation may be prepared, copied, published) s
-5 305 M
-( and distributed, in whole or in part, without restriction of any) s
-5 294 M
-( kind, provided that the above copyright notice and this paragraph are) s
-5 283 M
-( included on all such copies and derivative works. However, this) s
-5 272 M
-( document itself may not be modified in any way, such as by removing) s
-5 261 M
-( the copyright notice or references to the Internet Society or other) s
-5 250 M
-( Internet organizations, except as needed for the purpose of) s
-5 239 M
-( developing Internet standards in which case the procedures for) s
-5 228 M
-( copyrights defined in the Internet Standards process must be) s
-5 217 M
-( followed, or as required to translate it into languages other than) s
-5 206 M
-( English.) s
-5 184 M
-( The limited permissions granted above are perpetual and will not be) s
-5 173 M
-( revoked by the Internet Society or its successors or assignees.) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 28]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (28,29) 15
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 29 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( This document and the information contained herein is provided on an) s
-5 679 M
-( "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING) s
-5 668 M
-( TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING) s
-5 657 M
-( BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION) s
-5 646 M
-( HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF) s
-5 635 M
-( MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.) s
-5 602 M
-(Acknowledgment) s
-5 580 M
-( Funding for the RFC Editor function is currently provided by the) s
-5 569 M
-( Internet Society.) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 29]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-showpage
-PStoPSsaved restore
-%%Trailer
-%%Pages: 29
-%%DocumentNeededResources: font Courier-Bold Courier
-%%EOF
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-architecture-15.txt b/lib/ssh/doc/standard/draft-ietf-secsh-architecture-15.txt
deleted file mode 100644
index 18070e8485..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-architecture-15.txt
+++ /dev/null
@@ -1,1624 +0,0 @@
-
-
-
-Network Working Group T. Ylonen
-Internet-Draft SSH Communications Security Corp
-Expires: March 31, 2004 D. Moffat, Ed.
- Sun Microsystems, Inc
- Oct 2003
-
-
- SSH Protocol Architecture
- draft-ietf-secsh-architecture-15.txt
-
-Status of this Memo
-
- This document is an Internet-Draft and is in full conformance with
- all provisions of Section 10 of RFC2026.
-
- Internet-Drafts are working documents of the Internet Engineering
- Task Force (IETF), its areas, and its working groups. Note that other
- groups may also distribute working documents as Internet-Drafts.
-
- Internet-Drafts are draft documents valid for a maximum of six months
- and may be updated, replaced, or obsoleted by other documents at any
- time. It is inappropriate to use Internet-Drafts as reference
- material or to cite them other than as "work in progress."
-
- The list of current Internet-Drafts can be accessed at http://
- www.ietf.org/ietf/1id-abstracts.txt.
-
- The list of Internet-Draft Shadow Directories can be accessed at
- http://www.ietf.org/shadow.html.
-
- This Internet-Draft will expire on March 31, 2004.
-
-Copyright Notice
-
- Copyright (C) The Internet Society (2003). All Rights Reserved.
-
-Abstract
-
- SSH is a protocol for secure remote login and other secure network
- services over an insecure network. This document describes the
- architecture of the SSH protocol, as well as the notation and
- terminology used in SSH protocol documents. It also discusses the SSH
- algorithm naming system that allows local extensions. The SSH
- protocol consists of three major components: The Transport Layer
- Protocol provides server authentication, confidentiality, and
- integrity with perfect forward secrecy. The User Authentication
- Protocol authenticates the client to the server. The Connection
- Protocol multiplexes the encrypted tunnel into several logical
- channels. Details of these protocols are described in separate
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 1]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- documents.
-
-Table of Contents
-
- 1. Contributors . . . . . . . . . . . . . . . . . . . . . . . . 3
- 2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3
- 3. Specification of Requirements . . . . . . . . . . . . . . . 3
- 4. Architecture . . . . . . . . . . . . . . . . . . . . . . . . 3
- 4.1 Host Keys . . . . . . . . . . . . . . . . . . . . . . . . . 4
- 4.2 Extensibility . . . . . . . . . . . . . . . . . . . . . . . 5
- 4.3 Policy Issues . . . . . . . . . . . . . . . . . . . . . . . 5
- 4.4 Security Properties . . . . . . . . . . . . . . . . . . . . 6
- 4.5 Packet Size and Overhead . . . . . . . . . . . . . . . . . . 6
- 4.6 Localization and Character Set Support . . . . . . . . . . . 7
- 5. Data Type Representations Used in the SSH Protocols . . . . 8
- 6. Algorithm Naming . . . . . . . . . . . . . . . . . . . . . . 10
- 7. Message Numbers . . . . . . . . . . . . . . . . . . . . . . 11
- 8. IANA Considerations . . . . . . . . . . . . . . . . . . . . 11
- 9. Security Considerations . . . . . . . . . . . . . . . . . . 12
- 9.1 Pseudo-Random Number Generation . . . . . . . . . . . . . . 12
- 9.2 Transport . . . . . . . . . . . . . . . . . . . . . . . . . 13
- 9.2.1 Confidentiality . . . . . . . . . . . . . . . . . . . . . . 13
- 9.2.2 Data Integrity . . . . . . . . . . . . . . . . . . . . . . . 16
- 9.2.3 Replay . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
- 9.2.4 Man-in-the-middle . . . . . . . . . . . . . . . . . . . . . 17
- 9.2.5 Denial-of-service . . . . . . . . . . . . . . . . . . . . . 19
- 9.2.6 Covert Channels . . . . . . . . . . . . . . . . . . . . . . 19
- 9.2.7 Forward Secrecy . . . . . . . . . . . . . . . . . . . . . . 20
- 9.3 Authentication Protocol . . . . . . . . . . . . . . . . . . 20
- 9.3.1 Weak Transport . . . . . . . . . . . . . . . . . . . . . . . 21
- 9.3.2 Debug messages . . . . . . . . . . . . . . . . . . . . . . . 21
- 9.3.3 Local security policy . . . . . . . . . . . . . . . . . . . 21
- 9.3.4 Public key authentication . . . . . . . . . . . . . . . . . 22
- 9.3.5 Password authentication . . . . . . . . . . . . . . . . . . 22
- 9.3.6 Host based authentication . . . . . . . . . . . . . . . . . 23
- 9.4 Connection protocol . . . . . . . . . . . . . . . . . . . . 23
- 9.4.1 End point security . . . . . . . . . . . . . . . . . . . . . 23
- 9.4.2 Proxy forwarding . . . . . . . . . . . . . . . . . . . . . . 23
- 9.4.3 X11 forwarding . . . . . . . . . . . . . . . . . . . . . . . 24
- Normative References . . . . . . . . . . . . . . . . . . . . 24
- Informative References . . . . . . . . . . . . . . . . . . . 25
- Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 27
- Intellectual Property and Copyright Statements . . . . . . . 28
-
-
-
-
-
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 2]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
-1. Contributors
-
- The major original contributors of this document were: Tatu Ylonen,
- Tero Kivinen, Timo J. Rinne, Sami Lehtinen (all of SSH Communications
- Security Corp), and Markku-Juhani O. Saarinen (University of
- Jyvaskyla)
-
- The document editor is: [email protected]. Comments on this
- internet draft should be sent to the IETF SECSH working group,
- details at: http://ietf.org/html.charters/secsh-charter.html
-
-2. Introduction
-
- SSH is a protocol for secure remote login and other secure network
- services over an insecure network. It consists of three major
- components:
- o The Transport Layer Protocol [SSH-TRANS] provides server
- authentication, confidentiality, and integrity. It may optionally
- also provide compression. The transport layer will typically be
- run over a TCP/IP connection, but might also be used on top of any
- other reliable data stream.
- o The User Authentication Protocol [SSH-USERAUTH] authenticates the
- client-side user to the server. It runs over the transport layer
- protocol.
- o The Connection Protocol [SSH-CONNECT] multiplexes the encrypted
- tunnel into several logical channels. It runs over the user
- authentication protocol.
-
- The client sends a service request once a secure transport layer
- connection has been established. A second service request is sent
- after user authentication is complete. This allows new protocols to
- be defined and coexist with the protocols listed above.
-
- The connection protocol provides channels that can be used for a wide
- range of purposes. Standard methods are provided for setting up
- secure interactive shell sessions and for forwarding ("tunneling")
- arbitrary TCP/IP ports and X11 connections.
-
-3. Specification of Requirements
-
- All documents related to the SSH protocols shall use the keywords
- "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",
- "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" to describe
- requirements. They are to be interpreted as described in [RFC2119].
-
-4. Architecture
-
-
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 3]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
-4.1 Host Keys
-
- Each server host SHOULD have a host key. Hosts MAY have multiple
- host keys using multiple different algorithms. Multiple hosts MAY
- share the same host key. If a host has keys at all, it MUST have at
- least one key using each REQUIRED public key algorithm (DSS
- [FIPS-186]).
-
- The server host key is used during key exchange to verify that the
- client is really talking to the correct server. For this to be
- possible, the client must have a priori knowledge of the server's
- public host key.
-
- Two different trust models can be used:
- o The client has a local database that associates each host name (as
- typed by the user) with the corresponding public host key. This
- method requires no centrally administered infrastructure, and no
- third-party coordination. The downside is that the database of
- name-to-key associations may become burdensome to maintain.
- o The host name-to-key association is certified by some trusted
- certification authority. The client only knows the CA root key,
- and can verify the validity of all host keys certified by accepted
- CAs.
-
- The second alternative eases the maintenance problem, since
- ideally only a single CA key needs to be securely stored on the
- client. On the other hand, each host key must be appropriately
- certified by a central authority before authorization is possible.
- Also, a lot of trust is placed on the central infrastructure.
-
- The protocol provides the option that the server name - host key
- association is not checked when connecting to the host for the first
- time. This allows communication without prior communication of host
- keys or certification. The connection still provides protection
- against passive listening; however, it becomes vulnerable to active
- man-in-the-middle attacks. Implementations SHOULD NOT normally allow
- such connections by default, as they pose a potential security
- problem. However, as there is no widely deployed key infrastructure
- available on the Internet yet, this option makes the protocol much
- more usable during the transition time until such an infrastructure
- emerges, while still providing a much higher level of security than
- that offered by older solutions (e.g. telnet [RFC-854] and rlogin
- [RFC-1282]).
-
- Implementations SHOULD try to make the best effort to check host
- keys. An example of a possible strategy is to only accept a host key
- without checking the first time a host is connected, save the key in
- a local database, and compare against that key on all future
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 4]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- connections to that host.
-
- Implementations MAY provide additional methods for verifying the
- correctness of host keys, e.g. a hexadecimal fingerprint derived from
- the SHA-1 hash of the public key. Such fingerprints can easily be
- verified by using telephone or other external communication channels.
-
- All implementations SHOULD provide an option to not accept host keys
- that cannot be verified.
-
- We believe that ease of use is critical to end-user acceptance of
- security solutions, and no improvement in security is gained if the
- new solutions are not used. Thus, providing the option not to check
- the server host key is believed to improve the overall security of
- the Internet, even though it reduces the security of the protocol in
- configurations where it is allowed.
-
-4.2 Extensibility
-
- We believe that the protocol will evolve over time, and some
- organizations will want to use their own encryption, authentication
- and/or key exchange methods. Central registration of all extensions
- is cumbersome, especially for experimental or classified features.
- On the other hand, having no central registration leads to conflicts
- in method identifiers, making interoperability difficult.
-
- We have chosen to identify algorithms, methods, formats, and
- extension protocols with textual names that are of a specific format.
- DNS names are used to create local namespaces where experimental or
- classified extensions can be defined without fear of conflicts with
- other implementations.
-
- One design goal has been to keep the base protocol as simple as
- possible, and to require as few algorithms as possible. However, all
- implementations MUST support a minimal set of algorithms to ensure
- interoperability (this does not imply that the local policy on all
- hosts would necessary allow these algorithms). The mandatory
- algorithms are specified in the relevant protocol documents.
-
- Additional algorithms, methods, formats, and extension protocols can
- be defined in separate drafts. See Section Algorithm Naming (Section
- 6) for more information.
-
-4.3 Policy Issues
-
- The protocol allows full negotiation of encryption, integrity, key
- exchange, compression, and public key algorithms and formats.
- Encryption, integrity, public key, and compression algorithms can be
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 5]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- different for each direction.
-
- The following policy issues SHOULD be addressed in the configuration
- mechanisms of each implementation:
- o Encryption, integrity, and compression algorithms, separately for
- each direction. The policy MUST specify which is the preferred
- algorithm (e.g. the first algorithm listed in each category).
- o Public key algorithms and key exchange method to be used for host
- authentication. The existence of trusted host keys for different
- public key algorithms also affects this choice.
- o The authentication methods that are to be required by the server
- for each user. The server's policy MAY require multiple
- authentication for some or all users. The required algorithms MAY
- depend on the location where the user is trying to log in from.
- o The operations that the user is allowed to perform using the
- connection protocol. Some issues are related to security; for
- example, the policy SHOULD NOT allow the server to start sessions
- or run commands on the client machine, and MUST NOT allow
- connections to the authentication agent unless forwarding such
- connections has been requested. Other issues, such as which TCP/
- IP ports can be forwarded and by whom, are clearly issues of local
- policy. Many of these issues may involve traversing or bypassing
- firewalls, and are interrelated with the local security policy.
-
-4.4 Security Properties
-
- The primary goal of the SSH protocol is improved security on the
- Internet. It attempts to do this in a way that is easy to deploy,
- even at the cost of absolute security.
- o All encryption, integrity, and public key algorithms used are
- well-known, well-established algorithms.
- o All algorithms are used with cryptographically sound key sizes
- that are believed to provide protection against even the strongest
- cryptanalytic attacks for decades.
- o All algorithms are negotiated, and in case some algorithm is
- broken, it is easy to switch to some other algorithm without
- modifying the base protocol.
-
- Specific concessions were made to make wide-spread fast deployment
- easier. The particular case where this comes up is verifying that
- the server host key really belongs to the desired host; the protocol
- allows the verification to be left out (but this is NOT RECOMMENDED).
- This is believed to significantly improve usability in the short
- term, until widespread Internet public key infrastructures emerge.
-
-4.5 Packet Size and Overhead
-
- Some readers will worry about the increase in packet size due to new
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 6]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- headers, padding, and MAC. The minimum packet size is in the order
- of 28 bytes (depending on negotiated algorithms). The increase is
- negligible for large packets, but very significant for one-byte
- packets (telnet-type sessions). There are, however, several factors
- that make this a non-issue in almost all cases:
- o The minimum size of a TCP/IP header is 32 bytes. Thus, the
- increase is actually from 33 to 51 bytes (roughly).
- o The minimum size of the data field of an Ethernet packet is 46
- bytes [RFC-894]. Thus, the increase is no more than 5 bytes. When
- Ethernet headers are considered, the increase is less than 10
- percent.
- o The total fraction of telnet-type data in the Internet is
- negligible, even with increased packet sizes.
-
- The only environment where the packet size increase is likely to have
- a significant effect is PPP [RFC-1134] over slow modem lines (PPP
- compresses the TCP/IP headers, emphasizing the increase in packet
- size). However, with modern modems, the time needed to transfer is in
- the order of 2 milliseconds, which is a lot faster than people can
- type.
-
- There are also issues related to the maximum packet size. To
- minimize delays in screen updates, one does not want excessively
- large packets for interactive sessions. The maximum packet size is
- negotiated separately for each channel.
-
-4.6 Localization and Character Set Support
-
- For the most part, the SSH protocols do not directly pass text that
- would be displayed to the user. However, there are some places where
- such data might be passed. When applicable, the character set for the
- data MUST be explicitly specified. In most places, ISO 10646 with
- UTF-8 encoding is used [RFC-2279]. When applicable, a field is also
- provided for a language tag [RFC-3066].
-
- One big issue is the character set of the interactive session. There
- is no clear solution, as different applications may display data in
- different formats. Different types of terminal emulation may also be
- employed in the client, and the character set to be used is
- effectively determined by the terminal emulation. Thus, no place is
- provided for directly specifying the character set or encoding for
- terminal session data. However, the terminal emulation type (e.g.
- "vt100") is transmitted to the remote site, and it implicitly
- specifies the character set and encoding. Applications typically use
- the terminal type to determine what character set they use, or the
- character set is determined using some external means. The terminal
- emulation may also allow configuring the default character set. In
- any case, the character set for the terminal session is considered
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 7]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- primarily a client local issue.
-
- Internal names used to identify algorithms or protocols are normally
- never displayed to users, and must be in US-ASCII.
-
- The client and server user names are inherently constrained by what
- the server is prepared to accept. They might, however, occasionally
- be displayed in logs, reports, etc. They MUST be encoded using ISO
- 10646 UTF-8, but other encodings may be required in some cases. It
- is up to the server to decide how to map user names to accepted user
- names. Straight bit-wise binary comparison is RECOMMENDED.
-
- For localization purposes, the protocol attempts to minimize the
- number of textual messages transmitted. When present, such messages
- typically relate to errors, debugging information, or some externally
- configured data. For data that is normally displayed, it SHOULD be
- possible to fetch a localized message instead of the transmitted
- message by using a numerical code. The remaining messages SHOULD be
- configurable.
-
-5. Data Type Representations Used in the SSH Protocols
- byte
-
- A byte represents an arbitrary 8-bit value (octet) [RFC-1700].
- Fixed length data is sometimes represented as an array of bytes,
- written byte[n], where n is the number of bytes in the array.
-
- boolean
-
- A boolean value is stored as a single byte. The value 0
- represents FALSE, and the value 1 represents TRUE. All non-zero
- values MUST be interpreted as TRUE; however, applications MUST NOT
- store values other than 0 and 1.
-
- uint32
-
- Represents a 32-bit unsigned integer. Stored as four bytes in the
- order of decreasing significance (network byte order). For
- example, the value 699921578 (0x29b7f4aa) is stored as 29 b7 f4
- aa.
-
- uint64
-
- Represents a 64-bit unsigned integer. Stored as eight bytes in
- the order of decreasing significance (network byte order).
-
-
-
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 8]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- string
-
- Arbitrary length binary string. Strings are allowed to contain
- arbitrary binary data, including null characters and 8-bit
- characters. They are stored as a uint32 containing its length
- (number of bytes that follow) and zero (= empty string) or more
- bytes that are the value of the string. Terminating null
- characters are not used.
-
- Strings are also used to store text. In that case, US-ASCII is
- used for internal names, and ISO-10646 UTF-8 for text that might
- be displayed to the user. The terminating null character SHOULD
- NOT normally be stored in the string.
-
- For example, the US-ASCII string "testing" is represented as 00 00
- 00 07 t e s t i n g. The UTF8 mapping does not alter the encoding
- of US-ASCII characters.
-
- mpint
-
- Represents multiple precision integers in two's complement format,
- stored as a string, 8 bits per byte, MSB first. Negative numbers
- have the value 1 as the most significant bit of the first byte of
- the data partition. If the most significant bit would be set for a
- positive number, the number MUST be preceded by a zero byte.
- Unnecessary leading bytes with the value 0 or 255 MUST NOT be
- included. The value zero MUST be stored as a string with zero
- bytes of data.
-
- By convention, a number that is used in modular computations in
- Z_n SHOULD be represented in the range 0 <= x < n.
-
- Examples:
- value (hex) representation (hex)
- ---------------------------------------------------------------
- 0 00 00 00 00
- 9a378f9b2e332a7 00 00 00 08 09 a3 78 f9 b2 e3 32 a7
- 80 00 00 00 02 00 80
- -1234 00 00 00 02 ed cc
- -deadbeef 00 00 00 05 ff 21 52 41 11
-
-
-
- name-list
-
- A string containing a comma separated list of names. A name list
- is represented as a uint32 containing its length (number of bytes
- that follow) followed by a comma-separated list of zero or more
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 9]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- names. A name MUST be non-zero length, and it MUST NOT contain a
- comma (','). Context may impose additional restrictions on the
- names; for example, the names in a list may have to be valid
- algorithm identifier (see Algorithm Naming below), or [RFC-3066]
- language tags. The order of the names in a list may or may not be
- significant, also depending on the context where the list is is
- used. Terminating NUL characters are not used, neither for the
- individual names, nor for the list as a whole.
-
- Examples:
- value representation (hex)
- ---------------------------------------
- (), the empty list 00 00 00 00
- ("zlib") 00 00 00 04 7a 6c 69 62
- ("zlib", "none") 00 00 00 09 7a 6c 69 62 2c 6e 6f 6e 65
-
-
-
-
-6. Algorithm Naming
-
- The SSH protocols refer to particular hash, encryption, integrity,
- compression, and key exchange algorithms or protocols by names.
- There are some standard algorithms that all implementations MUST
- support. There are also algorithms that are defined in the protocol
- specification but are OPTIONAL. Furthermore, it is expected that
- some organizations will want to use their own algorithms.
-
- In this protocol, all algorithm identifiers MUST be printable
- US-ASCII non-empty strings no longer than 64 characters. Names MUST
- be case-sensitive.
-
- There are two formats for algorithm names:
- o Names that do not contain an at-sign (@) are reserved to be
- assigned by IETF consensus (RFCs). Examples include `3des-cbc',
- `sha-1', `hmac-sha1', and `zlib' (the quotes are not part of the
- name). Names of this format MUST NOT be used without first
- registering them. Registered names MUST NOT contain an at-sign
- (@) or a comma (,).
- o Anyone can define additional algorithms by using names in the
- format name@domainname, e.g. "[email protected]". The
- format of the part preceding the at sign is not specified; it MUST
- consist of US-ASCII characters except at-sign and comma. The part
- following the at-sign MUST be a valid fully qualified internet
- domain name [RFC-1034] controlled by the person or organization
- defining the name. It is up to each domain how it manages its
- local namespace.
-
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 10]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
-7. Message Numbers
-
- SSH packets have message numbers in the range 1 to 255. These numbers
- have been allocated as follows:
-
-
- Transport layer protocol:
-
- 1 to 19 Transport layer generic (e.g. disconnect, ignore, debug,
- etc.)
- 20 to 29 Algorithm negotiation
- 30 to 49 Key exchange method specific (numbers can be reused for
- different authentication methods)
-
- User authentication protocol:
-
- 50 to 59 User authentication generic
- 60 to 79 User authentication method specific (numbers can be
- reused for different authentication methods)
-
- Connection protocol:
-
- 80 to 89 Connection protocol generic
- 90 to 127 Channel related messages
-
- Reserved for client protocols:
-
- 128 to 191 Reserved
-
- Local extensions:
-
- 192 to 255 Local extensions
-
-
-
-8. IANA Considerations
-
- The initial state of the IANA registry is detailed in [SSH-NUMBERS].
-
- Allocation of the following types of names in the SSH protocols is
- assigned by IETF consensus:
- o SSH encryption algorithm names,
- o SSH MAC algorithm names,
- o SSH public key algorithm names (public key algorithm also implies
- encoding and signature/encryption capability),
- o SSH key exchange method names, and
- o SSH protocol (service) names.
-
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 11]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- These names MUST be printable US-ASCII strings, and MUST NOT contain
- the characters at-sign ('@'), comma (','), or whitespace or control
- characters (ASCII codes 32 or less). Names are case-sensitive, and
- MUST NOT be longer than 64 characters.
-
- Names with the at-sign ('@') in them are allocated by the owner of
- DNS name after the at-sign (hierarchical allocation in [RFC-2343]),
- otherwise the same restrictions as above.
-
- Each category of names listed above has a separate namespace.
- However, using the same name in multiple categories SHOULD be avoided
- to minimize confusion.
-
- Message numbers (see Section Message Numbers (Section 7)) in the
- range of 0..191 are allocated via IETF consensus; message numbers in
- the 192..255 range (the "Local extensions" set) are reserved for
- private use.
-
-9. Security Considerations
-
- In order to make the entire body of Security Considerations more
- accessible, Security Considerations for the transport,
- authentication, and connection documents have been gathered here.
-
- The transport protocol [1] provides a confidential channel over an
- insecure network. It performs server host authentication, key
- exchange, encryption, and integrity protection. It also derives a
- unique session id that may be used by higher-level protocols.
-
- The authentication protocol [2] provides a suite of mechanisms which
- can be used to authenticate the client user to the server.
- Individual mechanisms specified in the in authentication protocol use
- the session id provided by the transport protocol and/or depend on
- the security and integrity guarantees of the transport protocol.
-
- The connection protocol [3] specifies a mechanism to multiplex
- multiple streams [channels] of data over the confidential and
- authenticated transport. It also specifies channels for accessing an
- interactive shell, for 'proxy-forwarding' various external protocols
- over the secure transport (including arbitrary TCP/IP protocols), and
- for accessing secure 'subsystems' on the server host.
-
-9.1 Pseudo-Random Number Generation
-
- This protocol binds each session key to the session by including
- random, session specific data in the hash used to produce session
- keys. Special care should be taken to ensure that all of the random
- numbers are of good quality. If the random data here (e.g., DH
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 12]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- parameters) are pseudo-random then the pseudo-random number generator
- should be cryptographically secure (i.e., its next output not easily
- guessed even when knowing all previous outputs) and, furthermore,
- proper entropy needs to be added to the pseudo-random number
- generator. RFC 1750 [1750] offers suggestions for sources of random
- numbers and entropy. Implementors should note the importance of
- entropy and the well-meant, anecdotal warning about the difficulty in
- properly implementing pseudo-random number generating functions.
-
- The amount of entropy available to a given client or server may
- sometimes be less than what is required. In this case one must
- either resort to pseudo-random number generation regardless of
- insufficient entropy or refuse to run the protocol. The latter is
- preferable.
-
-9.2 Transport
-
-9.2.1 Confidentiality
-
- It is beyond the scope of this document and the Secure Shell Working
- Group to analyze or recommend specific ciphers other than the ones
- which have been established and accepted within the industry. At the
- time of this writing, ciphers commonly in use include 3DES, ARCFOUR,
- twofish, serpent and blowfish. AES has been accepted by The
- published as a US Federal Information Processing Standards [FIPS-197]
- and the cryptographic community as being acceptable for this purpose
- as well has accepted AES. As always, implementors and users should
- check current literature to ensure that no recent vulnerabilities
- have been found in ciphers used within products. Implementors should
- also check to see which ciphers are considered to be relatively
- stronger than others and should recommend their use to users over
- relatively weaker ciphers. It would be considered good form for an
- implementation to politely and unobtrusively notify a user that a
- stronger cipher is available and should be used when a weaker one is
- actively chosen.
-
- The "none" cipher is provided for debugging and SHOULD NOT be used
- except for that purpose. It's cryptographic properties are
- sufficiently described in RFC 2410, which will show that its use does
- not meet the intent of this protocol.
-
- The relative merits of these and other ciphers may also be found in
- current literature. Two references that may provide information on
- the subject are [SCHNEIER] and [KAUFMAN,PERLMAN,SPECINER]. Both of
- these describe the CBC mode of operation of certain ciphers and the
- weakness of this scheme. Essentially, this mode is theoretically
- vulnerable to chosen cipher-text attacks because of the high
- predictability of the start of packet sequence. However, this attack
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 13]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- is still deemed difficult and not considered fully practicable
- especially if relatively longer block sizes are used.
-
- Additionally, another CBC mode attack may be mitigated through the
- insertion of packets containing SSH_MSG_IGNORE. Without this
- technique, a specific attack may be successful. For this attack
- (commonly known as the Rogaway attack
- [ROGAWAY],[DAI],[BELLARE,KOHNO,NAMPREMPRE]) to work, the attacker
- would need to know the IV of the next block that is going to be
- encrypted. In CBC mode that is the output of the encryption of the
- previous block. If the attacker does not have any way to see the
- packet yet (i.e it is in the internal buffers of the ssh
- implementation or even in the kernel) then this attack will not work.
- If the last packet has been sent out to the network (i.e the attacker
- has access to it) then he can use the attack.
-
- In the optimal case an implementor would need to add an extra packet
- only if the packet has been sent out onto the network and there are
- no other packets waiting for transmission. Implementors may wish to
- check to see if there are any unsent packets awaiting transmission,
- but unfortunately it is not normally easy to obtain this information
- from the kernel or buffers. If there are not, then a packet
- containing SSH_MSG_IGNORE SHOULD be sent. If a new packet is added
- to the stream every time the attacker knows the IV that is supposed
- to be used for the next packet, then the attacker will not be able to
- guess the correct IV, thus the attack will never be successfull.
-
- As an example, consider the following case:
-
-
- Client Server
- ------ ------
- TCP(seq=x, len=500) ->
- contains Record 1
-
- [500 ms passes, no ACK]
-
- TCP(seq=x, len=1000) ->
- contains Records 1,2
-
- ACK
-
-
- 1. The Nagle algorithm + TCP retransmits mean that the two records
- get coalesced into a single TCP segment
- 2. Record 2 is *not* at the beginning of the TCP segment and never
- will be, since it gets ACKed.
-
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 14]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- 3. Yet, the attack is possible because Record 1 has already been
- seen.
-
- As this example indicates, it's totally unsafe to use the existence
- of unflushed data in the TCP buffers proper as a guide to whether you
- need an empty packet, since when you do the second write(), the
- buffers will contain the un-ACKed Record 1.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 15]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- On the other hand, it's perfectly safe to have the following
- situation:
-
-
- Client Server
- ------ ------
- TCP(seq=x, len=500) ->
- contains SSH_MSG_IGNORE
-
- TCP(seq=y, len=500) ->
- contains Data
-
- Provided that the IV for second SSH Record is fixed after the data for
- the Data packet is determined -i.e. you do:
- read from user
- encrypt null packet
- encrypt data packet
-
-
-9.2.2 Data Integrity
-
- This protocol does allow the Data Integrity mechanism to be disabled.
- Implementors SHOULD be wary of exposing this feature for any purpose
- other than debugging. Users and administrators SHOULD be explicitly
- warned anytime the "none" MAC is enabled.
-
- So long as the "none" MAC is not used, this protocol provides data
- integrity.
-
- Because MACs use a 32 bit sequence number, they might start to leak
- information after 2**32 packets have been sent. However, following
- the rekeying recommendations should prevent this attack. The
- transport protocol [1] recommends rekeying after one gigabyte of
- data, and the smallest possible packet is 16 bytes. Therefore,
- rekeying SHOULD happen after 2**28 packets at the very most.
-
-9.2.3 Replay
-
- The use of a MAC other than 'none' provides integrity and
- authentication. In addition, the transport protocol provides a
- unique session identifier (bound in part to pseudo-random data that
- is part of the algorithm and key exchange process) that can be used
- by higher level protocols to bind data to a given session and prevent
- replay of data from prior sessions. For example, the authentication
- protocol uses this to prevent replay of signatures from previous
- sessions. Because public key authentication exchanges are
- cryptographically bound to the session (i.e., to the initial key
- exchange) they cannot be successfully replayed in other sessions.
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 16]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- Note that the session ID can be made public without harming the
- security of the protocol.
-
- If two session happen to have the same session ID [hash of key
- exchanges] then packets from one can be replayed against the other.
- It must be stressed that the chances of such an occurrence are,
- needless to say, minimal when using modern cryptographic methods.
- This is all the more so true when specifying larger hash function
- outputs and DH parameters.
-
- Replay detection using monotonically increasing sequence numbers as
- input to the MAC, or HMAC in some cases, is described in [RFC2085] />
- [RFC2246], [RFC2743], [RFC1964], [RFC2025], and [RFC1510]. The
- underlying construct is discussed in [RFC2104]. Essentially a
- different sequence number in each packet ensures that at least this
- one input to the MAC function will be unique and will provide a
- nonrecurring MAC output that is not predictable to an attacker. If
- the session stays active long enough, however, this sequence number
- will wrap. This event may provide an attacker an opportunity to
- replay a previously recorded packet with an identical sequence number
- but only if the peers have not rekeyed since the transmission of the
- first packet with that sequence number. If the peers have rekeyed,
- then the replay will be detected as the MAC check will fail. For
- this reason, it must be emphasized that peers MUST rekey before a
- wrap of the sequence numbers. Naturally, if an attacker does attempt
- to replay a captured packet before the peers have rekeyed, then the
- receiver of the duplicate packet will not be able to validate the MAC
- and it will be discarded. The reason that the MAC will fail is
- because the receiver will formulate a MAC based upon the packet
- contents, the shared secret, and the expected sequence number. Since
- the replayed packet will not be using that expected sequence number
- (the sequence number of the replayed packet will have already been
- passed by the receiver) then the calculated MAC will not match the
- MAC received with the packet.
-
-9.2.4 Man-in-the-middle
-
- This protocol makes no assumptions nor provisions for an
- infrastructure or means for distributing the public keys of hosts. It
- is expected that this protocol will sometimes be used without first
- verifying the association between the server host key and the server
- host name. Such usage is vulnerable to man-in-the-middle attacks.
- This section describes this and encourages administrators and users
- to understand the importance of verifying this association before any
- session is initiated.
-
- There are three cases of man-in-the-middle attacks to consider. The
- first is where an attacker places a device between the client and the
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 17]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- server before the session is initiated. In this case, the attack
- device is trying to mimic the legitimate server and will offer its
- public key to the client when the client initiates a session. If it
- were to offer the public key of the server, then it would not be able
- to decrypt or sign the transmissions between the legitimate server
- and the client unless it also had access to the private-key of the
- host. The attack device will also, simultaneously to this, initiate
- a session to the legitimate server masquerading itself as the client.
- If the public key of the server had been securely distributed to the
- client prior to that session initiation, the key offered to the
- client by the attack device will not match the key stored on the
- client. In that case, the user SHOULD be given a warning that the
- offered host key does not match the host key cached on the client.
- As described in Section 3.1 of [ARCH], the user may be free to accept
- the new key and continue the session. It is RECOMMENDED that the
- warning provide sufficient information to the user of the client
- device so they may make an informed decision. If the user chooses to
- continue the session with the stored public-key of the server (not
- the public-key offered at the start of the session), then the session
- specific data between the attacker and server will be different
- between the client-to-attacker session and the attacker-to-server
- sessions due to the randomness discussed above. From this, the
- attacker will not be able to make this attack work since the attacker
- will not be able to correctly sign packets containing this session
- specific data from the server since he does not have the private key
- of that server.
-
- The second case that should be considered is similar to the first
- case in that it also happens at the time of connection but this case
- points out the need for the secure distribution of server public
- keys. If the server public keys are not securely distributed then
- the client cannot know if it is talking to the intended server. An
- attacker may use social engineering techniques to pass off server
- keys to unsuspecting users and may then place a man-in-the-middle
- attack device between the legitimate server and the clients. If this
- is allowed to happen then the clients will form client-to-attacker
- sessions and the attacker will form attacker-to-server sessions and
- will be able to monitor and manipulate all of the traffic between the
- clients and the legitimate servers. Server administrators are
- encouraged to make host key fingerprints available for checking by
- some means whose security does not rely on the integrity of the
- actual host keys. Possible mechanisms are discussed in Section 3.1
- of [SSH-ARCH] and may also include secured Web pages, physical pieces
- of paper, etc. Implementors SHOULD provide recommendations on how
- best to do this with their implementation. Because the protocol is
- extensible, future extensions to the protocol may provide better
- mechanisms for dealing with the need to know the server's host key
- before connecting. For example, making the host key fingerprint
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 18]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- available through a secure DNS lookup, or using kerberos over gssapi
- during key exchange to authenticate the server are possibilities.
-
- In the third man-in-the-middle case, attackers may attempt to
- manipulate packets in transit between peers after the session has
- been established. As described in the Replay part of this section, a
- successful attack of this nature is very improbable. As in the
- Replay section, this reasoning does assume that the MAC is secure and
- that it is infeasible to construct inputs to a MAC algorithm to give
- a known output. This is discussed in much greater detail in Section
- 6 of RFC 2104. If the MAC algorithm has a vulnerability or is weak
- enough, then the attacker may be able to specify certain inputs to
- yield a known MAC. With that they may be able to alter the contents
- of a packet in transit. Alternatively the attacker may be able to
- exploit the algorithm vulnerability or weakness to find the shared
- secret by reviewing the MACs from captured packets. In either of
- those cases, an attacker could construct a packet or packets that
- could be inserted into an SSH stream. To prevent that, implementors
- are encouraged to utilize commonly accepted MAC algorithms and
- administrators are encouraged to watch current literature and
- discussions of cryptography to ensure that they are not using a MAC
- algorithm that has a recently found vulnerability or weakness.
-
- In summary, the use of this protocol without a reliable association
- of the binding between a host and its host keys is inherently
- insecure and is NOT RECOMMENDED. It may however be necessary in
- non-security critical environments, and will still provide protection
- against passive attacks. Implementors of protocols and applications
- running on top of this protocol should keep this possibility in mind.
-
-9.2.5 Denial-of-service
-
- This protocol is designed to be used over a reliable transport. If
- transmission errors or message manipulation occur, the connection is
- closed. The connection SHOULD be re-established if this occurs.
- Denial of service attacks of this type ("wire cutter") are almost
- impossible to avoid.
-
- In addition, this protocol is vulnerable to Denial of Service attacks
- because an attacker can force the server to go through the CPU and
- memory intensive tasks of connection setup and key exchange without
- authenticating. Implementors SHOULD provide features that make this
- more difficult. For example, only allowing connections from a subset
- of IPs known to have valid users.
-
-9.2.6 Covert Channels
-
- The protocol was not designed to eliminate covert channels. For
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 19]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- example, the padding, SSH_MSG_IGNORE messages, and several other
- places in the protocol can be used to pass covert information, and
- the recipient has no reliable way to verify whether such information
- is being sent.
-
-9.2.7 Forward Secrecy
-
- It should be noted that the Diffie-Hellman key exchanges may provide
- perfect forward secrecy (PFS). PFS is essentially defined as the
- cryptographic property of a key-establishment protocol in which the
- compromise of a session key or long-term private key after a given
- session does not cause the compromise of any earlier session. [ANSI
- T1.523-2001] SSHv2 sessions resulting from a key exchange using
- diffie-hellman-group1-sha1 are secure even if private keying/
- authentication material is later revealed, but not if the session
- keys are revealed. So, given this definition of PFS, SSHv2 does have
- PFS. It is hoped that all other key exchange mechanisms proposed and
- used in the future will also provide PFS. This property is not
- commuted to any of the applications or protocols using SSH as a
- transport however. The transport layer of SSH provides
- confidentiality for password authentication and other methods that
- rely on secret data.
-
- Of course, if the DH private parameters for the client and server are
- revealed then the session key is revealed, but these items can be
- thrown away after the key exchange completes. It's worth pointing
- out that these items should not be allowed to end up on swap space
- and that they should be erased from memory as soon as the key
- exchange completes.
-
-9.3 Authentication Protocol
-
- The purpose of this protocol is to perform client user
- authentication. It assumes that this run over a secure transport
- layer protocol, which has already authenticated the server machine,
- established an encrypted communications channel, and computed a
- unique session identifier for this session.
-
- Several authentication methods with different security
- characteristics are allowed. It is up to the server's local policy
- to decide which methods (or combinations of methods) it is willing to
- accept for each user. Authentication is no stronger than the weakest
- combination allowed.
-
- The server may go into a "sleep" period after repeated unsuccessful
- authentication attempts to make key search more difficult for
- attackers. Care should be taken so that this doesn't become a
- self-denial of service vector.
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 20]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
-9.3.1 Weak Transport
-
- If the transport layer does not provide confidentiality,
- authentication methods that rely on secret data SHOULD be disabled.
- If it does not provide strong integrity protection, requests to
- change authentication data (e.g. a password change) SHOULD be
- disabled to prevent an attacker from modifying the ciphertext
- without being noticed, or rendering the new authentication data
- unusable (denial of service).
-
- The assumption as stated above that the Authentication Protocol only
- run over a secure transport that has previously authenticated the
- server is very important to note. People deploying SSH are reminded
- of the consequences of man-in-the-middle attacks if the client does
- not have a very strong a priori association of the server with the
- host key of that server. Specifically for the case of the
- Authentication Protocol the client may form a session to a
- man-in-the-middle attack device and divulge user credentials such as
- their username and password. Even in the cases of authentication
- where no user credentials are divulged, an attacker may still gain
- information they shouldn't have by capturing key-strokes in much the
- same way that a honeypot works.
-
-9.3.2 Debug messages
-
- Special care should be taken when designing debug messages. These
- messages may reveal surprising amounts of information about the host
- if not properly designed. Debug messages can be disabled (during
- user authentication phase) if high security is required.
- Administrators of host machines should make all attempts to
- compartmentalize all event notification messages and protect them
- from unwarranted observation. Developers should be aware of the
- sensitive nature of some of the normal event messages and debug
- messages and may want to provide guidance to administrators on ways
- to keep this information away from unauthorized people. Developers
- should consider minimizing the amount of sensitive information
- obtainable by users during the authentication phase in accordance
- with the local policies. For this reason, it is RECOMMENDED that
- debug messages be initially disabled at the time of deployment and
- require an active decision by an administrator to allow them to be
- enabled. It is also RECOMMENDED that a message expressing this
- concern be presented to the administrator of a system when the action
- is taken to enable debugging messages.
-
-9.3.3 Local security policy
-
- Implementer MUST ensure that the credentials provided validate the
- professed user and also MUST ensure that the local policy of the
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 21]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- server permits the user the access requested. In particular, because
- of the flexible nature of the SSH connection protocol, it may not be
- possible to determine the local security policy, if any, that should
- apply at the time of authentication because the kind of service being
- requested is not clear at that instant. For example, local policy
- might allow a user to access files on the server, but not start an
- interactive shell. However, during the authentication protocol, it is
- not known whether the user will be accessing files or attempting to
- use an interactive shell, or even both. In any event, where local
- security policy for the server host exists, it MUST be applied and
- enforced correctly.
-
- Implementors are encouraged to provide a default local policy and
- make its parameters known to administrators and users. At the
- discretion of the implementors, this default policy may be along the
- lines of 'anything goes' where there are no restrictions placed upon
- users, or it may be along the lines of 'excessively restrictive' in
- which case the administrators will have to actively make changes to
- this policy to meet their needs. Alternatively, it may be some
- attempt at providing something practical and immediately useful to
- the administrators of the system so they don't have to put in much
- effort to get SSH working. Whatever choice is made MUST be applied
- and enforced as required above.
-
-9.3.4 Public key authentication
-
- The use of public-key authentication assumes that the client host has
- not been compromised. It also assumes that the private-key of the
- server host has not been compromised.
-
- This risk can be mitigated by the use of passphrases on private keys;
- however, this is not an enforceable policy. The use of smartcards,
- or other technology to make passphrases an enforceable policy is
- suggested.
-
- The server could require both password and public-key authentication,
- however, this requires the client to expose its password to the
- server (see section on password authentication below.)
-
-9.3.5 Password authentication
-
- The password mechanism as specified in the authentication protocol
- assumes that the server has not been compromised. If the server has
- been compromised, using password authentication will reveal a valid
- username / password combination to the attacker, which may lead to
- further compromises.
-
- This vulnerability can be mitigated by using an alternative form of
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 22]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- authentication. For example, public-key authentication makes no
- assumptions about security on the server.
-
-9.3.6 Host based authentication
-
- Host based authentication assumes that the client has not been
- compromised. There are no mitigating strategies, other than to use
- host based authentication in combination with another authentication
- method.
-
-9.4 Connection protocol
-
-9.4.1 End point security
-
- End point security is assumed by the connection protocol. If the
- server has been compromised, any terminal sessions, port forwarding,
- or systems accessed on the host are compromised. There are no
- mitigating factors for this.
-
- If the client end point has been compromised, and the server fails to
- stop the attacker at the authentication protocol, all services
- exposed (either as subsystems or through forwarding) will be
- vulnerable to attack. Implementors SHOULD provide mechanisms for
- administrators to control which services are exposed to limit the
- vulnerability of other services.
-
- These controls might include controlling which machines and ports can
- be target in 'port-forwarding' operations, which users are allowed to
- use interactive shell facilities, or which users are allowed to use
- exposed subsystems.
-
-9.4.2 Proxy forwarding
-
- The SSH connection protocol allows for proxy forwarding of other
- protocols such as SNMP, POP3, and HTTP. This may be a concern for
- network administrators who wish to control the access of certain
- applications by users located outside of their physical location.
- Essentially, the forwarding of these protocols may violate site
- specific security policies as they may be undetectably tunneled
- through a firewall. Implementors SHOULD provide an administrative
- mechanism to control the proxy forwarding functionality so that site
- specific security policies may be upheld.
-
- In addition, a reverse proxy forwarding functionality is available,
- which again can be used to bypass firewall controls.
-
- As indicated above, end-point security is assumed during proxy
- forwarding operations. Failure of end-point security will compromise
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 23]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- all data passed over proxy forwarding.
-
-9.4.3 X11 forwarding
-
- Another form of proxy forwarding provided by the ssh connection
- protocol is the forwarding of the X11 protocol. If end-point
- security has been compromised, X11 forwarding may allow attacks
- against the X11 server. Users and administrators should, as a matter
- of course, use appropriate X11 security mechanisms to prevent
- unauthorized use of the X11 server. Implementors, administrators and
- users who wish to further explore the security mechanisms of X11 are
- invited to read [SCHEIFLER] and analyze previously reported problems
- with the interactions between SSH forwarding and X11 in CERT
- vulnerabilities VU#363181 and VU#118892 [CERT].
-
- X11 display forwarding with SSH, by itself, is not sufficient to
- correct well known problems with X11 security [VENEMA]. However, X11
- display forwarding in SSHv2 (or other, secure protocols), combined
- with actual and pseudo-displays which accept connections only over
- local IPC mechanisms authorized by permissions or ACLs, does correct
- many X11 security problems as long as the "none" MAC is not used. It
- is RECOMMENDED that X11 display implementations default to allowing
- display opens only over local IPC. It is RECOMMENDED that SSHv2
- server implementations that support X11 forwarding default to
- allowing display opens only over local IPC. On single-user systems
- it might be reasonable to default to allowing local display opens
- over TCP/IP.
-
- Implementors of the X11 forwarding protocol SHOULD implement the
- magic cookie access checking spoofing mechanism as described in
- [ssh-connect] as an additional mechanism to prevent unauthorized use
- of the proxy.
-
-Normative References
-
- [SSH-ARCH]
- Ylonen, T., "SSH Protocol Architecture", I-D
- draft-ietf-architecture-15.txt, Oct 2003.
-
- [SSH-TRANS]
- Ylonen, T., "SSH Transport Layer Protocol", I-D
- draft-ietf-transport-17.txt, Oct 2003.
-
- [SSH-USERAUTH]
- Ylonen, T., "SSH Authentication Protocol", I-D
- draft-ietf-userauth-18.txt, Oct 2003.
-
- [SSH-CONNECT]
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 24]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- Ylonen, T., "SSH Connection Protocol", I-D
- draft-ietf-connect-18.txt, Oct 2003.
-
- [SSH-NUMBERS]
- Lehtinen, S. and D. Moffat, "SSH Protocol Assigned
- Numbers", I-D draft-ietf-secsh-assignednumbers-05.txt, Oct
- 2003.
-
- [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
- Requirement Levels", BCP 14, RFC 2119, March 1997.
-
-Informative References
-
- [FIPS-186]
- Federal Information Processing Standards Publication,
- "FIPS PUB 186, Digital Signature Standard", May 1994.
-
- [FIPS-197]
- National Institue of Standards and Technology, "FIPS 197,
- Specification for the Advanced Encryption Standard",
- November 2001.
-
- [ANSI T1.523-2001]
- American National Standards Insitute, Inc., "Telecom
- Glossary 2000", February 2001.
-
- [SCHEIFLER]
- Scheifler, R., "X Window System : The Complete Reference
- to Xlib, X Protocol, Icccm, Xlfd, 3rd edition.", Digital
- Press ISBN 1555580882, Feburary 1992.
-
- [RFC0854] Postel, J. and J. Reynolds, "Telnet Protocol
- Specification", STD 8, RFC 854, May 1983.
-
- [RFC0894] Hornig, C., "Standard for the transmission of IP datagrams
- over Ethernet networks", STD 41, RFC 894, April 1984.
-
- [RFC1034] Mockapetris, P., "Domain names - concepts and facilities",
- STD 13, RFC 1034, November 1987.
-
- [RFC1134] Perkins, D., "Point-to-Point Protocol: A proposal for
- multi-protocol transmission of datagrams over
- Point-to-Point links", RFC 1134, November 1989.
-
- [RFC1282] Kantor, B., "BSD Rlogin", RFC 1282, December 1991.
-
- [RFC1510] Kohl, J. and B. Neuman, "The Kerberos Network
- Authentication Service (V5)", RFC 1510, September 1993.
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 25]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- [RFC1700] Reynolds, J. and J. Postel, "Assigned Numbers", RFC 1700,
- October 1994.
-
- [RFC1750] Eastlake, D., Crocker, S. and J. Schiller, "Randomness
- Recommendations for Security", RFC 1750, December 1994.
-
- [RFC3066] Alvestrand, H., "Tags for the Identification of
- Languages", BCP 47, RFC 3066, January 2001.
-
- [RFC1964] Linn, J., "The Kerberos Version 5 GSS-API Mechanism", RFC
- 1964, June 1996.
-
- [RFC2025] Adams, C., "The Simple Public-Key GSS-API Mechanism
- (SPKM)", RFC 2025, October 1996.
-
- [RFC2085] Oehler, M. and R. Glenn, "HMAC-MD5 IP Authentication with
- Replay Prevention", RFC 2085, February 1997.
-
- [RFC2104] Krawczyk, H., Bellare, M. and R. Canetti, "HMAC:
- Keyed-Hashing for Message Authentication", RFC 2104,
- February 1997.
-
- [RFC2246] Dierks, T., Allen, C., Treese, W., Karlton, P., Freier, A.
- and P. Kocher, "The TLS Protocol Version 1.0", RFC 2246,
- January 1999.
-
- [RFC2279] Yergeau, F., "UTF-8, a transformation format of ISO
- 10646", RFC 2279, January 1998.
-
- [RFC2410] Glenn, R. and S. Kent, "The NULL Encryption Algorithm and
- Its Use With IPsec", RFC 2410, November 1998.
-
- [RFC2434] Narten, T. and H. Alvestrand, "Guidelines for Writing an
- IANA Considerations Section in RFCs", BCP 26, RFC 2434,
- October 1998.
-
- [RFC2743] Linn, J., "Generic Security Service Application Program
- Interface Version 2, Update 1", RFC 2743, January 2000.
-
- [SCHNEIER]
- Schneier, B., "Applied Cryptography Second Edition:
- protocols algorithms and source in code in C", 1996.
-
- [KAUFMAN,PERLMAN,SPECINER]
- Kaufman, C., Perlman, R. and M. Speciner, "Network
- Security: PRIVATE Communication in a PUBLIC World", 1995.
-
- [CERT] CERT Coordination Center, The., "http://www.cert.org/nav/
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 26]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- index_red.html".
-
- [VENEMA] Venema, W., "Murphy's Law and Computer Security",
- Proceedings of 6th USENIX Security Symposium, San Jose CA
- http://www.usenix.org/publications/library/proceedings/
- sec96/venema.html, July 1996.
-
- [ROGAWAY] Rogaway, P., "Problems with Proposed IP Cryptography",
- Unpublished paper http://www.cs.ucdavis.edu/~rogaway/
- papers/draft-rogaway-ipsec-comments-00.txt, 1996.
-
- [DAI] Dai, W., "An attack against SSH2 protocol", Email to the
- SECSH Working Group [email protected] ftp://
- ftp.ietf.org/ietf-mail-archive/secsh/2002-02.mail, Feb
- 2002.
-
- [BELLARE,KOHNO,NAMPREMPRE]
- Bellaire, M., Kohno, T. and C. Namprempre, "Authenticated
- Encryption in SSH: Fixing the SSH Binary Packet Protocol",
- , Sept 2002.
-
-
-Authors' Addresses
-
- Tatu Ylonen
- SSH Communications Security Corp
- Fredrikinkatu 42
- HELSINKI FIN-00100
- Finland
-
-
-
- Darren J. Moffat (editor)
- Sun Microsystems, Inc
- 17 Network Circle
- Menlo Park CA 94025
- USA
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 27]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
-Intellectual Property Statement
-
- The IETF takes no position regarding the validity or scope of any
- intellectual property or other rights that might be claimed to
- pertain to the implementation or use of the technology described in
- this document or the extent to which any license under such rights
- might or might not be available; neither does it represent that it
- has made any effort to identify any such rights. Information on the
- IETF's procedures with respect to rights in standards-track and
- standards-related documentation can be found in BCP-11. Copies of
- claims of rights made available for publication and any assurances of
- licenses to be made available, or the result of an attempt made to
- obtain a general license or permission for the use of such
- proprietary rights by implementors or users of this specification can
- be obtained from the IETF Secretariat.
-
- The IETF invites any interested party to bring to its attention any
- copyrights, patents or patent applications, or other proprietary
- rights which may cover technology that may be required to practice
- this standard. Please address the information to the IETF Executive
- Director.
-
- The IETF has been notified of intellectual property rights claimed in
- regard to some or all of the specification contained in this
- document. For more information consult the online list of claimed
- rights.
-
-
-Full Copyright Statement
-
- Copyright (C) The Internet Society (2003). All Rights Reserved.
-
- This document and translations of it may be copied and furnished to
- others, and derivative works that comment on or otherwise explain it
- or assist in its implementation may be prepared, copied, published
- and distributed, in whole or in part, without restriction of any
- kind, provided that the above copyright notice and this paragraph are
- included on all such copies and derivative works. However, this
- document itself may not be modified in any way, such as by removing
- the copyright notice or references to the Internet Society or other
- Internet organizations, except as needed for the purpose of
- developing Internet standards in which case the procedures for
- copyrights defined in the Internet Standards process must be
- followed, or as required to translate it into languages other than
- English.
-
- The limited permissions granted above are perpetual and will not be
- revoked by the Internet Society or its successors or assignees.
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 28]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- This document and the information contained herein is provided on an
- "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
- TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
- BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
- HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
- MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-
-Acknowledgment
-
- Funding for the RFC Editor function is currently provided by the
- Internet Society.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 29] \ No newline at end of file
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-connect-18.2.ps b/lib/ssh/doc/standard/draft-ietf-secsh-connect-18.2.ps
deleted file mode 100644
index 7a386724c2..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-connect-18.2.ps
+++ /dev/null
@@ -1,2557 +0,0 @@
-%!PS-Adobe-3.0
-%%BoundingBox: 75 0 595 747
-%%Title: Enscript Output
-%%For: Magnus Thoang
-%%Creator: GNU enscript 1.6.1
-%%CreationDate: Fri Oct 31 13:33:02 2003
-%%Orientation: Portrait
-%%Pages: 11 0
-%%DocumentMedia: A4 595 842 0 () ()
-%%DocumentNeededResources: (atend)
-%%EndComments
-%%BeginProlog
-%%BeginProcSet: PStoPS 1 15
-userdict begin
-[/showpage/erasepage/copypage]{dup where{pop dup load
- type/operatortype eq{1 array cvx dup 0 3 index cvx put
- bind def}{pop}ifelse}{pop}ifelse}forall
-[/letter/legal/executivepage/a4/a4small/b5/com10envelope
- /monarchenvelope/c5envelope/dlenvelope/lettersmall/note
- /folio/quarto/a5]{dup where{dup wcheck{exch{}put}
- {pop{}def}ifelse}{pop}ifelse}forall
-/setpagedevice {pop}bind 1 index where{dup wcheck{3 1 roll put}
- {pop def}ifelse}{def}ifelse
-/PStoPSmatrix matrix currentmatrix def
-/PStoPSxform matrix def/PStoPSclip{clippath}def
-/defaultmatrix{PStoPSmatrix exch PStoPSxform exch concatmatrix}bind def
-/initmatrix{matrix defaultmatrix setmatrix}bind def
-/initclip[{matrix currentmatrix PStoPSmatrix setmatrix
- [{currentpoint}stopped{$error/newerror false put{newpath}}
- {/newpath cvx 3 1 roll/moveto cvx 4 array astore cvx}ifelse]
- {[/newpath cvx{/moveto cvx}{/lineto cvx}
- {/curveto cvx}{/closepath cvx}pathforall]cvx exch pop}
- stopped{$error/errorname get/invalidaccess eq{cleartomark
- $error/newerror false put cvx exec}{stop}ifelse}if}bind aload pop
- /initclip dup load dup type dup/operatortype eq{pop exch pop}
- {dup/arraytype eq exch/packedarraytype eq or
- {dup xcheck{exch pop aload pop}{pop cvx}ifelse}
- {pop cvx}ifelse}ifelse
- {newpath PStoPSclip clip newpath exec setmatrix} bind aload pop]cvx def
-/initgraphics{initmatrix newpath initclip 1 setlinewidth
- 0 setlinecap 0 setlinejoin []0 setdash 0 setgray
- 10 setmiterlimit}bind def
-end
-%%EndProcSet
-%%BeginResource: procset Enscript-Prolog 1.6 1
-%
-% Procedures.
-%
-
-/_S { % save current state
- /_s save def
-} def
-/_R { % restore from saved state
- _s restore
-} def
-
-/S { % showpage protecting gstate
- gsave
- showpage
- grestore
-} bind def
-
-/MF { % fontname newfontname -> - make a new encoded font
- /newfontname exch def
- /fontname exch def
-
- /fontdict fontname findfont def
- /newfont fontdict maxlength dict def
-
- fontdict {
- exch
- dup /FID eq {
- % skip FID pair
- pop pop
- } {
- % copy to the new font dictionary
- exch newfont 3 1 roll put
- } ifelse
- } forall
-
- newfont /FontName newfontname put
-
- % insert only valid encoding vectors
- encoding_vector length 256 eq {
- newfont /Encoding encoding_vector put
- } if
-
- newfontname newfont definefont pop
-} def
-
-/SF { % fontname width height -> - set a new font
- /height exch def
- /width exch def
-
- findfont
- [width 0 0 height 0 0] makefont setfont
-} def
-
-/SUF { % fontname width height -> - set a new user font
- /height exch def
- /width exch def
-
- /F-gs-user-font MF
- /F-gs-user-font width height SF
-} def
-
-/M {moveto} bind def
-/s {show} bind def
-
-/Box { % x y w h -> - define box path
- /d_h exch def /d_w exch def /d_y exch def /d_x exch def
- d_x d_y moveto
- d_w 0 rlineto
- 0 d_h rlineto
- d_w neg 0 rlineto
- closepath
-} def
-
-/bgs { % x y height blskip gray str -> - show string with bg color
- /str exch def
- /gray exch def
- /blskip exch def
- /height exch def
- /y exch def
- /x exch def
-
- gsave
- x y blskip sub str stringwidth pop height Box
- gray setgray
- fill
- grestore
- x y M str s
-} def
-
-% Highlight bars.
-/highlight_bars { % nlines lineheight output_y_margin gray -> -
- gsave
- setgray
- /ymarg exch def
- /lineheight exch def
- /nlines exch def
-
- % This 2 is just a magic number to sync highlight lines to text.
- 0 d_header_y ymarg sub 2 sub translate
-
- /cw d_output_w cols div def
- /nrows d_output_h ymarg 2 mul sub lineheight div cvi def
-
- % for each column
- 0 1 cols 1 sub {
- cw mul /xp exch def
-
- % for each rows
- 0 1 nrows 1 sub {
- /rn exch def
- rn lineheight mul neg /yp exch def
- rn nlines idiv 2 mod 0 eq {
- % Draw highlight bar. 4 is just a magic indentation.
- xp 4 add yp cw 8 sub lineheight neg Box fill
- } if
- } for
- } for
-
- grestore
-} def
-
-% Line highlight bar.
-/line_highlight { % x y width height gray -> -
- gsave
- /gray exch def
- Box gray setgray fill
- grestore
-} def
-
-% Column separator lines.
-/column_lines {
- gsave
- .1 setlinewidth
- 0 d_footer_h translate
- /cw d_output_w cols div def
- 1 1 cols 1 sub {
- cw mul 0 moveto
- 0 d_output_h rlineto stroke
- } for
- grestore
-} def
-
-% Column borders.
-/column_borders {
- gsave
- .1 setlinewidth
- 0 d_footer_h moveto
- 0 d_output_h rlineto
- d_output_w 0 rlineto
- 0 d_output_h neg rlineto
- closepath stroke
- grestore
-} def
-
-% Do the actual underlay drawing
-/draw_underlay {
- ul_style 0 eq {
- ul_str true charpath stroke
- } {
- ul_str show
- } ifelse
-} def
-
-% Underlay
-/underlay { % - -> -
- gsave
- 0 d_page_h translate
- d_page_h neg d_page_w atan rotate
-
- ul_gray setgray
- ul_font setfont
- /dw d_page_h dup mul d_page_w dup mul add sqrt def
- ul_str stringwidth pop dw exch sub 2 div ul_h_ptsize -2 div moveto
- draw_underlay
- grestore
-} def
-
-/user_underlay { % - -> -
- gsave
- ul_x ul_y translate
- ul_angle rotate
- ul_gray setgray
- ul_font setfont
- 0 0 ul_h_ptsize 2 div sub moveto
- draw_underlay
- grestore
-} def
-
-% Page prefeed
-/page_prefeed { % bool -> -
- statusdict /prefeed known {
- statusdict exch /prefeed exch put
- } {
- pop
- } ifelse
-} def
-
-% Wrapped line markers
-/wrapped_line_mark { % x y charwith charheight type -> -
- /type exch def
- /h exch def
- /w exch def
- /y exch def
- /x exch def
-
- type 2 eq {
- % Black boxes (like TeX does)
- gsave
- 0 setlinewidth
- x w 4 div add y M
- 0 h rlineto w 2 div 0 rlineto 0 h neg rlineto
- closepath fill
- grestore
- } {
- type 3 eq {
- % Small arrows
- gsave
- .2 setlinewidth
- x w 2 div add y h 2 div add M
- w 4 div 0 rlineto
- x w 4 div add y lineto stroke
-
- x w 4 div add w 8 div add y h 4 div add M
- x w 4 div add y lineto
- w 4 div h 8 div rlineto stroke
- grestore
- } {
- % do nothing
- } ifelse
- } ifelse
-} def
-
-% EPSF import.
-
-/BeginEPSF {
- /b4_Inc_state save def % Save state for cleanup
- /dict_count countdictstack def % Count objects on dict stack
- /op_count count 1 sub def % Count objects on operand stack
- userdict begin
- /showpage { } def
- 0 setgray 0 setlinecap
- 1 setlinewidth 0 setlinejoin
- 10 setmiterlimit [ ] 0 setdash newpath
- /languagelevel where {
- pop languagelevel
- 1 ne {
- false setstrokeadjust false setoverprint
- } if
- } if
-} bind def
-
-/EndEPSF {
- count op_count sub { pos } repeat % Clean up stacks
- countdictstack dict_count sub { end } repeat
- b4_Inc_state restore
-} bind def
-
-% Check PostScript language level.
-/languagelevel where {
- pop /gs_languagelevel languagelevel def
-} {
- /gs_languagelevel 1 def
-} ifelse
-%%EndResource
-%%BeginResource: procset Enscript-Encoding-88591 1.6 1
-/encoding_vector [
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/space /exclam /quotedbl /numbersign
-/dollar /percent /ampersand /quoteright
-/parenleft /parenright /asterisk /plus
-/comma /hyphen /period /slash
-/zero /one /two /three
-/four /five /six /seven
-/eight /nine /colon /semicolon
-/less /equal /greater /question
-/at /A /B /C
-/D /E /F /G
-/H /I /J /K
-/L /M /N /O
-/P /Q /R /S
-/T /U /V /W
-/X /Y /Z /bracketleft
-/backslash /bracketright /asciicircum /underscore
-/quoteleft /a /b /c
-/d /e /f /g
-/h /i /j /k
-/l /m /n /o
-/p /q /r /s
-/t /u /v /w
-/x /y /z /braceleft
-/bar /braceright /tilde /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/space /exclamdown /cent /sterling
-/currency /yen /brokenbar /section
-/dieresis /copyright /ordfeminine /guillemotleft
-/logicalnot /hyphen /registered /macron
-/degree /plusminus /twosuperior /threesuperior
-/acute /mu /paragraph /bullet
-/cedilla /onesuperior /ordmasculine /guillemotright
-/onequarter /onehalf /threequarters /questiondown
-/Agrave /Aacute /Acircumflex /Atilde
-/Adieresis /Aring /AE /Ccedilla
-/Egrave /Eacute /Ecircumflex /Edieresis
-/Igrave /Iacute /Icircumflex /Idieresis
-/Eth /Ntilde /Ograve /Oacute
-/Ocircumflex /Otilde /Odieresis /multiply
-/Oslash /Ugrave /Uacute /Ucircumflex
-/Udieresis /Yacute /Thorn /germandbls
-/agrave /aacute /acircumflex /atilde
-/adieresis /aring /ae /ccedilla
-/egrave /eacute /ecircumflex /edieresis
-/igrave /iacute /icircumflex /idieresis
-/eth /ntilde /ograve /oacute
-/ocircumflex /otilde /odieresis /divide
-/oslash /ugrave /uacute /ucircumflex
-/udieresis /yacute /thorn /ydieresis
-] def
-%%EndResource
-%%EndProlog
-%%BeginSetup
-%%IncludeResource: font Courier-Bold
-%%IncludeResource: font Courier
-/HFpt_w 10 def
-/HFpt_h 10 def
-/Courier-Bold /HF-gs-font MF
-/HF /HF-gs-font findfont [HFpt_w 0 0 HFpt_h 0 0] makefont def
-/Courier /F-gs-font MF
-/F-gs-font 10 10 SF
-/#copies 1 def
-/d_page_w 520 def
-/d_page_h 747 def
-/d_header_x 0 def
-/d_header_y 747 def
-/d_header_w 520 def
-/d_header_h 0 def
-/d_footer_x 0 def
-/d_footer_y 0 def
-/d_footer_w 520 def
-/d_footer_h 0 def
-/d_output_w 520 def
-/d_output_h 747 def
-/cols 1 def
-userdict/PStoPSxform PStoPSmatrix matrix currentmatrix
- matrix invertmatrix matrix concatmatrix
- matrix invertmatrix put
-%%EndSetup
-%%Page: (0,1) 1
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 1 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 701 M
-(Network Working Group T. Ylonen) s
-5 690 M
-(Internet-Draft SSH Communications Security Corp) s
-5 679 M
-(Expires: March 31, 2004 D. Moffat, Editor, Ed.) s
-5 668 M
-( Sun Microsystems, Inc) s
-5 657 M
-( Oct 2003) s
-5 624 M
-( SSH Connection Protocol) s
-5 613 M
-( draft-ietf-secsh-connect-18.txt) s
-5 591 M
-(Status of this Memo) s
-5 569 M
-( This document is an Internet-Draft and is in full conformance with) s
-5 558 M
-( all provisions of Section 10 of RFC2026.) s
-5 536 M
-( Internet-Drafts are working documents of the Internet Engineering) s
-5 525 M
-( Task Force \(IETF\), its areas, and its working groups. Note that other) s
-5 514 M
-( groups may also distribute working documents as Internet-Drafts.) s
-5 492 M
-( Internet-Drafts are draft documents valid for a maximum of six months) s
-5 481 M
-( and may be updated, replaced, or obsoleted by other documents at any) s
-5 470 M
-( time. It is inappropriate to use Internet-Drafts as reference) s
-5 459 M
-( material or to cite them other than as "work in progress.") s
-5 437 M
-( The list of current Internet-Drafts can be accessed at http://) s
-5 426 M
-( www.ietf.org/ietf/1id-abstracts.txt.) s
-5 404 M
-( The list of Internet-Draft Shadow Directories can be accessed at) s
-5 393 M
-( http://www.ietf.org/shadow.html.) s
-5 371 M
-( This Internet-Draft will expire on March 31, 2004.) s
-5 349 M
-(Copyright Notice) s
-5 327 M
-( Copyright \(C\) The Internet Society \(2003\). All Rights Reserved.) s
-5 305 M
-(Abstract) s
-5 283 M
-( SSH is a protocol for secure remote login and other secure network) s
-5 272 M
-( services over an insecure network.) s
-5 250 M
-( This document describes the SSH Connection Protocol. It provides) s
-5 239 M
-( interactive login sessions, remote execution of commands, forwarded) s
-5 228 M
-( TCP/IP connections, and forwarded X11 connections. All of these) s
-5 217 M
-( channels are multiplexed into a single encrypted tunnel.) s
-5 195 M
-( The SSH Connection Protocol has been designed to run on top of the) s
-5 184 M
-( SSH transport layer and user authentication protocols.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 1]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 2 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-(Table of Contents) s
-5 668 M
-( 1. Contributors . . . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 657 M
-( 2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 646 M
-( 3. Conventions Used in This Document . . . . . . . . . . . . . 3) s
-5 635 M
-( 4. Global Requests . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 624 M
-( 5. Channel Mechanism . . . . . . . . . . . . . . . . . . . . . 4) s
-5 613 M
-( 5.1 Opening a Channel . . . . . . . . . . . . . . . . . . . . . 4) s
-5 602 M
-( 5.2 Data Transfer . . . . . . . . . . . . . . . . . . . . . . . 5) s
-5 591 M
-( 5.3 Closing a Channel . . . . . . . . . . . . . . . . . . . . . 6) s
-5 580 M
-( 5.4 Channel-Specific Requests . . . . . . . . . . . . . . . . . 7) s
-5 569 M
-( 6. Interactive Sessions . . . . . . . . . . . . . . . . . . . . 8) s
-5 558 M
-( 6.1 Opening a Session . . . . . . . . . . . . . . . . . . . . . 8) s
-5 547 M
-( 6.2 Requesting a Pseudo-Terminal . . . . . . . . . . . . . . . . 8) s
-5 536 M
-( 6.3 X11 Forwarding . . . . . . . . . . . . . . . . . . . . . . . 9) s
-5 525 M
-( 6.3.1 Requesting X11 Forwarding . . . . . . . . . . . . . . . . . 9) s
-5 514 M
-( 6.3.2 X11 Channels . . . . . . . . . . . . . . . . . . . . . . . . 10) s
-5 503 M
-( 6.4 Environment Variable Passing . . . . . . . . . . . . . . . . 10) s
-5 492 M
-( 6.5 Starting a Shell or a Command . . . . . . . . . . . . . . . 10) s
-5 481 M
-( 6.6 Session Data Transfer . . . . . . . . . . . . . . . . . . . 11) s
-5 470 M
-( 6.7 Window Dimension Change Message . . . . . . . . . . . . . . 12) s
-5 459 M
-( 6.8 Local Flow Control . . . . . . . . . . . . . . . . . . . . . 12) s
-5 448 M
-( 6.9 Signals . . . . . . . . . . . . . . . . . . . . . . . . . . 12) s
-5 437 M
-( 6.10 Returning Exit Status . . . . . . . . . . . . . . . . . . . 13) s
-5 426 M
-( 7. TCP/IP Port Forwarding . . . . . . . . . . . . . . . . . . . 14) s
-5 415 M
-( 7.1 Requesting Port Forwarding . . . . . . . . . . . . . . . . . 14) s
-5 404 M
-( 7.2 TCP/IP Forwarding Channels . . . . . . . . . . . . . . . . . 15) s
-5 393 M
-( 8. Encoding of Terminal Modes . . . . . . . . . . . . . . . . . 16) s
-5 382 M
-( 9. Summary of Message Numbers . . . . . . . . . . . . . . . . . 18) s
-5 371 M
-( 10. Security Considerations . . . . . . . . . . . . . . . . . . 18) s
-5 360 M
-( 11. iana cONSiderations . . . . . . . . . . . . . . . . . . . . 19) s
-5 349 M
-( 12. Intellectual Property . . . . . . . . . . . . . . . . . . . 19) s
-5 338 M
-( Normative References . . . . . . . . . . . . . . . . . . . . 19) s
-5 327 M
-( Informative References . . . . . . . . . . . . . . . . . . . 20) s
-5 316 M
-( Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 20) s
-5 305 M
-( Intellectual Property and Copyright Statements . . . . . . . 21) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 2]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (2,3) 2
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 3 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-(1. Contributors) s
-5 668 M
-( The major original contributors of this document were: Tatu Ylonen,) s
-5 657 M
-( Tero Kivinen, Timo J. Rinne, Sami Lehtinen \(all of SSH Communications) s
-5 646 M
-( Security Corp\), and Markku-Juhani O. Saarinen \(University of) s
-5 635 M
-( Jyvaskyla\)) s
-5 613 M
-( The document editor is: [email protected]. Comments on this) s
-5 602 M
-( internet draft should be sent to the IETF SECSH working group,) s
-5 591 M
-( details at: http://ietf.org/html.charters/secsh-charter.html) s
-5 569 M
-(2. Introduction) s
-5 547 M
-( The SSH Connection Protocol has been designed to run on top of the) s
-5 536 M
-( SSH transport layer and user authentication protocols. It provides) s
-5 525 M
-( interactive login sessions, remote execution of commands, forwarded) s
-5 514 M
-( TCP/IP connections, and forwarded X11 connections. The service name) s
-5 503 M
-( for this protocol is "ssh-connection".) s
-5 481 M
-( This document should be read only after reading the SSH architecture) s
-5 470 M
-( document [SSH-ARCH]. This document freely uses terminology and) s
-5 459 M
-( notation from the architecture document without reference or further) s
-5 448 M
-( explanation.) s
-5 426 M
-(3. Conventions Used in This Document) s
-5 404 M
-( The keywords "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT",) s
-5 393 M
-( and "MAY" that appear in this document are to be interpreted as) s
-5 382 M
-( described in [RFC2119].) s
-5 360 M
-( The used data types and terminology are specified in the architecture) s
-5 349 M
-( document [SSH-ARCH].) s
-5 327 M
-( The architecture document also discusses the algorithm naming) s
-5 316 M
-( conventions that MUST be used with the SSH protocols.) s
-5 294 M
-(4. Global Requests) s
-5 272 M
-( There are several kinds of requests that affect the state of the) s
-5 261 M
-( remote end "globally", independent of any channels. An example is a) s
-5 250 M
-( request to start TCP/IP forwarding for a specific port. All such) s
-5 239 M
-( requests use the following format.) s
-5 217 M
-( byte SSH_MSG_GLOBAL_REQUEST) s
-5 206 M
-( string request name \(restricted to US-ASCII\)) s
-5 195 M
-( boolean want reply) s
-5 184 M
-( ... request-specific data follows) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 3]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 4 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( Request names follow the DNS extensibility naming convention outlined) s
-5 679 M
-( in [SSH-ARCH].) s
-5 657 M
-( The recipient will respond to this message with) s
-5 646 M
-( SSH_MSG_REQUEST_SUCCESS or SSH_MSG_REQUEST_FAILURE if `want reply' is) s
-5 635 M
-( TRUE.) s
-5 613 M
-( byte SSH_MSG_REQUEST_SUCCESS) s
-5 602 M
-( ..... response specific data) s
-5 580 M
-( Usually the response specific data is non-existent.) s
-5 558 M
-( If the recipient does not recognize or support the request, it simply) s
-5 547 M
-( responds with SSH_MSG_REQUEST_FAILURE.) s
-5 525 M
-( byte SSH_MSG_REQUEST_FAILURE) s
-5 492 M
-(5. Channel Mechanism) s
-5 470 M
-( All terminal sessions, forwarded connections, etc. are channels.) s
-5 459 M
-( Either side may open a channel. Multiple channels are multiplexed) s
-5 448 M
-( into a single connection.) s
-5 426 M
-( Channels are identified by numbers at each end. The number referring) s
-5 415 M
-( to a channel may be different on each side. Requests to open a) s
-5 404 M
-( channel contain the sender's channel number. Any other) s
-5 393 M
-( channel-related messages contain the recipient's channel number for) s
-5 382 M
-( the channel.) s
-5 360 M
-( Channels are flow-controlled. No data may be sent to a channel until) s
-5 349 M
-( a message is received to indicate that window space is available.) s
-5 327 M
-(5.1 Opening a Channel) s
-5 305 M
-( When either side wishes to open a new channel, it allocates a local) s
-5 294 M
-( number for the channel. It then sends the following message to the) s
-5 283 M
-( other side, and includes the local channel number and initial window) s
-5 272 M
-( size in the message.) s
-5 250 M
-( byte SSH_MSG_CHANNEL_OPEN) s
-5 239 M
-( string channel type \(restricted to US-ASCII\)) s
-5 228 M
-( uint32 sender channel) s
-5 217 M
-( uint32 initial window size) s
-5 206 M
-( uint32 maximum packet size) s
-5 195 M
-( ... channel type specific data follows) s
-5 173 M
-( The channel type is a name as described in the SSH architecture) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 4]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (4,5) 3
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 5 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( document, with similar extension mechanisms. `sender channel' is a) s
-5 679 M
-( local identifier for the channel used by the sender of this message.) s
-5 668 M
-( `initial window size' specifies how many bytes of channel data can be) s
-5 657 M
-( sent to the sender of this message without adjusting the window.) s
-5 646 M
-( `Maximum packet size' specifies the maximum size of an individual) s
-5 635 M
-( data packet that can be sent to the sender \(for example, one might) s
-5 624 M
-( want to use smaller packets for interactive connections to get better) s
-5 613 M
-( interactive response on slow links\).) s
-5 591 M
-( The remote side then decides whether it can open the channel, and) s
-5 580 M
-( responds with either) s
-5 558 M
-( byte SSH_MSG_CHANNEL_OPEN_CONFIRMATION) s
-5 547 M
-( uint32 recipient channel) s
-5 536 M
-( uint32 sender channel) s
-5 525 M
-( uint32 initial window size) s
-5 514 M
-( uint32 maximum packet size) s
-5 503 M
-( ... channel type specific data follows) s
-5 481 M
-( where `recipient channel' is the channel number given in the original) s
-5 470 M
-( open request, and `sender channel' is the channel number allocated by) s
-5 459 M
-( the other side, or) s
-5 437 M
-( byte SSH_MSG_CHANNEL_OPEN_FAILURE) s
-5 426 M
-( uint32 recipient channel) s
-5 415 M
-( uint32 reason code) s
-5 404 M
-( string additional textual information \(ISO-10646 UTF-8 [RFC2279]\)) s
-5 393 M
-( string language tag \(as defined in [RFC3066]\)) s
-5 371 M
-( If the recipient of the SSH_MSG_CHANNEL_OPEN message does not support) s
-5 360 M
-( the specified channel type, it simply responds with) s
-5 349 M
-( SSH_MSG_CHANNEL_OPEN_FAILURE. The client MAY show the additional) s
-5 338 M
-( information to the user. If this is done, the client software should) s
-5 327 M
-( take the precautions discussed in [SSH-ARCH].) s
-5 305 M
-( The following reason codes are defined:) s
-5 283 M
-( #define SSH_OPEN_ADMINISTRATIVELY_PROHIBITED 1) s
-5 272 M
-( #define SSH_OPEN_CONNECT_FAILED 2) s
-5 261 M
-( #define SSH_OPEN_UNKNOWN_CHANNEL_TYPE 3) s
-5 250 M
-( #define SSH_OPEN_RESOURCE_SHORTAGE 4) s
-5 217 M
-(5.2 Data Transfer) s
-5 195 M
-( The window size specifies how many bytes the other party can send) s
-5 184 M
-( before it must wait for the window to be adjusted. Both parties use) s
-5 173 M
-( the following message to adjust the window.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 5]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 6 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( byte SSH_MSG_CHANNEL_WINDOW_ADJUST) s
-5 679 M
-( uint32 recipient channel) s
-5 668 M
-( uint32 bytes to add) s
-5 646 M
-( After receiving this message, the recipient MAY send the given number) s
-5 635 M
-( of bytes more than it was previously allowed to send; the window size) s
-5 624 M
-( is incremented.) s
-5 602 M
-( Data transfer is done with messages of the following type.) s
-5 580 M
-( byte SSH_MSG_CHANNEL_DATA) s
-5 569 M
-( uint32 recipient channel) s
-5 558 M
-( string data) s
-5 536 M
-( The maximum amount of data allowed is the current window size. The) s
-5 525 M
-( window size is decremented by the amount of data sent. Both parties) s
-5 514 M
-( MAY ignore all extra data sent after the allowed window is empty.) s
-5 492 M
-( Additionally, some channels can transfer several types of data. An) s
-5 481 M
-( example of this is stderr data from interactive sessions. Such data) s
-5 470 M
-( can be passed with SSH_MSG_CHANNEL_EXTENDED_DATA messages, where a) s
-5 459 M
-( separate integer specifies the type of the data. The available types) s
-5 448 M
-( and their interpretation depend on the type of the channel.) s
-5 426 M
-( byte SSH_MSG_CHANNEL_EXTENDED_DATA) s
-5 415 M
-( uint32 recipient_channel) s
-5 404 M
-( uint32 data_type_code) s
-5 393 M
-( string data) s
-5 371 M
-( Data sent with these messages consumes the same window as ordinary) s
-5 360 M
-( data.) s
-5 338 M
-( Currently, only the following type is defined.) s
-5 316 M
-( #define SSH_EXTENDED_DATA_STDERR 1) s
-5 283 M
-(5.3 Closing a Channel) s
-5 261 M
-( When a party will no longer send more data to a channel, it SHOULD) s
-5 250 M
-( send SSH_MSG_CHANNEL_EOF.) s
-5 228 M
-( byte SSH_MSG_CHANNEL_EOF) s
-5 217 M
-( uint32 recipient_channel) s
-5 195 M
-( No explicit response is sent to this message; however, the) s
-5 184 M
-( application may send EOF to whatever is at the other end of the) s
-5 173 M
-( channel. Note that the channel remains open after this message, and) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 6]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (6,7) 4
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 7 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( more data may still be sent in the other direction. This message) s
-5 679 M
-( does not consume window space and can be sent even if no window space) s
-5 668 M
-( is available.) s
-5 646 M
-( When either party wishes to terminate the channel, it sends) s
-5 635 M
-( SSH_MSG_CHANNEL_CLOSE. Upon receiving this message, a party MUST) s
-5 624 M
-( send back a SSH_MSG_CHANNEL_CLOSE unless it has already sent this) s
-5 613 M
-( message for the channel. The channel is considered closed for a) s
-5 602 M
-( party when it has both sent and received SSH_MSG_CHANNEL_CLOSE, and) s
-5 591 M
-( the party may then reuse the channel number. A party MAY send) s
-5 580 M
-( SSH_MSG_CHANNEL_CLOSE without having sent or received) s
-5 569 M
-( SSH_MSG_CHANNEL_EOF.) s
-5 547 M
-( byte SSH_MSG_CHANNEL_CLOSE) s
-5 536 M
-( uint32 recipient_channel) s
-5 514 M
-( This message does not consume window space and can be sent even if no) s
-5 503 M
-( window space is available.) s
-5 481 M
-( It is recommended that any data sent before this message is delivered) s
-5 470 M
-( to the actual destination, if possible.) s
-5 448 M
-(5.4 Channel-Specific Requests) s
-5 426 M
-( Many channel types have extensions that are specific to that) s
-5 415 M
-( particular channel type. An example is requesting a pty \(pseudo) s
-5 404 M
-( terminal\) for an interactive session.) s
-5 382 M
-( All channel-specific requests use the following format.) s
-5 360 M
-( byte SSH_MSG_CHANNEL_REQUEST) s
-5 349 M
-( uint32 recipient channel) s
-5 338 M
-( string request type \(restricted to US-ASCII\)) s
-5 327 M
-( boolean want reply) s
-5 316 M
-( ... type-specific data) s
-5 294 M
-( If want reply is FALSE, no response will be sent to the request.) s
-5 283 M
-( Otherwise, the recipient responds with either SSH_MSG_CHANNEL_SUCCESS) s
-5 272 M
-( or SSH_MSG_CHANNEL_FAILURE, or request-specific continuation) s
-5 261 M
-( messages. If the request is not recognized or is not supported for) s
-5 250 M
-( the channel, SSH_MSG_CHANNEL_FAILURE is returned.) s
-5 228 M
-( This message does not consume window space and can be sent even if no) s
-5 217 M
-( window space is available. Request types are local to each channel) s
-5 206 M
-( type.) s
-5 184 M
-( The client is allowed to send further messages without waiting for) s
-5 173 M
-( the response to the request.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 7]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 8 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( request type names follow the DNS extensibility naming convention) s
-5 679 M
-( outlined in [SSH-ARCH]) s
-5 657 M
-( byte SSH_MSG_CHANNEL_SUCCESS) s
-5 646 M
-( uint32 recipient_channel) s
-5 613 M
-( byte SSH_MSG_CHANNEL_FAILURE) s
-5 602 M
-( uint32 recipient_channel) s
-5 580 M
-( These messages do not consume window space and can be sent even if no) s
-5 569 M
-( window space is available.) s
-5 547 M
-(6. Interactive Sessions) s
-5 525 M
-( A session is a remote execution of a program. The program may be a) s
-5 514 M
-( shell, an application, a system command, or some built-in subsystem.) s
-5 503 M
-( It may or may not have a tty, and may or may not involve X11) s
-5 492 M
-( forwarding. Multiple sessions can be active simultaneously.) s
-5 470 M
-(6.1 Opening a Session) s
-5 448 M
-( A session is started by sending the following message.) s
-5 426 M
-( byte SSH_MSG_CHANNEL_OPEN) s
-5 415 M
-( string "session") s
-5 404 M
-( uint32 sender channel) s
-5 393 M
-( uint32 initial window size) s
-5 382 M
-( uint32 maximum packet size) s
-5 360 M
-( Client implementations SHOULD reject any session channel open) s
-5 349 M
-( requests to make it more difficult for a corrupt server to attack the) s
-5 338 M
-( client.) s
-5 316 M
-(6.2 Requesting a Pseudo-Terminal) s
-5 294 M
-( A pseudo-terminal can be allocated for the session by sending the) s
-5 283 M
-( following message.) s
-5 261 M
-( byte SSH_MSG_CHANNEL_REQUEST) s
-5 250 M
-( uint32 recipient_channel) s
-5 239 M
-( string "pty-req") s
-5 228 M
-( boolean want_reply) s
-5 217 M
-( string TERM environment variable value \(e.g., vt100\)) s
-5 206 M
-( uint32 terminal width, characters \(e.g., 80\)) s
-5 195 M
-( uint32 terminal height, rows \(e.g., 24\)) s
-5 184 M
-( uint32 terminal width, pixels \(e.g., 640\)) s
-5 173 M
-( uint32 terminal height, pixels \(e.g., 480\)) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 8]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (8,9) 5
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 9 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( string encoded terminal modes) s
-5 668 M
-( The encoding of terminal modes is described in Section Encoding of) s
-5 657 M
-( Terminal Modes \(Section 8\). Zero dimension parameters MUST be) s
-5 646 M
-( ignored. The character/row dimensions override the pixel dimensions) s
-5 635 M
-( \(when nonzero\). Pixel dimensions refer to the drawable area of the) s
-5 624 M
-( window.) s
-5 602 M
-( The dimension parameters are only informational.) s
-5 580 M
-( The client SHOULD ignore pty requests.) s
-5 558 M
-(6.3 X11 Forwarding) s
-5 536 M
-(6.3.1 Requesting X11 Forwarding) s
-5 514 M
-( X11 forwarding may be requested for a session by sending) s
-5 492 M
-( byte SSH_MSG_CHANNEL_REQUEST) s
-5 481 M
-( uint32 recipient channel) s
-5 470 M
-( string "x11-req") s
-5 459 M
-( boolean want reply) s
-5 448 M
-( boolean single connection) s
-5 437 M
-( string x11 authentication protocol) s
-5 426 M
-( string x11 authentication cookie) s
-5 415 M
-( uint32 x11 screen number) s
-5 393 M
-( It is recommended that the authentication cookie that is sent be a) s
-5 382 M
-( fake, random cookie, and that the cookie is checked and replaced by) s
-5 371 M
-( the real cookie when a connection request is received.) s
-5 349 M
-( X11 connection forwarding should stop when the session channel is) s
-5 338 M
-( closed; however, already opened forwardings should not be) s
-5 327 M
-( automatically closed when the session channel is closed.) s
-5 305 M
-( If `single connection' is TRUE, only a single connection should be) s
-5 294 M
-( forwarded. No more connections will be forwarded after the first, or) s
-5 283 M
-( after the session channel has been closed.) s
-5 261 M
-( The "x11 authentication protocol" is the name of the X11) s
-5 250 M
-( authentication method used, e.g. "MIT-MAGIC-COOKIE-1".) s
-5 228 M
-( The x11 authentication cookie MUST be hexadecimal encoded.) s
-5 206 M
-( X Protocol is documented in [SCHEIFLER].) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 9]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 10 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-(6.3.2 X11 Channels) s
-5 668 M
-( X11 channels are opened with a channel open request. The resulting) s
-5 657 M
-( channels are independent of the session, and closing the session) s
-5 646 M
-( channel does not close the forwarded X11 channels.) s
-5 624 M
-( byte SSH_MSG_CHANNEL_OPEN) s
-5 613 M
-( string "x11") s
-5 602 M
-( uint32 sender channel) s
-5 591 M
-( uint32 initial window size) s
-5 580 M
-( uint32 maximum packet size) s
-5 569 M
-( string originator address \(e.g. "192.168.7.38"\)) s
-5 558 M
-( uint32 originator port) s
-5 536 M
-( The recipient should respond with SSH_MSG_CHANNEL_OPEN_CONFIRMATION) s
-5 525 M
-( or SSH_MSG_CHANNEL_OPEN_FAILURE.) s
-5 503 M
-( Implementations MUST reject any X11 channel open requests if they) s
-5 492 M
-( have not requested X11 forwarding.) s
-5 470 M
-(6.4 Environment Variable Passing) s
-5 448 M
-( Environment variables may be passed to the shell/command to be) s
-5 437 M
-( started later. Uncontrolled setting of environment variables in a) s
-5 426 M
-( privileged process can be a security hazard. It is recommended that) s
-5 415 M
-( implementations either maintain a list of allowable variable names or) s
-5 404 M
-( only set environment variables after the server process has dropped) s
-5 393 M
-( sufficient privileges.) s
-5 371 M
-( byte SSH_MSG_CHANNEL_REQUEST) s
-5 360 M
-( uint32 recipient channel) s
-5 349 M
-( string "env") s
-5 338 M
-( boolean want reply) s
-5 327 M
-( string variable name) s
-5 316 M
-( string variable value) s
-5 283 M
-(6.5 Starting a Shell or a Command) s
-5 261 M
-( Once the session has been set up, a program is started at the remote) s
-5 250 M
-( end. The program can be a shell, an application program or a) s
-5 239 M
-( subsystem with a host-independent name. Only one of these requests) s
-5 228 M
-( can succeed per channel.) s
-5 206 M
-( byte SSH_MSG_CHANNEL_REQUEST) s
-5 195 M
-( uint32 recipient channel) s
-5 184 M
-( string "shell") s
-5 173 M
-( boolean want reply) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 10]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (10,11) 6
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 11 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( This message will request the user's default shell \(typically defined) s
-5 679 M
-( in /etc/passwd in UNIX systems\) to be started at the other end.) s
-5 657 M
-( byte SSH_MSG_CHANNEL_REQUEST) s
-5 646 M
-( uint32 recipient channel) s
-5 635 M
-( string "exec") s
-5 624 M
-( boolean want reply) s
-5 613 M
-( string command) s
-5 591 M
-( This message will request the server to start the execution of the) s
-5 580 M
-( given command. The command string may contain a path. Normal) s
-5 569 M
-( precautions MUST be taken to prevent the execution of unauthorized) s
-5 558 M
-( commands.) s
-5 536 M
-( byte SSH_MSG_CHANNEL_REQUEST) s
-5 525 M
-( uint32 recipient channel) s
-5 514 M
-( string "subsystem") s
-5 503 M
-( boolean want reply) s
-5 492 M
-( string subsystem name) s
-5 470 M
-( This last form executes a predefined subsystem. It is expected that) s
-5 459 M
-( these will include a general file transfer mechanism, and possibly) s
-5 448 M
-( other features. Implementations may also allow configuring more such) s
-5 437 M
-( mechanisms. As the user's shell is usually used to execute the) s
-5 426 M
-( subsystem, it is advisable for the subsystem protocol to have a) s
-5 415 M
-( "magic cookie" at the beginning of the protocol transaction to) s
-5 404 M
-( distinguish it from arbitrary output generated by shell) s
-5 393 M
-( initialization scripts etc. This spurious output from the shell may) s
-5 382 M
-( be filtered out either at the server or at the client.) s
-5 360 M
-( The server SHOULD not halt the execution of the protocol stack when) s
-5 349 M
-( starting a shell or a program. All input and output from these SHOULD) s
-5 338 M
-( be redirected to the channel or to the encrypted tunnel.) s
-5 316 M
-( It is RECOMMENDED to request and check the reply for these messages.) s
-5 305 M
-( The client SHOULD ignore these messages.) s
-5 283 M
-( Subsystem names follow the DNS extensibility naming convention) s
-5 272 M
-( outlined in [SSH-ARCH].) s
-5 250 M
-(6.6 Session Data Transfer) s
-5 228 M
-( Data transfer for a session is done using SSH_MSG_CHANNEL_DATA and) s
-5 217 M
-( SSH_MSG_CHANNEL_EXTENDED_DATA packets and the window mechanism. The) s
-5 206 M
-( extended data type SSH_EXTENDED_DATA_STDERR has been defined for) s
-5 195 M
-( stderr data.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 11]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 12 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-(6.7 Window Dimension Change Message) s
-5 668 M
-( When the window \(terminal\) size changes on the client side, it MAY) s
-5 657 M
-( send a message to the other side to inform it of the new dimensions.) s
-5 635 M
-( byte SSH_MSG_CHANNEL_REQUEST) s
-5 624 M
-( uint32 recipient_channel) s
-5 613 M
-( string "window-change") s
-5 602 M
-( boolean FALSE) s
-5 591 M
-( uint32 terminal width, columns) s
-5 580 M
-( uint32 terminal height, rows) s
-5 569 M
-( uint32 terminal width, pixels) s
-5 558 M
-( uint32 terminal height, pixels) s
-5 536 M
-( No response SHOULD be sent to this message.) s
-5 514 M
-(6.8 Local Flow Control) s
-5 492 M
-( On many systems, it is possible to determine if a pseudo-terminal is) s
-5 481 M
-( using control-S/control-Q flow control. When flow control is) s
-5 470 M
-( allowed, it is often desirable to do the flow control at the client) s
-5 459 M
-( end to speed up responses to user requests. This is facilitated by) s
-5 448 M
-( the following notification. Initially, the server is responsible for) s
-5 437 M
-( flow control. \(Here, again, client means the side originating the) s
-5 426 M
-( session, and server means the other side.\)) s
-5 404 M
-( The message below is used by the server to inform the client when it) s
-5 393 M
-( can or cannot perform flow control \(control-S/control-Q processing\).) s
-5 382 M
-( If `client can do' is TRUE, the client is allowed to do flow control) s
-5 371 M
-( using control-S and control-Q. The client MAY ignore this message.) s
-5 349 M
-( byte SSH_MSG_CHANNEL_REQUEST) s
-5 338 M
-( uint32 recipient channel) s
-5 327 M
-( string "xon-xoff") s
-5 316 M
-( boolean FALSE) s
-5 305 M
-( boolean client can do) s
-5 283 M
-( No response is sent to this message.) s
-5 261 M
-(6.9 Signals) s
-5 239 M
-( A signal can be delivered to the remote process/service using the) s
-5 228 M
-( following message. Some systems may not implement signals, in which) s
-5 217 M
-( case they SHOULD ignore this message.) s
-5 195 M
-( byte SSH_MSG_CHANNEL_REQUEST) s
-5 184 M
-( uint32 recipient channel) s
-5 173 M
-( string "signal") s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 12]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (12,13) 7
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 13 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( boolean FALSE) s
-5 679 M
-( string signal name without the "SIG" prefix.) s
-5 657 M
-( Signal names will be encoded as discussed in the "exit-signal") s
-5 646 M
-( SSH_MSG_CHANNEL_REQUEST.) s
-5 624 M
-(6.10 Returning Exit Status) s
-5 602 M
-( When the command running at the other end terminates, the following) s
-5 591 M
-( message can be sent to return the exit status of the command.) s
-5 580 M
-( Returning the status is RECOMMENDED. No acknowledgment is sent for) s
-5 569 M
-( this message. The channel needs to be closed with) s
-5 558 M
-( SSH_MSG_CHANNEL_CLOSE after this message.) s
-5 536 M
-( The client MAY ignore these messages.) s
-5 514 M
-( byte SSH_MSG_CHANNEL_REQUEST) s
-5 503 M
-( uint32 recipient_channel) s
-5 492 M
-( string "exit-status") s
-5 481 M
-( boolean FALSE) s
-5 470 M
-( uint32 exit_status) s
-5 448 M
-( The remote command may also terminate violently due to a signal.) s
-5 437 M
-( Such a condition can be indicated by the following message. A zero) s
-5 426 M
-( exit_status usually means that the command terminated successfully.) s
-5 404 M
-( byte SSH_MSG_CHANNEL_REQUEST) s
-5 393 M
-( uint32 recipient channel) s
-5 382 M
-( string "exit-signal") s
-5 371 M
-( boolean FALSE) s
-5 360 M
-( string signal name without the "SIG" prefix.) s
-5 349 M
-( boolean core dumped) s
-5 338 M
-( string error message \(ISO-10646 UTF-8\)) s
-5 327 M
-( string language tag \(as defined in [RFC3066]\)) s
-5 305 M
-( The signal name is one of the following \(these are from [POSIX]\)) s
-5 283 M
-( ABRT) s
-5 272 M
-( ALRM) s
-5 261 M
-( FPE) s
-5 250 M
-( HUP) s
-5 239 M
-( ILL) s
-5 228 M
-( INT) s
-5 217 M
-( KILL) s
-5 206 M
-( PIPE) s
-5 195 M
-( QUIT) s
-5 184 M
-( SEGV) s
-5 173 M
-( TERM) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 13]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 14 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( USR1) s
-5 679 M
-( USR2) s
-5 657 M
-( Additional signal names MAY be sent in the format "sig-name@xyz",) s
-5 646 M
-( where `sig-name' and `xyz' may be anything a particular implementor) s
-5 635 M
-( wants \(except the `@' sign\). However, it is suggested that if a) s
-5 624 M
-( `configure' script is used, the non-standard signal names it finds be) s
-5 613 M
-( encoded as "[email protected]", where `SIG' is the signal name) s
-5 602 M
-( without the "SIG" prefix, and `xyz' be the host type, as determined) s
-5 591 M
-( by `config.guess'.) s
-5 569 M
-( The `error message' contains an additional explanation of the error) s
-5 558 M
-( message. The message may consist of multiple lines. The client) s
-5 547 M
-( software MAY display this message to the user. If this is done, the) s
-5 536 M
-( client software should take the precautions discussed in [SSH-ARCH].) s
-5 514 M
-(7. TCP/IP Port Forwarding) s
-5 492 M
-(7.1 Requesting Port Forwarding) s
-5 470 M
-( A party need not explicitly request forwardings from its own end to) s
-5 459 M
-( the other direction. However, if it wishes that connections to a) s
-5 448 M
-( port on the other side be forwarded to the local side, it must) s
-5 437 M
-( explicitly request this.) s
-5 404 M
-( byte SSH_MSG_GLOBAL_REQUEST) s
-5 393 M
-( string "tcpip-forward") s
-5 382 M
-( boolean want reply) s
-5 371 M
-( string address to bind \(e.g. "0.0.0.0"\)) s
-5 360 M
-( uint32 port number to bind) s
-5 338 M
-( `Address to bind' and `port number to bind' specify the IP address) s
-5 327 M
-( and port to which the socket to be listened is bound. The address) s
-5 316 M
-( should be "0.0.0.0" if connections are allowed from anywhere. \(Note) s
-5 305 M
-( that the client can still filter connections based on information) s
-5 294 M
-( passed in the open request.\)) s
-5 272 M
-( Implementations should only allow forwarding privileged ports if the) s
-5 261 M
-( user has been authenticated as a privileged user.) s
-5 239 M
-( Client implementations SHOULD reject these messages; they are) s
-5 228 M
-( normally only sent by the client.) s
-5 195 M
-( If a client passes 0 as port number to bind and has want reply TRUE) s
-5 184 M
-( then the server allocates the next available unprivileged port number) s
-5 173 M
-( and replies with the following message, otherwise there is no) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 14]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (14,15) 8
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 15 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( response specific data.) s
-5 657 M
-( byte SSH_MSG_GLOBAL_REQUEST_SUCCESS) s
-5 646 M
-( uint32 port that was bound on the server) s
-5 624 M
-( A port forwarding can be cancelled with the following message. Note) s
-5 613 M
-( that channel open requests may be received until a reply to this) s
-5 602 M
-( message is received.) s
-5 580 M
-( byte SSH_MSG_GLOBAL_REQUEST) s
-5 569 M
-( string "cancel-tcpip-forward") s
-5 558 M
-( boolean want reply) s
-5 547 M
-( string address_to_bind \(e.g. "127.0.0.1"\)) s
-5 536 M
-( uint32 port number to bind) s
-5 514 M
-( Client implementations SHOULD reject these messages; they are) s
-5 503 M
-( normally only sent by the client.) s
-5 481 M
-(7.2 TCP/IP Forwarding Channels) s
-5 459 M
-( When a connection comes to a port for which remote forwarding has) s
-5 448 M
-( been requested, a channel is opened to forward the port to the other) s
-5 437 M
-( side.) s
-5 415 M
-( byte SSH_MSG_CHANNEL_OPEN) s
-5 404 M
-( string "forwarded-tcpip") s
-5 393 M
-( uint32 sender channel) s
-5 382 M
-( uint32 initial window size) s
-5 371 M
-( uint32 maximum packet size) s
-5 360 M
-( string address that was connected) s
-5 349 M
-( uint32 port that was connected) s
-5 338 M
-( string originator IP address) s
-5 327 M
-( uint32 originator port) s
-5 305 M
-( Implementations MUST reject these messages unless they have) s
-5 294 M
-( previously requested a remote TCP/IP port forwarding with the given) s
-5 283 M
-( port number.) s
-5 261 M
-( When a connection comes to a locally forwarded TCP/IP port, the) s
-5 250 M
-( following packet is sent to the other side. Note that these messages) s
-5 239 M
-( MAY be sent also for ports for which no forwarding has been) s
-5 228 M
-( explicitly requested. The receiving side must decide whether to) s
-5 217 M
-( allow the forwarding.) s
-5 195 M
-( byte SSH_MSG_CHANNEL_OPEN) s
-5 184 M
-( string "direct-tcpip") s
-5 173 M
-( uint32 sender channel) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 15]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 16 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( uint32 initial window size) s
-5 679 M
-( uint32 maximum packet size) s
-5 668 M
-( string host to connect) s
-5 657 M
-( uint32 port to connect) s
-5 646 M
-( string originator IP address) s
-5 635 M
-( uint32 originator port) s
-5 613 M
-( `Host to connect' and `port to connect' specify the TCP/IP host and) s
-5 602 M
-( port where the recipient should connect the channel. `Host to) s
-5 591 M
-( connect' may be either a domain name or a numeric IP address.) s
-5 569 M
-( `Originator IP address' is the numeric IP address of the machine) s
-5 558 M
-( where the connection request comes from, and `originator port' is the) s
-5 547 M
-( port on the originator host from where the connection came from.) s
-5 525 M
-( Forwarded TCP/IP channels are independent of any sessions, and) s
-5 514 M
-( closing a session channel does not in any way imply that forwarded) s
-5 503 M
-( connections should be closed.) s
-5 481 M
-( Client implementations SHOULD reject direct TCP/IP open requests for) s
-5 470 M
-( security reasons.) s
-5 448 M
-(8. Encoding of Terminal Modes) s
-5 426 M
-( Terminal modes \(as passed in a pty request\) are encoded into a byte) s
-5 415 M
-( stream. It is intended that the coding be portable across different) s
-5 404 M
-( environments.) s
-5 382 M
-( The tty mode description is a stream of bytes. The stream consists) s
-5 371 M
-( of opcode-argument pairs. It is terminated by opcode TTY_OP_END \(0\).) s
-5 360 M
-( Opcodes 1 to 159 have a single uint32 argument. Opcodes 160 to 255) s
-5 349 M
-( are not yet defined, and cause parsing to stop \(they should only be) s
-5 338 M
-( used after any other data\).) s
-5 316 M
-( The client SHOULD put in the stream any modes it knows about, and the) s
-5 305 M
-( server MAY ignore any modes it does not know about. This allows some) s
-5 294 M
-( degree of machine-independence, at least between systems that use a) s
-5 283 M
-( POSIX-like tty interface. The protocol can support other systems as) s
-5 272 M
-( well, but the client may need to fill reasonable values for a number) s
-5 261 M
-( of parameters so the server pty gets set to a reasonable mode \(the) s
-5 250 M
-( server leaves all unspecified mode bits in their default values, and) s
-5 239 M
-( only some combinations make sense\).) s
-5 217 M
-( The following opcodes have been defined. The naming of opcodes) s
-5 206 M
-( mostly follows the POSIX terminal mode flags.) s
-5 184 M
-( 0 TTY_OP_END Indicates end of options.) s
-5 173 M
-( 1 VINTR Interrupt character; 255 if none. Similarly for the) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 16]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (16,17) 9
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 17 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( other characters. Not all of these characters are) s
-5 679 M
-( supported on all systems.) s
-5 668 M
-( 2 VQUIT The quit character \(sends SIGQUIT signal on POSIX) s
-5 657 M
-( systems\).) s
-5 646 M
-( 3 VERASE Erase the character to left of the cursor.) s
-5 635 M
-( 4 VKILL Kill the current input line.) s
-5 624 M
-( 5 VEOF End-of-file character \(sends EOF from the terminal\).) s
-5 613 M
-( 6 VEOL End-of-line character in addition to carriage return) s
-5 602 M
-( and/or linefeed.) s
-5 591 M
-( 7 VEOL2 Additional end-of-line character.) s
-5 580 M
-( 8 VSTART Continues paused output \(normally control-Q\).) s
-5 569 M
-( 9 VSTOP Pauses output \(normally control-S\).) s
-5 558 M
-( 10 VSUSP Suspends the current program.) s
-5 547 M
-( 11 VDSUSP Another suspend character.) s
-5 536 M
-( 12 VREPRINT Reprints the current input line.) s
-5 525 M
-( 13 VWERASE Erases a word left of cursor.) s
-5 514 M
-( 14 VLNEXT Enter the next character typed literally, even if it) s
-5 503 M
-( is a special character) s
-5 492 M
-( 15 VFLUSH Character to flush output.) s
-5 481 M
-( 16 VSWTCH Switch to a different shell layer.) s
-5 470 M
-( 17 VSTATUS Prints system status line \(load, command, pid etc\).) s
-5 459 M
-( 18 VDISCARD Toggles the flushing of terminal output.) s
-5 448 M
-( 30 IGNPAR The ignore parity flag. The parameter SHOULD be 0 if) s
-5 437 M
-( this flag is FALSE set, and 1 if it is TRUE.) s
-5 426 M
-( 31 PARMRK Mark parity and framing errors.) s
-5 415 M
-( 32 INPCK Enable checking of parity errors.) s
-5 404 M
-( 33 ISTRIP Strip 8th bit off characters.) s
-5 393 M
-( 34 INLCR Map NL into CR on input.) s
-5 382 M
-( 35 IGNCR Ignore CR on input.) s
-5 371 M
-( 36 ICRNL Map CR to NL on input.) s
-5 360 M
-( 37 IUCLC Translate uppercase characters to lowercase.) s
-5 349 M
-( 38 IXON Enable output flow control.) s
-5 338 M
-( 39 IXANY Any char will restart after stop.) s
-5 327 M
-( 40 IXOFF Enable input flow control.) s
-5 316 M
-( 41 IMAXBEL Ring bell on input queue full.) s
-5 305 M
-( 50 ISIG Enable signals INTR, QUIT, [D]SUSP.) s
-5 294 M
-( 51 ICANON Canonicalize input lines.) s
-5 283 M
-( 52 XCASE Enable input and output of uppercase characters by) s
-5 272 M
-( preceding their lowercase equivalents with `\\'.) s
-5 261 M
-( 53 ECHO Enable echoing.) s
-5 250 M
-( 54 ECHOE Visually erase chars.) s
-5 239 M
-( 55 ECHOK Kill character discards current line.) s
-5 228 M
-( 56 ECHONL Echo NL even if ECHO is off.) s
-5 217 M
-( 57 NOFLSH Don't flush after interrupt.) s
-5 206 M
-( 58 TOSTOP Stop background jobs from output.) s
-5 195 M
-( 59 IEXTEN Enable extensions.) s
-5 184 M
-( 60 ECHOCTL Echo control characters as ^\(Char\).) s
-5 173 M
-( 61 ECHOKE Visual erase for line kill.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 17]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 18 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( 62 PENDIN Retype pending input.) s
-5 679 M
-( 70 OPOST Enable output processing.) s
-5 668 M
-( 71 OLCUC Convert lowercase to uppercase.) s
-5 657 M
-( 72 ONLCR Map NL to CR-NL.) s
-5 646 M
-( 73 OCRNL Translate carriage return to newline \(output\).) s
-5 635 M
-( 74 ONOCR Translate newline to carriage return-newline) s
-5 624 M
-( \(output\).) s
-5 613 M
-( 75 ONLRET Newline performs a carriage return \(output\).) s
-5 602 M
-( 90 CS7 7 bit mode.) s
-5 591 M
-( 91 CS8 8 bit mode.) s
-5 580 M
-( 92 PARENB Parity enable.) s
-5 569 M
-( 93 PARODD Odd parity, else even.) s
-5 547 M
-( 128 TTY_OP_ISPEED Specifies the input baud rate in bits per second.) s
-5 536 M
-( 129 TTY_OP_OSPEED Specifies the output baud rate in bits per second.) s
-5 503 M
-(9. Summary of Message Numbers) s
-5 481 M
-( #define SSH_MSG_GLOBAL_REQUEST 80) s
-5 470 M
-( #define SSH_MSG_REQUEST_SUCCESS 81) s
-5 459 M
-( #define SSH_MSG_REQUEST_FAILURE 82) s
-5 448 M
-( #define SSH_MSG_CHANNEL_OPEN 90) s
-5 437 M
-( #define SSH_MSG_CHANNEL_OPEN_CONFIRMATION 91) s
-5 426 M
-( #define SSH_MSG_CHANNEL_OPEN_FAILURE 92) s
-5 415 M
-( #define SSH_MSG_CHANNEL_WINDOW_ADJUST 93) s
-5 404 M
-( #define SSH_MSG_CHANNEL_DATA 94) s
-5 393 M
-( #define SSH_MSG_CHANNEL_EXTENDED_DATA 95) s
-5 382 M
-( #define SSH_MSG_CHANNEL_EOF 96) s
-5 371 M
-( #define SSH_MSG_CHANNEL_CLOSE 97) s
-5 360 M
-( #define SSH_MSG_CHANNEL_REQUEST 98) s
-5 349 M
-( #define SSH_MSG_CHANNEL_SUCCESS 99) s
-5 338 M
-( #define SSH_MSG_CHANNEL_FAILURE 100) s
-5 305 M
-(10. Security Considerations) s
-5 283 M
-( This protocol is assumed to run on top of a secure, authenticated) s
-5 272 M
-( transport. User authentication and protection against network-level) s
-5 261 M
-( attacks are assumed to be provided by the underlying protocols.) s
-5 239 M
-( It is RECOMMENDED that implementations disable all the potentially) s
-5 228 M
-( dangerous features \(e.g. agent forwarding, X11 forwarding, and TCP/IP) s
-5 217 M
-( forwarding\) if the host key has changed.) s
-5 195 M
-( Full security considerations for this protocol are provided in) s
-5 184 M
-( Section 8 of [SSH-ARCH]) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 18]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (18,19) 10
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 19 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-(11. iana cONSiderations) s
-5 668 M
-( This document is part of a set, the IANA considerations for the SSH) s
-5 657 M
-( protocol as defined in [SSH-ARCH], [SSH-TRANS], [SSH-USERAUTH],) s
-5 646 M
-( [SSH-CONNECT] are detailed in [SSH-NUMBERS].) s
-5 624 M
-(12. Intellectual Property) s
-5 602 M
-( The IETF takes no position regarding the validity or scope of any) s
-5 591 M
-( intellectual property or other rights that might be claimed to) s
-5 580 M
-( pertain to the implementation or use of the technology described in) s
-5 569 M
-( this document or the extent to which any license under such rights) s
-5 558 M
-( might or might not be available; neither does it represent that it) s
-5 547 M
-( has made any effort to identify any such rights. Information on the) s
-5 536 M
-( IETF's procedures with respect to rights in standards-track and) s
-5 525 M
-( standards-related documentation can be found in BCP-11. Copies of) s
-5 514 M
-( claims of rights made available for publication and any assurances of) s
-5 503 M
-( licenses to be made available, or the result of an attempt made to) s
-5 492 M
-( obtain a general license or permission for the use of such) s
-5 481 M
-( proprietary rights by implementers or users of this specification can) s
-5 470 M
-( be obtained from the IETF Secretariat.) s
-5 448 M
-( The IETF has been notified of intellectual property rights claimed in) s
-5 437 M
-( regard to some or all of the specification contained in this) s
-5 426 M
-( document. For more information consult the online list of claimed) s
-5 415 M
-( rights.) s
-5 393 M
-(Normative References) s
-5 371 M
-( [SSH-ARCH]) s
-5 360 M
-( Ylonen, T., "SSH Protocol Architecture", I-D) s
-5 349 M
-( draft-ietf-architecture-15.txt, Oct 2003.) s
-5 327 M
-( [SSH-TRANS]) s
-5 316 M
-( Ylonen, T., "SSH Transport Layer Protocol", I-D) s
-5 305 M
-( draft-ietf-transport-17.txt, Oct 2003.) s
-5 283 M
-( [SSH-USERAUTH]) s
-5 272 M
-( Ylonen, T., "SSH Authentication Protocol", I-D) s
-5 261 M
-( draft-ietf-userauth-18.txt, Oct 2003.) s
-5 239 M
-( [SSH-CONNECT]) s
-5 228 M
-( Ylonen, T., "SSH Connection Protocol", I-D) s
-5 217 M
-( draft-ietf-connect-18.txt, Oct 2003.) s
-5 195 M
-( [SSH-NUMBERS]) s
-5 184 M
-( Lehtinen, S. and D. Moffat, "SSH Protocol Assigned) s
-5 173 M
-( Numbers", I-D draft-ietf-secsh-assignednumbers-05.txt, Oct) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 19]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 20 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( 2003.) s
-5 668 M
-( [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate) s
-5 657 M
-( Requirement Levels", BCP 14, RFC 2119, March 1997.) s
-5 635 M
-(Informative References) s
-5 613 M
-( [RFC3066] Alvestrand, H., "Tags for the Identification of) s
-5 602 M
-( Languages", BCP 47, RFC 3066, January 2001.) s
-5 580 M
-( [RFC1884] Hinden, R. and S. Deering, "IP Version 6 Addressing) s
-5 569 M
-( Architecture", RFC 1884, December 1995.) s
-5 547 M
-( [RFC2279] Yergeau, F., "UTF-8, a transformation format of ISO) s
-5 536 M
-( 10646", RFC 2279, January 1998.) s
-5 514 M
-( [SCHEIFLER]) s
-5 503 M
-( Scheifler, R., "X Window System : The Complete Reference) s
-5 492 M
-( to Xlib, X Protocol, Icccm, Xlfd, 3rd edition.", Digital) s
-5 481 M
-( Press ISBN 1555580882, Feburary 1992.) s
-5 459 M
-( [POSIX] ISO/IEC, 9945-1., "Information technology -- Portable) s
-5 448 M
-( Operating System Interface \(POSIX\)-Part 1: System) s
-5 437 M
-( Application Program Interface \(API\) C Language", ANSI/IEE) s
-5 426 M
-( Std 1003.1, July 1996.) s
-5 393 M
-(Authors' Addresses) s
-5 371 M
-( Tatu Ylonen) s
-5 360 M
-( SSH Communications Security Corp) s
-5 349 M
-( Fredrikinkatu 42) s
-5 338 M
-( HELSINKI FIN-00100) s
-5 327 M
-( Finland) s
-5 305 M
-( EMail: [email protected]) s
-5 272 M
-( Darren J. Moffat \(editor\)) s
-5 261 M
-( Sun Microsystems, Inc) s
-5 250 M
-( 17 Network Circle) s
-5 239 M
-( Menlo Park CA 94025) s
-5 228 M
-( USA) s
-5 206 M
-( EMail: [email protected]) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 20]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (20,21) 11
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 21 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-(Intellectual Property Statement) s
-5 668 M
-( The IETF takes no position regarding the validity or scope of any) s
-5 657 M
-( intellectual property or other rights that might be claimed to) s
-5 646 M
-( pertain to the implementation or use of the technology described in) s
-5 635 M
-( this document or the extent to which any license under such rights) s
-5 624 M
-( might or might not be available; neither does it represent that it) s
-5 613 M
-( has made any effort to identify any such rights. Information on the) s
-5 602 M
-( IETF's procedures with respect to rights in standards-track and) s
-5 591 M
-( standards-related documentation can be found in BCP-11. Copies of) s
-5 580 M
-( claims of rights made available for publication and any assurances of) s
-5 569 M
-( licenses to be made available, or the result of an attempt made to) s
-5 558 M
-( obtain a general license or permission for the use of such) s
-5 547 M
-( proprietary rights by implementors or users of this specification can) s
-5 536 M
-( be obtained from the IETF Secretariat.) s
-5 514 M
-( The IETF invites any interested party to bring to its attention any) s
-5 503 M
-( copyrights, patents or patent applications, or other proprietary) s
-5 492 M
-( rights which may cover technology that may be required to practice) s
-5 481 M
-( this standard. Please address the information to the IETF Executive) s
-5 470 M
-( Director.) s
-5 448 M
-( The IETF has been notified of intellectual property rights claimed in) s
-5 437 M
-( regard to some or all of the specification contained in this) s
-5 426 M
-( document. For more information consult the online list of claimed) s
-5 415 M
-( rights.) s
-5 382 M
-(Full Copyright Statement) s
-5 360 M
-( Copyright \(C\) The Internet Society \(2003\). All Rights Reserved.) s
-5 338 M
-( This document and translations of it may be copied and furnished to) s
-5 327 M
-( others, and derivative works that comment on or otherwise explain it) s
-5 316 M
-( or assist in its implementation may be prepared, copied, published) s
-5 305 M
-( and distributed, in whole or in part, without restriction of any) s
-5 294 M
-( kind, provided that the above copyright notice and this paragraph are) s
-5 283 M
-( included on all such copies and derivative works. However, this) s
-5 272 M
-( document itself may not be modified in any way, such as by removing) s
-5 261 M
-( the copyright notice or references to the Internet Society or other) s
-5 250 M
-( Internet organizations, except as needed for the purpose of) s
-5 239 M
-( developing Internet standards in which case the procedures for) s
-5 228 M
-( copyrights defined in the Internet Standards process must be) s
-5 217 M
-( followed, or as required to translate it into languages other than) s
-5 206 M
-( English.) s
-5 184 M
-( The limited permissions granted above are perpetual and will not be) s
-5 173 M
-( revoked by the Internet Society or its successors or assignees.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 21]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 22 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( This document and the information contained herein is provided on an) s
-5 679 M
-( "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING) s
-5 668 M
-( TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING) s
-5 657 M
-( BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION) s
-5 646 M
-( HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF) s
-5 635 M
-( MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.) s
-5 602 M
-(Acknowledgment) s
-5 580 M
-( Funding for the RFC Editor function is currently provided by the) s
-5 569 M
-( Internet Society.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 22]) s
-_R
-S
-PStoPSsaved restore
-%%Trailer
-%%Pages: 22
-%%DocumentNeededResources: font Courier-Bold Courier
-%%EOF
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-connect-18.txt b/lib/ssh/doc/standard/draft-ietf-secsh-connect-18.txt
deleted file mode 100644
index 1cb8ad6409..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-connect-18.txt
+++ /dev/null
@@ -1,1232 +0,0 @@
-
-
-
-Network Working Group T. Ylonen
-Internet-Draft SSH Communications Security Corp
-Expires: March 31, 2004 D. Moffat, Editor, Ed.
- Sun Microsystems, Inc
- Oct 2003
-
-
- SSH Connection Protocol
- draft-ietf-secsh-connect-18.txt
-
-Status of this Memo
-
- This document is an Internet-Draft and is in full conformance with
- all provisions of Section 10 of RFC2026.
-
- Internet-Drafts are working documents of the Internet Engineering
- Task Force (IETF), its areas, and its working groups. Note that other
- groups may also distribute working documents as Internet-Drafts.
-
- Internet-Drafts are draft documents valid for a maximum of six months
- and may be updated, replaced, or obsoleted by other documents at any
- time. It is inappropriate to use Internet-Drafts as reference
- material or to cite them other than as "work in progress."
-
- The list of current Internet-Drafts can be accessed at http://
- www.ietf.org/ietf/1id-abstracts.txt.
-
- The list of Internet-Draft Shadow Directories can be accessed at
- http://www.ietf.org/shadow.html.
-
- This Internet-Draft will expire on March 31, 2004.
-
-Copyright Notice
-
- Copyright (C) The Internet Society (2003). All Rights Reserved.
-
-Abstract
-
- SSH is a protocol for secure remote login and other secure network
- services over an insecure network.
-
- This document describes the SSH Connection Protocol. It provides
- interactive login sessions, remote execution of commands, forwarded
- TCP/IP connections, and forwarded X11 connections. All of these
- channels are multiplexed into a single encrypted tunnel.
-
- The SSH Connection Protocol has been designed to run on top of the
- SSH transport layer and user authentication protocols.
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 1]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
-Table of Contents
-
- 1. Contributors . . . . . . . . . . . . . . . . . . . . . . . . 3
- 2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3
- 3. Conventions Used in This Document . . . . . . . . . . . . . 3
- 4. Global Requests . . . . . . . . . . . . . . . . . . . . . . 3
- 5. Channel Mechanism . . . . . . . . . . . . . . . . . . . . . 4
- 5.1 Opening a Channel . . . . . . . . . . . . . . . . . . . . . 4
- 5.2 Data Transfer . . . . . . . . . . . . . . . . . . . . . . . 5
- 5.3 Closing a Channel . . . . . . . . . . . . . . . . . . . . . 6
- 5.4 Channel-Specific Requests . . . . . . . . . . . . . . . . . 7
- 6. Interactive Sessions . . . . . . . . . . . . . . . . . . . . 8
- 6.1 Opening a Session . . . . . . . . . . . . . . . . . . . . . 8
- 6.2 Requesting a Pseudo-Terminal . . . . . . . . . . . . . . . . 8
- 6.3 X11 Forwarding . . . . . . . . . . . . . . . . . . . . . . . 9
- 6.3.1 Requesting X11 Forwarding . . . . . . . . . . . . . . . . . 9
- 6.3.2 X11 Channels . . . . . . . . . . . . . . . . . . . . . . . . 10
- 6.4 Environment Variable Passing . . . . . . . . . . . . . . . . 10
- 6.5 Starting a Shell or a Command . . . . . . . . . . . . . . . 10
- 6.6 Session Data Transfer . . . . . . . . . . . . . . . . . . . 11
- 6.7 Window Dimension Change Message . . . . . . . . . . . . . . 12
- 6.8 Local Flow Control . . . . . . . . . . . . . . . . . . . . . 12
- 6.9 Signals . . . . . . . . . . . . . . . . . . . . . . . . . . 12
- 6.10 Returning Exit Status . . . . . . . . . . . . . . . . . . . 13
- 7. TCP/IP Port Forwarding . . . . . . . . . . . . . . . . . . . 14
- 7.1 Requesting Port Forwarding . . . . . . . . . . . . . . . . . 14
- 7.2 TCP/IP Forwarding Channels . . . . . . . . . . . . . . . . . 15
- 8. Encoding of Terminal Modes . . . . . . . . . . . . . . . . . 16
- 9. Summary of Message Numbers . . . . . . . . . . . . . . . . . 18
- 10. Security Considerations . . . . . . . . . . . . . . . . . . 18
- 11. iana cONSiderations . . . . . . . . . . . . . . . . . . . . 19
- 12. Intellectual Property . . . . . . . . . . . . . . . . . . . 19
- Normative References . . . . . . . . . . . . . . . . . . . . 19
- Informative References . . . . . . . . . . . . . . . . . . . 20
- Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 20
- Intellectual Property and Copyright Statements . . . . . . . 21
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 2]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
-1. Contributors
-
- The major original contributors of this document were: Tatu Ylonen,
- Tero Kivinen, Timo J. Rinne, Sami Lehtinen (all of SSH Communications
- Security Corp), and Markku-Juhani O. Saarinen (University of
- Jyvaskyla)
-
- The document editor is: [email protected]. Comments on this
- internet draft should be sent to the IETF SECSH working group,
- details at: http://ietf.org/html.charters/secsh-charter.html
-
-2. Introduction
-
- The SSH Connection Protocol has been designed to run on top of the
- SSH transport layer and user authentication protocols. It provides
- interactive login sessions, remote execution of commands, forwarded
- TCP/IP connections, and forwarded X11 connections. The service name
- for this protocol is "ssh-connection".
-
- This document should be read only after reading the SSH architecture
- document [SSH-ARCH]. This document freely uses terminology and
- notation from the architecture document without reference or further
- explanation.
-
-3. Conventions Used in This Document
-
- The keywords "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT",
- and "MAY" that appear in this document are to be interpreted as
- described in [RFC2119].
-
- The used data types and terminology are specified in the architecture
- document [SSH-ARCH].
-
- The architecture document also discusses the algorithm naming
- conventions that MUST be used with the SSH protocols.
-
-4. Global Requests
-
- There are several kinds of requests that affect the state of the
- remote end "globally", independent of any channels. An example is a
- request to start TCP/IP forwarding for a specific port. All such
- requests use the following format.
-
- byte SSH_MSG_GLOBAL_REQUEST
- string request name (restricted to US-ASCII)
- boolean want reply
- ... request-specific data follows
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 3]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- Request names follow the DNS extensibility naming convention outlined
- in [SSH-ARCH].
-
- The recipient will respond to this message with
- SSH_MSG_REQUEST_SUCCESS or SSH_MSG_REQUEST_FAILURE if `want reply' is
- TRUE.
-
- byte SSH_MSG_REQUEST_SUCCESS
- ..... response specific data
-
- Usually the response specific data is non-existent.
-
- If the recipient does not recognize or support the request, it simply
- responds with SSH_MSG_REQUEST_FAILURE.
-
- byte SSH_MSG_REQUEST_FAILURE
-
-
-5. Channel Mechanism
-
- All terminal sessions, forwarded connections, etc. are channels.
- Either side may open a channel. Multiple channels are multiplexed
- into a single connection.
-
- Channels are identified by numbers at each end. The number referring
- to a channel may be different on each side. Requests to open a
- channel contain the sender's channel number. Any other
- channel-related messages contain the recipient's channel number for
- the channel.
-
- Channels are flow-controlled. No data may be sent to a channel until
- a message is received to indicate that window space is available.
-
-5.1 Opening a Channel
-
- When either side wishes to open a new channel, it allocates a local
- number for the channel. It then sends the following message to the
- other side, and includes the local channel number and initial window
- size in the message.
-
- byte SSH_MSG_CHANNEL_OPEN
- string channel type (restricted to US-ASCII)
- uint32 sender channel
- uint32 initial window size
- uint32 maximum packet size
- ... channel type specific data follows
-
- The channel type is a name as described in the SSH architecture
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 4]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- document, with similar extension mechanisms. `sender channel' is a
- local identifier for the channel used by the sender of this message.
- `initial window size' specifies how many bytes of channel data can be
- sent to the sender of this message without adjusting the window.
- `Maximum packet size' specifies the maximum size of an individual
- data packet that can be sent to the sender (for example, one might
- want to use smaller packets for interactive connections to get better
- interactive response on slow links).
-
- The remote side then decides whether it can open the channel, and
- responds with either
-
- byte SSH_MSG_CHANNEL_OPEN_CONFIRMATION
- uint32 recipient channel
- uint32 sender channel
- uint32 initial window size
- uint32 maximum packet size
- ... channel type specific data follows
-
- where `recipient channel' is the channel number given in the original
- open request, and `sender channel' is the channel number allocated by
- the other side, or
-
- byte SSH_MSG_CHANNEL_OPEN_FAILURE
- uint32 recipient channel
- uint32 reason code
- string additional textual information (ISO-10646 UTF-8 [RFC2279])
- string language tag (as defined in [RFC3066])
-
- If the recipient of the SSH_MSG_CHANNEL_OPEN message does not support
- the specified channel type, it simply responds with
- SSH_MSG_CHANNEL_OPEN_FAILURE. The client MAY show the additional
- information to the user. If this is done, the client software should
- take the precautions discussed in [SSH-ARCH].
-
- The following reason codes are defined:
-
- #define SSH_OPEN_ADMINISTRATIVELY_PROHIBITED 1
- #define SSH_OPEN_CONNECT_FAILED 2
- #define SSH_OPEN_UNKNOWN_CHANNEL_TYPE 3
- #define SSH_OPEN_RESOURCE_SHORTAGE 4
-
-
-5.2 Data Transfer
-
- The window size specifies how many bytes the other party can send
- before it must wait for the window to be adjusted. Both parties use
- the following message to adjust the window.
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 5]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- byte SSH_MSG_CHANNEL_WINDOW_ADJUST
- uint32 recipient channel
- uint32 bytes to add
-
- After receiving this message, the recipient MAY send the given number
- of bytes more than it was previously allowed to send; the window size
- is incremented.
-
- Data transfer is done with messages of the following type.
-
- byte SSH_MSG_CHANNEL_DATA
- uint32 recipient channel
- string data
-
- The maximum amount of data allowed is the current window size. The
- window size is decremented by the amount of data sent. Both parties
- MAY ignore all extra data sent after the allowed window is empty.
-
- Additionally, some channels can transfer several types of data. An
- example of this is stderr data from interactive sessions. Such data
- can be passed with SSH_MSG_CHANNEL_EXTENDED_DATA messages, where a
- separate integer specifies the type of the data. The available types
- and their interpretation depend on the type of the channel.
-
- byte SSH_MSG_CHANNEL_EXTENDED_DATA
- uint32 recipient_channel
- uint32 data_type_code
- string data
-
- Data sent with these messages consumes the same window as ordinary
- data.
-
- Currently, only the following type is defined.
-
- #define SSH_EXTENDED_DATA_STDERR 1
-
-
-5.3 Closing a Channel
-
- When a party will no longer send more data to a channel, it SHOULD
- send SSH_MSG_CHANNEL_EOF.
-
- byte SSH_MSG_CHANNEL_EOF
- uint32 recipient_channel
-
- No explicit response is sent to this message; however, the
- application may send EOF to whatever is at the other end of the
- channel. Note that the channel remains open after this message, and
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 6]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- more data may still be sent in the other direction. This message
- does not consume window space and can be sent even if no window space
- is available.
-
- When either party wishes to terminate the channel, it sends
- SSH_MSG_CHANNEL_CLOSE. Upon receiving this message, a party MUST
- send back a SSH_MSG_CHANNEL_CLOSE unless it has already sent this
- message for the channel. The channel is considered closed for a
- party when it has both sent and received SSH_MSG_CHANNEL_CLOSE, and
- the party may then reuse the channel number. A party MAY send
- SSH_MSG_CHANNEL_CLOSE without having sent or received
- SSH_MSG_CHANNEL_EOF.
-
- byte SSH_MSG_CHANNEL_CLOSE
- uint32 recipient_channel
-
- This message does not consume window space and can be sent even if no
- window space is available.
-
- It is recommended that any data sent before this message is delivered
- to the actual destination, if possible.
-
-5.4 Channel-Specific Requests
-
- Many channel types have extensions that are specific to that
- particular channel type. An example is requesting a pty (pseudo
- terminal) for an interactive session.
-
- All channel-specific requests use the following format.
-
- byte SSH_MSG_CHANNEL_REQUEST
- uint32 recipient channel
- string request type (restricted to US-ASCII)
- boolean want reply
- ... type-specific data
-
- If want reply is FALSE, no response will be sent to the request.
- Otherwise, the recipient responds with either SSH_MSG_CHANNEL_SUCCESS
- or SSH_MSG_CHANNEL_FAILURE, or request-specific continuation
- messages. If the request is not recognized or is not supported for
- the channel, SSH_MSG_CHANNEL_FAILURE is returned.
-
- This message does not consume window space and can be sent even if no
- window space is available. Request types are local to each channel
- type.
-
- The client is allowed to send further messages without waiting for
- the response to the request.
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 7]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- request type names follow the DNS extensibility naming convention
- outlined in [SSH-ARCH]
-
- byte SSH_MSG_CHANNEL_SUCCESS
- uint32 recipient_channel
-
-
- byte SSH_MSG_CHANNEL_FAILURE
- uint32 recipient_channel
-
- These messages do not consume window space and can be sent even if no
- window space is available.
-
-6. Interactive Sessions
-
- A session is a remote execution of a program. The program may be a
- shell, an application, a system command, or some built-in subsystem.
- It may or may not have a tty, and may or may not involve X11
- forwarding. Multiple sessions can be active simultaneously.
-
-6.1 Opening a Session
-
- A session is started by sending the following message.
-
- byte SSH_MSG_CHANNEL_OPEN
- string "session"
- uint32 sender channel
- uint32 initial window size
- uint32 maximum packet size
-
- Client implementations SHOULD reject any session channel open
- requests to make it more difficult for a corrupt server to attack the
- client.
-
-6.2 Requesting a Pseudo-Terminal
-
- A pseudo-terminal can be allocated for the session by sending the
- following message.
-
- byte SSH_MSG_CHANNEL_REQUEST
- uint32 recipient_channel
- string "pty-req"
- boolean want_reply
- string TERM environment variable value (e.g., vt100)
- uint32 terminal width, characters (e.g., 80)
- uint32 terminal height, rows (e.g., 24)
- uint32 terminal width, pixels (e.g., 640)
- uint32 terminal height, pixels (e.g., 480)
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 8]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- string encoded terminal modes
-
- The encoding of terminal modes is described in Section Encoding of
- Terminal Modes (Section 8). Zero dimension parameters MUST be
- ignored. The character/row dimensions override the pixel dimensions
- (when nonzero). Pixel dimensions refer to the drawable area of the
- window.
-
- The dimension parameters are only informational.
-
- The client SHOULD ignore pty requests.
-
-6.3 X11 Forwarding
-
-6.3.1 Requesting X11 Forwarding
-
- X11 forwarding may be requested for a session by sending
-
- byte SSH_MSG_CHANNEL_REQUEST
- uint32 recipient channel
- string "x11-req"
- boolean want reply
- boolean single connection
- string x11 authentication protocol
- string x11 authentication cookie
- uint32 x11 screen number
-
- It is recommended that the authentication cookie that is sent be a
- fake, random cookie, and that the cookie is checked and replaced by
- the real cookie when a connection request is received.
-
- X11 connection forwarding should stop when the session channel is
- closed; however, already opened forwardings should not be
- automatically closed when the session channel is closed.
-
- If `single connection' is TRUE, only a single connection should be
- forwarded. No more connections will be forwarded after the first, or
- after the session channel has been closed.
-
- The "x11 authentication protocol" is the name of the X11
- authentication method used, e.g. "MIT-MAGIC-COOKIE-1".
-
- The x11 authentication cookie MUST be hexadecimal encoded.
-
- X Protocol is documented in [SCHEIFLER].
-
-
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 9]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
-6.3.2 X11 Channels
-
- X11 channels are opened with a channel open request. The resulting
- channels are independent of the session, and closing the session
- channel does not close the forwarded X11 channels.
-
- byte SSH_MSG_CHANNEL_OPEN
- string "x11"
- uint32 sender channel
- uint32 initial window size
- uint32 maximum packet size
- string originator address (e.g. "192.168.7.38")
- uint32 originator port
-
- The recipient should respond with SSH_MSG_CHANNEL_OPEN_CONFIRMATION
- or SSH_MSG_CHANNEL_OPEN_FAILURE.
-
- Implementations MUST reject any X11 channel open requests if they
- have not requested X11 forwarding.
-
-6.4 Environment Variable Passing
-
- Environment variables may be passed to the shell/command to be
- started later. Uncontrolled setting of environment variables in a
- privileged process can be a security hazard. It is recommended that
- implementations either maintain a list of allowable variable names or
- only set environment variables after the server process has dropped
- sufficient privileges.
-
- byte SSH_MSG_CHANNEL_REQUEST
- uint32 recipient channel
- string "env"
- boolean want reply
- string variable name
- string variable value
-
-
-6.5 Starting a Shell or a Command
-
- Once the session has been set up, a program is started at the remote
- end. The program can be a shell, an application program or a
- subsystem with a host-independent name. Only one of these requests
- can succeed per channel.
-
- byte SSH_MSG_CHANNEL_REQUEST
- uint32 recipient channel
- string "shell"
- boolean want reply
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 10]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- This message will request the user's default shell (typically defined
- in /etc/passwd in UNIX systems) to be started at the other end.
-
- byte SSH_MSG_CHANNEL_REQUEST
- uint32 recipient channel
- string "exec"
- boolean want reply
- string command
-
- This message will request the server to start the execution of the
- given command. The command string may contain a path. Normal
- precautions MUST be taken to prevent the execution of unauthorized
- commands.
-
- byte SSH_MSG_CHANNEL_REQUEST
- uint32 recipient channel
- string "subsystem"
- boolean want reply
- string subsystem name
-
- This last form executes a predefined subsystem. It is expected that
- these will include a general file transfer mechanism, and possibly
- other features. Implementations may also allow configuring more such
- mechanisms. As the user's shell is usually used to execute the
- subsystem, it is advisable for the subsystem protocol to have a
- "magic cookie" at the beginning of the protocol transaction to
- distinguish it from arbitrary output generated by shell
- initialization scripts etc. This spurious output from the shell may
- be filtered out either at the server or at the client.
-
- The server SHOULD not halt the execution of the protocol stack when
- starting a shell or a program. All input and output from these SHOULD
- be redirected to the channel or to the encrypted tunnel.
-
- It is RECOMMENDED to request and check the reply for these messages.
- The client SHOULD ignore these messages.
-
- Subsystem names follow the DNS extensibility naming convention
- outlined in [SSH-ARCH].
-
-6.6 Session Data Transfer
-
- Data transfer for a session is done using SSH_MSG_CHANNEL_DATA and
- SSH_MSG_CHANNEL_EXTENDED_DATA packets and the window mechanism. The
- extended data type SSH_EXTENDED_DATA_STDERR has been defined for
- stderr data.
-
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 11]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
-6.7 Window Dimension Change Message
-
- When the window (terminal) size changes on the client side, it MAY
- send a message to the other side to inform it of the new dimensions.
-
- byte SSH_MSG_CHANNEL_REQUEST
- uint32 recipient_channel
- string "window-change"
- boolean FALSE
- uint32 terminal width, columns
- uint32 terminal height, rows
- uint32 terminal width, pixels
- uint32 terminal height, pixels
-
- No response SHOULD be sent to this message.
-
-6.8 Local Flow Control
-
- On many systems, it is possible to determine if a pseudo-terminal is
- using control-S/control-Q flow control. When flow control is
- allowed, it is often desirable to do the flow control at the client
- end to speed up responses to user requests. This is facilitated by
- the following notification. Initially, the server is responsible for
- flow control. (Here, again, client means the side originating the
- session, and server means the other side.)
-
- The message below is used by the server to inform the client when it
- can or cannot perform flow control (control-S/control-Q processing).
- If `client can do' is TRUE, the client is allowed to do flow control
- using control-S and control-Q. The client MAY ignore this message.
-
- byte SSH_MSG_CHANNEL_REQUEST
- uint32 recipient channel
- string "xon-xoff"
- boolean FALSE
- boolean client can do
-
- No response is sent to this message.
-
-6.9 Signals
-
- A signal can be delivered to the remote process/service using the
- following message. Some systems may not implement signals, in which
- case they SHOULD ignore this message.
-
- byte SSH_MSG_CHANNEL_REQUEST
- uint32 recipient channel
- string "signal"
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 12]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- boolean FALSE
- string signal name without the "SIG" prefix.
-
- Signal names will be encoded as discussed in the "exit-signal"
- SSH_MSG_CHANNEL_REQUEST.
-
-6.10 Returning Exit Status
-
- When the command running at the other end terminates, the following
- message can be sent to return the exit status of the command.
- Returning the status is RECOMMENDED. No acknowledgment is sent for
- this message. The channel needs to be closed with
- SSH_MSG_CHANNEL_CLOSE after this message.
-
- The client MAY ignore these messages.
-
- byte SSH_MSG_CHANNEL_REQUEST
- uint32 recipient_channel
- string "exit-status"
- boolean FALSE
- uint32 exit_status
-
- The remote command may also terminate violently due to a signal.
- Such a condition can be indicated by the following message. A zero
- exit_status usually means that the command terminated successfully.
-
- byte SSH_MSG_CHANNEL_REQUEST
- uint32 recipient channel
- string "exit-signal"
- boolean FALSE
- string signal name without the "SIG" prefix.
- boolean core dumped
- string error message (ISO-10646 UTF-8)
- string language tag (as defined in [RFC3066])
-
- The signal name is one of the following (these are from [POSIX])
-
- ABRT
- ALRM
- FPE
- HUP
- ILL
- INT
- KILL
- PIPE
- QUIT
- SEGV
- TERM
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 13]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- USR1
- USR2
-
- Additional signal names MAY be sent in the format "sig-name@xyz",
- where `sig-name' and `xyz' may be anything a particular implementor
- wants (except the `@' sign). However, it is suggested that if a
- `configure' script is used, the non-standard signal names it finds be
- encoded as "[email protected]", where `SIG' is the signal name
- without the "SIG" prefix, and `xyz' be the host type, as determined
- by `config.guess'.
-
- The `error message' contains an additional explanation of the error
- message. The message may consist of multiple lines. The client
- software MAY display this message to the user. If this is done, the
- client software should take the precautions discussed in [SSH-ARCH].
-
-7. TCP/IP Port Forwarding
-
-7.1 Requesting Port Forwarding
-
- A party need not explicitly request forwardings from its own end to
- the other direction. However, if it wishes that connections to a
- port on the other side be forwarded to the local side, it must
- explicitly request this.
-
-
- byte SSH_MSG_GLOBAL_REQUEST
- string "tcpip-forward"
- boolean want reply
- string address to bind (e.g. "0.0.0.0")
- uint32 port number to bind
-
- `Address to bind' and `port number to bind' specify the IP address
- and port to which the socket to be listened is bound. The address
- should be "0.0.0.0" if connections are allowed from anywhere. (Note
- that the client can still filter connections based on information
- passed in the open request.)
-
- Implementations should only allow forwarding privileged ports if the
- user has been authenticated as a privileged user.
-
- Client implementations SHOULD reject these messages; they are
- normally only sent by the client.
-
-
- If a client passes 0 as port number to bind and has want reply TRUE
- then the server allocates the next available unprivileged port number
- and replies with the following message, otherwise there is no
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 14]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- response specific data.
-
-
- byte SSH_MSG_GLOBAL_REQUEST_SUCCESS
- uint32 port that was bound on the server
-
- A port forwarding can be cancelled with the following message. Note
- that channel open requests may be received until a reply to this
- message is received.
-
- byte SSH_MSG_GLOBAL_REQUEST
- string "cancel-tcpip-forward"
- boolean want reply
- string address_to_bind (e.g. "127.0.0.1")
- uint32 port number to bind
-
- Client implementations SHOULD reject these messages; they are
- normally only sent by the client.
-
-7.2 TCP/IP Forwarding Channels
-
- When a connection comes to a port for which remote forwarding has
- been requested, a channel is opened to forward the port to the other
- side.
-
- byte SSH_MSG_CHANNEL_OPEN
- string "forwarded-tcpip"
- uint32 sender channel
- uint32 initial window size
- uint32 maximum packet size
- string address that was connected
- uint32 port that was connected
- string originator IP address
- uint32 originator port
-
- Implementations MUST reject these messages unless they have
- previously requested a remote TCP/IP port forwarding with the given
- port number.
-
- When a connection comes to a locally forwarded TCP/IP port, the
- following packet is sent to the other side. Note that these messages
- MAY be sent also for ports for which no forwarding has been
- explicitly requested. The receiving side must decide whether to
- allow the forwarding.
-
- byte SSH_MSG_CHANNEL_OPEN
- string "direct-tcpip"
- uint32 sender channel
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 15]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- uint32 initial window size
- uint32 maximum packet size
- string host to connect
- uint32 port to connect
- string originator IP address
- uint32 originator port
-
- `Host to connect' and `port to connect' specify the TCP/IP host and
- port where the recipient should connect the channel. `Host to
- connect' may be either a domain name or a numeric IP address.
-
- `Originator IP address' is the numeric IP address of the machine
- where the connection request comes from, and `originator port' is the
- port on the originator host from where the connection came from.
-
- Forwarded TCP/IP channels are independent of any sessions, and
- closing a session channel does not in any way imply that forwarded
- connections should be closed.
-
- Client implementations SHOULD reject direct TCP/IP open requests for
- security reasons.
-
-8. Encoding of Terminal Modes
-
- Terminal modes (as passed in a pty request) are encoded into a byte
- stream. It is intended that the coding be portable across different
- environments.
-
- The tty mode description is a stream of bytes. The stream consists
- of opcode-argument pairs. It is terminated by opcode TTY_OP_END (0).
- Opcodes 1 to 159 have a single uint32 argument. Opcodes 160 to 255
- are not yet defined, and cause parsing to stop (they should only be
- used after any other data).
-
- The client SHOULD put in the stream any modes it knows about, and the
- server MAY ignore any modes it does not know about. This allows some
- degree of machine-independence, at least between systems that use a
- POSIX-like tty interface. The protocol can support other systems as
- well, but the client may need to fill reasonable values for a number
- of parameters so the server pty gets set to a reasonable mode (the
- server leaves all unspecified mode bits in their default values, and
- only some combinations make sense).
-
- The following opcodes have been defined. The naming of opcodes
- mostly follows the POSIX terminal mode flags.
-
- 0 TTY_OP_END Indicates end of options.
- 1 VINTR Interrupt character; 255 if none. Similarly for the
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 16]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- other characters. Not all of these characters are
- supported on all systems.
- 2 VQUIT The quit character (sends SIGQUIT signal on POSIX
- systems).
- 3 VERASE Erase the character to left of the cursor.
- 4 VKILL Kill the current input line.
- 5 VEOF End-of-file character (sends EOF from the terminal).
- 6 VEOL End-of-line character in addition to carriage return
- and/or linefeed.
- 7 VEOL2 Additional end-of-line character.
- 8 VSTART Continues paused output (normally control-Q).
- 9 VSTOP Pauses output (normally control-S).
- 10 VSUSP Suspends the current program.
- 11 VDSUSP Another suspend character.
- 12 VREPRINT Reprints the current input line.
- 13 VWERASE Erases a word left of cursor.
- 14 VLNEXT Enter the next character typed literally, even if it
- is a special character
- 15 VFLUSH Character to flush output.
- 16 VSWTCH Switch to a different shell layer.
- 17 VSTATUS Prints system status line (load, command, pid etc).
- 18 VDISCARD Toggles the flushing of terminal output.
- 30 IGNPAR The ignore parity flag. The parameter SHOULD be 0 if
- this flag is FALSE set, and 1 if it is TRUE.
- 31 PARMRK Mark parity and framing errors.
- 32 INPCK Enable checking of parity errors.
- 33 ISTRIP Strip 8th bit off characters.
- 34 INLCR Map NL into CR on input.
- 35 IGNCR Ignore CR on input.
- 36 ICRNL Map CR to NL on input.
- 37 IUCLC Translate uppercase characters to lowercase.
- 38 IXON Enable output flow control.
- 39 IXANY Any char will restart after stop.
- 40 IXOFF Enable input flow control.
- 41 IMAXBEL Ring bell on input queue full.
- 50 ISIG Enable signals INTR, QUIT, [D]SUSP.
- 51 ICANON Canonicalize input lines.
- 52 XCASE Enable input and output of uppercase characters by
- preceding their lowercase equivalents with `\'.
- 53 ECHO Enable echoing.
- 54 ECHOE Visually erase chars.
- 55 ECHOK Kill character discards current line.
- 56 ECHONL Echo NL even if ECHO is off.
- 57 NOFLSH Don't flush after interrupt.
- 58 TOSTOP Stop background jobs from output.
- 59 IEXTEN Enable extensions.
- 60 ECHOCTL Echo control characters as ^(Char).
- 61 ECHOKE Visual erase for line kill.
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 17]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- 62 PENDIN Retype pending input.
- 70 OPOST Enable output processing.
- 71 OLCUC Convert lowercase to uppercase.
- 72 ONLCR Map NL to CR-NL.
- 73 OCRNL Translate carriage return to newline (output).
- 74 ONOCR Translate newline to carriage return-newline
- (output).
- 75 ONLRET Newline performs a carriage return (output).
- 90 CS7 7 bit mode.
- 91 CS8 8 bit mode.
- 92 PARENB Parity enable.
- 93 PARODD Odd parity, else even.
-
- 128 TTY_OP_ISPEED Specifies the input baud rate in bits per second.
- 129 TTY_OP_OSPEED Specifies the output baud rate in bits per second.
-
-
-9. Summary of Message Numbers
-
- #define SSH_MSG_GLOBAL_REQUEST 80
- #define SSH_MSG_REQUEST_SUCCESS 81
- #define SSH_MSG_REQUEST_FAILURE 82
- #define SSH_MSG_CHANNEL_OPEN 90
- #define SSH_MSG_CHANNEL_OPEN_CONFIRMATION 91
- #define SSH_MSG_CHANNEL_OPEN_FAILURE 92
- #define SSH_MSG_CHANNEL_WINDOW_ADJUST 93
- #define SSH_MSG_CHANNEL_DATA 94
- #define SSH_MSG_CHANNEL_EXTENDED_DATA 95
- #define SSH_MSG_CHANNEL_EOF 96
- #define SSH_MSG_CHANNEL_CLOSE 97
- #define SSH_MSG_CHANNEL_REQUEST 98
- #define SSH_MSG_CHANNEL_SUCCESS 99
- #define SSH_MSG_CHANNEL_FAILURE 100
-
-
-10. Security Considerations
-
- This protocol is assumed to run on top of a secure, authenticated
- transport. User authentication and protection against network-level
- attacks are assumed to be provided by the underlying protocols.
-
- It is RECOMMENDED that implementations disable all the potentially
- dangerous features (e.g. agent forwarding, X11 forwarding, and TCP/IP
- forwarding) if the host key has changed.
-
- Full security considerations for this protocol are provided in
- Section 8 of [SSH-ARCH]
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 18]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
-11. iana cONSiderations
-
- This document is part of a set, the IANA considerations for the SSH
- protocol as defined in [SSH-ARCH], [SSH-TRANS], [SSH-USERAUTH],
- [SSH-CONNECT] are detailed in [SSH-NUMBERS].
-
-12. Intellectual Property
-
- The IETF takes no position regarding the validity or scope of any
- intellectual property or other rights that might be claimed to
- pertain to the implementation or use of the technology described in
- this document or the extent to which any license under such rights
- might or might not be available; neither does it represent that it
- has made any effort to identify any such rights. Information on the
- IETF's procedures with respect to rights in standards-track and
- standards-related documentation can be found in BCP-11. Copies of
- claims of rights made available for publication and any assurances of
- licenses to be made available, or the result of an attempt made to
- obtain a general license or permission for the use of such
- proprietary rights by implementers or users of this specification can
- be obtained from the IETF Secretariat.
-
- The IETF has been notified of intellectual property rights claimed in
- regard to some or all of the specification contained in this
- document. For more information consult the online list of claimed
- rights.
-
-Normative References
-
- [SSH-ARCH]
- Ylonen, T., "SSH Protocol Architecture", I-D
- draft-ietf-architecture-15.txt, Oct 2003.
-
- [SSH-TRANS]
- Ylonen, T., "SSH Transport Layer Protocol", I-D
- draft-ietf-transport-17.txt, Oct 2003.
-
- [SSH-USERAUTH]
- Ylonen, T., "SSH Authentication Protocol", I-D
- draft-ietf-userauth-18.txt, Oct 2003.
-
- [SSH-CONNECT]
- Ylonen, T., "SSH Connection Protocol", I-D
- draft-ietf-connect-18.txt, Oct 2003.
-
- [SSH-NUMBERS]
- Lehtinen, S. and D. Moffat, "SSH Protocol Assigned
- Numbers", I-D draft-ietf-secsh-assignednumbers-05.txt, Oct
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 19]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- 2003.
-
- [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
- Requirement Levels", BCP 14, RFC 2119, March 1997.
-
-Informative References
-
- [RFC3066] Alvestrand, H., "Tags for the Identification of
- Languages", BCP 47, RFC 3066, January 2001.
-
- [RFC1884] Hinden, R. and S. Deering, "IP Version 6 Addressing
- Architecture", RFC 1884, December 1995.
-
- [RFC2279] Yergeau, F., "UTF-8, a transformation format of ISO
- 10646", RFC 2279, January 1998.
-
- [SCHEIFLER]
- Scheifler, R., "X Window System : The Complete Reference
- to Xlib, X Protocol, Icccm, Xlfd, 3rd edition.", Digital
- Press ISBN 1555580882, Feburary 1992.
-
- [POSIX] ISO/IEC, 9945-1., "Information technology -- Portable
- Operating System Interface (POSIX)-Part 1: System
- Application Program Interface (API) C Language", ANSI/IEE
- Std 1003.1, July 1996.
-
-
-Authors' Addresses
-
- Tatu Ylonen
- SSH Communications Security Corp
- Fredrikinkatu 42
- HELSINKI FIN-00100
- Finland
-
-
-
- Darren J. Moffat (editor)
- Sun Microsystems, Inc
- 17 Network Circle
- Menlo Park CA 94025
- USA
-
-
-
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 20]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
-Intellectual Property Statement
-
- The IETF takes no position regarding the validity or scope of any
- intellectual property or other rights that might be claimed to
- pertain to the implementation or use of the technology described in
- this document or the extent to which any license under such rights
- might or might not be available; neither does it represent that it
- has made any effort to identify any such rights. Information on the
- IETF's procedures with respect to rights in standards-track and
- standards-related documentation can be found in BCP-11. Copies of
- claims of rights made available for publication and any assurances of
- licenses to be made available, or the result of an attempt made to
- obtain a general license or permission for the use of such
- proprietary rights by implementors or users of this specification can
- be obtained from the IETF Secretariat.
-
- The IETF invites any interested party to bring to its attention any
- copyrights, patents or patent applications, or other proprietary
- rights which may cover technology that may be required to practice
- this standard. Please address the information to the IETF Executive
- Director.
-
- The IETF has been notified of intellectual property rights claimed in
- regard to some or all of the specification contained in this
- document. For more information consult the online list of claimed
- rights.
-
-
-Full Copyright Statement
-
- Copyright (C) The Internet Society (2003). All Rights Reserved.
-
- This document and translations of it may be copied and furnished to
- others, and derivative works that comment on or otherwise explain it
- or assist in its implementation may be prepared, copied, published
- and distributed, in whole or in part, without restriction of any
- kind, provided that the above copyright notice and this paragraph are
- included on all such copies and derivative works. However, this
- document itself may not be modified in any way, such as by removing
- the copyright notice or references to the Internet Society or other
- Internet organizations, except as needed for the purpose of
- developing Internet standards in which case the procedures for
- copyrights defined in the Internet Standards process must be
- followed, or as required to translate it into languages other than
- English.
-
- The limited permissions granted above are perpetual and will not be
- revoked by the Internet Society or its successors or assignees.
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 21]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- This document and the information contained herein is provided on an
- "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
- TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
- BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
- HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
- MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-
-Acknowledgment
-
- Funding for the RFC Editor function is currently provided by the
- Internet Society.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 22] \ No newline at end of file
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-02.2.ps b/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-02.2.ps
deleted file mode 100644
index 06c91bf8cd..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-02.2.ps
+++ /dev/null
@@ -1,2853 +0,0 @@
-%!PS-Adobe-3.0
-%%BoundingBox: 75 0 595 747
-%%Title: Enscript Output
-%%For: Magnus Thoang
-%%Creator: GNU enscript 1.6.1
-%%CreationDate: Wed Nov 12 12:26:07 2003
-%%Orientation: Portrait
-%%Pages: 15 0
-%%DocumentMedia: A4 595 842 0 () ()
-%%DocumentNeededResources: (atend)
-%%EndComments
-%%BeginProlog
-%%BeginProcSet: PStoPS 1 15
-userdict begin
-[/showpage/erasepage/copypage]{dup where{pop dup load
- type/operatortype eq{1 array cvx dup 0 3 index cvx put
- bind def}{pop}ifelse}{pop}ifelse}forall
-[/letter/legal/executivepage/a4/a4small/b5/com10envelope
- /monarchenvelope/c5envelope/dlenvelope/lettersmall/note
- /folio/quarto/a5]{dup where{dup wcheck{exch{}put}
- {pop{}def}ifelse}{pop}ifelse}forall
-/setpagedevice {pop}bind 1 index where{dup wcheck{3 1 roll put}
- {pop def}ifelse}{def}ifelse
-/PStoPSmatrix matrix currentmatrix def
-/PStoPSxform matrix def/PStoPSclip{clippath}def
-/defaultmatrix{PStoPSmatrix exch PStoPSxform exch concatmatrix}bind def
-/initmatrix{matrix defaultmatrix setmatrix}bind def
-/initclip[{matrix currentmatrix PStoPSmatrix setmatrix
- [{currentpoint}stopped{$error/newerror false put{newpath}}
- {/newpath cvx 3 1 roll/moveto cvx 4 array astore cvx}ifelse]
- {[/newpath cvx{/moveto cvx}{/lineto cvx}
- {/curveto cvx}{/closepath cvx}pathforall]cvx exch pop}
- stopped{$error/errorname get/invalidaccess eq{cleartomark
- $error/newerror false put cvx exec}{stop}ifelse}if}bind aload pop
- /initclip dup load dup type dup/operatortype eq{pop exch pop}
- {dup/arraytype eq exch/packedarraytype eq or
- {dup xcheck{exch pop aload pop}{pop cvx}ifelse}
- {pop cvx}ifelse}ifelse
- {newpath PStoPSclip clip newpath exec setmatrix} bind aload pop]cvx def
-/initgraphics{initmatrix newpath initclip 1 setlinewidth
- 0 setlinecap 0 setlinejoin []0 setdash 0 setgray
- 10 setmiterlimit}bind def
-end
-%%EndProcSet
-%%BeginResource: procset Enscript-Prolog 1.6 1
-%
-% Procedures.
-%
-
-/_S { % save current state
- /_s save def
-} def
-/_R { % restore from saved state
- _s restore
-} def
-
-/S { % showpage protecting gstate
- gsave
- showpage
- grestore
-} bind def
-
-/MF { % fontname newfontname -> - make a new encoded font
- /newfontname exch def
- /fontname exch def
-
- /fontdict fontname findfont def
- /newfont fontdict maxlength dict def
-
- fontdict {
- exch
- dup /FID eq {
- % skip FID pair
- pop pop
- } {
- % copy to the new font dictionary
- exch newfont 3 1 roll put
- } ifelse
- } forall
-
- newfont /FontName newfontname put
-
- % insert only valid encoding vectors
- encoding_vector length 256 eq {
- newfont /Encoding encoding_vector put
- } if
-
- newfontname newfont definefont pop
-} def
-
-/SF { % fontname width height -> - set a new font
- /height exch def
- /width exch def
-
- findfont
- [width 0 0 height 0 0] makefont setfont
-} def
-
-/SUF { % fontname width height -> - set a new user font
- /height exch def
- /width exch def
-
- /F-gs-user-font MF
- /F-gs-user-font width height SF
-} def
-
-/M {moveto} bind def
-/s {show} bind def
-
-/Box { % x y w h -> - define box path
- /d_h exch def /d_w exch def /d_y exch def /d_x exch def
- d_x d_y moveto
- d_w 0 rlineto
- 0 d_h rlineto
- d_w neg 0 rlineto
- closepath
-} def
-
-/bgs { % x y height blskip gray str -> - show string with bg color
- /str exch def
- /gray exch def
- /blskip exch def
- /height exch def
- /y exch def
- /x exch def
-
- gsave
- x y blskip sub str stringwidth pop height Box
- gray setgray
- fill
- grestore
- x y M str s
-} def
-
-% Highlight bars.
-/highlight_bars { % nlines lineheight output_y_margin gray -> -
- gsave
- setgray
- /ymarg exch def
- /lineheight exch def
- /nlines exch def
-
- % This 2 is just a magic number to sync highlight lines to text.
- 0 d_header_y ymarg sub 2 sub translate
-
- /cw d_output_w cols div def
- /nrows d_output_h ymarg 2 mul sub lineheight div cvi def
-
- % for each column
- 0 1 cols 1 sub {
- cw mul /xp exch def
-
- % for each rows
- 0 1 nrows 1 sub {
- /rn exch def
- rn lineheight mul neg /yp exch def
- rn nlines idiv 2 mod 0 eq {
- % Draw highlight bar. 4 is just a magic indentation.
- xp 4 add yp cw 8 sub lineheight neg Box fill
- } if
- } for
- } for
-
- grestore
-} def
-
-% Line highlight bar.
-/line_highlight { % x y width height gray -> -
- gsave
- /gray exch def
- Box gray setgray fill
- grestore
-} def
-
-% Column separator lines.
-/column_lines {
- gsave
- .1 setlinewidth
- 0 d_footer_h translate
- /cw d_output_w cols div def
- 1 1 cols 1 sub {
- cw mul 0 moveto
- 0 d_output_h rlineto stroke
- } for
- grestore
-} def
-
-% Column borders.
-/column_borders {
- gsave
- .1 setlinewidth
- 0 d_footer_h moveto
- 0 d_output_h rlineto
- d_output_w 0 rlineto
- 0 d_output_h neg rlineto
- closepath stroke
- grestore
-} def
-
-% Do the actual underlay drawing
-/draw_underlay {
- ul_style 0 eq {
- ul_str true charpath stroke
- } {
- ul_str show
- } ifelse
-} def
-
-% Underlay
-/underlay { % - -> -
- gsave
- 0 d_page_h translate
- d_page_h neg d_page_w atan rotate
-
- ul_gray setgray
- ul_font setfont
- /dw d_page_h dup mul d_page_w dup mul add sqrt def
- ul_str stringwidth pop dw exch sub 2 div ul_h_ptsize -2 div moveto
- draw_underlay
- grestore
-} def
-
-/user_underlay { % - -> -
- gsave
- ul_x ul_y translate
- ul_angle rotate
- ul_gray setgray
- ul_font setfont
- 0 0 ul_h_ptsize 2 div sub moveto
- draw_underlay
- grestore
-} def
-
-% Page prefeed
-/page_prefeed { % bool -> -
- statusdict /prefeed known {
- statusdict exch /prefeed exch put
- } {
- pop
- } ifelse
-} def
-
-% Wrapped line markers
-/wrapped_line_mark { % x y charwith charheight type -> -
- /type exch def
- /h exch def
- /w exch def
- /y exch def
- /x exch def
-
- type 2 eq {
- % Black boxes (like TeX does)
- gsave
- 0 setlinewidth
- x w 4 div add y M
- 0 h rlineto w 2 div 0 rlineto 0 h neg rlineto
- closepath fill
- grestore
- } {
- type 3 eq {
- % Small arrows
- gsave
- .2 setlinewidth
- x w 2 div add y h 2 div add M
- w 4 div 0 rlineto
- x w 4 div add y lineto stroke
-
- x w 4 div add w 8 div add y h 4 div add M
- x w 4 div add y lineto
- w 4 div h 8 div rlineto stroke
- grestore
- } {
- % do nothing
- } ifelse
- } ifelse
-} def
-
-% EPSF import.
-
-/BeginEPSF {
- /b4_Inc_state save def % Save state for cleanup
- /dict_count countdictstack def % Count objects on dict stack
- /op_count count 1 sub def % Count objects on operand stack
- userdict begin
- /showpage { } def
- 0 setgray 0 setlinecap
- 1 setlinewidth 0 setlinejoin
- 10 setmiterlimit [ ] 0 setdash newpath
- /languagelevel where {
- pop languagelevel
- 1 ne {
- false setstrokeadjust false setoverprint
- } if
- } if
-} bind def
-
-/EndEPSF {
- count op_count sub { pos } repeat % Clean up stacks
- countdictstack dict_count sub { end } repeat
- b4_Inc_state restore
-} bind def
-
-% Check PostScript language level.
-/languagelevel where {
- pop /gs_languagelevel languagelevel def
-} {
- /gs_languagelevel 1 def
-} ifelse
-%%EndResource
-%%BeginResource: procset Enscript-Encoding-88591 1.6 1
-/encoding_vector [
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/space /exclam /quotedbl /numbersign
-/dollar /percent /ampersand /quoteright
-/parenleft /parenright /asterisk /plus
-/comma /hyphen /period /slash
-/zero /one /two /three
-/four /five /six /seven
-/eight /nine /colon /semicolon
-/less /equal /greater /question
-/at /A /B /C
-/D /E /F /G
-/H /I /J /K
-/L /M /N /O
-/P /Q /R /S
-/T /U /V /W
-/X /Y /Z /bracketleft
-/backslash /bracketright /asciicircum /underscore
-/quoteleft /a /b /c
-/d /e /f /g
-/h /i /j /k
-/l /m /n /o
-/p /q /r /s
-/t /u /v /w
-/x /y /z /braceleft
-/bar /braceright /tilde /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/space /exclamdown /cent /sterling
-/currency /yen /brokenbar /section
-/dieresis /copyright /ordfeminine /guillemotleft
-/logicalnot /hyphen /registered /macron
-/degree /plusminus /twosuperior /threesuperior
-/acute /mu /paragraph /bullet
-/cedilla /onesuperior /ordmasculine /guillemotright
-/onequarter /onehalf /threequarters /questiondown
-/Agrave /Aacute /Acircumflex /Atilde
-/Adieresis /Aring /AE /Ccedilla
-/Egrave /Eacute /Ecircumflex /Edieresis
-/Igrave /Iacute /Icircumflex /Idieresis
-/Eth /Ntilde /Ograve /Oacute
-/Ocircumflex /Otilde /Odieresis /multiply
-/Oslash /Ugrave /Uacute /Ucircumflex
-/Udieresis /Yacute /Thorn /germandbls
-/agrave /aacute /acircumflex /atilde
-/adieresis /aring /ae /ccedilla
-/egrave /eacute /ecircumflex /edieresis
-/igrave /iacute /icircumflex /idieresis
-/eth /ntilde /ograve /oacute
-/ocircumflex /otilde /odieresis /divide
-/oslash /ugrave /uacute /ucircumflex
-/udieresis /yacute /thorn /ydieresis
-] def
-%%EndResource
-%%EndProlog
-%%BeginSetup
-%%IncludeResource: font Courier-Bold
-%%IncludeResource: font Courier
-/HFpt_w 10 def
-/HFpt_h 10 def
-/Courier-Bold /HF-gs-font MF
-/HF /HF-gs-font findfont [HFpt_w 0 0 HFpt_h 0 0] makefont def
-/Courier /F-gs-font MF
-/F-gs-font 10 10 SF
-/#copies 1 def
-/d_page_w 520 def
-/d_page_h 747 def
-/d_header_x 0 def
-/d_header_y 747 def
-/d_header_w 520 def
-/d_header_h 0 def
-/d_footer_x 0 def
-/d_footer_y 0 def
-/d_footer_w 520 def
-/d_footer_h 0 def
-/d_output_w 520 def
-/d_output_h 747 def
-/cols 1 def
-userdict/PStoPSxform PStoPSmatrix matrix currentmatrix
- matrix invertmatrix matrix concatmatrix
- matrix invertmatrix put
-%%EndSetup
-%%Page: (0,1) 1
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 1 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 701 M
-(Network Working Group T. Ylonen) s
-5 690 M
-(Internet-Draft S. Lehtinen) s
-5 679 M
-(Expires: April 1, 2002 SSH Communications Security Corp) s
-5 668 M
-( October 2001) s
-5 635 M
-( SSH File Transfer Protocol) s
-5 624 M
-( draft-ietf-secsh-filexfer-02.txt) s
-5 602 M
-(Status of this Memo) s
-5 580 M
-( This document is an Internet-Draft and is in full conformance with) s
-5 569 M
-( all provisions of Section 10 of RFC2026.) s
-5 547 M
-( Internet-Drafts are working documents of the Internet Engineering) s
-5 536 M
-( Task Force \(IETF\), its areas, and its working groups. Note that) s
-5 525 M
-( other groups may also distribute working documents as Internet-) s
-5 514 M
-( Drafts.) s
-5 492 M
-( Internet-Drafts are draft documents valid for a maximum of six months) s
-5 481 M
-( and may be updated, replaced, or obsoleted by other documents at any) s
-5 470 M
-( time. It is inappropriate to use Internet-Drafts as reference) s
-5 459 M
-( material or to cite them other than as "work in progress.") s
-5 437 M
-( The list of current Internet-Drafts can be accessed at http://) s
-5 426 M
-( www.ietf.org/ietf/1id-abstracts.txt.) s
-5 404 M
-( The list of Internet-Draft Shadow Directories can be accessed at) s
-5 393 M
-( http://www.ietf.org/shadow.html.) s
-5 371 M
-( This Internet-Draft will expire on April 1, 2002.) s
-5 349 M
-(Copyright Notice) s
-5 327 M
-( Copyright \(C\) The Internet Society \(2001\). All Rights Reserved.) s
-5 305 M
-(Abstract) s
-5 283 M
-( The SSH File Transfer Protocol provides secure file transfer) s
-5 272 M
-( functionality over any reliable data stream. It is the standard file) s
-5 261 M
-( transfer protocol for use with the SSH2 protocol. This document) s
-5 250 M
-( describes the file transfer protocol and its interface to the SSH2) s
-5 239 M
-( protocol suite.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 1]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 2 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(Table of Contents) s
-5 668 M
-( 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 657 M
-( 2. Use with the SSH Connection Protocol . . . . . . . . . . . . 4) s
-5 646 M
-( 3. General Packet Format . . . . . . . . . . . . . . . . . . . 5) s
-5 635 M
-( 4. Protocol Initialization . . . . . . . . . . . . . . . . . . 7) s
-5 624 M
-( 5. File Attributes . . . . . . . . . . . . . . . . . . . . . . 8) s
-5 613 M
-( 6. Requests From the Client to the Server . . . . . . . . . . . 10) s
-5 602 M
-( 6.1 Request Synchronization and Reordering . . . . . . . . . . . 10) s
-5 591 M
-( 6.2 File Names . . . . . . . . . . . . . . . . . . . . . . . . . 11) s
-5 580 M
-( 6.3 Opening, Creating, and Closing Files . . . . . . . . . . . . 11) s
-5 569 M
-( 6.4 Reading and Writing . . . . . . . . . . . . . . . . . . . . 13) s
-5 558 M
-( 6.5 Removing and Renaming Files . . . . . . . . . . . . . . . . 14) s
-5 547 M
-( 6.6 Creating and Deleting Directories . . . . . . . . . . . . . 15) s
-5 536 M
-( 6.7 Scanning Directories . . . . . . . . . . . . . . . . . . . . 15) s
-5 525 M
-( 6.8 Retrieving File Attributes . . . . . . . . . . . . . . . . . 16) s
-5 514 M
-( 6.9 Setting File Attributes . . . . . . . . . . . . . . . . . . 17) s
-5 503 M
-( 6.10 Dealing with Symbolic links . . . . . . . . . . . . . . . . 18) s
-5 492 M
-( 6.11 Canonicalizing the Server-Side Path Name . . . . . . . . . . 18) s
-5 481 M
-( 7. Responses from the Server to the Client . . . . . . . . . . 20) s
-5 470 M
-( 8. Vendor-Specific Extensions . . . . . . . . . . . . . . . . . 24) s
-5 459 M
-( 9. Security Considerations . . . . . . . . . . . . . . . . . . 25) s
-5 448 M
-( 10. Changes from previous protocol versions . . . . . . . . . . 26) s
-5 437 M
-( 10.1 Changes between versions 3 and 2 . . . . . . . . . . . . . . 26) s
-5 426 M
-( 10.2 Changes between versions 2 and 1 . . . . . . . . . . . . . . 26) s
-5 415 M
-( 10.3 Changes between versions 1 and 0 . . . . . . . . . . . . . . 26) s
-5 404 M
-( 11. Trademark Issues . . . . . . . . . . . . . . . . . . . . . . 27) s
-5 393 M
-( References . . . . . . . . . . . . . . . . . . . . . . . . . 28) s
-5 382 M
-( Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 28) s
-5 371 M
-( Full Copyright Statement . . . . . . . . . . . . . . . . . . 29) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 2]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (2,3) 2
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 3 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(1. Introduction) s
-5 668 M
-( This protocol provides secure file transfer \(and more generally file) s
-5 657 M
-( system access\) functionality over a reliable data stream, such as a) s
-5 646 M
-( channel in the SSH2 protocol [3].) s
-5 624 M
-( This protocol is designed so that it could be used to implement a) s
-5 613 M
-( secure remote file system service, as well as a secure file transfer) s
-5 602 M
-( service.) s
-5 580 M
-( This protocol assumes that it runs over a secure channel, and that) s
-5 569 M
-( the server has already authenticated the user at the client end, and) s
-5 558 M
-( that the identity of the client user is externally available to the) s
-5 547 M
-( server implementation.) s
-5 525 M
-( In general, this protocol follows a simple request-response model.) s
-5 514 M
-( Each request and response contains a sequence number and multiple) s
-5 503 M
-( requests may be pending simultaneously. There are a relatively large) s
-5 492 M
-( number of different request messages, but a small number of possible) s
-5 481 M
-( response messages. Each request has one or more response messages) s
-5 470 M
-( that may be returned in result \(e.g., a read either returns data or) s
-5 459 M
-( reports error status\).) s
-5 437 M
-( The packet format descriptions in this specification follow the) s
-5 426 M
-( notation presented in the secsh architecture draft.[3].) s
-5 404 M
-( Even though this protocol is described in the context of the SSH2) s
-5 393 M
-( protocol, this protocol is general and independent of the rest of the) s
-5 382 M
-( SSH2 protocol suite. It could be used in a number of different) s
-5 371 M
-( applications, such as secure file transfer over TLS RFC 2246 [1] and) s
-5 360 M
-( transfer of management information in VPN applications.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 3]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 4 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(2. Use with the SSH Connection Protocol) s
-5 668 M
-( When used with the SSH2 Protocol suite, this protocol is intended to) s
-5 657 M
-( be used from the SSH Connection Protocol [5] as a subsystem, as) s
-5 646 M
-( described in section ``Starting a Shell or a Command''. The) s
-5 635 M
-( subsystem name used with this protocol is "sftp".) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 4]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (4,5) 3
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 5 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(3. General Packet Format) s
-5 668 M
-( All packets transmitted over the secure connection are of the) s
-5 657 M
-( following format:) s
-5 635 M
-( uint32 length) s
-5 624 M
-( byte type) s
-5 613 M
-( byte[length - 1] data payload) s
-5 591 M
-( That is, they are just data preceded by 32-bit length and 8-bit type) s
-5 580 M
-( fields. The `length' is the length of the data area, and does not) s
-5 569 M
-( include the `length' field itself. The format and interpretation of) s
-5 558 M
-( the data area depends on the packet type.) s
-5 536 M
-( All packet descriptions below only specify the packet type and the) s
-5 525 M
-( data that goes into the data field. Thus, they should be prefixed by) s
-5 514 M
-( the `length' and `type' fields.) s
-5 492 M
-( The maximum size of a packet is in practice determined by the client) s
-5 481 M
-( \(the maximum size of read or write requests that it sends, plus a few) s
-5 470 M
-( bytes of packet overhead\). All servers SHOULD support packets of at) s
-5 459 M
-( least 34000 bytes \(where the packet size refers to the full length,) s
-5 448 M
-( including the header above\). This should allow for reads and writes) s
-5 437 M
-( of at most 32768 bytes.) s
-5 415 M
-( There is no limit on the number of outstanding \(non-acknowledged\)) s
-5 404 M
-( requests that the client may send to the server. In practice this is) s
-5 393 M
-( limited by the buffering available on the data stream and the queuing) s
-5 382 M
-( performed by the server. If the server's queues are full, it should) s
-5 371 M
-( not read any more data from the stream, and flow control will prevent) s
-5 360 M
-( the client from sending more requests. Note, however, that while) s
-5 349 M
-( there is no restriction on the protocol level, the client's API may) s
-5 338 M
-( provide a limit in order to prevent infinite queuing of outgoing) s
-5 327 M
-( requests at the client.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 5]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 6 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-( The following values are defined for packet types.) s
-5 668 M
-( #define SSH_FXP_INIT 1) s
-5 657 M
-( #define SSH_FXP_VERSION 2) s
-5 646 M
-( #define SSH_FXP_OPEN 3) s
-5 635 M
-( #define SSH_FXP_CLOSE 4) s
-5 624 M
-( #define SSH_FXP_READ 5) s
-5 613 M
-( #define SSH_FXP_WRITE 6) s
-5 602 M
-( #define SSH_FXP_LSTAT 7) s
-5 591 M
-( #define SSH_FXP_FSTAT 8) s
-5 580 M
-( #define SSH_FXP_SETSTAT 9) s
-5 569 M
-( #define SSH_FXP_FSETSTAT 10) s
-5 558 M
-( #define SSH_FXP_OPENDIR 11) s
-5 547 M
-( #define SSH_FXP_READDIR 12) s
-5 536 M
-( #define SSH_FXP_REMOVE 13) s
-5 525 M
-( #define SSH_FXP_MKDIR 14) s
-5 514 M
-( #define SSH_FXP_RMDIR 15) s
-5 503 M
-( #define SSH_FXP_REALPATH 16) s
-5 492 M
-( #define SSH_FXP_STAT 17) s
-5 481 M
-( #define SSH_FXP_RENAME 18) s
-5 470 M
-( #define SSH_FXP_READLINK 19) s
-5 459 M
-( #define SSH_FXP_SYMLINK 20) s
-5 448 M
-( #define SSH_FXP_STATUS 101) s
-5 437 M
-( #define SSH_FXP_HANDLE 102) s
-5 426 M
-( #define SSH_FXP_DATA 103) s
-5 415 M
-( #define SSH_FXP_NAME 104) s
-5 404 M
-( #define SSH_FXP_ATTRS 105) s
-5 393 M
-( #define SSH_FXP_EXTENDED 200) s
-5 382 M
-( #define SSH_FXP_EXTENDED_REPLY 201) s
-5 360 M
-( Additional packet types should only be defined if the protocol) s
-5 349 M
-( version number \(see Section ``Protocol Initialization''\) is) s
-5 338 M
-( incremented, and their use MUST be negotiated using the version) s
-5 327 M
-( number. However, the SSH_FXP_EXTENDED and SSH_FXP_EXTENDED_REPLY) s
-5 316 M
-( packets can be used to implement vendor-specific extensions. See) s
-5 305 M
-( Section ``Vendor-Specific-Extensions'' for more details.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 6]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (6,7) 4
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 7 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(4. Protocol Initialization) s
-5 668 M
-( When the file transfer protocol starts, it first sends a SSH_FXP_INIT) s
-5 657 M
-( \(including its version number\) packet to the server. The server) s
-5 646 M
-( responds with a SSH_FXP_VERSION packet, supplying the lowest of its) s
-5 635 M
-( own and the client's version number. Both parties should from then) s
-5 624 M
-( on adhere to particular version of the protocol.) s
-5 602 M
-( The SSH_FXP_INIT packet \(from client to server\) has the following) s
-5 591 M
-( data:) s
-5 569 M
-( uint32 version) s
-5 558 M
-( <extension data>) s
-5 536 M
-( The SSH_FXP_VERSION packet \(from server to client\) has the following) s
-5 525 M
-( data:) s
-5 503 M
-( uint32 version) s
-5 492 M
-( <extension data>) s
-5 470 M
-( The version number of the protocol specified in this document is 3.) s
-5 459 M
-( The version number should be incremented for each incompatible) s
-5 448 M
-( revision of this protocol.) s
-5 426 M
-( The extension data in the above packets may be empty, or may be a) s
-5 415 M
-( sequence of) s
-5 393 M
-( string extension_name) s
-5 382 M
-( string extension_data) s
-5 360 M
-( pairs \(both strings MUST always be present if one is, but the) s
-5 349 M
-( `extension_data' string may be of zero length\). If present, these) s
-5 338 M
-( strings indicate extensions to the baseline protocol. The) s
-5 327 M
-( `extension_name' field\(s\) identify the name of the extension. The) s
-5 316 M
-( name should be of the form "name@domain", where the domain is the DNS) s
-5 305 M
-( domain name of the organization defining the extension. Additional) s
-5 294 M
-( names that are not of this format may be defined later by the IETF.) s
-5 283 M
-( Implementations MUST silently ignore any extensions whose name they) s
-5 272 M
-( do not recognize.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 7]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 8 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(5. File Attributes) s
-5 668 M
-( A new compound data type is defined for encoding file attributes. It) s
-5 657 M
-( is basically just a combination of elementary types, but is defined) s
-5 646 M
-( once because of the non-trivial description of the fields and to) s
-5 635 M
-( ensure maintainability.) s
-5 613 M
-( The same encoding is used both when returning file attributes from) s
-5 602 M
-( the server and when sending file attributes to the server. When) s
-5 591 M
-( sending it to the server, the flags field specifies which attributes) s
-5 580 M
-( are included, and the server will use default values for the) s
-5 569 M
-( remaining attributes \(or will not modify the values of remaining) s
-5 558 M
-( attributes\). When receiving attributes from the server, the flags) s
-5 547 M
-( specify which attributes are included in the returned data. The) s
-5 536 M
-( server normally returns all attributes it knows about.) s
-5 514 M
-( uint32 flags) s
-5 503 M
-( uint64 size present only if flag SSH_FILEXFER_ATTR_SIZE) s
-5 492 M
-( uint32 uid present only if flag SSH_FILEXFER_ATTR_UIDGID) s
-5 481 M
-( uint32 gid present only if flag SSH_FILEXFER_ATTR_UIDGID) s
-5 470 M
-( uint32 permissions present only if flag SSH_FILEXFER_ATTR_PERMISSIONS) s
-5 459 M
-( uint32 atime present only if flag SSH_FILEXFER_ACMODTIME) s
-5 448 M
-( uint32 mtime present only if flag SSH_FILEXFER_ACMODTIME) s
-5 437 M
-( uint32 extended_count present only if flag SSH_FILEXFER_ATTR_EXTENDED) s
-5 426 M
-( string extended_type) s
-5 415 M
-( string extended_data) s
-5 404 M
-( ... more extended data \(extended_type - extended_data pairs\),) s
-5 393 M
-( so that number of pairs equals extended_count) s
-5 371 M
-( The `flags' specify which of the fields are present. Those fields) s
-5 360 M
-( for which the corresponding flag is not set are not present \(not) s
-5 349 M
-( included in the packet\). New flags can only be added by incrementing) s
-5 338 M
-( the protocol version number \(or by using the extension mechanism) s
-5 327 M
-( described below\).) s
-5 305 M
-( The `size' field specifies the size of the file in bytes.) s
-5 283 M
-( The `uid' and `gid' fields contain numeric Unix-like user and group) s
-5 272 M
-( identifiers, respectively.) s
-5 250 M
-( The `permissions' field contains a bit mask of file permissions as) s
-5 239 M
-( defined by posix [1].) s
-5 217 M
-( The `atime' and `mtime' contain the access and modification times of) s
-5 206 M
-( the files, respectively. They are represented as seconds from Jan 1,) s
-5 195 M
-( 1970 in UTC.) s
-5 173 M
-( The SSH_FILEXFER_ATTR_EXTENDED flag provides a general extension) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 8]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (8,9) 5
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 9 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-( mechanism for vendor-specific extensions. If the flag is specified,) s
-5 679 M
-( then the `extended_count' field is present. It specifies the number) s
-5 668 M
-( of extended_type-extended_data pairs that follow. Each of these) s
-5 657 M
-( pairs specifies an extended attribute. For each of the attributes,) s
-5 646 M
-( the extended_type field should be a string of the format) s
-5 635 M
-( "name@domain", where "domain" is a valid, registered domain name and) s
-5 624 M
-( "name" identifies the method. The IETF may later standardize certain) s
-5 613 M
-( names that deviate from this format \(e.g., that do not contain the) s
-5 602 M
-( "@" sign\). The interpretation of `extended_data' depends on the) s
-5 591 M
-( type. Implementations SHOULD ignore extended data fields that they) s
-5 580 M
-( do not understand.) s
-5 558 M
-( Additional fields can be added to the attributes by either defining) s
-5 547 M
-( additional bits to the flags field to indicate their presence, or by) s
-5 536 M
-( defining extended attributes for them. The extended attributes) s
-5 525 M
-( mechanism is recommended for most purposes; additional flags bits) s
-5 514 M
-( should only be defined by an IETF standards action that also) s
-5 503 M
-( increments the protocol version number. The use of such new fields) s
-5 492 M
-( MUST be negotiated by the version number in the protocol exchange.) s
-5 481 M
-( It is a protocol error if a packet with unsupported protocol bits is) s
-5 470 M
-( received.) s
-5 448 M
-( The flags bits are defined to have the following values:) s
-5 426 M
-( #define SSH_FILEXFER_ATTR_SIZE 0x00000001) s
-5 415 M
-( #define SSH_FILEXFER_ATTR_UIDGID 0x00000002) s
-5 404 M
-( #define SSH_FILEXFER_ATTR_PERMISSIONS 0x00000004) s
-5 393 M
-( #define SSH_FILEXFER_ATTR_ACMODTIME 0x00000008) s
-5 382 M
-( #define SSH_FILEXFER_ATTR_EXTENDED 0x80000000) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 9]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 10 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(6. Requests From the Client to the Server) s
-5 668 M
-( Requests from the client to the server represent the various file) s
-5 657 M
-( system operations. Each request begins with an `id' field, which is) s
-5 646 M
-( a 32-bit identifier identifying the request \(selected by the client\).) s
-5 635 M
-( The same identifier will be returned in the response to the request.) s
-5 624 M
-( One possible implementation of it is a monotonically increasing) s
-5 613 M
-( request sequence number \(modulo 2^32\).) s
-5 591 M
-( Many operations in the protocol operate on open files. The) s
-5 580 M
-( SSH_FXP_OPEN request can return a file handle \(which is an opaque) s
-5 569 M
-( variable-length string\) which may be used to access the file later) s
-5 558 M
-( \(e.g. in a read operation\). The client MUST NOT send requests the) s
-5 547 M
-( server with bogus or closed handles. However, the server MUST) s
-5 536 M
-( perform adequate checks on the handle in order to avoid security) s
-5 525 M
-( risks due to fabricated handles.) s
-5 503 M
-( This design allows either stateful and stateless server) s
-5 492 M
-( implementation, as well as an implementation which caches state) s
-5 481 M
-( between requests but may also flush it. The contents of the file) s
-5 470 M
-( handle string are entirely up to the server and its design. The) s
-5 459 M
-( client should not modify or attempt to interpret the file handle) s
-5 448 M
-( strings.) s
-5 426 M
-( The file handle strings MUST NOT be longer than 256 bytes.) s
-5 404 M
-(6.1 Request Synchronization and Reordering) s
-5 382 M
-( The protocol and implementations MUST process requests relating to) s
-5 371 M
-( the same file in the order in which they are received. In other) s
-5 360 M
-( words, if an application submits multiple requests to the server, the) s
-5 349 M
-( results in the responses will be the same as if it had sent the) s
-5 338 M
-( requests one at a time and waited for the response in each case. For) s
-5 327 M
-( example, the server may process non-overlapping read/write requests) s
-5 316 M
-( to the same file in parallel, but overlapping reads and writes cannot) s
-5 305 M
-( be reordered or parallelized. However, there are no ordering) s
-5 294 M
-( restrictions on the server for processing requests from two different) s
-5 283 M
-( file transfer connections. The server may interleave and parallelize) s
-5 272 M
-( them at will.) s
-5 250 M
-( There are no restrictions on the order in which responses to) s
-5 239 M
-( outstanding requests are delivered to the client, except that the) s
-5 228 M
-( server must ensure fairness in the sense that processing of no) s
-5 217 M
-( request will be indefinitely delayed even if the client is sending) s
-5 206 M
-( other requests so that there are multiple outstanding requests all) s
-5 195 M
-( the time.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 10]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (10,11) 6
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 11 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(6.2 File Names) s
-5 668 M
-( This protocol represents file names as strings. File names are) s
-5 657 M
-( assumed to use the slash \('/'\) character as a directory separator.) s
-5 635 M
-( File names starting with a slash are "absolute", and are relative to) s
-5 624 M
-( the root of the file system. Names starting with any other character) s
-5 613 M
-( are relative to the user's default directory \(home directory\). Note) s
-5 602 M
-( that identifying the user is assumed to take place outside of this) s
-5 591 M
-( protocol.) s
-5 569 M
-( Servers SHOULD interpret a path name component ".." as referring to) s
-5 558 M
-( the parent directory, and "." as referring to the current directory.) s
-5 547 M
-( If the server implementation limits access to certain parts of the) s
-5 536 M
-( file system, it must be extra careful in parsing file names when) s
-5 525 M
-( enforcing such restrictions. There have been numerous reported) s
-5 514 M
-( security bugs where a ".." in a path name has allowed access outside) s
-5 503 M
-( the intended area.) s
-5 481 M
-( An empty path name is valid, and it refers to the user's default) s
-5 470 M
-( directory \(usually the user's home directory\).) s
-5 448 M
-( Otherwise, no syntax is defined for file names by this specification.) s
-5 437 M
-( Clients should not make any other assumptions; however, they can) s
-5 426 M
-( splice path name components returned by SSH_FXP_READDIR together) s
-5 415 M
-( using a slash \('/'\) as the separator, and that will work as expected.) s
-5 393 M
-( It is understood that the lack of well-defined semantics for file) s
-5 382 M
-( names may cause interoperability problems between clients and servers) s
-5 371 M
-( using radically different operating systems. However, this approach) s
-5 360 M
-( is known to work acceptably with most systems, and alternative) s
-5 349 M
-( approaches that e.g. treat file names as sequences of structured) s
-5 338 M
-( components are quite complicated.) s
-5 316 M
-(6.3 Opening, Creating, and Closing Files) s
-5 294 M
-( Files are opened and created using the SSH_FXP_OPEN message, whose) s
-5 283 M
-( data part is as follows:) s
-5 261 M
-( uint32 id) s
-5 250 M
-( string filename) s
-5 239 M
-( uint32 pflags) s
-5 228 M
-( ATTRS attrs) s
-5 206 M
-( The `id' field is the request identifier as for all requests.) s
-5 184 M
-( The `filename' field specifies the file name. See Section ``File) s
-5 173 M
-( Names'' for more information.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 11]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 12 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-( The `pflags' field is a bitmask. The following bits have been) s
-5 679 M
-( defined.) s
-5 657 M
-( #define SSH_FXF_READ 0x00000001) s
-5 646 M
-( #define SSH_FXF_WRITE 0x00000002) s
-5 635 M
-( #define SSH_FXF_APPEND 0x00000004) s
-5 624 M
-( #define SSH_FXF_CREAT 0x00000008) s
-5 613 M
-( #define SSH_FXF_TRUNC 0x00000010) s
-5 602 M
-( #define SSH_FXF_EXCL 0x00000020) s
-5 580 M
-( These have the following meanings:) s
-5 558 M
-( SSH_FXF_READ) s
-5 547 M
-( Open the file for reading.) s
-5 525 M
-( SSH_FXF_WRITE) s
-5 514 M
-( Open the file for writing. If both this and SSH_FXF_READ are) s
-5 503 M
-( specified, the file is opened for both reading and writing.) s
-5 481 M
-( SSH_FXF_APPEND) s
-5 470 M
-( Force all writes to append data at the end of the file.) s
-5 448 M
-( SSH_FXF_CREAT) s
-5 437 M
-( If this flag is specified, then a new file will be created if one) s
-5 426 M
-( does not already exist \(if O_TRUNC is specified, the new file will) s
-5 415 M
-( be truncated to zero length if it previously exists\).) s
-5 393 M
-( SSH_FXF_TRUNC) s
-5 382 M
-( Forces an existing file with the same name to be truncated to zero) s
-5 371 M
-( length when creating a file by specifying SSH_FXF_CREAT.) s
-5 360 M
-( SSH_FXF_CREAT MUST also be specified if this flag is used.) s
-5 338 M
-( SSH_FXF_EXCL) s
-5 327 M
-( Causes the request to fail if the named file already exists.) s
-5 316 M
-( SSH_FXF_CREAT MUST also be specified if this flag is used.) s
-5 294 M
-( The `attrs' field specifies the initial attributes for the file.) s
-5 283 M
-( Default values will be used for those attributes that are not) s
-5 272 M
-( specified. See Section ``File Attributes'' for more information.) s
-5 250 M
-( Regardless the server operating system, the file will always be) s
-5 239 M
-( opened in "binary" mode \(i.e., no translations between different) s
-5 228 M
-( character sets and newline encodings\).) s
-5 206 M
-( The response to this message will be either SSH_FXP_HANDLE \(if the) s
-5 195 M
-( operation is successful\) or SSH_FXP_STATUS \(if the operation fails\).) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 12]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (12,13) 7
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 13 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-( A file is closed by using the SSH_FXP_CLOSE request. Its data field) s
-5 679 M
-( has the following format:) s
-5 657 M
-( uint32 id) s
-5 646 M
-( string handle) s
-5 624 M
-( where `id' is the request identifier, and `handle' is a handle) s
-5 613 M
-( previously returned in the response to SSH_FXP_OPEN or) s
-5 602 M
-( SSH_FXP_OPENDIR. The handle becomes invalid immediately after this) s
-5 591 M
-( request has been sent.) s
-5 569 M
-( The response to this request will be a SSH_FXP_STATUS message. One) s
-5 558 M
-( should note that on some server platforms even a close can fail.) s
-5 547 M
-( This can happen e.g. if the server operating system caches writes,) s
-5 536 M
-( and an error occurs while flushing cached writes during the close.) s
-5 514 M
-(6.4 Reading and Writing) s
-5 492 M
-( Once a file has been opened, it can be read using the SSH_FXP_READ) s
-5 481 M
-( message, which has the following format:) s
-5 459 M
-( uint32 id) s
-5 448 M
-( string handle) s
-5 437 M
-( uint64 offset) s
-5 426 M
-( uint32 len) s
-5 404 M
-( where `id' is the request identifier, `handle' is an open file handle) s
-5 393 M
-( returned by SSH_FXP_OPEN, `offset' is the offset \(in bytes\) relative) s
-5 382 M
-( to the beginning of the file from where to start reading, and `len') s
-5 371 M
-( is the maximum number of bytes to read.) s
-5 349 M
-( In response to this request, the server will read as many bytes as it) s
-5 338 M
-( can from the file \(up to `len'\), and return them in a SSH_FXP_DATA) s
-5 327 M
-( message. If an error occurs or EOF is encountered before reading any) s
-5 316 M
-( data, the server will respond with SSH_FXP_STATUS. For normal disk) s
-5 305 M
-( files, it is guaranteed that this will read the specified number of) s
-5 294 M
-( bytes, or up to end of file. For e.g. device files this may return) s
-5 283 M
-( fewer bytes than requested.) s
-5 261 M
-( Writing to a file is achieved using the SSH_FXP_WRITE message, which) s
-5 250 M
-( has the following format:) s
-5 228 M
-( uint32 id) s
-5 217 M
-( string handle) s
-5 206 M
-( uint64 offset) s
-5 195 M
-( string data) s
-5 173 M
-( where `id' is a request identifier, `handle' is a file handle) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 13]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 14 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-( returned by SSH_FXP_OPEN, `offset' is the offset \(in bytes\) from the) s
-5 679 M
-( beginning of the file where to start writing, and `data' is the data) s
-5 668 M
-( to be written.) s
-5 646 M
-( The write will extend the file if writing beyond the end of the file.) s
-5 635 M
-( It is legal to write way beyond the end of the file; the semantics) s
-5 624 M
-( are to write zeroes from the end of the file to the specified offset) s
-5 613 M
-( and then the data. On most operating systems, such writes do not) s
-5 602 M
-( allocate disk space but instead leave "holes" in the file.) s
-5 580 M
-( The server responds to a write request with a SSH_FXP_STATUS message.) s
-5 558 M
-(6.5 Removing and Renaming Files) s
-5 536 M
-( Files can be removed using the SSH_FXP_REMOVE message. It has the) s
-5 525 M
-( following format:) s
-5 503 M
-( uint32 id) s
-5 492 M
-( string filename) s
-5 470 M
-( where `id' is the request identifier and `filename' is the name of) s
-5 459 M
-( the file to be removed. See Section ``File Names'' for more) s
-5 448 M
-( information. This request cannot be used to remove directories.) s
-5 426 M
-( The server will respond to this request with a SSH_FXP_STATUS) s
-5 415 M
-( message.) s
-5 393 M
-( Files \(and directories\) can be renamed using the SSH_FXP_RENAME) s
-5 382 M
-( message. Its data is as follows:) s
-5 360 M
-( uint32 id) s
-5 349 M
-( string oldpath) s
-5 338 M
-( string newpath) s
-5 316 M
-( where `id' is the request identifier, `oldpath' is the name of an) s
-5 305 M
-( existing file or directory, and `newpath' is the new name for the) s
-5 294 M
-( file or directory. It is an error if there already exists a file) s
-5 283 M
-( with the name specified by newpath. The server may also fail rename) s
-5 272 M
-( requests in other situations, for example if `oldpath' and `newpath') s
-5 261 M
-( point to different file systems on the server.) s
-5 239 M
-( The server will respond to this request with a SSH_FXP_STATUS) s
-5 228 M
-( message.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 14]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (14,15) 8
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 15 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(6.6 Creating and Deleting Directories) s
-5 668 M
-( New directories can be created using the SSH_FXP_MKDIR request. It) s
-5 657 M
-( has the following format:) s
-5 635 M
-( uint32 id) s
-5 624 M
-( string path) s
-5 613 M
-( ATTRS attrs) s
-5 591 M
-( where `id' is the request identifier, `path' and `attrs' specifies) s
-5 580 M
-( the modifications to be made to its attributes. See Section ``File) s
-5 569 M
-( Names'' for more information on file names. Attributes are discussed) s
-5 558 M
-( in more detail in Section ``File Attributes''. specifies the) s
-5 547 M
-( directory to be created. An error will be returned if a file or) s
-5 536 M
-( directory with the specified path already exists. The server will) s
-5 525 M
-( respond to this request with a SSH_FXP_STATUS message.) s
-5 503 M
-( Directories can be removed using the SSH_FXP_RMDIR request, which) s
-5 492 M
-( has the following format:) s
-5 470 M
-( uint32 id) s
-5 459 M
-( string path) s
-5 437 M
-( where `id' is the request identifier, and `path' specifies the) s
-5 426 M
-( directory to be removed. See Section ``File Names'' for more) s
-5 415 M
-( information on file names. An error will be returned if no directory) s
-5 404 M
-( with the specified path exists, or if the specified directory is not) s
-5 393 M
-( empty, or if the path specified a file system object other than a) s
-5 382 M
-( directory. The server responds to this request with a SSH_FXP_STATUS) s
-5 371 M
-( message.) s
-5 349 M
-(6.7 Scanning Directories) s
-5 327 M
-( The files in a directory can be listed using the SSH_FXP_OPENDIR and) s
-5 316 M
-( SSH_FXP_READDIR requests. Each SSH_FXP_READDIR request returns one) s
-5 305 M
-( or more file names with full file attributes for each file. The) s
-5 294 M
-( client should call SSH_FXP_READDIR repeatedly until it has found the) s
-5 283 M
-( file it is looking for or until the server responds with a) s
-5 272 M
-( SSH_FXP_STATUS message indicating an error \(normally SSH_FX_EOF if) s
-5 261 M
-( there are no more files in the directory\). The client should then) s
-5 250 M
-( close the handle using the SSH_FXP_CLOSE request.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 15]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 16 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-( The SSH_FXP_OPENDIR opens a directory for reading. It has the) s
-5 679 M
-( following format:) s
-5 657 M
-( uint32 id) s
-5 646 M
-( string path) s
-5 624 M
-( where `id' is the request identifier and `path' is the path name of) s
-5 613 M
-( the directory to be listed \(without any trailing slash\). See Section) s
-5 602 M
-( ``File Names'' for more information on file names. This will return) s
-5 591 M
-( an error if the path does not specify a directory or if the directory) s
-5 580 M
-( is not readable. The server will respond to this request with either) s
-5 569 M
-( a SSH_FXP_HANDLE or a SSH_FXP_STATUS message.) s
-5 547 M
-( Once the directory has been successfully opened, files \(and) s
-5 536 M
-( directories\) contained in it can be listed using SSH_FXP_READDIR) s
-5 525 M
-( requests. These are of the format) s
-5 503 M
-( uint32 id) s
-5 492 M
-( string handle) s
-5 470 M
-( where `id' is the request identifier, and `handle' is a handle) s
-5 459 M
-( returned by SSH_FXP_OPENDIR. \(It is a protocol error to attempt to) s
-5 448 M
-( use an ordinary file handle returned by SSH_FXP_OPEN.\)) s
-5 426 M
-( The server responds to this request with either a SSH_FXP_NAME or a) s
-5 415 M
-( SSH_FXP_STATUS message. One or more names may be returned at a time.) s
-5 404 M
-( Full status information is returned for each name in order to speed) s
-5 393 M
-( up typical directory listings.) s
-5 371 M
-( When the client no longer wishes to read more names from the) s
-5 360 M
-( directory, it SHOULD call SSH_FXP_CLOSE for the handle. The handle) s
-5 349 M
-( should be closed regardless of whether an error has occurred or not.) s
-5 327 M
-(6.8 Retrieving File Attributes) s
-5 305 M
-( Very often, file attributes are automatically returned by) s
-5 294 M
-( SSH_FXP_READDIR. However, sometimes there is need to specifically) s
-5 283 M
-( retrieve the attributes for a named file. This can be done using the) s
-5 272 M
-( SSH_FXP_STAT, SSH_FXP_LSTAT and SSH_FXP_FSTAT requests.) s
-5 250 M
-( SSH_FXP_STAT and SSH_FXP_LSTAT only differ in that SSH_FXP_STAT) s
-5 239 M
-( follows symbolic links on the server, whereas SSH_FXP_LSTAT does not) s
-5 228 M
-( follow symbolic links. Both have the same format:) s
-5 206 M
-( uint32 id) s
-5 195 M
-( string path) s
-5 173 M
-( where `id' is the request identifier, and `path' specifies the file) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 16]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (16,17) 9
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 17 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-( system object for which status is to be returned. The server) s
-5 679 M
-( responds to this request with either SSH_FXP_ATTRS or SSH_FXP_STATUS.) s
-5 657 M
-( SSH_FXP_FSTAT differs from the others in that it returns status) s
-5 646 M
-( information for an open file \(identified by the file handle\). Its) s
-5 635 M
-( format is as follows:) s
-5 613 M
-( uint32 id) s
-5 602 M
-( string handle) s
-5 580 M
-( where `id' is the request identifier and `handle' is a file handle) s
-5 569 M
-( returned by SSH_FXP_OPEN. The server responds to this request with) s
-5 558 M
-( SSH_FXP_ATTRS or SSH_FXP_STATUS.) s
-5 536 M
-(6.9 Setting File Attributes) s
-5 514 M
-( File attributes may be modified using the SSH_FXP_SETSTAT and) s
-5 503 M
-( SSH_FXP_FSETSTAT requests. These requests are used for operations) s
-5 492 M
-( such as changing the ownership, permissions or access times, as well) s
-5 481 M
-( as for truncating a file.) s
-5 459 M
-( The SSH_FXP_SETSTAT request is of the following format:) s
-5 437 M
-( uint32 id) s
-5 426 M
-( string path) s
-5 415 M
-( ATTRS attrs) s
-5 393 M
-( where `id' is the request identifier, `path' specifies the file) s
-5 382 M
-( system object \(e.g. file or directory\) whose attributes are to be) s
-5 371 M
-( modified, and `attrs' specifies the modifications to be made to its) s
-5 360 M
-( attributes. Attributes are discussed in more detail in Section) s
-5 349 M
-( ``File Attributes''.) s
-5 327 M
-( An error will be returned if the specified file system object does) s
-5 316 M
-( not exist or the user does not have sufficient rights to modify the) s
-5 305 M
-( specified attributes. The server responds to this request with a) s
-5 294 M
-( SSH_FXP_STATUS message.) s
-5 272 M
-( The SSH_FXP_FSETSTAT request modifies the attributes of a file which) s
-5 261 M
-( is already open. It has the following format:) s
-5 239 M
-( uint32 id) s
-5 228 M
-( string handle) s
-5 217 M
-( ATTRS attrs) s
-5 195 M
-( where `id' is the request identifier, `handle' \(MUST be returned by) s
-5 184 M
-( SSH_FXP_OPEN\) identifies the file whose attributes are to be) s
-5 173 M
-( modified, and `attrs' specifies the modifications to be made to its) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 17]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 18 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-( attributes. Attributes are discussed in more detail in Section) s
-5 679 M
-( ``File Attributes''. The server will respond to this request with) s
-5 668 M
-( SSH_FXP_STATUS.) s
-5 646 M
-(6.10 Dealing with Symbolic links) s
-5 624 M
-( The SSH_FXP_READLINK request may be used to read the target of a) s
-5 613 M
-( symbolic link. It would have a data part as follows:) s
-5 591 M
-( uint32 id) s
-5 580 M
-( string path) s
-5 558 M
-( where `id' is the request identifier and `path' specifies the path) s
-5 547 M
-( name of the symlink to be read.) s
-5 525 M
-( The server will respond with a SSH_FXP_NAME packet containing only) s
-5 514 M
-( one name and a dummy attributes value. The name in the returned) s
-5 503 M
-( packet contains the target of the link. If an error occurs, the) s
-5 492 M
-( server may respond with SSH_FXP_STATUS.) s
-5 470 M
-( The SSH_FXP_SYMLINK request will create a symbolic link on the) s
-5 459 M
-( server. It is of the following format) s
-5 437 M
-( uint32 id) s
-5 426 M
-( string linkpath) s
-5 415 M
-( string targetpath) s
-5 393 M
-( where `id' is the request identifier, `linkpath' specifies the path) s
-5 382 M
-( name of the symlink to be created and `targetpath' specifies the) s
-5 371 M
-( target of the symlink. The server shall respond with a) s
-5 360 M
-( SSH_FXP_STATUS indicating either success \(SSH_FX_OK\) or an error) s
-5 349 M
-( condition.) s
-5 327 M
-(6.11 Canonicalizing the Server-Side Path Name) s
-5 305 M
-( The SSH_FXP_REALPATH request can be used to have the server) s
-5 294 M
-( canonicalize any given path name to an absolute path. This is useful) s
-5 283 M
-( for converting path names containing ".." components or relative) s
-5 272 M
-( pathnames without a leading slash into absolute paths. The format of) s
-5 261 M
-( the request is as follows:) s
-5 239 M
-( uint32 id) s
-5 228 M
-( string path) s
-5 206 M
-( where `id' is the request identifier and `path' specifies the path) s
-5 195 M
-( name to be canonicalized. The server will respond with a) s
-5 184 M
-( SSH_FXP_NAME packet containing only one name and a dummy attributes) s
-5 173 M
-( value. The name is the returned packet will be in canonical form.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 18]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (18,19) 10
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 19 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-( If an error occurs, the server may also respond with SSH_FXP_STATUS.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 19]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 20 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(7. Responses from the Server to the Client) s
-5 668 M
-( The server responds to the client using one of a few response) s
-5 657 M
-( packets. All requests can return a SSH_FXP_STATUS response upon) s
-5 646 M
-( failure. When the operation is successful, any of the responses may) s
-5 635 M
-( be returned \(depending on the operation\). If no data needs to be) s
-5 624 M
-( returned to the client, the SSH_FXP_STATUS response with SSH_FX_OK) s
-5 613 M
-( status is appropriate. Otherwise, the SSH_FXP_HANDLE message is used) s
-5 602 M
-( to return a file handle \(for SSH_FXP_OPEN and SSH_FXP_OPENDIR) s
-5 591 M
-( requests\), SSH_FXP_DATA is used to return data from SSH_FXP_READ,) s
-5 580 M
-( SSH_FXP_NAME is used to return one or more file names from a) s
-5 569 M
-( SSH_FXP_READDIR or SSH_FXP_REALPATH request, and SSH_FXP_ATTRS is) s
-5 558 M
-( used to return file attributes from SSH_FXP_STAT, SSH_FXP_LSTAT, and) s
-5 547 M
-( SSH_FXP_FSTAT requests.) s
-5 525 M
-( Exactly one response will be returned for each request. Each) s
-5 514 M
-( response packet contains a request identifier which can be used to) s
-5 503 M
-( match each response with the corresponding request. Note that it is) s
-5 492 M
-( legal to have several requests outstanding simultaneously, and the) s
-5 481 M
-( server is allowed to send responses to them in a different order from) s
-5 470 M
-( the order in which the requests were sent \(the result of their) s
-5 459 M
-( execution, however, is guaranteed to be as if they had been processed) s
-5 448 M
-( one at a time in the order in which the requests were sent\).) s
-5 426 M
-( Response packets are of the same general format as request packets.) s
-5 415 M
-( Each response packet begins with the request identifier.) s
-5 393 M
-( The format of the data portion of the SSH_FXP_STATUS response is as) s
-5 382 M
-( follows:) s
-5 360 M
-( uint32 id) s
-5 349 M
-( uint32 error/status code) s
-5 338 M
-( string error message \(ISO-10646 UTF-8 [RFC-2279]\)) s
-5 327 M
-( string language tag \(as defined in [RFC-1766]\)) s
-5 305 M
-( where `id' is the request identifier, and `error/status code') s
-5 294 M
-( indicates the result of the requested operation. The value SSH_FX_OK) s
-5 283 M
-( indicates success, and all other values indicate failure.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 20]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (20,21) 11
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 21 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-( Currently, the following values are defined \(other values may be) s
-5 679 M
-( defined by future versions of this protocol\):) s
-5 657 M
-( #define SSH_FX_OK 0) s
-5 646 M
-( #define SSH_FX_EOF 1) s
-5 635 M
-( #define SSH_FX_NO_SUCH_FILE 2) s
-5 624 M
-( #define SSH_FX_PERMISSION_DENIED 3) s
-5 613 M
-( #define SSH_FX_FAILURE 4) s
-5 602 M
-( #define SSH_FX_BAD_MESSAGE 5) s
-5 591 M
-( #define SSH_FX_NO_CONNECTION 6) s
-5 580 M
-( #define SSH_FX_CONNECTION_LOST 7) s
-5 569 M
-( #define SSH_FX_OP_UNSUPPORTED 8) s
-5 547 M
-( SSH_FX_OK) s
-5 536 M
-( Indicates successful completion of the operation.) s
-5 514 M
-( SSH_FX_EOF) s
-5 503 M
-( indicates end-of-file condition; for SSH_FX_READ it means that no) s
-5 492 M
-( more data is available in the file, and for SSH_FX_READDIR it) s
-5 481 M
-( indicates that no more files are contained in the directory.) s
-5 459 M
-( SSH_FX_NO_SUCH_FILE) s
-5 448 M
-( is returned when a reference is made to a file which should exist) s
-5 437 M
-( but doesn't.) s
-5 415 M
-( SSH_FX_PERMISSION_DENIED) s
-5 404 M
-( is returned when the authenticated user does not have sufficient) s
-5 393 M
-( permissions to perform the operation.) s
-5 371 M
-( SSH_FX_FAILURE) s
-5 360 M
-( is a generic catch-all error message; it should be returned if an) s
-5 349 M
-( error occurs for which there is no more specific error code) s
-5 338 M
-( defined.) s
-5 316 M
-( SSH_FX_BAD_MESSAGE) s
-5 305 M
-( may be returned if a badly formatted packet or protocol) s
-5 294 M
-( incompatibility is detected.) s
-5 272 M
-( SSH_FX_NO_CONNECTION) s
-5 261 M
-( is a pseudo-error which indicates that the client has no) s
-5 250 M
-( connection to the server \(it can only be generated locally by the) s
-5 239 M
-( client, and MUST NOT be returned by servers\).) s
-5 217 M
-( SSH_FX_CONNECTION_LOST) s
-5 206 M
-( is a pseudo-error which indicates that the connection to the) s
-5 195 M
-( server has been lost \(it can only be generated locally by the) s
-5 184 M
-( client, and MUST NOT be returned by servers\).) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 21]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 22 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-( SSH_FX_OP_UNSUPPORTED) s
-5 679 M
-( indicates that an attempt was made to perform an operation which) s
-5 668 M
-( is not supported for the server \(it may be generated locally by) s
-5 657 M
-( the client if e.g. the version number exchange indicates that a) s
-5 646 M
-( required feature is not supported by the server, or it may be) s
-5 635 M
-( returned by the server if the server does not implement an) s
-5 624 M
-( operation\).) s
-5 602 M
-( The SSH_FXP_HANDLE response has the following format:) s
-5 580 M
-( uint32 id) s
-5 569 M
-( string handle) s
-5 547 M
-( where `id' is the request identifier, and `handle' is an arbitrary) s
-5 536 M
-( string that identifies an open file or directory on the server. The) s
-5 525 M
-( handle is opaque to the client; the client MUST NOT attempt to) s
-5 514 M
-( interpret or modify it in any way. The length of the handle string) s
-5 503 M
-( MUST NOT exceed 256 data bytes.) s
-5 481 M
-( The SSH_FXP_DATA response has the following format:) s
-5 459 M
-( uint32 id) s
-5 448 M
-( string data) s
-5 426 M
-( where `id' is the request identifier, and `data' is an arbitrary byte) s
-5 415 M
-( string containing the requested data. The data string may be at most) s
-5 404 M
-( the number of bytes requested in a SSH_FXP_READ request, but may also) s
-5 393 M
-( be shorter if end of file is reached or if the read is from something) s
-5 382 M
-( other than a regular file.) s
-5 360 M
-( The SSH_FXP_NAME response has the following format:) s
-5 338 M
-( uint32 id) s
-5 327 M
-( uint32 count) s
-5 316 M
-( repeats count times:) s
-5 305 M
-( string filename) s
-5 294 M
-( string longname) s
-5 283 M
-( ATTRS attrs) s
-5 261 M
-( where `id' is the request identifier, `count' is the number of names) s
-5 250 M
-( returned in this response, and the remaining fields repeat `count') s
-5 239 M
-( times \(so that all three fields are first included for the first) s
-5 228 M
-( file, then for the second file, etc\). In the repeated part,) s
-5 217 M
-( `filename' is a file name being returned \(for SSH_FXP_READDIR, it) s
-5 206 M
-( will be a relative name within the directory, without any path) s
-5 195 M
-( components; for SSH_FXP_REALPATH it will be an absolute path name\),) s
-5 184 M
-( `longname' is an expanded format for the file name, similar to what) s
-5 173 M
-( is returned by "ls -l" on Unix systems, and `attrs' is the attributes) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 22]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (22,23) 12
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 23 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-( of the file as described in Section ``File Attributes''.) s
-5 668 M
-( The format of the `longname' field is unspecified by this protocol.) s
-5 657 M
-( It MUST be suitable for use in the output of a directory listing) s
-5 646 M
-( command \(in fact, the recommended operation for a directory listing) s
-5 635 M
-( command is to simply display this data\). However, clients SHOULD NOT) s
-5 624 M
-( attempt to parse the longname field for file attributes; they SHOULD) s
-5 613 M
-( use the attrs field instead.) s
-5 591 M
-( The recommended format for the longname field is as follows:) s
-5 569 M
-( -rwxr-xr-x 1 mjos staff 348911 Mar 25 14:29 t-filexfer) s
-5 558 M
-( 1234567890 123 12345678 12345678 12345678 123456789012) s
-5 536 M
-( Here, the first line is sample output, and the second field indicates) s
-5 525 M
-( widths of the various fields. Fields are separated by spaces. The) s
-5 514 M
-( first field lists file permissions for user, group, and others; the) s
-5 503 M
-( second field is link count; the third field is the name of the user) s
-5 492 M
-( who owns the file; the fourth field is the name of the group that) s
-5 481 M
-( owns the file; the fifth field is the size of the file in bytes; the) s
-5 470 M
-( sixth field \(which actually may contain spaces, but is fixed to 12) s
-5 459 M
-( characters\) is the file modification time, and the seventh field is) s
-5 448 M
-( the file name. Each field is specified to be a minimum of certain) s
-5 437 M
-( number of character positions \(indicated by the second line above\),) s
-5 426 M
-( but may also be longer if the data does not fit in the specified) s
-5 415 M
-( length.) s
-5 393 M
-( The SSH_FXP_ATTRS response has the following format:) s
-5 371 M
-( uint32 id) s
-5 360 M
-( ATTRS attrs) s
-5 338 M
-( where `id' is the request identifier, and `attrs' is the returned) s
-5 327 M
-( file attributes as described in Section ``File Attributes''.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 23]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 24 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(8. Vendor-Specific Extensions) s
-5 668 M
-( The SSH_FXP_EXTENDED request provides a generic extension mechanism) s
-5 657 M
-( for adding vendor-specific commands. The request has the following) s
-5 646 M
-( format:) s
-5 624 M
-( uint32 id) s
-5 613 M
-( string extended-request) s
-5 602 M
-( ... any request-specific data ...) s
-5 580 M
-( where `id' is the request identifier, and `extended-request' is a) s
-5 569 M
-( string of the format "name@domain", where domain is an internet) s
-5 558 M
-( domain name of the vendor defining the request. The rest of the) s
-5 547 M
-( request is completely vendor-specific, and servers should only) s
-5 536 M
-( attempt to interpret it if they recognize the `extended-request') s
-5 525 M
-( name.) s
-5 503 M
-( The server may respond to such requests using any of the response) s
-5 492 M
-( packets defined in Section ``Responses from the Server to the) s
-5 481 M
-( Client''. Additionally, the server may also respond with a) s
-5 470 M
-( SSH_FXP_EXTENDED_REPLY packet, as defined below. If the server does) s
-5 459 M
-( not recognize the `extended-request' name, then the server MUST) s
-5 448 M
-( respond with SSH_FXP_STATUS with error/status set to) s
-5 437 M
-( SSH_FX_OP_UNSUPPORTED.) s
-5 415 M
-( The SSH_FXP_EXTENDED_REPLY packet can be used to carry arbitrary) s
-5 404 M
-( extension-specific data from the server to the client. It is of the) s
-5 393 M
-( following format:) s
-5 371 M
-( uint32 id) s
-5 360 M
-( ... any request-specific data ...) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 24]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (24,25) 13
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 25 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(9. Security Considerations) s
-5 668 M
-( This protocol assumes that it is run over a secure channel and that) s
-5 657 M
-( the endpoints of the channel have been authenticated. Thus, this) s
-5 646 M
-( protocol assumes that it is externally protected from network-level) s
-5 635 M
-( attacks.) s
-5 613 M
-( This protocol provides file system access to arbitrary files on the) s
-5 602 M
-( server \(only constrained by the server implementation\). It is the) s
-5 591 M
-( responsibility of the server implementation to enforce any access) s
-5 580 M
-( controls that may be required to limit the access allowed for any) s
-5 569 M
-( particular user \(the user being authenticated externally to this) s
-5 558 M
-( protocol, typically using the SSH User Authentication Protocol [6].) s
-5 536 M
-( Care must be taken in the server implementation to check the validity) s
-5 525 M
-( of received file handle strings. The server should not rely on them) s
-5 514 M
-( directly; it MUST check the validity of each handle before relying on) s
-5 503 M
-( it.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 25]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 26 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(10. Changes from previous protocol versions) s
-5 668 M
-( The SSH File Transfer Protocol has changed over time, before it's) s
-5 657 M
-( standardization. The following is a description of the incompatible) s
-5 646 M
-( changes between different versions.) s
-5 624 M
-(10.1 Changes between versions 3 and 2) s
-5 602 M
-( o The SSH_FXP_READLINK and SSH_FXP_SYMLINK messages were added.) s
-5 580 M
-( o The SSH_FXP_EXTENDED and SSH_FXP_EXTENDED_REPLY messages were) s
-5 569 M
-( added.) s
-5 547 M
-( o The SSH_FXP_STATUS message was changed to include fields `error) s
-5 536 M
-( message' and `language tag'.) s
-5 503 M
-(10.2 Changes between versions 2 and 1) s
-5 481 M
-( o The SSH_FXP_RENAME message was added.) s
-5 448 M
-(10.3 Changes between versions 1 and 0) s
-5 426 M
-( o Implementation changes, no actual protocol changes.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 26]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (26,27) 14
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 27 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(11. Trademark Issues) s
-5 668 M
-( "ssh" is a registered trademark of SSH Communications Security Corp) s
-5 657 M
-( in the United States and/or other countries.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 27]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 28 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(References) s
-5 668 M
-( [1] Dierks, T., Allen, C., Treese, W., Karlton, P., Freier, A. and) s
-5 657 M
-( P. Kocher, "The TLS Protocol Version 1.0", RFC 2246, January) s
-5 646 M
-( 1999.) s
-5 624 M
-( [2] Institute of Electrical and Electronics Engineers, "Information) s
-5 613 M
-( Technology - Portable Operating System Interface \(POSIX\) - Part) s
-5 602 M
-( 1: System Application Program Interface \(API\) [C Language]",) s
-5 591 M
-( IEEE Standard 1003.2, 1996.) s
-5 569 M
-( [3] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.) s
-5 558 M
-( Lehtinen, "SSH Protocol Architecture", draft-ietf-secsh-) s
-5 547 M
-( architecture-09 \(work in progress\), July 2001.) s
-5 525 M
-( [4] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.) s
-5 514 M
-( Lehtinen, "SSH Protocol Transport Protocol", draft-ietf-secsh-) s
-5 503 M
-( architecture-09 \(work in progress\), July 2001.) s
-5 481 M
-( [5] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.) s
-5 470 M
-( Lehtinen, "SSH Connection Protocol", draft-ietf-secsh-connect-11) s
-5 459 M
-( \(work in progress\), July 2001.) s
-5 437 M
-( [6] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.) s
-5 426 M
-( Lehtinen, "SSH Authentication Protocol", draft-ietf-secsh-) s
-5 415 M
-( userauth-11 \(work in progress\), July 2001.) s
-5 382 M
-(Authors' Addresses) s
-5 360 M
-( Tatu Ylonen) s
-5 349 M
-( SSH Communications Security Corp) s
-5 338 M
-( Fredrikinkatu 42) s
-5 327 M
-( HELSINKI FIN-00100) s
-5 316 M
-( Finland) s
-5 294 M
-( EMail: [email protected]) s
-5 261 M
-( Sami Lehtinen) s
-5 250 M
-( SSH Communications Security Corp) s
-5 239 M
-( Fredrikinkatu 42) s
-5 228 M
-( HELSINKI FIN-00100) s
-5 217 M
-( Finland) s
-5 195 M
-( EMail: [email protected]) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 28]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (28,29) 15
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 29 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(Full Copyright Statement) s
-5 668 M
-( Copyright \(C\) The Internet Society \(2001\). All Rights Reserved.) s
-5 646 M
-( This document and translations of it may be copied and furnished to) s
-5 635 M
-( others, and derivative works that comment on or otherwise explain it) s
-5 624 M
-( or assist in its implementation may be prepared, copied, published) s
-5 613 M
-( and distributed, in whole or in part, without restriction of any) s
-5 602 M
-( kind, provided that the above copyright notice and this paragraph are) s
-5 591 M
-( included on all such copies and derivative works. However, this) s
-5 580 M
-( document itself may not be modified in any way, such as by removing) s
-5 569 M
-( the copyright notice or references to the Internet Society or other) s
-5 558 M
-( Internet organizations, except as needed for the purpose of) s
-5 547 M
-( developing Internet standards in which case the procedures for) s
-5 536 M
-( copyrights defined in the Internet Standards process must be) s
-5 525 M
-( followed, or as required to translate it into languages other than) s
-5 514 M
-( English.) s
-5 492 M
-( The limited permissions granted above are perpetual and will not be) s
-5 481 M
-( revoked by the Internet Society or its successors or assigns.) s
-5 459 M
-( This document and the information contained herein is provided on an) s
-5 448 M
-( "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING) s
-5 437 M
-( TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING) s
-5 426 M
-( BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION) s
-5 415 M
-( HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF) s
-5 404 M
-( MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.) s
-5 382 M
-(Acknowledgement) s
-5 360 M
-( Funding for the RFC Editor function is currently provided by the) s
-5 349 M
-( Internet Society.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 29]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 30 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-_R
-S
-PStoPSsaved restore
-%%Trailer
-%%Pages: 30
-%%DocumentNeededResources: font Courier-Bold Courier
-%%EOF
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-02.txt b/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-02.txt
deleted file mode 100644
index c4ec8c1125..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-02.txt
+++ /dev/null
@@ -1,1627 +0,0 @@
-
-
-
-Network Working Group T. Ylonen
-Internet-Draft S. Lehtinen
-Expires: April 1, 2002 SSH Communications Security Corp
- October 2001
-
-
- SSH File Transfer Protocol
- draft-ietf-secsh-filexfer-02.txt
-
-Status of this Memo
-
- This document is an Internet-Draft and is in full conformance with
- all provisions of Section 10 of RFC2026.
-
- Internet-Drafts are working documents of the Internet Engineering
- Task Force (IETF), its areas, and its working groups. Note that
- other groups may also distribute working documents as Internet-
- Drafts.
-
- Internet-Drafts are draft documents valid for a maximum of six months
- and may be updated, replaced, or obsoleted by other documents at any
- time. It is inappropriate to use Internet-Drafts as reference
- material or to cite them other than as "work in progress."
-
- The list of current Internet-Drafts can be accessed at http://
- www.ietf.org/ietf/1id-abstracts.txt.
-
- The list of Internet-Draft Shadow Directories can be accessed at
- http://www.ietf.org/shadow.html.
-
- This Internet-Draft will expire on April 1, 2002.
-
-Copyright Notice
-
- Copyright (C) The Internet Society (2001). All Rights Reserved.
-
-Abstract
-
- The SSH File Transfer Protocol provides secure file transfer
- functionality over any reliable data stream. It is the standard file
- transfer protocol for use with the SSH2 protocol. This document
- describes the file transfer protocol and its interface to the SSH2
- protocol suite.
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 1]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-Table of Contents
-
- 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3
- 2. Use with the SSH Connection Protocol . . . . . . . . . . . . 4
- 3. General Packet Format . . . . . . . . . . . . . . . . . . . 5
- 4. Protocol Initialization . . . . . . . . . . . . . . . . . . 7
- 5. File Attributes . . . . . . . . . . . . . . . . . . . . . . 8
- 6. Requests From the Client to the Server . . . . . . . . . . . 10
- 6.1 Request Synchronization and Reordering . . . . . . . . . . . 10
- 6.2 File Names . . . . . . . . . . . . . . . . . . . . . . . . . 11
- 6.3 Opening, Creating, and Closing Files . . . . . . . . . . . . 11
- 6.4 Reading and Writing . . . . . . . . . . . . . . . . . . . . 13
- 6.5 Removing and Renaming Files . . . . . . . . . . . . . . . . 14
- 6.6 Creating and Deleting Directories . . . . . . . . . . . . . 15
- 6.7 Scanning Directories . . . . . . . . . . . . . . . . . . . . 15
- 6.8 Retrieving File Attributes . . . . . . . . . . . . . . . . . 16
- 6.9 Setting File Attributes . . . . . . . . . . . . . . . . . . 17
- 6.10 Dealing with Symbolic links . . . . . . . . . . . . . . . . 18
- 6.11 Canonicalizing the Server-Side Path Name . . . . . . . . . . 18
- 7. Responses from the Server to the Client . . . . . . . . . . 20
- 8. Vendor-Specific Extensions . . . . . . . . . . . . . . . . . 24
- 9. Security Considerations . . . . . . . . . . . . . . . . . . 25
- 10. Changes from previous protocol versions . . . . . . . . . . 26
- 10.1 Changes between versions 3 and 2 . . . . . . . . . . . . . . 26
- 10.2 Changes between versions 2 and 1 . . . . . . . . . . . . . . 26
- 10.3 Changes between versions 1 and 0 . . . . . . . . . . . . . . 26
- 11. Trademark Issues . . . . . . . . . . . . . . . . . . . . . . 27
- References . . . . . . . . . . . . . . . . . . . . . . . . . 28
- Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 28
- Full Copyright Statement . . . . . . . . . . . . . . . . . . 29
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 2]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-1. Introduction
-
- This protocol provides secure file transfer (and more generally file
- system access) functionality over a reliable data stream, such as a
- channel in the SSH2 protocol [3].
-
- This protocol is designed so that it could be used to implement a
- secure remote file system service, as well as a secure file transfer
- service.
-
- This protocol assumes that it runs over a secure channel, and that
- the server has already authenticated the user at the client end, and
- that the identity of the client user is externally available to the
- server implementation.
-
- In general, this protocol follows a simple request-response model.
- Each request and response contains a sequence number and multiple
- requests may be pending simultaneously. There are a relatively large
- number of different request messages, but a small number of possible
- response messages. Each request has one or more response messages
- that may be returned in result (e.g., a read either returns data or
- reports error status).
-
- The packet format descriptions in this specification follow the
- notation presented in the secsh architecture draft.[3].
-
- Even though this protocol is described in the context of the SSH2
- protocol, this protocol is general and independent of the rest of the
- SSH2 protocol suite. It could be used in a number of different
- applications, such as secure file transfer over TLS RFC 2246 [1] and
- transfer of management information in VPN applications.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 3]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-2. Use with the SSH Connection Protocol
-
- When used with the SSH2 Protocol suite, this protocol is intended to
- be used from the SSH Connection Protocol [5] as a subsystem, as
- described in section ``Starting a Shell or a Command''. The
- subsystem name used with this protocol is "sftp".
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 4]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-3. General Packet Format
-
- All packets transmitted over the secure connection are of the
- following format:
-
- uint32 length
- byte type
- byte[length - 1] data payload
-
- That is, they are just data preceded by 32-bit length and 8-bit type
- fields. The `length' is the length of the data area, and does not
- include the `length' field itself. The format and interpretation of
- the data area depends on the packet type.
-
- All packet descriptions below only specify the packet type and the
- data that goes into the data field. Thus, they should be prefixed by
- the `length' and `type' fields.
-
- The maximum size of a packet is in practice determined by the client
- (the maximum size of read or write requests that it sends, plus a few
- bytes of packet overhead). All servers SHOULD support packets of at
- least 34000 bytes (where the packet size refers to the full length,
- including the header above). This should allow for reads and writes
- of at most 32768 bytes.
-
- There is no limit on the number of outstanding (non-acknowledged)
- requests that the client may send to the server. In practice this is
- limited by the buffering available on the data stream and the queuing
- performed by the server. If the server's queues are full, it should
- not read any more data from the stream, and flow control will prevent
- the client from sending more requests. Note, however, that while
- there is no restriction on the protocol level, the client's API may
- provide a limit in order to prevent infinite queuing of outgoing
- requests at the client.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 5]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
- The following values are defined for packet types.
-
- #define SSH_FXP_INIT 1
- #define SSH_FXP_VERSION 2
- #define SSH_FXP_OPEN 3
- #define SSH_FXP_CLOSE 4
- #define SSH_FXP_READ 5
- #define SSH_FXP_WRITE 6
- #define SSH_FXP_LSTAT 7
- #define SSH_FXP_FSTAT 8
- #define SSH_FXP_SETSTAT 9
- #define SSH_FXP_FSETSTAT 10
- #define SSH_FXP_OPENDIR 11
- #define SSH_FXP_READDIR 12
- #define SSH_FXP_REMOVE 13
- #define SSH_FXP_MKDIR 14
- #define SSH_FXP_RMDIR 15
- #define SSH_FXP_REALPATH 16
- #define SSH_FXP_STAT 17
- #define SSH_FXP_RENAME 18
- #define SSH_FXP_READLINK 19
- #define SSH_FXP_SYMLINK 20
- #define SSH_FXP_STATUS 101
- #define SSH_FXP_HANDLE 102
- #define SSH_FXP_DATA 103
- #define SSH_FXP_NAME 104
- #define SSH_FXP_ATTRS 105
- #define SSH_FXP_EXTENDED 200
- #define SSH_FXP_EXTENDED_REPLY 201
-
- Additional packet types should only be defined if the protocol
- version number (see Section ``Protocol Initialization'') is
- incremented, and their use MUST be negotiated using the version
- number. However, the SSH_FXP_EXTENDED and SSH_FXP_EXTENDED_REPLY
- packets can be used to implement vendor-specific extensions. See
- Section ``Vendor-Specific-Extensions'' for more details.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 6]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-4. Protocol Initialization
-
- When the file transfer protocol starts, it first sends a SSH_FXP_INIT
- (including its version number) packet to the server. The server
- responds with a SSH_FXP_VERSION packet, supplying the lowest of its
- own and the client's version number. Both parties should from then
- on adhere to particular version of the protocol.
-
- The SSH_FXP_INIT packet (from client to server) has the following
- data:
-
- uint32 version
- <extension data>
-
- The SSH_FXP_VERSION packet (from server to client) has the following
- data:
-
- uint32 version
- <extension data>
-
- The version number of the protocol specified in this document is 3.
- The version number should be incremented for each incompatible
- revision of this protocol.
-
- The extension data in the above packets may be empty, or may be a
- sequence of
-
- string extension_name
- string extension_data
-
- pairs (both strings MUST always be present if one is, but the
- `extension_data' string may be of zero length). If present, these
- strings indicate extensions to the baseline protocol. The
- `extension_name' field(s) identify the name of the extension. The
- name should be of the form "name@domain", where the domain is the DNS
- domain name of the organization defining the extension. Additional
- names that are not of this format may be defined later by the IETF.
- Implementations MUST silently ignore any extensions whose name they
- do not recognize.
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 7]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-5. File Attributes
-
- A new compound data type is defined for encoding file attributes. It
- is basically just a combination of elementary types, but is defined
- once because of the non-trivial description of the fields and to
- ensure maintainability.
-
- The same encoding is used both when returning file attributes from
- the server and when sending file attributes to the server. When
- sending it to the server, the flags field specifies which attributes
- are included, and the server will use default values for the
- remaining attributes (or will not modify the values of remaining
- attributes). When receiving attributes from the server, the flags
- specify which attributes are included in the returned data. The
- server normally returns all attributes it knows about.
-
- uint32 flags
- uint64 size present only if flag SSH_FILEXFER_ATTR_SIZE
- uint32 uid present only if flag SSH_FILEXFER_ATTR_UIDGID
- uint32 gid present only if flag SSH_FILEXFER_ATTR_UIDGID
- uint32 permissions present only if flag SSH_FILEXFER_ATTR_PERMISSIONS
- uint32 atime present only if flag SSH_FILEXFER_ACMODTIME
- uint32 mtime present only if flag SSH_FILEXFER_ACMODTIME
- uint32 extended_count present only if flag SSH_FILEXFER_ATTR_EXTENDED
- string extended_type
- string extended_data
- ... more extended data (extended_type - extended_data pairs),
- so that number of pairs equals extended_count
-
- The `flags' specify which of the fields are present. Those fields
- for which the corresponding flag is not set are not present (not
- included in the packet). New flags can only be added by incrementing
- the protocol version number (or by using the extension mechanism
- described below).
-
- The `size' field specifies the size of the file in bytes.
-
- The `uid' and `gid' fields contain numeric Unix-like user and group
- identifiers, respectively.
-
- The `permissions' field contains a bit mask of file permissions as
- defined by posix [1].
-
- The `atime' and `mtime' contain the access and modification times of
- the files, respectively. They are represented as seconds from Jan 1,
- 1970 in UTC.
-
- The SSH_FILEXFER_ATTR_EXTENDED flag provides a general extension
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 8]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
- mechanism for vendor-specific extensions. If the flag is specified,
- then the `extended_count' field is present. It specifies the number
- of extended_type-extended_data pairs that follow. Each of these
- pairs specifies an extended attribute. For each of the attributes,
- the extended_type field should be a string of the format
- "name@domain", where "domain" is a valid, registered domain name and
- "name" identifies the method. The IETF may later standardize certain
- names that deviate from this format (e.g., that do not contain the
- "@" sign). The interpretation of `extended_data' depends on the
- type. Implementations SHOULD ignore extended data fields that they
- do not understand.
-
- Additional fields can be added to the attributes by either defining
- additional bits to the flags field to indicate their presence, or by
- defining extended attributes for them. The extended attributes
- mechanism is recommended for most purposes; additional flags bits
- should only be defined by an IETF standards action that also
- increments the protocol version number. The use of such new fields
- MUST be negotiated by the version number in the protocol exchange.
- It is a protocol error if a packet with unsupported protocol bits is
- received.
-
- The flags bits are defined to have the following values:
-
- #define SSH_FILEXFER_ATTR_SIZE 0x00000001
- #define SSH_FILEXFER_ATTR_UIDGID 0x00000002
- #define SSH_FILEXFER_ATTR_PERMISSIONS 0x00000004
- #define SSH_FILEXFER_ATTR_ACMODTIME 0x00000008
- #define SSH_FILEXFER_ATTR_EXTENDED 0x80000000
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 9]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-6. Requests From the Client to the Server
-
- Requests from the client to the server represent the various file
- system operations. Each request begins with an `id' field, which is
- a 32-bit identifier identifying the request (selected by the client).
- The same identifier will be returned in the response to the request.
- One possible implementation of it is a monotonically increasing
- request sequence number (modulo 2^32).
-
- Many operations in the protocol operate on open files. The
- SSH_FXP_OPEN request can return a file handle (which is an opaque
- variable-length string) which may be used to access the file later
- (e.g. in a read operation). The client MUST NOT send requests the
- server with bogus or closed handles. However, the server MUST
- perform adequate checks on the handle in order to avoid security
- risks due to fabricated handles.
-
- This design allows either stateful and stateless server
- implementation, as well as an implementation which caches state
- between requests but may also flush it. The contents of the file
- handle string are entirely up to the server and its design. The
- client should not modify or attempt to interpret the file handle
- strings.
-
- The file handle strings MUST NOT be longer than 256 bytes.
-
-6.1 Request Synchronization and Reordering
-
- The protocol and implementations MUST process requests relating to
- the same file in the order in which they are received. In other
- words, if an application submits multiple requests to the server, the
- results in the responses will be the same as if it had sent the
- requests one at a time and waited for the response in each case. For
- example, the server may process non-overlapping read/write requests
- to the same file in parallel, but overlapping reads and writes cannot
- be reordered or parallelized. However, there are no ordering
- restrictions on the server for processing requests from two different
- file transfer connections. The server may interleave and parallelize
- them at will.
-
- There are no restrictions on the order in which responses to
- outstanding requests are delivered to the client, except that the
- server must ensure fairness in the sense that processing of no
- request will be indefinitely delayed even if the client is sending
- other requests so that there are multiple outstanding requests all
- the time.
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 10]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-6.2 File Names
-
- This protocol represents file names as strings. File names are
- assumed to use the slash ('/') character as a directory separator.
-
- File names starting with a slash are "absolute", and are relative to
- the root of the file system. Names starting with any other character
- are relative to the user's default directory (home directory). Note
- that identifying the user is assumed to take place outside of this
- protocol.
-
- Servers SHOULD interpret a path name component ".." as referring to
- the parent directory, and "." as referring to the current directory.
- If the server implementation limits access to certain parts of the
- file system, it must be extra careful in parsing file names when
- enforcing such restrictions. There have been numerous reported
- security bugs where a ".." in a path name has allowed access outside
- the intended area.
-
- An empty path name is valid, and it refers to the user's default
- directory (usually the user's home directory).
-
- Otherwise, no syntax is defined for file names by this specification.
- Clients should not make any other assumptions; however, they can
- splice path name components returned by SSH_FXP_READDIR together
- using a slash ('/') as the separator, and that will work as expected.
-
- It is understood that the lack of well-defined semantics for file
- names may cause interoperability problems between clients and servers
- using radically different operating systems. However, this approach
- is known to work acceptably with most systems, and alternative
- approaches that e.g. treat file names as sequences of structured
- components are quite complicated.
-
-6.3 Opening, Creating, and Closing Files
-
- Files are opened and created using the SSH_FXP_OPEN message, whose
- data part is as follows:
-
- uint32 id
- string filename
- uint32 pflags
- ATTRS attrs
-
- The `id' field is the request identifier as for all requests.
-
- The `filename' field specifies the file name. See Section ``File
- Names'' for more information.
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 11]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
- The `pflags' field is a bitmask. The following bits have been
- defined.
-
- #define SSH_FXF_READ 0x00000001
- #define SSH_FXF_WRITE 0x00000002
- #define SSH_FXF_APPEND 0x00000004
- #define SSH_FXF_CREAT 0x00000008
- #define SSH_FXF_TRUNC 0x00000010
- #define SSH_FXF_EXCL 0x00000020
-
- These have the following meanings:
-
- SSH_FXF_READ
- Open the file for reading.
-
- SSH_FXF_WRITE
- Open the file for writing. If both this and SSH_FXF_READ are
- specified, the file is opened for both reading and writing.
-
- SSH_FXF_APPEND
- Force all writes to append data at the end of the file.
-
- SSH_FXF_CREAT
- If this flag is specified, then a new file will be created if one
- does not already exist (if O_TRUNC is specified, the new file will
- be truncated to zero length if it previously exists).
-
- SSH_FXF_TRUNC
- Forces an existing file with the same name to be truncated to zero
- length when creating a file by specifying SSH_FXF_CREAT.
- SSH_FXF_CREAT MUST also be specified if this flag is used.
-
- SSH_FXF_EXCL
- Causes the request to fail if the named file already exists.
- SSH_FXF_CREAT MUST also be specified if this flag is used.
-
- The `attrs' field specifies the initial attributes for the file.
- Default values will be used for those attributes that are not
- specified. See Section ``File Attributes'' for more information.
-
- Regardless the server operating system, the file will always be
- opened in "binary" mode (i.e., no translations between different
- character sets and newline encodings).
-
- The response to this message will be either SSH_FXP_HANDLE (if the
- operation is successful) or SSH_FXP_STATUS (if the operation fails).
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 12]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
- A file is closed by using the SSH_FXP_CLOSE request. Its data field
- has the following format:
-
- uint32 id
- string handle
-
- where `id' is the request identifier, and `handle' is a handle
- previously returned in the response to SSH_FXP_OPEN or
- SSH_FXP_OPENDIR. The handle becomes invalid immediately after this
- request has been sent.
-
- The response to this request will be a SSH_FXP_STATUS message. One
- should note that on some server platforms even a close can fail.
- This can happen e.g. if the server operating system caches writes,
- and an error occurs while flushing cached writes during the close.
-
-6.4 Reading and Writing
-
- Once a file has been opened, it can be read using the SSH_FXP_READ
- message, which has the following format:
-
- uint32 id
- string handle
- uint64 offset
- uint32 len
-
- where `id' is the request identifier, `handle' is an open file handle
- returned by SSH_FXP_OPEN, `offset' is the offset (in bytes) relative
- to the beginning of the file from where to start reading, and `len'
- is the maximum number of bytes to read.
-
- In response to this request, the server will read as many bytes as it
- can from the file (up to `len'), and return them in a SSH_FXP_DATA
- message. If an error occurs or EOF is encountered before reading any
- data, the server will respond with SSH_FXP_STATUS. For normal disk
- files, it is guaranteed that this will read the specified number of
- bytes, or up to end of file. For e.g. device files this may return
- fewer bytes than requested.
-
- Writing to a file is achieved using the SSH_FXP_WRITE message, which
- has the following format:
-
- uint32 id
- string handle
- uint64 offset
- string data
-
- where `id' is a request identifier, `handle' is a file handle
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 13]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
- returned by SSH_FXP_OPEN, `offset' is the offset (in bytes) from the
- beginning of the file where to start writing, and `data' is the data
- to be written.
-
- The write will extend the file if writing beyond the end of the file.
- It is legal to write way beyond the end of the file; the semantics
- are to write zeroes from the end of the file to the specified offset
- and then the data. On most operating systems, such writes do not
- allocate disk space but instead leave "holes" in the file.
-
- The server responds to a write request with a SSH_FXP_STATUS message.
-
-6.5 Removing and Renaming Files
-
- Files can be removed using the SSH_FXP_REMOVE message. It has the
- following format:
-
- uint32 id
- string filename
-
- where `id' is the request identifier and `filename' is the name of
- the file to be removed. See Section ``File Names'' for more
- information. This request cannot be used to remove directories.
-
- The server will respond to this request with a SSH_FXP_STATUS
- message.
-
- Files (and directories) can be renamed using the SSH_FXP_RENAME
- message. Its data is as follows:
-
- uint32 id
- string oldpath
- string newpath
-
- where `id' is the request identifier, `oldpath' is the name of an
- existing file or directory, and `newpath' is the new name for the
- file or directory. It is an error if there already exists a file
- with the name specified by newpath. The server may also fail rename
- requests in other situations, for example if `oldpath' and `newpath'
- point to different file systems on the server.
-
- The server will respond to this request with a SSH_FXP_STATUS
- message.
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 14]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-6.6 Creating and Deleting Directories
-
- New directories can be created using the SSH_FXP_MKDIR request. It
- has the following format:
-
- uint32 id
- string path
- ATTRS attrs
-
- where `id' is the request identifier, `path' and `attrs' specifies
- the modifications to be made to its attributes. See Section ``File
- Names'' for more information on file names. Attributes are discussed
- in more detail in Section ``File Attributes''. specifies the
- directory to be created. An error will be returned if a file or
- directory with the specified path already exists. The server will
- respond to this request with a SSH_FXP_STATUS message.
-
- Directories can be removed using the SSH_FXP_RMDIR request, which
- has the following format:
-
- uint32 id
- string path
-
- where `id' is the request identifier, and `path' specifies the
- directory to be removed. See Section ``File Names'' for more
- information on file names. An error will be returned if no directory
- with the specified path exists, or if the specified directory is not
- empty, or if the path specified a file system object other than a
- directory. The server responds to this request with a SSH_FXP_STATUS
- message.
-
-6.7 Scanning Directories
-
- The files in a directory can be listed using the SSH_FXP_OPENDIR and
- SSH_FXP_READDIR requests. Each SSH_FXP_READDIR request returns one
- or more file names with full file attributes for each file. The
- client should call SSH_FXP_READDIR repeatedly until it has found the
- file it is looking for or until the server responds with a
- SSH_FXP_STATUS message indicating an error (normally SSH_FX_EOF if
- there are no more files in the directory). The client should then
- close the handle using the SSH_FXP_CLOSE request.
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 15]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
- The SSH_FXP_OPENDIR opens a directory for reading. It has the
- following format:
-
- uint32 id
- string path
-
- where `id' is the request identifier and `path' is the path name of
- the directory to be listed (without any trailing slash). See Section
- ``File Names'' for more information on file names. This will return
- an error if the path does not specify a directory or if the directory
- is not readable. The server will respond to this request with either
- a SSH_FXP_HANDLE or a SSH_FXP_STATUS message.
-
- Once the directory has been successfully opened, files (and
- directories) contained in it can be listed using SSH_FXP_READDIR
- requests. These are of the format
-
- uint32 id
- string handle
-
- where `id' is the request identifier, and `handle' is a handle
- returned by SSH_FXP_OPENDIR. (It is a protocol error to attempt to
- use an ordinary file handle returned by SSH_FXP_OPEN.)
-
- The server responds to this request with either a SSH_FXP_NAME or a
- SSH_FXP_STATUS message. One or more names may be returned at a time.
- Full status information is returned for each name in order to speed
- up typical directory listings.
-
- When the client no longer wishes to read more names from the
- directory, it SHOULD call SSH_FXP_CLOSE for the handle. The handle
- should be closed regardless of whether an error has occurred or not.
-
-6.8 Retrieving File Attributes
-
- Very often, file attributes are automatically returned by
- SSH_FXP_READDIR. However, sometimes there is need to specifically
- retrieve the attributes for a named file. This can be done using the
- SSH_FXP_STAT, SSH_FXP_LSTAT and SSH_FXP_FSTAT requests.
-
- SSH_FXP_STAT and SSH_FXP_LSTAT only differ in that SSH_FXP_STAT
- follows symbolic links on the server, whereas SSH_FXP_LSTAT does not
- follow symbolic links. Both have the same format:
-
- uint32 id
- string path
-
- where `id' is the request identifier, and `path' specifies the file
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 16]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
- system object for which status is to be returned. The server
- responds to this request with either SSH_FXP_ATTRS or SSH_FXP_STATUS.
-
- SSH_FXP_FSTAT differs from the others in that it returns status
- information for an open file (identified by the file handle). Its
- format is as follows:
-
- uint32 id
- string handle
-
- where `id' is the request identifier and `handle' is a file handle
- returned by SSH_FXP_OPEN. The server responds to this request with
- SSH_FXP_ATTRS or SSH_FXP_STATUS.
-
-6.9 Setting File Attributes
-
- File attributes may be modified using the SSH_FXP_SETSTAT and
- SSH_FXP_FSETSTAT requests. These requests are used for operations
- such as changing the ownership, permissions or access times, as well
- as for truncating a file.
-
- The SSH_FXP_SETSTAT request is of the following format:
-
- uint32 id
- string path
- ATTRS attrs
-
- where `id' is the request identifier, `path' specifies the file
- system object (e.g. file or directory) whose attributes are to be
- modified, and `attrs' specifies the modifications to be made to its
- attributes. Attributes are discussed in more detail in Section
- ``File Attributes''.
-
- An error will be returned if the specified file system object does
- not exist or the user does not have sufficient rights to modify the
- specified attributes. The server responds to this request with a
- SSH_FXP_STATUS message.
-
- The SSH_FXP_FSETSTAT request modifies the attributes of a file which
- is already open. It has the following format:
-
- uint32 id
- string handle
- ATTRS attrs
-
- where `id' is the request identifier, `handle' (MUST be returned by
- SSH_FXP_OPEN) identifies the file whose attributes are to be
- modified, and `attrs' specifies the modifications to be made to its
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 17]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
- attributes. Attributes are discussed in more detail in Section
- ``File Attributes''. The server will respond to this request with
- SSH_FXP_STATUS.
-
-6.10 Dealing with Symbolic links
-
- The SSH_FXP_READLINK request may be used to read the target of a
- symbolic link. It would have a data part as follows:
-
- uint32 id
- string path
-
- where `id' is the request identifier and `path' specifies the path
- name of the symlink to be read.
-
- The server will respond with a SSH_FXP_NAME packet containing only
- one name and a dummy attributes value. The name in the returned
- packet contains the target of the link. If an error occurs, the
- server may respond with SSH_FXP_STATUS.
-
- The SSH_FXP_SYMLINK request will create a symbolic link on the
- server. It is of the following format
-
- uint32 id
- string linkpath
- string targetpath
-
- where `id' is the request identifier, `linkpath' specifies the path
- name of the symlink to be created and `targetpath' specifies the
- target of the symlink. The server shall respond with a
- SSH_FXP_STATUS indicating either success (SSH_FX_OK) or an error
- condition.
-
-6.11 Canonicalizing the Server-Side Path Name
-
- The SSH_FXP_REALPATH request can be used to have the server
- canonicalize any given path name to an absolute path. This is useful
- for converting path names containing ".." components or relative
- pathnames without a leading slash into absolute paths. The format of
- the request is as follows:
-
- uint32 id
- string path
-
- where `id' is the request identifier and `path' specifies the path
- name to be canonicalized. The server will respond with a
- SSH_FXP_NAME packet containing only one name and a dummy attributes
- value. The name is the returned packet will be in canonical form.
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 18]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
- If an error occurs, the server may also respond with SSH_FXP_STATUS.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 19]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-7. Responses from the Server to the Client
-
- The server responds to the client using one of a few response
- packets. All requests can return a SSH_FXP_STATUS response upon
- failure. When the operation is successful, any of the responses may
- be returned (depending on the operation). If no data needs to be
- returned to the client, the SSH_FXP_STATUS response with SSH_FX_OK
- status is appropriate. Otherwise, the SSH_FXP_HANDLE message is used
- to return a file handle (for SSH_FXP_OPEN and SSH_FXP_OPENDIR
- requests), SSH_FXP_DATA is used to return data from SSH_FXP_READ,
- SSH_FXP_NAME is used to return one or more file names from a
- SSH_FXP_READDIR or SSH_FXP_REALPATH request, and SSH_FXP_ATTRS is
- used to return file attributes from SSH_FXP_STAT, SSH_FXP_LSTAT, and
- SSH_FXP_FSTAT requests.
-
- Exactly one response will be returned for each request. Each
- response packet contains a request identifier which can be used to
- match each response with the corresponding request. Note that it is
- legal to have several requests outstanding simultaneously, and the
- server is allowed to send responses to them in a different order from
- the order in which the requests were sent (the result of their
- execution, however, is guaranteed to be as if they had been processed
- one at a time in the order in which the requests were sent).
-
- Response packets are of the same general format as request packets.
- Each response packet begins with the request identifier.
-
- The format of the data portion of the SSH_FXP_STATUS response is as
- follows:
-
- uint32 id
- uint32 error/status code
- string error message (ISO-10646 UTF-8 [RFC-2279])
- string language tag (as defined in [RFC-1766])
-
- where `id' is the request identifier, and `error/status code'
- indicates the result of the requested operation. The value SSH_FX_OK
- indicates success, and all other values indicate failure.
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 20]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
- Currently, the following values are defined (other values may be
- defined by future versions of this protocol):
-
- #define SSH_FX_OK 0
- #define SSH_FX_EOF 1
- #define SSH_FX_NO_SUCH_FILE 2
- #define SSH_FX_PERMISSION_DENIED 3
- #define SSH_FX_FAILURE 4
- #define SSH_FX_BAD_MESSAGE 5
- #define SSH_FX_NO_CONNECTION 6
- #define SSH_FX_CONNECTION_LOST 7
- #define SSH_FX_OP_UNSUPPORTED 8
-
- SSH_FX_OK
- Indicates successful completion of the operation.
-
- SSH_FX_EOF
- indicates end-of-file condition; for SSH_FX_READ it means that no
- more data is available in the file, and for SSH_FX_READDIR it
- indicates that no more files are contained in the directory.
-
- SSH_FX_NO_SUCH_FILE
- is returned when a reference is made to a file which should exist
- but doesn't.
-
- SSH_FX_PERMISSION_DENIED
- is returned when the authenticated user does not have sufficient
- permissions to perform the operation.
-
- SSH_FX_FAILURE
- is a generic catch-all error message; it should be returned if an
- error occurs for which there is no more specific error code
- defined.
-
- SSH_FX_BAD_MESSAGE
- may be returned if a badly formatted packet or protocol
- incompatibility is detected.
-
- SSH_FX_NO_CONNECTION
- is a pseudo-error which indicates that the client has no
- connection to the server (it can only be generated locally by the
- client, and MUST NOT be returned by servers).
-
- SSH_FX_CONNECTION_LOST
- is a pseudo-error which indicates that the connection to the
- server has been lost (it can only be generated locally by the
- client, and MUST NOT be returned by servers).
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 21]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
- SSH_FX_OP_UNSUPPORTED
- indicates that an attempt was made to perform an operation which
- is not supported for the server (it may be generated locally by
- the client if e.g. the version number exchange indicates that a
- required feature is not supported by the server, or it may be
- returned by the server if the server does not implement an
- operation).
-
- The SSH_FXP_HANDLE response has the following format:
-
- uint32 id
- string handle
-
- where `id' is the request identifier, and `handle' is an arbitrary
- string that identifies an open file or directory on the server. The
- handle is opaque to the client; the client MUST NOT attempt to
- interpret or modify it in any way. The length of the handle string
- MUST NOT exceed 256 data bytes.
-
- The SSH_FXP_DATA response has the following format:
-
- uint32 id
- string data
-
- where `id' is the request identifier, and `data' is an arbitrary byte
- string containing the requested data. The data string may be at most
- the number of bytes requested in a SSH_FXP_READ request, but may also
- be shorter if end of file is reached or if the read is from something
- other than a regular file.
-
- The SSH_FXP_NAME response has the following format:
-
- uint32 id
- uint32 count
- repeats count times:
- string filename
- string longname
- ATTRS attrs
-
- where `id' is the request identifier, `count' is the number of names
- returned in this response, and the remaining fields repeat `count'
- times (so that all three fields are first included for the first
- file, then for the second file, etc). In the repeated part,
- `filename' is a file name being returned (for SSH_FXP_READDIR, it
- will be a relative name within the directory, without any path
- components; for SSH_FXP_REALPATH it will be an absolute path name),
- `longname' is an expanded format for the file name, similar to what
- is returned by "ls -l" on Unix systems, and `attrs' is the attributes
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 22]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
- of the file as described in Section ``File Attributes''.
-
- The format of the `longname' field is unspecified by this protocol.
- It MUST be suitable for use in the output of a directory listing
- command (in fact, the recommended operation for a directory listing
- command is to simply display this data). However, clients SHOULD NOT
- attempt to parse the longname field for file attributes; they SHOULD
- use the attrs field instead.
-
- The recommended format for the longname field is as follows:
-
- -rwxr-xr-x 1 mjos staff 348911 Mar 25 14:29 t-filexfer
- 1234567890 123 12345678 12345678 12345678 123456789012
-
- Here, the first line is sample output, and the second field indicates
- widths of the various fields. Fields are separated by spaces. The
- first field lists file permissions for user, group, and others; the
- second field is link count; the third field is the name of the user
- who owns the file; the fourth field is the name of the group that
- owns the file; the fifth field is the size of the file in bytes; the
- sixth field (which actually may contain spaces, but is fixed to 12
- characters) is the file modification time, and the seventh field is
- the file name. Each field is specified to be a minimum of certain
- number of character positions (indicated by the second line above),
- but may also be longer if the data does not fit in the specified
- length.
-
- The SSH_FXP_ATTRS response has the following format:
-
- uint32 id
- ATTRS attrs
-
- where `id' is the request identifier, and `attrs' is the returned
- file attributes as described in Section ``File Attributes''.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 23]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-8. Vendor-Specific Extensions
-
- The SSH_FXP_EXTENDED request provides a generic extension mechanism
- for adding vendor-specific commands. The request has the following
- format:
-
- uint32 id
- string extended-request
- ... any request-specific data ...
-
- where `id' is the request identifier, and `extended-request' is a
- string of the format "name@domain", where domain is an internet
- domain name of the vendor defining the request. The rest of the
- request is completely vendor-specific, and servers should only
- attempt to interpret it if they recognize the `extended-request'
- name.
-
- The server may respond to such requests using any of the response
- packets defined in Section ``Responses from the Server to the
- Client''. Additionally, the server may also respond with a
- SSH_FXP_EXTENDED_REPLY packet, as defined below. If the server does
- not recognize the `extended-request' name, then the server MUST
- respond with SSH_FXP_STATUS with error/status set to
- SSH_FX_OP_UNSUPPORTED.
-
- The SSH_FXP_EXTENDED_REPLY packet can be used to carry arbitrary
- extension-specific data from the server to the client. It is of the
- following format:
-
- uint32 id
- ... any request-specific data ...
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 24]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-9. Security Considerations
-
- This protocol assumes that it is run over a secure channel and that
- the endpoints of the channel have been authenticated. Thus, this
- protocol assumes that it is externally protected from network-level
- attacks.
-
- This protocol provides file system access to arbitrary files on the
- server (only constrained by the server implementation). It is the
- responsibility of the server implementation to enforce any access
- controls that may be required to limit the access allowed for any
- particular user (the user being authenticated externally to this
- protocol, typically using the SSH User Authentication Protocol [6].
-
- Care must be taken in the server implementation to check the validity
- of received file handle strings. The server should not rely on them
- directly; it MUST check the validity of each handle before relying on
- it.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 25]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-10. Changes from previous protocol versions
-
- The SSH File Transfer Protocol has changed over time, before it's
- standardization. The following is a description of the incompatible
- changes between different versions.
-
-10.1 Changes between versions 3 and 2
-
- o The SSH_FXP_READLINK and SSH_FXP_SYMLINK messages were added.
-
- o The SSH_FXP_EXTENDED and SSH_FXP_EXTENDED_REPLY messages were
- added.
-
- o The SSH_FXP_STATUS message was changed to include fields `error
- message' and `language tag'.
-
-
-10.2 Changes between versions 2 and 1
-
- o The SSH_FXP_RENAME message was added.
-
-
-10.3 Changes between versions 1 and 0
-
- o Implementation changes, no actual protocol changes.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 26]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-11. Trademark Issues
-
- "ssh" is a registered trademark of SSH Communications Security Corp
- in the United States and/or other countries.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 27]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-References
-
- [1] Dierks, T., Allen, C., Treese, W., Karlton, P., Freier, A. and
- P. Kocher, "The TLS Protocol Version 1.0", RFC 2246, January
- 1999.
-
- [2] Institute of Electrical and Electronics Engineers, "Information
- Technology - Portable Operating System Interface (POSIX) - Part
- 1: System Application Program Interface (API) [C Language]",
- IEEE Standard 1003.2, 1996.
-
- [3] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.
- Lehtinen, "SSH Protocol Architecture", draft-ietf-secsh-
- architecture-09 (work in progress), July 2001.
-
- [4] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.
- Lehtinen, "SSH Protocol Transport Protocol", draft-ietf-secsh-
- architecture-09 (work in progress), July 2001.
-
- [5] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.
- Lehtinen, "SSH Connection Protocol", draft-ietf-secsh-connect-11
- (work in progress), July 2001.
-
- [6] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.
- Lehtinen, "SSH Authentication Protocol", draft-ietf-secsh-
- userauth-11 (work in progress), July 2001.
-
-
-Authors' Addresses
-
- Tatu Ylonen
- SSH Communications Security Corp
- Fredrikinkatu 42
- HELSINKI FIN-00100
- Finland
-
-
-
- Sami Lehtinen
- SSH Communications Security Corp
- Fredrikinkatu 42
- HELSINKI FIN-00100
- Finland
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 28]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-Full Copyright Statement
-
- Copyright (C) The Internet Society (2001). All Rights Reserved.
-
- This document and translations of it may be copied and furnished to
- others, and derivative works that comment on or otherwise explain it
- or assist in its implementation may be prepared, copied, published
- and distributed, in whole or in part, without restriction of any
- kind, provided that the above copyright notice and this paragraph are
- included on all such copies and derivative works. However, this
- document itself may not be modified in any way, such as by removing
- the copyright notice or references to the Internet Society or other
- Internet organizations, except as needed for the purpose of
- developing Internet standards in which case the procedures for
- copyrights defined in the Internet Standards process must be
- followed, or as required to translate it into languages other than
- English.
-
- The limited permissions granted above are perpetual and will not be
- revoked by the Internet Society or its successors or assigns.
-
- This document and the information contained herein is provided on an
- "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
- TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
- BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
- HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
- MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-Acknowledgement
-
- Funding for the RFC Editor function is currently provided by the
- Internet Society.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 29]
-
-
-
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-03.2.ps b/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-03.2.ps
deleted file mode 100644
index 6a40cd6067..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-03.2.ps
+++ /dev/null
@@ -1,3511 +0,0 @@
-%!PS-Adobe-3.0
-%%BoundingBox: 75 0 595 747
-%%Title: Enscript Output
-%%For: Magnus Thoang
-%%Creator: GNU enscript 1.6.1
-%%CreationDate: Wed Nov 12 12:18:50 2003
-%%Orientation: Portrait
-%%Pages: 18 0
-%%DocumentMedia: A4 595 842 0 () ()
-%%DocumentNeededResources: (atend)
-%%EndComments
-%%BeginProlog
-%%BeginProcSet: PStoPS 1 15
-userdict begin
-[/showpage/erasepage/copypage]{dup where{pop dup load
- type/operatortype eq{1 array cvx dup 0 3 index cvx put
- bind def}{pop}ifelse}{pop}ifelse}forall
-[/letter/legal/executivepage/a4/a4small/b5/com10envelope
- /monarchenvelope/c5envelope/dlenvelope/lettersmall/note
- /folio/quarto/a5]{dup where{dup wcheck{exch{}put}
- {pop{}def}ifelse}{pop}ifelse}forall
-/setpagedevice {pop}bind 1 index where{dup wcheck{3 1 roll put}
- {pop def}ifelse}{def}ifelse
-/PStoPSmatrix matrix currentmatrix def
-/PStoPSxform matrix def/PStoPSclip{clippath}def
-/defaultmatrix{PStoPSmatrix exch PStoPSxform exch concatmatrix}bind def
-/initmatrix{matrix defaultmatrix setmatrix}bind def
-/initclip[{matrix currentmatrix PStoPSmatrix setmatrix
- [{currentpoint}stopped{$error/newerror false put{newpath}}
- {/newpath cvx 3 1 roll/moveto cvx 4 array astore cvx}ifelse]
- {[/newpath cvx{/moveto cvx}{/lineto cvx}
- {/curveto cvx}{/closepath cvx}pathforall]cvx exch pop}
- stopped{$error/errorname get/invalidaccess eq{cleartomark
- $error/newerror false put cvx exec}{stop}ifelse}if}bind aload pop
- /initclip dup load dup type dup/operatortype eq{pop exch pop}
- {dup/arraytype eq exch/packedarraytype eq or
- {dup xcheck{exch pop aload pop}{pop cvx}ifelse}
- {pop cvx}ifelse}ifelse
- {newpath PStoPSclip clip newpath exec setmatrix} bind aload pop]cvx def
-/initgraphics{initmatrix newpath initclip 1 setlinewidth
- 0 setlinecap 0 setlinejoin []0 setdash 0 setgray
- 10 setmiterlimit}bind def
-end
-%%EndProcSet
-%%BeginResource: procset Enscript-Prolog 1.6 1
-%
-% Procedures.
-%
-
-/_S { % save current state
- /_s save def
-} def
-/_R { % restore from saved state
- _s restore
-} def
-
-/S { % showpage protecting gstate
- gsave
- showpage
- grestore
-} bind def
-
-/MF { % fontname newfontname -> - make a new encoded font
- /newfontname exch def
- /fontname exch def
-
- /fontdict fontname findfont def
- /newfont fontdict maxlength dict def
-
- fontdict {
- exch
- dup /FID eq {
- % skip FID pair
- pop pop
- } {
- % copy to the new font dictionary
- exch newfont 3 1 roll put
- } ifelse
- } forall
-
- newfont /FontName newfontname put
-
- % insert only valid encoding vectors
- encoding_vector length 256 eq {
- newfont /Encoding encoding_vector put
- } if
-
- newfontname newfont definefont pop
-} def
-
-/SF { % fontname width height -> - set a new font
- /height exch def
- /width exch def
-
- findfont
- [width 0 0 height 0 0] makefont setfont
-} def
-
-/SUF { % fontname width height -> - set a new user font
- /height exch def
- /width exch def
-
- /F-gs-user-font MF
- /F-gs-user-font width height SF
-} def
-
-/M {moveto} bind def
-/s {show} bind def
-
-/Box { % x y w h -> - define box path
- /d_h exch def /d_w exch def /d_y exch def /d_x exch def
- d_x d_y moveto
- d_w 0 rlineto
- 0 d_h rlineto
- d_w neg 0 rlineto
- closepath
-} def
-
-/bgs { % x y height blskip gray str -> - show string with bg color
- /str exch def
- /gray exch def
- /blskip exch def
- /height exch def
- /y exch def
- /x exch def
-
- gsave
- x y blskip sub str stringwidth pop height Box
- gray setgray
- fill
- grestore
- x y M str s
-} def
-
-% Highlight bars.
-/highlight_bars { % nlines lineheight output_y_margin gray -> -
- gsave
- setgray
- /ymarg exch def
- /lineheight exch def
- /nlines exch def
-
- % This 2 is just a magic number to sync highlight lines to text.
- 0 d_header_y ymarg sub 2 sub translate
-
- /cw d_output_w cols div def
- /nrows d_output_h ymarg 2 mul sub lineheight div cvi def
-
- % for each column
- 0 1 cols 1 sub {
- cw mul /xp exch def
-
- % for each rows
- 0 1 nrows 1 sub {
- /rn exch def
- rn lineheight mul neg /yp exch def
- rn nlines idiv 2 mod 0 eq {
- % Draw highlight bar. 4 is just a magic indentation.
- xp 4 add yp cw 8 sub lineheight neg Box fill
- } if
- } for
- } for
-
- grestore
-} def
-
-% Line highlight bar.
-/line_highlight { % x y width height gray -> -
- gsave
- /gray exch def
- Box gray setgray fill
- grestore
-} def
-
-% Column separator lines.
-/column_lines {
- gsave
- .1 setlinewidth
- 0 d_footer_h translate
- /cw d_output_w cols div def
- 1 1 cols 1 sub {
- cw mul 0 moveto
- 0 d_output_h rlineto stroke
- } for
- grestore
-} def
-
-% Column borders.
-/column_borders {
- gsave
- .1 setlinewidth
- 0 d_footer_h moveto
- 0 d_output_h rlineto
- d_output_w 0 rlineto
- 0 d_output_h neg rlineto
- closepath stroke
- grestore
-} def
-
-% Do the actual underlay drawing
-/draw_underlay {
- ul_style 0 eq {
- ul_str true charpath stroke
- } {
- ul_str show
- } ifelse
-} def
-
-% Underlay
-/underlay { % - -> -
- gsave
- 0 d_page_h translate
- d_page_h neg d_page_w atan rotate
-
- ul_gray setgray
- ul_font setfont
- /dw d_page_h dup mul d_page_w dup mul add sqrt def
- ul_str stringwidth pop dw exch sub 2 div ul_h_ptsize -2 div moveto
- draw_underlay
- grestore
-} def
-
-/user_underlay { % - -> -
- gsave
- ul_x ul_y translate
- ul_angle rotate
- ul_gray setgray
- ul_font setfont
- 0 0 ul_h_ptsize 2 div sub moveto
- draw_underlay
- grestore
-} def
-
-% Page prefeed
-/page_prefeed { % bool -> -
- statusdict /prefeed known {
- statusdict exch /prefeed exch put
- } {
- pop
- } ifelse
-} def
-
-% Wrapped line markers
-/wrapped_line_mark { % x y charwith charheight type -> -
- /type exch def
- /h exch def
- /w exch def
- /y exch def
- /x exch def
-
- type 2 eq {
- % Black boxes (like TeX does)
- gsave
- 0 setlinewidth
- x w 4 div add y M
- 0 h rlineto w 2 div 0 rlineto 0 h neg rlineto
- closepath fill
- grestore
- } {
- type 3 eq {
- % Small arrows
- gsave
- .2 setlinewidth
- x w 2 div add y h 2 div add M
- w 4 div 0 rlineto
- x w 4 div add y lineto stroke
-
- x w 4 div add w 8 div add y h 4 div add M
- x w 4 div add y lineto
- w 4 div h 8 div rlineto stroke
- grestore
- } {
- % do nothing
- } ifelse
- } ifelse
-} def
-
-% EPSF import.
-
-/BeginEPSF {
- /b4_Inc_state save def % Save state for cleanup
- /dict_count countdictstack def % Count objects on dict stack
- /op_count count 1 sub def % Count objects on operand stack
- userdict begin
- /showpage { } def
- 0 setgray 0 setlinecap
- 1 setlinewidth 0 setlinejoin
- 10 setmiterlimit [ ] 0 setdash newpath
- /languagelevel where {
- pop languagelevel
- 1 ne {
- false setstrokeadjust false setoverprint
- } if
- } if
-} bind def
-
-/EndEPSF {
- count op_count sub { pos } repeat % Clean up stacks
- countdictstack dict_count sub { end } repeat
- b4_Inc_state restore
-} bind def
-
-% Check PostScript language level.
-/languagelevel where {
- pop /gs_languagelevel languagelevel def
-} {
- /gs_languagelevel 1 def
-} ifelse
-%%EndResource
-%%BeginResource: procset Enscript-Encoding-88591 1.6 1
-/encoding_vector [
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/space /exclam /quotedbl /numbersign
-/dollar /percent /ampersand /quoteright
-/parenleft /parenright /asterisk /plus
-/comma /hyphen /period /slash
-/zero /one /two /three
-/four /five /six /seven
-/eight /nine /colon /semicolon
-/less /equal /greater /question
-/at /A /B /C
-/D /E /F /G
-/H /I /J /K
-/L /M /N /O
-/P /Q /R /S
-/T /U /V /W
-/X /Y /Z /bracketleft
-/backslash /bracketright /asciicircum /underscore
-/quoteleft /a /b /c
-/d /e /f /g
-/h /i /j /k
-/l /m /n /o
-/p /q /r /s
-/t /u /v /w
-/x /y /z /braceleft
-/bar /braceright /tilde /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/space /exclamdown /cent /sterling
-/currency /yen /brokenbar /section
-/dieresis /copyright /ordfeminine /guillemotleft
-/logicalnot /hyphen /registered /macron
-/degree /plusminus /twosuperior /threesuperior
-/acute /mu /paragraph /bullet
-/cedilla /onesuperior /ordmasculine /guillemotright
-/onequarter /onehalf /threequarters /questiondown
-/Agrave /Aacute /Acircumflex /Atilde
-/Adieresis /Aring /AE /Ccedilla
-/Egrave /Eacute /Ecircumflex /Edieresis
-/Igrave /Iacute /Icircumflex /Idieresis
-/Eth /Ntilde /Ograve /Oacute
-/Ocircumflex /Otilde /Odieresis /multiply
-/Oslash /Ugrave /Uacute /Ucircumflex
-/Udieresis /Yacute /Thorn /germandbls
-/agrave /aacute /acircumflex /atilde
-/adieresis /aring /ae /ccedilla
-/egrave /eacute /ecircumflex /edieresis
-/igrave /iacute /icircumflex /idieresis
-/eth /ntilde /ograve /oacute
-/ocircumflex /otilde /odieresis /divide
-/oslash /ugrave /uacute /ucircumflex
-/udieresis /yacute /thorn /ydieresis
-] def
-%%EndResource
-%%EndProlog
-%%BeginSetup
-%%IncludeResource: font Courier-Bold
-%%IncludeResource: font Courier
-/HFpt_w 10 def
-/HFpt_h 10 def
-/Courier-Bold /HF-gs-font MF
-/HF /HF-gs-font findfont [HFpt_w 0 0 HFpt_h 0 0] makefont def
-/Courier /F-gs-font MF
-/F-gs-font 10 10 SF
-/#copies 1 def
-/d_page_w 520 def
-/d_page_h 747 def
-/d_header_x 0 def
-/d_header_y 747 def
-/d_header_w 520 def
-/d_header_h 0 def
-/d_footer_x 0 def
-/d_footer_y 0 def
-/d_footer_w 520 def
-/d_footer_h 0 def
-/d_output_w 520 def
-/d_output_h 747 def
-/cols 1 def
-userdict/PStoPSxform PStoPSmatrix matrix currentmatrix
- matrix invertmatrix matrix concatmatrix
- matrix invertmatrix put
-%%EndSetup
-%%Page: (0,1) 1
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 1 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 701 M
-(Secure Shell Working Group J. Galbraith) s
-5 690 M
-(Internet-Draft VanDyke Software) s
-5 679 M
-(Expires: April 16, 2003 T. Ylonen) s
-5 668 M
-( S. Lehtinen) s
-5 657 M
-( SSH Communications Security Corp) s
-5 646 M
-( October 16, 2002) s
-5 613 M
-( SSH File Transfer Protocol) s
-5 602 M
-( draft-ietf-secsh-filexfer-03.txt) s
-5 580 M
-(Status of this Memo) s
-5 558 M
-( This document is an Internet-Draft and is in full conformance with) s
-5 547 M
-( all provisions of Section 10 of RFC2026.) s
-5 525 M
-( Internet-Drafts are working documents of the Internet Engineering) s
-5 514 M
-( Task Force \(IETF\), its areas, and its working groups. Note that) s
-5 503 M
-( other groups may also distribute working documents as Internet-) s
-5 492 M
-( Drafts.) s
-5 470 M
-( Internet-Drafts are draft documents valid for a maximum of six months) s
-5 459 M
-( and may be updated, replaced, or obsoleted by other documents at any) s
-5 448 M
-( time. It is inappropriate to use Internet-Drafts as reference) s
-5 437 M
-( material or to cite them other than as "work in progress.") s
-5 415 M
-( The list of current Internet-Drafts can be accessed at http://) s
-5 404 M
-( www.ietf.org/ietf/1id-abstracts.txt.) s
-5 382 M
-( The list of Internet-Draft Shadow Directories can be accessed at) s
-5 371 M
-( http://www.ietf.org/shadow.html.) s
-5 349 M
-( This Internet-Draft will expire on April 16, 2003.) s
-5 327 M
-(Copyright Notice) s
-5 305 M
-( Copyright \(C\) The Internet Society \(2002\). All Rights Reserved.) s
-5 283 M
-(Abstract) s
-5 261 M
-( The SSH File Transfer Protocol provides secure file transfer) s
-5 250 M
-( functionality over any reliable data stream. It is the standard file) s
-5 239 M
-( transfer protocol for use with the SSH2 protocol. This document) s
-5 228 M
-( describes the file transfer protocol and its interface to the SSH2) s
-5 217 M
-( protocol suite.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 1]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 2 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(Table of Contents) s
-5 668 M
-( 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 657 M
-( 2. Use with the SSH Connection Protocol . . . . . . . . . . . 4) s
-5 646 M
-( 3. General Packet Format . . . . . . . . . . . . . . . . . . 5) s
-5 635 M
-( 4. Protocol Initialization . . . . . . . . . . . . . . . . . 7) s
-5 624 M
-( 4.1 Client Initialization . . . . . . . . . . . . . . . . . . 7) s
-5 613 M
-( 4.2 Server Initialization . . . . . . . . . . . . . . . . . . 7) s
-5 602 M
-( 4.3 Determining Server Newline Convention . . . . . . . . . . 8) s
-5 591 M
-( 5. File Attributes . . . . . . . . . . . . . . . . . . . . . 9) s
-5 580 M
-( 5.1 Flags . . . . . . . . . . . . . . . . . . . . . . . . . . 9) s
-5 569 M
-( 5.2 Type . . . . . . . . . . . . . . . . . . . . . . . . . . . 10) s
-5 558 M
-( 5.3 Size . . . . . . . . . . . . . . . . . . . . . . . . . . . 10) s
-5 547 M
-( 5.4 Owner and Group . . . . . . . . . . . . . . . . . . . . . 10) s
-5 536 M
-( 5.5 Permissions . . . . . . . . . . . . . . . . . . . . . . . 11) s
-5 525 M
-( 5.6 Times . . . . . . . . . . . . . . . . . . . . . . . . . . 11) s
-5 514 M
-( 5.7 ACL . . . . . . . . . . . . . . . . . . . . . . . . . . . 11) s
-5 503 M
-( 5.8 Extended attributes . . . . . . . . . . . . . . . . . . . 12) s
-5 492 M
-( 6. Requests From the Client to the Server . . . . . . . . . . 13) s
-5 481 M
-( 6.1 Request Synchronization and Reordering . . . . . . . . . . 13) s
-5 470 M
-( 6.2 File Names . . . . . . . . . . . . . . . . . . . . . . . . 14) s
-5 459 M
-( 6.3 Opening, Creating, and Closing Files . . . . . . . . . . . 14) s
-5 448 M
-( 6.4 Reading and Writing . . . . . . . . . . . . . . . . . . . 17) s
-5 437 M
-( 6.5 Removing and Renaming Files . . . . . . . . . . . . . . . 18) s
-5 426 M
-( 6.6 Creating and Deleting Directories . . . . . . . . . . . . 19) s
-5 415 M
-( 6.7 Scanning Directories . . . . . . . . . . . . . . . . . . . 19) s
-5 404 M
-( 6.8 Retrieving File Attributes . . . . . . . . . . . . . . . . 20) s
-5 393 M
-( 6.9 Setting File Attributes . . . . . . . . . . . . . . . . . 21) s
-5 382 M
-( 6.10 Dealing with Symbolic links . . . . . . . . . . . . . . . 22) s
-5 371 M
-( 6.11 Canonicalizing the Server-Side Path Name . . . . . . . . . 23) s
-5 360 M
-( 6.11.1 Best practice for dealing with paths . . . . . . . . . . . 23) s
-5 349 M
-( 7. Responses from the Server to the Client . . . . . . . . . 24) s
-5 338 M
-( 8. Vendor-Specific Extensions . . . . . . . . . . . . . . . . 28) s
-5 327 M
-( 9. Security Considerations . . . . . . . . . . . . . . . . . 29) s
-5 316 M
-( 10. Changes from previous protocol versions . . . . . . . . . 30) s
-5 305 M
-( 10.1 Changes between versions 4 and 3 . . . . . . . . . . . . . 30) s
-5 294 M
-( 10.2 Changes between versions 3 and 2 . . . . . . . . . . . . . 31) s
-5 283 M
-( 10.3 Changes between versions 2 and 1 . . . . . . . . . . . . . 31) s
-5 272 M
-( 10.4 Changes between versions 1 and 0 . . . . . . . . . . . . . 31) s
-5 261 M
-( 11. Trademark Issues . . . . . . . . . . . . . . . . . . . . . 32) s
-5 250 M
-( References . . . . . . . . . . . . . . . . . . . . . . . . 33) s
-5 239 M
-( Authors' Addresses . . . . . . . . . . . . . . . . . . . . 33) s
-5 228 M
-( Full Copyright Statement . . . . . . . . . . . . . . . . . 35) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 2]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (2,3) 2
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 3 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(1. Introduction) s
-5 668 M
-( This protocol provides secure file transfer \(and more generally file) s
-5 657 M
-( system access\) functionality over a reliable data stream, such as a) s
-5 646 M
-( channel in the SSH2 protocol [5].) s
-5 624 M
-( This protocol is designed so that it could be used to implement a) s
-5 613 M
-( secure remote file system service, as well as a secure file transfer) s
-5 602 M
-( service.) s
-5 580 M
-( This protocol assumes that it runs over a secure channel, and that) s
-5 569 M
-( the server has already authenticated the user at the client end, and) s
-5 558 M
-( that the identity of the client user is externally available to the) s
-5 547 M
-( server implementation.) s
-5 525 M
-( In general, this protocol follows a simple request-response model.) s
-5 514 M
-( Each request and response contains a sequence number and multiple) s
-5 503 M
-( requests may be pending simultaneously. There are a relatively large) s
-5 492 M
-( number of different request messages, but a small number of possible) s
-5 481 M
-( response messages. Each request has one or more response messages) s
-5 470 M
-( that may be returned in result \(e.g., a read either returns data or) s
-5 459 M
-( reports error status\).) s
-5 437 M
-( The packet format descriptions in this specification follow the) s
-5 426 M
-( notation presented in the secsh architecture draft. [5]) s
-5 404 M
-( Even though this protocol is described in the context of the SSH2) s
-5 393 M
-( protocol, this protocol is general and independent of the rest of the) s
-5 382 M
-( SSH2 protocol suite. It could be used in a number of different) s
-5 371 M
-( applications, such as secure file transfer over TLS RFC 2246 [1] and) s
-5 360 M
-( transfer of management information in VPN applications.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 3]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 4 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(2. Use with the SSH Connection Protocol) s
-5 668 M
-( When used with the SSH2 Protocol suite, this protocol is intended to) s
-5 657 M
-( be used from the SSH Connection Protocol [7] as a subsystem, as) s
-5 646 M
-( described in section ``Starting a Shell or a Command''. The) s
-5 635 M
-( subsystem name used with this protocol is "sftp".) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 4]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (4,5) 3
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 5 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(3. General Packet Format) s
-5 668 M
-( All packets transmitted over the secure connection are of the) s
-5 657 M
-( following format:) s
-5 635 M
-( uint32 length) s
-5 624 M
-( byte type) s
-5 613 M
-( byte[length - 1] data payload) s
-5 591 M
-( That is, they are just data preceded by 32-bit length and 8-bit type) s
-5 580 M
-( fields. The `length' is the length of the data area, and does not) s
-5 569 M
-( include the `length' field itself. The format and interpretation of) s
-5 558 M
-( the data area depends on the packet type.) s
-5 536 M
-( All packet descriptions below only specify the packet type and the) s
-5 525 M
-( data that goes into the data field. Thus, they should be prefixed by) s
-5 514 M
-( the `length' and `type' fields.) s
-5 492 M
-( The maximum size of a packet is in practice determined by the client) s
-5 481 M
-( \(the maximum size of read or write requests that it sends, plus a few) s
-5 470 M
-( bytes of packet overhead\). All servers SHOULD support packets of at) s
-5 459 M
-( least 34000 bytes \(where the packet size refers to the full length,) s
-5 448 M
-( including the header above\). This should allow for reads and writes) s
-5 437 M
-( of at most 32768 bytes.) s
-5 415 M
-( There is no limit on the number of outstanding \(non-acknowledged\)) s
-5 404 M
-( requests that the client may send to the server. In practice this is) s
-5 393 M
-( limited by the buffering available on the data stream and the queuing) s
-5 382 M
-( performed by the server. If the server's queues are full, it should) s
-5 371 M
-( not read any more data from the stream, and flow control will prevent) s
-5 360 M
-( the client from sending more requests. Note, however, that while) s
-5 349 M
-( there is no restriction on the protocol level, the client's API may) s
-5 338 M
-( provide a limit in order to prevent infinite queuing of outgoing) s
-5 327 M
-( requests at the client.) s
-5 305 M
-( The following values are defined for packet types.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 5]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 6 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( #define SSH_FXP_INIT 1) s
-5 679 M
-( #define SSH_FXP_VERSION 2) s
-5 668 M
-( #define SSH_FXP_OPEN 3) s
-5 657 M
-( #define SSH_FXP_CLOSE 4) s
-5 646 M
-( #define SSH_FXP_READ 5) s
-5 635 M
-( #define SSH_FXP_WRITE 6) s
-5 624 M
-( #define SSH_FXP_LSTAT 7) s
-5 613 M
-( #define SSH_FXP_FSTAT 8) s
-5 602 M
-( #define SSH_FXP_SETSTAT 9) s
-5 591 M
-( #define SSH_FXP_FSETSTAT 10) s
-5 580 M
-( #define SSH_FXP_OPENDIR 11) s
-5 569 M
-( #define SSH_FXP_READDIR 12) s
-5 558 M
-( #define SSH_FXP_REMOVE 13) s
-5 547 M
-( #define SSH_FXP_MKDIR 14) s
-5 536 M
-( #define SSH_FXP_RMDIR 15) s
-5 525 M
-( #define SSH_FXP_REALPATH 16) s
-5 514 M
-( #define SSH_FXP_STAT 17) s
-5 503 M
-( #define SSH_FXP_RENAME 18) s
-5 492 M
-( #define SSH_FXP_READLINK 19) s
-5 481 M
-( #define SSH_FXP_SYMLINK 20) s
-5 459 M
-( #define SSH_FXP_STATUS 101) s
-5 448 M
-( #define SSH_FXP_HANDLE 102) s
-5 437 M
-( #define SSH_FXP_DATA 103) s
-5 426 M
-( #define SSH_FXP_NAME 104) s
-5 415 M
-( #define SSH_FXP_ATTRS 105) s
-5 393 M
-( #define SSH_FXP_EXTENDED 200) s
-5 382 M
-( #define SSH_FXP_EXTENDED_REPLY 201) s
-5 360 M
-( RESERVED_FOR_EXTENSIONS 210-255) s
-5 338 M
-( Additional packet types should only be defined if the protocol) s
-5 327 M
-( version number \(see Section ``Protocol Initialization''\) is) s
-5 316 M
-( incremented, and their use MUST be negotiated using the version) s
-5 305 M
-( number. However, the SSH_FXP_EXTENDED and SSH_FXP_EXTENDED_REPLY) s
-5 294 M
-( packets can be used to implement vendor-specific extensions. See) s
-5 283 M
-( Section ``Vendor-Specific-Extensions'' for more details.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 6]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (6,7) 4
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 7 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(4. Protocol Initialization) s
-5 668 M
-( When the file transfer protocol starts, the client first sends a) s
-5 657 M
-( SSH_FXP_INIT \(including its version number\) packet to the server.) s
-5 646 M
-( The server responds with a SSH_FXP_VERSION packet, supplying the) s
-5 635 M
-( lowest of its own and the client's version number. Both parties) s
-5 624 M
-( should from then on adhere to particular version of the protocol.) s
-5 602 M
-( The version number of the protocol specified in this document is 4.) s
-5 591 M
-( The version number should be incremented for each incompatible) s
-5 580 M
-( revision of this protocol.) s
-5 558 M
-(4.1 Client Initialization) s
-5 536 M
-( The SSH_FXP_INIT packet \(from client to server\) has the following) s
-5 525 M
-( data:) s
-5 503 M
-( uint32 version) s
-5 481 M
-( Version 3 of this protocol allowed clients to include extensions in) s
-5 470 M
-( the SSH_FXP_INIT packet; however, this can cause interoperability) s
-5 459 M
-( problems with version 1 and version 2 servers because the client must) s
-5 448 M
-( send this packet before knowing the servers version.) s
-5 426 M
-( In this version of the protocol, clients MUST use the) s
-5 415 M
-( SSH_FXP_EXTENDED packet to send extensions to the server after) s
-5 404 M
-( version exchange has completed. Clients MUST NOT include extensions) s
-5 393 M
-( in the version packet. This will prevent interoperability problems) s
-5 382 M
-( with older servers) s
-5 360 M
-(4.2 Server Initialization) s
-5 338 M
-( The SSH_FXP_VERSION packet \(from server to client\) has the following) s
-5 327 M
-( data:) s
-5 305 M
-( uint32 version) s
-5 294 M
-( <extension data>) s
-5 272 M
-( 'version' is the lower of the protocol version supported by the) s
-5 261 M
-( server and the version number received from the client.) s
-5 239 M
-( The extension data may be empty, or may be a sequence of) s
-5 217 M
-( string extension_name) s
-5 206 M
-( string extension_data) s
-5 184 M
-( pairs \(both strings MUST always be present if one is, but the) s
-5 173 M
-( `extension_data' string may be of zero length\). If present, these) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 7]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 8 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( strings indicate extensions to the baseline protocol. The) s
-5 679 M
-( `extension_name' field\(s\) identify the name of the extension. The) s
-5 668 M
-( name should be of the form "name@domain", where the domain is the DNS) s
-5 657 M
-( domain name of the organization defining the extension. Additional) s
-5 646 M
-( names that are not of this format may be defined later by the IETF.) s
-5 635 M
-( Implementations MUST silently ignore any extensions whose name they) s
-5 624 M
-( do not recognize.) s
-5 602 M
-(4.3 Determining Server Newline Convention) s
-5 580 M
-( In order to correctly process text files in a cross platform) s
-5 569 M
-( compatible way, the newline convention must be converted from that of) s
-5 558 M
-( the server to that of the client, or, during an upload, from that of) s
-5 547 M
-( the client to that of the server.) s
-5 525 M
-( Versions 3 and prior of this protocol made no provisions for) s
-5 514 M
-( processing text files. Many clients implemented some sort of) s
-5 503 M
-( conversion algorithm, but without either a 'canonical' on the wire) s
-5 492 M
-( format or knowledge of the servers newline convention, correct) s
-5 481 M
-( conversion was not always possible.) s
-5 459 M
-( Starting with Version 4, the SSH_FXF_TEXT file open flag \(Section) s
-5 448 M
-( 6.3\) makes it possible to request that the server translate a file to) s
-5 437 M
-( a 'canonical' on the wire format. This format uses \\r\\n as the line) s
-5 426 M
-( separator.) s
-5 404 M
-( Servers for systems using multiple newline characters \(for example,) s
-5 393 M
-( Mac OS X or VMS\) or systems using counted records, MUST translate to) s
-5 382 M
-( the canonical form.) s
-5 360 M
-( However, to ease the burden of implementation on servers that use a) s
-5 349 M
-( single, simple separator sequence, the following extension allows the) s
-5 338 M
-( canonical format to be changed.) s
-5 316 M
-( string "newline") s
-5 305 M
-( string new-canonical-separator \(usually "\\r" or "\\n" or "\\r\\n"\)) s
-5 283 M
-( All clients MUST support this extension.) s
-5 261 M
-( When processing text files, clients SHOULD NOT translate any) s
-5 250 M
-( character or sequence that is not an exact match of the servers) s
-5 239 M
-( newline separator.) s
-5 217 M
-( In particular, if the newline sequence being used is the canonical) s
-5 206 M
-( "\\r\\n" sequence, a lone \\r or a lone \\n SHOULD be written through) s
-5 195 M
-( without change.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 8]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (8,9) 5
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 9 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(5. File Attributes) s
-5 668 M
-( A new compound data type is defined for encoding file attributes.) s
-5 657 M
-( The same encoding is used both when returning file attributes from) s
-5 646 M
-( the server and when sending file attributes to the server. When) s
-5 635 M
-( sending it to the server, the flags field specifies which attributes) s
-5 624 M
-( are included, and the server will use default values for the) s
-5 613 M
-( remaining attributes \(or will not modify the values of remaining) s
-5 602 M
-( attributes\). When receiving attributes from the server, the flags) s
-5 591 M
-( specify which attributes are included in the returned data. The) s
-5 580 M
-( server normally returns all attributes it knows about.) s
-5 558 M
-( uint32 flags) s
-5 547 M
-( byte type always present) s
-5 536 M
-( uint64 size present only if flag SSH_FILEXFER_ATTR_SIZE) s
-5 525 M
-( string owner present only if flag SSH_FILEXFER_ATTR_OWNERGROUP) s
-5 514 M
-( string group present only if flag SSH_FILEXFER_ATTR_OWNERGROUP) s
-5 503 M
-( uint32 permissions present only if flag SSH_FILEXFER_ATTR_PERMISSIONS) s
-5 492 M
-( uint32 atime present only if flag SSH_FILEXFER_ATTR_ACCESSTIME) s
-5 481 M
-( uint32 createtime present only if flag SSH_FILEXFER_ATTR_CREATETIME) s
-5 470 M
-( uint32 mtime present only if flag SSH_FILEXFER_ATTR_MODIFYTIME) s
-5 459 M
-( string acl present only if flag SSH_FILEXFER_ATTR_ACL) s
-5 448 M
-( uint32 extended_count present only if flag SSH_FILEXFER_ATTR_EXTENDED) s
-5 437 M
-( string extended_type) s
-5 426 M
-( string extended_data) s
-5 415 M
-( ... more extended data \(extended_type - extended_data pairs\),) s
-5 404 M
-( so that number of pairs equals extended_count) s
-5 371 M
-(5.1 Flags) s
-5 349 M
-( The `flags' specify which of the fields are present. Those fields) s
-5 338 M
-( for which the corresponding flag is not set are not present \(not) s
-5 327 M
-( included in the packet\). New flags can only be added by incrementing) s
-5 316 M
-( the protocol version number \(or by using the extension mechanism) s
-5 305 M
-( described below\).) s
-5 283 M
-( The flags bits are defined to have the following values:) s
-5 261 M
-( #define SSH_FILEXFER_ATTR_SIZE 0x00000001) s
-5 250 M
-( #define SSH_FILEXFER_ATTR_PERMISSIONS 0x00000004) s
-5 239 M
-( #define SSH_FILEXFER_ATTR_ACCESSTIME 0x00000008) s
-5 228 M
-( #define SSH_FILEXFER_ATTR_CREATETIME 0x00000010) s
-5 217 M
-( #define SSH_FILEXFER_ATTR_MODIFYTIME 0x00000020) s
-5 206 M
-( #define SSH_FILEXFER_ATTR_ACL 0x00000040) s
-5 195 M
-( #define SSH_FILEXFER_ATTR_OWNERGROUP 0x00000080) s
-5 184 M
-( #define SSH_FILEXFER_ATTR_EXTENDED 0x80000000) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 9]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 10 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( In previous versions of this protocol flags value 0x00000002 was) s
-5 679 M
-( SSH_FILEXFER_ATTR_UIDGID. This value is now unused, and OWNERGROUP) s
-5 668 M
-( was given a new value in order to ease implementation burden.) s
-5 657 M
-( 0x00000002 MUST NOT appear in the mask. Some future version of this) s
-5 646 M
-( protocol may reuse flag 0x00000002.) s
-5 624 M
-(5.2 Type) s
-5 602 M
-( The type field is always present. The following types are defined:) s
-5 580 M
-( #define SSH_FILEXFER_TYPE_REGULAR 1) s
-5 569 M
-( #define SSH_FILEXFER_TYPE_DIRECTORY 2) s
-5 558 M
-( #define SSH_FILEXFER_TYPE_SYMLINK 3) s
-5 547 M
-( #define SSH_FILEXFER_TYPE_SPECIAL 4) s
-5 536 M
-( #define SSH_FILEXFER_TYPE_UNKNOWN 5) s
-5 514 M
-( On a POSIX system, these values would be derived from the permission) s
-5 503 M
-( field.) s
-5 481 M
-(5.3 Size) s
-5 459 M
-( The `size' field specifies the size of the file on disk, in bytes.) s
-5 448 M
-( If it is present during file creation, it should be considered a hint) s
-5 437 M
-( as to the files eventual size.) s
-5 415 M
-( Files opened with the SSH_FXF_TEXT flag may have a size that is) s
-5 404 M
-( greater or less than the value of the size field.) s
-5 382 M
-(5.4 Owner and Group) s
-5 360 M
-( The `owner' and `group' fields are represented as UTF-8 strings; this) s
-5 349 M
-( is the form used by NFS v4. See NFS version 4 Protocol. [3] The) s
-5 338 M
-( following text is selected quotations from section 5.6.) s
-5 316 M
-( To avoid a representation that is tied to a particular underlying) s
-5 305 M
-( implementation at the client or server, the use of UTF-8 strings has) s
-5 294 M
-( been chosen. The string should be of the form user@dns_domain".) s
-5 283 M
-( This will allow for a client and server that do not use the same) s
-5 272 M
-( local representation the ability to translate to a common syntax that) s
-5 261 M
-( can be interpreted by both. In the case where there is no) s
-5 250 M
-( translation available to the client or server, the attribute value) s
-5 239 M
-( must be constructed without the "@". Therefore, the absence of the @) s
-5 228 M
-( from the owner or owner_group attribute signifies that no translation) s
-5 217 M
-( was available and the receiver of the attribute should not place any) s
-5 206 M
-( special meaning with the attribute value. Even though the attribute) s
-5 195 M
-( value can not be translated, it may still be useful. In the case of) s
-5 184 M
-( a client, the attribute string may be used for local display of) s
-5 173 M
-( ownership.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 10]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (10,11) 6
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 11 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(5.5 Permissions) s
-5 668 M
-( The `permissions' field contains a bit mask of file permissions as) s
-5 657 M
-( defined by POSIX [1].) s
-5 635 M
-(5.6 Times) s
-5 613 M
-( The 'atime', 'createtime', and 'mtime' contain the access, creation,) s
-5 602 M
-( and modification times of the files, respectively. They are) s
-5 591 M
-( represented as seconds from Jan 1, 1970 in UTC.) s
-5 569 M
-(5.7 ACL) s
-5 547 M
-( The 'ACL' field contains an ACL similar to that defined in section) s
-5 536 M
-( 5.9 of NFS version 4 Protocol [3].) s
-5 514 M
-( uint32 ace-count) s
-5 492 M
-( repeated ace-count time:) s
-5 481 M
-( uint32 ace-type) s
-5 470 M
-( uint32 ace-flag) s
-5 459 M
-( uint32 ace-mask) s
-5 448 M
-( string who [UTF-8]) s
-5 426 M
-( ace-type is one of the following four values \(taken from NFS Version) s
-5 415 M
-( 4 Protocol [3]:) s
-5 393 M
-( const ACE4_ACCESS_ALLOWED_ACE_TYPE = 0x00000000;) s
-5 382 M
-( const ACE4_ACCESS_DENIED_ACE_TYPE = 0x00000001;) s
-5 371 M
-( const ACE4_SYSTEM_AUDIT_ACE_TYPE = 0x00000002;) s
-5 360 M
-( const ACE4_SYSTEM_ALARM_ACE_TYPE = 0x00000003;) s
-5 338 M
-( ace-flag is a combination of the following flag values. See NFS) s
-5 327 M
-( Version 4 Protocol [3] section 5.9.2:) s
-5 305 M
-( const ACE4_FILE_INHERIT_ACE = 0x00000001;) s
-5 294 M
-( const ACE4_DIRECTORY_INHERIT_ACE = 0x00000002;) s
-5 283 M
-( const ACE4_NO_PROPAGATE_INHERIT_ACE = 0x00000004;) s
-5 272 M
-( const ACE4_INHERIT_ONLY_ACE = 0x00000008;) s
-5 261 M
-( const ACE4_SUCCESSFUL_ACCESS_ACE_FLAG = 0x00000010;) s
-5 250 M
-( const ACE4_FAILED_ACCESS_ACE_FLAG = 0x00000020;) s
-5 239 M
-( const ACE4_IDENTIFIER_GROUP = 0x00000040;) s
-5 217 M
-( ace-mask is any combination of the following flags \(taken from NFS) s
-5 206 M
-( Version 4 Protocol [3] section 5.9.3:) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 11]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 12 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( const ACE4_READ_DATA = 0x00000001;) s
-5 679 M
-( const ACE4_LIST_DIRECTORY = 0x00000001;) s
-5 668 M
-( const ACE4_WRITE_DATA = 0x00000002;) s
-5 657 M
-( const ACE4_ADD_FILE = 0x00000002;) s
-5 646 M
-( const ACE4_APPEND_DATA = 0x00000004;) s
-5 635 M
-( const ACE4_ADD_SUBDIRECTORY = 0x00000004;) s
-5 624 M
-( const ACE4_READ_NAMED_ATTRS = 0x00000008;) s
-5 613 M
-( const ACE4_WRITE_NAMED_ATTRS = 0x00000010;) s
-5 602 M
-( const ACE4_EXECUTE = 0x00000020;) s
-5 591 M
-( const ACE4_DELETE_CHILD = 0x00000040;) s
-5 580 M
-( const ACE4_READ_ATTRIBUTES = 0x00000080;) s
-5 569 M
-( const ACE4_WRITE_ATTRIBUTES = 0x00000100;) s
-5 558 M
-( const ACE4_DELETE = 0x00010000;) s
-5 547 M
-( const ACE4_READ_ACL = 0x00020000;) s
-5 536 M
-( const ACE4_WRITE_ACL = 0x00040000;) s
-5 525 M
-( const ACE4_WRITE_OWNER = 0x00080000;) s
-5 514 M
-( const ACE4_SYNCHRONIZE = 0x00100000;) s
-5 492 M
-( who is a UTF-8 string of the form described in 'Owner and Group') s
-5 481 M
-( \(Section 5.4\)) s
-5 459 M
-(5.8 Extended attributes) s
-5 437 M
-( The SSH_FILEXFER_ATTR_EXTENDED flag provides a general extension) s
-5 426 M
-( mechanism for vendor-specific extensions. If the flag is specified,) s
-5 415 M
-( then the `extended_count' field is present. It specifies the number) s
-5 404 M
-( of extended_type-extended_data pairs that follow. Each of these) s
-5 393 M
-( pairs specifies an extended attribute. For each of the attributes,) s
-5 382 M
-( the extended_type field should be a string of the format) s
-5 371 M
-( "name@domain", where "domain" is a valid, registered domain name and) s
-5 360 M
-( "name" identifies the method. The IETF may later standardize certain) s
-5 349 M
-( names that deviate from this format \(e.g., that do not contain the) s
-5 338 M
-( "@" sign\). The interpretation of `extended_data' depends on the) s
-5 327 M
-( type. Implementations SHOULD ignore extended data fields that they) s
-5 316 M
-( do not understand.) s
-5 294 M
-( Additional fields can be added to the attributes by either defining) s
-5 283 M
-( additional bits to the flags field to indicate their presence, or by) s
-5 272 M
-( defining extended attributes for them. The extended attributes) s
-5 261 M
-( mechanism is recommended for most purposes; additional flags bits) s
-5 250 M
-( should only be defined by an IETF standards action that also) s
-5 239 M
-( increments the protocol version number. The use of such new fields) s
-5 228 M
-( MUST be negotiated by the version number in the protocol exchange.) s
-5 217 M
-( It is a protocol error if a packet with unsupported protocol bits is) s
-5 206 M
-( received.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 12]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (12,13) 7
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 13 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(6. Requests From the Client to the Server) s
-5 668 M
-( Requests from the client to the server represent the various file) s
-5 657 M
-( system operations. Each request begins with an `id' field, which is) s
-5 646 M
-( a 32-bit identifier identifying the request \(selected by the client\).) s
-5 635 M
-( The same identifier will be returned in the response to the request.) s
-5 624 M
-( One possible implementation is a monotonically increasing request) s
-5 613 M
-( sequence number \(modulo 2^32\).) s
-5 591 M
-( Many operations in the protocol operate on open files. The) s
-5 580 M
-( SSH_FXP_OPEN request can return a file handle \(which is an opaque) s
-5 569 M
-( variable-length string\) which may be used to access the file later) s
-5 558 M
-( \(e.g. in a read operation\). The client MUST NOT send requests the) s
-5 547 M
-( server with bogus or closed handles. However, the server MUST) s
-5 536 M
-( perform adequate checks on the handle in order to avoid security) s
-5 525 M
-( risks due to fabricated handles.) s
-5 503 M
-( This design allows either stateful and stateless server) s
-5 492 M
-( implementation, as well as an implementation which caches state) s
-5 481 M
-( between requests but may also flush it. The contents of the file) s
-5 470 M
-( handle string are entirely up to the server and its design. The) s
-5 459 M
-( client should not modify or attempt to interpret the file handle) s
-5 448 M
-( strings.) s
-5 426 M
-( The file handle strings MUST NOT be longer than 256 bytes.) s
-5 404 M
-(6.1 Request Synchronization and Reordering) s
-5 382 M
-( The protocol and implementations MUST process requests relating to) s
-5 371 M
-( the same file in the order in which they are received. In other) s
-5 360 M
-( words, if an application submits multiple requests to the server, the) s
-5 349 M
-( results in the responses will be the same as if it had sent the) s
-5 338 M
-( requests one at a time and waited for the response in each case. For) s
-5 327 M
-( example, the server may process non-overlapping read/write requests) s
-5 316 M
-( to the same file in parallel, but overlapping reads and writes cannot) s
-5 305 M
-( be reordered or parallelized. However, there are no ordering) s
-5 294 M
-( restrictions on the server for processing requests from two different) s
-5 283 M
-( file transfer connections. The server may interleave and parallelize) s
-5 272 M
-( them at will.) s
-5 250 M
-( There are no restrictions on the order in which responses to) s
-5 239 M
-( outstanding requests are delivered to the client, except that the) s
-5 228 M
-( server must ensure fairness in the sense that processing of no) s
-5 217 M
-( request will be indefinitely delayed even if the client is sending) s
-5 206 M
-( other requests so that there are multiple outstanding requests all) s
-5 195 M
-( the time.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 13]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 14 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(6.2 File Names) s
-5 668 M
-( This protocol represents file names as strings. File names are) s
-5 657 M
-( assumed to use the slash \('/'\) character as a directory separator.) s
-5 635 M
-( File names starting with a slash are "absolute", and are relative to) s
-5 624 M
-( the root of the file system. Names starting with any other character) s
-5 613 M
-( are relative to the user's default directory \(home directory\). Note) s
-5 602 M
-( that identifying the user is assumed to take place outside of this) s
-5 591 M
-( protocol.) s
-5 569 M
-( Servers SHOULD interpret a path name component ".." as referring to) s
-5 558 M
-( the parent directory, and "." as referring to the current directory.) s
-5 547 M
-( If the server implementation limits access to certain parts of the) s
-5 536 M
-( file system, it must be extra careful in parsing file names when) s
-5 525 M
-( enforcing such restrictions. There have been numerous reported) s
-5 514 M
-( security bugs where a ".." in a path name has allowed access outside) s
-5 503 M
-( the intended area.) s
-5 481 M
-( An empty path name is valid, and it refers to the user's default) s
-5 470 M
-( directory \(usually the user's home directory\).) s
-5 448 M
-( Otherwise, no syntax is defined for file names by this specification.) s
-5 437 M
-( Clients should not make any other assumptions; however, they can) s
-5 426 M
-( splice path name components returned by SSH_FXP_READDIR together) s
-5 415 M
-( using a slash \('/'\) as the separator, and that will work as expected.) s
-5 393 M
-( In order to comply with IETF Policy on Character Sets and Languages) s
-5 382 M
-( [2], all filenames are to be encoded in UTF-8. The shortest valid) s
-5 371 M
-( UTF-8 encoding of the UNICODE data MUST be used. The server is) s
-5 360 M
-( responsible for converting the UNICODE data to whatever canonical) s
-5 349 M
-( form it requires.) s
-5 327 M
-( For example, if the server requires that precomposed characters) s
-5 316 M
-( always be used, the server MUST NOT assume the filename as sent by) s
-5 305 M
-( the client has this attribute, but must do this normalization itself.) s
-5 283 M
-( It is understood that the lack of well-defined semantics for file) s
-5 272 M
-( names may cause interoperability problems between clients and servers) s
-5 261 M
-( using radically different operating systems. However, this approach) s
-5 250 M
-( is known to work acceptably with most systems, and alternative) s
-5 239 M
-( approaches that e.g. treat file names as sequences of structured) s
-5 228 M
-( components are quite complicated.) s
-5 206 M
-(6.3 Opening, Creating, and Closing Files) s
-5 184 M
-( Files are opened and created using the SSH_FXP_OPEN message, whose) s
-5 173 M
-( data part is as follows:) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 14]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (14,15) 8
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 15 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( uint32 id) s
-5 679 M
-( string filename [UTF-8]) s
-5 668 M
-( uint32 pflags) s
-5 657 M
-( ATTRS attrs) s
-5 635 M
-( The `id' field is the request identifier as for all requests.) s
-5 613 M
-( The `filename' field specifies the file name. See Section ``File) s
-5 602 M
-( Names'' for more information.) s
-5 580 M
-( The `pflags' field is a bitmask. The following bits have been) s
-5 569 M
-( defined.) s
-5 547 M
-( #define SSH_FXF_READ 0x00000001) s
-5 536 M
-( #define SSH_FXF_WRITE 0x00000002) s
-5 525 M
-( #define SSH_FXF_APPEND 0x00000004) s
-5 514 M
-( #define SSH_FXF_CREAT 0x00000008) s
-5 503 M
-( #define SSH_FXF_TRUNC 0x00000010) s
-5 492 M
-( #define SSH_FXF_EXCL 0x00000020) s
-5 481 M
-( #define SSH_FXF_TEXT 0x00000040) s
-5 459 M
-( These have the following meanings:) s
-5 437 M
-( SSH_FXF_READ) s
-5 426 M
-( Open the file for reading.) s
-5 404 M
-( SSH_FXF_WRITE) s
-5 393 M
-( Open the file for writing. If both this and SSH_FXF_READ are) s
-5 382 M
-( specified, the file is opened for both reading and writing.) s
-5 360 M
-( SSH_FXF_APPEND) s
-5 349 M
-( Force all writes to append data at the end of the file. The) s
-5 338 M
-( offset parameter to write will be ignored.) s
-5 316 M
-( SSH_FXF_CREAT) s
-5 305 M
-( If this flag is specified, then a new file will be created if one) s
-5 294 M
-( does not already exist \(if O_TRUNC is specified, the new file will) s
-5 283 M
-( be truncated to zero length if it previously exists\).) s
-5 261 M
-( SSH_FXF_TRUNC) s
-5 250 M
-( Forces an existing file with the same name to be truncated to zero) s
-5 239 M
-( length when creating a file by specifying SSH_FXF_CREAT.) s
-5 228 M
-( SSH_FXF_CREAT MUST also be specified if this flag is used.) s
-5 206 M
-( SSH_FXF_EXCL) s
-5 195 M
-( Causes the request to fail if the named file already exists.) s
-5 184 M
-( SSH_FXF_CREAT MUST also be specified if this flag is used.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 15]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 16 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( SSH_FXF_TEXT) s
-5 679 M
-( Indicates that the server should treat the file as text and) s
-5 668 M
-( convert it to the canonical newline convention in use. \(See) s
-5 657 M
-( Determining Server Newline Convention. \(Section 4.3\)) s
-5 635 M
-( When a file is opened with the FXF_TEXT flag, the offset field in) s
-5 624 M
-( both the read and write function are ignored.) s
-5 602 M
-( Servers MUST correctly process multiple parallel reads and writes) s
-5 591 M
-( correctly in this mode. Naturally, it is permissible for them to) s
-5 580 M
-( do this by serializing the requests. It would not be possible for) s
-5 569 M
-( a client to reliably detect a server that does not implement) s
-5 558 M
-( parallel writes in time to prevent damage.) s
-5 536 M
-( Clients SHOULD use the SSH_FXF_APPEND flag to append data to a) s
-5 525 M
-( text file rather then using write with a calculated offset.) s
-5 503 M
-( To support seeks on text file the following SSH_FXP_EXTENDED) s
-5 492 M
-( packet is defined.) s
-5 448 M
-( string "text-seek") s
-5 437 M
-( string file-handle) s
-5 426 M
-( uint64 line-number) s
-5 404 M
-( line-number is the index of the line number to seek to, where byte) s
-5 393 M
-( 0 in the file is line number 0, and the byte directly following) s
-5 382 M
-( the first newline sequence in the file is line number 1 and so on.) s
-5 360 M
-( The response to a "text-seek" request is an SSH_FXP_STATUS) s
-5 349 M
-( message.) s
-5 327 M
-( An attempt to seek past the end-of-file should result in a) s
-5 316 M
-( SSH_FX_EOF status.) s
-5 294 M
-( Servers SHOULD support at least one "text-seek" in order to) s
-5 283 M
-( support resume. However, a client MUST be prepared to receive) s
-5 272 M
-( SSH_FX_OP_UNSUPPORTED when attempting a "text-seek" operation.) s
-5 261 M
-( The client can then try a fall-back strategy, if it has one.) s
-5 239 M
-( Clients MUST be prepared to handle SSH_FX_OP_UNSUPPORTED returned) s
-5 228 M
-( for read or write operations that are not sequential.) s
-5 206 M
-( The `attrs' field specifies the initial attributes for the file.) s
-5 195 M
-( Default values will be used for those attributes that are not) s
-5 184 M
-( specified. See Section ``File Attributes'' for more information.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 16]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (16,17) 9
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 17 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( The response to this message will be either SSH_FXP_HANDLE \(if the) s
-5 679 M
-( operation is successful\) or SSH_FXP_STATUS \(if the operation fails\).) s
-5 657 M
-( A file is closed by using the SSH_FXP_CLOSE request. Its data field) s
-5 646 M
-( has the following format:) s
-5 624 M
-( uint32 id) s
-5 613 M
-( string handle) s
-5 591 M
-( where `id' is the request identifier, and `handle' is a handle) s
-5 580 M
-( previously returned in the response to SSH_FXP_OPEN or) s
-5 569 M
-( SSH_FXP_OPENDIR. The handle becomes invalid immediately after this) s
-5 558 M
-( request has been sent.) s
-5 536 M
-( The response to this request will be a SSH_FXP_STATUS message. One) s
-5 525 M
-( should note that on some server platforms even a close can fail.) s
-5 514 M
-( This can happen e.g. if the server operating system caches writes,) s
-5 503 M
-( and an error occurs while flushing cached writes during the close.) s
-5 481 M
-(6.4 Reading and Writing) s
-5 459 M
-( Once a file has been opened, it can be read using the SSH_FXP_READ) s
-5 448 M
-( message, which has the following format:) s
-5 426 M
-( uint32 id) s
-5 415 M
-( string handle) s
-5 404 M
-( uint64 offset) s
-5 393 M
-( uint32 len) s
-5 371 M
-( where `id' is the request identifier, `handle' is an open file handle) s
-5 360 M
-( returned by SSH_FXP_OPEN, `offset' is the offset \(in bytes\) relative) s
-5 349 M
-( to the beginning of the file from where to start reading, and `len') s
-5 338 M
-( is the maximum number of bytes to read.) s
-5 316 M
-( In response to this request, the server will read as many bytes as it) s
-5 305 M
-( can from the file \(up to `len'\), and return them in a SSH_FXP_DATA) s
-5 294 M
-( message. If an error occurs or EOF is encountered before reading any) s
-5 283 M
-( data, the server will respond with SSH_FXP_STATUS. For normal disk) s
-5 272 M
-( files, it is guaranteed that this will read the specified number of) s
-5 261 M
-( bytes, or up to end of file. For e.g. device files this may return) s
-5 250 M
-( fewer bytes than requested.) s
-5 228 M
-( Writing to a file is achieved using the SSH_FXP_WRITE message, which) s
-5 217 M
-( has the following format:) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 17]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 18 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( uint32 id) s
-5 679 M
-( string handle) s
-5 668 M
-( uint64 offset) s
-5 657 M
-( string data) s
-5 635 M
-( where `id' is a request identifier, `handle' is a file handle) s
-5 624 M
-( returned by SSH_FXP_OPEN, `offset' is the offset \(in bytes\) from the) s
-5 613 M
-( beginning of the file where to start writing, and `data' is the data) s
-5 602 M
-( to be written.) s
-5 580 M
-( The write will extend the file if writing beyond the end of the file.) s
-5 569 M
-( It is legal to write way beyond the end of the file; the semantics) s
-5 558 M
-( are to write zeroes from the end of the file to the specified offset) s
-5 547 M
-( and then the data. On most operating systems, such writes do not) s
-5 536 M
-( allocate disk space but instead leave "holes" in the file.) s
-5 514 M
-( The server responds to a write request with a SSH_FXP_STATUS message.) s
-5 492 M
-(6.5 Removing and Renaming Files) s
-5 470 M
-( Files can be removed using the SSH_FXP_REMOVE message. It has the) s
-5 459 M
-( following format:) s
-5 437 M
-( uint32 id) s
-5 426 M
-( string filename [UTF-8]) s
-5 404 M
-( where `id' is the request identifier and `filename' is the name of) s
-5 393 M
-( the file to be removed. See Section ``File Names'' for more) s
-5 382 M
-( information. This request cannot be used to remove directories.) s
-5 360 M
-( The server will respond to this request with a SSH_FXP_STATUS) s
-5 349 M
-( message.) s
-5 327 M
-( Files \(and directories\) can be renamed using the SSH_FXP_RENAME) s
-5 316 M
-( message. Its data is as follows:) s
-5 294 M
-( uint32 id) s
-5 283 M
-( string oldpath [UTF-8]) s
-5 272 M
-( string newpath [UTF-8]) s
-5 250 M
-( where `id' is the request identifier, `oldpath' is the name of an) s
-5 239 M
-( existing file or directory, and `newpath' is the new name for the) s
-5 228 M
-( file or directory. It is an error if there already exists a file) s
-5 217 M
-( with the name specified by newpath. The server may also fail rename) s
-5 206 M
-( requests in other situations, for example if `oldpath' and `newpath') s
-5 195 M
-( point to different file systems on the server.) s
-5 173 M
-( The server will respond to this request with a SSH_FXP_STATUS) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 18]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (18,19) 10
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 19 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( message.) s
-5 668 M
-(6.6 Creating and Deleting Directories) s
-5 646 M
-( New directories can be created using the SSH_FXP_MKDIR request. It) s
-5 635 M
-( has the following format:) s
-5 613 M
-( uint32 id) s
-5 602 M
-( string path [UTF-8]) s
-5 591 M
-( ATTRS attrs) s
-5 569 M
-( where `id' is the request identifier.) s
-5 547 M
-( `path' specifies the directory to be created. See Section ``File) s
-5 536 M
-( Names'' for more information on file names.) s
-5 514 M
-( `attrs' specifies the attributes that should be applied to it upon) s
-5 503 M
-( creation. Attributes are discussed in more detail in Section ``File) s
-5 492 M
-( Attributes''.) s
-5 470 M
-( The server will respond to this request with a SSH_FXP_STATUS) s
-5 459 M
-( message. If a file or directory with the specified path already) s
-5 448 M
-( exists, an error will be returned.) s
-5 426 M
-( Directories can be removed using the SSH_FXP_RMDIR request, which has) s
-5 415 M
-( the following format:) s
-5 393 M
-( uint32 id) s
-5 382 M
-( string path [UTF-8]) s
-5 360 M
-( where `id' is the request identifier, and `path' specifies the) s
-5 349 M
-( directory to be removed. See Section ``File Names'' for more) s
-5 338 M
-( information on file names.) s
-5 316 M
-( The server responds to this request with a SSH_FXP_STATUS message.) s
-5 305 M
-( Errors may be returned from this operation for various reasons,) s
-5 294 M
-( including, but not limited to, the path does not exist, the path does) s
-5 283 M
-( not refer to a directory object, the directory is not empty, or the) s
-5 272 M
-( user has insufficient access or permission to perform the requested) s
-5 261 M
-( operation.) s
-5 239 M
-(6.7 Scanning Directories) s
-5 217 M
-( The files in a directory can be listed using the SSH_FXP_OPENDIR and) s
-5 206 M
-( SSH_FXP_READDIR requests. Each SSH_FXP_READDIR request returns one) s
-5 195 M
-( or more file names with full file attributes for each file. The) s
-5 184 M
-( client should call SSH_FXP_READDIR repeatedly until it has found the) s
-5 173 M
-( file it is looking for or until the server responds with a) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 19]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 20 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( SSH_FXP_STATUS message indicating an error \(normally SSH_FX_EOF if) s
-5 679 M
-( there are no more files in the directory\). The client should then) s
-5 668 M
-( close the handle using the SSH_FXP_CLOSE request.) s
-5 646 M
-( The SSH_FXP_OPENDIR opens a directory for reading. It has the) s
-5 635 M
-( following format:) s
-5 613 M
-( uint32 id) s
-5 602 M
-( string path [UTF-8]) s
-5 580 M
-( where `id' is the request identifier and `path' is the path name of) s
-5 569 M
-( the directory to be listed \(without any trailing slash\). See Section) s
-5 558 M
-( ``File Names'' for more information on file names. This will return) s
-5 547 M
-( an error if the path does not specify a directory or if the directory) s
-5 536 M
-( is not readable. The server will respond to this request with either) s
-5 525 M
-( a SSH_FXP_HANDLE or a SSH_FXP_STATUS message.) s
-5 503 M
-( Once the directory has been successfully opened, files \(and) s
-5 492 M
-( directories\) contained in it can be listed using SSH_FXP_READDIR) s
-5 481 M
-( requests. These are of the format) s
-5 459 M
-( uint32 id) s
-5 448 M
-( string handle) s
-5 426 M
-( where `id' is the request identifier, and `handle' is a handle) s
-5 415 M
-( returned by SSH_FXP_OPENDIR. \(It is a protocol error to attempt to) s
-5 404 M
-( use an ordinary file handle returned by SSH_FXP_OPEN.\)) s
-5 382 M
-( The server responds to this request with either a SSH_FXP_NAME or a) s
-5 371 M
-( SSH_FXP_STATUS message. One or more names may be returned at a time.) s
-5 360 M
-( Full status information is returned for each name in order to speed) s
-5 349 M
-( up typical directory listings.) s
-5 327 M
-( If there are no more names available to be read, the server MUST) s
-5 316 M
-( respond with a SSH_FXP_STATUS message with error code of SSH_FX_EOF.) s
-5 294 M
-( When the client no longer wishes to read more names from the) s
-5 283 M
-( directory, it SHOULD call SSH_FXP_CLOSE for the handle. The handle) s
-5 272 M
-( should be closed regardless of whether an error has occurred or not.) s
-5 250 M
-(6.8 Retrieving File Attributes) s
-5 228 M
-( Very often, file attributes are automatically returned by) s
-5 217 M
-( SSH_FXP_READDIR. However, sometimes there is need to specifically) s
-5 206 M
-( retrieve the attributes for a named file. This can be done using the) s
-5 195 M
-( SSH_FXP_STAT, SSH_FXP_LSTAT and SSH_FXP_FSTAT requests.) s
-5 173 M
-( SSH_FXP_STAT and SSH_FXP_LSTAT only differ in that SSH_FXP_STAT) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 20]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (20,21) 11
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 21 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( follows symbolic links on the server, whereas SSH_FXP_LSTAT does not) s
-5 679 M
-( follow symbolic links. Both have the same format:) s
-5 657 M
-( uint32 id) s
-5 646 M
-( string path [UTF-8]) s
-5 635 M
-( uint32 flags) s
-5 613 M
-( where `id' is the request identifier, and `path' specifies the file) s
-5 602 M
-( system object for which status is to be returned. The server) s
-5 591 M
-( responds to this request with either SSH_FXP_ATTRS or SSH_FXP_STATUS.) s
-5 569 M
-( The flags field specify the attribute flags in which the client has) s
-5 558 M
-( particular interest. This is a hint to the server. For example,) s
-5 547 M
-( because retrieving owner / group and acl information can be an) s
-5 536 M
-( expensive operation under some operating systems, the server may) s
-5 525 M
-( choose not to retrieve this information unless the client expresses a) s
-5 514 M
-( specific interest in it.) s
-5 492 M
-( The client has no guarantee the server will provide all the fields) s
-5 481 M
-( that it has expressed an interest in.) s
-5 459 M
-( SSH_FXP_FSTAT differs from the others in that it returns status) s
-5 448 M
-( information for an open file \(identified by the file handle\). Its) s
-5 437 M
-( format is as follows:) s
-5 415 M
-( uint32 id) s
-5 404 M
-( string handle) s
-5 393 M
-( uint32 flags) s
-5 371 M
-( where `id' is the request identifier and `handle' is a file handle) s
-5 360 M
-( returned by SSH_FXP_OPEN. The server responds to this request with) s
-5 349 M
-( SSH_FXP_ATTRS or SSH_FXP_STATUS.) s
-5 327 M
-(6.9 Setting File Attributes) s
-5 305 M
-( File attributes may be modified using the SSH_FXP_SETSTAT and) s
-5 294 M
-( SSH_FXP_FSETSTAT requests. These requests are used for operations) s
-5 283 M
-( such as changing the ownership, permissions or access times, as well) s
-5 272 M
-( as for truncating a file.) s
-5 250 M
-( The SSH_FXP_SETSTAT request is of the following format:) s
-5 228 M
-( uint32 id) s
-5 217 M
-( string path [UTF-8]) s
-5 206 M
-( ATTRS attrs) s
-5 184 M
-( where `id' is the request identifier, `path' specifies the file) s
-5 173 M
-( system object \(e.g. file or directory\) whose attributes are to be) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 21]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 22 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( modified, and `attrs' specifies the modifications to be made to its) s
-5 679 M
-( attributes. Attributes are discussed in more detail in Section) s
-5 668 M
-( ``File Attributes''.) s
-5 646 M
-( An error will be returned if the specified file system object does) s
-5 635 M
-( not exist or the user does not have sufficient rights to modify the) s
-5 624 M
-( specified attributes. The server responds to this request with a) s
-5 613 M
-( SSH_FXP_STATUS message.) s
-5 591 M
-( The SSH_FXP_FSETSTAT request modifies the attributes of a file which) s
-5 580 M
-( is already open. It has the following format:) s
-5 558 M
-( uint32 id) s
-5 547 M
-( string handle) s
-5 536 M
-( ATTRS attrs) s
-5 514 M
-( where `id' is the request identifier, `handle' \(MUST be returned by) s
-5 503 M
-( SSH_FXP_OPEN\) identifies the file whose attributes are to be) s
-5 492 M
-( modified, and `attrs' specifies the modifications to be made to its) s
-5 481 M
-( attributes. Attributes are discussed in more detail in Section) s
-5 470 M
-( ``File Attributes''. The server will respond to this request with) s
-5 459 M
-( SSH_FXP_STATUS.) s
-5 437 M
-(6.10 Dealing with Symbolic links) s
-5 415 M
-( The SSH_FXP_READLINK request may be used to read the target of a) s
-5 404 M
-( symbolic link. It would have a data part as follows:) s
-5 382 M
-( uint32 id) s
-5 371 M
-( string path [UTF-8]) s
-5 349 M
-( where `id' is the request identifier and `path' specifies the path) s
-5 338 M
-( name of the symlink to be read.) s
-5 316 M
-( The server will respond with a SSH_FXP_NAME packet containing only) s
-5 305 M
-( one name and a dummy attributes value. The name in the returned) s
-5 294 M
-( packet contains the target of the link. If an error occurs, the) s
-5 283 M
-( server may respond with SSH_FXP_STATUS.) s
-5 261 M
-( The SSH_FXP_SYMLINK request will create a symbolic link on the) s
-5 250 M
-( server. It is of the following format) s
-5 228 M
-( uint32 id) s
-5 217 M
-( string linkpath [UTF-8]) s
-5 206 M
-( string targetpath [UTF-8]) s
-5 184 M
-( where `id' is the request identifier, `linkpath' specifies the path) s
-5 173 M
-( name of the symlink to be created and `targetpath' specifies the) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 22]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (22,23) 12
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 23 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( target of the symlink. The server shall respond with a) s
-5 679 M
-( SSH_FXP_STATUS indicating either success \(SSH_FX_OK\) or an error) s
-5 668 M
-( condition.) s
-5 646 M
-(6.11 Canonicalizing the Server-Side Path Name) s
-5 624 M
-( The SSH_FXP_REALPATH request can be used to have the server) s
-5 613 M
-( canonicalize any given path name to an absolute path. This is useful) s
-5 602 M
-( for converting path names containing ".." components or relative) s
-5 591 M
-( pathnames without a leading slash into absolute paths. The format of) s
-5 580 M
-( the request is as follows:) s
-5 558 M
-( uint32 id) s
-5 547 M
-( string path [UTF-8]) s
-5 525 M
-( where `id' is the request identifier and `path' specifies the path) s
-5 514 M
-( name to be canonicalized. The server will respond with a) s
-5 503 M
-( SSH_FXP_NAME packet containing the name in canonical form and a dummy) s
-5 492 M
-( attributes value. If an error occurs, the server may also respond) s
-5 481 M
-( with SSH_FXP_STATUS.) s
-5 459 M
-(6.11.1 Best practice for dealing with paths) s
-5 437 M
-( The client SHOULD treat the results of SSH_FXP_REALPATH as a) s
-5 426 M
-( canonical absolute path, even if the path does not appear to be) s
-5 415 M
-( absolute. A client that use REALPATH\("."\) and treats the result as) s
-5 404 M
-( absolute, even if there is no leading slash, will continue to) s
-5 393 M
-( function correctly, even when talking to a Windows NT or VMS style) s
-5 382 M
-( system, where absolute paths may not begin with a slash.) s
-5 360 M
-( For example, if the client wishes to change directory up, and the) s
-5 349 M
-( server has returned "c:/x/y/z" from REALPATH, the client SHOULD use) s
-5 338 M
-( "c:/x/y/z/..".) s
-5 316 M
-( As a second example, if the client wishes to open the file "x.txt" in) s
-5 305 M
-( the current directory, and server has returned "dka100:/x/y/z" as the) s
-5 294 M
-( canonical path of the directory, the client SHOULD open "dka100:/x/y/) s
-5 283 M
-( z/x.txt") s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 23]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 24 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(7. Responses from the Server to the Client) s
-5 668 M
-( The server responds to the client using one of a few response) s
-5 657 M
-( packets. All requests can return a SSH_FXP_STATUS response upon) s
-5 646 M
-( failure. When the operation is successful, any of the responses may) s
-5 635 M
-( be returned \(depending on the operation\). If no data needs to be) s
-5 624 M
-( returned to the client, the SSH_FXP_STATUS response with SSH_FX_OK) s
-5 613 M
-( status is appropriate. Otherwise, the SSH_FXP_HANDLE message is used) s
-5 602 M
-( to return a file handle \(for SSH_FXP_OPEN and SSH_FXP_OPENDIR) s
-5 591 M
-( requests\), SSH_FXP_DATA is used to return data from SSH_FXP_READ,) s
-5 580 M
-( SSH_FXP_NAME is used to return one or more file names from a) s
-5 569 M
-( SSH_FXP_READDIR or SSH_FXP_REALPATH request, and SSH_FXP_ATTRS is) s
-5 558 M
-( used to return file attributes from SSH_FXP_STAT, SSH_FXP_LSTAT, and) s
-5 547 M
-( SSH_FXP_FSTAT requests.) s
-5 525 M
-( Exactly one response will be returned for each request. Each) s
-5 514 M
-( response packet contains a request identifier which can be used to) s
-5 503 M
-( match each response with the corresponding request. Note that it is) s
-5 492 M
-( legal to have several requests outstanding simultaneously, and the) s
-5 481 M
-( server is allowed to send responses to them in a different order from) s
-5 470 M
-( the order in which the requests were sent \(the result of their) s
-5 459 M
-( execution, however, is guaranteed to be as if they had been processed) s
-5 448 M
-( one at a time in the order in which the requests were sent\).) s
-5 426 M
-( Response packets are of the same general format as request packets.) s
-5 415 M
-( Each response packet begins with the request identifier.) s
-5 393 M
-( The format of the data portion of the SSH_FXP_STATUS response is as) s
-5 382 M
-( follows:) s
-5 360 M
-( uint32 id) s
-5 349 M
-( uint32 error/status code) s
-5 338 M
-( string error message \(ISO-10646 UTF-8 [RFC-2279]\)) s
-5 327 M
-( string language tag \(as defined in [RFC-1766]\)) s
-5 305 M
-( where `id' is the request identifier, and `error/status code') s
-5 294 M
-( indicates the result of the requested operation. The value SSH_FX_OK) s
-5 283 M
-( indicates success, and all other values indicate failure.) s
-5 261 M
-( Currently, the following values are defined \(other values may be) s
-5 250 M
-( defined by future versions of this protocol\):) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 24]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (24,25) 13
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 25 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( #define SSH_FX_OK 0) s
-5 679 M
-( #define SSH_FX_EOF 1) s
-5 668 M
-( #define SSH_FX_NO_SUCH_FILE 2) s
-5 657 M
-( #define SSH_FX_PERMISSION_DENIED 3) s
-5 646 M
-( #define SSH_FX_FAILURE 4) s
-5 635 M
-( #define SSH_FX_BAD_MESSAGE 5) s
-5 624 M
-( #define SSH_FX_NO_CONNECTION 6) s
-5 613 M
-( #define SSH_FX_CONNECTION_LOST 7) s
-5 602 M
-( #define SSH_FX_OP_UNSUPPORTED 8) s
-5 591 M
-( #define SSH_FX_INVALID_HANDLE 9) s
-5 580 M
-( #define SSH_FX_NO_SUCH_PATH 10) s
-5 569 M
-( #define SSH_FX_FILE_ALREADY_EXISTS 11) s
-5 558 M
-( #define SSH_FX_WRITE_PROTECT 12) s
-5 536 M
-( SSH_FX_OK) s
-5 525 M
-( Indicates successful completion of the operation.) s
-5 503 M
-( SSH_FX_EOF) s
-5 492 M
-( indicates end-of-file condition; for SSH_FX_READ it means that no) s
-5 481 M
-( more data is available in the file, and for SSH_FX_READDIR it) s
-5 470 M
-( indicates that no more files are contained in the directory.) s
-5 448 M
-( SSH_FX_NO_SUCH_FILE) s
-5 437 M
-( is returned when a reference is made to a file which does not) s
-5 426 M
-( exist.) s
-5 404 M
-( SSH_FX_PERMISSION_DENIED) s
-5 393 M
-( is returned when the authenticated user does not have sufficient) s
-5 382 M
-( permissions to perform the operation.) s
-5 360 M
-( SSH_FX_FAILURE) s
-5 349 M
-( is a generic catch-all error message; it should be returned if an) s
-5 338 M
-( error occurs for which there is no more specific error code) s
-5 327 M
-( defined.) s
-5 305 M
-( SSH_FX_BAD_MESSAGE) s
-5 294 M
-( may be returned if a badly formatted packet or protocol) s
-5 283 M
-( incompatibility is detected.) s
-5 261 M
-( SSH_FX_NO_CONNECTION) s
-5 250 M
-( is a pseudo-error which indicates that the client has no) s
-5 239 M
-( connection to the server \(it can only be generated locally by the) s
-5 228 M
-( client, and MUST NOT be returned by servers\).) s
-5 206 M
-( SSH_FX_CONNECTION_LOST) s
-5 195 M
-( is a pseudo-error which indicates that the connection to the) s
-5 184 M
-( server has been lost \(it can only be generated locally by the) s
-5 173 M
-( client, and MUST NOT be returned by servers\).) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 25]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 26 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( SSH_FX_OP_UNSUPPORTED) s
-5 679 M
-( indicates that an attempt was made to perform an operation which) s
-5 668 M
-( is not supported for the server \(it may be generated locally by) s
-5 657 M
-( the client if e.g. the version number exchange indicates that a) s
-5 646 M
-( required feature is not supported by the server, or it may be) s
-5 635 M
-( returned by the server if the server does not implement an) s
-5 624 M
-( operation\).) s
-5 602 M
-( SSH_FX_INVALID_HANDLE) s
-5 591 M
-( The handle value was invalid.) s
-5 569 M
-( SSH_FX_NO_SUCH_PATH) s
-5 558 M
-( The file path does not exist or is invalid.) s
-5 536 M
-( SSH_FX_FILE_ALREADY_EXISTS) s
-5 525 M
-( The file already exists.) s
-5 503 M
-( SSH_FX_WRITE_PROTECT) s
-5 492 M
-( The file is on read only media, or the media is write protected.) s
-5 470 M
-( The SSH_FXP_HANDLE response has the following format:) s
-5 448 M
-( uint32 id) s
-5 437 M
-( string handle) s
-5 415 M
-( where `id' is the request identifier, and `handle' is an arbitrary) s
-5 404 M
-( string that identifies an open file or directory on the server. The) s
-5 393 M
-( handle is opaque to the client; the client MUST NOT attempt to) s
-5 382 M
-( interpret or modify it in any way. The length of the handle string) s
-5 371 M
-( MUST NOT exceed 256 data bytes.) s
-5 349 M
-( The SSH_FXP_DATA response has the following format:) s
-5 327 M
-( uint32 id) s
-5 316 M
-( string data) s
-5 294 M
-( where `id' is the request identifier, and `data' is an arbitrary byte) s
-5 283 M
-( string containing the requested data. The data string may be at most) s
-5 272 M
-( the number of bytes requested in a SSH_FXP_READ request, but may also) s
-5 261 M
-( be shorter if end of file is reached or if the read is from something) s
-5 250 M
-( other than a regular file.) s
-5 228 M
-( The SSH_FXP_NAME response has the following format:) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 26]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (26,27) 14
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 27 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( uint32 id) s
-5 679 M
-( uint32 count) s
-5 668 M
-( repeats count times:) s
-5 657 M
-( string filename [UTF-8]) s
-5 646 M
-( ATTRS attrs) s
-5 624 M
-( where `id' is the request identifier, `count' is the number of names) s
-5 613 M
-( returned in this response, and the remaining fields repeat `count') s
-5 602 M
-( times \(so that all three fields are first included for the first) s
-5 591 M
-( file, then for the second file, etc\). In the repeated part,) s
-5 580 M
-( `filename' is a file name being returned \(for SSH_FXP_READDIR, it) s
-5 569 M
-( will be a relative name within the directory, without any path) s
-5 558 M
-( components; for SSH_FXP_REALPATH it will be an absolute path name\),) s
-5 547 M
-( and `attrs' is the attributes of the file as described in Section) s
-5 536 M
-( ``File Attributes''.) s
-5 514 M
-( The SSH_FXP_ATTRS response has the following format:) s
-5 492 M
-( uint32 id) s
-5 481 M
-( ATTRS attrs) s
-5 459 M
-( where `id' is the request identifier, and `attrs' is the returned) s
-5 448 M
-( file attributes as described in Section ``File Attributes''.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 27]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 28 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(8. Vendor-Specific Extensions) s
-5 668 M
-( The SSH_FXP_EXTENDED request provides a generic extension mechanism) s
-5 657 M
-( for adding vendor-specific commands. The request has the following) s
-5 646 M
-( format:) s
-5 624 M
-( uint32 id) s
-5 613 M
-( string extended-request) s
-5 602 M
-( ... any request-specific data ...) s
-5 580 M
-( where `id' is the request identifier, and `extended-request' is a) s
-5 569 M
-( string of the format "name@domain", where domain is an internet) s
-5 558 M
-( domain name of the vendor defining the request. The rest of the) s
-5 547 M
-( request is completely vendor-specific, and servers should only) s
-5 536 M
-( attempt to interpret it if they recognize the `extended-request') s
-5 525 M
-( name.) s
-5 503 M
-( The server may respond to such requests using any of the response) s
-5 492 M
-( packets defined in Section ``Responses from the Server to the) s
-5 481 M
-( Client''. Additionally, the server may also respond with a) s
-5 470 M
-( SSH_FXP_EXTENDED_REPLY packet, as defined below. If the server does) s
-5 459 M
-( not recognize the `extended-request' name, then the server MUST) s
-5 448 M
-( respond with SSH_FXP_STATUS with error/status set to) s
-5 437 M
-( SSH_FX_OP_UNSUPPORTED.) s
-5 415 M
-( The SSH_FXP_EXTENDED_REPLY packet can be used to carry arbitrary) s
-5 404 M
-( extension-specific data from the server to the client. It is of the) s
-5 393 M
-( following format:) s
-5 371 M
-( uint32 id) s
-5 360 M
-( ... any request-specific data ...) s
-5 338 M
-( There is a range of packet types reserved for use by extensions. In) s
-5 327 M
-( order to avoid collision, extensions that turn on the use of) s
-5 316 M
-( additional packet types should determine those numbers dynamically.) s
-5 294 M
-( The suggested way of doing this is have an extension request from the) s
-5 283 M
-( client to the server that enables the extension; the extension) s
-5 272 M
-( response from the server to the client would specify the actual type) s
-5 261 M
-( values to use, in additional to any other data.) s
-5 239 M
-( Extension authors should be mindful of the limited range of packet) s
-5 228 M
-( types available \(there are only 45 values available\) and avoid) s
-5 217 M
-( requiring a new packet type where possible.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 28]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (28,29) 15
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 29 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(9. Security Considerations) s
-5 668 M
-( This protocol assumes that it is run over a secure channel and that) s
-5 657 M
-( the endpoints of the channel have been authenticated. Thus, this) s
-5 646 M
-( protocol assumes that it is externally protected from network-level) s
-5 635 M
-( attacks.) s
-5 613 M
-( This protocol provides file system access to arbitrary files on the) s
-5 602 M
-( server \(only constrained by the server implementation\). It is the) s
-5 591 M
-( responsibility of the server implementation to enforce any access) s
-5 580 M
-( controls that may be required to limit the access allowed for any) s
-5 569 M
-( particular user \(the user being authenticated externally to this) s
-5 558 M
-( protocol, typically using the SSH User Authentication Protocol [8].) s
-5 536 M
-( Care must be taken in the server implementation to check the validity) s
-5 525 M
-( of received file handle strings. The server should not rely on them) s
-5 514 M
-( directly; it MUST check the validity of each handle before relying on) s
-5 503 M
-( it.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 29]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 30 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(10. Changes from previous protocol versions) s
-5 668 M
-( The SSH File Transfer Protocol has changed over time, before it's) s
-5 657 M
-( standardization. The following is a description of the incompatible) s
-5 646 M
-( changes between different versions.) s
-5 624 M
-(10.1 Changes between versions 4 and 3) s
-5 602 M
-( Many of the changes between version 4 and version 3 are to the) s
-5 591 M
-( attribute structure to make it more flexible for non-unix platforms.) s
-5 569 M
-( o Make all filenames UTF-8.) s
-5 547 M
-( o Added 'newline' extension.) s
-5 525 M
-( o Made file attribute owner and group strings so they can actually) s
-5 514 M
-( be used on disparate systems.) s
-5 492 M
-( o Added createtime field, and added separate flags for atime,) s
-5 481 M
-( createtime, and mtime so they can be set separately.) s
-5 459 M
-( o Split the file type out of the permissions field and into it's own) s
-5 448 M
-( field \(which is always present.\)) s
-5 426 M
-( o Added acl attribute.) s
-5 404 M
-( o Added SSH_FXF_TEXT file open flag.) s
-5 382 M
-( o Added flags field to the get stat commands so that the client can) s
-5 371 M
-( specifically request information the server might not normally) s
-5 360 M
-( included for performance reasons.) s
-5 338 M
-( o Removed the long filename from the names structure-- it can now be) s
-5 327 M
-( built from information available in the attrs structure.) s
-5 305 M
-( o Added reserved range of packet numbers for extensions.) s
-5 283 M
-( o Added several additional error codes.) s
-5 261 M
-( o Change the way version negotiate works slightly. Previously, if) s
-5 250 M
-( the client version were higher than the server version, the server) s
-5 239 M
-( was supposed to 'echo back' the clients version. The server now) s
-5 228 M
-( sends it's own version and the lower of the two is considered to) s
-5 217 M
-( be the one in use.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 30]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (30,31) 16
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 31 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(10.2 Changes between versions 3 and 2) s
-5 668 M
-( o The SSH_FXP_READLINK and SSH_FXP_SYMLINK messages were added.) s
-5 646 M
-( o The SSH_FXP_EXTENDED and SSH_FXP_EXTENDED_REPLY messages were) s
-5 635 M
-( added.) s
-5 613 M
-( o The SSH_FXP_STATUS message was changed to include fields `error) s
-5 602 M
-( message' and `language tag'.) s
-5 569 M
-(10.3 Changes between versions 2 and 1) s
-5 547 M
-( o The SSH_FXP_RENAME message was added.) s
-5 514 M
-(10.4 Changes between versions 1 and 0) s
-5 492 M
-( o Implementation changes, no actual protocol changes.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 31]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 32 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(11. Trademark Issues) s
-5 668 M
-( "ssh" is a registered trademark of SSH Communications Security Corp) s
-5 657 M
-( in the United States and/or other countries.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 32]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (32,33) 17
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 33 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(References) s
-5 668 M
-( [1] Dierks, T., Allen, C., Treese, W., Karlton, P., Freier, A. and) s
-5 657 M
-( P. Kocher, "The TLS Protocol Version 1.0", RFC 2246, January) s
-5 646 M
-( 1999.) s
-5 624 M
-( [2] Alvestrand, H., "IETF Policy on Character Sets and Languages",) s
-5 613 M
-( BCP 18, RFC 2277, January 1998.) s
-5 591 M
-( [3] Shepler, S., Callaghan, B., Robinson, D., Thurlow, R., Beame,) s
-5 580 M
-( C., Eisler, M. and D. Noveck, "NFS version 4 Protocol", RFC) s
-5 569 M
-( 3010, December 2000.) s
-5 547 M
-( [4] Institute of Electrical and Electronics Engineers, "Information) s
-5 536 M
-( Technology - Portable Operating System Interface \(POSIX\) - Part) s
-5 525 M
-( 1: System Application Program Interface \(API\) [C Language]",) s
-5 514 M
-( IEEE Standard 1003.2, 1996.) s
-5 492 M
-( [5] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.) s
-5 481 M
-( Lehtinen, "SSH Protocol Architecture", draft-ietf-secsh-) s
-5 470 M
-( architecture-13 \(work in progress\), September 2002.) s
-5 448 M
-( [6] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.) s
-5 437 M
-( Lehtinen, "SSH Protocol Transport Protocol", draft-ietf-secsh-) s
-5 426 M
-( transport-15 \(work in progress\), September 2002.) s
-5 404 M
-( [7] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.) s
-5 393 M
-( Lehtinen, "SSH Connection Protocol", draft-ietf-secsh-connect-16) s
-5 382 M
-( \(work in progress\), September 2002.) s
-5 360 M
-( [8] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.) s
-5 349 M
-( Lehtinen, "SSH Authentication Protocol", draft-ietf-secsh-) s
-5 338 M
-( userauth-16 \(work in progress\), September 2002.) s
-5 305 M
-(Authors' Addresses) s
-5 283 M
-( Joseph Galbraith) s
-5 272 M
-( VanDyke Software) s
-5 261 M
-( 4848 Tramway Ridge Blvd) s
-5 250 M
-( Suite 101) s
-5 239 M
-( Albuquerque, NM 87111) s
-5 228 M
-( US) s
-5 206 M
-( Phone: +1 505 332 5700) s
-5 195 M
-( EMail: [email protected]) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 33]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 34 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( Tatu Ylonen) s
-5 679 M
-( SSH Communications Security Corp) s
-5 668 M
-( Fredrikinkatu 42) s
-5 657 M
-( HELSINKI FIN-00100) s
-5 646 M
-( Finland) s
-5 624 M
-( EMail: [email protected]) s
-5 591 M
-( Sami Lehtinen) s
-5 580 M
-( SSH Communications Security Corp) s
-5 569 M
-( Fredrikinkatu 42) s
-5 558 M
-( HELSINKI FIN-00100) s
-5 547 M
-( Finland) s
-5 525 M
-( EMail: [email protected]) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 34]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (34,35) 18
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 35 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(Full Copyright Statement) s
-5 668 M
-( Copyright \(C\) The Internet Society \(2002\). All Rights Reserved.) s
-5 646 M
-( This document and translations of it may be copied and furnished to) s
-5 635 M
-( others, and derivative works that comment on or otherwise explain it) s
-5 624 M
-( or assist in its implementation may be prepared, copied, published) s
-5 613 M
-( and distributed, in whole or in part, without restriction of any) s
-5 602 M
-( kind, provided that the above copyright notice and this paragraph are) s
-5 591 M
-( included on all such copies and derivative works. However, this) s
-5 580 M
-( document itself may not be modified in any way, such as by removing) s
-5 569 M
-( the copyright notice or references to the Internet Society or other) s
-5 558 M
-( Internet organizations, except as needed for the purpose of) s
-5 547 M
-( developing Internet standards in which case the procedures for) s
-5 536 M
-( copyrights defined in the Internet Standards process must be) s
-5 525 M
-( followed, or as required to translate it into languages other than) s
-5 514 M
-( English.) s
-5 492 M
-( The limited permissions granted above are perpetual and will not be) s
-5 481 M
-( revoked by the Internet Society or its successors or assigns.) s
-5 459 M
-( This document and the information contained herein is provided on an) s
-5 448 M
-( "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING) s
-5 437 M
-( TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING) s
-5 426 M
-( BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION) s
-5 415 M
-( HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF) s
-5 404 M
-( MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.) s
-5 382 M
-(Acknowledgement) s
-5 360 M
-( Funding for the RFC Editor function is currently provided by the) s
-5 349 M
-( Internet Society.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 35]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 36 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-_R
-S
-PStoPSsaved restore
-%%Trailer
-%%Pages: 36
-%%DocumentNeededResources: font Courier-Bold Courier
-%%EOF
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-03.txt b/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-03.txt
deleted file mode 100644
index 83960ae976..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-03.txt
+++ /dev/null
@@ -1,1962 +0,0 @@
-
-
-
-Secure Shell Working Group J. Galbraith
-Internet-Draft VanDyke Software
-Expires: April 16, 2003 T. Ylonen
- S. Lehtinen
- SSH Communications Security Corp
- October 16, 2002
-
-
- SSH File Transfer Protocol
- draft-ietf-secsh-filexfer-03.txt
-
-Status of this Memo
-
- This document is an Internet-Draft and is in full conformance with
- all provisions of Section 10 of RFC2026.
-
- Internet-Drafts are working documents of the Internet Engineering
- Task Force (IETF), its areas, and its working groups. Note that
- other groups may also distribute working documents as Internet-
- Drafts.
-
- Internet-Drafts are draft documents valid for a maximum of six months
- and may be updated, replaced, or obsoleted by other documents at any
- time. It is inappropriate to use Internet-Drafts as reference
- material or to cite them other than as "work in progress."
-
- The list of current Internet-Drafts can be accessed at http://
- www.ietf.org/ietf/1id-abstracts.txt.
-
- The list of Internet-Draft Shadow Directories can be accessed at
- http://www.ietf.org/shadow.html.
-
- This Internet-Draft will expire on April 16, 2003.
-
-Copyright Notice
-
- Copyright (C) The Internet Society (2002). All Rights Reserved.
-
-Abstract
-
- The SSH File Transfer Protocol provides secure file transfer
- functionality over any reliable data stream. It is the standard file
- transfer protocol for use with the SSH2 protocol. This document
- describes the file transfer protocol and its interface to the SSH2
- protocol suite.
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 1]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-Table of Contents
-
- 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . 3
- 2. Use with the SSH Connection Protocol . . . . . . . . . . . 4
- 3. General Packet Format . . . . . . . . . . . . . . . . . . 5
- 4. Protocol Initialization . . . . . . . . . . . . . . . . . 7
- 4.1 Client Initialization . . . . . . . . . . . . . . . . . . 7
- 4.2 Server Initialization . . . . . . . . . . . . . . . . . . 7
- 4.3 Determining Server Newline Convention . . . . . . . . . . 8
- 5. File Attributes . . . . . . . . . . . . . . . . . . . . . 9
- 5.1 Flags . . . . . . . . . . . . . . . . . . . . . . . . . . 9
- 5.2 Type . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
- 5.3 Size . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
- 5.4 Owner and Group . . . . . . . . . . . . . . . . . . . . . 10
- 5.5 Permissions . . . . . . . . . . . . . . . . . . . . . . . 11
- 5.6 Times . . . . . . . . . . . . . . . . . . . . . . . . . . 11
- 5.7 ACL . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
- 5.8 Extended attributes . . . . . . . . . . . . . . . . . . . 12
- 6. Requests From the Client to the Server . . . . . . . . . . 13
- 6.1 Request Synchronization and Reordering . . . . . . . . . . 13
- 6.2 File Names . . . . . . . . . . . . . . . . . . . . . . . . 14
- 6.3 Opening, Creating, and Closing Files . . . . . . . . . . . 14
- 6.4 Reading and Writing . . . . . . . . . . . . . . . . . . . 17
- 6.5 Removing and Renaming Files . . . . . . . . . . . . . . . 18
- 6.6 Creating and Deleting Directories . . . . . . . . . . . . 19
- 6.7 Scanning Directories . . . . . . . . . . . . . . . . . . . 19
- 6.8 Retrieving File Attributes . . . . . . . . . . . . . . . . 20
- 6.9 Setting File Attributes . . . . . . . . . . . . . . . . . 21
- 6.10 Dealing with Symbolic links . . . . . . . . . . . . . . . 22
- 6.11 Canonicalizing the Server-Side Path Name . . . . . . . . . 23
- 6.11.1 Best practice for dealing with paths . . . . . . . . . . . 23
- 7. Responses from the Server to the Client . . . . . . . . . 24
- 8. Vendor-Specific Extensions . . . . . . . . . . . . . . . . 28
- 9. Security Considerations . . . . . . . . . . . . . . . . . 29
- 10. Changes from previous protocol versions . . . . . . . . . 30
- 10.1 Changes between versions 4 and 3 . . . . . . . . . . . . . 30
- 10.2 Changes between versions 3 and 2 . . . . . . . . . . . . . 31
- 10.3 Changes between versions 2 and 1 . . . . . . . . . . . . . 31
- 10.4 Changes between versions 1 and 0 . . . . . . . . . . . . . 31
- 11. Trademark Issues . . . . . . . . . . . . . . . . . . . . . 32
- References . . . . . . . . . . . . . . . . . . . . . . . . 33
- Authors' Addresses . . . . . . . . . . . . . . . . . . . . 33
- Full Copyright Statement . . . . . . . . . . . . . . . . . 35
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 2]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-1. Introduction
-
- This protocol provides secure file transfer (and more generally file
- system access) functionality over a reliable data stream, such as a
- channel in the SSH2 protocol [5].
-
- This protocol is designed so that it could be used to implement a
- secure remote file system service, as well as a secure file transfer
- service.
-
- This protocol assumes that it runs over a secure channel, and that
- the server has already authenticated the user at the client end, and
- that the identity of the client user is externally available to the
- server implementation.
-
- In general, this protocol follows a simple request-response model.
- Each request and response contains a sequence number and multiple
- requests may be pending simultaneously. There are a relatively large
- number of different request messages, but a small number of possible
- response messages. Each request has one or more response messages
- that may be returned in result (e.g., a read either returns data or
- reports error status).
-
- The packet format descriptions in this specification follow the
- notation presented in the secsh architecture draft. [5]
-
- Even though this protocol is described in the context of the SSH2
- protocol, this protocol is general and independent of the rest of the
- SSH2 protocol suite. It could be used in a number of different
- applications, such as secure file transfer over TLS RFC 2246 [1] and
- transfer of management information in VPN applications.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 3]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-2. Use with the SSH Connection Protocol
-
- When used with the SSH2 Protocol suite, this protocol is intended to
- be used from the SSH Connection Protocol [7] as a subsystem, as
- described in section ``Starting a Shell or a Command''. The
- subsystem name used with this protocol is "sftp".
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 4]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-3. General Packet Format
-
- All packets transmitted over the secure connection are of the
- following format:
-
- uint32 length
- byte type
- byte[length - 1] data payload
-
- That is, they are just data preceded by 32-bit length and 8-bit type
- fields. The `length' is the length of the data area, and does not
- include the `length' field itself. The format and interpretation of
- the data area depends on the packet type.
-
- All packet descriptions below only specify the packet type and the
- data that goes into the data field. Thus, they should be prefixed by
- the `length' and `type' fields.
-
- The maximum size of a packet is in practice determined by the client
- (the maximum size of read or write requests that it sends, plus a few
- bytes of packet overhead). All servers SHOULD support packets of at
- least 34000 bytes (where the packet size refers to the full length,
- including the header above). This should allow for reads and writes
- of at most 32768 bytes.
-
- There is no limit on the number of outstanding (non-acknowledged)
- requests that the client may send to the server. In practice this is
- limited by the buffering available on the data stream and the queuing
- performed by the server. If the server's queues are full, it should
- not read any more data from the stream, and flow control will prevent
- the client from sending more requests. Note, however, that while
- there is no restriction on the protocol level, the client's API may
- provide a limit in order to prevent infinite queuing of outgoing
- requests at the client.
-
- The following values are defined for packet types.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 5]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- #define SSH_FXP_INIT 1
- #define SSH_FXP_VERSION 2
- #define SSH_FXP_OPEN 3
- #define SSH_FXP_CLOSE 4
- #define SSH_FXP_READ 5
- #define SSH_FXP_WRITE 6
- #define SSH_FXP_LSTAT 7
- #define SSH_FXP_FSTAT 8
- #define SSH_FXP_SETSTAT 9
- #define SSH_FXP_FSETSTAT 10
- #define SSH_FXP_OPENDIR 11
- #define SSH_FXP_READDIR 12
- #define SSH_FXP_REMOVE 13
- #define SSH_FXP_MKDIR 14
- #define SSH_FXP_RMDIR 15
- #define SSH_FXP_REALPATH 16
- #define SSH_FXP_STAT 17
- #define SSH_FXP_RENAME 18
- #define SSH_FXP_READLINK 19
- #define SSH_FXP_SYMLINK 20
-
- #define SSH_FXP_STATUS 101
- #define SSH_FXP_HANDLE 102
- #define SSH_FXP_DATA 103
- #define SSH_FXP_NAME 104
- #define SSH_FXP_ATTRS 105
-
- #define SSH_FXP_EXTENDED 200
- #define SSH_FXP_EXTENDED_REPLY 201
-
- RESERVED_FOR_EXTENSIONS 210-255
-
- Additional packet types should only be defined if the protocol
- version number (see Section ``Protocol Initialization'') is
- incremented, and their use MUST be negotiated using the version
- number. However, the SSH_FXP_EXTENDED and SSH_FXP_EXTENDED_REPLY
- packets can be used to implement vendor-specific extensions. See
- Section ``Vendor-Specific-Extensions'' for more details.
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 6]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-4. Protocol Initialization
-
- When the file transfer protocol starts, the client first sends a
- SSH_FXP_INIT (including its version number) packet to the server.
- The server responds with a SSH_FXP_VERSION packet, supplying the
- lowest of its own and the client's version number. Both parties
- should from then on adhere to particular version of the protocol.
-
- The version number of the protocol specified in this document is 4.
- The version number should be incremented for each incompatible
- revision of this protocol.
-
-4.1 Client Initialization
-
- The SSH_FXP_INIT packet (from client to server) has the following
- data:
-
- uint32 version
-
- Version 3 of this protocol allowed clients to include extensions in
- the SSH_FXP_INIT packet; however, this can cause interoperability
- problems with version 1 and version 2 servers because the client must
- send this packet before knowing the servers version.
-
- In this version of the protocol, clients MUST use the
- SSH_FXP_EXTENDED packet to send extensions to the server after
- version exchange has completed. Clients MUST NOT include extensions
- in the version packet. This will prevent interoperability problems
- with older servers
-
-4.2 Server Initialization
-
- The SSH_FXP_VERSION packet (from server to client) has the following
- data:
-
- uint32 version
- <extension data>
-
- 'version' is the lower of the protocol version supported by the
- server and the version number received from the client.
-
- The extension data may be empty, or may be a sequence of
-
- string extension_name
- string extension_data
-
- pairs (both strings MUST always be present if one is, but the
- `extension_data' string may be of zero length). If present, these
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 7]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- strings indicate extensions to the baseline protocol. The
- `extension_name' field(s) identify the name of the extension. The
- name should be of the form "name@domain", where the domain is the DNS
- domain name of the organization defining the extension. Additional
- names that are not of this format may be defined later by the IETF.
- Implementations MUST silently ignore any extensions whose name they
- do not recognize.
-
-4.3 Determining Server Newline Convention
-
- In order to correctly process text files in a cross platform
- compatible way, the newline convention must be converted from that of
- the server to that of the client, or, during an upload, from that of
- the client to that of the server.
-
- Versions 3 and prior of this protocol made no provisions for
- processing text files. Many clients implemented some sort of
- conversion algorithm, but without either a 'canonical' on the wire
- format or knowledge of the servers newline convention, correct
- conversion was not always possible.
-
- Starting with Version 4, the SSH_FXF_TEXT file open flag (Section
- 6.3) makes it possible to request that the server translate a file to
- a 'canonical' on the wire format. This format uses \r\n as the line
- separator.
-
- Servers for systems using multiple newline characters (for example,
- Mac OS X or VMS) or systems using counted records, MUST translate to
- the canonical form.
-
- However, to ease the burden of implementation on servers that use a
- single, simple separator sequence, the following extension allows the
- canonical format to be changed.
-
- string "newline"
- string new-canonical-separator (usually "\r" or "\n" or "\r\n")
-
- All clients MUST support this extension.
-
- When processing text files, clients SHOULD NOT translate any
- character or sequence that is not an exact match of the servers
- newline separator.
-
- In particular, if the newline sequence being used is the canonical
- "\r\n" sequence, a lone \r or a lone \n SHOULD be written through
- without change.
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 8]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-5. File Attributes
-
- A new compound data type is defined for encoding file attributes.
- The same encoding is used both when returning file attributes from
- the server and when sending file attributes to the server. When
- sending it to the server, the flags field specifies which attributes
- are included, and the server will use default values for the
- remaining attributes (or will not modify the values of remaining
- attributes). When receiving attributes from the server, the flags
- specify which attributes are included in the returned data. The
- server normally returns all attributes it knows about.
-
- uint32 flags
- byte type always present
- uint64 size present only if flag SSH_FILEXFER_ATTR_SIZE
- string owner present only if flag SSH_FILEXFER_ATTR_OWNERGROUP
- string group present only if flag SSH_FILEXFER_ATTR_OWNERGROUP
- uint32 permissions present only if flag SSH_FILEXFER_ATTR_PERMISSIONS
- uint32 atime present only if flag SSH_FILEXFER_ATTR_ACCESSTIME
- uint32 createtime present only if flag SSH_FILEXFER_ATTR_CREATETIME
- uint32 mtime present only if flag SSH_FILEXFER_ATTR_MODIFYTIME
- string acl present only if flag SSH_FILEXFER_ATTR_ACL
- uint32 extended_count present only if flag SSH_FILEXFER_ATTR_EXTENDED
- string extended_type
- string extended_data
- ... more extended data (extended_type - extended_data pairs),
- so that number of pairs equals extended_count
-
-
-5.1 Flags
-
- The `flags' specify which of the fields are present. Those fields
- for which the corresponding flag is not set are not present (not
- included in the packet). New flags can only be added by incrementing
- the protocol version number (or by using the extension mechanism
- described below).
-
- The flags bits are defined to have the following values:
-
- #define SSH_FILEXFER_ATTR_SIZE 0x00000001
- #define SSH_FILEXFER_ATTR_PERMISSIONS 0x00000004
- #define SSH_FILEXFER_ATTR_ACCESSTIME 0x00000008
- #define SSH_FILEXFER_ATTR_CREATETIME 0x00000010
- #define SSH_FILEXFER_ATTR_MODIFYTIME 0x00000020
- #define SSH_FILEXFER_ATTR_ACL 0x00000040
- #define SSH_FILEXFER_ATTR_OWNERGROUP 0x00000080
- #define SSH_FILEXFER_ATTR_EXTENDED 0x80000000
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 9]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- In previous versions of this protocol flags value 0x00000002 was
- SSH_FILEXFER_ATTR_UIDGID. This value is now unused, and OWNERGROUP
- was given a new value in order to ease implementation burden.
- 0x00000002 MUST NOT appear in the mask. Some future version of this
- protocol may reuse flag 0x00000002.
-
-5.2 Type
-
- The type field is always present. The following types are defined:
-
- #define SSH_FILEXFER_TYPE_REGULAR 1
- #define SSH_FILEXFER_TYPE_DIRECTORY 2
- #define SSH_FILEXFER_TYPE_SYMLINK 3
- #define SSH_FILEXFER_TYPE_SPECIAL 4
- #define SSH_FILEXFER_TYPE_UNKNOWN 5
-
- On a POSIX system, these values would be derived from the permission
- field.
-
-5.3 Size
-
- The `size' field specifies the size of the file on disk, in bytes.
- If it is present during file creation, it should be considered a hint
- as to the files eventual size.
-
- Files opened with the SSH_FXF_TEXT flag may have a size that is
- greater or less than the value of the size field.
-
-5.4 Owner and Group
-
- The `owner' and `group' fields are represented as UTF-8 strings; this
- is the form used by NFS v4. See NFS version 4 Protocol. [3] The
- following text is selected quotations from section 5.6.
-
- To avoid a representation that is tied to a particular underlying
- implementation at the client or server, the use of UTF-8 strings has
- been chosen. The string should be of the form user@dns_domain".
- This will allow for a client and server that do not use the same
- local representation the ability to translate to a common syntax that
- can be interpreted by both. In the case where there is no
- translation available to the client or server, the attribute value
- must be constructed without the "@". Therefore, the absence of the @
- from the owner or owner_group attribute signifies that no translation
- was available and the receiver of the attribute should not place any
- special meaning with the attribute value. Even though the attribute
- value can not be translated, it may still be useful. In the case of
- a client, the attribute string may be used for local display of
- ownership.
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 10]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-5.5 Permissions
-
- The `permissions' field contains a bit mask of file permissions as
- defined by POSIX [1].
-
-5.6 Times
-
- The 'atime', 'createtime', and 'mtime' contain the access, creation,
- and modification times of the files, respectively. They are
- represented as seconds from Jan 1, 1970 in UTC.
-
-5.7 ACL
-
- The 'ACL' field contains an ACL similar to that defined in section
- 5.9 of NFS version 4 Protocol [3].
-
- uint32 ace-count
-
- repeated ace-count time:
- uint32 ace-type
- uint32 ace-flag
- uint32 ace-mask
- string who [UTF-8]
-
- ace-type is one of the following four values (taken from NFS Version
- 4 Protocol [3]:
-
- const ACE4_ACCESS_ALLOWED_ACE_TYPE = 0x00000000;
- const ACE4_ACCESS_DENIED_ACE_TYPE = 0x00000001;
- const ACE4_SYSTEM_AUDIT_ACE_TYPE = 0x00000002;
- const ACE4_SYSTEM_ALARM_ACE_TYPE = 0x00000003;
-
- ace-flag is a combination of the following flag values. See NFS
- Version 4 Protocol [3] section 5.9.2:
-
- const ACE4_FILE_INHERIT_ACE = 0x00000001;
- const ACE4_DIRECTORY_INHERIT_ACE = 0x00000002;
- const ACE4_NO_PROPAGATE_INHERIT_ACE = 0x00000004;
- const ACE4_INHERIT_ONLY_ACE = 0x00000008;
- const ACE4_SUCCESSFUL_ACCESS_ACE_FLAG = 0x00000010;
- const ACE4_FAILED_ACCESS_ACE_FLAG = 0x00000020;
- const ACE4_IDENTIFIER_GROUP = 0x00000040;
-
- ace-mask is any combination of the following flags (taken from NFS
- Version 4 Protocol [3] section 5.9.3:
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 11]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- const ACE4_READ_DATA = 0x00000001;
- const ACE4_LIST_DIRECTORY = 0x00000001;
- const ACE4_WRITE_DATA = 0x00000002;
- const ACE4_ADD_FILE = 0x00000002;
- const ACE4_APPEND_DATA = 0x00000004;
- const ACE4_ADD_SUBDIRECTORY = 0x00000004;
- const ACE4_READ_NAMED_ATTRS = 0x00000008;
- const ACE4_WRITE_NAMED_ATTRS = 0x00000010;
- const ACE4_EXECUTE = 0x00000020;
- const ACE4_DELETE_CHILD = 0x00000040;
- const ACE4_READ_ATTRIBUTES = 0x00000080;
- const ACE4_WRITE_ATTRIBUTES = 0x00000100;
- const ACE4_DELETE = 0x00010000;
- const ACE4_READ_ACL = 0x00020000;
- const ACE4_WRITE_ACL = 0x00040000;
- const ACE4_WRITE_OWNER = 0x00080000;
- const ACE4_SYNCHRONIZE = 0x00100000;
-
- who is a UTF-8 string of the form described in 'Owner and Group'
- (Section 5.4)
-
-5.8 Extended attributes
-
- The SSH_FILEXFER_ATTR_EXTENDED flag provides a general extension
- mechanism for vendor-specific extensions. If the flag is specified,
- then the `extended_count' field is present. It specifies the number
- of extended_type-extended_data pairs that follow. Each of these
- pairs specifies an extended attribute. For each of the attributes,
- the extended_type field should be a string of the format
- "name@domain", where "domain" is a valid, registered domain name and
- "name" identifies the method. The IETF may later standardize certain
- names that deviate from this format (e.g., that do not contain the
- "@" sign). The interpretation of `extended_data' depends on the
- type. Implementations SHOULD ignore extended data fields that they
- do not understand.
-
- Additional fields can be added to the attributes by either defining
- additional bits to the flags field to indicate their presence, or by
- defining extended attributes for them. The extended attributes
- mechanism is recommended for most purposes; additional flags bits
- should only be defined by an IETF standards action that also
- increments the protocol version number. The use of such new fields
- MUST be negotiated by the version number in the protocol exchange.
- It is a protocol error if a packet with unsupported protocol bits is
- received.
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 12]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-6. Requests From the Client to the Server
-
- Requests from the client to the server represent the various file
- system operations. Each request begins with an `id' field, which is
- a 32-bit identifier identifying the request (selected by the client).
- The same identifier will be returned in the response to the request.
- One possible implementation is a monotonically increasing request
- sequence number (modulo 2^32).
-
- Many operations in the protocol operate on open files. The
- SSH_FXP_OPEN request can return a file handle (which is an opaque
- variable-length string) which may be used to access the file later
- (e.g. in a read operation). The client MUST NOT send requests the
- server with bogus or closed handles. However, the server MUST
- perform adequate checks on the handle in order to avoid security
- risks due to fabricated handles.
-
- This design allows either stateful and stateless server
- implementation, as well as an implementation which caches state
- between requests but may also flush it. The contents of the file
- handle string are entirely up to the server and its design. The
- client should not modify or attempt to interpret the file handle
- strings.
-
- The file handle strings MUST NOT be longer than 256 bytes.
-
-6.1 Request Synchronization and Reordering
-
- The protocol and implementations MUST process requests relating to
- the same file in the order in which they are received. In other
- words, if an application submits multiple requests to the server, the
- results in the responses will be the same as if it had sent the
- requests one at a time and waited for the response in each case. For
- example, the server may process non-overlapping read/write requests
- to the same file in parallel, but overlapping reads and writes cannot
- be reordered or parallelized. However, there are no ordering
- restrictions on the server for processing requests from two different
- file transfer connections. The server may interleave and parallelize
- them at will.
-
- There are no restrictions on the order in which responses to
- outstanding requests are delivered to the client, except that the
- server must ensure fairness in the sense that processing of no
- request will be indefinitely delayed even if the client is sending
- other requests so that there are multiple outstanding requests all
- the time.
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 13]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-6.2 File Names
-
- This protocol represents file names as strings. File names are
- assumed to use the slash ('/') character as a directory separator.
-
- File names starting with a slash are "absolute", and are relative to
- the root of the file system. Names starting with any other character
- are relative to the user's default directory (home directory). Note
- that identifying the user is assumed to take place outside of this
- protocol.
-
- Servers SHOULD interpret a path name component ".." as referring to
- the parent directory, and "." as referring to the current directory.
- If the server implementation limits access to certain parts of the
- file system, it must be extra careful in parsing file names when
- enforcing such restrictions. There have been numerous reported
- security bugs where a ".." in a path name has allowed access outside
- the intended area.
-
- An empty path name is valid, and it refers to the user's default
- directory (usually the user's home directory).
-
- Otherwise, no syntax is defined for file names by this specification.
- Clients should not make any other assumptions; however, they can
- splice path name components returned by SSH_FXP_READDIR together
- using a slash ('/') as the separator, and that will work as expected.
-
- In order to comply with IETF Policy on Character Sets and Languages
- [2], all filenames are to be encoded in UTF-8. The shortest valid
- UTF-8 encoding of the UNICODE data MUST be used. The server is
- responsible for converting the UNICODE data to whatever canonical
- form it requires.
-
- For example, if the server requires that precomposed characters
- always be used, the server MUST NOT assume the filename as sent by
- the client has this attribute, but must do this normalization itself.
-
- It is understood that the lack of well-defined semantics for file
- names may cause interoperability problems between clients and servers
- using radically different operating systems. However, this approach
- is known to work acceptably with most systems, and alternative
- approaches that e.g. treat file names as sequences of structured
- components are quite complicated.
-
-6.3 Opening, Creating, and Closing Files
-
- Files are opened and created using the SSH_FXP_OPEN message, whose
- data part is as follows:
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 14]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- uint32 id
- string filename [UTF-8]
- uint32 pflags
- ATTRS attrs
-
- The `id' field is the request identifier as for all requests.
-
- The `filename' field specifies the file name. See Section ``File
- Names'' for more information.
-
- The `pflags' field is a bitmask. The following bits have been
- defined.
-
- #define SSH_FXF_READ 0x00000001
- #define SSH_FXF_WRITE 0x00000002
- #define SSH_FXF_APPEND 0x00000004
- #define SSH_FXF_CREAT 0x00000008
- #define SSH_FXF_TRUNC 0x00000010
- #define SSH_FXF_EXCL 0x00000020
- #define SSH_FXF_TEXT 0x00000040
-
- These have the following meanings:
-
- SSH_FXF_READ
- Open the file for reading.
-
- SSH_FXF_WRITE
- Open the file for writing. If both this and SSH_FXF_READ are
- specified, the file is opened for both reading and writing.
-
- SSH_FXF_APPEND
- Force all writes to append data at the end of the file. The
- offset parameter to write will be ignored.
-
- SSH_FXF_CREAT
- If this flag is specified, then a new file will be created if one
- does not already exist (if O_TRUNC is specified, the new file will
- be truncated to zero length if it previously exists).
-
- SSH_FXF_TRUNC
- Forces an existing file with the same name to be truncated to zero
- length when creating a file by specifying SSH_FXF_CREAT.
- SSH_FXF_CREAT MUST also be specified if this flag is used.
-
- SSH_FXF_EXCL
- Causes the request to fail if the named file already exists.
- SSH_FXF_CREAT MUST also be specified if this flag is used.
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 15]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- SSH_FXF_TEXT
- Indicates that the server should treat the file as text and
- convert it to the canonical newline convention in use. (See
- Determining Server Newline Convention. (Section 4.3)
-
- When a file is opened with the FXF_TEXT flag, the offset field in
- both the read and write function are ignored.
-
- Servers MUST correctly process multiple parallel reads and writes
- correctly in this mode. Naturally, it is permissible for them to
- do this by serializing the requests. It would not be possible for
- a client to reliably detect a server that does not implement
- parallel writes in time to prevent damage.
-
- Clients SHOULD use the SSH_FXF_APPEND flag to append data to a
- text file rather then using write with a calculated offset.
-
- To support seeks on text file the following SSH_FXP_EXTENDED
- packet is defined.
-
-
-
- string "text-seek"
- string file-handle
- uint64 line-number
-
- line-number is the index of the line number to seek to, where byte
- 0 in the file is line number 0, and the byte directly following
- the first newline sequence in the file is line number 1 and so on.
-
- The response to a "text-seek" request is an SSH_FXP_STATUS
- message.
-
- An attempt to seek past the end-of-file should result in a
- SSH_FX_EOF status.
-
- Servers SHOULD support at least one "text-seek" in order to
- support resume. However, a client MUST be prepared to receive
- SSH_FX_OP_UNSUPPORTED when attempting a "text-seek" operation.
- The client can then try a fall-back strategy, if it has one.
-
- Clients MUST be prepared to handle SSH_FX_OP_UNSUPPORTED returned
- for read or write operations that are not sequential.
-
- The `attrs' field specifies the initial attributes for the file.
- Default values will be used for those attributes that are not
- specified. See Section ``File Attributes'' for more information.
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 16]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- The response to this message will be either SSH_FXP_HANDLE (if the
- operation is successful) or SSH_FXP_STATUS (if the operation fails).
-
- A file is closed by using the SSH_FXP_CLOSE request. Its data field
- has the following format:
-
- uint32 id
- string handle
-
- where `id' is the request identifier, and `handle' is a handle
- previously returned in the response to SSH_FXP_OPEN or
- SSH_FXP_OPENDIR. The handle becomes invalid immediately after this
- request has been sent.
-
- The response to this request will be a SSH_FXP_STATUS message. One
- should note that on some server platforms even a close can fail.
- This can happen e.g. if the server operating system caches writes,
- and an error occurs while flushing cached writes during the close.
-
-6.4 Reading and Writing
-
- Once a file has been opened, it can be read using the SSH_FXP_READ
- message, which has the following format:
-
- uint32 id
- string handle
- uint64 offset
- uint32 len
-
- where `id' is the request identifier, `handle' is an open file handle
- returned by SSH_FXP_OPEN, `offset' is the offset (in bytes) relative
- to the beginning of the file from where to start reading, and `len'
- is the maximum number of bytes to read.
-
- In response to this request, the server will read as many bytes as it
- can from the file (up to `len'), and return them in a SSH_FXP_DATA
- message. If an error occurs or EOF is encountered before reading any
- data, the server will respond with SSH_FXP_STATUS. For normal disk
- files, it is guaranteed that this will read the specified number of
- bytes, or up to end of file. For e.g. device files this may return
- fewer bytes than requested.
-
- Writing to a file is achieved using the SSH_FXP_WRITE message, which
- has the following format:
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 17]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- uint32 id
- string handle
- uint64 offset
- string data
-
- where `id' is a request identifier, `handle' is a file handle
- returned by SSH_FXP_OPEN, `offset' is the offset (in bytes) from the
- beginning of the file where to start writing, and `data' is the data
- to be written.
-
- The write will extend the file if writing beyond the end of the file.
- It is legal to write way beyond the end of the file; the semantics
- are to write zeroes from the end of the file to the specified offset
- and then the data. On most operating systems, such writes do not
- allocate disk space but instead leave "holes" in the file.
-
- The server responds to a write request with a SSH_FXP_STATUS message.
-
-6.5 Removing and Renaming Files
-
- Files can be removed using the SSH_FXP_REMOVE message. It has the
- following format:
-
- uint32 id
- string filename [UTF-8]
-
- where `id' is the request identifier and `filename' is the name of
- the file to be removed. See Section ``File Names'' for more
- information. This request cannot be used to remove directories.
-
- The server will respond to this request with a SSH_FXP_STATUS
- message.
-
- Files (and directories) can be renamed using the SSH_FXP_RENAME
- message. Its data is as follows:
-
- uint32 id
- string oldpath [UTF-8]
- string newpath [UTF-8]
-
- where `id' is the request identifier, `oldpath' is the name of an
- existing file or directory, and `newpath' is the new name for the
- file or directory. It is an error if there already exists a file
- with the name specified by newpath. The server may also fail rename
- requests in other situations, for example if `oldpath' and `newpath'
- point to different file systems on the server.
-
- The server will respond to this request with a SSH_FXP_STATUS
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 18]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- message.
-
-6.6 Creating and Deleting Directories
-
- New directories can be created using the SSH_FXP_MKDIR request. It
- has the following format:
-
- uint32 id
- string path [UTF-8]
- ATTRS attrs
-
- where `id' is the request identifier.
-
- `path' specifies the directory to be created. See Section ``File
- Names'' for more information on file names.
-
- `attrs' specifies the attributes that should be applied to it upon
- creation. Attributes are discussed in more detail in Section ``File
- Attributes''.
-
- The server will respond to this request with a SSH_FXP_STATUS
- message. If a file or directory with the specified path already
- exists, an error will be returned.
-
- Directories can be removed using the SSH_FXP_RMDIR request, which has
- the following format:
-
- uint32 id
- string path [UTF-8]
-
- where `id' is the request identifier, and `path' specifies the
- directory to be removed. See Section ``File Names'' for more
- information on file names.
-
- The server responds to this request with a SSH_FXP_STATUS message.
- Errors may be returned from this operation for various reasons,
- including, but not limited to, the path does not exist, the path does
- not refer to a directory object, the directory is not empty, or the
- user has insufficient access or permission to perform the requested
- operation.
-
-6.7 Scanning Directories
-
- The files in a directory can be listed using the SSH_FXP_OPENDIR and
- SSH_FXP_READDIR requests. Each SSH_FXP_READDIR request returns one
- or more file names with full file attributes for each file. The
- client should call SSH_FXP_READDIR repeatedly until it has found the
- file it is looking for or until the server responds with a
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 19]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- SSH_FXP_STATUS message indicating an error (normally SSH_FX_EOF if
- there are no more files in the directory). The client should then
- close the handle using the SSH_FXP_CLOSE request.
-
- The SSH_FXP_OPENDIR opens a directory for reading. It has the
- following format:
-
- uint32 id
- string path [UTF-8]
-
- where `id' is the request identifier and `path' is the path name of
- the directory to be listed (without any trailing slash). See Section
- ``File Names'' for more information on file names. This will return
- an error if the path does not specify a directory or if the directory
- is not readable. The server will respond to this request with either
- a SSH_FXP_HANDLE or a SSH_FXP_STATUS message.
-
- Once the directory has been successfully opened, files (and
- directories) contained in it can be listed using SSH_FXP_READDIR
- requests. These are of the format
-
- uint32 id
- string handle
-
- where `id' is the request identifier, and `handle' is a handle
- returned by SSH_FXP_OPENDIR. (It is a protocol error to attempt to
- use an ordinary file handle returned by SSH_FXP_OPEN.)
-
- The server responds to this request with either a SSH_FXP_NAME or a
- SSH_FXP_STATUS message. One or more names may be returned at a time.
- Full status information is returned for each name in order to speed
- up typical directory listings.
-
- If there are no more names available to be read, the server MUST
- respond with a SSH_FXP_STATUS message with error code of SSH_FX_EOF.
-
- When the client no longer wishes to read more names from the
- directory, it SHOULD call SSH_FXP_CLOSE for the handle. The handle
- should be closed regardless of whether an error has occurred or not.
-
-6.8 Retrieving File Attributes
-
- Very often, file attributes are automatically returned by
- SSH_FXP_READDIR. However, sometimes there is need to specifically
- retrieve the attributes for a named file. This can be done using the
- SSH_FXP_STAT, SSH_FXP_LSTAT and SSH_FXP_FSTAT requests.
-
- SSH_FXP_STAT and SSH_FXP_LSTAT only differ in that SSH_FXP_STAT
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 20]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- follows symbolic links on the server, whereas SSH_FXP_LSTAT does not
- follow symbolic links. Both have the same format:
-
- uint32 id
- string path [UTF-8]
- uint32 flags
-
- where `id' is the request identifier, and `path' specifies the file
- system object for which status is to be returned. The server
- responds to this request with either SSH_FXP_ATTRS or SSH_FXP_STATUS.
-
- The flags field specify the attribute flags in which the client has
- particular interest. This is a hint to the server. For example,
- because retrieving owner / group and acl information can be an
- expensive operation under some operating systems, the server may
- choose not to retrieve this information unless the client expresses a
- specific interest in it.
-
- The client has no guarantee the server will provide all the fields
- that it has expressed an interest in.
-
- SSH_FXP_FSTAT differs from the others in that it returns status
- information for an open file (identified by the file handle). Its
- format is as follows:
-
- uint32 id
- string handle
- uint32 flags
-
- where `id' is the request identifier and `handle' is a file handle
- returned by SSH_FXP_OPEN. The server responds to this request with
- SSH_FXP_ATTRS or SSH_FXP_STATUS.
-
-6.9 Setting File Attributes
-
- File attributes may be modified using the SSH_FXP_SETSTAT and
- SSH_FXP_FSETSTAT requests. These requests are used for operations
- such as changing the ownership, permissions or access times, as well
- as for truncating a file.
-
- The SSH_FXP_SETSTAT request is of the following format:
-
- uint32 id
- string path [UTF-8]
- ATTRS attrs
-
- where `id' is the request identifier, `path' specifies the file
- system object (e.g. file or directory) whose attributes are to be
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 21]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- modified, and `attrs' specifies the modifications to be made to its
- attributes. Attributes are discussed in more detail in Section
- ``File Attributes''.
-
- An error will be returned if the specified file system object does
- not exist or the user does not have sufficient rights to modify the
- specified attributes. The server responds to this request with a
- SSH_FXP_STATUS message.
-
- The SSH_FXP_FSETSTAT request modifies the attributes of a file which
- is already open. It has the following format:
-
- uint32 id
- string handle
- ATTRS attrs
-
- where `id' is the request identifier, `handle' (MUST be returned by
- SSH_FXP_OPEN) identifies the file whose attributes are to be
- modified, and `attrs' specifies the modifications to be made to its
- attributes. Attributes are discussed in more detail in Section
- ``File Attributes''. The server will respond to this request with
- SSH_FXP_STATUS.
-
-6.10 Dealing with Symbolic links
-
- The SSH_FXP_READLINK request may be used to read the target of a
- symbolic link. It would have a data part as follows:
-
- uint32 id
- string path [UTF-8]
-
- where `id' is the request identifier and `path' specifies the path
- name of the symlink to be read.
-
- The server will respond with a SSH_FXP_NAME packet containing only
- one name and a dummy attributes value. The name in the returned
- packet contains the target of the link. If an error occurs, the
- server may respond with SSH_FXP_STATUS.
-
- The SSH_FXP_SYMLINK request will create a symbolic link on the
- server. It is of the following format
-
- uint32 id
- string linkpath [UTF-8]
- string targetpath [UTF-8]
-
- where `id' is the request identifier, `linkpath' specifies the path
- name of the symlink to be created and `targetpath' specifies the
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 22]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- target of the symlink. The server shall respond with a
- SSH_FXP_STATUS indicating either success (SSH_FX_OK) or an error
- condition.
-
-6.11 Canonicalizing the Server-Side Path Name
-
- The SSH_FXP_REALPATH request can be used to have the server
- canonicalize any given path name to an absolute path. This is useful
- for converting path names containing ".." components or relative
- pathnames without a leading slash into absolute paths. The format of
- the request is as follows:
-
- uint32 id
- string path [UTF-8]
-
- where `id' is the request identifier and `path' specifies the path
- name to be canonicalized. The server will respond with a
- SSH_FXP_NAME packet containing the name in canonical form and a dummy
- attributes value. If an error occurs, the server may also respond
- with SSH_FXP_STATUS.
-
-6.11.1 Best practice for dealing with paths
-
- The client SHOULD treat the results of SSH_FXP_REALPATH as a
- canonical absolute path, even if the path does not appear to be
- absolute. A client that use REALPATH(".") and treats the result as
- absolute, even if there is no leading slash, will continue to
- function correctly, even when talking to a Windows NT or VMS style
- system, where absolute paths may not begin with a slash.
-
- For example, if the client wishes to change directory up, and the
- server has returned "c:/x/y/z" from REALPATH, the client SHOULD use
- "c:/x/y/z/..".
-
- As a second example, if the client wishes to open the file "x.txt" in
- the current directory, and server has returned "dka100:/x/y/z" as the
- canonical path of the directory, the client SHOULD open "dka100:/x/y/
- z/x.txt"
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 23]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-7. Responses from the Server to the Client
-
- The server responds to the client using one of a few response
- packets. All requests can return a SSH_FXP_STATUS response upon
- failure. When the operation is successful, any of the responses may
- be returned (depending on the operation). If no data needs to be
- returned to the client, the SSH_FXP_STATUS response with SSH_FX_OK
- status is appropriate. Otherwise, the SSH_FXP_HANDLE message is used
- to return a file handle (for SSH_FXP_OPEN and SSH_FXP_OPENDIR
- requests), SSH_FXP_DATA is used to return data from SSH_FXP_READ,
- SSH_FXP_NAME is used to return one or more file names from a
- SSH_FXP_READDIR or SSH_FXP_REALPATH request, and SSH_FXP_ATTRS is
- used to return file attributes from SSH_FXP_STAT, SSH_FXP_LSTAT, and
- SSH_FXP_FSTAT requests.
-
- Exactly one response will be returned for each request. Each
- response packet contains a request identifier which can be used to
- match each response with the corresponding request. Note that it is
- legal to have several requests outstanding simultaneously, and the
- server is allowed to send responses to them in a different order from
- the order in which the requests were sent (the result of their
- execution, however, is guaranteed to be as if they had been processed
- one at a time in the order in which the requests were sent).
-
- Response packets are of the same general format as request packets.
- Each response packet begins with the request identifier.
-
- The format of the data portion of the SSH_FXP_STATUS response is as
- follows:
-
- uint32 id
- uint32 error/status code
- string error message (ISO-10646 UTF-8 [RFC-2279])
- string language tag (as defined in [RFC-1766])
-
- where `id' is the request identifier, and `error/status code'
- indicates the result of the requested operation. The value SSH_FX_OK
- indicates success, and all other values indicate failure.
-
- Currently, the following values are defined (other values may be
- defined by future versions of this protocol):
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 24]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- #define SSH_FX_OK 0
- #define SSH_FX_EOF 1
- #define SSH_FX_NO_SUCH_FILE 2
- #define SSH_FX_PERMISSION_DENIED 3
- #define SSH_FX_FAILURE 4
- #define SSH_FX_BAD_MESSAGE 5
- #define SSH_FX_NO_CONNECTION 6
- #define SSH_FX_CONNECTION_LOST 7
- #define SSH_FX_OP_UNSUPPORTED 8
- #define SSH_FX_INVALID_HANDLE 9
- #define SSH_FX_NO_SUCH_PATH 10
- #define SSH_FX_FILE_ALREADY_EXISTS 11
- #define SSH_FX_WRITE_PROTECT 12
-
- SSH_FX_OK
- Indicates successful completion of the operation.
-
- SSH_FX_EOF
- indicates end-of-file condition; for SSH_FX_READ it means that no
- more data is available in the file, and for SSH_FX_READDIR it
- indicates that no more files are contained in the directory.
-
- SSH_FX_NO_SUCH_FILE
- is returned when a reference is made to a file which does not
- exist.
-
- SSH_FX_PERMISSION_DENIED
- is returned when the authenticated user does not have sufficient
- permissions to perform the operation.
-
- SSH_FX_FAILURE
- is a generic catch-all error message; it should be returned if an
- error occurs for which there is no more specific error code
- defined.
-
- SSH_FX_BAD_MESSAGE
- may be returned if a badly formatted packet or protocol
- incompatibility is detected.
-
- SSH_FX_NO_CONNECTION
- is a pseudo-error which indicates that the client has no
- connection to the server (it can only be generated locally by the
- client, and MUST NOT be returned by servers).
-
- SSH_FX_CONNECTION_LOST
- is a pseudo-error which indicates that the connection to the
- server has been lost (it can only be generated locally by the
- client, and MUST NOT be returned by servers).
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 25]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- SSH_FX_OP_UNSUPPORTED
- indicates that an attempt was made to perform an operation which
- is not supported for the server (it may be generated locally by
- the client if e.g. the version number exchange indicates that a
- required feature is not supported by the server, or it may be
- returned by the server if the server does not implement an
- operation).
-
- SSH_FX_INVALID_HANDLE
- The handle value was invalid.
-
- SSH_FX_NO_SUCH_PATH
- The file path does not exist or is invalid.
-
- SSH_FX_FILE_ALREADY_EXISTS
- The file already exists.
-
- SSH_FX_WRITE_PROTECT
- The file is on read only media, or the media is write protected.
-
- The SSH_FXP_HANDLE response has the following format:
-
- uint32 id
- string handle
-
- where `id' is the request identifier, and `handle' is an arbitrary
- string that identifies an open file or directory on the server. The
- handle is opaque to the client; the client MUST NOT attempt to
- interpret or modify it in any way. The length of the handle string
- MUST NOT exceed 256 data bytes.
-
- The SSH_FXP_DATA response has the following format:
-
- uint32 id
- string data
-
- where `id' is the request identifier, and `data' is an arbitrary byte
- string containing the requested data. The data string may be at most
- the number of bytes requested in a SSH_FXP_READ request, but may also
- be shorter if end of file is reached or if the read is from something
- other than a regular file.
-
- The SSH_FXP_NAME response has the following format:
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 26]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- uint32 id
- uint32 count
- repeats count times:
- string filename [UTF-8]
- ATTRS attrs
-
- where `id' is the request identifier, `count' is the number of names
- returned in this response, and the remaining fields repeat `count'
- times (so that all three fields are first included for the first
- file, then for the second file, etc). In the repeated part,
- `filename' is a file name being returned (for SSH_FXP_READDIR, it
- will be a relative name within the directory, without any path
- components; for SSH_FXP_REALPATH it will be an absolute path name),
- and `attrs' is the attributes of the file as described in Section
- ``File Attributes''.
-
- The SSH_FXP_ATTRS response has the following format:
-
- uint32 id
- ATTRS attrs
-
- where `id' is the request identifier, and `attrs' is the returned
- file attributes as described in Section ``File Attributes''.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 27]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-8. Vendor-Specific Extensions
-
- The SSH_FXP_EXTENDED request provides a generic extension mechanism
- for adding vendor-specific commands. The request has the following
- format:
-
- uint32 id
- string extended-request
- ... any request-specific data ...
-
- where `id' is the request identifier, and `extended-request' is a
- string of the format "name@domain", where domain is an internet
- domain name of the vendor defining the request. The rest of the
- request is completely vendor-specific, and servers should only
- attempt to interpret it if they recognize the `extended-request'
- name.
-
- The server may respond to such requests using any of the response
- packets defined in Section ``Responses from the Server to the
- Client''. Additionally, the server may also respond with a
- SSH_FXP_EXTENDED_REPLY packet, as defined below. If the server does
- not recognize the `extended-request' name, then the server MUST
- respond with SSH_FXP_STATUS with error/status set to
- SSH_FX_OP_UNSUPPORTED.
-
- The SSH_FXP_EXTENDED_REPLY packet can be used to carry arbitrary
- extension-specific data from the server to the client. It is of the
- following format:
-
- uint32 id
- ... any request-specific data ...
-
- There is a range of packet types reserved for use by extensions. In
- order to avoid collision, extensions that turn on the use of
- additional packet types should determine those numbers dynamically.
-
- The suggested way of doing this is have an extension request from the
- client to the server that enables the extension; the extension
- response from the server to the client would specify the actual type
- values to use, in additional to any other data.
-
- Extension authors should be mindful of the limited range of packet
- types available (there are only 45 values available) and avoid
- requiring a new packet type where possible.
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 28]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-9. Security Considerations
-
- This protocol assumes that it is run over a secure channel and that
- the endpoints of the channel have been authenticated. Thus, this
- protocol assumes that it is externally protected from network-level
- attacks.
-
- This protocol provides file system access to arbitrary files on the
- server (only constrained by the server implementation). It is the
- responsibility of the server implementation to enforce any access
- controls that may be required to limit the access allowed for any
- particular user (the user being authenticated externally to this
- protocol, typically using the SSH User Authentication Protocol [8].
-
- Care must be taken in the server implementation to check the validity
- of received file handle strings. The server should not rely on them
- directly; it MUST check the validity of each handle before relying on
- it.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 29]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-10. Changes from previous protocol versions
-
- The SSH File Transfer Protocol has changed over time, before it's
- standardization. The following is a description of the incompatible
- changes between different versions.
-
-10.1 Changes between versions 4 and 3
-
- Many of the changes between version 4 and version 3 are to the
- attribute structure to make it more flexible for non-unix platforms.
-
- o Make all filenames UTF-8.
-
- o Added 'newline' extension.
-
- o Made file attribute owner and group strings so they can actually
- be used on disparate systems.
-
- o Added createtime field, and added separate flags for atime,
- createtime, and mtime so they can be set separately.
-
- o Split the file type out of the permissions field and into it's own
- field (which is always present.)
-
- o Added acl attribute.
-
- o Added SSH_FXF_TEXT file open flag.
-
- o Added flags field to the get stat commands so that the client can
- specifically request information the server might not normally
- included for performance reasons.
-
- o Removed the long filename from the names structure-- it can now be
- built from information available in the attrs structure.
-
- o Added reserved range of packet numbers for extensions.
-
- o Added several additional error codes.
-
- o Change the way version negotiate works slightly. Previously, if
- the client version were higher than the server version, the server
- was supposed to 'echo back' the clients version. The server now
- sends it's own version and the lower of the two is considered to
- be the one in use.
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 30]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-10.2 Changes between versions 3 and 2
-
- o The SSH_FXP_READLINK and SSH_FXP_SYMLINK messages were added.
-
- o The SSH_FXP_EXTENDED and SSH_FXP_EXTENDED_REPLY messages were
- added.
-
- o The SSH_FXP_STATUS message was changed to include fields `error
- message' and `language tag'.
-
-
-10.3 Changes between versions 2 and 1
-
- o The SSH_FXP_RENAME message was added.
-
-
-10.4 Changes between versions 1 and 0
-
- o Implementation changes, no actual protocol changes.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 31]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-11. Trademark Issues
-
- "ssh" is a registered trademark of SSH Communications Security Corp
- in the United States and/or other countries.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 32]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-References
-
- [1] Dierks, T., Allen, C., Treese, W., Karlton, P., Freier, A. and
- P. Kocher, "The TLS Protocol Version 1.0", RFC 2246, January
- 1999.
-
- [2] Alvestrand, H., "IETF Policy on Character Sets and Languages",
- BCP 18, RFC 2277, January 1998.
-
- [3] Shepler, S., Callaghan, B., Robinson, D., Thurlow, R., Beame,
- C., Eisler, M. and D. Noveck, "NFS version 4 Protocol", RFC
- 3010, December 2000.
-
- [4] Institute of Electrical and Electronics Engineers, "Information
- Technology - Portable Operating System Interface (POSIX) - Part
- 1: System Application Program Interface (API) [C Language]",
- IEEE Standard 1003.2, 1996.
-
- [5] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.
- Lehtinen, "SSH Protocol Architecture", draft-ietf-secsh-
- architecture-13 (work in progress), September 2002.
-
- [6] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.
- Lehtinen, "SSH Protocol Transport Protocol", draft-ietf-secsh-
- transport-15 (work in progress), September 2002.
-
- [7] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.
- Lehtinen, "SSH Connection Protocol", draft-ietf-secsh-connect-16
- (work in progress), September 2002.
-
- [8] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.
- Lehtinen, "SSH Authentication Protocol", draft-ietf-secsh-
- userauth-16 (work in progress), September 2002.
-
-
-Authors' Addresses
-
- Joseph Galbraith
- VanDyke Software
- 4848 Tramway Ridge Blvd
- Suite 101
- Albuquerque, NM 87111
- US
-
- Phone: +1 505 332 5700
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 33]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- Tatu Ylonen
- SSH Communications Security Corp
- Fredrikinkatu 42
- HELSINKI FIN-00100
- Finland
-
-
-
- Sami Lehtinen
- SSH Communications Security Corp
- Fredrikinkatu 42
- HELSINKI FIN-00100
- Finland
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 34]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-Full Copyright Statement
-
- Copyright (C) The Internet Society (2002). All Rights Reserved.
-
- This document and translations of it may be copied and furnished to
- others, and derivative works that comment on or otherwise explain it
- or assist in its implementation may be prepared, copied, published
- and distributed, in whole or in part, without restriction of any
- kind, provided that the above copyright notice and this paragraph are
- included on all such copies and derivative works. However, this
- document itself may not be modified in any way, such as by removing
- the copyright notice or references to the Internet Society or other
- Internet organizations, except as needed for the purpose of
- developing Internet standards in which case the procedures for
- copyrights defined in the Internet Standards process must be
- followed, or as required to translate it into languages other than
- English.
-
- The limited permissions granted above are perpetual and will not be
- revoked by the Internet Society or its successors or assigns.
-
- This document and the information contained herein is provided on an
- "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
- TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
- BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
- HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
- MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-Acknowledgement
-
- Funding for the RFC Editor function is currently provided by the
- Internet Society.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 35]
-
-
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-04.txt b/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-04.txt
deleted file mode 100644
index 9f51883cd2..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-04.txt
+++ /dev/null
@@ -1,2130 +0,0 @@
-
-
-
-Secure Shell Working Group J. Galbraith
-Internet-Draft VanDyke Software
-Expires: June 18, 2003 T. Ylonen
- S. Lehtinen
- SSH Communications Security Corp
- December 18, 2002
-
-
- SSH File Transfer Protocol
- draft-ietf-secsh-filexfer-04.txt
-
-Status of this Memo
-
- This document is an Internet-Draft and is in full conformance with
- all provisions of Section 10 of RFC2026.
-
- Internet-Drafts are working documents of the Internet Engineering
- Task Force (IETF), its areas, and its working groups. Note that
- other groups may also distribute working documents as
- Internet-Drafts.
-
- Internet-Drafts are draft documents valid for a maximum of six months
- and may be updated, replaced, or obsoleted by other documents at any
- time. It is inappropriate to use Internet-Drafts as reference
- material or to cite them other than as "work in progress."
-
- The list of current Internet-Drafts can be accessed at http://
- www.ietf.org/ietf/1id-abstracts.txt.
-
- The list of Internet-Draft Shadow Directories can be accessed at
- http://www.ietf.org/shadow.html.
-
- This Internet-Draft will expire on June 18, 2003.
-
-Copyright Notice
-
- Copyright (C) The Internet Society (2002). All Rights Reserved.
-
-Abstract
-
- The SSH File Transfer Protocol provides secure file transfer
- functionality over any reliable data stream. It is the standard file
- transfer protocol for use with the SSH2 protocol. This document
- describes the file transfer protocol and its interface to the SSH2
- protocol suite.
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 1]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-Table of Contents
-
- 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . 3
- 2. Use with the SSH Connection Protocol . . . . . . . . . . . 4
- 3. General Packet Format . . . . . . . . . . . . . . . . . . 5
- 3.1 The use of stderr in the server . . . . . . . . . . . . . 6
- 4. Protocol Initialization . . . . . . . . . . . . . . . . . 8
- 4.1 Client Initialization . . . . . . . . . . . . . . . . . . 8
- 4.2 Server Initialization . . . . . . . . . . . . . . . . . . 8
- 4.3 Determining Server Newline Convention . . . . . . . . . . 9
- 5. File Attributes . . . . . . . . . . . . . . . . . . . . . 10
- 5.1 Flags . . . . . . . . . . . . . . . . . . . . . . . . . . 10
- 5.2 Type . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
- 5.3 Size . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
- 5.4 Owner and Group . . . . . . . . . . . . . . . . . . . . . 11
- 5.5 Permissions . . . . . . . . . . . . . . . . . . . . . . . 12
- 5.6 Times . . . . . . . . . . . . . . . . . . . . . . . . . . 12
- 5.7 ACL . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
- 5.8 Extended attributes . . . . . . . . . . . . . . . . . . . 14
- 6. Requests From the Client to the Server . . . . . . . . . . 15
- 6.1 Request Synchronization and Reordering . . . . . . . . . . 15
- 6.2 File Names . . . . . . . . . . . . . . . . . . . . . . . . 16
- 6.3 Opening, Creating, and Closing Files . . . . . . . . . . . 16
- 6.4 Reading and Writing . . . . . . . . . . . . . . . . . . . 19
- 6.5 Removing and Renaming Files . . . . . . . . . . . . . . . 20
- 6.6 Creating and Deleting Directories . . . . . . . . . . . . 21
- 6.7 Scanning Directories . . . . . . . . . . . . . . . . . . . 21
- 6.8 Retrieving File Attributes . . . . . . . . . . . . . . . . 22
- 6.9 Setting File Attributes . . . . . . . . . . . . . . . . . 23
- 6.10 Dealing with Symbolic links . . . . . . . . . . . . . . . 24
- 6.11 Canonicalizing the Server-Side Path Name . . . . . . . . . 25
- 6.11.1 Best practice for dealing with paths . . . . . . . . . . . 25
- 7. Responses from the Server to the Client . . . . . . . . . 26
- 8. Vendor-Specific Extensions . . . . . . . . . . . . . . . . 30
- 9. Security Considerations . . . . . . . . . . . . . . . . . 31
- 10. Changes from previous protocol versions . . . . . . . . . 32
- 10.1 Changes between versions 4 and 3 . . . . . . . . . . . . . 32
- 10.2 Changes between versions 3 and 2 . . . . . . . . . . . . . 33
- 10.3 Changes between versions 2 and 1 . . . . . . . . . . . . . 33
- 10.4 Changes between versions 1 and 0 . . . . . . . . . . . . . 33
- 11. Trademark Issues . . . . . . . . . . . . . . . . . . . . . 34
- References . . . . . . . . . . . . . . . . . . . . . . . . 35
- Authors' Addresses . . . . . . . . . . . . . . . . . . . . 35
- Intellectual Property and Copyright Statements . . . . . . 37
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 2]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-1. Introduction
-
- This protocol provides secure file transfer (and more generally file
- system access) functionality over a reliable data stream, such as a
- channel in the SSH2 protocol [5].
-
- This protocol is designed so that it could be used to implement a
- secure remote file system service, as well as a secure file transfer
- service.
-
- This protocol assumes that it runs over a secure channel, and that
- the server has already authenticated the user at the client end, and
- that the identity of the client user is externally available to the
- server implementation.
-
- In general, this protocol follows a simple request-response model.
- Each request and response contains a sequence number and multiple
- requests may be pending simultaneously. There are a relatively large
- number of different request messages, but a small number of possible
- response messages. Each request has one or more response messages
- that may be returned in result (e.g., a read either returns data or
- reports error status).
-
- The packet format descriptions in this specification follow the
- notation presented in the secsh architecture draft. [5]
-
- Even though this protocol is described in the context of the SSH2
- protocol, this protocol is general and independent of the rest of the
- SSH2 protocol suite. It could be used in a number of different
- applications, such as secure file transfer over TLS RFC 2246 [1] and
- transfer of management information in VPN applications.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 3]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-2. Use with the SSH Connection Protocol
-
- When used with the SSH2 Protocol suite, this protocol is intended to
- be used from the SSH Connection Protocol [7] as a subsystem, as
- described in section ``Starting a Shell or a Command''. The
- subsystem name used with this protocol is "sftp".
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 4]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-3. General Packet Format
-
- All packets transmitted over the secure connection are of the
- following format:
-
- uint32 length
- byte type
- byte[length - 1] data payload
-
- That is, they are just data preceded by 32-bit length and 8-bit type
- fields. The `length' is the length of the data area, and does not
- include the `length' field itself. The format and interpretation of
- the data area depends on the packet type.
-
- All packet descriptions below only specify the packet type and the
- data that goes into the data field. Thus, they should be prefixed by
- the `length' and `type' fields.
-
- The maximum size of a packet is in practice determined by the client
- (the maximum size of read or write requests that it sends, plus a few
- bytes of packet overhead). All servers SHOULD support packets of at
- least 34000 bytes (where the packet size refers to the full length,
- including the header above). This should allow for reads and writes
- of at most 32768 bytes.
-
- There is no limit on the number of outstanding (non-acknowledged)
- requests that the client may send to the server. In practice this is
- limited by the buffering available on the data stream and the queuing
- performed by the server. If the server's queues are full, it should
- not read any more data from the stream, and flow control will prevent
- the client from sending more requests. Note, however, that while
- there is no restriction on the protocol level, the client's API may
- provide a limit in order to prevent infinite queuing of outgoing
- requests at the client.
-
- The following values are defined for packet types.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 5]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- #define SSH_FXP_INIT 1
- #define SSH_FXP_VERSION 2
- #define SSH_FXP_OPEN 3
- #define SSH_FXP_CLOSE 4
- #define SSH_FXP_READ 5
- #define SSH_FXP_WRITE 6
- #define SSH_FXP_LSTAT 7
- #define SSH_FXP_FSTAT 8
- #define SSH_FXP_SETSTAT 9
- #define SSH_FXP_FSETSTAT 10
- #define SSH_FXP_OPENDIR 11
- #define SSH_FXP_READDIR 12
- #define SSH_FXP_REMOVE 13
- #define SSH_FXP_MKDIR 14
- #define SSH_FXP_RMDIR 15
- #define SSH_FXP_REALPATH 16
- #define SSH_FXP_STAT 17
- #define SSH_FXP_RENAME 18
- #define SSH_FXP_READLINK 19
- #define SSH_FXP_SYMLINK 20
-
- #define SSH_FXP_STATUS 101
- #define SSH_FXP_HANDLE 102
- #define SSH_FXP_DATA 103
- #define SSH_FXP_NAME 104
- #define SSH_FXP_ATTRS 105
-
- #define SSH_FXP_EXTENDED 200
- #define SSH_FXP_EXTENDED_REPLY 201
-
- RESERVED_FOR_EXTENSIONS 210-255
-
- Additional packet types should only be defined if the protocol
- version number (see Section ``Protocol Initialization'') is
- incremented, and their use MUST be negotiated using the version
- number. However, the SSH_FXP_EXTENDED and SSH_FXP_EXTENDED_REPLY
- packets can be used to implement vendor-specific extensions. See
- Section ``Vendor-Specific-Extensions'' for more details.
-
-3.1 The use of stderr in the server
-
- Packets are sent and received on stdout and stdin. Data sent on
- stderr by the server SHOULD be considered debug or supplemental error
- information, and MAY be displayed to the user.
-
- For example, during initialization, there is no client request
- active, so errors or warning information cannot be sent to the client
- as part of the SFTP protocol at this early stage. However, the
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 6]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- errors or warnings MAY be sent as stderr text.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 7]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-4. Protocol Initialization
-
- When the file transfer protocol starts, the client first sends a
- SSH_FXP_INIT (including its version number) packet to the server.
- The server responds with a SSH_FXP_VERSION packet, supplying the
- lowest of its own and the client's version number. Both parties
- should from then on adhere to particular version of the protocol.
-
- The version number of the protocol specified in this document is 4.
- The version number should be incremented for each incompatible
- revision of this protocol.
-
-4.1 Client Initialization
-
- The SSH_FXP_INIT packet (from client to server) has the following
- data:
-
- uint32 version
-
- Version 3 of this protocol allowed clients to include extensions in
- the SSH_FXP_INIT packet; however, this can cause interoperability
- problems with version 1 and version 2 servers because the client must
- send this packet before knowing the servers version.
-
- In this version of the protocol, clients MUST use the
- SSH_FXP_EXTENDED packet to send extensions to the server after
- version exchange has completed. Clients MUST NOT include extensions
- in the version packet. This will prevent interoperability problems
- with older servers
-
-4.2 Server Initialization
-
- The SSH_FXP_VERSION packet (from server to client) has the following
- data:
-
- uint32 version
- <extension data>
-
- 'version' is the lower of the protocol version supported by the
- server and the version number received from the client.
-
- The extension data may be empty, or may be a sequence of
-
- string extension_name
- string extension_data
-
- pairs (both strings MUST always be present if one is, but the
- `extension_data' string may be of zero length). If present, these
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 8]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- strings indicate extensions to the baseline protocol. The
- `extension_name' field(s) identify the name of the extension. The
- name should be of the form "name@domain", where the domain is the DNS
- domain name of the organization defining the extension. Additional
- names that are not of this format may be defined later by the IETF.
- Implementations MUST silently ignore any extensions whose name they
- do not recognize.
-
-4.3 Determining Server Newline Convention
-
- In order to correctly process text files in a cross platform
- compatible way, the newline convention must be converted from that of
- the server to that of the client, or, during an upload, from that of
- the client to that of the server.
-
- Versions 3 and prior of this protocol made no provisions for
- processing text files. Many clients implemented some sort of
- conversion algorithm, but without either a 'canonical' on the wire
- format or knowledge of the servers newline convention, correct
- conversion was not always possible.
-
- Starting with Version 4, the SSH_FXF_TEXT file open flag (Section
- 6.3) makes it possible to request that the server translate a file to
- a 'canonical' on the wire format. This format uses \r\n as the line
- separator.
-
- Servers for systems using multiple newline characters (for example,
- Mac OS X or VMS) or systems using counted records, MUST translate to
- the canonical form.
-
- However, to ease the burden of implementation on servers that use a
- single, simple separator sequence, the following extension allows the
- canonical format to be changed.
-
- string "newline"
- string new-canonical-separator (usually "\r" or "\n" or "\r\n")
-
- All clients MUST support this extension.
-
- When processing text files, clients SHOULD NOT translate any
- character or sequence that is not an exact match of the servers
- newline separator.
-
- In particular, if the newline sequence being used is the canonical
- "\r\n" sequence, a lone \r or a lone \n SHOULD be written through
- without change.
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 9]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-5. File Attributes
-
- A new compound data type is defined for encoding file attributes.
- The same encoding is used both when returning file attributes from
- the server and when sending file attributes to the server. When
- sending it to the server, the flags field specifies which attributes
- are included, and the server will use default values for the
- remaining attributes (or will not modify the values of remaining
- attributes). When receiving attributes from the server, the flags
- specify which attributes are included in the returned data. The
- server normally returns all attributes it knows about.
-
- uint32 flags
- byte type always present
- uint64 size present only if flag SIZE
- string owner present only if flag OWNERGROUP
- string group present only if flag OWNERGROUP
- uint32 permissions present only if flag PERMISSIONS
- uint64 atime present only if flag ACCESSTIME
- uint32 atime_nseconds present only if flag SUBSECOND_TIMES
- uint64 createtime present only if flag CREATETIME
- uint32 createtime_nseconds present only if flag SUBSECOND_TIMES
- uint64 mtime present only if flag MODIFYTIME
- uint32 mtime_nseconds present only if flag SUBSECOND_TIMES
- string acl present only if flag ACL
- uint32 extended_count present only if flag EXTENDED
- string extended_type
- string extended_data
- ... more extended data (extended_type - extended_data pairs),
- so that number of pairs equals extended_count
-
-
-5.1 Flags
-
- The `flags' specify which of the fields are present. Those fields
- for which the corresponding flag is not set are not present (not
- included in the packet). New flags can only be added by incrementing
- the protocol version number (or by using the extension mechanism
- described below).
-
- The flags bits are defined to have the following values:
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 10]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- #define SSH_FILEXFER_ATTR_SIZE 0x00000001
- #define SSH_FILEXFER_ATTR_PERMISSIONS 0x00000040
- #define SSH_FILEXFER_ATTR_ACCESSTIME 0x00000008
- #define SSH_FILEXFER_ATTR_CREATETIME 0x00000010
- #define SSH_FILEXFER_ATTR_MODIFYTIME 0x00000020
- #define SSH_FILEXFER_ATTR_ACL 0x00000040
- #define SSH_FILEXFER_ATTR_OWNERGROUP 0x00000080
- #define SSH_FILEXFER_ATTR_SUBSECOND_TIMES 0x00000100
- #define SSH_FILEXFER_ATTR_EXTENDED 0x80000000
-
- In previous versions of this protocol flags value 0x00000002 was
- SSH_FILEXFER_ATTR_UIDGID. This value is now unused, and OWNERGROUP
- was given a new value in order to ease implementation burden.
- 0x00000002 MUST NOT appear in the mask. Some future version of this
- protocol may reuse flag 0x00000002.
-
-5.2 Type
-
- The type field is always present. The following types are defined:
-
- #define SSH_FILEXFER_TYPE_REGULAR 1
- #define SSH_FILEXFER_TYPE_DIRECTORY 2
- #define SSH_FILEXFER_TYPE_SYMLINK 3
- #define SSH_FILEXFER_TYPE_SPECIAL 4
- #define SSH_FILEXFER_TYPE_UNKNOWN 5
-
- On a POSIX system, these values would be derived from the permission
- field.
-
-5.3 Size
-
- The `size' field specifies the size of the file on disk, in bytes.
- If it is present during file creation, it should be considered a hint
- as to the files eventual size.
-
- Files opened with the SSH_FXF_TEXT flag may have a size that is
- greater or less than the value of the size field.
-
-5.4 Owner and Group
-
- The `owner' and `group' fields are represented as UTF-8 strings; this
- is the form used by NFS v4. See NFS version 4 Protocol. [3] The
- following text is selected quotations from section 5.6.
-
- To avoid a representation that is tied to a particular underlying
- implementation at the client or server, the use of UTF-8 strings has
- been chosen. The string should be of the form user@dns_domain".
- This will allow for a client and server that do not use the same
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 11]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- local representation the ability to translate to a common syntax that
- can be interpreted by both. In the case where there is no
- translation available to the client or server, the attribute value
- must be constructed without the "@". Therefore, the absence of the @
- from the owner or owner_group attribute signifies that no translation
- was available and the receiver of the attribute should not place any
- special meaning with the attribute value. Even though the attribute
- value can not be translated, it may still be useful. In the case of
- a client, the attribute string may be used for local display of
- ownership.
-
-5.5 Permissions
-
- The `permissions' field contains a bit mask of file permissions as
- defined by POSIX [1].
-
-5.6 Times
-
- The 'atime', 'createtime', and 'mtime' contain the access, creation,
- and modification times of the files, respectively. They are
- represented as seconds from Jan 1, 1970 in UTC.
-
- A negative value indicates number of seconds before Jan 1, 1970. In
- both cases, if the SSH_FILEXFER_ATTR_SUBSECOND_TIMES flag is set, the
- nseconds field is to be added to the seconds field for the final time
- representation. For example, if the time to be represented is
- one-half second before 0 hour January 1, 1970, the seconds field
- would have a value of negative one (-1) and the nseconds fields would
- have a value of one-half second (500000000). Values greater than
- 999,999,999 for nseconds are considered invalid.
-
-5.7 ACL
-
- The 'ACL' field contains an ACL similar to that defined in section
- 5.9 of NFS version 4 Protocol [3].
-
- uint32 ace-count
-
- repeated ace-count time:
- uint32 ace-type
- uint32 ace-flag
- uint32 ace-mask
- string who [UTF-8]
-
- ace-type is one of the following four values (taken from NFS Version
- 4 Protocol [3]:
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 12]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- const ACE4_ACCESS_ALLOWED_ACE_TYPE = 0x00000000;
- const ACE4_ACCESS_DENIED_ACE_TYPE = 0x00000001;
- const ACE4_SYSTEM_AUDIT_ACE_TYPE = 0x00000002;
- const ACE4_SYSTEM_ALARM_ACE_TYPE = 0x00000003;
-
- ace-flag is a combination of the following flag values. See NFS
- Version 4 Protocol [3] section 5.9.2:
-
- const ACE4_FILE_INHERIT_ACE = 0x00000001;
- const ACE4_DIRECTORY_INHERIT_ACE = 0x00000002;
- const ACE4_NO_PROPAGATE_INHERIT_ACE = 0x00000004;
- const ACE4_INHERIT_ONLY_ACE = 0x00000008;
- const ACE4_SUCCESSFUL_ACCESS_ACE_FLAG = 0x00000010;
- const ACE4_FAILED_ACCESS_ACE_FLAG = 0x00000020;
- const ACE4_IDENTIFIER_GROUP = 0x00000040;
-
- ace-mask is any combination of the following flags (taken from NFS
- Version 4 Protocol [3] section 5.9.3:
-
- const ACE4_READ_DATA = 0x00000001;
- const ACE4_LIST_DIRECTORY = 0x00000001;
- const ACE4_WRITE_DATA = 0x00000002;
- const ACE4_ADD_FILE = 0x00000002;
- const ACE4_APPEND_DATA = 0x00000004;
- const ACE4_ADD_SUBDIRECTORY = 0x00000004;
- const ACE4_READ_NAMED_ATTRS = 0x00000008;
- const ACE4_WRITE_NAMED_ATTRS = 0x00000010;
- const ACE4_EXECUTE = 0x00000020;
- const ACE4_DELETE_CHILD = 0x00000040;
- const ACE4_READ_ATTRIBUTES = 0x00000080;
- const ACE4_WRITE_ATTRIBUTES = 0x00000100;
- const ACE4_DELETE = 0x00010000;
- const ACE4_READ_ACL = 0x00020000;
- const ACE4_WRITE_ACL = 0x00040000;
- const ACE4_WRITE_OWNER = 0x00080000;
- const ACE4_SYNCHRONIZE = 0x00100000;
-
- who is a UTF-8 string of the form described in 'Owner and Group'
- (Section 5.4)
-
- Also, as per '5.9.4 ACE who' [3] there are several identifiers that
- need to be understood universally. Some of these identifiers cannot
- be understood when an client access the server, but have meaning when
- a local process accesses the file. The ability to display and modify
- these permissions is permitted over SFTP.
-
- OWNER The owner of the file.
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 13]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- GROUP The group associated with the file.
-
- EVERYONE The world.
-
- INTERACTIVE Accessed from an interactive terminal.
-
- NETWORK Accessed via the network.
-
- DIALUP Accessed as a dialup user to the server.
-
- BATCH Accessed from a batch job.
-
- ANONYMOUS Accessed without any authentication.
-
- AUTHENTICATED Any authenticated user (opposite of ANONYMOUS).
-
- SERVICE Access from a system service.
-
- To avoid conflict, these special identifiers are distinguish by an
- appended "@" and should appear in the form "xxxx@" (note: no domain
- name after the "@"). For example: ANONYMOUS@.
-
-5.8 Extended attributes
-
- The SSH_FILEXFER_ATTR_EXTENDED flag provides a general extension
- mechanism for vendor-specific extensions. If the flag is specified,
- then the `extended_count' field is present. It specifies the number
- of extended_type-extended_data pairs that follow. Each of these
- pairs specifies an extended attribute. For each of the attributes,
- the extended_type field should be a string of the format
- "name@domain", where "domain" is a valid, registered domain name and
- "name" identifies the method. The IETF may later standardize certain
- names that deviate from this format (e.g., that do not contain the
- "@" sign). The interpretation of `extended_data' depends on the
- type. Implementations SHOULD ignore extended data fields that they
- do not understand.
-
- Additional fields can be added to the attributes by either defining
- additional bits to the flags field to indicate their presence, or by
- defining extended attributes for them. The extended attributes
- mechanism is recommended for most purposes; additional flags bits
- should only be defined by an IETF standards action that also
- increments the protocol version number. The use of such new fields
- MUST be negotiated by the version number in the protocol exchange.
- It is a protocol error if a packet with unsupported protocol bits is
- received.
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 14]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-6. Requests From the Client to the Server
-
- Requests from the client to the server represent the various file
- system operations. Each request begins with an `id' field, which is
- a 32-bit identifier identifying the request (selected by the client).
- The same identifier will be returned in the response to the request.
- One possible implementation is a monotonically increasing request
- sequence number (modulo 2^32).
-
- Many operations in the protocol operate on open files. The
- SSH_FXP_OPEN request can return a file handle (which is an opaque
- variable-length string) which may be used to access the file later
- (e.g. in a read operation). The client MUST NOT send requests the
- server with bogus or closed handles. However, the server MUST
- perform adequate checks on the handle in order to avoid security
- risks due to fabricated handles.
-
- This design allows either stateful and stateless server
- implementation, as well as an implementation which caches state
- between requests but may also flush it. The contents of the file
- handle string are entirely up to the server and its design. The
- client should not modify or attempt to interpret the file handle
- strings.
-
- The file handle strings MUST NOT be longer than 256 bytes.
-
-6.1 Request Synchronization and Reordering
-
- The protocol and implementations MUST process requests relating to
- the same file in the order in which they are received. In other
- words, if an application submits multiple requests to the server, the
- results in the responses will be the same as if it had sent the
- requests one at a time and waited for the response in each case. For
- example, the server may process non-overlapping read/write requests
- to the same file in parallel, but overlapping reads and writes cannot
- be reordered or parallelized. However, there are no ordering
- restrictions on the server for processing requests from two different
- file transfer connections. The server may interleave and parallelize
- them at will.
-
- There are no restrictions on the order in which responses to
- outstanding requests are delivered to the client, except that the
- server must ensure fairness in the sense that processing of no
- request will be indefinitely delayed even if the client is sending
- other requests so that there are multiple outstanding requests all
- the time.
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 15]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-6.2 File Names
-
- This protocol represents file names as strings. File names are
- assumed to use the slash ('/') character as a directory separator.
-
- File names starting with a slash are "absolute", and are relative to
- the root of the file system. Names starting with any other character
- are relative to the user's default directory (home directory). Note
- that identifying the user is assumed to take place outside of this
- protocol.
-
- Servers SHOULD interpret a path name component ".." as referring to
- the parent directory, and "." as referring to the current directory.
- If the server implementation limits access to certain parts of the
- file system, it must be extra careful in parsing file names when
- enforcing such restrictions. There have been numerous reported
- security bugs where a ".." in a path name has allowed access outside
- the intended area.
-
- An empty path name is valid, and it refers to the user's default
- directory (usually the user's home directory).
-
- Otherwise, no syntax is defined for file names by this specification.
- Clients should not make any other assumptions; however, they can
- splice path name components returned by SSH_FXP_READDIR together
- using a slash ('/') as the separator, and that will work as expected.
-
- In order to comply with IETF Policy on Character Sets and Languages
- [2], all filenames are to be encoded in UTF-8. The shortest valid
- UTF-8 encoding of the UNICODE data MUST be used. The server is
- responsible for converting the UNICODE data to whatever canonical
- form it requires.
-
- For example, if the server requires that precomposed characters
- always be used, the server MUST NOT assume the filename as sent by
- the client has this attribute, but must do this normalization itself.
-
- It is understood that the lack of well-defined semantics for file
- names may cause interoperability problems between clients and servers
- using radically different operating systems. However, this approach
- is known to work acceptably with most systems, and alternative
- approaches that e.g. treat file names as sequences of structured
- components are quite complicated.
-
-6.3 Opening, Creating, and Closing Files
-
- Files are opened and created using the SSH_FXP_OPEN message, whose
- data part is as follows:
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 16]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- uint32 id
- string filename [UTF-8]
- uint32 pflags
- ATTRS attrs
-
- The `id' field is the request identifier as for all requests.
-
- The `filename' field specifies the file name. See Section ``File
- Names'' for more information.
-
- The `pflags' field is a bitmask. The following bits have been
- defined.
-
- #define SSH_FXF_READ 0x00000001
- #define SSH_FXF_WRITE 0x00000002
- #define SSH_FXF_APPEND 0x00000004
- #define SSH_FXF_CREAT 0x00000008
- #define SSH_FXF_TRUNC 0x00000010
- #define SSH_FXF_EXCL 0x00000020
- #define SSH_FXF_TEXT 0x00000040
-
- These have the following meanings:
-
- SSH_FXF_READ
- Open the file for reading.
-
- SSH_FXF_WRITE
- Open the file for writing. If both this and SSH_FXF_READ are
- specified, the file is opened for both reading and writing.
-
- SSH_FXF_APPEND
- Force all writes to append data at the end of the file. The
- offset parameter to write will be ignored.
-
- SSH_FXF_CREAT
- If this flag is specified, then a new file will be created if one
- does not already exist (if O_TRUNC is specified, the new file will
- be truncated to zero length if it previously exists).
-
- SSH_FXF_TRUNC
- Forces an existing file with the same name to be truncated to zero
- length when creating a file by specifying SSH_FXF_CREAT.
- SSH_FXF_CREAT MUST also be specified if this flag is used.
-
- SSH_FXF_EXCL
- Causes the request to fail if the named file already exists.
- SSH_FXF_CREAT MUST also be specified if this flag is used.
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 17]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- SSH_FXF_TEXT
- Indicates that the server should treat the file as text and
- convert it to the canonical newline convention in use. (See
- Determining Server Newline Convention. (Section 4.3)
-
- When a file is opened with the FXF_TEXT flag, the offset field in
- both the read and write function are ignored.
-
- Servers MUST correctly process multiple parallel reads and writes
- correctly in this mode. Naturally, it is permissible for them to
- do this by serializing the requests. It would not be possible for
- a client to reliably detect a server that does not implement
- parallel writes in time to prevent damage.
-
- Clients SHOULD use the SSH_FXF_APPEND flag to append data to a
- text file rather then using write with a calculated offset.
-
- To support seeks on text file the following SSH_FXP_EXTENDED
- packet is defined.
-
-
-
- string "text-seek"
- string file-handle
- uint64 line-number
-
- line-number is the index of the line number to seek to, where byte
- 0 in the file is line number 0, and the byte directly following
- the first newline sequence in the file is line number 1 and so on.
-
- The response to a "text-seek" request is an SSH_FXP_STATUS
- message.
-
- An attempt to seek past the end-of-file should result in a
- SSH_FX_EOF status.
-
- Servers SHOULD support at least one "text-seek" in order to
- support resume. However, a client MUST be prepared to receive
- SSH_FX_OP_UNSUPPORTED when attempting a "text-seek" operation.
- The client can then try a fall-back strategy, if it has one.
-
- Clients MUST be prepared to handle SSH_FX_OP_UNSUPPORTED returned
- for read or write operations that are not sequential.
-
- The `attrs' field specifies the initial attributes for the file.
- Default values will be used for those attributes that are not
- specified. See Section ``File Attributes'' for more information.
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 18]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- The response to this message will be either SSH_FXP_HANDLE (if the
- operation is successful) or SSH_FXP_STATUS (if the operation fails).
-
- A file is closed by using the SSH_FXP_CLOSE request. Its data field
- has the following format:
-
- uint32 id
- string handle
-
- where `id' is the request identifier, and `handle' is a handle
- previously returned in the response to SSH_FXP_OPEN or
- SSH_FXP_OPENDIR. The handle becomes invalid immediately after this
- request has been sent.
-
- The response to this request will be a SSH_FXP_STATUS message. One
- should note that on some server platforms even a close can fail.
- This can happen e.g. if the server operating system caches writes,
- and an error occurs while flushing cached writes during the close.
-
-6.4 Reading and Writing
-
- Once a file has been opened, it can be read using the following
- message:
-
- byte SSH_FXP_READ
- uint32 id
- string handle
- uint64 offset
- uint32 len
-
- where `id' is the request identifier, `handle' is an open file handle
- returned by SSH_FXP_OPEN, `offset' is the offset (in bytes) relative
- to the beginning of the file from where to start reading, and `len'
- is the maximum number of bytes to read.
-
- In response to this request, the server will read as many bytes as it
- can from the file (up to `len'), and return them in a SSH_FXP_DATA
- message. If an error occurs or EOF is encountered before reading any
- data, the server will respond with SSH_FXP_STATUS.
-
- For normal disk files, it is normally guaranteed that this will read
- the specified number of bytes, or up to end of file. However, if the
- read length is very long, the server may truncate it if it doesn't
- support packets of that length. See General Packet Format (Section
- 3).
-
- For e.g. device files this may return fewer bytes than requested.
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 19]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- Writing to a file is achieved using the following message:
-
- byte SSH_FXP_WRITE
- uint32 id
- string handle
- uint64 offset
- string data
-
- where `id' is a request identifier, `handle' is a file handle
- returned by SSH_FXP_OPEN, `offset' is the offset (in bytes) from the
- beginning of the file where to start writing, and `data' is the data
- to be written.
-
- The write will extend the file if writing beyond the end of the file.
- It is legal to write way beyond the end of the file; the semantics
- are to write zeroes from the end of the file to the specified offset
- and then the data. On most operating systems, such writes do not
- allocate disk space but instead leave "holes" in the file.
-
- The server responds to a write request with a SSH_FXP_STATUS message.
-
-6.5 Removing and Renaming Files
-
- Files can be removed using the SSH_FXP_REMOVE message. It has the
- following format:
-
- uint32 id
- string filename [UTF-8]
-
- where `id' is the request identifier and `filename' is the name of
- the file to be removed. See Section ``File Names'' for more
- information. This request cannot be used to remove directories.
-
- The server will respond to this request with a SSH_FXP_STATUS
- message.
-
- Files (and directories) can be renamed using the SSH_FXP_RENAME
- message. Its data is as follows:
-
- uint32 id
- string oldpath [UTF-8]
- string newpath [UTF-8]
-
- where `id' is the request identifier, `oldpath' is the name of an
- existing file or directory, and `newpath' is the new name for the
- file or directory. It is an error if there already exists a file
- with the name specified by newpath. The server may also fail rename
- requests in other situations, for example if `oldpath' and `newpath'
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 20]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- point to different file systems on the server.
-
- The server will respond to this request with a SSH_FXP_STATUS
- message.
-
-6.6 Creating and Deleting Directories
-
- New directories can be created using the SSH_FXP_MKDIR request. It
- has the following format:
-
- uint32 id
- string path [UTF-8]
- ATTRS attrs
-
- where `id' is the request identifier.
-
- `path' specifies the directory to be created. See Section ``File
- Names'' for more information on file names.
-
- `attrs' specifies the attributes that should be applied to it upon
- creation. Attributes are discussed in more detail in Section ``File
- Attributes''.
-
- The server will respond to this request with a SSH_FXP_STATUS
- message. If a file or directory with the specified path already
- exists, an error will be returned.
-
- Directories can be removed using the SSH_FXP_RMDIR request, which has
- the following format:
-
- uint32 id
- string path [UTF-8]
-
- where `id' is the request identifier, and `path' specifies the
- directory to be removed. See Section ``File Names'' for more
- information on file names.
-
- The server responds to this request with a SSH_FXP_STATUS message.
- Errors may be returned from this operation for various reasons,
- including, but not limited to, the path does not exist, the path does
- not refer to a directory object, the directory is not empty, or the
- user has insufficient access or permission to perform the requested
- operation.
-
-6.7 Scanning Directories
-
- The files in a directory can be listed using the SSH_FXP_OPENDIR and
- SSH_FXP_READDIR requests. Each SSH_FXP_READDIR request returns one
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 21]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- or more file names with full file attributes for each file. The
- client should call SSH_FXP_READDIR repeatedly until it has found the
- file it is looking for or until the server responds with a
- SSH_FXP_STATUS message indicating an error (normally SSH_FX_EOF if
- there are no more files in the directory). The client should then
- close the handle using the SSH_FXP_CLOSE request.
-
- The SSH_FXP_OPENDIR opens a directory for reading. It has the
- following format:
-
- uint32 id
- string path [UTF-8]
-
- where `id' is the request identifier and `path' is the path name of
- the directory to be listed (without any trailing slash). See Section
- ``File Names'' for more information on file names. This will return
- an error if the path does not specify a directory or if the directory
- is not readable. The server will respond to this request with either
- a SSH_FXP_HANDLE or a SSH_FXP_STATUS message.
-
- Once the directory has been successfully opened, files (and
- directories) contained in it can be listed using SSH_FXP_READDIR
- requests. These are of the format
-
- uint32 id
- string handle
-
- where `id' is the request identifier, and `handle' is a handle
- returned by SSH_FXP_OPENDIR. (It is a protocol error to attempt to
- use an ordinary file handle returned by SSH_FXP_OPEN.)
-
- The server responds to this request with either a SSH_FXP_NAME or a
- SSH_FXP_STATUS message. One or more names may be returned at a time.
- Full status information is returned for each name in order to speed
- up typical directory listings.
-
- If there are no more names available to be read, the server MUST
- respond with a SSH_FXP_STATUS message with error code of SSH_FX_EOF.
-
- When the client no longer wishes to read more names from the
- directory, it SHOULD call SSH_FXP_CLOSE for the handle. The handle
- should be closed regardless of whether an error has occurred or not.
-
-6.8 Retrieving File Attributes
-
- Very often, file attributes are automatically returned by
- SSH_FXP_READDIR. However, sometimes there is need to specifically
- retrieve the attributes for a named file. This can be done using the
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 22]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- SSH_FXP_STAT, SSH_FXP_LSTAT and SSH_FXP_FSTAT requests.
-
- SSH_FXP_STAT and SSH_FXP_LSTAT only differ in that SSH_FXP_STAT
- follows symbolic links on the server, whereas SSH_FXP_LSTAT does not
- follow symbolic links. Both have the same format:
-
- uint32 id
- string path [UTF-8]
- uint32 flags
-
- where `id' is the request identifier, and `path' specifies the file
- system object for which status is to be returned. The server
- responds to this request with either SSH_FXP_ATTRS or SSH_FXP_STATUS.
-
- The flags field specify the attribute flags in which the client has
- particular interest. This is a hint to the server. For example,
- because retrieving owner / group and acl information can be an
- expensive operation under some operating systems, the server may
- choose not to retrieve this information unless the client expresses a
- specific interest in it.
-
- The client has no guarantee the server will provide all the fields
- that it has expressed an interest in.
-
- SSH_FXP_FSTAT differs from the others in that it returns status
- information for an open file (identified by the file handle). Its
- format is as follows:
-
- uint32 id
- string handle
- uint32 flags
-
- where `id' is the request identifier and `handle' is a file handle
- returned by SSH_FXP_OPEN. The server responds to this request with
- SSH_FXP_ATTRS or SSH_FXP_STATUS.
-
-6.9 Setting File Attributes
-
- File attributes may be modified using the SSH_FXP_SETSTAT and
- SSH_FXP_FSETSTAT requests. These requests are used for operations
- such as changing the ownership, permissions or access times, as well
- as for truncating a file.
-
- The SSH_FXP_SETSTAT request is of the following format:
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 23]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- uint32 id
- string path [UTF-8]
- ATTRS attrs
-
- where `id' is the request identifier, `path' specifies the file
- system object (e.g. file or directory) whose attributes are to be
- modified, and `attrs' specifies the modifications to be made to its
- attributes. Attributes are discussed in more detail in Section
- ``File Attributes''.
-
- An error will be returned if the specified file system object does
- not exist or the user does not have sufficient rights to modify the
- specified attributes. The server responds to this request with a
- SSH_FXP_STATUS message.
-
- The SSH_FXP_FSETSTAT request modifies the attributes of a file which
- is already open. It has the following format:
-
- uint32 id
- string handle
- ATTRS attrs
-
- where `id' is the request identifier, `handle' (MUST be returned by
- SSH_FXP_OPEN) identifies the file whose attributes are to be
- modified, and `attrs' specifies the modifications to be made to its
- attributes. Attributes are discussed in more detail in Section
- ``File Attributes''. The server will respond to this request with
- SSH_FXP_STATUS.
-
-6.10 Dealing with Symbolic links
-
- The SSH_FXP_READLINK request may be used to read the target of a
- symbolic link. It would have a data part as follows:
-
- uint32 id
- string path [UTF-8]
-
- where `id' is the request identifier and `path' specifies the path
- name of the symlink to be read.
-
- The server will respond with a SSH_FXP_NAME packet containing only
- one name and a dummy attributes value. The name in the returned
- packet contains the target of the link. If an error occurs, the
- server may respond with SSH_FXP_STATUS.
-
- The SSH_FXP_SYMLINK request will create a symbolic link on the
- server. It is of the following format
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 24]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- uint32 id
- string linkpath [UTF-8]
- string targetpath [UTF-8]
-
- where `id' is the request identifier, `linkpath' specifies the path
- name of the symlink to be created and `targetpath' specifies the
- target of the symlink. The server shall respond with a
- SSH_FXP_STATUS indicating either success (SSH_FX_OK) or an error
- condition.
-
-6.11 Canonicalizing the Server-Side Path Name
-
- The SSH_FXP_REALPATH request can be used to have the server
- canonicalize any given path name to an absolute path. This is useful
- for converting path names containing ".." components or relative
- pathnames without a leading slash into absolute paths. The format of
- the request is as follows:
-
- uint32 id
- string path [UTF-8]
-
- where `id' is the request identifier and `path' specifies the path
- name to be canonicalized. The server will respond with a
- SSH_FXP_NAME packet containing the name in canonical form and a dummy
- attributes value. If an error occurs, the server may also respond
- with SSH_FXP_STATUS.
-
-6.11.1 Best practice for dealing with paths
-
- The client SHOULD treat the results of SSH_FXP_REALPATH as a
- canonical absolute path, even if the path does not appear to be
- absolute. A client that use REALPATH(".") and treats the result as
- absolute, even if there is no leading slash, will continue to
- function correctly, even when talking to a Windows NT or VMS style
- system, where absolute paths may not begin with a slash.
-
- For example, if the client wishes to change directory up, and the
- server has returned "c:/x/y/z" from REALPATH, the client SHOULD use
- "c:/x/y/z/..".
-
- As a second example, if the client wishes to open the file "x.txt" in
- the current directory, and server has returned "dka100:/x/y/z" as the
- canonical path of the directory, the client SHOULD open "dka100:/x/y/
- z/x.txt"
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 25]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-7. Responses from the Server to the Client
-
- The server responds to the client using one of a few response
- packets. All requests can return a SSH_FXP_STATUS response upon
- failure. When the operation is successful, any of the responses may
- be returned (depending on the operation). If no data needs to be
- returned to the client, the SSH_FXP_STATUS response with SSH_FX_OK
- status is appropriate. Otherwise, the SSH_FXP_HANDLE message is used
- to return a file handle (for SSH_FXP_OPEN and SSH_FXP_OPENDIR
- requests), SSH_FXP_DATA is used to return data from SSH_FXP_READ,
- SSH_FXP_NAME is used to return one or more file names from a
- SSH_FXP_READDIR or SSH_FXP_REALPATH request, and SSH_FXP_ATTRS is
- used to return file attributes from SSH_FXP_STAT, SSH_FXP_LSTAT, and
- SSH_FXP_FSTAT requests.
-
- Exactly one response will be returned for each request. Each
- response packet contains a request identifier which can be used to
- match each response with the corresponding request. Note that it is
- legal to have several requests outstanding simultaneously, and the
- server is allowed to send responses to them in a different order from
- the order in which the requests were sent (the result of their
- execution, however, is guaranteed to be as if they had been processed
- one at a time in the order in which the requests were sent).
-
- Response packets are of the same general format as request packets.
- Each response packet begins with the request identifier.
-
- The format of the data portion of the SSH_FXP_STATUS response is as
- follows:
-
- uint32 id
- uint32 error/status code
- string error message (ISO-10646 UTF-8 [RFC-2279])
- string language tag (as defined in [RFC-1766])
-
- where `id' is the request identifier, and `error/status code'
- indicates the result of the requested operation. The value SSH_FX_OK
- indicates success, and all other values indicate failure.
-
- Currently, the following values are defined (other values may be
- defined by future versions of this protocol):
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 26]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- #define SSH_FX_OK 0
- #define SSH_FX_EOF 1
- #define SSH_FX_NO_SUCH_FILE 2
- #define SSH_FX_PERMISSION_DENIED 3
- #define SSH_FX_FAILURE 4
- #define SSH_FX_BAD_MESSAGE 5
- #define SSH_FX_NO_CONNECTION 6
- #define SSH_FX_CONNECTION_LOST 7
- #define SSH_FX_OP_UNSUPPORTED 8
- #define SSH_FX_INVALID_HANDLE 9
- #define SSH_FX_NO_SUCH_PATH 10
- #define SSH_FX_FILE_ALREADY_EXISTS 11
- #define SSH_FX_WRITE_PROTECT 12
- #define SSH_FX_NO_MEDIA 13
-
- SSH_FX_OK
- Indicates successful completion of the operation.
-
- SSH_FX_EOF
- indicates end-of-file condition; for SSH_FX_READ it means that no
- more data is available in the file, and for SSH_FX_READDIR it
- indicates that no more files are contained in the directory.
-
- SSH_FX_NO_SUCH_FILE
- is returned when a reference is made to a file which does not
- exist.
-
- SSH_FX_PERMISSION_DENIED
- is returned when the authenticated user does not have sufficient
- permissions to perform the operation.
-
- SSH_FX_FAILURE
- is a generic catch-all error message; it should be returned if an
- error occurs for which there is no more specific error code
- defined.
-
- SSH_FX_BAD_MESSAGE
- may be returned if a badly formatted packet or protocol
- incompatibility is detected.
-
- SSH_FX_NO_CONNECTION
- is a pseudo-error which indicates that the client has no
- connection to the server (it can only be generated locally by the
- client, and MUST NOT be returned by servers).
-
- SSH_FX_CONNECTION_LOST
- is a pseudo-error which indicates that the connection to the
- server has been lost (it can only be generated locally by the
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 27]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- client, and MUST NOT be returned by servers).
-
- SSH_FX_OP_UNSUPPORTED
- indicates that an attempt was made to perform an operation which
- is not supported for the server (it may be generated locally by
- the client if e.g. the version number exchange indicates that a
- required feature is not supported by the server, or it may be
- returned by the server if the server does not implement an
- operation).
-
- SSH_FX_INVALID_HANDLE
- The handle value was invalid.
-
- SSH_FX_NO_SUCH_PATH
- The file path does not exist or is invalid.
-
- SSH_FX_FILE_ALREADY_EXISTS
- The file already exists.
-
- SSH_FX_WRITE_PROTECT
- The file is on read only media, or the media is write protected.
-
- SSH_FX_NO_MEDIA
- The requested operation can not be completed because there is no
- media available in the drive.
-
- The SSH_FXP_HANDLE response has the following format:
-
- uint32 id
- string handle
-
- where `id' is the request identifier, and `handle' is an arbitrary
- string that identifies an open file or directory on the server. The
- handle is opaque to the client; the client MUST NOT attempt to
- interpret or modify it in any way. The length of the handle string
- MUST NOT exceed 256 data bytes.
-
- The SSH_FXP_DATA response has the following format:
-
- uint32 id
- string data
-
- where `id' is the request identifier, and `data' is an arbitrary byte
- string containing the requested data. The data string may be at most
- the number of bytes requested in a SSH_FXP_READ request, but may also
- be shorter if end of file is reached or if the read is from something
- other than a regular file.
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 28]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- The SSH_FXP_NAME response has the following format:
-
- uint32 id
- uint32 count
- repeats count times:
- string filename [UTF-8]
- ATTRS attrs
-
- where `id' is the request identifier, `count' is the number of names
- returned in this response, and the remaining fields repeat `count'
- times (so that all three fields are first included for the first
- file, then for the second file, etc). In the repeated part,
- `filename' is a file name being returned (for SSH_FXP_READDIR, it
- will be a relative name within the directory, without any path
- components; for SSH_FXP_REALPATH it will be an absolute path name),
- and `attrs' is the attributes of the file as described in Section
- ``File Attributes''.
-
- The SSH_FXP_ATTRS response has the following format:
-
- uint32 id
- ATTRS attrs
-
- where `id' is the request identifier, and `attrs' is the returned
- file attributes as described in Section ``File Attributes''.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 29]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-8. Vendor-Specific Extensions
-
- The SSH_FXP_EXTENDED request provides a generic extension mechanism
- for adding vendor-specific commands. The request has the following
- format:
-
- uint32 id
- string extended-request
- ... any request-specific data ...
-
- where `id' is the request identifier, and `extended-request' is a
- string of the format "name@domain", where domain is an internet
- domain name of the vendor defining the request. The rest of the
- request is completely vendor-specific, and servers should only
- attempt to interpret it if they recognize the `extended-request'
- name.
-
- The server may respond to such requests using any of the response
- packets defined in Section ``Responses from the Server to the
- Client''. Additionally, the server may also respond with a
- SSH_FXP_EXTENDED_REPLY packet, as defined below. If the server does
- not recognize the `extended-request' name, then the server MUST
- respond with SSH_FXP_STATUS with error/status set to
- SSH_FX_OP_UNSUPPORTED.
-
- The SSH_FXP_EXTENDED_REPLY packet can be used to carry arbitrary
- extension-specific data from the server to the client. It is of the
- following format:
-
- uint32 id
- ... any request-specific data ...
-
- There is a range of packet types reserved for use by extensions. In
- order to avoid collision, extensions that turn on the use of
- additional packet types should determine those numbers dynamically.
-
- The suggested way of doing this is have an extension request from the
- client to the server that enables the extension; the extension
- response from the server to the client would specify the actual type
- values to use, in additional to any other data.
-
- Extension authors should be mindful of the limited range of packet
- types available (there are only 45 values available) and avoid
- requiring a new packet type where possible.
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 30]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-9. Security Considerations
-
- This protocol assumes that it is run over a secure channel and that
- the endpoints of the channel have been authenticated. Thus, this
- protocol assumes that it is externally protected from network-level
- attacks.
-
- This protocol provides file system access to arbitrary files on the
- server (only constrained by the server implementation). It is the
- responsibility of the server implementation to enforce any access
- controls that may be required to limit the access allowed for any
- particular user (the user being authenticated externally to this
- protocol, typically using the SSH User Authentication Protocol [8].
-
- Care must be taken in the server implementation to check the validity
- of received file handle strings. The server should not rely on them
- directly; it MUST check the validity of each handle before relying on
- it.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 31]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-10. Changes from previous protocol versions
-
- The SSH File Transfer Protocol has changed over time, before it's
- standardization. The following is a description of the incompatible
- changes between different versions.
-
-10.1 Changes between versions 4 and 3
-
- Many of the changes between version 4 and version 3 are to the
- attribute structure to make it more flexible for non-unix platforms.
-
- o Clarify the use of stderr by the server.
-
- o Clarify handling of very large read requests by the server.
-
- o Make all filenames UTF-8.
-
- o Added 'newline' extension.
-
- o Made time fields 64 bit, and optionally have nanosecond resultion.
-
- o Made file attribute owner and group strings so they can actually
- be used on disparate systems.
-
- o Added createtime field, and added separate flags for atime,
- createtime, and mtime so they can be set separately.
-
- o Split the file type out of the permissions field and into it's own
- field (which is always present.)
-
- o Added acl attribute.
-
- o Added SSH_FXF_TEXT file open flag.
-
- o Added flags field to the get stat commands so that the client can
- specifically request information the server might not normally
- included for performance reasons.
-
- o Removed the long filename from the names structure-- it can now be
- built from information available in the attrs structure.
-
- o Added reserved range of packet numbers for extensions.
-
- o Added several additional error codes.
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 32]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-10.2 Changes between versions 3 and 2
-
- o The SSH_FXP_READLINK and SSH_FXP_SYMLINK messages were added.
-
- o The SSH_FXP_EXTENDED and SSH_FXP_EXTENDED_REPLY messages were
- added.
-
- o The SSH_FXP_STATUS message was changed to include fields `error
- message' and `language tag'.
-
-
-10.3 Changes between versions 2 and 1
-
- o The SSH_FXP_RENAME message was added.
-
-
-10.4 Changes between versions 1 and 0
-
- o Implementation changes, no actual protocol changes.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 33]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-11. Trademark Issues
-
- "ssh" is a registered trademark of SSH Communications Security Corp
- in the United States and/or other countries.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 34]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-References
-
- [1] Dierks, T., Allen, C., Treese, W., Karlton, P., Freier, A. and
- P. Kocher, "The TLS Protocol Version 1.0", RFC 2246, January
- 1999.
-
- [2] Alvestrand, H., "IETF Policy on Character Sets and Languages",
- BCP 18, RFC 2277, January 1998.
-
- [3] Shepler, S., Callaghan, B., Robinson, D., Thurlow, R., Beame,
- C., Eisler, M. and D. Noveck, "NFS version 4 Protocol", RFC
- 3010, December 2000.
-
- [4] Institute of Electrical and Electronics Engineers, "Information
- Technology - Portable Operating System Interface (POSIX) - Part
- 1: System Application Program Interface (API) [C Language]",
- IEEE Standard 1003.2, 1996.
-
- [5] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.
- Lehtinen, "SSH Protocol Architecture",
- draft-ietf-secsh-architecture-13 (work in progress), September
- 2002.
-
- [6] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.
- Lehtinen, "SSH Protocol Transport Protocol",
- draft-ietf-secsh-transport-15 (work in progress), September
- 2002.
-
- [7] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.
- Lehtinen, "SSH Connection Protocol", draft-ietf-secsh-connect-16
- (work in progress), September 2002.
-
- [8] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.
- Lehtinen, "SSH Authentication Protocol",
- draft-ietf-secsh-userauth-16 (work in progress), September 2002.
-
-
-Authors' Addresses
-
- Joseph Galbraith
- VanDyke Software
- 4848 Tramway Ridge Blvd
- Suite 101
- Albuquerque, NM 87111
- US
-
- Phone: +1 505 332 5700
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 35]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- Tatu Ylonen
- SSH Communications Security Corp
- Fredrikinkatu 42
- HELSINKI FIN-00100
- Finland
-
-
-
- Sami Lehtinen
- SSH Communications Security Corp
- Fredrikinkatu 42
- HELSINKI FIN-00100
- Finland
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 36]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-Intellectual Property Statement
-
- The IETF takes no position regarding the validity or scope of any
- intellectual property or other rights that might be claimed to
- pertain to the implementation or use of the technology described in
- this document or the extent to which any license under such rights
- might or might not be available; neither does it represent that it
- has made any effort to identify any such rights. Information on the
- IETF's procedures with respect to rights in standards-track and
- standards-related documentation can be found in BCP-11. Copies of
- claims of rights made available for publication and any assurances of
- licenses to be made available, or the result of an attempt made to
- obtain a general license or permission for the use of such
- proprietary rights by implementors or users of this specification can
- be obtained from the IETF Secretariat.
-
- The IETF invites any interested party to bring to its attention any
- copyrights, patents or patent applications, or other proprietary
- rights which may cover technology that may be required to practice
- this standard. Please address the information to the IETF Executive
- Director.
-
-
-Full Copyright Statement
-
- Copyright (C) The Internet Society (2002). All Rights Reserved.
-
- This document and translations of it may be copied and furnished to
- others, and derivative works that comment on or otherwise explain it
- or assist in its implementation may be prepared, copied, published
- and distributed, in whole or in part, without restriction of any
- kind, provided that the above copyright notice and this paragraph are
- included on all such copies and derivative works. However, this
- document itself may not be modified in any way, such as by removing
- the copyright notice or references to the Internet Society or other
- Internet organizations, except as needed for the purpose of
- developing Internet standards in which case the procedures for
- copyrights defined in the Internet Standards process must be
- followed, or as required to translate it into languages other than
- English.
-
- The limited permissions granted above are perpetual and will not be
- revoked by the Internet Society or its successors or assignees.
-
- This document and the information contained herein is provided on an
- "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
- TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
- BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 37]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
- MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-
-Acknowledgement
-
- Funding for the RFC Editor function is currently provided by the
- Internet Society.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 38]
-
-
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-transport-17.2.ps b/lib/ssh/doc/standard/draft-ietf-secsh-transport-17.2.ps
deleted file mode 100644
index d692285b4e..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-transport-17.2.ps
+++ /dev/null
@@ -1,3205 +0,0 @@
-%!PS-Adobe-3.0
-%%BoundingBox: 75 0 595 747
-%%Title: Enscript Output
-%%For: Magnus Thoang
-%%Creator: GNU enscript 1.6.1
-%%CreationDate: Fri Oct 31 13:35:14 2003
-%%Orientation: Portrait
-%%Pages: 15 0
-%%DocumentMedia: A4 595 842 0 () ()
-%%DocumentNeededResources: (atend)
-%%EndComments
-%%BeginProlog
-%%BeginProcSet: PStoPS 1 15
-userdict begin
-[/showpage/erasepage/copypage]{dup where{pop dup load
- type/operatortype eq{1 array cvx dup 0 3 index cvx put
- bind def}{pop}ifelse}{pop}ifelse}forall
-[/letter/legal/executivepage/a4/a4small/b5/com10envelope
- /monarchenvelope/c5envelope/dlenvelope/lettersmall/note
- /folio/quarto/a5]{dup where{dup wcheck{exch{}put}
- {pop{}def}ifelse}{pop}ifelse}forall
-/setpagedevice {pop}bind 1 index where{dup wcheck{3 1 roll put}
- {pop def}ifelse}{def}ifelse
-/PStoPSmatrix matrix currentmatrix def
-/PStoPSxform matrix def/PStoPSclip{clippath}def
-/defaultmatrix{PStoPSmatrix exch PStoPSxform exch concatmatrix}bind def
-/initmatrix{matrix defaultmatrix setmatrix}bind def
-/initclip[{matrix currentmatrix PStoPSmatrix setmatrix
- [{currentpoint}stopped{$error/newerror false put{newpath}}
- {/newpath cvx 3 1 roll/moveto cvx 4 array astore cvx}ifelse]
- {[/newpath cvx{/moveto cvx}{/lineto cvx}
- {/curveto cvx}{/closepath cvx}pathforall]cvx exch pop}
- stopped{$error/errorname get/invalidaccess eq{cleartomark
- $error/newerror false put cvx exec}{stop}ifelse}if}bind aload pop
- /initclip dup load dup type dup/operatortype eq{pop exch pop}
- {dup/arraytype eq exch/packedarraytype eq or
- {dup xcheck{exch pop aload pop}{pop cvx}ifelse}
- {pop cvx}ifelse}ifelse
- {newpath PStoPSclip clip newpath exec setmatrix} bind aload pop]cvx def
-/initgraphics{initmatrix newpath initclip 1 setlinewidth
- 0 setlinecap 0 setlinejoin []0 setdash 0 setgray
- 10 setmiterlimit}bind def
-end
-%%EndProcSet
-%%BeginResource: procset Enscript-Prolog 1.6 1
-%
-% Procedures.
-%
-
-/_S { % save current state
- /_s save def
-} def
-/_R { % restore from saved state
- _s restore
-} def
-
-/S { % showpage protecting gstate
- gsave
- showpage
- grestore
-} bind def
-
-/MF { % fontname newfontname -> - make a new encoded font
- /newfontname exch def
- /fontname exch def
-
- /fontdict fontname findfont def
- /newfont fontdict maxlength dict def
-
- fontdict {
- exch
- dup /FID eq {
- % skip FID pair
- pop pop
- } {
- % copy to the new font dictionary
- exch newfont 3 1 roll put
- } ifelse
- } forall
-
- newfont /FontName newfontname put
-
- % insert only valid encoding vectors
- encoding_vector length 256 eq {
- newfont /Encoding encoding_vector put
- } if
-
- newfontname newfont definefont pop
-} def
-
-/SF { % fontname width height -> - set a new font
- /height exch def
- /width exch def
-
- findfont
- [width 0 0 height 0 0] makefont setfont
-} def
-
-/SUF { % fontname width height -> - set a new user font
- /height exch def
- /width exch def
-
- /F-gs-user-font MF
- /F-gs-user-font width height SF
-} def
-
-/M {moveto} bind def
-/s {show} bind def
-
-/Box { % x y w h -> - define box path
- /d_h exch def /d_w exch def /d_y exch def /d_x exch def
- d_x d_y moveto
- d_w 0 rlineto
- 0 d_h rlineto
- d_w neg 0 rlineto
- closepath
-} def
-
-/bgs { % x y height blskip gray str -> - show string with bg color
- /str exch def
- /gray exch def
- /blskip exch def
- /height exch def
- /y exch def
- /x exch def
-
- gsave
- x y blskip sub str stringwidth pop height Box
- gray setgray
- fill
- grestore
- x y M str s
-} def
-
-% Highlight bars.
-/highlight_bars { % nlines lineheight output_y_margin gray -> -
- gsave
- setgray
- /ymarg exch def
- /lineheight exch def
- /nlines exch def
-
- % This 2 is just a magic number to sync highlight lines to text.
- 0 d_header_y ymarg sub 2 sub translate
-
- /cw d_output_w cols div def
- /nrows d_output_h ymarg 2 mul sub lineheight div cvi def
-
- % for each column
- 0 1 cols 1 sub {
- cw mul /xp exch def
-
- % for each rows
- 0 1 nrows 1 sub {
- /rn exch def
- rn lineheight mul neg /yp exch def
- rn nlines idiv 2 mod 0 eq {
- % Draw highlight bar. 4 is just a magic indentation.
- xp 4 add yp cw 8 sub lineheight neg Box fill
- } if
- } for
- } for
-
- grestore
-} def
-
-% Line highlight bar.
-/line_highlight { % x y width height gray -> -
- gsave
- /gray exch def
- Box gray setgray fill
- grestore
-} def
-
-% Column separator lines.
-/column_lines {
- gsave
- .1 setlinewidth
- 0 d_footer_h translate
- /cw d_output_w cols div def
- 1 1 cols 1 sub {
- cw mul 0 moveto
- 0 d_output_h rlineto stroke
- } for
- grestore
-} def
-
-% Column borders.
-/column_borders {
- gsave
- .1 setlinewidth
- 0 d_footer_h moveto
- 0 d_output_h rlineto
- d_output_w 0 rlineto
- 0 d_output_h neg rlineto
- closepath stroke
- grestore
-} def
-
-% Do the actual underlay drawing
-/draw_underlay {
- ul_style 0 eq {
- ul_str true charpath stroke
- } {
- ul_str show
- } ifelse
-} def
-
-% Underlay
-/underlay { % - -> -
- gsave
- 0 d_page_h translate
- d_page_h neg d_page_w atan rotate
-
- ul_gray setgray
- ul_font setfont
- /dw d_page_h dup mul d_page_w dup mul add sqrt def
- ul_str stringwidth pop dw exch sub 2 div ul_h_ptsize -2 div moveto
- draw_underlay
- grestore
-} def
-
-/user_underlay { % - -> -
- gsave
- ul_x ul_y translate
- ul_angle rotate
- ul_gray setgray
- ul_font setfont
- 0 0 ul_h_ptsize 2 div sub moveto
- draw_underlay
- grestore
-} def
-
-% Page prefeed
-/page_prefeed { % bool -> -
- statusdict /prefeed known {
- statusdict exch /prefeed exch put
- } {
- pop
- } ifelse
-} def
-
-% Wrapped line markers
-/wrapped_line_mark { % x y charwith charheight type -> -
- /type exch def
- /h exch def
- /w exch def
- /y exch def
- /x exch def
-
- type 2 eq {
- % Black boxes (like TeX does)
- gsave
- 0 setlinewidth
- x w 4 div add y M
- 0 h rlineto w 2 div 0 rlineto 0 h neg rlineto
- closepath fill
- grestore
- } {
- type 3 eq {
- % Small arrows
- gsave
- .2 setlinewidth
- x w 2 div add y h 2 div add M
- w 4 div 0 rlineto
- x w 4 div add y lineto stroke
-
- x w 4 div add w 8 div add y h 4 div add M
- x w 4 div add y lineto
- w 4 div h 8 div rlineto stroke
- grestore
- } {
- % do nothing
- } ifelse
- } ifelse
-} def
-
-% EPSF import.
-
-/BeginEPSF {
- /b4_Inc_state save def % Save state for cleanup
- /dict_count countdictstack def % Count objects on dict stack
- /op_count count 1 sub def % Count objects on operand stack
- userdict begin
- /showpage { } def
- 0 setgray 0 setlinecap
- 1 setlinewidth 0 setlinejoin
- 10 setmiterlimit [ ] 0 setdash newpath
- /languagelevel where {
- pop languagelevel
- 1 ne {
- false setstrokeadjust false setoverprint
- } if
- } if
-} bind def
-
-/EndEPSF {
- count op_count sub { pos } repeat % Clean up stacks
- countdictstack dict_count sub { end } repeat
- b4_Inc_state restore
-} bind def
-
-% Check PostScript language level.
-/languagelevel where {
- pop /gs_languagelevel languagelevel def
-} {
- /gs_languagelevel 1 def
-} ifelse
-%%EndResource
-%%BeginResource: procset Enscript-Encoding-88591 1.6 1
-/encoding_vector [
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/space /exclam /quotedbl /numbersign
-/dollar /percent /ampersand /quoteright
-/parenleft /parenright /asterisk /plus
-/comma /hyphen /period /slash
-/zero /one /two /three
-/four /five /six /seven
-/eight /nine /colon /semicolon
-/less /equal /greater /question
-/at /A /B /C
-/D /E /F /G
-/H /I /J /K
-/L /M /N /O
-/P /Q /R /S
-/T /U /V /W
-/X /Y /Z /bracketleft
-/backslash /bracketright /asciicircum /underscore
-/quoteleft /a /b /c
-/d /e /f /g
-/h /i /j /k
-/l /m /n /o
-/p /q /r /s
-/t /u /v /w
-/x /y /z /braceleft
-/bar /braceright /tilde /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/space /exclamdown /cent /sterling
-/currency /yen /brokenbar /section
-/dieresis /copyright /ordfeminine /guillemotleft
-/logicalnot /hyphen /registered /macron
-/degree /plusminus /twosuperior /threesuperior
-/acute /mu /paragraph /bullet
-/cedilla /onesuperior /ordmasculine /guillemotright
-/onequarter /onehalf /threequarters /questiondown
-/Agrave /Aacute /Acircumflex /Atilde
-/Adieresis /Aring /AE /Ccedilla
-/Egrave /Eacute /Ecircumflex /Edieresis
-/Igrave /Iacute /Icircumflex /Idieresis
-/Eth /Ntilde /Ograve /Oacute
-/Ocircumflex /Otilde /Odieresis /multiply
-/Oslash /Ugrave /Uacute /Ucircumflex
-/Udieresis /Yacute /Thorn /germandbls
-/agrave /aacute /acircumflex /atilde
-/adieresis /aring /ae /ccedilla
-/egrave /eacute /ecircumflex /edieresis
-/igrave /iacute /icircumflex /idieresis
-/eth /ntilde /ograve /oacute
-/ocircumflex /otilde /odieresis /divide
-/oslash /ugrave /uacute /ucircumflex
-/udieresis /yacute /thorn /ydieresis
-] def
-%%EndResource
-%%EndProlog
-%%BeginSetup
-%%IncludeResource: font Courier-Bold
-%%IncludeResource: font Courier
-/HFpt_w 10 def
-/HFpt_h 10 def
-/Courier-Bold /HF-gs-font MF
-/HF /HF-gs-font findfont [HFpt_w 0 0 HFpt_h 0 0] makefont def
-/Courier /F-gs-font MF
-/F-gs-font 10 10 SF
-/#copies 1 def
-/d_page_w 520 def
-/d_page_h 747 def
-/d_header_x 0 def
-/d_header_y 747 def
-/d_header_w 520 def
-/d_header_h 0 def
-/d_footer_x 0 def
-/d_footer_y 0 def
-/d_footer_w 520 def
-/d_footer_h 0 def
-/d_output_w 520 def
-/d_output_h 747 def
-/cols 1 def
-userdict/PStoPSxform PStoPSmatrix matrix currentmatrix
- matrix invertmatrix matrix concatmatrix
- matrix invertmatrix put
-%%EndSetup
-%%Page: (0,1) 1
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 1 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 701 M
-(Network Working Group T. Ylonen) s
-5 690 M
-(Internet-Draft SSH Communications Security Corp) s
-5 679 M
-(Expires: March 31, 2004 D. Moffat, Editor, Ed.) s
-5 668 M
-( Sun Microsystems, Inc) s
-5 657 M
-( Oct 2003) s
-5 624 M
-( SSH Transport Layer Protocol) s
-5 613 M
-( draft-ietf-secsh-transport-17.txt) s
-5 591 M
-(Status of this Memo) s
-5 569 M
-( This document is an Internet-Draft and is in full conformance with) s
-5 558 M
-( all provisions of Section 10 of RFC2026.) s
-5 536 M
-( Internet-Drafts are working documents of the Internet Engineering) s
-5 525 M
-( Task Force \(IETF\), its areas, and its working groups. Note that other) s
-5 514 M
-( groups may also distribute working documents as Internet-Drafts.) s
-5 492 M
-( Internet-Drafts are draft documents valid for a maximum of six months) s
-5 481 M
-( and may be updated, replaced, or obsoleted by other documents at any) s
-5 470 M
-( time. It is inappropriate to use Internet-Drafts as reference) s
-5 459 M
-( material or to cite them other than as "work in progress.") s
-5 437 M
-( The list of current Internet-Drafts can be accessed at http://) s
-5 426 M
-( www.ietf.org/ietf/1id-abstracts.txt.) s
-5 404 M
-( The list of Internet-Draft Shadow Directories can be accessed at) s
-5 393 M
-( http://www.ietf.org/shadow.html.) s
-5 371 M
-( This Internet-Draft will expire on March 31, 2004.) s
-5 349 M
-(Copyright Notice) s
-5 327 M
-( Copyright \(C\) The Internet Society \(2003\). All Rights Reserved.) s
-5 305 M
-(Abstract) s
-5 283 M
-( SSH is a protocol for secure remote login and other secure network) s
-5 272 M
-( services over an insecure network.) s
-5 250 M
-( This document describes the SSH transport layer protocol which) s
-5 239 M
-( typically runs on top of TCP/IP. The protocol can be used as a basis) s
-5 228 M
-( for a number of secure network services. It provides strong) s
-5 217 M
-( encryption, server authentication, and integrity protection. It may) s
-5 206 M
-( also provide compression.) s
-5 184 M
-( Key exchange method, public key algorithm, symmetric encryption) s
-5 173 M
-( algorithm, message authentication algorithm, and hash algorithm are) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 1]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 2 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( all negotiated.) s
-5 668 M
-( This document also describes the Diffie-Hellman key exchange method) s
-5 657 M
-( and the minimal set of algorithms that are needed to implement the) s
-5 646 M
-( SSH transport layer protocol.) s
-5 624 M
-(Table of Contents) s
-5 602 M
-( 1. Contributors . . . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 591 M
-( 2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 580 M
-( 3. Conventions Used in This Document . . . . . . . . . . . . . 3) s
-5 569 M
-( 4. Connection Setup . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 558 M
-( 4.1 Use over TCP/IP . . . . . . . . . . . . . . . . . . . . . . 4) s
-5 547 M
-( 4.2 Protocol Version Exchange . . . . . . . . . . . . . . . . . 4) s
-5 536 M
-( 4.3 Compatibility With Old SSH Versions . . . . . . . . . . . . 4) s
-5 525 M
-( 4.3.1 Old Client, New Server . . . . . . . . . . . . . . . . . . . 5) s
-5 514 M
-( 4.3.2 New Client, Old Server . . . . . . . . . . . . . . . . . . . 5) s
-5 503 M
-( 5. Binary Packet Protocol . . . . . . . . . . . . . . . . . . . 5) s
-5 492 M
-( 5.1 Maximum Packet Length . . . . . . . . . . . . . . . . . . . 6) s
-5 481 M
-( 5.2 Compression . . . . . . . . . . . . . . . . . . . . . . . . 7) s
-5 470 M
-( 5.3 Encryption . . . . . . . . . . . . . . . . . . . . . . . . . 7) s
-5 459 M
-( 5.4 Data Integrity . . . . . . . . . . . . . . . . . . . . . . . 9) s
-5 448 M
-( 5.5 Key Exchange Methods . . . . . . . . . . . . . . . . . . . . 10) s
-5 437 M
-( 5.6 Public Key Algorithms . . . . . . . . . . . . . . . . . . . 11) s
-5 426 M
-( 6. Key Exchange . . . . . . . . . . . . . . . . . . . . . . . . 13) s
-5 415 M
-( 6.1 Algorithm Negotiation . . . . . . . . . . . . . . . . . . . 13) s
-5 404 M
-( 6.2 Output from Key Exchange . . . . . . . . . . . . . . . . . . 16) s
-5 393 M
-( 6.3 Taking Keys Into Use . . . . . . . . . . . . . . . . . . . . 17) s
-5 382 M
-( 7. Diffie-Hellman Key Exchange . . . . . . . . . . . . . . . . 18) s
-5 371 M
-( 7.1 diffie-hellman-group1-sha1 . . . . . . . . . . . . . . . . . 19) s
-5 360 M
-( 8. Key Re-Exchange . . . . . . . . . . . . . . . . . . . . . . 20) s
-5 349 M
-( 9. Service Request . . . . . . . . . . . . . . . . . . . . . . 21) s
-5 338 M
-( 10. Additional Messages . . . . . . . . . . . . . . . . . . . . 21) s
-5 327 M
-( 10.1 Disconnection Message . . . . . . . . . . . . . . . . . . . 22) s
-5 316 M
-( 10.2 Ignored Data Message . . . . . . . . . . . . . . . . . . . . 22) s
-5 305 M
-( 10.3 Debug Message . . . . . . . . . . . . . . . . . . . . . . . 23) s
-5 294 M
-( 10.4 Reserved Messages . . . . . . . . . . . . . . . . . . . . . 23) s
-5 283 M
-( 11. Summary of Message Numbers . . . . . . . . . . . . . . . . . 23) s
-5 272 M
-( 12. IANA Considerations . . . . . . . . . . . . . . . . . . . . 24) s
-5 261 M
-( 13. Security Considerations . . . . . . . . . . . . . . . . . . 24) s
-5 250 M
-( 14. Intellectual Property . . . . . . . . . . . . . . . . . . . 24) s
-5 239 M
-( 15. Additional Information . . . . . . . . . . . . . . . . . . . 24) s
-5 228 M
-( Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 26) s
-5 217 M
-( Normative . . . . . . . . . . . . . . . . . . . . . . . . . 25) s
-5 206 M
-( Informative . . . . . . . . . . . . . . . . . . . . . . . . 25) s
-5 195 M
-( A. Contibutors . . . . . . . . . . . . . . . . . . . . . . . . 27) s
-5 184 M
-( Intellectual Property and Copyright Statements . . . . . . . 28) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 2]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (2,3) 2
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 3 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-(1. Contributors) s
-5 668 M
-( The major original contributors of this document were: Tatu Ylonen,) s
-5 657 M
-( Tero Kivinen, Timo J. Rinne, Sami Lehtinen \(all of SSH Communications) s
-5 646 M
-( Security Corp\), and Markku-Juhani O. Saarinen \(University of) s
-5 635 M
-( Jyvaskyla\)) s
-5 613 M
-( The document editor is: [email protected]. Comments on this) s
-5 602 M
-( internet draft should be sent to the IETF SECSH working group,) s
-5 591 M
-( details at: http://ietf.org/html.charters/secsh-charter.html) s
-5 569 M
-(2. Introduction) s
-5 547 M
-( The SSH transport layer is a secure low level transport protocol. It) s
-5 536 M
-( provides strong encryption, cryptographic host authentication, and) s
-5 525 M
-( integrity protection.) s
-5 503 M
-( Authentication in this protocol level is host-based; this protocol) s
-5 492 M
-( does not perform user authentication. A higher level protocol for) s
-5 481 M
-( user authentication can be designed on top of this protocol.) s
-5 459 M
-( The protocol has been designed to be simple, flexible, to allow) s
-5 448 M
-( parameter negotiation, and to minimize the number of round-trips.) s
-5 437 M
-( Key exchange method, public key algorithm, symmetric encryption) s
-5 426 M
-( algorithm, message authentication algorithm, and hash algorithm are) s
-5 415 M
-( all negotiated. It is expected that in most environments, only 2) s
-5 404 M
-( round-trips will be needed for full key exchange, server) s
-5 393 M
-( authentication, service request, and acceptance notification of) s
-5 382 M
-( service request. The worst case is 3 round-trips.) s
-5 360 M
-(3. Conventions Used in This Document) s
-5 338 M
-( The keywords "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT",) s
-5 327 M
-( and "MAY" that appear in this document are to be interpreted as) s
-5 316 M
-( described in [RFC2119].) s
-5 294 M
-( The used data types and terminology are specified in the architecture) s
-5 283 M
-( document [SSH-ARCH].) s
-5 261 M
-( The architecture document also discusses the algorithm naming) s
-5 250 M
-( conventions that MUST be used with the SSH protocols.) s
-5 228 M
-(4. Connection Setup) s
-5 206 M
-( SSH works over any 8-bit clean, binary-transparent transport. The) s
-5 195 M
-( underlying transport SHOULD protect against transmission errors as) s
-5 184 M
-( such errors cause the SSH connection to terminate.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 3]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 4 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( The client initiates the connection.) s
-5 668 M
-(4.1 Use over TCP/IP) s
-5 646 M
-( When used over TCP/IP, the server normally listens for connections on) s
-5 635 M
-( port 22. This port number has been registered with the IANA, and has) s
-5 624 M
-( been officially assigned for SSH.) s
-5 602 M
-(4.2 Protocol Version Exchange) s
-5 580 M
-( When the connection has been established, both sides MUST send an) s
-5 569 M
-( identification string of the form "SSH-protoversion-softwareversion) s
-5 558 M
-( comments", followed by carriage return and newline characters \(ASCII) s
-5 547 M
-( 13 and 10, respectively\). Both sides MUST be able to process) s
-5 536 M
-( identification strings without carriage return character. No null) s
-5 525 M
-( character is sent. The maximum length of the string is 255) s
-5 514 M
-( characters, including the carriage return and newline.) s
-5 492 M
-( The part of the identification string preceding carriage return and) s
-5 481 M
-( newline is used in the Diffie-Hellman key exchange \(see Section) s
-5 470 M
-( Section 7\).) s
-5 448 M
-( The server MAY send other lines of data before sending the version) s
-5 437 M
-( string. Each line SHOULD be terminated by a carriage return and) s
-5 426 M
-( newline. Such lines MUST NOT begin with "SSH-", and SHOULD be) s
-5 415 M
-( encoded in ISO-10646 UTF-8 [RFC2279] \(language is not specified\).) s
-5 404 M
-( Clients MUST be able to process such lines; they MAY be silently) s
-5 393 M
-( ignored, or MAY be displayed to the client user; if they are) s
-5 382 M
-( displayed, control character filtering discussed in [SSH-ARCH] SHOULD) s
-5 371 M
-( be used. The primary use of this feature is to allow TCP-wrappers to) s
-5 360 M
-( display an error message before disconnecting.) s
-5 338 M
-( Version strings MUST consist of printable US-ASCII characters, not) s
-5 327 M
-( including whitespaces or a minus sign \(-\). The version string is) s
-5 316 M
-( primarily used to trigger compatibility extensions and to indicate) s
-5 305 M
-( the capabilities of an implementation. The comment string should) s
-5 294 M
-( contain additional information that might be useful in solving user) s
-5 283 M
-( problems.) s
-5 261 M
-( The protocol version described in this document is 2.0.) s
-5 239 M
-( Key exchange will begin immediately after sending this identifier.) s
-5 228 M
-( All packets following the identification string SHALL use the binary) s
-5 217 M
-( packet protocol, to be described below.) s
-5 195 M
-(4.3 Compatibility With Old SSH Versions) s
-5 173 M
-( During the transition period, it is important to be able to work in a) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 4]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (4,5) 3
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 5 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( way that is compatible with the installed SSH clients and servers) s
-5 679 M
-( that use an older version of the protocol. Information in this) s
-5 668 M
-( section is only relevant for implementations supporting compatibility) s
-5 657 M
-( with SSH versions 1.x. There is no standards track or informational) s
-5 646 M
-( draft available that defines the SSH 1.x protocol. The only known) s
-5 635 M
-( documentation of the 1.x protocol is contained in README files that) s
-5 624 M
-( are shipped along with the source code.) s
-5 602 M
-(4.3.1 Old Client, New Server) s
-5 580 M
-( Server implementations MAY support a configurable "compatibility") s
-5 569 M
-( flag that enables compatibility with old versions. When this flag is) s
-5 558 M
-( on, the server SHOULD identify its protocol version as "1.99".) s
-5 547 M
-( Clients using protocol 2.0 MUST be able to identify this as identical) s
-5 536 M
-( to "2.0". In this mode the server SHOULD NOT send the carriage) s
-5 525 M
-( return character \(ASCII 13\) after the version identification string.) s
-5 503 M
-( In the compatibility mode the server SHOULD NOT send any further data) s
-5 492 M
-( after its initialization string until it has received an) s
-5 481 M
-( identification string from the client. The server can then determine) s
-5 470 M
-( whether the client is using an old protocol, and can revert to the) s
-5 459 M
-( old protocol if required. In the compatibility mode, the server MUST) s
-5 448 M
-( NOT send additional data before the version string.) s
-5 426 M
-( When compatibility with old clients is not needed, the server MAY) s
-5 415 M
-( send its initial key exchange data immediately after the) s
-5 404 M
-( identification string.) s
-5 382 M
-(4.3.2 New Client, Old Server) s
-5 360 M
-( Since the new client MAY immediately send additional data after its) s
-5 349 M
-( identification string \(before receiving server's identification\), the) s
-5 338 M
-( old protocol may already have been corrupted when the client learns) s
-5 327 M
-( that the server is old. When this happens, the client SHOULD close) s
-5 316 M
-( the connection to the server, and reconnect using the old protocol.) s
-5 294 M
-(5. Binary Packet Protocol) s
-5 272 M
-( Each packet is in the following format:) s
-5 250 M
-( uint32 packet_length) s
-5 239 M
-( byte padding_length) s
-5 228 M
-( byte[n1] payload; n1 = packet_length - padding_length - 1) s
-5 217 M
-( byte[n2] random padding; n2 = padding_length) s
-5 206 M
-( byte[m] mac \(message authentication code\); m = mac_length) s
-5 184 M
-( packet_length) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 5]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 6 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( The length of the packet \(bytes\), not including MAC or the) s
-5 679 M
-( packet_length field itself.) s
-5 657 M
-( padding_length) s
-5 646 M
-( Length of padding \(bytes\).) s
-5 624 M
-( payload) s
-5 613 M
-( The useful contents of the packet. If compression has been) s
-5 602 M
-( negotiated, this field is compressed. Initially, compression) s
-5 591 M
-( MUST be "none".) s
-5 569 M
-( random padding) s
-5 558 M
-( Arbitrary-length padding, such that the total length of) s
-5 547 M
-( \(packet_length || padding_length || payload || padding\) is a) s
-5 536 M
-( multiple of the cipher block size or 8, whichever is larger.) s
-5 525 M
-( There MUST be at least four bytes of padding. The padding) s
-5 514 M
-( SHOULD consist of random bytes. The maximum amount of padding) s
-5 503 M
-( is 255 bytes.) s
-5 481 M
-( mac) s
-5 470 M
-( Message authentication code. If message authentication has) s
-5 459 M
-( been negotiated, this field contains the MAC bytes. Initially,) s
-5 448 M
-( the MAC algorithm MUST be "none".) s
-5 415 M
-( Note that length of the concatenation of packet length, padding) s
-5 404 M
-( length, payload, and padding MUST be a multiple of the cipher block) s
-5 393 M
-( size or 8, whichever is larger. This constraint MUST be enforced) s
-5 382 M
-( even when using stream ciphers. Note that the packet length field is) s
-5 371 M
-( also encrypted, and processing it requires special care when sending) s
-5 360 M
-( or receiving packets.) s
-5 338 M
-( The minimum size of a packet is 16 \(or the cipher block size,) s
-5 327 M
-( whichever is larger\) bytes \(plus MAC\); implementations SHOULD decrypt) s
-5 316 M
-( the length after receiving the first 8 \(or cipher block size,) s
-5 305 M
-( whichever is larger\) bytes of a packet.) s
-5 283 M
-(5.1 Maximum Packet Length) s
-5 261 M
-( All implementations MUST be able to process packets with uncompressed) s
-5 250 M
-( payload length of 32768 bytes or less and total packet size of 35000) s
-5 239 M
-( bytes or less \(including length, padding length, payload, padding,) s
-5 228 M
-( and MAC.\). The maximum of 35000 bytes is an arbitrary chosen value) s
-5 217 M
-( larger than uncompressed size. Implementations SHOULD support longer) s
-5 206 M
-( packets, where they might be needed, e.g. if an implementation wants) s
-5 195 M
-( to send a very large number of certificates. Such packets MAY be) s
-5 184 M
-( sent if the version string indicates that the other party is able to) s
-5 173 M
-( process them. However, implementations SHOULD check that the packet) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 6]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (6,7) 4
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 7 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( length is reasonable for the implementation to avoid) s
-5 679 M
-( denial-of-service and/or buffer overflow attacks.) s
-5 657 M
-(5.2 Compression) s
-5 635 M
-( If compression has been negotiated, the payload field \(and only it\)) s
-5 624 M
-( will be compressed using the negotiated algorithm. The length field) s
-5 613 M
-( and MAC will be computed from the compressed payload. Encryption will) s
-5 602 M
-( be done after compression.) s
-5 580 M
-( Compression MAY be stateful, depending on the method. Compression) s
-5 569 M
-( MUST be independent for each direction, and implementations MUST) s
-5 558 M
-( allow independently choosing the algorithm for each direction.) s
-5 536 M
-( The following compression methods are currently defined:) s
-5 514 M
-( none REQUIRED no compression) s
-5 503 M
-( zlib OPTIONAL ZLIB \(LZ77\) compression) s
-5 481 M
-( The "zlib" compression is described in [RFC1950] and in [RFC1951].) s
-5 470 M
-( The compression context is initialized after each key exchange, and) s
-5 459 M
-( is passed from one packet to the next with only a partial flush being) s
-5 448 M
-( performed at the end of each packet. A partial flush means that the) s
-5 437 M
-( current compressed block is ended and all data will be output. If the) s
-5 426 M
-( current block is not a stored block, one or more empty blocks are) s
-5 415 M
-( added after the current block to ensure that there are at least 8) s
-5 404 M
-( bits counting from the start of the end-of-block code of the current) s
-5 393 M
-( block to the end of the packet payload.) s
-5 371 M
-( Additional methods may be defined as specified in [SSH-ARCH].) s
-5 349 M
-(5.3 Encryption) s
-5 327 M
-( An encryption algorithm and a key will be negotiated during the key) s
-5 316 M
-( exchange. When encryption is in effect, the packet length, padding) s
-5 305 M
-( length, payload and padding fields of each packet MUST be encrypted) s
-5 294 M
-( with the given algorithm.) s
-5 272 M
-( The encrypted data in all packets sent in one direction SHOULD be) s
-5 261 M
-( considered a single data stream. For example, initialization vectors) s
-5 250 M
-( SHOULD be passed from the end of one packet to the beginning of the) s
-5 239 M
-( next packet. All ciphers SHOULD use keys with an effective key length) s
-5 228 M
-( of 128 bits or more.) s
-5 206 M
-( The ciphers in each direction MUST run independently of each other,) s
-5 195 M
-( and implementations MUST allow independently choosing the algorithm) s
-5 184 M
-( for each direction \(if multiple algorithms are allowed by local) s
-5 173 M
-( policy\).) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 7]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 8 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( The following ciphers are currently defined:) s
-5 668 M
-( 3des-cbc REQUIRED three-key 3DES in CBC mode) s
-5 657 M
-( blowfish-cbc OPTIONALi Blowfish in CBC mode) s
-5 646 M
-( twofish256-cbc OPTIONAL Twofish in CBC mode,) s
-5 635 M
-( with 256-bit key) s
-5 624 M
-( twofish-cbc OPTIONAL alias for "twofish256-cbc" \(this) s
-5 613 M
-( is being retained for) s
-5 602 M
-( historical reasons\)) s
-5 591 M
-( twofish192-cbc OPTIONAL Twofish with 192-bit key) s
-5 580 M
-( twofish128-cbc OPTIONAL Twofish with 128-bit key) s
-5 569 M
-( aes256-cbc OPTIONAL AES \(Rijndael\) in CBC mode,) s
-5 558 M
-( with 256-bit key) s
-5 547 M
-( aes192-cbc OPTIONAL AES with 192-bit key) s
-5 536 M
-( aes128-cbc RECOMMENDED AES with 128-bit key) s
-5 525 M
-( serpent256-cbc OPTIONAL Serpent in CBC mode, with) s
-5 514 M
-( 256-bit key) s
-5 503 M
-( serpent192-cbc OPTIONAL Serpent with 192-bit key) s
-5 492 M
-( serpent128-cbc OPTIONAL Serpent with 128-bit key) s
-5 481 M
-( arcfour OPTIONAL the ARCFOUR stream cipher) s
-5 470 M
-( idea-cbc OPTIONAL IDEA in CBC mode) s
-5 459 M
-( cast128-cbc OPTIONAL CAST-128 in CBC mode) s
-5 448 M
-( none OPTIONAL no encryption; NOT RECOMMENDED) s
-5 426 M
-( The "3des-cbc" cipher is three-key triple-DES) s
-5 415 M
-( \(encrypt-decrypt-encrypt\), where the first 8 bytes of the key are) s
-5 404 M
-( used for the first encryption, the next 8 bytes for the decryption,) s
-5 393 M
-( and the following 8 bytes for the final encryption. This requires 24) s
-5 382 M
-( bytes of key data \(of which 168 bits are actually used\). To) s
-5 371 M
-( implement CBC mode, outer chaining MUST be used \(i.e., there is only) s
-5 360 M
-( one initialization vector\). This is a block cipher with 8 byte) s
-5 349 M
-( blocks. This algorithm is defined in [FIPS-46-3]) s
-5 327 M
-( The "blowfish-cbc" cipher is Blowfish in CBC mode, with 128 bit keys) s
-5 316 M
-( [SCHNEIER]. This is a block cipher with 8 byte blocks.) s
-5 294 M
-( The "twofish-cbc" or "twofish256-cbc" cipher is Twofish in CBC mode,) s
-5 283 M
-( with 256 bit keys as described [TWOFISH]. This is a block cipher with) s
-5 272 M
-( 16 byte blocks.) s
-5 250 M
-( The "twofish192-cbc" cipher. Same as above but with 192-bit key.) s
-5 228 M
-( The "twofish128-cbc" cipher. Same as above but with 128-bit key.) s
-5 206 M
-( The "aes256-cbc" cipher is AES \(Advanced Encryption Standard\)) s
-5 195 M
-( [FIPS-197], formerly Rijndael, in CBC mode. This version uses 256-bit) s
-5 184 M
-( key.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 8]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (8,9) 5
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 9 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( The "aes192-cbc" cipher. Same as above but with 192-bit key.) s
-5 668 M
-( The "aes128-cbc" cipher. Same as above but with 128-bit key.) s
-5 646 M
-( The "serpent256-cbc" cipher in CBC mode, with 256-bit key as) s
-5 635 M
-( described in the Serpent AES submission.) s
-5 613 M
-( The "serpent192-cbc" cipher. Same as above but with 192-bit key.) s
-5 591 M
-( The "serpent128-cbc" cipher. Same as above but with 128-bit key.) s
-5 569 M
-( The "arcfour" is the Arcfour stream cipher with 128 bit keys. The) s
-5 558 M
-( Arcfour cipher is believed to be compatible with the RC4 cipher) s
-5 547 M
-( [SCHNEIER]. RC4 is a registered trademark of RSA Data Security Inc.) s
-5 536 M
-( Arcfour \(and RC4\) has problems with weak keys, and should be used) s
-5 525 M
-( with caution.) s
-5 503 M
-( The "idea-cbc" cipher is the IDEA cipher in CBC mode [SCHNEIER].) s
-5 481 M
-( The "cast128-cbc" cipher is the CAST-128 cipher in CBC mode) s
-5 470 M
-( [RFC2144].) s
-5 448 M
-( The "none" algorithm specifies that no encryption is to be done.) s
-5 437 M
-( Note that this method provides no confidentiality protection, and it) s
-5 426 M
-( is not recommended. Some functionality \(e.g. password) s
-5 415 M
-( authentication\) may be disabled for security reasons if this cipher) s
-5 404 M
-( is chosen.) s
-5 382 M
-( Additional methods may be defined as specified in [SSH-ARCH].) s
-5 360 M
-(5.4 Data Integrity) s
-5 338 M
-( Data integrity is protected by including with each packet a message) s
-5 327 M
-( authentication code \(MAC\) that is computed from a shared secret,) s
-5 316 M
-( packet sequence number, and the contents of the packet.) s
-5 294 M
-( The message authentication algorithm and key are negotiated during) s
-5 283 M
-( key exchange. Initially, no MAC will be in effect, and its length) s
-5 272 M
-( MUST be zero. After key exchange, the selected MAC will be computed) s
-5 261 M
-( before encryption from the concatenation of packet data:) s
-5 239 M
-( mac = MAC\(key, sequence_number || unencrypted_packet\)) s
-5 217 M
-( where unencrypted_packet is the entire packet without MAC \(the length) s
-5 206 M
-( fields, payload and padding\), and sequence_number is an implicit) s
-5 195 M
-( packet sequence number represented as uint32. The sequence number is) s
-5 184 M
-( initialized to zero for the first packet, and is incremented after) s
-5 173 M
-( every packet \(regardless of whether encryption or MAC is in use\). It) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 9]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 10 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( is never reset, even if keys/algorithms are renegotiated later. It) s
-5 679 M
-( wraps around to zero after every 2^32 packets. The packet sequence) s
-5 668 M
-( number itself is not included in the packet sent over the wire.) s
-5 646 M
-( The MAC algorithms for each direction MUST run independently, and) s
-5 635 M
-( implementations MUST allow choosing the algorithm independently for) s
-5 624 M
-( both directions.) s
-5 602 M
-( The MAC bytes resulting from the MAC algorithm MUST be transmitted) s
-5 591 M
-( without encryption as the last part of the packet. The number of MAC) s
-5 580 M
-( bytes depends on the algorithm chosen.) s
-5 558 M
-( The following MAC algorithms are currently defined:) s
-5 536 M
-( hmac-sha1 REQUIRED HMAC-SHA1 \(digest length = key) s
-5 525 M
-( length = 20\)) s
-5 514 M
-( hmac-sha1-96 RECOMMENDED first 96 bits of HMAC-SHA1 \(digest) s
-5 503 M
-( length = 12, key length = 20\)) s
-5 492 M
-( hmac-md5 OPTIONAL HMAC-MD5 \(digest length = key) s
-5 481 M
-( length = 16\)) s
-5 470 M
-( hmac-md5-96 OPTIONAL first 96 bits of HMAC-MD5 \(digest) s
-5 459 M
-( length = 12, key length = 16\)) s
-5 448 M
-( none OPTIONAL no MAC; NOT RECOMMENDED) s
-5 426 M
-( Figure 1) s
-5 404 M
-( The "hmac-*" algorithms are described in [RFC2104] The "*-n" MACs use) s
-5 393 M
-( only the first n bits of the resulting value.) s
-5 371 M
-( The hash algorithms are described in [SCHNEIER].) s
-5 349 M
-( Additional methods may be defined as specified in [SSH-ARCH].) s
-5 327 M
-(5.5 Key Exchange Methods) s
-5 305 M
-( The key exchange method specifies how one-time session keys are) s
-5 294 M
-( generated for encryption and for authentication, and how the server) s
-5 283 M
-( authentication is done.) s
-5 261 M
-( Only one REQUIRED key exchange method has been defined:) s
-5 239 M
-( diffie-hellman-group1-sha1 REQUIRED) s
-5 217 M
-( This method is described later in this document.) s
-5 195 M
-( Additional methods may be defined as specified in [SSH-ARCH].) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 10]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (10,11) 6
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 11 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-(5.6 Public Key Algorithms) s
-5 668 M
-( This protocol has been designed to be able to operate with almost any) s
-5 657 M
-( public key format, encoding, and algorithm \(signature and/or) s
-5 646 M
-( encryption\).) s
-5 624 M
-( There are several aspects that define a public key type:) s
-5 613 M
-( o Key format: how is the key encoded and how are certificates) s
-5 602 M
-( represented. The key blobs in this protocol MAY contain) s
-5 591 M
-( certificates in addition to keys.) s
-5 580 M
-( o Signature and/or encryption algorithms. Some key types may not) s
-5 569 M
-( support both signing and encryption. Key usage may also be) s
-5 558 M
-( restricted by policy statements in e.g. certificates. In this) s
-5 547 M
-( case, different key types SHOULD be defined for the different) s
-5 536 M
-( policy alternatives.) s
-5 525 M
-( o Encoding of signatures and/or encrypted data. This includes but is) s
-5 514 M
-( not limited to padding, byte order, and data formats.) s
-5 492 M
-( The following public key and/or certificate formats are currently defined:) s
-5 470 M
-( ssh-dss REQUIRED sign Raw DSS Key) s
-5 459 M
-( ssh-rsa RECOMMENDED sign Raw RSA Key) s
-5 448 M
-( x509v3-sign-rsa OPTIONAL sign X.509 certificates \(RSA key\)) s
-5 437 M
-( x509v3-sign-dss OPTIONAL sign X.509 certificates \(DSS key\)) s
-5 426 M
-( spki-sign-rsa OPTIONAL sign SPKI certificates \(RSA key\)) s
-5 415 M
-( spki-sign-dss OPTIONAL sign SPKI certificates \(DSS key\)) s
-5 404 M
-( pgp-sign-rsa OPTIONAL sign OpenPGP certificates \(RSA key\)) s
-5 393 M
-( pgp-sign-dss OPTIONAL sign OpenPGP certificates \(DSS key\)) s
-5 371 M
-( Additional key types may be defined as specified in [SSH-ARCH].) s
-5 349 M
-( The key type MUST always be explicitly known \(from algorithm) s
-5 338 M
-( negotiation or some other source\). It is not normally included in) s
-5 327 M
-( the key blob.) s
-5 305 M
-( Certificates and public keys are encoded as follows:) s
-5 283 M
-( string certificate or public key format identifier) s
-5 272 M
-( byte[n] key/certificate data) s
-5 250 M
-( The certificate part may have be a zero length string, but a public) s
-5 239 M
-( key is required. This is the public key that will be used for) s
-5 228 M
-( authentication; the certificate sequence contained in the certificate) s
-5 217 M
-( blob can be used to provide authorization.) s
-5 195 M
-( Public key / certifcate formats that do not explicitly specify a) s
-5 184 M
-( signature format identifier MUST use the public key / certificate) s
-5 173 M
-( format identifier as the signature identifier.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 11]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 12 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( Signatures are encoded as follows:) s
-5 679 M
-( string signature format identifier \(as specified by the) s
-5 668 M
-( public key / cert format\)) s
-5 657 M
-( byte[n] signature blob in format specific encoding.) s
-5 624 M
-( The "ssh-dss" key format has the following specific encoding:) s
-5 602 M
-( string "ssh-dss") s
-5 591 M
-( mpint p) s
-5 580 M
-( mpint q) s
-5 569 M
-( mpint g) s
-5 558 M
-( mpint y) s
-5 536 M
-( Here the p, q, g, and y parameters form the signature key blob.) s
-5 514 M
-( Signing and verifying using this key format is done according to the) s
-5 503 M
-( Digital Signature Standard [FIPS-186] using the SHA-1 hash. A) s
-5 492 M
-( description can also be found in [SCHNEIER].) s
-5 470 M
-( The resulting signature is encoded as follows:) s
-5 448 M
-( string "ssh-dss") s
-5 437 M
-( string dss_signature_blob) s
-5 415 M
-( dss_signature_blob is encoded as a string containing r followed by s) s
-5 404 M
-( \(which are 160 bits long integers, without lengths or padding,) s
-5 393 M
-( unsigned and in network byte order\).) s
-5 371 M
-( The "ssh-rsa" key format has the following specific encoding:) s
-5 349 M
-( string "ssh-rsa") s
-5 338 M
-( mpint e) s
-5 327 M
-( mpint n) s
-5 305 M
-( Here the e and n parameters form the signature key blob.) s
-5 283 M
-( Signing and verifying using this key format is done according to) s
-5 272 M
-( [SCHNEIER] and [PKCS1] using the SHA-1 hash.) s
-5 250 M
-( The resulting signature is encoded as follows:) s
-5 228 M
-( string "ssh-rsa") s
-5 217 M
-( string rsa_signature_blob) s
-5 195 M
-( rsa_signature_blob is encoded as a string containing s \(which is an) s
-5 184 M
-( integer, without lengths or padding, unsigned and in network byte) s
-5 173 M
-( order\).) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 12]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (12,13) 7
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 13 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( The "spki-sign-rsa" method indicates that the certificate blob) s
-5 679 M
-( contains a sequence of SPKI certificates. The format of SPKI) s
-5 668 M
-( certificates is described in [RFC2693]. This method indicates that) s
-5 657 M
-( the key \(or one of the keys in the certificate\) is an RSA-key.) s
-5 635 M
-( The "spki-sign-dss". As above, but indicates that the key \(or one of) s
-5 624 M
-( the keys in the certificate\) is a DSS-key.) s
-5 602 M
-( The "pgp-sign-rsa" method indicates the certificates, the public key,) s
-5 591 M
-( and the signature are in OpenPGP compatible binary format) s
-5 580 M
-( \([RFC2440]\). This method indicates that the key is an RSA-key.) s
-5 558 M
-( The "pgp-sign-dss". As above, but indicates that the key is a) s
-5 547 M
-( DSS-key.) s
-5 525 M
-(6. Key Exchange) s
-5 503 M
-( Key exchange begins by each side sending lists of supported) s
-5 492 M
-( algorithms. Each side has a preferred algorithm in each category, and) s
-5 481 M
-( it is assumed that most implementations at any given time will use) s
-5 470 M
-( the same preferred algorithm. Each side MAY guess which algorithm) s
-5 459 M
-( the other side is using, and MAY send an initial key exchange packet) s
-5 448 M
-( according to the algorithm if appropriate for the preferred method.) s
-5 426 M
-( Guess is considered wrong, if:) s
-5 415 M
-( o the kex algorithm and/or the host key algorithm is guessed wrong) s
-5 404 M
-( \(server and client have different preferred algorithm\), or) s
-5 393 M
-( o if any of the other algorithms cannot be agreed upon \(the) s
-5 382 M
-( procedure is defined below in Section Section 6.1\).) s
-5 360 M
-( Otherwise, the guess is considered to be right and the optimistically) s
-5 349 M
-( sent packet MUST be handled as the first key exchange packet.) s
-5 327 M
-( However, if the guess was wrong, and a packet was optimistically sent) s
-5 316 M
-( by one or both parties, such packets MUST be ignored \(even if the) s
-5 305 M
-( error in the guess would not affect the contents of the initial) s
-5 294 M
-( packet\(s\)\), and the appropriate side MUST send the correct initial) s
-5 283 M
-( packet.) s
-5 261 M
-( Server authentication in the key exchange MAY be implicit. After a) s
-5 250 M
-( key exchange with implicit server authentication, the client MUST) s
-5 239 M
-( wait for response to its service request message before sending any) s
-5 228 M
-( further data.) s
-5 206 M
-(6.1 Algorithm Negotiation) s
-5 184 M
-( Key exchange begins by each side sending the following packet:) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 13]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 14 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( byte SSH_MSG_KEXINIT) s
-5 679 M
-( byte[16] cookie \(random bytes\)) s
-5 668 M
-( string kex_algorithms) s
-5 657 M
-( string server_host_key_algorithms) s
-5 646 M
-( string encryption_algorithms_client_to_server) s
-5 635 M
-( string encryption_algorithms_server_to_client) s
-5 624 M
-( string mac_algorithms_client_to_server) s
-5 613 M
-( string mac_algorithms_server_to_client) s
-5 602 M
-( string compression_algorithms_client_to_server) s
-5 591 M
-( string compression_algorithms_server_to_client) s
-5 580 M
-( string languages_client_to_server) s
-5 569 M
-( string languages_server_to_client) s
-5 558 M
-( boolean first_kex_packet_follows) s
-5 547 M
-( uint32 0 \(reserved for future extension\)) s
-5 525 M
-( Each of the algorithm strings MUST be a comma-separated list of) s
-5 514 M
-( algorithm names \(see ''Algorithm Naming'' in [SSH-ARCH]\). Each) s
-5 503 M
-( supported \(allowed\) algorithm MUST be listed in order of preference.) s
-5 481 M
-( The first algorithm in each list MUST be the preferred \(guessed\)) s
-5 470 M
-( algorithm. Each string MUST contain at least one algorithm name.) s
-5 437 M
-( cookie) s
-5 426 M
-( The cookie MUST be a random value generated by the sender. Its) s
-5 415 M
-( purpose is to make it impossible for either side to fully) s
-5 404 M
-( determine the keys and the session identifier.) s
-5 382 M
-( kex_algorithms) s
-5 371 M
-( Key exchange algorithms were defined above. The first) s
-5 360 M
-( algorithm MUST be the preferred \(and guessed\) algorithm. If) s
-5 349 M
-( both sides make the same guess, that algorithm MUST be used.) s
-5 338 M
-( Otherwise, the following algorithm MUST be used to choose a key) s
-5 327 M
-( exchange method: iterate over client's kex algorithms, one at a) s
-5 316 M
-( time. Choose the first algorithm that satisfies the following) s
-5 305 M
-( conditions:) s
-5 294 M
-( + the server also supports the algorithm,) s
-5 283 M
-( + if the algorithm requires an encryption-capable host key,) s
-5 272 M
-( there is an encryption-capable algorithm on the server's) s
-5 261 M
-( server_host_key_algorithms that is also supported by the) s
-5 250 M
-( client, and) s
-5 239 M
-( + if the algorithm requires a signature-capable host key,) s
-5 228 M
-( there is a signature-capable algorithm on the server's) s
-5 217 M
-( server_host_key_algorithms that is also supported by the) s
-5 206 M
-( client.) s
-5 195 M
-( + If no algorithm satisfying all these conditions can be) s
-5 184 M
-( found, the connection fails, and both sides MUST disconnect.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 14]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (14,15) 8
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 15 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( server_host_key_algorithms) s
-5 679 M
-( List of the algorithms supported for the server host key. The) s
-5 668 M
-( server lists the algorithms for which it has host keys; the) s
-5 657 M
-( client lists the algorithms that it is willing to accept.) s
-5 646 M
-( \(There MAY be multiple host keys for a host, possibly with) s
-5 635 M
-( different algorithms.\)) s
-5 613 M
-( Some host keys may not support both signatures and encryption) s
-5 602 M
-( \(this can be determined from the algorithm\), and thus not all) s
-5 591 M
-( host keys are valid for all key exchange methods.) s
-5 569 M
-( Algorithm selection depends on whether the chosen key exchange) s
-5 558 M
-( algorithm requires a signature or encryption capable host key.) s
-5 547 M
-( It MUST be possible to determine this from the public key) s
-5 536 M
-( algorithm name. The first algorithm on the client's list that) s
-5 525 M
-( satisfies the requirements and is also supported by the server) s
-5 514 M
-( MUST be chosen. If there is no such algorithm, both sides MUST) s
-5 503 M
-( disconnect.) s
-5 481 M
-( encryption_algorithms) s
-5 470 M
-( Lists the acceptable symmetric encryption algorithms in order) s
-5 459 M
-( of preference. The chosen encryption algorithm to each) s
-5 448 M
-( direction MUST be the first algorithm on the client's list) s
-5 437 M
-( that is also on the server's list. If there is no such) s
-5 426 M
-( algorithm, both sides MUST disconnect.) s
-5 404 M
-( Note that "none" must be explicitly listed if it is to be) s
-5 393 M
-( acceptable. The defined algorithm names are listed in Section) s
-5 382 M
-( Section 5.3.) s
-5 360 M
-( mac_algorithms) s
-5 349 M
-( Lists the acceptable MAC algorithms in order of preference.) s
-5 338 M
-( The chosen MAC algorithm MUST be the first algorithm on the) s
-5 327 M
-( client's list that is also on the server's list. If there is) s
-5 316 M
-( no such algorithm, both sides MUST disconnect.) s
-5 294 M
-( Note that "none" must be explicitly listed if it is to be) s
-5 283 M
-( acceptable. The MAC algorithm names are listed in Section) s
-5 272 M
-( Figure 1.) s
-5 250 M
-( compression_algorithms) s
-5 239 M
-( Lists the acceptable compression algorithms in order of) s
-5 228 M
-( preference. The chosen compression algorithm MUST be the first) s
-5 217 M
-( algorithm on the client's list that is also on the server's) s
-5 206 M
-( list. If there is no such algorithm, both sides MUST) s
-5 195 M
-( disconnect.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 15]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 16 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( Note that "none" must be explicitly listed if it is to be) s
-5 679 M
-( acceptable. The compression algorithm names are listed in) s
-5 668 M
-( Section Section 5.2.) s
-5 646 M
-( languages) s
-5 635 M
-( This is a comma-separated list of language tags in order of) s
-5 624 M
-( preference [RFC3066]. Both parties MAY ignore this list. If) s
-5 613 M
-( there are no language preferences, this list SHOULD be empty.) s
-5 602 M
-( Language tags SHOULD NOT be present unless they are known to be) s
-5 591 M
-( needed by the sending party.) s
-5 569 M
-( first_kex_packet_follows) s
-5 558 M
-( Indicates whether a guessed key exchange packet follows. If a) s
-5 547 M
-( guessed packet will be sent, this MUST be TRUE. If no guessed) s
-5 536 M
-( packet will be sent, this MUST be FALSE.) s
-5 514 M
-( After receiving the SSH_MSG_KEXINIT packet from the other side,) s
-5 503 M
-( each party will know whether their guess was right. If the) s
-5 492 M
-( other party's guess was wrong, and this field was TRUE, the) s
-5 481 M
-( next packet MUST be silently ignored, and both sides MUST then) s
-5 470 M
-( act as determined by the negotiated key exchange method. If) s
-5 459 M
-( the guess was right, key exchange MUST continue using the) s
-5 448 M
-( guessed packet.) s
-5 426 M
-( After the KEXINIT packet exchange, the key exchange algorithm is run.) s
-5 415 M
-( It may involve several packet exchanges, as specified by the key) s
-5 404 M
-( exchange method.) s
-5 382 M
-(6.2 Output from Key Exchange) s
-5 360 M
-( The key exchange produces two values: a shared secret K, and an) s
-5 349 M
-( exchange hash H. Encryption and authentication keys are derived from) s
-5 338 M
-( these. The exchange hash H from the first key exchange is) s
-5 327 M
-( additionally used as the session identifier, which is a unique) s
-5 316 M
-( identifier for this connection. It is used by authentication methods) s
-5 305 M
-( as a part of the data that is signed as a proof of possession of a) s
-5 294 M
-( private key. Once computed, the session identifier is not changed,) s
-5 283 M
-( even if keys are later re-exchanged.) s
-5 250 M
-( Each key exchange method specifies a hash function that is used in) s
-5 239 M
-( the key exchange. The same hash algorithm MUST be used in key) s
-5 228 M
-( derivation. Here, we'll call it HASH.) s
-5 195 M
-( Encryption keys MUST be computed as HASH of a known value and K as) s
-5 184 M
-( follows:) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 16]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (16,17) 9
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 17 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( o Initial IV client to server: HASH\(K || H || "A" || session_id\)) s
-5 679 M
-( \(Here K is encoded as mpint and "A" as byte and session_id as raw) s
-5 668 M
-( data."A" means the single character A, ASCII 65\).) s
-5 657 M
-( o Initial IV server to client: HASH\(K || H || "B" || session_id\)) s
-5 646 M
-( o Encryption key client to server: HASH\(K || H || "C" || session_id\)) s
-5 635 M
-( o Encryption key server to client: HASH\(K || H || "D" || session_id\)) s
-5 624 M
-( o Integrity key client to server: HASH\(K || H || "E" || session_id\)) s
-5 613 M
-( o Integrity key server to client: HASH\(K || H || "F" || session_id\)) s
-5 591 M
-( Key data MUST be taken from the beginning of the hash output. 128) s
-5 580 M
-( bits \(16 bytes\) MUST be used for algorithms with variable-length) s
-5 569 M
-( keys. The only variable key length algorithm defined in this document) s
-5 558 M
-( is arcfour\). For other algorithms, as many bytes as are needed are) s
-5 547 M
-( taken from the beginning of the hash value. If the key length needed) s
-5 536 M
-( is longer than the output of the HASH, the key is extended by) s
-5 525 M
-( computing HASH of the concatenation of K and H and the entire key so) s
-5 514 M
-( far, and appending the resulting bytes \(as many as HASH generates\) to) s
-5 503 M
-( the key. This process is repeated until enough key material is) s
-5 492 M
-( available; the key is taken from the beginning of this value. In) s
-5 481 M
-( other words:) s
-5 459 M
-( K1 = HASH\(K || H || X || session_id\) \(X is e.g. "A"\)) s
-5 448 M
-( K2 = HASH\(K || H || K1\)) s
-5 437 M
-( K3 = HASH\(K || H || K1 || K2\)) s
-5 426 M
-( ...) s
-5 415 M
-( key = K1 || K2 || K3 || ...) s
-5 393 M
-( This process will lose entropy if the amount of entropy in K is) s
-5 382 M
-( larger than the internal state size of HASH.) s
-5 360 M
-(6.3 Taking Keys Into Use) s
-5 338 M
-( Key exchange ends by each side sending an SSH_MSG_NEWKEYS message.) s
-5 327 M
-( This message is sent with the old keys and algorithms. All messages) s
-5 316 M
-( sent after this message MUST use the new keys and algorithms.) s
-5 283 M
-( When this message is received, the new keys and algorithms MUST be) s
-5 272 M
-( taken into use for receiving.) s
-5 239 M
-( This message is the only valid message after key exchange, in) s
-5 228 M
-( addition to SSH_MSG_DEBUG, SSH_MSG_DISCONNECT and SSH_MSG_IGNORE) s
-5 217 M
-( messages. The purpose of this message is to ensure that a party is) s
-5 206 M
-( able to respond with a disconnect message that the other party can) s
-5 195 M
-( understand if something goes wrong with the key exchange.) s
-5 184 M
-( Implementations MUST NOT accept any other messages after key exchange) s
-5 173 M
-( before receiving SSH_MSG_NEWKEYS.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 17]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 18 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( byte SSH_MSG_NEWKEYS) s
-5 657 M
-(7. Diffie-Hellman Key Exchange) s
-5 635 M
-( The Diffie-Hellman key exchange provides a shared secret that can not) s
-5 624 M
-( be determined by either party alone. The key exchange is combined) s
-5 613 M
-( with a signature with the host key to provide host authentication.) s
-5 580 M
-( In the following description \(C is the client, S is the server; p is) s
-5 569 M
-( a large safe prime, g is a generator for a subgroup of GF\(p\), and q) s
-5 558 M
-( is the order of the subgroup; V_S is S's version string; V_C is C's) s
-5 547 M
-( version string; K_S is S's public host key; I_C is C's KEXINIT) s
-5 536 M
-( message and I_S S's KEXINIT message which have been exchanged before) s
-5 525 M
-( this part begins\):) s
-5 492 M
-( 1. C generates a random number x \(1 < x < q\) and computes e = g^x) s
-5 481 M
-( mod p. C sends "e" to S.) s
-5 459 M
-( 2. S generates a random number y \(0 < y < q\) and computes f = g^y) s
-5 448 M
-( mod p. S receives "e". It computes K = e^y mod p, H = hash\(V_C) s
-5 437 M
-( || V_S || I_C || I_S || K_S || e || f || K\) \(these elements are) s
-5 426 M
-( encoded according to their types; see below\), and signature s on) s
-5 415 M
-( H with its private host key. S sends "K_S || f || s" to C. The) s
-5 404 M
-( signing operation may involve a second hashing operation.) s
-5 382 M
-( 3. C verifies that K_S really is the host key for S \(e.g. using) s
-5 371 M
-( certificates or a local database\). C is also allowed to accept) s
-5 360 M
-( the key without verification; however, doing so will render the) s
-5 349 M
-( protocol insecure against active attacks \(but may be desirable) s
-5 338 M
-( for practical reasons in the short term in many environments\). C) s
-5 327 M
-( then computes K = f^x mod p, H = hash\(V_C || V_S || I_C || I_S ||) s
-5 316 M
-( K_S || e || f || K\), and verifies the signature s on H.) s
-5 294 M
-( Either side MUST NOT send or accept e or f values that are not in the) s
-5 283 M
-( range [1, p-1]. If this condition is violated, the key exchange) s
-5 272 M
-( fails.) s
-5 239 M
-( This is implemented with the following messages. The hash algorithm) s
-5 228 M
-( for computing the exchange hash is defined by the method name, and is) s
-5 217 M
-( called HASH. The public key algorithm for signing is negotiated with) s
-5 206 M
-( the KEXINIT messages.) s
-5 184 M
-( First, the client sends the following:) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 18]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (18,19) 10
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 19 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( byte SSH_MSG_KEXDH_INIT) s
-5 679 M
-( mpint e) s
-5 646 M
-( The server responds with the following:) s
-5 624 M
-( byte SSH_MSG_KEXDH_REPLY) s
-5 613 M
-( string server public host key and certificates \(K_S\)) s
-5 602 M
-( mpint f) s
-5 591 M
-( string signature of H) s
-5 569 M
-( The hash H is computed as the HASH hash of the concatenation of the) s
-5 558 M
-( following:) s
-5 536 M
-( string V_C, the client's version string \(CR and NL excluded\)) s
-5 525 M
-( string V_S, the server's version string \(CR and NL excluded\)) s
-5 514 M
-( string I_C, the payload of the client's SSH_MSG_KEXINIT) s
-5 503 M
-( string I_S, the payload of the server's SSH_MSG_KEXINIT) s
-5 492 M
-( string K_S, the host key) s
-5 481 M
-( mpint e, exchange value sent by the client) s
-5 470 M
-( mpint f, exchange value sent by the server) s
-5 459 M
-( mpint K, the shared secret) s
-5 437 M
-( This value is called the exchange hash, and it is used to) s
-5 426 M
-( authenticate the key exchange. The exchange hash SHOULD be kept) s
-5 415 M
-( secret.) s
-5 382 M
-( The signature algorithm MUST be applied over H, not the original) s
-5 371 M
-( data. Most signature algorithms include hashing and additional) s
-5 360 M
-( padding. For example, "ssh-dss" specifies SHA-1 hashing; in that) s
-5 349 M
-( case, the data is first hashed with HASH to compute H, and H is then) s
-5 338 M
-( hashed with SHA-1 as part of the signing operation.) s
-5 316 M
-(7.1 diffie-hellman-group1-sha1) s
-5 294 M
-( The "diffie-hellman-group1-sha1" method specifies Diffie-Hellman key) s
-5 283 M
-( exchange with SHA-1 as HASH, and Oakley group 14 [RFC3526] \(2048-bit) s
-5 272 M
-( MODP Group\). It is included below in hexadecimal and decimal.) s
-5 250 M
-( The prime p is equal to 2^1024 - 2^960 - 1 + 2^64 * floor\( 2^894 Pi +) s
-5 239 M
-( 129093 \). Its hexadecimal value is:) s
-5 217 M
-( FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1) s
-5 206 M
-( 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD) s
-5 195 M
-( EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245) s
-5 184 M
-( E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED) s
-5 173 M
-( EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 19]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 20 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( FFFFFFFF FFFFFFFF.) s
-5 668 M
-( In decimal, this value is:) s
-5 646 M
-( 179769313486231590770839156793787453197860296048756011706444) s
-5 635 M
-( 423684197180216158519368947833795864925541502180565485980503) s
-5 624 M
-( 646440548199239100050792877003355816639229553136239076508735) s
-5 613 M
-( 759914822574862575007425302077447712589550957937778424442426) s
-5 602 M
-( 617334727629299387668709205606050270810842907692932019128194) s
-5 591 M
-( 467627007.) s
-5 569 M
-( The generator used with this prime is g = 2. The group order q is \(p) s
-5 558 M
-( - 1\) / 2.) s
-5 536 M
-(8. Key Re-Exchange) s
-5 514 M
-( Key re-exchange is started by sending an SSH_MSG_KEXINIT packet when) s
-5 503 M
-( not already doing a key exchange \(as described in Section Section) s
-5 492 M
-( 6.1\). When this message is received, a party MUST respond with its) s
-5 481 M
-( own SSH_MSG_KEXINIT message except when the received SSH_MSG_KEXINIT) s
-5 470 M
-( already was a reply. Either party MAY initiate the re-exchange, but) s
-5 459 M
-( roles MUST NOT be changed \(i.e., the server remains the server, and) s
-5 448 M
-( the client remains the client\).) s
-5 415 M
-( Key re-exchange is performed using whatever encryption was in effect) s
-5 404 M
-( when the exchange was started. Encryption, compression, and MAC) s
-5 393 M
-( methods are not changed before a new SSH_MSG_NEWKEYS is sent after) s
-5 382 M
-( the key exchange \(as in the initial key exchange\). Re-exchange is) s
-5 371 M
-( processed identically to the initial key exchange, except for the) s
-5 360 M
-( session identifier that will remain unchanged. It is permissible to) s
-5 349 M
-( change some or all of the algorithms during the re-exchange. Host) s
-5 338 M
-( keys can also change. All keys and initialization vectors are) s
-5 327 M
-( recomputed after the exchange. Compression and encryption contexts) s
-5 316 M
-( are reset.) s
-5 283 M
-( It is recommended that the keys are changed after each gigabyte of) s
-5 272 M
-( transmitted data or after each hour of connection time, whichever) s
-5 261 M
-( comes sooner. However, since the re-exchange is a public key) s
-5 250 M
-( operation, it requires a fair amount of processing power and should) s
-5 239 M
-( not be performed too often.) s
-5 206 M
-( More application data may be sent after the SSH_MSG_NEWKEYS packet) s
-5 195 M
-( has been sent; key exchange does not affect the protocols that lie) s
-5 184 M
-( above the SSH transport layer.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 20]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (20,21) 11
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 21 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-(9. Service Request) s
-5 668 M
-( After the key exchange, the client requests a service. The service is) s
-5 657 M
-( identified by a name. The format of names and procedures for defining) s
-5 646 M
-( new names are defined in [SSH-ARCH].) s
-5 613 M
-( Currently, the following names have been reserved:) s
-5 591 M
-( ssh-userauth) s
-5 580 M
-( ssh-connection) s
-5 558 M
-( Similar local naming policy is applied to the service names, as is) s
-5 547 M
-( applied to the algorithm names; a local service should use the) s
-5 536 M
-( "servicename@domain" syntax.) s
-5 514 M
-( byte SSH_MSG_SERVICE_REQUEST) s
-5 503 M
-( string service name) s
-5 481 M
-( If the server rejects the service request, it SHOULD send an) s
-5 470 M
-( appropriate SSH_MSG_DISCONNECT message and MUST disconnect.) s
-5 437 M
-( When the service starts, it may have access to the session identifier) s
-5 426 M
-( generated during the key exchange.) s
-5 393 M
-( If the server supports the service \(and permits the client to use) s
-5 382 M
-( it\), it MUST respond with the following:) s
-5 360 M
-( byte SSH_MSG_SERVICE_ACCEPT) s
-5 349 M
-( string service name) s
-5 327 M
-( Message numbers used by services should be in the area reserved for) s
-5 316 M
-( them \(see Section 6 in [SSH-ARCH]\). The transport level will) s
-5 305 M
-( continue to process its own messages.) s
-5 272 M
-( Note that after a key exchange with implicit server authentication,) s
-5 261 M
-( the client MUST wait for response to its service request message) s
-5 250 M
-( before sending any further data.) s
-5 228 M
-(10. Additional Messages) s
-5 206 M
-( Either party may send any of the following messages at any time.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 21]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 22 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-(10.1 Disconnection Message) s
-5 668 M
-( byte SSH_MSG_DISCONNECT) s
-5 657 M
-( uint32 reason code) s
-5 646 M
-( string description [RFC2279]) s
-5 635 M
-( string language tag [RFC3066]) s
-5 613 M
-( This message causes immediate termination of the connection. All) s
-5 602 M
-( implementations MUST be able to process this message; they SHOULD be) s
-5 591 M
-( able to send this message.) s
-5 569 M
-( The sender MUST NOT send or receive any data after this message, and) s
-5 558 M
-( the recipient MUST NOT accept any data after receiving this message.) s
-5 547 M
-( The description field gives a more specific explanation in a) s
-5 536 M
-( human-readable form. The error code gives the reason in a more) s
-5 525 M
-( machine-readable format \(suitable for localization\), and can have the) s
-5 514 M
-( following values:) s
-5 492 M
-( #define SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT 1) s
-5 481 M
-( #define SSH_DISCONNECT_PROTOCOL_ERROR 2) s
-5 470 M
-( #define SSH_DISCONNECT_KEY_EXCHANGE_FAILED 3) s
-5 459 M
-( #define SSH_DISCONNECT_RESERVED 4) s
-5 448 M
-( #define SSH_DISCONNECT_MAC_ERROR 5) s
-5 437 M
-( #define SSH_DISCONNECT_COMPRESSION_ERROR 6) s
-5 426 M
-( #define SSH_DISCONNECT_SERVICE_NOT_AVAILABLE 7) s
-5 415 M
-( #define SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED 8) s
-5 404 M
-( #define SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE 9) s
-5 393 M
-( #define SSH_DISCONNECT_CONNECTION_LOST 10) s
-5 382 M
-( #define SSH_DISCONNECT_BY_APPLICATION 11) s
-5 371 M
-( #define SSH_DISCONNECT_TOO_MANY_CONNECTIONS 12) s
-5 360 M
-( #define SSH_DISCONNECT_AUTH_CANCELLED_BY_USER 13) s
-5 349 M
-( #define SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE 14) s
-5 338 M
-( #define SSH_DISCONNECT_ILLEGAL_USER_NAME 15) s
-5 316 M
-( If the description string is displayed, control character filtering) s
-5 305 M
-( discussed in [SSH-ARCH] should be used to avoid attacks by sending) s
-5 294 M
-( terminal control characters.) s
-5 272 M
-(10.2 Ignored Data Message) s
-5 250 M
-( byte SSH_MSG_IGNORE) s
-5 239 M
-( string data) s
-5 217 M
-( All implementations MUST understand \(and ignore\) this message at any) s
-5 206 M
-( time \(after receiving the protocol version\). No implementation is) s
-5 195 M
-( required to send them. This message can be used as an additional) s
-5 184 M
-( protection measure against advanced traffic analysis techniques.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 22]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (22,23) 12
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 23 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-(10.3 Debug Message) s
-5 668 M
-( byte SSH_MSG_DEBUG) s
-5 657 M
-( boolean always_display) s
-5 646 M
-( string message [RFC2279]) s
-5 635 M
-( string language tag [RFC3066]) s
-5 613 M
-( All implementations MUST understand this message, but they are) s
-5 602 M
-( allowed to ignore it. This message is used to pass the other side) s
-5 591 M
-( information that may help debugging. If always_display is TRUE, the) s
-5 580 M
-( message SHOULD be displayed. Otherwise, it SHOULD NOT be displayed) s
-5 569 M
-( unless debugging information has been explicitly requested by the) s
-5 558 M
-( user.) s
-5 525 M
-( The message doesn't need to contain a newline. It is, however,) s
-5 514 M
-( allowed to consist of multiple lines separated by CRLF \(Carriage) s
-5 503 M
-( Return - Line Feed\) pairs.) s
-5 470 M
-( If the message string is displayed, terminal control character) s
-5 459 M
-( filtering discussed in [SSH-ARCH] should be used to avoid attacks by) s
-5 448 M
-( sending terminal control characters.) s
-5 426 M
-(10.4 Reserved Messages) s
-5 404 M
-( An implementation MUST respond to all unrecognized messages with an) s
-5 393 M
-( SSH_MSG_UNIMPLEMENTED message in the order in which the messages were) s
-5 382 M
-( received. Such messages MUST be otherwise ignored. Later protocol) s
-5 371 M
-( versions may define other meanings for these message types.) s
-5 349 M
-( byte SSH_MSG_UNIMPLEMENTED) s
-5 338 M
-( uint32 packet sequence number of rejected message) s
-5 305 M
-(11. Summary of Message Numbers) s
-5 283 M
-( The following message numbers have been defined in this protocol:) s
-5 261 M
-( #define SSH_MSG_DISCONNECT 1) s
-5 250 M
-( #define SSH_MSG_IGNORE 2) s
-5 239 M
-( #define SSH_MSG_UNIMPLEMENTED 3) s
-5 228 M
-( #define SSH_MSG_DEBUG 4) s
-5 217 M
-( #define SSH_MSG_SERVICE_REQUEST 5) s
-5 206 M
-( #define SSH_MSG_SERVICE_ACCEPT 6) s
-5 184 M
-( #define SSH_MSG_KEXINIT 20) s
-5 173 M
-( #define SSH_MSG_NEWKEYS 21) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 23]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 24 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( /* Numbers 30-49 used for kex packets.) s
-5 679 M
-( Different kex methods may reuse message numbers in) s
-5 668 M
-( this range. */) s
-5 646 M
-( #define SSH_MSG_KEXDH_INIT 30) s
-5 635 M
-( #define SSH_MSG_KEXDH_REPLY 31) s
-5 602 M
-(12. IANA Considerations) s
-5 580 M
-( This document is part of a set, the IANA considerations for the SSH) s
-5 569 M
-( protocol as defined in [SSH-ARCH], [SSH-TRANS], [SSH-USERAUTH],) s
-5 558 M
-( [SSH-CONNECT] are detailed in [SSH-NUMBERS].) s
-5 536 M
-(13. Security Considerations) s
-5 514 M
-( This protocol provides a secure encrypted channel over an insecure) s
-5 503 M
-( network. It performs server host authentication, key exchange,) s
-5 492 M
-( encryption, and integrity protection. It also derives a unique) s
-5 481 M
-( session id that may be used by higher-level protocols.) s
-5 459 M
-( Full security considerations for this protocol are provided in) s
-5 448 M
-( Section 8 of [SSH-ARCH]) s
-5 426 M
-(14. Intellectual Property) s
-5 404 M
-( The IETF takes no position regarding the validity or scope of any) s
-5 393 M
-( intellectual property or other rights that might be claimed to) s
-5 382 M
-( pertain to the implementation or use of the technology described in) s
-5 371 M
-( this document or the extent to which any license under such rights) s
-5 360 M
-( might or might not be available; neither does it represent that it) s
-5 349 M
-( has made any effort to identify any such rights. Information on the) s
-5 338 M
-( IETF's procedures with respect to rights in standards-track and) s
-5 327 M
-( standards-related documentation can be found in BCP-11. Copies of) s
-5 316 M
-( claims of rights made available for publication and any assurances of) s
-5 305 M
-( licenses to be made available, or the result of an attempt made to) s
-5 294 M
-( obtain a general license or permission for the use of such) s
-5 283 M
-( proprietary rights by implementers or users of this specification can) s
-5 272 M
-( be obtained from the IETF Secretariat.) s
-5 250 M
-( The IETF has been notified of intellectual property rights claimed in) s
-5 239 M
-( regard to some or all of the specification contained in this) s
-5 228 M
-( document. For more information consult the online list of claimed) s
-5 217 M
-( rights.) s
-5 195 M
-(15. Additional Information) s
-5 173 M
-( The current document editor is: [email protected]. Comments on) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 24]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (24,25) 13
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 25 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( this internet draft should be sent to the IETF SECSH working group,) s
-5 679 M
-( details at: http://ietf.org/html.charters/secsh-charter.html) s
-5 657 M
-(Normative) s
-5 635 M
-( [SSH-ARCH]) s
-5 624 M
-( Ylonen, T., "SSH Protocol Architecture", I-D) s
-5 613 M
-( draft-ietf-architecture-15.txt, Oct 2003.) s
-5 591 M
-( [SSH-TRANS]) s
-5 580 M
-( Ylonen, T., "SSH Transport Layer Protocol", I-D) s
-5 569 M
-( draft-ietf-transport-17.txt, Oct 2003.) s
-5 547 M
-( [SSH-USERAUTH]) s
-5 536 M
-( Ylonen, T., "SSH Authentication Protocol", I-D) s
-5 525 M
-( draft-ietf-userauth-18.txt, Oct 2003.) s
-5 503 M
-( [SSH-CONNECT]) s
-5 492 M
-( Ylonen, T., "SSH Connection Protocol", I-D) s
-5 481 M
-( draft-ietf-connect-18.txt, Oct 2003.) s
-5 459 M
-( [SSH-NUMBERS]) s
-5 448 M
-( Lehtinen, S. and D. Moffat, "SSH Protocol Assigned) s
-5 437 M
-( Numbers", I-D draft-ietf-secsh-assignednumbers-05.txt, Oct) s
-5 426 M
-( 2003.) s
-5 404 M
-( [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate) s
-5 393 M
-( Requirement Levels", BCP 14, RFC 2119, March 1997.) s
-5 371 M
-(Informative) s
-5 349 M
-( [FIPS-186]) s
-5 338 M
-( Federal Information Processing Standards Publication,) s
-5 327 M
-( "FIPS PUB 186, Digital Signature Standard", May 1994.) s
-5 305 M
-( [FIPS-197]) s
-5 294 M
-( NIST, "FIPS PUB 197 Advanced Encryption Standard \(AES\)",) s
-5 283 M
-( November 2001.) s
-5 261 M
-( [FIPS-46-3]) s
-5 250 M
-( U.S. Dept. of Commerce, "FIPS PUB 46-3, Data Encryption) s
-5 239 M
-( Standard \(DES\)", October 1999.) s
-5 217 M
-( [RFC2459] Housley, R., Ford, W., Polk, T. and D. Solo, "Internet) s
-5 206 M
-( X.509 Public Key Infrastructure Certificate and CRL) s
-5 195 M
-( Profile", RFC 2459, January 1999.) s
-5 173 M
-( [RFC1034] Mockapetris, P., "Domain names - concepts and facilities",) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 25]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 26 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( STD 13, RFC 1034, November 1987.) s
-5 668 M
-( [RFC3066] Alvestrand, H., "Tags for the Identification of) s
-5 657 M
-( Languages", BCP 47, RFC 3066, January 2001.) s
-5 635 M
-( [RFC1950] Deutsch, L. and J-L. Gailly, "ZLIB Compressed Data Format) s
-5 624 M
-( Specification version 3.3", RFC 1950, May 1996.) s
-5 602 M
-( [RFC1951] Deutsch, P., "DEFLATE Compressed Data Format Specification) s
-5 591 M
-( version 1.3", RFC 1951, May 1996.) s
-5 569 M
-( [RFC2279] Yergeau, F., "UTF-8, a transformation format of ISO) s
-5 558 M
-( 10646", RFC 2279, January 1998.) s
-5 536 M
-( [RFC2104] Krawczyk, H., Bellare, M. and R. Canetti, "HMAC:) s
-5 525 M
-( Keyed-Hashing for Message Authentication", RFC 2104,) s
-5 514 M
-( February 1997.) s
-5 492 M
-( [RFC2144] Adams, C., "The CAST-128 Encryption Algorithm", RFC 2144,) s
-5 481 M
-( May 1997.) s
-5 459 M
-( [RFC2440] Callas, J., Donnerhacke, L., Finney, H. and R. Thayer,) s
-5 448 M
-( "OpenPGP Message Format", RFC 2440, November 1998.) s
-5 426 M
-( [RFC2693] Ellison, C., Frantz, B., Lampson, B., Rivest, R., Thomas,) s
-5 415 M
-( B. and T. Ylonen, "SPKI Certificate Theory", RFC 2693,) s
-5 404 M
-( September 1999.) s
-5 382 M
-( [RFC3526] Kivinen, T. and M. Kojo, "More Modular Exponential \(MODP\)) s
-5 371 M
-( Diffie-Hellman groups for Internet Key Exchange \(IKE\)",) s
-5 360 M
-( RFC 3526, May 2003.) s
-5 338 M
-( [SCHNEIER]) s
-5 327 M
-( Schneier, B., "Applied Cryptography Second Edition:) s
-5 316 M
-( protocols algorithms and source in code in C", 1996.) s
-5 294 M
-( [TWOFISH] Schneier, B., "The Twofish Encryptions Algorithm: A) s
-5 283 M
-( 128-Bit Block Cipher, 1st Edition", March 1999.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 26]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (26,27) 14
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 27 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-(Authors' Addresses) s
-5 668 M
-( Tatu Ylonen) s
-5 657 M
-( SSH Communications Security Corp) s
-5 646 M
-( Fredrikinkatu 42) s
-5 635 M
-( HELSINKI FIN-00100) s
-5 624 M
-( Finland) s
-5 602 M
-( EMail: [email protected]) s
-5 569 M
-( Darren J. Moffat \(editor\)) s
-5 558 M
-( Sun Microsystems, Inc) s
-5 547 M
-( 17 Network Circle) s
-5 536 M
-( Menlo Park 95025) s
-5 525 M
-( USA) s
-5 503 M
-( EMail: [email protected]) s
-5 481 M
-(Appendix A. Contibutors) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 27]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 28 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-(Intellectual Property Statement) s
-5 668 M
-( The IETF takes no position regarding the validity or scope of any) s
-5 657 M
-( intellectual property or other rights that might be claimed to) s
-5 646 M
-( pertain to the implementation or use of the technology described in) s
-5 635 M
-( this document or the extent to which any license under such rights) s
-5 624 M
-( might or might not be available; neither does it represent that it) s
-5 613 M
-( has made any effort to identify any such rights. Information on the) s
-5 602 M
-( IETF's procedures with respect to rights in standards-track and) s
-5 591 M
-( standards-related documentation can be found in BCP-11. Copies of) s
-5 580 M
-( claims of rights made available for publication and any assurances of) s
-5 569 M
-( licenses to be made available, or the result of an attempt made to) s
-5 558 M
-( obtain a general license or permission for the use of such) s
-5 547 M
-( proprietary rights by implementors or users of this specification can) s
-5 536 M
-( be obtained from the IETF Secretariat.) s
-5 514 M
-( The IETF invites any interested party to bring to its attention any) s
-5 503 M
-( copyrights, patents or patent applications, or other proprietary) s
-5 492 M
-( rights which may cover technology that may be required to practice) s
-5 481 M
-( this standard. Please address the information to the IETF Executive) s
-5 470 M
-( Director.) s
-5 448 M
-( The IETF has been notified of intellectual property rights claimed in) s
-5 437 M
-( regard to some or all of the specification contained in this) s
-5 426 M
-( document. For more information consult the online list of claimed) s
-5 415 M
-( rights.) s
-5 382 M
-(Full Copyright Statement) s
-5 360 M
-( Copyright \(C\) The Internet Society \(2003\). All Rights Reserved.) s
-5 338 M
-( This document and translations of it may be copied and furnished to) s
-5 327 M
-( others, and derivative works that comment on or otherwise explain it) s
-5 316 M
-( or assist in its implementation may be prepared, copied, published) s
-5 305 M
-( and distributed, in whole or in part, without restriction of any) s
-5 294 M
-( kind, provided that the above copyright notice and this paragraph are) s
-5 283 M
-( included on all such copies and derivative works. However, this) s
-5 272 M
-( document itself may not be modified in any way, such as by removing) s
-5 261 M
-( the copyright notice or references to the Internet Society or other) s
-5 250 M
-( Internet organizations, except as needed for the purpose of) s
-5 239 M
-( developing Internet standards in which case the procedures for) s
-5 228 M
-( copyrights defined in the Internet Standards process must be) s
-5 217 M
-( followed, or as required to translate it into languages other than) s
-5 206 M
-( English.) s
-5 184 M
-( The limited permissions granted above are perpetual and will not be) s
-5 173 M
-( revoked by the Internet Society or its successors or assignees.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 28]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (28,29) 15
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 29 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( This document and the information contained herein is provided on an) s
-5 679 M
-( "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING) s
-5 668 M
-( TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING) s
-5 657 M
-( BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION) s
-5 646 M
-( HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF) s
-5 635 M
-( MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.) s
-5 602 M
-(Acknowledgment) s
-5 580 M
-( Funding for the RFC Editor function is currently provided by the) s
-5 569 M
-( Internet Society.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 29]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-showpage
-PStoPSsaved restore
-%%Trailer
-%%Pages: 29
-%%DocumentNeededResources: font Courier-Bold Courier
-%%EOF
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-transport-17.txt b/lib/ssh/doc/standard/draft-ietf-secsh-transport-17.txt
deleted file mode 100644
index 9073ea52b2..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-transport-17.txt
+++ /dev/null
@@ -1,1624 +0,0 @@
-
-
-
-Network Working Group T. Ylonen
-Internet-Draft SSH Communications Security Corp
-Expires: March 31, 2004 D. Moffat, Editor, Ed.
- Sun Microsystems, Inc
- Oct 2003
-
-
- SSH Transport Layer Protocol
- draft-ietf-secsh-transport-17.txt
-
-Status of this Memo
-
- This document is an Internet-Draft and is in full conformance with
- all provisions of Section 10 of RFC2026.
-
- Internet-Drafts are working documents of the Internet Engineering
- Task Force (IETF), its areas, and its working groups. Note that other
- groups may also distribute working documents as Internet-Drafts.
-
- Internet-Drafts are draft documents valid for a maximum of six months
- and may be updated, replaced, or obsoleted by other documents at any
- time. It is inappropriate to use Internet-Drafts as reference
- material or to cite them other than as "work in progress."
-
- The list of current Internet-Drafts can be accessed at http://
- www.ietf.org/ietf/1id-abstracts.txt.
-
- The list of Internet-Draft Shadow Directories can be accessed at
- http://www.ietf.org/shadow.html.
-
- This Internet-Draft will expire on March 31, 2004.
-
-Copyright Notice
-
- Copyright (C) The Internet Society (2003). All Rights Reserved.
-
-Abstract
-
- SSH is a protocol for secure remote login and other secure network
- services over an insecure network.
-
- This document describes the SSH transport layer protocol which
- typically runs on top of TCP/IP. The protocol can be used as a basis
- for a number of secure network services. It provides strong
- encryption, server authentication, and integrity protection. It may
- also provide compression.
-
- Key exchange method, public key algorithm, symmetric encryption
- algorithm, message authentication algorithm, and hash algorithm are
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 1]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- all negotiated.
-
- This document also describes the Diffie-Hellman key exchange method
- and the minimal set of algorithms that are needed to implement the
- SSH transport layer protocol.
-
-Table of Contents
-
- 1. Contributors . . . . . . . . . . . . . . . . . . . . . . . . 3
- 2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3
- 3. Conventions Used in This Document . . . . . . . . . . . . . 3
- 4. Connection Setup . . . . . . . . . . . . . . . . . . . . . . 3
- 4.1 Use over TCP/IP . . . . . . . . . . . . . . . . . . . . . . 4
- 4.2 Protocol Version Exchange . . . . . . . . . . . . . . . . . 4
- 4.3 Compatibility With Old SSH Versions . . . . . . . . . . . . 4
- 4.3.1 Old Client, New Server . . . . . . . . . . . . . . . . . . . 5
- 4.3.2 New Client, Old Server . . . . . . . . . . . . . . . . . . . 5
- 5. Binary Packet Protocol . . . . . . . . . . . . . . . . . . . 5
- 5.1 Maximum Packet Length . . . . . . . . . . . . . . . . . . . 6
- 5.2 Compression . . . . . . . . . . . . . . . . . . . . . . . . 7
- 5.3 Encryption . . . . . . . . . . . . . . . . . . . . . . . . . 7
- 5.4 Data Integrity . . . . . . . . . . . . . . . . . . . . . . . 9
- 5.5 Key Exchange Methods . . . . . . . . . . . . . . . . . . . . 10
- 5.6 Public Key Algorithms . . . . . . . . . . . . . . . . . . . 11
- 6. Key Exchange . . . . . . . . . . . . . . . . . . . . . . . . 13
- 6.1 Algorithm Negotiation . . . . . . . . . . . . . . . . . . . 13
- 6.2 Output from Key Exchange . . . . . . . . . . . . . . . . . . 16
- 6.3 Taking Keys Into Use . . . . . . . . . . . . . . . . . . . . 17
- 7. Diffie-Hellman Key Exchange . . . . . . . . . . . . . . . . 18
- 7.1 diffie-hellman-group1-sha1 . . . . . . . . . . . . . . . . . 19
- 8. Key Re-Exchange . . . . . . . . . . . . . . . . . . . . . . 20
- 9. Service Request . . . . . . . . . . . . . . . . . . . . . . 21
- 10. Additional Messages . . . . . . . . . . . . . . . . . . . . 21
- 10.1 Disconnection Message . . . . . . . . . . . . . . . . . . . 22
- 10.2 Ignored Data Message . . . . . . . . . . . . . . . . . . . . 22
- 10.3 Debug Message . . . . . . . . . . . . . . . . . . . . . . . 23
- 10.4 Reserved Messages . . . . . . . . . . . . . . . . . . . . . 23
- 11. Summary of Message Numbers . . . . . . . . . . . . . . . . . 23
- 12. IANA Considerations . . . . . . . . . . . . . . . . . . . . 24
- 13. Security Considerations . . . . . . . . . . . . . . . . . . 24
- 14. Intellectual Property . . . . . . . . . . . . . . . . . . . 24
- 15. Additional Information . . . . . . . . . . . . . . . . . . . 24
- Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 26
- Normative . . . . . . . . . . . . . . . . . . . . . . . . . 25
- Informative . . . . . . . . . . . . . . . . . . . . . . . . 25
- A. Contibutors . . . . . . . . . . . . . . . . . . . . . . . . 27
- Intellectual Property and Copyright Statements . . . . . . . 28
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 2]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
-1. Contributors
-
- The major original contributors of this document were: Tatu Ylonen,
- Tero Kivinen, Timo J. Rinne, Sami Lehtinen (all of SSH Communications
- Security Corp), and Markku-Juhani O. Saarinen (University of
- Jyvaskyla)
-
- The document editor is: [email protected]. Comments on this
- internet draft should be sent to the IETF SECSH working group,
- details at: http://ietf.org/html.charters/secsh-charter.html
-
-2. Introduction
-
- The SSH transport layer is a secure low level transport protocol. It
- provides strong encryption, cryptographic host authentication, and
- integrity protection.
-
- Authentication in this protocol level is host-based; this protocol
- does not perform user authentication. A higher level protocol for
- user authentication can be designed on top of this protocol.
-
- The protocol has been designed to be simple, flexible, to allow
- parameter negotiation, and to minimize the number of round-trips.
- Key exchange method, public key algorithm, symmetric encryption
- algorithm, message authentication algorithm, and hash algorithm are
- all negotiated. It is expected that in most environments, only 2
- round-trips will be needed for full key exchange, server
- authentication, service request, and acceptance notification of
- service request. The worst case is 3 round-trips.
-
-3. Conventions Used in This Document
-
- The keywords "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT",
- and "MAY" that appear in this document are to be interpreted as
- described in [RFC2119].
-
- The used data types and terminology are specified in the architecture
- document [SSH-ARCH].
-
- The architecture document also discusses the algorithm naming
- conventions that MUST be used with the SSH protocols.
-
-4. Connection Setup
-
- SSH works over any 8-bit clean, binary-transparent transport. The
- underlying transport SHOULD protect against transmission errors as
- such errors cause the SSH connection to terminate.
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 3]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- The client initiates the connection.
-
-4.1 Use over TCP/IP
-
- When used over TCP/IP, the server normally listens for connections on
- port 22. This port number has been registered with the IANA, and has
- been officially assigned for SSH.
-
-4.2 Protocol Version Exchange
-
- When the connection has been established, both sides MUST send an
- identification string of the form "SSH-protoversion-softwareversion
- comments", followed by carriage return and newline characters (ASCII
- 13 and 10, respectively). Both sides MUST be able to process
- identification strings without carriage return character. No null
- character is sent. The maximum length of the string is 255
- characters, including the carriage return and newline.
-
- The part of the identification string preceding carriage return and
- newline is used in the Diffie-Hellman key exchange (see Section
- Section 7).
-
- The server MAY send other lines of data before sending the version
- string. Each line SHOULD be terminated by a carriage return and
- newline. Such lines MUST NOT begin with "SSH-", and SHOULD be
- encoded in ISO-10646 UTF-8 [RFC2279] (language is not specified).
- Clients MUST be able to process such lines; they MAY be silently
- ignored, or MAY be displayed to the client user; if they are
- displayed, control character filtering discussed in [SSH-ARCH] SHOULD
- be used. The primary use of this feature is to allow TCP-wrappers to
- display an error message before disconnecting.
-
- Version strings MUST consist of printable US-ASCII characters, not
- including whitespaces or a minus sign (-). The version string is
- primarily used to trigger compatibility extensions and to indicate
- the capabilities of an implementation. The comment string should
- contain additional information that might be useful in solving user
- problems.
-
- The protocol version described in this document is 2.0.
-
- Key exchange will begin immediately after sending this identifier.
- All packets following the identification string SHALL use the binary
- packet protocol, to be described below.
-
-4.3 Compatibility With Old SSH Versions
-
- During the transition period, it is important to be able to work in a
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 4]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- way that is compatible with the installed SSH clients and servers
- that use an older version of the protocol. Information in this
- section is only relevant for implementations supporting compatibility
- with SSH versions 1.x. There is no standards track or informational
- draft available that defines the SSH 1.x protocol. The only known
- documentation of the 1.x protocol is contained in README files that
- are shipped along with the source code.
-
-4.3.1 Old Client, New Server
-
- Server implementations MAY support a configurable "compatibility"
- flag that enables compatibility with old versions. When this flag is
- on, the server SHOULD identify its protocol version as "1.99".
- Clients using protocol 2.0 MUST be able to identify this as identical
- to "2.0". In this mode the server SHOULD NOT send the carriage
- return character (ASCII 13) after the version identification string.
-
- In the compatibility mode the server SHOULD NOT send any further data
- after its initialization string until it has received an
- identification string from the client. The server can then determine
- whether the client is using an old protocol, and can revert to the
- old protocol if required. In the compatibility mode, the server MUST
- NOT send additional data before the version string.
-
- When compatibility with old clients is not needed, the server MAY
- send its initial key exchange data immediately after the
- identification string.
-
-4.3.2 New Client, Old Server
-
- Since the new client MAY immediately send additional data after its
- identification string (before receiving server's identification), the
- old protocol may already have been corrupted when the client learns
- that the server is old. When this happens, the client SHOULD close
- the connection to the server, and reconnect using the old protocol.
-
-5. Binary Packet Protocol
-
- Each packet is in the following format:
-
- uint32 packet_length
- byte padding_length
- byte[n1] payload; n1 = packet_length - padding_length - 1
- byte[n2] random padding; n2 = padding_length
- byte[m] mac (message authentication code); m = mac_length
-
- packet_length
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 5]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- The length of the packet (bytes), not including MAC or the
- packet_length field itself.
-
- padding_length
- Length of padding (bytes).
-
- payload
- The useful contents of the packet. If compression has been
- negotiated, this field is compressed. Initially, compression
- MUST be "none".
-
- random padding
- Arbitrary-length padding, such that the total length of
- (packet_length || padding_length || payload || padding) is a
- multiple of the cipher block size or 8, whichever is larger.
- There MUST be at least four bytes of padding. The padding
- SHOULD consist of random bytes. The maximum amount of padding
- is 255 bytes.
-
- mac
- Message authentication code. If message authentication has
- been negotiated, this field contains the MAC bytes. Initially,
- the MAC algorithm MUST be "none".
-
-
- Note that length of the concatenation of packet length, padding
- length, payload, and padding MUST be a multiple of the cipher block
- size or 8, whichever is larger. This constraint MUST be enforced
- even when using stream ciphers. Note that the packet length field is
- also encrypted, and processing it requires special care when sending
- or receiving packets.
-
- The minimum size of a packet is 16 (or the cipher block size,
- whichever is larger) bytes (plus MAC); implementations SHOULD decrypt
- the length after receiving the first 8 (or cipher block size,
- whichever is larger) bytes of a packet.
-
-5.1 Maximum Packet Length
-
- All implementations MUST be able to process packets with uncompressed
- payload length of 32768 bytes or less and total packet size of 35000
- bytes or less (including length, padding length, payload, padding,
- and MAC.). The maximum of 35000 bytes is an arbitrary chosen value
- larger than uncompressed size. Implementations SHOULD support longer
- packets, where they might be needed, e.g. if an implementation wants
- to send a very large number of certificates. Such packets MAY be
- sent if the version string indicates that the other party is able to
- process them. However, implementations SHOULD check that the packet
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 6]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- length is reasonable for the implementation to avoid
- denial-of-service and/or buffer overflow attacks.
-
-5.2 Compression
-
- If compression has been negotiated, the payload field (and only it)
- will be compressed using the negotiated algorithm. The length field
- and MAC will be computed from the compressed payload. Encryption will
- be done after compression.
-
- Compression MAY be stateful, depending on the method. Compression
- MUST be independent for each direction, and implementations MUST
- allow independently choosing the algorithm for each direction.
-
- The following compression methods are currently defined:
-
- none REQUIRED no compression
- zlib OPTIONAL ZLIB (LZ77) compression
-
- The "zlib" compression is described in [RFC1950] and in [RFC1951].
- The compression context is initialized after each key exchange, and
- is passed from one packet to the next with only a partial flush being
- performed at the end of each packet. A partial flush means that the
- current compressed block is ended and all data will be output. If the
- current block is not a stored block, one or more empty blocks are
- added after the current block to ensure that there are at least 8
- bits counting from the start of the end-of-block code of the current
- block to the end of the packet payload.
-
- Additional methods may be defined as specified in [SSH-ARCH].
-
-5.3 Encryption
-
- An encryption algorithm and a key will be negotiated during the key
- exchange. When encryption is in effect, the packet length, padding
- length, payload and padding fields of each packet MUST be encrypted
- with the given algorithm.
-
- The encrypted data in all packets sent in one direction SHOULD be
- considered a single data stream. For example, initialization vectors
- SHOULD be passed from the end of one packet to the beginning of the
- next packet. All ciphers SHOULD use keys with an effective key length
- of 128 bits or more.
-
- The ciphers in each direction MUST run independently of each other,
- and implementations MUST allow independently choosing the algorithm
- for each direction (if multiple algorithms are allowed by local
- policy).
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 7]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- The following ciphers are currently defined:
-
- 3des-cbc REQUIRED three-key 3DES in CBC mode
- blowfish-cbc OPTIONALi Blowfish in CBC mode
- twofish256-cbc OPTIONAL Twofish in CBC mode,
- with 256-bit key
- twofish-cbc OPTIONAL alias for "twofish256-cbc" (this
- is being retained for
- historical reasons)
- twofish192-cbc OPTIONAL Twofish with 192-bit key
- twofish128-cbc OPTIONAL Twofish with 128-bit key
- aes256-cbc OPTIONAL AES (Rijndael) in CBC mode,
- with 256-bit key
- aes192-cbc OPTIONAL AES with 192-bit key
- aes128-cbc RECOMMENDED AES with 128-bit key
- serpent256-cbc OPTIONAL Serpent in CBC mode, with
- 256-bit key
- serpent192-cbc OPTIONAL Serpent with 192-bit key
- serpent128-cbc OPTIONAL Serpent with 128-bit key
- arcfour OPTIONAL the ARCFOUR stream cipher
- idea-cbc OPTIONAL IDEA in CBC mode
- cast128-cbc OPTIONAL CAST-128 in CBC mode
- none OPTIONAL no encryption; NOT RECOMMENDED
-
- The "3des-cbc" cipher is three-key triple-DES
- (encrypt-decrypt-encrypt), where the first 8 bytes of the key are
- used for the first encryption, the next 8 bytes for the decryption,
- and the following 8 bytes for the final encryption. This requires 24
- bytes of key data (of which 168 bits are actually used). To
- implement CBC mode, outer chaining MUST be used (i.e., there is only
- one initialization vector). This is a block cipher with 8 byte
- blocks. This algorithm is defined in [FIPS-46-3]
-
- The "blowfish-cbc" cipher is Blowfish in CBC mode, with 128 bit keys
- [SCHNEIER]. This is a block cipher with 8 byte blocks.
-
- The "twofish-cbc" or "twofish256-cbc" cipher is Twofish in CBC mode,
- with 256 bit keys as described [TWOFISH]. This is a block cipher with
- 16 byte blocks.
-
- The "twofish192-cbc" cipher. Same as above but with 192-bit key.
-
- The "twofish128-cbc" cipher. Same as above but with 128-bit key.
-
- The "aes256-cbc" cipher is AES (Advanced Encryption Standard)
- [FIPS-197], formerly Rijndael, in CBC mode. This version uses 256-bit
- key.
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 8]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- The "aes192-cbc" cipher. Same as above but with 192-bit key.
-
- The "aes128-cbc" cipher. Same as above but with 128-bit key.
-
- The "serpent256-cbc" cipher in CBC mode, with 256-bit key as
- described in the Serpent AES submission.
-
- The "serpent192-cbc" cipher. Same as above but with 192-bit key.
-
- The "serpent128-cbc" cipher. Same as above but with 128-bit key.
-
- The "arcfour" is the Arcfour stream cipher with 128 bit keys. The
- Arcfour cipher is believed to be compatible with the RC4 cipher
- [SCHNEIER]. RC4 is a registered trademark of RSA Data Security Inc.
- Arcfour (and RC4) has problems with weak keys, and should be used
- with caution.
-
- The "idea-cbc" cipher is the IDEA cipher in CBC mode [SCHNEIER].
-
- The "cast128-cbc" cipher is the CAST-128 cipher in CBC mode
- [RFC2144].
-
- The "none" algorithm specifies that no encryption is to be done.
- Note that this method provides no confidentiality protection, and it
- is not recommended. Some functionality (e.g. password
- authentication) may be disabled for security reasons if this cipher
- is chosen.
-
- Additional methods may be defined as specified in [SSH-ARCH].
-
-5.4 Data Integrity
-
- Data integrity is protected by including with each packet a message
- authentication code (MAC) that is computed from a shared secret,
- packet sequence number, and the contents of the packet.
-
- The message authentication algorithm and key are negotiated during
- key exchange. Initially, no MAC will be in effect, and its length
- MUST be zero. After key exchange, the selected MAC will be computed
- before encryption from the concatenation of packet data:
-
- mac = MAC(key, sequence_number || unencrypted_packet)
-
- where unencrypted_packet is the entire packet without MAC (the length
- fields, payload and padding), and sequence_number is an implicit
- packet sequence number represented as uint32. The sequence number is
- initialized to zero for the first packet, and is incremented after
- every packet (regardless of whether encryption or MAC is in use). It
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 9]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- is never reset, even if keys/algorithms are renegotiated later. It
- wraps around to zero after every 2^32 packets. The packet sequence
- number itself is not included in the packet sent over the wire.
-
- The MAC algorithms for each direction MUST run independently, and
- implementations MUST allow choosing the algorithm independently for
- both directions.
-
- The MAC bytes resulting from the MAC algorithm MUST be transmitted
- without encryption as the last part of the packet. The number of MAC
- bytes depends on the algorithm chosen.
-
- The following MAC algorithms are currently defined:
-
- hmac-sha1 REQUIRED HMAC-SHA1 (digest length = key
- length = 20)
- hmac-sha1-96 RECOMMENDED first 96 bits of HMAC-SHA1 (digest
- length = 12, key length = 20)
- hmac-md5 OPTIONAL HMAC-MD5 (digest length = key
- length = 16)
- hmac-md5-96 OPTIONAL first 96 bits of HMAC-MD5 (digest
- length = 12, key length = 16)
- none OPTIONAL no MAC; NOT RECOMMENDED
-
- Figure 1
-
- The "hmac-*" algorithms are described in [RFC2104] The "*-n" MACs use
- only the first n bits of the resulting value.
-
- The hash algorithms are described in [SCHNEIER].
-
- Additional methods may be defined as specified in [SSH-ARCH].
-
-5.5 Key Exchange Methods
-
- The key exchange method specifies how one-time session keys are
- generated for encryption and for authentication, and how the server
- authentication is done.
-
- Only one REQUIRED key exchange method has been defined:
-
- diffie-hellman-group1-sha1 REQUIRED
-
- This method is described later in this document.
-
- Additional methods may be defined as specified in [SSH-ARCH].
-
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 10]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
-5.6 Public Key Algorithms
-
- This protocol has been designed to be able to operate with almost any
- public key format, encoding, and algorithm (signature and/or
- encryption).
-
- There are several aspects that define a public key type:
- o Key format: how is the key encoded and how are certificates
- represented. The key blobs in this protocol MAY contain
- certificates in addition to keys.
- o Signature and/or encryption algorithms. Some key types may not
- support both signing and encryption. Key usage may also be
- restricted by policy statements in e.g. certificates. In this
- case, different key types SHOULD be defined for the different
- policy alternatives.
- o Encoding of signatures and/or encrypted data. This includes but is
- not limited to padding, byte order, and data formats.
-
- The following public key and/or certificate formats are currently defined:
-
- ssh-dss REQUIRED sign Raw DSS Key
- ssh-rsa RECOMMENDED sign Raw RSA Key
- x509v3-sign-rsa OPTIONAL sign X.509 certificates (RSA key)
- x509v3-sign-dss OPTIONAL sign X.509 certificates (DSS key)
- spki-sign-rsa OPTIONAL sign SPKI certificates (RSA key)
- spki-sign-dss OPTIONAL sign SPKI certificates (DSS key)
- pgp-sign-rsa OPTIONAL sign OpenPGP certificates (RSA key)
- pgp-sign-dss OPTIONAL sign OpenPGP certificates (DSS key)
-
- Additional key types may be defined as specified in [SSH-ARCH].
-
- The key type MUST always be explicitly known (from algorithm
- negotiation or some other source). It is not normally included in
- the key blob.
-
- Certificates and public keys are encoded as follows:
-
- string certificate or public key format identifier
- byte[n] key/certificate data
-
- The certificate part may have be a zero length string, but a public
- key is required. This is the public key that will be used for
- authentication; the certificate sequence contained in the certificate
- blob can be used to provide authorization.
-
- Public key / certifcate formats that do not explicitly specify a
- signature format identifier MUST use the public key / certificate
- format identifier as the signature identifier.
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 11]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- Signatures are encoded as follows:
- string signature format identifier (as specified by the
- public key / cert format)
- byte[n] signature blob in format specific encoding.
-
-
- The "ssh-dss" key format has the following specific encoding:
-
- string "ssh-dss"
- mpint p
- mpint q
- mpint g
- mpint y
-
- Here the p, q, g, and y parameters form the signature key blob.
-
- Signing and verifying using this key format is done according to the
- Digital Signature Standard [FIPS-186] using the SHA-1 hash. A
- description can also be found in [SCHNEIER].
-
- The resulting signature is encoded as follows:
-
- string "ssh-dss"
- string dss_signature_blob
-
- dss_signature_blob is encoded as a string containing r followed by s
- (which are 160 bits long integers, without lengths or padding,
- unsigned and in network byte order).
-
- The "ssh-rsa" key format has the following specific encoding:
-
- string "ssh-rsa"
- mpint e
- mpint n
-
- Here the e and n parameters form the signature key blob.
-
- Signing and verifying using this key format is done according to
- [SCHNEIER] and [PKCS1] using the SHA-1 hash.
-
- The resulting signature is encoded as follows:
-
- string "ssh-rsa"
- string rsa_signature_blob
-
- rsa_signature_blob is encoded as a string containing s (which is an
- integer, without lengths or padding, unsigned and in network byte
- order).
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 12]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- The "spki-sign-rsa" method indicates that the certificate blob
- contains a sequence of SPKI certificates. The format of SPKI
- certificates is described in [RFC2693]. This method indicates that
- the key (or one of the keys in the certificate) is an RSA-key.
-
- The "spki-sign-dss". As above, but indicates that the key (or one of
- the keys in the certificate) is a DSS-key.
-
- The "pgp-sign-rsa" method indicates the certificates, the public key,
- and the signature are in OpenPGP compatible binary format
- ([RFC2440]). This method indicates that the key is an RSA-key.
-
- The "pgp-sign-dss". As above, but indicates that the key is a
- DSS-key.
-
-6. Key Exchange
-
- Key exchange begins by each side sending lists of supported
- algorithms. Each side has a preferred algorithm in each category, and
- it is assumed that most implementations at any given time will use
- the same preferred algorithm. Each side MAY guess which algorithm
- the other side is using, and MAY send an initial key exchange packet
- according to the algorithm if appropriate for the preferred method.
-
- Guess is considered wrong, if:
- o the kex algorithm and/or the host key algorithm is guessed wrong
- (server and client have different preferred algorithm), or
- o if any of the other algorithms cannot be agreed upon (the
- procedure is defined below in Section Section 6.1).
-
- Otherwise, the guess is considered to be right and the optimistically
- sent packet MUST be handled as the first key exchange packet.
-
- However, if the guess was wrong, and a packet was optimistically sent
- by one or both parties, such packets MUST be ignored (even if the
- error in the guess would not affect the contents of the initial
- packet(s)), and the appropriate side MUST send the correct initial
- packet.
-
- Server authentication in the key exchange MAY be implicit. After a
- key exchange with implicit server authentication, the client MUST
- wait for response to its service request message before sending any
- further data.
-
-6.1 Algorithm Negotiation
-
- Key exchange begins by each side sending the following packet:
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 13]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- byte SSH_MSG_KEXINIT
- byte[16] cookie (random bytes)
- string kex_algorithms
- string server_host_key_algorithms
- string encryption_algorithms_client_to_server
- string encryption_algorithms_server_to_client
- string mac_algorithms_client_to_server
- string mac_algorithms_server_to_client
- string compression_algorithms_client_to_server
- string compression_algorithms_server_to_client
- string languages_client_to_server
- string languages_server_to_client
- boolean first_kex_packet_follows
- uint32 0 (reserved for future extension)
-
- Each of the algorithm strings MUST be a comma-separated list of
- algorithm names (see ''Algorithm Naming'' in [SSH-ARCH]). Each
- supported (allowed) algorithm MUST be listed in order of preference.
-
- The first algorithm in each list MUST be the preferred (guessed)
- algorithm. Each string MUST contain at least one algorithm name.
-
-
- cookie
- The cookie MUST be a random value generated by the sender. Its
- purpose is to make it impossible for either side to fully
- determine the keys and the session identifier.
-
- kex_algorithms
- Key exchange algorithms were defined above. The first
- algorithm MUST be the preferred (and guessed) algorithm. If
- both sides make the same guess, that algorithm MUST be used.
- Otherwise, the following algorithm MUST be used to choose a key
- exchange method: iterate over client's kex algorithms, one at a
- time. Choose the first algorithm that satisfies the following
- conditions:
- + the server also supports the algorithm,
- + if the algorithm requires an encryption-capable host key,
- there is an encryption-capable algorithm on the server's
- server_host_key_algorithms that is also supported by the
- client, and
- + if the algorithm requires a signature-capable host key,
- there is a signature-capable algorithm on the server's
- server_host_key_algorithms that is also supported by the
- client.
- + If no algorithm satisfying all these conditions can be
- found, the connection fails, and both sides MUST disconnect.
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 14]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- server_host_key_algorithms
- List of the algorithms supported for the server host key. The
- server lists the algorithms for which it has host keys; the
- client lists the algorithms that it is willing to accept.
- (There MAY be multiple host keys for a host, possibly with
- different algorithms.)
-
- Some host keys may not support both signatures and encryption
- (this can be determined from the algorithm), and thus not all
- host keys are valid for all key exchange methods.
-
- Algorithm selection depends on whether the chosen key exchange
- algorithm requires a signature or encryption capable host key.
- It MUST be possible to determine this from the public key
- algorithm name. The first algorithm on the client's list that
- satisfies the requirements and is also supported by the server
- MUST be chosen. If there is no such algorithm, both sides MUST
- disconnect.
-
- encryption_algorithms
- Lists the acceptable symmetric encryption algorithms in order
- of preference. The chosen encryption algorithm to each
- direction MUST be the first algorithm on the client's list
- that is also on the server's list. If there is no such
- algorithm, both sides MUST disconnect.
-
- Note that "none" must be explicitly listed if it is to be
- acceptable. The defined algorithm names are listed in Section
- Section 5.3.
-
- mac_algorithms
- Lists the acceptable MAC algorithms in order of preference.
- The chosen MAC algorithm MUST be the first algorithm on the
- client's list that is also on the server's list. If there is
- no such algorithm, both sides MUST disconnect.
-
- Note that "none" must be explicitly listed if it is to be
- acceptable. The MAC algorithm names are listed in Section
- Figure 1.
-
- compression_algorithms
- Lists the acceptable compression algorithms in order of
- preference. The chosen compression algorithm MUST be the first
- algorithm on the client's list that is also on the server's
- list. If there is no such algorithm, both sides MUST
- disconnect.
-
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 15]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- Note that "none" must be explicitly listed if it is to be
- acceptable. The compression algorithm names are listed in
- Section Section 5.2.
-
- languages
- This is a comma-separated list of language tags in order of
- preference [RFC3066]. Both parties MAY ignore this list. If
- there are no language preferences, this list SHOULD be empty.
- Language tags SHOULD NOT be present unless they are known to be
- needed by the sending party.
-
- first_kex_packet_follows
- Indicates whether a guessed key exchange packet follows. If a
- guessed packet will be sent, this MUST be TRUE. If no guessed
- packet will be sent, this MUST be FALSE.
-
- After receiving the SSH_MSG_KEXINIT packet from the other side,
- each party will know whether their guess was right. If the
- other party's guess was wrong, and this field was TRUE, the
- next packet MUST be silently ignored, and both sides MUST then
- act as determined by the negotiated key exchange method. If
- the guess was right, key exchange MUST continue using the
- guessed packet.
-
- After the KEXINIT packet exchange, the key exchange algorithm is run.
- It may involve several packet exchanges, as specified by the key
- exchange method.
-
-6.2 Output from Key Exchange
-
- The key exchange produces two values: a shared secret K, and an
- exchange hash H. Encryption and authentication keys are derived from
- these. The exchange hash H from the first key exchange is
- additionally used as the session identifier, which is a unique
- identifier for this connection. It is used by authentication methods
- as a part of the data that is signed as a proof of possession of a
- private key. Once computed, the session identifier is not changed,
- even if keys are later re-exchanged.
-
-
- Each key exchange method specifies a hash function that is used in
- the key exchange. The same hash algorithm MUST be used in key
- derivation. Here, we'll call it HASH.
-
-
- Encryption keys MUST be computed as HASH of a known value and K as
- follows:
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 16]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- o Initial IV client to server: HASH(K || H || "A" || session_id)
- (Here K is encoded as mpint and "A" as byte and session_id as raw
- data."A" means the single character A, ASCII 65).
- o Initial IV server to client: HASH(K || H || "B" || session_id)
- o Encryption key client to server: HASH(K || H || "C" || session_id)
- o Encryption key server to client: HASH(K || H || "D" || session_id)
- o Integrity key client to server: HASH(K || H || "E" || session_id)
- o Integrity key server to client: HASH(K || H || "F" || session_id)
-
- Key data MUST be taken from the beginning of the hash output. 128
- bits (16 bytes) MUST be used for algorithms with variable-length
- keys. The only variable key length algorithm defined in this document
- is arcfour). For other algorithms, as many bytes as are needed are
- taken from the beginning of the hash value. If the key length needed
- is longer than the output of the HASH, the key is extended by
- computing HASH of the concatenation of K and H and the entire key so
- far, and appending the resulting bytes (as many as HASH generates) to
- the key. This process is repeated until enough key material is
- available; the key is taken from the beginning of this value. In
- other words:
-
- K1 = HASH(K || H || X || session_id) (X is e.g. "A")
- K2 = HASH(K || H || K1)
- K3 = HASH(K || H || K1 || K2)
- ...
- key = K1 || K2 || K3 || ...
-
- This process will lose entropy if the amount of entropy in K is
- larger than the internal state size of HASH.
-
-6.3 Taking Keys Into Use
-
- Key exchange ends by each side sending an SSH_MSG_NEWKEYS message.
- This message is sent with the old keys and algorithms. All messages
- sent after this message MUST use the new keys and algorithms.
-
-
- When this message is received, the new keys and algorithms MUST be
- taken into use for receiving.
-
-
- This message is the only valid message after key exchange, in
- addition to SSH_MSG_DEBUG, SSH_MSG_DISCONNECT and SSH_MSG_IGNORE
- messages. The purpose of this message is to ensure that a party is
- able to respond with a disconnect message that the other party can
- understand if something goes wrong with the key exchange.
- Implementations MUST NOT accept any other messages after key exchange
- before receiving SSH_MSG_NEWKEYS.
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 17]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- byte SSH_MSG_NEWKEYS
-
-
-7. Diffie-Hellman Key Exchange
-
- The Diffie-Hellman key exchange provides a shared secret that can not
- be determined by either party alone. The key exchange is combined
- with a signature with the host key to provide host authentication.
-
-
- In the following description (C is the client, S is the server; p is
- a large safe prime, g is a generator for a subgroup of GF(p), and q
- is the order of the subgroup; V_S is S's version string; V_C is C's
- version string; K_S is S's public host key; I_C is C's KEXINIT
- message and I_S S's KEXINIT message which have been exchanged before
- this part begins):
-
-
- 1. C generates a random number x (1 < x < q) and computes e = g^x
- mod p. C sends "e" to S.
-
- 2. S generates a random number y (0 < y < q) and computes f = g^y
- mod p. S receives "e". It computes K = e^y mod p, H = hash(V_C
- || V_S || I_C || I_S || K_S || e || f || K) (these elements are
- encoded according to their types; see below), and signature s on
- H with its private host key. S sends "K_S || f || s" to C. The
- signing operation may involve a second hashing operation.
-
- 3. C verifies that K_S really is the host key for S (e.g. using
- certificates or a local database). C is also allowed to accept
- the key without verification; however, doing so will render the
- protocol insecure against active attacks (but may be desirable
- for practical reasons in the short term in many environments). C
- then computes K = f^x mod p, H = hash(V_C || V_S || I_C || I_S ||
- K_S || e || f || K), and verifies the signature s on H.
-
- Either side MUST NOT send or accept e or f values that are not in the
- range [1, p-1]. If this condition is violated, the key exchange
- fails.
-
-
- This is implemented with the following messages. The hash algorithm
- for computing the exchange hash is defined by the method name, and is
- called HASH. The public key algorithm for signing is negotiated with
- the KEXINIT messages.
-
- First, the client sends the following:
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 18]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- byte SSH_MSG_KEXDH_INIT
- mpint e
-
-
- The server responds with the following:
-
- byte SSH_MSG_KEXDH_REPLY
- string server public host key and certificates (K_S)
- mpint f
- string signature of H
-
- The hash H is computed as the HASH hash of the concatenation of the
- following:
-
- string V_C, the client's version string (CR and NL excluded)
- string V_S, the server's version string (CR and NL excluded)
- string I_C, the payload of the client's SSH_MSG_KEXINIT
- string I_S, the payload of the server's SSH_MSG_KEXINIT
- string K_S, the host key
- mpint e, exchange value sent by the client
- mpint f, exchange value sent by the server
- mpint K, the shared secret
-
- This value is called the exchange hash, and it is used to
- authenticate the key exchange. The exchange hash SHOULD be kept
- secret.
-
-
- The signature algorithm MUST be applied over H, not the original
- data. Most signature algorithms include hashing and additional
- padding. For example, "ssh-dss" specifies SHA-1 hashing; in that
- case, the data is first hashed with HASH to compute H, and H is then
- hashed with SHA-1 as part of the signing operation.
-
-7.1 diffie-hellman-group1-sha1
-
- The "diffie-hellman-group1-sha1" method specifies Diffie-Hellman key
- exchange with SHA-1 as HASH, and Oakley group 14 [RFC3526] (2048-bit
- MODP Group). It is included below in hexadecimal and decimal.
-
- The prime p is equal to 2^1024 - 2^960 - 1 + 2^64 * floor( 2^894 Pi +
- 129093 ). Its hexadecimal value is:
-
- FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1
- 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD
- EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245
- E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED
- EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 19]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- FFFFFFFF FFFFFFFF.
-
- In decimal, this value is:
-
- 179769313486231590770839156793787453197860296048756011706444
- 423684197180216158519368947833795864925541502180565485980503
- 646440548199239100050792877003355816639229553136239076508735
- 759914822574862575007425302077447712589550957937778424442426
- 617334727629299387668709205606050270810842907692932019128194
- 467627007.
-
- The generator used with this prime is g = 2. The group order q is (p
- - 1) / 2.
-
-8. Key Re-Exchange
-
- Key re-exchange is started by sending an SSH_MSG_KEXINIT packet when
- not already doing a key exchange (as described in Section Section
- 6.1). When this message is received, a party MUST respond with its
- own SSH_MSG_KEXINIT message except when the received SSH_MSG_KEXINIT
- already was a reply. Either party MAY initiate the re-exchange, but
- roles MUST NOT be changed (i.e., the server remains the server, and
- the client remains the client).
-
-
- Key re-exchange is performed using whatever encryption was in effect
- when the exchange was started. Encryption, compression, and MAC
- methods are not changed before a new SSH_MSG_NEWKEYS is sent after
- the key exchange (as in the initial key exchange). Re-exchange is
- processed identically to the initial key exchange, except for the
- session identifier that will remain unchanged. It is permissible to
- change some or all of the algorithms during the re-exchange. Host
- keys can also change. All keys and initialization vectors are
- recomputed after the exchange. Compression and encryption contexts
- are reset.
-
-
- It is recommended that the keys are changed after each gigabyte of
- transmitted data or after each hour of connection time, whichever
- comes sooner. However, since the re-exchange is a public key
- operation, it requires a fair amount of processing power and should
- not be performed too often.
-
-
- More application data may be sent after the SSH_MSG_NEWKEYS packet
- has been sent; key exchange does not affect the protocols that lie
- above the SSH transport layer.
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 20]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
-9. Service Request
-
- After the key exchange, the client requests a service. The service is
- identified by a name. The format of names and procedures for defining
- new names are defined in [SSH-ARCH].
-
-
- Currently, the following names have been reserved:
-
- ssh-userauth
- ssh-connection
-
- Similar local naming policy is applied to the service names, as is
- applied to the algorithm names; a local service should use the
- "servicename@domain" syntax.
-
- byte SSH_MSG_SERVICE_REQUEST
- string service name
-
- If the server rejects the service request, it SHOULD send an
- appropriate SSH_MSG_DISCONNECT message and MUST disconnect.
-
-
- When the service starts, it may have access to the session identifier
- generated during the key exchange.
-
-
- If the server supports the service (and permits the client to use
- it), it MUST respond with the following:
-
- byte SSH_MSG_SERVICE_ACCEPT
- string service name
-
- Message numbers used by services should be in the area reserved for
- them (see Section 6 in [SSH-ARCH]). The transport level will
- continue to process its own messages.
-
-
- Note that after a key exchange with implicit server authentication,
- the client MUST wait for response to its service request message
- before sending any further data.
-
-10. Additional Messages
-
- Either party may send any of the following messages at any time.
-
-
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 21]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
-10.1 Disconnection Message
-
- byte SSH_MSG_DISCONNECT
- uint32 reason code
- string description [RFC2279]
- string language tag [RFC3066]
-
- This message causes immediate termination of the connection. All
- implementations MUST be able to process this message; they SHOULD be
- able to send this message.
-
- The sender MUST NOT send or receive any data after this message, and
- the recipient MUST NOT accept any data after receiving this message.
- The description field gives a more specific explanation in a
- human-readable form. The error code gives the reason in a more
- machine-readable format (suitable for localization), and can have the
- following values:
-
- #define SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT 1
- #define SSH_DISCONNECT_PROTOCOL_ERROR 2
- #define SSH_DISCONNECT_KEY_EXCHANGE_FAILED 3
- #define SSH_DISCONNECT_RESERVED 4
- #define SSH_DISCONNECT_MAC_ERROR 5
- #define SSH_DISCONNECT_COMPRESSION_ERROR 6
- #define SSH_DISCONNECT_SERVICE_NOT_AVAILABLE 7
- #define SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED 8
- #define SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE 9
- #define SSH_DISCONNECT_CONNECTION_LOST 10
- #define SSH_DISCONNECT_BY_APPLICATION 11
- #define SSH_DISCONNECT_TOO_MANY_CONNECTIONS 12
- #define SSH_DISCONNECT_AUTH_CANCELLED_BY_USER 13
- #define SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE 14
- #define SSH_DISCONNECT_ILLEGAL_USER_NAME 15
-
- If the description string is displayed, control character filtering
- discussed in [SSH-ARCH] should be used to avoid attacks by sending
- terminal control characters.
-
-10.2 Ignored Data Message
-
- byte SSH_MSG_IGNORE
- string data
-
- All implementations MUST understand (and ignore) this message at any
- time (after receiving the protocol version). No implementation is
- required to send them. This message can be used as an additional
- protection measure against advanced traffic analysis techniques.
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 22]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
-10.3 Debug Message
-
- byte SSH_MSG_DEBUG
- boolean always_display
- string message [RFC2279]
- string language tag [RFC3066]
-
- All implementations MUST understand this message, but they are
- allowed to ignore it. This message is used to pass the other side
- information that may help debugging. If always_display is TRUE, the
- message SHOULD be displayed. Otherwise, it SHOULD NOT be displayed
- unless debugging information has been explicitly requested by the
- user.
-
-
- The message doesn't need to contain a newline. It is, however,
- allowed to consist of multiple lines separated by CRLF (Carriage
- Return - Line Feed) pairs.
-
-
- If the message string is displayed, terminal control character
- filtering discussed in [SSH-ARCH] should be used to avoid attacks by
- sending terminal control characters.
-
-10.4 Reserved Messages
-
- An implementation MUST respond to all unrecognized messages with an
- SSH_MSG_UNIMPLEMENTED message in the order in which the messages were
- received. Such messages MUST be otherwise ignored. Later protocol
- versions may define other meanings for these message types.
-
- byte SSH_MSG_UNIMPLEMENTED
- uint32 packet sequence number of rejected message
-
-
-11. Summary of Message Numbers
-
- The following message numbers have been defined in this protocol:
-
- #define SSH_MSG_DISCONNECT 1
- #define SSH_MSG_IGNORE 2
- #define SSH_MSG_UNIMPLEMENTED 3
- #define SSH_MSG_DEBUG 4
- #define SSH_MSG_SERVICE_REQUEST 5
- #define SSH_MSG_SERVICE_ACCEPT 6
-
- #define SSH_MSG_KEXINIT 20
- #define SSH_MSG_NEWKEYS 21
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 23]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- /* Numbers 30-49 used for kex packets.
- Different kex methods may reuse message numbers in
- this range. */
-
- #define SSH_MSG_KEXDH_INIT 30
- #define SSH_MSG_KEXDH_REPLY 31
-
-
-12. IANA Considerations
-
- This document is part of a set, the IANA considerations for the SSH
- protocol as defined in [SSH-ARCH], [SSH-TRANS], [SSH-USERAUTH],
- [SSH-CONNECT] are detailed in [SSH-NUMBERS].
-
-13. Security Considerations
-
- This protocol provides a secure encrypted channel over an insecure
- network. It performs server host authentication, key exchange,
- encryption, and integrity protection. It also derives a unique
- session id that may be used by higher-level protocols.
-
- Full security considerations for this protocol are provided in
- Section 8 of [SSH-ARCH]
-
-14. Intellectual Property
-
- The IETF takes no position regarding the validity or scope of any
- intellectual property or other rights that might be claimed to
- pertain to the implementation or use of the technology described in
- this document or the extent to which any license under such rights
- might or might not be available; neither does it represent that it
- has made any effort to identify any such rights. Information on the
- IETF's procedures with respect to rights in standards-track and
- standards-related documentation can be found in BCP-11. Copies of
- claims of rights made available for publication and any assurances of
- licenses to be made available, or the result of an attempt made to
- obtain a general license or permission for the use of such
- proprietary rights by implementers or users of this specification can
- be obtained from the IETF Secretariat.
-
- The IETF has been notified of intellectual property rights claimed in
- regard to some or all of the specification contained in this
- document. For more information consult the online list of claimed
- rights.
-
-15. Additional Information
-
- The current document editor is: [email protected]. Comments on
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 24]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- this internet draft should be sent to the IETF SECSH working group,
- details at: http://ietf.org/html.charters/secsh-charter.html
-
-Normative
-
- [SSH-ARCH]
- Ylonen, T., "SSH Protocol Architecture", I-D
- draft-ietf-architecture-15.txt, Oct 2003.
-
- [SSH-TRANS]
- Ylonen, T., "SSH Transport Layer Protocol", I-D
- draft-ietf-transport-17.txt, Oct 2003.
-
- [SSH-USERAUTH]
- Ylonen, T., "SSH Authentication Protocol", I-D
- draft-ietf-userauth-18.txt, Oct 2003.
-
- [SSH-CONNECT]
- Ylonen, T., "SSH Connection Protocol", I-D
- draft-ietf-connect-18.txt, Oct 2003.
-
- [SSH-NUMBERS]
- Lehtinen, S. and D. Moffat, "SSH Protocol Assigned
- Numbers", I-D draft-ietf-secsh-assignednumbers-05.txt, Oct
- 2003.
-
- [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
- Requirement Levels", BCP 14, RFC 2119, March 1997.
-
-Informative
-
- [FIPS-186]
- Federal Information Processing Standards Publication,
- "FIPS PUB 186, Digital Signature Standard", May 1994.
-
- [FIPS-197]
- NIST, "FIPS PUB 197 Advanced Encryption Standard (AES)",
- November 2001.
-
- [FIPS-46-3]
- U.S. Dept. of Commerce, "FIPS PUB 46-3, Data Encryption
- Standard (DES)", October 1999.
-
- [RFC2459] Housley, R., Ford, W., Polk, T. and D. Solo, "Internet
- X.509 Public Key Infrastructure Certificate and CRL
- Profile", RFC 2459, January 1999.
-
- [RFC1034] Mockapetris, P., "Domain names - concepts and facilities",
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 25]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- STD 13, RFC 1034, November 1987.
-
- [RFC3066] Alvestrand, H., "Tags for the Identification of
- Languages", BCP 47, RFC 3066, January 2001.
-
- [RFC1950] Deutsch, L. and J-L. Gailly, "ZLIB Compressed Data Format
- Specification version 3.3", RFC 1950, May 1996.
-
- [RFC1951] Deutsch, P., "DEFLATE Compressed Data Format Specification
- version 1.3", RFC 1951, May 1996.
-
- [RFC2279] Yergeau, F., "UTF-8, a transformation format of ISO
- 10646", RFC 2279, January 1998.
-
- [RFC2104] Krawczyk, H., Bellare, M. and R. Canetti, "HMAC:
- Keyed-Hashing for Message Authentication", RFC 2104,
- February 1997.
-
- [RFC2144] Adams, C., "The CAST-128 Encryption Algorithm", RFC 2144,
- May 1997.
-
- [RFC2440] Callas, J., Donnerhacke, L., Finney, H. and R. Thayer,
- "OpenPGP Message Format", RFC 2440, November 1998.
-
- [RFC2693] Ellison, C., Frantz, B., Lampson, B., Rivest, R., Thomas,
- B. and T. Ylonen, "SPKI Certificate Theory", RFC 2693,
- September 1999.
-
- [RFC3526] Kivinen, T. and M. Kojo, "More Modular Exponential (MODP)
- Diffie-Hellman groups for Internet Key Exchange (IKE)",
- RFC 3526, May 2003.
-
- [SCHNEIER]
- Schneier, B., "Applied Cryptography Second Edition:
- protocols algorithms and source in code in C", 1996.
-
- [TWOFISH] Schneier, B., "The Twofish Encryptions Algorithm: A
- 128-Bit Block Cipher, 1st Edition", March 1999.
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 26]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
-Authors' Addresses
-
- Tatu Ylonen
- SSH Communications Security Corp
- Fredrikinkatu 42
- HELSINKI FIN-00100
- Finland
-
-
-
- Darren J. Moffat (editor)
- Sun Microsystems, Inc
- 17 Network Circle
- Menlo Park 95025
- USA
-
-
-Appendix A. Contibutors
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 27]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
-Intellectual Property Statement
-
- The IETF takes no position regarding the validity or scope of any
- intellectual property or other rights that might be claimed to
- pertain to the implementation or use of the technology described in
- this document or the extent to which any license under such rights
- might or might not be available; neither does it represent that it
- has made any effort to identify any such rights. Information on the
- IETF's procedures with respect to rights in standards-track and
- standards-related documentation can be found in BCP-11. Copies of
- claims of rights made available for publication and any assurances of
- licenses to be made available, or the result of an attempt made to
- obtain a general license or permission for the use of such
- proprietary rights by implementors or users of this specification can
- be obtained from the IETF Secretariat.
-
- The IETF invites any interested party to bring to its attention any
- copyrights, patents or patent applications, or other proprietary
- rights which may cover technology that may be required to practice
- this standard. Please address the information to the IETF Executive
- Director.
-
- The IETF has been notified of intellectual property rights claimed in
- regard to some or all of the specification contained in this
- document. For more information consult the online list of claimed
- rights.
-
-
-Full Copyright Statement
-
- Copyright (C) The Internet Society (2003). All Rights Reserved.
-
- This document and translations of it may be copied and furnished to
- others, and derivative works that comment on or otherwise explain it
- or assist in its implementation may be prepared, copied, published
- and distributed, in whole or in part, without restriction of any
- kind, provided that the above copyright notice and this paragraph are
- included on all such copies and derivative works. However, this
- document itself may not be modified in any way, such as by removing
- the copyright notice or references to the Internet Society or other
- Internet organizations, except as needed for the purpose of
- developing Internet standards in which case the procedures for
- copyrights defined in the Internet Standards process must be
- followed, or as required to translate it into languages other than
- English.
-
- The limited permissions granted above are perpetual and will not be
- revoked by the Internet Society or its successors or assignees.
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 28]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- This document and the information contained herein is provided on an
- "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
- TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
- BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
- HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
- MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-
-Acknowledgment
-
- Funding for the RFC Editor function is currently provided by the
- Internet Society.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 29] \ No newline at end of file
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-userauth-18.2.ps b/lib/ssh/doc/standard/draft-ietf-secsh-userauth-18.2.ps
deleted file mode 100644
index be5799dbce..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-userauth-18.2.ps
+++ /dev/null
@@ -1,1881 +0,0 @@
-%!PS-Adobe-3.0
-%%BoundingBox: 75 0 595 747
-%%Title: Enscript Output
-%%For: Magnus Thoang
-%%Creator: GNU enscript 1.6.1
-%%CreationDate: Fri Oct 31 13:35:32 2003
-%%Orientation: Portrait
-%%Pages: 8 0
-%%DocumentMedia: A4 595 842 0 () ()
-%%DocumentNeededResources: (atend)
-%%EndComments
-%%BeginProlog
-%%BeginProcSet: PStoPS 1 15
-userdict begin
-[/showpage/erasepage/copypage]{dup where{pop dup load
- type/operatortype eq{1 array cvx dup 0 3 index cvx put
- bind def}{pop}ifelse}{pop}ifelse}forall
-[/letter/legal/executivepage/a4/a4small/b5/com10envelope
- /monarchenvelope/c5envelope/dlenvelope/lettersmall/note
- /folio/quarto/a5]{dup where{dup wcheck{exch{}put}
- {pop{}def}ifelse}{pop}ifelse}forall
-/setpagedevice {pop}bind 1 index where{dup wcheck{3 1 roll put}
- {pop def}ifelse}{def}ifelse
-/PStoPSmatrix matrix currentmatrix def
-/PStoPSxform matrix def/PStoPSclip{clippath}def
-/defaultmatrix{PStoPSmatrix exch PStoPSxform exch concatmatrix}bind def
-/initmatrix{matrix defaultmatrix setmatrix}bind def
-/initclip[{matrix currentmatrix PStoPSmatrix setmatrix
- [{currentpoint}stopped{$error/newerror false put{newpath}}
- {/newpath cvx 3 1 roll/moveto cvx 4 array astore cvx}ifelse]
- {[/newpath cvx{/moveto cvx}{/lineto cvx}
- {/curveto cvx}{/closepath cvx}pathforall]cvx exch pop}
- stopped{$error/errorname get/invalidaccess eq{cleartomark
- $error/newerror false put cvx exec}{stop}ifelse}if}bind aload pop
- /initclip dup load dup type dup/operatortype eq{pop exch pop}
- {dup/arraytype eq exch/packedarraytype eq or
- {dup xcheck{exch pop aload pop}{pop cvx}ifelse}
- {pop cvx}ifelse}ifelse
- {newpath PStoPSclip clip newpath exec setmatrix} bind aload pop]cvx def
-/initgraphics{initmatrix newpath initclip 1 setlinewidth
- 0 setlinecap 0 setlinejoin []0 setdash 0 setgray
- 10 setmiterlimit}bind def
-end
-%%EndProcSet
-%%BeginResource: procset Enscript-Prolog 1.6 1
-%
-% Procedures.
-%
-
-/_S { % save current state
- /_s save def
-} def
-/_R { % restore from saved state
- _s restore
-} def
-
-/S { % showpage protecting gstate
- gsave
- showpage
- grestore
-} bind def
-
-/MF { % fontname newfontname -> - make a new encoded font
- /newfontname exch def
- /fontname exch def
-
- /fontdict fontname findfont def
- /newfont fontdict maxlength dict def
-
- fontdict {
- exch
- dup /FID eq {
- % skip FID pair
- pop pop
- } {
- % copy to the new font dictionary
- exch newfont 3 1 roll put
- } ifelse
- } forall
-
- newfont /FontName newfontname put
-
- % insert only valid encoding vectors
- encoding_vector length 256 eq {
- newfont /Encoding encoding_vector put
- } if
-
- newfontname newfont definefont pop
-} def
-
-/SF { % fontname width height -> - set a new font
- /height exch def
- /width exch def
-
- findfont
- [width 0 0 height 0 0] makefont setfont
-} def
-
-/SUF { % fontname width height -> - set a new user font
- /height exch def
- /width exch def
-
- /F-gs-user-font MF
- /F-gs-user-font width height SF
-} def
-
-/M {moveto} bind def
-/s {show} bind def
-
-/Box { % x y w h -> - define box path
- /d_h exch def /d_w exch def /d_y exch def /d_x exch def
- d_x d_y moveto
- d_w 0 rlineto
- 0 d_h rlineto
- d_w neg 0 rlineto
- closepath
-} def
-
-/bgs { % x y height blskip gray str -> - show string with bg color
- /str exch def
- /gray exch def
- /blskip exch def
- /height exch def
- /y exch def
- /x exch def
-
- gsave
- x y blskip sub str stringwidth pop height Box
- gray setgray
- fill
- grestore
- x y M str s
-} def
-
-% Highlight bars.
-/highlight_bars { % nlines lineheight output_y_margin gray -> -
- gsave
- setgray
- /ymarg exch def
- /lineheight exch def
- /nlines exch def
-
- % This 2 is just a magic number to sync highlight lines to text.
- 0 d_header_y ymarg sub 2 sub translate
-
- /cw d_output_w cols div def
- /nrows d_output_h ymarg 2 mul sub lineheight div cvi def
-
- % for each column
- 0 1 cols 1 sub {
- cw mul /xp exch def
-
- % for each rows
- 0 1 nrows 1 sub {
- /rn exch def
- rn lineheight mul neg /yp exch def
- rn nlines idiv 2 mod 0 eq {
- % Draw highlight bar. 4 is just a magic indentation.
- xp 4 add yp cw 8 sub lineheight neg Box fill
- } if
- } for
- } for
-
- grestore
-} def
-
-% Line highlight bar.
-/line_highlight { % x y width height gray -> -
- gsave
- /gray exch def
- Box gray setgray fill
- grestore
-} def
-
-% Column separator lines.
-/column_lines {
- gsave
- .1 setlinewidth
- 0 d_footer_h translate
- /cw d_output_w cols div def
- 1 1 cols 1 sub {
- cw mul 0 moveto
- 0 d_output_h rlineto stroke
- } for
- grestore
-} def
-
-% Column borders.
-/column_borders {
- gsave
- .1 setlinewidth
- 0 d_footer_h moveto
- 0 d_output_h rlineto
- d_output_w 0 rlineto
- 0 d_output_h neg rlineto
- closepath stroke
- grestore
-} def
-
-% Do the actual underlay drawing
-/draw_underlay {
- ul_style 0 eq {
- ul_str true charpath stroke
- } {
- ul_str show
- } ifelse
-} def
-
-% Underlay
-/underlay { % - -> -
- gsave
- 0 d_page_h translate
- d_page_h neg d_page_w atan rotate
-
- ul_gray setgray
- ul_font setfont
- /dw d_page_h dup mul d_page_w dup mul add sqrt def
- ul_str stringwidth pop dw exch sub 2 div ul_h_ptsize -2 div moveto
- draw_underlay
- grestore
-} def
-
-/user_underlay { % - -> -
- gsave
- ul_x ul_y translate
- ul_angle rotate
- ul_gray setgray
- ul_font setfont
- 0 0 ul_h_ptsize 2 div sub moveto
- draw_underlay
- grestore
-} def
-
-% Page prefeed
-/page_prefeed { % bool -> -
- statusdict /prefeed known {
- statusdict exch /prefeed exch put
- } {
- pop
- } ifelse
-} def
-
-% Wrapped line markers
-/wrapped_line_mark { % x y charwith charheight type -> -
- /type exch def
- /h exch def
- /w exch def
- /y exch def
- /x exch def
-
- type 2 eq {
- % Black boxes (like TeX does)
- gsave
- 0 setlinewidth
- x w 4 div add y M
- 0 h rlineto w 2 div 0 rlineto 0 h neg rlineto
- closepath fill
- grestore
- } {
- type 3 eq {
- % Small arrows
- gsave
- .2 setlinewidth
- x w 2 div add y h 2 div add M
- w 4 div 0 rlineto
- x w 4 div add y lineto stroke
-
- x w 4 div add w 8 div add y h 4 div add M
- x w 4 div add y lineto
- w 4 div h 8 div rlineto stroke
- grestore
- } {
- % do nothing
- } ifelse
- } ifelse
-} def
-
-% EPSF import.
-
-/BeginEPSF {
- /b4_Inc_state save def % Save state for cleanup
- /dict_count countdictstack def % Count objects on dict stack
- /op_count count 1 sub def % Count objects on operand stack
- userdict begin
- /showpage { } def
- 0 setgray 0 setlinecap
- 1 setlinewidth 0 setlinejoin
- 10 setmiterlimit [ ] 0 setdash newpath
- /languagelevel where {
- pop languagelevel
- 1 ne {
- false setstrokeadjust false setoverprint
- } if
- } if
-} bind def
-
-/EndEPSF {
- count op_count sub { pos } repeat % Clean up stacks
- countdictstack dict_count sub { end } repeat
- b4_Inc_state restore
-} bind def
-
-% Check PostScript language level.
-/languagelevel where {
- pop /gs_languagelevel languagelevel def
-} {
- /gs_languagelevel 1 def
-} ifelse
-%%EndResource
-%%BeginResource: procset Enscript-Encoding-88591 1.6 1
-/encoding_vector [
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/space /exclam /quotedbl /numbersign
-/dollar /percent /ampersand /quoteright
-/parenleft /parenright /asterisk /plus
-/comma /hyphen /period /slash
-/zero /one /two /three
-/four /five /six /seven
-/eight /nine /colon /semicolon
-/less /equal /greater /question
-/at /A /B /C
-/D /E /F /G
-/H /I /J /K
-/L /M /N /O
-/P /Q /R /S
-/T /U /V /W
-/X /Y /Z /bracketleft
-/backslash /bracketright /asciicircum /underscore
-/quoteleft /a /b /c
-/d /e /f /g
-/h /i /j /k
-/l /m /n /o
-/p /q /r /s
-/t /u /v /w
-/x /y /z /braceleft
-/bar /braceright /tilde /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/space /exclamdown /cent /sterling
-/currency /yen /brokenbar /section
-/dieresis /copyright /ordfeminine /guillemotleft
-/logicalnot /hyphen /registered /macron
-/degree /plusminus /twosuperior /threesuperior
-/acute /mu /paragraph /bullet
-/cedilla /onesuperior /ordmasculine /guillemotright
-/onequarter /onehalf /threequarters /questiondown
-/Agrave /Aacute /Acircumflex /Atilde
-/Adieresis /Aring /AE /Ccedilla
-/Egrave /Eacute /Ecircumflex /Edieresis
-/Igrave /Iacute /Icircumflex /Idieresis
-/Eth /Ntilde /Ograve /Oacute
-/Ocircumflex /Otilde /Odieresis /multiply
-/Oslash /Ugrave /Uacute /Ucircumflex
-/Udieresis /Yacute /Thorn /germandbls
-/agrave /aacute /acircumflex /atilde
-/adieresis /aring /ae /ccedilla
-/egrave /eacute /ecircumflex /edieresis
-/igrave /iacute /icircumflex /idieresis
-/eth /ntilde /ograve /oacute
-/ocircumflex /otilde /odieresis /divide
-/oslash /ugrave /uacute /ucircumflex
-/udieresis /yacute /thorn /ydieresis
-] def
-%%EndResource
-%%EndProlog
-%%BeginSetup
-%%IncludeResource: font Courier-Bold
-%%IncludeResource: font Courier
-/HFpt_w 10 def
-/HFpt_h 10 def
-/Courier-Bold /HF-gs-font MF
-/HF /HF-gs-font findfont [HFpt_w 0 0 HFpt_h 0 0] makefont def
-/Courier /F-gs-font MF
-/F-gs-font 10 10 SF
-/#copies 1 def
-/d_page_w 520 def
-/d_page_h 747 def
-/d_header_x 0 def
-/d_header_y 747 def
-/d_header_w 520 def
-/d_header_h 0 def
-/d_footer_x 0 def
-/d_footer_y 0 def
-/d_footer_w 520 def
-/d_footer_h 0 def
-/d_output_w 520 def
-/d_output_h 747 def
-/cols 1 def
-userdict/PStoPSxform PStoPSmatrix matrix currentmatrix
- matrix invertmatrix matrix concatmatrix
- matrix invertmatrix put
-%%EndSetup
-%%Page: (0,1) 1
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 1 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 701 M
-(Network Working Group T. Ylonen) s
-5 690 M
-(Internet-Draft SSH Communications Security Corp) s
-5 679 M
-(Expires: March 2, 2003 D. Moffat, Ed.) s
-5 668 M
-( Sun Microsystems, Inc) s
-5 657 M
-( September 2002) s
-5 624 M
-( SSH Authentication Protocol) s
-5 613 M
-( draft-ietf-secsh-userauth-18.txt) s
-5 591 M
-(Status of this Memo) s
-5 569 M
-( This document is an Internet-Draft and is in full conformance with) s
-5 558 M
-( all provisions of Section 10 of RFC2026.) s
-5 536 M
-( Internet-Drafts are working documents of the Internet Engineering) s
-5 525 M
-( Task Force \(IETF\), its areas, and its working groups. Note that other) s
-5 514 M
-( groups may also distribute working documents as Internet-Drafts.) s
-5 492 M
-( Internet-Drafts are draft documents valid for a maximum of six months) s
-5 481 M
-( and may be updated, replaced, or obsoleted by other documents at any) s
-5 470 M
-( time. It is inappropriate to use Internet-Drafts as reference) s
-5 459 M
-( material or to cite them other than as "work in progress.") s
-5 437 M
-( The list of current Internet-Drafts can be accessed at http://) s
-5 426 M
-( www.ietf.org/ietf/1id-abstracts.txt.) s
-5 404 M
-( The list of Internet-Draft Shadow Directories can be accessed at) s
-5 393 M
-( http://www.ietf.org/shadow.html.) s
-5 371 M
-( This Internet-Draft will expire on March 2, 2003.) s
-5 349 M
-(Copyright Notice) s
-5 327 M
-( Copyright \(C\) The Internet Society \(2002\). All Rights Reserved.) s
-5 305 M
-(Abstract) s
-5 283 M
-( SSH is a protocol for secure remote login and other secure network) s
-5 272 M
-( services over an insecure network. This document describes the SSH) s
-5 261 M
-( authentication protocol framework and public key, password, and) s
-5 250 M
-( host-based client authentication methods. Additional authentication) s
-5 239 M
-( methods are described in separate documents. The SSH authentication) s
-5 228 M
-( protocol runs on top of the SSH transport layer protocol and provides) s
-5 217 M
-( a single authenticated tunnel for the SSH connection protocol.) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 1]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 2 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-(Table of Contents) s
-5 668 M
-( 1. Contributors . . . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 657 M
-( 2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 646 M
-( 3. Conventions Used in This Document . . . . . . . . . . . . . 3) s
-5 635 M
-( 3.1 The Authentication Protocol Framework . . . . . . . . . . . 3) s
-5 624 M
-( 3.1.1 Authentication Requests . . . . . . . . . . . . . . . . . . 4) s
-5 613 M
-( 3.1.2 Responses to Authentication Requests . . . . . . . . . . . . 5) s
-5 602 M
-( 3.1.3 The "none" Authentication Request . . . . . . . . . . . . . 6) s
-5 591 M
-( 3.1.4 Completion of User Authentication . . . . . . . . . . . . . 6) s
-5 580 M
-( 3.1.5 Banner Message . . . . . . . . . . . . . . . . . . . . . . . 7) s
-5 569 M
-( 3.2 Authentication Protocol Message Numbers . . . . . . . . . . 7) s
-5 558 M
-( 3.3 Public Key Authentication Method: publickey . . . . . . . . 8) s
-5 547 M
-( 3.4 Password Authentication Method: password . . . . . . . . . . 10) s
-5 536 M
-( 3.5 Host-Based Authentication: hostbased . . . . . . . . . . . . 11) s
-5 525 M
-( 4. Security Considerations . . . . . . . . . . . . . . . . . . 12) s
-5 514 M
-( Normative . . . . . . . . . . . . . . . . . . . . . . . . . 13) s
-5 503 M
-( Informative . . . . . . . . . . . . . . . . . . . . . . . . 13) s
-5 492 M
-( Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 14) s
-5 481 M
-( Intellectual Property and Copyright Statements . . . . . . . 15) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 2]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (2,3) 2
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 3 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-(1. Contributors) s
-5 668 M
-( The major original contributors of this document were: Tatu Ylonen,) s
-5 657 M
-( Tero Kivinen, Timo J. Rinne, Sami Lehtinen \(all of SSH Communications) s
-5 646 M
-( Security Corp\), and Markku-Juhani O. Saarinen \(University of) s
-5 635 M
-( Jyvaskyla\)) s
-5 613 M
-( The document editor is: [email protected]. Comments on this) s
-5 602 M
-( internet draft should be sent to the IETF SECSH working group,) s
-5 591 M
-( details at: http://ietf.org/html.charters/secsh-charter.html) s
-5 569 M
-(2. Introduction) s
-5 547 M
-( The SSH authentication protocol is a general-purpose user) s
-5 536 M
-( authentication protocol. It is intended to be run over the SSH) s
-5 525 M
-( transport layer protocol [SSH-TRANS]. This protocol assumes that the) s
-5 514 M
-( underlying protocols provide integrity and confidentiality) s
-5 503 M
-( protection.) s
-5 481 M
-( This document should be read only after reading the SSH architecture) s
-5 470 M
-( document [SSH-ARCH]. This document freely uses terminology and) s
-5 459 M
-( notation from the architecture document without reference or further) s
-5 448 M
-( explanation.) s
-5 426 M
-( The service name for this protocol is "ssh-userauth".) s
-5 404 M
-( When this protocol starts, it receives the session identifier from) s
-5 393 M
-( the lower-level protocol \(this is the exchange hash H from the first) s
-5 382 M
-( key exchange\). The session identifier uniquely identifies this) s
-5 371 M
-( session and is suitable for signing in order to prove ownership of a) s
-5 360 M
-( private key. This protocol also needs to know whether the lower-level) s
-5 349 M
-( protocol provides confidentiality protection.) s
-5 327 M
-(3. Conventions Used in This Document) s
-5 305 M
-( The keywords "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT",) s
-5 294 M
-( and "MAY" that appear in this document are to be interpreted as) s
-5 283 M
-( described in [RFC2119]) s
-5 261 M
-( The used data types and terminology are specified in the architecture) s
-5 250 M
-( document [SSH-ARCH]) s
-5 228 M
-( The architecture document also discusses the algorithm naming) s
-5 217 M
-( conventions that MUST be used with the SSH protocols.) s
-5 195 M
-(3.1 The Authentication Protocol Framework) s
-5 173 M
-( The server drives the authentication by telling the client which) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 3]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 4 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-( authentication methods can be used to continue the exchange at any) s
-5 679 M
-( given time. The client has the freedom to try the methods listed by) s
-5 668 M
-( the server in any order. This gives the server complete control over) s
-5 657 M
-( the authentication process if desired, but also gives enough) s
-5 646 M
-( flexibility for the client to use the methods it supports or that are) s
-5 635 M
-( most convenient for the user, when multiple methods are offered by) s
-5 624 M
-( the server.) s
-5 602 M
-( Authentication methods are identified by their name, as defined in) s
-5 591 M
-( [SSH-ARCH]. The "none" method is reserved, and MUST NOT be listed as) s
-5 580 M
-( supported. However, it MAY be sent by the client. The server MUST) s
-5 569 M
-( always reject this request, unless the client is to be allowed in) s
-5 558 M
-( without any authentication, in which case the server MUST accept this) s
-5 547 M
-( request. The main purpose of sending this request is to get the list) s
-5 536 M
-( of supported methods from the server.) s
-5 514 M
-( The server SHOULD have a timeout for authentication, and disconnect) s
-5 503 M
-( if the authentication has not been accepted within the timeout) s
-5 492 M
-( period. The RECOMMENDED timeout period is 10 minutes. Additionally,) s
-5 481 M
-( the implementation SHOULD limit the number of failed authentication) s
-5 470 M
-( attempts a client may perform in a single session \(the RECOMMENDED) s
-5 459 M
-( limit is 20 attempts\). If the threshold is exceeded, the server) s
-5 448 M
-( SHOULD disconnect.) s
-5 426 M
-(3.1.1 Authentication Requests) s
-5 404 M
-( All authentication requests MUST use the following message format.) s
-5 393 M
-( Only the first few fields are defined; the remaining fields depend on) s
-5 382 M
-( the authentication method.) s
-5 360 M
-( byte SSH_MSG_USERAUTH_REQUEST) s
-5 349 M
-( string user name \(in ISO-10646 UTF-8 encoding [RFC2279]\)) s
-5 338 M
-( string service name \(in US-ASCII\)) s
-5 327 M
-( string method name \(US-ASCII\)) s
-5 316 M
-( The rest of the packet is method-specific.) s
-5 294 M
-( The user name and service are repeated in every new authentication) s
-5 283 M
-( attempt, and MAY change. The server implementation MUST carefully) s
-5 272 M
-( check them in every message, and MUST flush any accumulated) s
-5 261 M
-( authentication states if they change. If it is unable to flush some) s
-5 250 M
-( authentication state, it MUST disconnect if the user or service name) s
-5 239 M
-( changes.) s
-5 217 M
-( The service name specifies the service to start after authentication.) s
-5 206 M
-( There may be several different authenticated services provided. If) s
-5 195 M
-( the requested service is not available, the server MAY disconnect) s
-5 184 M
-( immediately or at any later time. Sending a proper disconnect) s
-5 173 M
-( message is RECOMMENDED. In any case, if the service does not exist,) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 4]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (4,5) 3
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 5 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-( authentication MUST NOT be accepted.) s
-5 668 M
-( If the requested user does not exist, the server MAY disconnect, or) s
-5 657 M
-( MAY send a bogus list of acceptable authentication methods, but never) s
-5 646 M
-( accept any. This makes it possible for the server to avoid) s
-5 635 M
-( disclosing information on which accounts exist. In any case, if the) s
-5 624 M
-( user does not exist, the authentication request MUST NOT be accepted.) s
-5 602 M
-( While there is usually little point for clients to send requests that) s
-5 591 M
-( the server does not list as acceptable, sending such requests is not) s
-5 580 M
-( an error, and the server SHOULD simply reject requests that it does) s
-5 569 M
-( not recognize.) s
-5 547 M
-( An authentication request MAY result in a further exchange of) s
-5 536 M
-( messages. All such messages depend on the authentication method) s
-5 525 M
-( used, and the client MAY at any time continue with a new) s
-5 514 M
-( SSH_MSG_USERAUTH_REQUEST message, in which case the server MUST) s
-5 503 M
-( abandon the previous authentication attempt and continue with the new) s
-5 492 M
-( one.) s
-5 470 M
-(3.1.2 Responses to Authentication Requests) s
-5 448 M
-( If the server rejects the authentication request, it MUST respond) s
-5 437 M
-( with the following:) s
-5 415 M
-( byte SSH_MSG_USERAUTH_FAILURE) s
-5 404 M
-( string authentications that can continue) s
-5 393 M
-( boolean partial success) s
-5 371 M
-( "Authentications that can continue" is a comma-separated list of) s
-5 360 M
-( authentication method names that may productively continue the) s
-5 349 M
-( authentication dialog.) s
-5 327 M
-( It is RECOMMENDED that servers only include those methods in the list) s
-5 316 M
-( that are actually useful. However, it is not illegal to include) s
-5 305 M
-( methods that cannot be used to authenticate the user.) s
-5 283 M
-( Already successfully completed authentications SHOULD NOT be included) s
-5 272 M
-( in the list, unless they really should be performed again for some) s
-5 261 M
-( reason.) s
-5 239 M
-( "Partial success" MUST be TRUE if the authentication request to which) s
-5 228 M
-( this is a response was successful. It MUST be FALSE if the request) s
-5 217 M
-( was not successfully processed.) s
-5 195 M
-( When the server accepts authentication, it MUST respond with the) s
-5 184 M
-( following:) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 5]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 6 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-( byte SSH_MSG_USERAUTH_SUCCESS) s
-5 668 M
-( Note that this is not sent after each step in a multi-method) s
-5 657 M
-( authentication sequence, but only when the authentication is) s
-5 646 M
-( complete.) s
-5 624 M
-( The client MAY send several authentication requests without waiting) s
-5 613 M
-( for responses from previous requests. The server MUST process each) s
-5 602 M
-( request completely and acknowledge any failed requests with a) s
-5 591 M
-( SSH_MSG_USERAUTH_FAILURE message before processing the next request.) s
-5 569 M
-( A request that results in further exchange of messages will be) s
-5 558 M
-( aborted by a second request. It is not possible to send a second) s
-5 547 M
-( request without waiting for a response from the server, if the first) s
-5 536 M
-( request will result in further exchange of messages. No) s
-5 525 M
-( SSH_MSG_USERAUTH_FAILURE message will be sent for the aborted method.) s
-5 503 M
-( SSH_MSG_USERAUTH_SUCCESS MUST be sent only once. When) s
-5 492 M
-( SSH_MSG_USERAUTH_SUCCESS has been sent, any further authentication) s
-5 481 M
-( requests received after that SHOULD be silently ignored.) s
-5 459 M
-( Any non-authentication messages sent by the client after the request) s
-5 448 M
-( that resulted in SSH_MSG_USERAUTH_SUCCESS being sent MUST be passed) s
-5 437 M
-( to the service being run on top of this protocol. Such messages can) s
-5 426 M
-( be identified by their message numbers \(see Section Message Numbers) s
-5 415 M
-( \(Section 3.2\)\).) s
-5 393 M
-(3.1.3 The "none" Authentication Request) s
-5 371 M
-( A client may request a list of authentication methods that may) s
-5 360 M
-( continue by using the "none" authentication method.) s
-5 338 M
-( If no authentication at all is needed for the user, the server MUST) s
-5 327 M
-( return SSH_MSG_USERAUTH_SUCCESS. Otherwise, the server MUST return) s
-5 316 M
-( SSH_MSG_USERAUTH_FAILURE and MAY return with it a list of) s
-5 305 M
-( authentication methods that can continue.) s
-5 283 M
-( This method MUST NOT be listed as supported by the server.) s
-5 261 M
-(3.1.4 Completion of User Authentication) s
-5 239 M
-( Authentication is complete when the server has responded with) s
-5 228 M
-( SSH_MSG_USERAUTH_SUCCESS; all authentication related messages) s
-5 217 M
-( received after sending this message SHOULD be silently ignored.) s
-5 195 M
-( After sending SSH_MSG_USERAUTH_SUCCESS, the server starts the) s
-5 184 M
-( requested service.) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 6]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (6,7) 4
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 7 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-(3.1.5 Banner Message) s
-5 668 M
-( In some jurisdictions, sending a warning message before) s
-5 657 M
-( authentication may be relevant for getting legal protection. Many) s
-5 646 M
-( UNIX machines, for example, normally display text from `/etc/issue',) s
-5 635 M
-( or use "tcp wrappers" or similar software to display a banner before) s
-5 624 M
-( issuing a login prompt.) s
-5 602 M
-( The SSH server may send a SSH_MSG_USERAUTH_BANNER message at any time) s
-5 591 M
-( before authentication is successful. This message contains text to) s
-5 580 M
-( be displayed to the client user before authentication is attempted.) s
-5 569 M
-( The format is as follows:) s
-5 547 M
-( byte SSH_MSG_USERAUTH_BANNER) s
-5 536 M
-( string message \(ISO-10646 UTF-8\)) s
-5 525 M
-( string language tag \(as defined in [RFC3066]\)) s
-5 503 M
-( The client SHOULD by default display the message on the screen.) s
-5 492 M
-( However, since the message is likely to be sent for every login) s
-5 481 M
-( attempt, and since some client software will need to open a separate) s
-5 470 M
-( window for this warning, the client software may allow the user to) s
-5 459 M
-( explicitly disable the display of banners from the server. The) s
-5 448 M
-( message may consist of multiple lines.) s
-5 426 M
-( If the message string is displayed, control character filtering) s
-5 415 M
-( discussed in [SSH-ARCH] SHOULD be used to avoid attacks by sending) s
-5 404 M
-( terminal control characters.) s
-5 382 M
-(3.2 Authentication Protocol Message Numbers) s
-5 360 M
-( All message numbers used by this authentication protocol are in the) s
-5 349 M
-( range from 50 to 79, which is part of the range reserved for) s
-5 338 M
-( protocols running on top of the SSH transport layer protocol.) s
-5 316 M
-( Message numbers of 80 and higher are reserved for protocols running) s
-5 305 M
-( after this authentication protocol, so receiving one of them before) s
-5 294 M
-( authentication is complete is an error, to which the server MUST) s
-5 283 M
-( respond by disconnecting \(preferably with a proper disconnect message) s
-5 272 M
-( sent first to ease troubleshooting\).) s
-5 250 M
-( After successful authentication, such messages are passed to the) s
-5 239 M
-( higher-level service.) s
-5 217 M
-( These are the general authentication message codes:) s
-5 195 M
-( #define SSH_MSG_USERAUTH_REQUEST 50) s
-5 184 M
-( #define SSH_MSG_USERAUTH_FAILURE 51) s
-5 173 M
-( #define SSH_MSG_USERAUTH_SUCCESS 52) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 7]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 8 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-( #define SSH_MSG_USERAUTH_BANNER 53) s
-5 668 M
-( In addition to the above, there is a range of message numbers) s
-5 657 M
-( \(60..79\) reserved for method-specific messages. These messages are) s
-5 646 M
-( only sent by the server \(client sends only SSH_MSG_USERAUTH_REQUEST) s
-5 635 M
-( messages\). Different authentication methods reuse the same message) s
-5 624 M
-( numbers.) s
-5 602 M
-(3.3 Public Key Authentication Method: publickey) s
-5 580 M
-( The only REQUIRED authentication method is public key authentication.) s
-5 569 M
-( All implementations MUST support this method; however, not all users) s
-5 558 M
-( need to have public keys, and most local policies are not likely to) s
-5 547 M
-( require public key authentication for all users in the near future.) s
-5 525 M
-( With this method, the possession of a private key serves as) s
-5 514 M
-( authentication. This method works by sending a signature created) s
-5 503 M
-( with a private key of the user. The server MUST check that the key) s
-5 492 M
-( is a valid authenticator for the user, and MUST check that the) s
-5 481 M
-( signature is valid. If both hold, the authentication request MUST be) s
-5 470 M
-( accepted; otherwise it MUST be rejected. \(Note that the server MAY) s
-5 459 M
-( require additional authentications after successful authentication.\)) s
-5 437 M
-( Private keys are often stored in an encrypted form at the client) s
-5 426 M
-( host, and the user must supply a passphrase before the signature can) s
-5 415 M
-( be generated. Even if they are not, the signing operation involves) s
-5 404 M
-( some expensive computation. To avoid unnecessary processing and user) s
-5 393 M
-( interaction, the following message is provided for querying whether) s
-5 382 M
-( authentication using the key would be acceptable.) s
-5 360 M
-( byte SSH_MSG_USERAUTH_REQUEST) s
-5 349 M
-( string user name) s
-5 338 M
-( string service) s
-5 327 M
-( string "publickey") s
-5 316 M
-( boolean FALSE) s
-5 305 M
-( string public key algorithm name) s
-5 294 M
-( string public key blob) s
-5 272 M
-( Public key algorithms are defined in the transport layer) s
-5 261 M
-( specification [SSH-TRANS]. The public key blob may contain) s
-5 250 M
-( certificates.) s
-5 228 M
-( Any public key algorithm may be offered for use in authentication.) s
-5 217 M
-( In particular, the list is not constrained by what was negotiated) s
-5 206 M
-( during key exchange. If the server does not support some algorithm,) s
-5 195 M
-( it MUST simply reject the request.) s
-5 173 M
-( The server MUST respond to this message with either) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 8]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (8,9) 5
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 9 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-( SSH_MSG_USERAUTH_FAILURE or with the following:) s
-5 668 M
-( byte SSH_MSG_USERAUTH_PK_OK) s
-5 657 M
-( string public key algorithm name from the request) s
-5 646 M
-( string public key blob from the request) s
-5 624 M
-( To perform actual authentication, the client MAY then send a) s
-5 613 M
-( signature generated using the private key. The client MAY send the) s
-5 602 M
-( signature directly without first verifying whether the key is) s
-5 591 M
-( acceptable. The signature is sent using the following packet:) s
-5 569 M
-( byte SSH_MSG_USERAUTH_REQUEST) s
-5 558 M
-( string user name) s
-5 547 M
-( string service) s
-5 536 M
-( string "publickey") s
-5 525 M
-( boolean TRUE) s
-5 514 M
-( string public key algorithm name) s
-5 503 M
-( string public key to be used for authentication) s
-5 492 M
-( string signature) s
-5 470 M
-( Signature is a signature by the corresponding private key over the) s
-5 459 M
-( following data, in the following order:) s
-5 437 M
-( string session identifier) s
-5 426 M
-( byte SSH_MSG_USERAUTH_REQUEST) s
-5 415 M
-( string user name) s
-5 404 M
-( string service) s
-5 393 M
-( string "publickey") s
-5 382 M
-( boolean TRUE) s
-5 371 M
-( string public key algorithm name) s
-5 360 M
-( string public key to be used for authentication) s
-5 338 M
-( When the server receives this message, it MUST check whether the) s
-5 327 M
-( supplied key is acceptable for authentication, and if so, it MUST) s
-5 316 M
-( check whether the signature is correct.) s
-5 294 M
-( If both checks succeed, this method is successful. Note that the) s
-5 283 M
-( server may require additional authentications. The server MUST) s
-5 272 M
-( respond with SSH_MSG_USERAUTH_SUCCESS \(if no more authentications are) s
-5 261 M
-( needed\), or SSH_MSG_USERAUTH_FAILURE \(if the request failed, or more) s
-5 250 M
-( authentications are needed\).) s
-5 228 M
-( The following method-specific message numbers are used by the) s
-5 217 M
-( publickey authentication method.) s
-5 195 M
-( /* Key-based */) s
-5 184 M
-( #define SSH_MSG_USERAUTH_PK_OK 60) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 9]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 10 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-(3.4 Password Authentication Method: password) s
-5 668 M
-( Password authentication uses the following packets. Note that a) s
-5 657 M
-( server MAY request the user to change the password. All) s
-5 646 M
-( implementations SHOULD support password authentication.) s
-5 624 M
-( byte SSH_MSG_USERAUTH_REQUEST) s
-5 613 M
-( string user name) s
-5 602 M
-( string service) s
-5 591 M
-( string "password") s
-5 580 M
-( boolean FALSE) s
-5 569 M
-( string plaintext password \(ISO-10646 UTF-8\)) s
-5 547 M
-( Note that the password is encoded in ISO-10646 UTF-8. It is up to) s
-5 536 M
-( the server how it interprets the password and validates it against) s
-5 525 M
-( the password database. However, if the client reads the password in) s
-5 514 M
-( some other encoding \(e.g., ISO 8859-1 \(ISO Latin1\)\), it MUST convert) s
-5 503 M
-( the password to ISO-10646 UTF-8 before transmitting, and the server) s
-5 492 M
-( MUST convert the password to the encoding used on that system for) s
-5 481 M
-( passwords.) s
-5 459 M
-( Note that even though the cleartext password is transmitted in the) s
-5 448 M
-( packet, the entire packet is encrypted by the transport layer. Both) s
-5 437 M
-( the server and the client should check whether the underlying) s
-5 426 M
-( transport layer provides confidentiality \(i.e., if encryption is) s
-5 415 M
-( being used\). If no confidentiality is provided \(none cipher\),) s
-5 404 M
-( password authentication SHOULD be disabled. If there is no) s
-5 393 M
-( confidentiality or no MAC, password change SHOULD be disabled.) s
-5 371 M
-( Normally, the server responds to this message with success or) s
-5 360 M
-( failure. However, if the password has expired the server SHOULD) s
-5 349 M
-( indicate this by responding with SSH_MSG_USERAUTH_PASSWD_CHANGEREQ.) s
-5 338 M
-( In anycase the server MUST NOT allow an expired password to be used) s
-5 327 M
-( for authentication.) s
-5 305 M
-( byte SSH_MSG_USERAUTH_PASSWD_CHANGEREQ) s
-5 294 M
-( string prompt \(ISO-10646 UTF-8\)) s
-5 283 M
-( string language tag \(as defined in [RFC3066]\)) s
-5 261 M
-( In this case, the client MAY continue with a different authentication) s
-5 250 M
-( method, or request a new password from the user and retry password) s
-5 239 M
-( authentication using the following message. The client MAY also send) s
-5 228 M
-( this message instead of the normal password authentication request) s
-5 217 M
-( without the server asking for it.) s
-5 195 M
-( byte SSH_MSG_USERAUTH_REQUEST) s
-5 184 M
-( string user name) s
-5 173 M
-( string service) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 10]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (10,11) 6
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 11 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-( string "password") s
-5 679 M
-( boolean TRUE) s
-5 668 M
-( string plaintext old password \(ISO-10646 UTF-8\)) s
-5 657 M
-( string plaintext new password \(ISO-10646 UTF-8\)) s
-5 635 M
-( The server must reply to request message with) s
-5 624 M
-( SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, or another) s
-5 613 M
-( SSH_MSG_USERAUTH_PASSWD_CHANGEREQ. The meaning of these is as) s
-5 602 M
-( follows:) s
-5 580 M
-( SSH_MSG_USERAUTH_SUCCESS The password has been changed, and) s
-5 569 M
-( authentication has been successfully completed.) s
-5 547 M
-( SSH_MSG_USERAUTH_FAILURE with partial success The password has) s
-5 536 M
-( been changed, but more authentications are needed.) s
-5 514 M
-( SSH_MSG_USERAUTH_FAILURE without partial success The password has) s
-5 503 M
-( not been changed. Either password changing was not supported, or) s
-5 492 M
-( the old password was bad. Note that if the server has already) s
-5 481 M
-( sent SSH_MSG_USERAUTH_PASSWD_CHANGEREQ, we know that it supports) s
-5 470 M
-( changing the password.) s
-5 448 M
-( SSH_MSG_USERAUTH_CHANGEREQ The password was not changed because) s
-5 437 M
-( the new password was not acceptable \(e.g. too easy to guess\).) s
-5 415 M
-( The following method-specific message numbers are used by the) s
-5 404 M
-( password authentication method.) s
-5 382 M
-( #define SSH_MSG_USERAUTH_PASSWD_CHANGEREQ 60) s
-5 349 M
-(3.5 Host-Based Authentication: hostbased) s
-5 327 M
-( Some sites wish to allow authentication based on the host where the) s
-5 316 M
-( user is coming from, and the user name on the remote host. While) s
-5 305 M
-( this form of authentication is not suitable for high-security sites,) s
-5 294 M
-( it can be very convenient in many environments. This form of) s
-5 283 M
-( authentication is OPTIONAL. When used, special care SHOULD be taken) s
-5 272 M
-( to prevent a regular user from obtaining the private host key.) s
-5 250 M
-( The client requests this form of authentication by sending the) s
-5 239 M
-( following message. It is similar to the UNIX "rhosts" and) s
-5 228 M
-( "hosts.equiv" styles of authentication, except that the identity of) s
-5 217 M
-( the client host is checked more rigorously.) s
-5 195 M
-( This method works by having the client send a signature created with) s
-5 184 M
-( the private key of the client host, which the server checks with that) s
-5 173 M
-( host's public key. Once the client host's identity is established,) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 11]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 12 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-( authorization \(but no further authentication\) is performed based on) s
-5 679 M
-( the user names on the server and the client, and the client host) s
-5 668 M
-( name.) s
-5 646 M
-( byte SSH_MSG_USERAUTH_REQUEST) s
-5 635 M
-( string user name) s
-5 624 M
-( string service) s
-5 613 M
-( string "hostbased") s
-5 602 M
-( string public key algorithm for host key) s
-5 591 M
-( string public host key and certificates for client host) s
-5 580 M
-( string client host name \(FQDN; US-ASCII\)) s
-5 569 M
-( string user name on the client host \(ISO-10646 UTF-8\)) s
-5 558 M
-( string signature) s
-5 536 M
-( Public key algorithm names for use in "public key algorithm for host) s
-5 525 M
-( key" are defined in the transport layer specification. The "public) s
-5 514 M
-( host key for client host" may include certificates.) s
-5 492 M
-( Signature is a signature with the private host key of the following) s
-5 481 M
-( data, in this order:) s
-5 459 M
-( string session identifier) s
-5 448 M
-( byte SSH_MSG_USERAUTH_REQUEST) s
-5 437 M
-( string user name) s
-5 426 M
-( string service) s
-5 415 M
-( string "hostbased") s
-5 404 M
-( string public key algorithm for host key) s
-5 393 M
-( string public host key and certificates for client host) s
-5 382 M
-( string client host name \(FQDN; US-ASCII\)) s
-5 371 M
-( string user name on the client host\(ISO-10646 UTF-8\)) s
-5 349 M
-( The server MUST verify that the host key actually belongs to the) s
-5 338 M
-( client host named in the message, that the given user on that host is) s
-5 327 M
-( allowed to log in, and that the signature is a valid signature on the) s
-5 316 M
-( appropriate value by the given host key. The server MAY ignore the) s
-5 305 M
-( client user name, if it wants to authenticate only the client host.) s
-5 283 M
-( It is RECOMMENDED that whenever possible, the server perform) s
-5 272 M
-( additional checks to verify that the network address obtained from) s
-5 261 M
-( the \(untrusted\) network matches the given client host name. This) s
-5 250 M
-( makes exploiting compromised host keys more difficult. Note that) s
-5 239 M
-( this may require special handling for connections coming through a) s
-5 228 M
-( firewall.) s
-5 206 M
-(4. Security Considerations) s
-5 184 M
-( The purpose of this protocol is to perform client user) s
-5 173 M
-( authentication. It assumed that this runs over a secure transport) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 12]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (12,13) 7
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 13 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-( layer protocol, which has already authenticated the server machine,) s
-5 679 M
-( established an encrypted communications channel, and computed a) s
-5 668 M
-( unique session identifier for this session. The transport layer) s
-5 657 M
-( provides forward secrecy for password authentication and other) s
-5 646 M
-( methods that rely on secret data.) s
-5 624 M
-( Full security considerations for this protocol are provided in) s
-5 613 M
-( Section 8 of [SSH-ARCH]) s
-5 591 M
-(Normative) s
-5 569 M
-( [SSH-ARCH]) s
-5 558 M
-( Ylonen, T., "SSH Protocol Architecture", I-D) s
-5 547 M
-( draft-ietf-architecture-15.txt, Oct 2003.) s
-5 525 M
-( [SSH-TRANS]) s
-5 514 M
-( Ylonen, T., "SSH Transport Layer Protocol", I-D) s
-5 503 M
-( draft-ietf-transport-17.txt, Oct 2003.) s
-5 481 M
-( [SSH-USERAUTH]) s
-5 470 M
-( Ylonen, T., "SSH Authentication Protocol", I-D) s
-5 459 M
-( draft-ietf-userauth-18.txt, Oct 2003.) s
-5 437 M
-( [SSH-CONNECT]) s
-5 426 M
-( Ylonen, T., "SSH Connection Protocol", I-D) s
-5 415 M
-( draft-ietf-connect-18.txt, Oct 2003.) s
-5 393 M
-( [SSH-NUMBERS]) s
-5 382 M
-( Lehtinen, S. and D. Moffat, "SSH Protocol Assigned) s
-5 371 M
-( Numbers", I-D draft-ietf-secsh-assignednumbers-05.txt, Oct) s
-5 360 M
-( 2003.) s
-5 338 M
-( [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate) s
-5 327 M
-( Requirement Levels", BCP 14, RFC 2119, March 1997.) s
-5 305 M
-(Informative) s
-5 283 M
-( [RFC3066] Alvestrand, H., "Tags for the Identification of) s
-5 272 M
-( Languages", BCP 47, RFC 3066, January 2001.) s
-5 250 M
-( [RFC2279] Yergeau, F., "UTF-8, a transformation format of ISO) s
-5 239 M
-( 10646", RFC 2279, January 1998.) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 13]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 14 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-(Authors' Addresses) s
-5 668 M
-( Tatu Ylonen) s
-5 657 M
-( SSH Communications Security Corp) s
-5 646 M
-( Fredrikinkatu 42) s
-5 635 M
-( HELSINKI FIN-00100) s
-5 624 M
-( Finland) s
-5 602 M
-( EMail: [email protected]) s
-5 569 M
-( Darren J. Moffat \(editor\)) s
-5 558 M
-( Sun Microsystems, Inc) s
-5 547 M
-( 17 Network Circle) s
-5 536 M
-( Menlo Park 95025) s
-5 525 M
-( USA) s
-5 503 M
-( EMail: [email protected]) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 14]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (14,15) 8
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 15 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-(Intellectual Property Statement) s
-5 668 M
-( The IETF takes no position regarding the validity or scope of any) s
-5 657 M
-( intellectual property or other rights that might be claimed to) s
-5 646 M
-( pertain to the implementation or use of the technology described in) s
-5 635 M
-( this document or the extent to which any license under such rights) s
-5 624 M
-( might or might not be available; neither does it represent that it) s
-5 613 M
-( has made any effort to identify any such rights. Information on the) s
-5 602 M
-( IETF's procedures with respect to rights in standards-track and) s
-5 591 M
-( standards-related documentation can be found in BCP-11. Copies of) s
-5 580 M
-( claims of rights made available for publication and any assurances of) s
-5 569 M
-( licenses to be made available, or the result of an attempt made to) s
-5 558 M
-( obtain a general license or permission for the use of such) s
-5 547 M
-( proprietary rights by implementors or users of this specification can) s
-5 536 M
-( be obtained from the IETF Secretariat.) s
-5 514 M
-( The IETF invites any interested party to bring to its attention any) s
-5 503 M
-( copyrights, patents or patent applications, or other proprietary) s
-5 492 M
-( rights which may cover technology that may be required to practice) s
-5 481 M
-( this standard. Please address the information to the IETF Executive) s
-5 470 M
-( Director.) s
-5 448 M
-( The IETF has been notified of intellectual property rights claimed in) s
-5 437 M
-( regard to some or all of the specification contained in this) s
-5 426 M
-( document. For more information consult the online list of claimed) s
-5 415 M
-( rights.) s
-5 382 M
-(Full Copyright Statement) s
-5 360 M
-( Copyright \(C\) The Internet Society \(2002\). All Rights Reserved.) s
-5 338 M
-( This document and translations of it may be copied and furnished to) s
-5 327 M
-( others, and derivative works that comment on or otherwise explain it) s
-5 316 M
-( or assist in its implementation may be prepared, copied, published) s
-5 305 M
-( and distributed, in whole or in part, without restriction of any) s
-5 294 M
-( kind, provided that the above copyright notice and this paragraph are) s
-5 283 M
-( included on all such copies and derivative works. However, this) s
-5 272 M
-( document itself may not be modified in any way, such as by removing) s
-5 261 M
-( the copyright notice or references to the Internet Society or other) s
-5 250 M
-( Internet organizations, except as needed for the purpose of) s
-5 239 M
-( developing Internet standards in which case the procedures for) s
-5 228 M
-( copyrights defined in the Internet Standards process must be) s
-5 217 M
-( followed, or as required to translate it into languages other than) s
-5 206 M
-( English.) s
-5 184 M
-( The limited permissions granted above are perpetual and will not be) s
-5 173 M
-( revoked by the Internet Society or its successors or assignees.) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 15]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 16 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-( This document and the information contained herein is provided on an) s
-5 679 M
-( "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING) s
-5 668 M
-( TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING) s
-5 657 M
-( BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION) s
-5 646 M
-( HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF) s
-5 635 M
-( MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.) s
-5 602 M
-(Acknowledgment) s
-5 580 M
-( Funding for the RFC Editor function is currently provided by the) s
-5 569 M
-( Internet Society.) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 16]) s
-_R
-S
-PStoPSsaved restore
-%%Trailer
-%%Pages: 16
-%%DocumentNeededResources: font Courier-Bold Courier
-%%EOF
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-userauth-18.txt b/lib/ssh/doc/standard/draft-ietf-secsh-userauth-18.txt
deleted file mode 100644
index 9dae578a35..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-userauth-18.txt
+++ /dev/null
@@ -1,896 +0,0 @@
-
-
-
-Network Working Group T. Ylonen
-Internet-Draft SSH Communications Security Corp
-Expires: March 2, 2003 D. Moffat, Ed.
- Sun Microsystems, Inc
- September 2002
-
-
- SSH Authentication Protocol
- draft-ietf-secsh-userauth-18.txt
-
-Status of this Memo
-
- This document is an Internet-Draft and is in full conformance with
- all provisions of Section 10 of RFC2026.
-
- Internet-Drafts are working documents of the Internet Engineering
- Task Force (IETF), its areas, and its working groups. Note that other
- groups may also distribute working documents as Internet-Drafts.
-
- Internet-Drafts are draft documents valid for a maximum of six months
- and may be updated, replaced, or obsoleted by other documents at any
- time. It is inappropriate to use Internet-Drafts as reference
- material or to cite them other than as "work in progress."
-
- The list of current Internet-Drafts can be accessed at http://
- www.ietf.org/ietf/1id-abstracts.txt.
-
- The list of Internet-Draft Shadow Directories can be accessed at
- http://www.ietf.org/shadow.html.
-
- This Internet-Draft will expire on March 2, 2003.
-
-Copyright Notice
-
- Copyright (C) The Internet Society (2002). All Rights Reserved.
-
-Abstract
-
- SSH is a protocol for secure remote login and other secure network
- services over an insecure network. This document describes the SSH
- authentication protocol framework and public key, password, and
- host-based client authentication methods. Additional authentication
- methods are described in separate documents. The SSH authentication
- protocol runs on top of the SSH transport layer protocol and provides
- a single authenticated tunnel for the SSH connection protocol.
-
-
-
-
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 1]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
-Table of Contents
-
- 1. Contributors . . . . . . . . . . . . . . . . . . . . . . . . 3
- 2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3
- 3. Conventions Used in This Document . . . . . . . . . . . . . 3
- 3.1 The Authentication Protocol Framework . . . . . . . . . . . 3
- 3.1.1 Authentication Requests . . . . . . . . . . . . . . . . . . 4
- 3.1.2 Responses to Authentication Requests . . . . . . . . . . . . 5
- 3.1.3 The "none" Authentication Request . . . . . . . . . . . . . 6
- 3.1.4 Completion of User Authentication . . . . . . . . . . . . . 6
- 3.1.5 Banner Message . . . . . . . . . . . . . . . . . . . . . . . 7
- 3.2 Authentication Protocol Message Numbers . . . . . . . . . . 7
- 3.3 Public Key Authentication Method: publickey . . . . . . . . 8
- 3.4 Password Authentication Method: password . . . . . . . . . . 10
- 3.5 Host-Based Authentication: hostbased . . . . . . . . . . . . 11
- 4. Security Considerations . . . . . . . . . . . . . . . . . . 12
- Normative . . . . . . . . . . . . . . . . . . . . . . . . . 13
- Informative . . . . . . . . . . . . . . . . . . . . . . . . 13
- Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 14
- Intellectual Property and Copyright Statements . . . . . . . 15
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 2]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
-1. Contributors
-
- The major original contributors of this document were: Tatu Ylonen,
- Tero Kivinen, Timo J. Rinne, Sami Lehtinen (all of SSH Communications
- Security Corp), and Markku-Juhani O. Saarinen (University of
- Jyvaskyla)
-
- The document editor is: [email protected]. Comments on this
- internet draft should be sent to the IETF SECSH working group,
- details at: http://ietf.org/html.charters/secsh-charter.html
-
-2. Introduction
-
- The SSH authentication protocol is a general-purpose user
- authentication protocol. It is intended to be run over the SSH
- transport layer protocol [SSH-TRANS]. This protocol assumes that the
- underlying protocols provide integrity and confidentiality
- protection.
-
- This document should be read only after reading the SSH architecture
- document [SSH-ARCH]. This document freely uses terminology and
- notation from the architecture document without reference or further
- explanation.
-
- The service name for this protocol is "ssh-userauth".
-
- When this protocol starts, it receives the session identifier from
- the lower-level protocol (this is the exchange hash H from the first
- key exchange). The session identifier uniquely identifies this
- session and is suitable for signing in order to prove ownership of a
- private key. This protocol also needs to know whether the lower-level
- protocol provides confidentiality protection.
-
-3. Conventions Used in This Document
-
- The keywords "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT",
- and "MAY" that appear in this document are to be interpreted as
- described in [RFC2119]
-
- The used data types and terminology are specified in the architecture
- document [SSH-ARCH]
-
- The architecture document also discusses the algorithm naming
- conventions that MUST be used with the SSH protocols.
-
-3.1 The Authentication Protocol Framework
-
- The server drives the authentication by telling the client which
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 3]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
- authentication methods can be used to continue the exchange at any
- given time. The client has the freedom to try the methods listed by
- the server in any order. This gives the server complete control over
- the authentication process if desired, but also gives enough
- flexibility for the client to use the methods it supports or that are
- most convenient for the user, when multiple methods are offered by
- the server.
-
- Authentication methods are identified by their name, as defined in
- [SSH-ARCH]. The "none" method is reserved, and MUST NOT be listed as
- supported. However, it MAY be sent by the client. The server MUST
- always reject this request, unless the client is to be allowed in
- without any authentication, in which case the server MUST accept this
- request. The main purpose of sending this request is to get the list
- of supported methods from the server.
-
- The server SHOULD have a timeout for authentication, and disconnect
- if the authentication has not been accepted within the timeout
- period. The RECOMMENDED timeout period is 10 minutes. Additionally,
- the implementation SHOULD limit the number of failed authentication
- attempts a client may perform in a single session (the RECOMMENDED
- limit is 20 attempts). If the threshold is exceeded, the server
- SHOULD disconnect.
-
-3.1.1 Authentication Requests
-
- All authentication requests MUST use the following message format.
- Only the first few fields are defined; the remaining fields depend on
- the authentication method.
-
- byte SSH_MSG_USERAUTH_REQUEST
- string user name (in ISO-10646 UTF-8 encoding [RFC2279])
- string service name (in US-ASCII)
- string method name (US-ASCII)
- The rest of the packet is method-specific.
-
- The user name and service are repeated in every new authentication
- attempt, and MAY change. The server implementation MUST carefully
- check them in every message, and MUST flush any accumulated
- authentication states if they change. If it is unable to flush some
- authentication state, it MUST disconnect if the user or service name
- changes.
-
- The service name specifies the service to start after authentication.
- There may be several different authenticated services provided. If
- the requested service is not available, the server MAY disconnect
- immediately or at any later time. Sending a proper disconnect
- message is RECOMMENDED. In any case, if the service does not exist,
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 4]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
- authentication MUST NOT be accepted.
-
- If the requested user does not exist, the server MAY disconnect, or
- MAY send a bogus list of acceptable authentication methods, but never
- accept any. This makes it possible for the server to avoid
- disclosing information on which accounts exist. In any case, if the
- user does not exist, the authentication request MUST NOT be accepted.
-
- While there is usually little point for clients to send requests that
- the server does not list as acceptable, sending such requests is not
- an error, and the server SHOULD simply reject requests that it does
- not recognize.
-
- An authentication request MAY result in a further exchange of
- messages. All such messages depend on the authentication method
- used, and the client MAY at any time continue with a new
- SSH_MSG_USERAUTH_REQUEST message, in which case the server MUST
- abandon the previous authentication attempt and continue with the new
- one.
-
-3.1.2 Responses to Authentication Requests
-
- If the server rejects the authentication request, it MUST respond
- with the following:
-
- byte SSH_MSG_USERAUTH_FAILURE
- string authentications that can continue
- boolean partial success
-
- "Authentications that can continue" is a comma-separated list of
- authentication method names that may productively continue the
- authentication dialog.
-
- It is RECOMMENDED that servers only include those methods in the list
- that are actually useful. However, it is not illegal to include
- methods that cannot be used to authenticate the user.
-
- Already successfully completed authentications SHOULD NOT be included
- in the list, unless they really should be performed again for some
- reason.
-
- "Partial success" MUST be TRUE if the authentication request to which
- this is a response was successful. It MUST be FALSE if the request
- was not successfully processed.
-
- When the server accepts authentication, it MUST respond with the
- following:
-
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 5]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
- byte SSH_MSG_USERAUTH_SUCCESS
-
- Note that this is not sent after each step in a multi-method
- authentication sequence, but only when the authentication is
- complete.
-
- The client MAY send several authentication requests without waiting
- for responses from previous requests. The server MUST process each
- request completely and acknowledge any failed requests with a
- SSH_MSG_USERAUTH_FAILURE message before processing the next request.
-
- A request that results in further exchange of messages will be
- aborted by a second request. It is not possible to send a second
- request without waiting for a response from the server, if the first
- request will result in further exchange of messages. No
- SSH_MSG_USERAUTH_FAILURE message will be sent for the aborted method.
-
- SSH_MSG_USERAUTH_SUCCESS MUST be sent only once. When
- SSH_MSG_USERAUTH_SUCCESS has been sent, any further authentication
- requests received after that SHOULD be silently ignored.
-
- Any non-authentication messages sent by the client after the request
- that resulted in SSH_MSG_USERAUTH_SUCCESS being sent MUST be passed
- to the service being run on top of this protocol. Such messages can
- be identified by their message numbers (see Section Message Numbers
- (Section 3.2)).
-
-3.1.3 The "none" Authentication Request
-
- A client may request a list of authentication methods that may
- continue by using the "none" authentication method.
-
- If no authentication at all is needed for the user, the server MUST
- return SSH_MSG_USERAUTH_SUCCESS. Otherwise, the server MUST return
- SSH_MSG_USERAUTH_FAILURE and MAY return with it a list of
- authentication methods that can continue.
-
- This method MUST NOT be listed as supported by the server.
-
-3.1.4 Completion of User Authentication
-
- Authentication is complete when the server has responded with
- SSH_MSG_USERAUTH_SUCCESS; all authentication related messages
- received after sending this message SHOULD be silently ignored.
-
- After sending SSH_MSG_USERAUTH_SUCCESS, the server starts the
- requested service.
-
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 6]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
-3.1.5 Banner Message
-
- In some jurisdictions, sending a warning message before
- authentication may be relevant for getting legal protection. Many
- UNIX machines, for example, normally display text from `/etc/issue',
- or use "tcp wrappers" or similar software to display a banner before
- issuing a login prompt.
-
- The SSH server may send a SSH_MSG_USERAUTH_BANNER message at any time
- before authentication is successful. This message contains text to
- be displayed to the client user before authentication is attempted.
- The format is as follows:
-
- byte SSH_MSG_USERAUTH_BANNER
- string message (ISO-10646 UTF-8)
- string language tag (as defined in [RFC3066])
-
- The client SHOULD by default display the message on the screen.
- However, since the message is likely to be sent for every login
- attempt, and since some client software will need to open a separate
- window for this warning, the client software may allow the user to
- explicitly disable the display of banners from the server. The
- message may consist of multiple lines.
-
- If the message string is displayed, control character filtering
- discussed in [SSH-ARCH] SHOULD be used to avoid attacks by sending
- terminal control characters.
-
-3.2 Authentication Protocol Message Numbers
-
- All message numbers used by this authentication protocol are in the
- range from 50 to 79, which is part of the range reserved for
- protocols running on top of the SSH transport layer protocol.
-
- Message numbers of 80 and higher are reserved for protocols running
- after this authentication protocol, so receiving one of them before
- authentication is complete is an error, to which the server MUST
- respond by disconnecting (preferably with a proper disconnect message
- sent first to ease troubleshooting).
-
- After successful authentication, such messages are passed to the
- higher-level service.
-
- These are the general authentication message codes:
-
- #define SSH_MSG_USERAUTH_REQUEST 50
- #define SSH_MSG_USERAUTH_FAILURE 51
- #define SSH_MSG_USERAUTH_SUCCESS 52
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 7]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
- #define SSH_MSG_USERAUTH_BANNER 53
-
- In addition to the above, there is a range of message numbers
- (60..79) reserved for method-specific messages. These messages are
- only sent by the server (client sends only SSH_MSG_USERAUTH_REQUEST
- messages). Different authentication methods reuse the same message
- numbers.
-
-3.3 Public Key Authentication Method: publickey
-
- The only REQUIRED authentication method is public key authentication.
- All implementations MUST support this method; however, not all users
- need to have public keys, and most local policies are not likely to
- require public key authentication for all users in the near future.
-
- With this method, the possession of a private key serves as
- authentication. This method works by sending a signature created
- with a private key of the user. The server MUST check that the key
- is a valid authenticator for the user, and MUST check that the
- signature is valid. If both hold, the authentication request MUST be
- accepted; otherwise it MUST be rejected. (Note that the server MAY
- require additional authentications after successful authentication.)
-
- Private keys are often stored in an encrypted form at the client
- host, and the user must supply a passphrase before the signature can
- be generated. Even if they are not, the signing operation involves
- some expensive computation. To avoid unnecessary processing and user
- interaction, the following message is provided for querying whether
- authentication using the key would be acceptable.
-
- byte SSH_MSG_USERAUTH_REQUEST
- string user name
- string service
- string "publickey"
- boolean FALSE
- string public key algorithm name
- string public key blob
-
- Public key algorithms are defined in the transport layer
- specification [SSH-TRANS]. The public key blob may contain
- certificates.
-
- Any public key algorithm may be offered for use in authentication.
- In particular, the list is not constrained by what was negotiated
- during key exchange. If the server does not support some algorithm,
- it MUST simply reject the request.
-
- The server MUST respond to this message with either
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 8]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
- SSH_MSG_USERAUTH_FAILURE or with the following:
-
- byte SSH_MSG_USERAUTH_PK_OK
- string public key algorithm name from the request
- string public key blob from the request
-
- To perform actual authentication, the client MAY then send a
- signature generated using the private key. The client MAY send the
- signature directly without first verifying whether the key is
- acceptable. The signature is sent using the following packet:
-
- byte SSH_MSG_USERAUTH_REQUEST
- string user name
- string service
- string "publickey"
- boolean TRUE
- string public key algorithm name
- string public key to be used for authentication
- string signature
-
- Signature is a signature by the corresponding private key over the
- following data, in the following order:
-
- string session identifier
- byte SSH_MSG_USERAUTH_REQUEST
- string user name
- string service
- string "publickey"
- boolean TRUE
- string public key algorithm name
- string public key to be used for authentication
-
- When the server receives this message, it MUST check whether the
- supplied key is acceptable for authentication, and if so, it MUST
- check whether the signature is correct.
-
- If both checks succeed, this method is successful. Note that the
- server may require additional authentications. The server MUST
- respond with SSH_MSG_USERAUTH_SUCCESS (if no more authentications are
- needed), or SSH_MSG_USERAUTH_FAILURE (if the request failed, or more
- authentications are needed).
-
- The following method-specific message numbers are used by the
- publickey authentication method.
-
- /* Key-based */
- #define SSH_MSG_USERAUTH_PK_OK 60
-
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 9]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
-3.4 Password Authentication Method: password
-
- Password authentication uses the following packets. Note that a
- server MAY request the user to change the password. All
- implementations SHOULD support password authentication.
-
- byte SSH_MSG_USERAUTH_REQUEST
- string user name
- string service
- string "password"
- boolean FALSE
- string plaintext password (ISO-10646 UTF-8)
-
- Note that the password is encoded in ISO-10646 UTF-8. It is up to
- the server how it interprets the password and validates it against
- the password database. However, if the client reads the password in
- some other encoding (e.g., ISO 8859-1 (ISO Latin1)), it MUST convert
- the password to ISO-10646 UTF-8 before transmitting, and the server
- MUST convert the password to the encoding used on that system for
- passwords.
-
- Note that even though the cleartext password is transmitted in the
- packet, the entire packet is encrypted by the transport layer. Both
- the server and the client should check whether the underlying
- transport layer provides confidentiality (i.e., if encryption is
- being used). If no confidentiality is provided (none cipher),
- password authentication SHOULD be disabled. If there is no
- confidentiality or no MAC, password change SHOULD be disabled.
-
- Normally, the server responds to this message with success or
- failure. However, if the password has expired the server SHOULD
- indicate this by responding with SSH_MSG_USERAUTH_PASSWD_CHANGEREQ.
- In anycase the server MUST NOT allow an expired password to be used
- for authentication.
-
- byte SSH_MSG_USERAUTH_PASSWD_CHANGEREQ
- string prompt (ISO-10646 UTF-8)
- string language tag (as defined in [RFC3066])
-
- In this case, the client MAY continue with a different authentication
- method, or request a new password from the user and retry password
- authentication using the following message. The client MAY also send
- this message instead of the normal password authentication request
- without the server asking for it.
-
- byte SSH_MSG_USERAUTH_REQUEST
- string user name
- string service
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 10]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
- string "password"
- boolean TRUE
- string plaintext old password (ISO-10646 UTF-8)
- string plaintext new password (ISO-10646 UTF-8)
-
- The server must reply to request message with
- SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, or another
- SSH_MSG_USERAUTH_PASSWD_CHANGEREQ. The meaning of these is as
- follows:
-
- SSH_MSG_USERAUTH_SUCCESS The password has been changed, and
- authentication has been successfully completed.
-
- SSH_MSG_USERAUTH_FAILURE with partial success The password has
- been changed, but more authentications are needed.
-
- SSH_MSG_USERAUTH_FAILURE without partial success The password has
- not been changed. Either password changing was not supported, or
- the old password was bad. Note that if the server has already
- sent SSH_MSG_USERAUTH_PASSWD_CHANGEREQ, we know that it supports
- changing the password.
-
- SSH_MSG_USERAUTH_CHANGEREQ The password was not changed because
- the new password was not acceptable (e.g. too easy to guess).
-
- The following method-specific message numbers are used by the
- password authentication method.
-
- #define SSH_MSG_USERAUTH_PASSWD_CHANGEREQ 60
-
-
-3.5 Host-Based Authentication: hostbased
-
- Some sites wish to allow authentication based on the host where the
- user is coming from, and the user name on the remote host. While
- this form of authentication is not suitable for high-security sites,
- it can be very convenient in many environments. This form of
- authentication is OPTIONAL. When used, special care SHOULD be taken
- to prevent a regular user from obtaining the private host key.
-
- The client requests this form of authentication by sending the
- following message. It is similar to the UNIX "rhosts" and
- "hosts.equiv" styles of authentication, except that the identity of
- the client host is checked more rigorously.
-
- This method works by having the client send a signature created with
- the private key of the client host, which the server checks with that
- host's public key. Once the client host's identity is established,
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 11]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
- authorization (but no further authentication) is performed based on
- the user names on the server and the client, and the client host
- name.
-
- byte SSH_MSG_USERAUTH_REQUEST
- string user name
- string service
- string "hostbased"
- string public key algorithm for host key
- string public host key and certificates for client host
- string client host name (FQDN; US-ASCII)
- string user name on the client host (ISO-10646 UTF-8)
- string signature
-
- Public key algorithm names for use in "public key algorithm for host
- key" are defined in the transport layer specification. The "public
- host key for client host" may include certificates.
-
- Signature is a signature with the private host key of the following
- data, in this order:
-
- string session identifier
- byte SSH_MSG_USERAUTH_REQUEST
- string user name
- string service
- string "hostbased"
- string public key algorithm for host key
- string public host key and certificates for client host
- string client host name (FQDN; US-ASCII)
- string user name on the client host(ISO-10646 UTF-8)
-
- The server MUST verify that the host key actually belongs to the
- client host named in the message, that the given user on that host is
- allowed to log in, and that the signature is a valid signature on the
- appropriate value by the given host key. The server MAY ignore the
- client user name, if it wants to authenticate only the client host.
-
- It is RECOMMENDED that whenever possible, the server perform
- additional checks to verify that the network address obtained from
- the (untrusted) network matches the given client host name. This
- makes exploiting compromised host keys more difficult. Note that
- this may require special handling for connections coming through a
- firewall.
-
-4. Security Considerations
-
- The purpose of this protocol is to perform client user
- authentication. It assumed that this runs over a secure transport
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 12]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
- layer protocol, which has already authenticated the server machine,
- established an encrypted communications channel, and computed a
- unique session identifier for this session. The transport layer
- provides forward secrecy for password authentication and other
- methods that rely on secret data.
-
- Full security considerations for this protocol are provided in
- Section 8 of [SSH-ARCH]
-
-Normative
-
- [SSH-ARCH]
- Ylonen, T., "SSH Protocol Architecture", I-D
- draft-ietf-architecture-15.txt, Oct 2003.
-
- [SSH-TRANS]
- Ylonen, T., "SSH Transport Layer Protocol", I-D
- draft-ietf-transport-17.txt, Oct 2003.
-
- [SSH-USERAUTH]
- Ylonen, T., "SSH Authentication Protocol", I-D
- draft-ietf-userauth-18.txt, Oct 2003.
-
- [SSH-CONNECT]
- Ylonen, T., "SSH Connection Protocol", I-D
- draft-ietf-connect-18.txt, Oct 2003.
-
- [SSH-NUMBERS]
- Lehtinen, S. and D. Moffat, "SSH Protocol Assigned
- Numbers", I-D draft-ietf-secsh-assignednumbers-05.txt, Oct
- 2003.
-
- [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
- Requirement Levels", BCP 14, RFC 2119, March 1997.
-
-Informative
-
- [RFC3066] Alvestrand, H., "Tags for the Identification of
- Languages", BCP 47, RFC 3066, January 2001.
-
- [RFC2279] Yergeau, F., "UTF-8, a transformation format of ISO
- 10646", RFC 2279, January 1998.
-
-
-
-
-
-
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 13]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
-Authors' Addresses
-
- Tatu Ylonen
- SSH Communications Security Corp
- Fredrikinkatu 42
- HELSINKI FIN-00100
- Finland
-
-
-
- Darren J. Moffat (editor)
- Sun Microsystems, Inc
- 17 Network Circle
- Menlo Park 95025
- USA
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 14]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
-Intellectual Property Statement
-
- The IETF takes no position regarding the validity or scope of any
- intellectual property or other rights that might be claimed to
- pertain to the implementation or use of the technology described in
- this document or the extent to which any license under such rights
- might or might not be available; neither does it represent that it
- has made any effort to identify any such rights. Information on the
- IETF's procedures with respect to rights in standards-track and
- standards-related documentation can be found in BCP-11. Copies of
- claims of rights made available for publication and any assurances of
- licenses to be made available, or the result of an attempt made to
- obtain a general license or permission for the use of such
- proprietary rights by implementors or users of this specification can
- be obtained from the IETF Secretariat.
-
- The IETF invites any interested party to bring to its attention any
- copyrights, patents or patent applications, or other proprietary
- rights which may cover technology that may be required to practice
- this standard. Please address the information to the IETF Executive
- Director.
-
- The IETF has been notified of intellectual property rights claimed in
- regard to some or all of the specification contained in this
- document. For more information consult the online list of claimed
- rights.
-
-
-Full Copyright Statement
-
- Copyright (C) The Internet Society (2002). All Rights Reserved.
-
- This document and translations of it may be copied and furnished to
- others, and derivative works that comment on or otherwise explain it
- or assist in its implementation may be prepared, copied, published
- and distributed, in whole or in part, without restriction of any
- kind, provided that the above copyright notice and this paragraph are
- included on all such copies and derivative works. However, this
- document itself may not be modified in any way, such as by removing
- the copyright notice or references to the Internet Society or other
- Internet organizations, except as needed for the purpose of
- developing Internet standards in which case the procedures for
- copyrights defined in the Internet Standards process must be
- followed, or as required to translate it into languages other than
- English.
-
- The limited permissions granted above are perpetual and will not be
- revoked by the Internet Society or its successors or assignees.
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 15]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
- This document and the information contained herein is provided on an
- "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
- TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
- BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
- HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
- MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-
-Acknowledgment
-
- Funding for the RFC Editor function is currently provided by the
- Internet Society.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 16] \ No newline at end of file
diff --git a/lib/ssh/src/ssh.erl b/lib/ssh/src/ssh.erl
index 132de71aed..54f94acbdc 100644
--- a/lib/ssh/src/ssh.erl
+++ b/lib/ssh/src/ssh.erl
@@ -33,7 +33,8 @@
default_algorithms/0,
stop_listener/1, stop_listener/2, stop_listener/3,
stop_daemon/1, stop_daemon/2, stop_daemon/3,
- shell/1, shell/2, shell/3]).
+ shell/1, shell/2, shell/3
+ ]).
%%--------------------------------------------------------------------
-spec start() -> ok | {error, term()}.
@@ -117,9 +118,9 @@ channel_info(ConnectionRef, ChannelId, Options) ->
ssh_connection_handler:channel_info(ConnectionRef, ChannelId, Options).
%%--------------------------------------------------------------------
--spec daemon(integer()) -> {ok, pid()}.
--spec daemon(integer(), proplists:proplist()) -> {ok, pid()}.
--spec daemon(any | inet:ip_address(), integer(), proplists:proplist()) -> {ok, pid()}.
+-spec daemon(integer()) -> {ok, pid()} | {error, term()}.
+-spec daemon(integer(), proplists:proplist()) -> {ok, pid()} | {error, term()}.
+-spec daemon(any | inet:ip_address(), integer(), proplists:proplist()) -> {ok, pid()} | {error, term()}.
%% Description: Starts a server listening for SSH connections
%% on the given port.
@@ -234,10 +235,27 @@ start_daemon(Host, Port, Options, Inet) ->
{error, _Reason} = Error ->
Error;
{SocketOptions, SshOptions}->
- do_start_daemon(Host, Port,[{role, server} |SshOptions] , [Inet | SocketOptions])
+ try
+ do_start_daemon(Host, Port,[{role, server} |SshOptions] , [Inet | SocketOptions])
+ catch
+ throw:bad_fd -> {error,bad_fd};
+ _C:_E -> {error,{cannot_start_daemon,_C,_E}}
+ end
end.
-do_start_daemon(Host, Port, Options, SocketOptions) ->
+do_start_daemon(Host0, Port0, Options, SocketOptions) ->
+ {Host,Port} = try
+ case proplists:get_value(fd, SocketOptions) of
+ undefined ->
+ {Host0,Port0};
+ Fd when Port0==0 ->
+ find_hostport(Fd);
+ _ ->
+ {Host0,Port0}
+ end
+ catch
+ _:_ -> throw(bad_fd)
+ end,
Profile = proplists:get_value(profile, Options, ?DEFAULT_PROFILE),
case ssh_system_sup:system_supervisor(Host, Port, Profile) of
undefined ->
@@ -271,6 +289,15 @@ do_start_daemon(Host, Port, Options, SocketOptions) ->
end
end.
+find_hostport(Fd) ->
+ %% Using internal functions inet:open/8 and inet:close/0.
+ %% Don't try this at home unless you know what you are doing!
+ {ok,S} = inet:open(Fd, {0,0,0,0}, 0, [], tcp, inet, stream, inet_tcp),
+ {ok, HostPort} = inet:sockname(S),
+ ok = inet:close(S),
+ HostPort.
+
+
handle_options(Opts) ->
try handle_option(algs_compatibility(proplists:unfold(Opts)), [], []) of
{Inet, Ssh} ->
@@ -281,32 +308,27 @@ handle_options(Opts) ->
end.
-algs_compatibility(Os) ->
+algs_compatibility(Os0) ->
%% Take care of old options 'public_key_alg' and 'pref_public_key_algs'
- comp_pk(proplists:get_value(preferred_algorithms,Os),
- proplists:get_value(pref_public_key_algs,Os),
- proplists:get_value(public_key_alg, Os),
- [{K,V} || {K,V} <- Os,
- K =/= public_key_alg,
- K =/= pref_public_key_algs]
- ).
-
-comp_pk(undefined, undefined, undefined, Os) -> Os;
-comp_pk( PrefAlgs, _, _, Os) when PrefAlgs =/= undefined -> Os;
-
-comp_pk(undefined, undefined, ssh_dsa, Os) -> comp_pk(undefined, undefined, 'ssh-dss', Os);
-comp_pk(undefined, undefined, ssh_rsa, Os) -> comp_pk(undefined, undefined, 'ssh-rsa', Os);
-comp_pk(undefined, undefined, PK, Os) ->
- PKs = [PK | ssh_transport:supported_algorithms(public_key)--[PK]],
- [{preferred_algorithms, [{public_key,PKs}] } | Os];
-
-comp_pk(undefined, PrefPKs, _, Os) when PrefPKs =/= undefined ->
- PKs = [case PK of
- ssh_dsa -> 'ssh-dss';
- ssh_rsa -> 'ssh-rsa';
- _ -> PK
- end || PK <- PrefPKs],
- [{preferred_algorithms, [{public_key,PKs}]} | Os].
+ case proplists:get_value(public_key_alg, Os0) of
+ undefined ->
+ Os0;
+ A when is_atom(A) ->
+ %% Skip public_key_alg if pref_public_key_algs is defined:
+ Os = lists:keydelete(public_key_alg, 1, Os0),
+ case proplists:get_value(pref_public_key_algs,Os) of
+ undefined when A == 'ssh-rsa' ; A==ssh_rsa ->
+ [{pref_public_key_algs,['ssh-rsa','ssh-dss']} | Os];
+ undefined when A == 'ssh-dss' ; A==ssh_dsa ->
+ [{pref_public_key_algs,['ssh-dss','ssh-rsa']} | Os];
+ undefined ->
+ throw({error, {eoptions, {public_key_alg,A} }});
+ _ ->
+ Os
+ end;
+ V ->
+ throw({error, {eoptions, {public_key_alg,V} }})
+ end.
handle_option([], SocketOptions, SshOptions) ->
@@ -335,7 +357,13 @@ handle_option([{user_passwords, _} = Opt | Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{pwdfun, _} = Opt | Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{key_cb, _} = Opt | Rest], SocketOptions, SshOptions) ->
+handle_option([{key_cb, {Module, Options}} | Rest], SocketOptions, SshOptions) ->
+ handle_option(Rest, SocketOptions, [handle_ssh_option({key_cb, Module}),
+ handle_ssh_priv_option({key_cb_private, Options}) |
+ SshOptions]);
+handle_option([{key_cb, Module} | Rest], SocketOptions, SshOptions) ->
+ handle_option([{key_cb, {Module, []}} | Rest], SocketOptions, SshOptions);
+handle_option([{keyboard_interact_fun, _} = Opt | Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
%%Backwards compatibility
handle_option([{allow_user_interaction, Value} | Rest], SocketOptions, SshOptions) ->
@@ -371,6 +399,8 @@ handle_option([{auth_methods, _} = Opt | Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{auth_method_kb_interactive_data, _} = Opt | Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
+handle_option([{pref_public_key_algs, _} = Opt | Rest], SocketOptions, SshOptions) ->
+ handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{preferred_algorithms,_} = Opt | Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{dh_gex_groups,_} = Opt | Rest], SocketOptions, SshOptions) ->
@@ -385,12 +415,15 @@ handle_option([{rekey_limit, _} = Opt|Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{max_sessions, _} = Opt|Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
+handle_option([{max_channels, _} = Opt|Rest], SocketOptions, SshOptions) ->
+ handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{negotiation_timeout, _} = Opt|Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{parallel_login, _} = Opt|Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([parallel_login|Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option({parallel_login,true}) | SshOptions]);
+%% (Is handled by proplists:unfold above:)
+%% handle_option([parallel_login|Rest], SocketOptions, SshOptions) ->
+%% handle_option(Rest, SocketOptions, [handle_ssh_option({parallel_login,true}) | SshOptions]);
handle_option([{minimal_remote_max_packet_size, _} = Opt|Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{id_string, _ID} = Opt|Rest], SocketOptions, SshOptions) ->
@@ -417,32 +450,81 @@ handle_ssh_option({user_interaction, Value} = Opt) when is_boolean(Value) ->
Opt;
handle_ssh_option({preferred_algorithms,[_|_]} = Opt) ->
handle_pref_algs(Opt);
-handle_ssh_option({dh_gex_groups,L=[{I1,I2,I3}|_]}) when is_integer(I1), I1>0,
- is_integer(I2), I2>0,
- is_integer(I3), I3>0 ->
- {dh_gex_groups, lists:map(fun({N,G,P}) -> {N,{G,P}} end, L)};
-handle_ssh_option({dh_gex_groups,{file,File=[C|_]}}=Opt) when is_integer(C), C>0 ->
- %% A string, (file name)
- case file:consult(File) of
- {ok, List} ->
- try handle_ssh_option({dh_gex_groups,List}) of
- {dh_gex_groups,_} = NewOpt ->
- NewOpt
- catch
- _:_ ->
- throw({error, {{eoptions, Opt}, "Bad format in file"}})
- end;
- Error ->
- throw({error, {{eoptions, Opt},{"Error reading file",Error}}})
- end;
+
+handle_ssh_option({dh_gex_groups,L0}) when is_list(L0) ->
+ {dh_gex_groups,
+ collect_per_size(
+ lists:foldl(
+ fun({N,G,P}, Acc) when is_integer(N),N>0,
+ is_integer(G),G>0,
+ is_integer(P),P>0 ->
+ [{N,{G,P}} | Acc];
+ ({N,{G,P}}, Acc) when is_integer(N),N>0,
+ is_integer(G),G>0,
+ is_integer(P),P>0 ->
+ [{N,{G,P}} | Acc];
+ ({N,GPs}, Acc) when is_list(GPs) ->
+ lists:foldr(fun({Gi,Pi}, Acci) when is_integer(Gi),Gi>0,
+ is_integer(Pi),Pi>0 ->
+ [{N,{Gi,Pi}} | Acci]
+ end, Acc, GPs)
+ end, [], L0))};
+
+handle_ssh_option({dh_gex_groups,{Tag,File=[C|_]}}=Opt) when is_integer(C), C>0,
+ Tag == file ;
+ Tag == ssh_moduli_file ->
+ {ok,GroupDefs} =
+ case Tag of
+ file ->
+ file:consult(File);
+ ssh_moduli_file ->
+ case file:open(File,[read]) of
+ {ok,D} ->
+ try
+ {ok,Moduli} = read_moduli_file(D, 1, []),
+ file:close(D),
+ {ok, Moduli}
+ catch
+ _:_ ->
+ throw({error, {{eoptions, Opt}, "Bad format in file "++File}})
+ end;
+ {error,enoent} ->
+ throw({error, {{eoptions, Opt}, "File not found:"++File}});
+ {error,Error} ->
+ throw({error, {{eoptions, Opt}, io_lib:format("Error reading file ~s: ~p",[File,Error])}})
+ end
+ end,
+
+ try
+ handle_ssh_option({dh_gex_groups,GroupDefs})
+ catch
+ _:_ ->
+ throw({error, {{eoptions, Opt}, "Bad format in file: "++File}})
+ end;
+
+
+handle_ssh_option({dh_gex_limits,{Min,Max}} = Opt) when is_integer(Min), Min>0,
+ is_integer(Max), Max>=Min ->
+ %% Server
+ Opt;
handle_ssh_option({dh_gex_limits,{Min,I,Max}} = Opt) when is_integer(Min), Min>0,
is_integer(I), I>=Min,
is_integer(Max), Max>=I ->
+ %% Client
Opt;
+handle_ssh_option({pref_public_key_algs, Value} = Opt) when is_list(Value), length(Value) >= 1 ->
+ case handle_user_pref_pubkey_algs(Value, []) of
+ {true, NewOpts} ->
+ {pref_public_key_algs, NewOpts};
+ _ ->
+ throw({error, {eoptions, Opt}})
+ end;
handle_ssh_option({connect_timeout, Value} = Opt) when is_integer(Value); Value == infinity ->
Opt;
handle_ssh_option({max_sessions, Value} = Opt) when is_integer(Value), Value>0 ->
Opt;
+handle_ssh_option({max_channels, Value} = Opt) when is_integer(Value), Value>0 ->
+ Opt;
handle_ssh_option({negotiation_timeout, Value} = Opt) when is_integer(Value); Value == infinity ->
Opt;
handle_ssh_option({parallel_login, Value} = Opt) when Value==true ; Value==false ->
@@ -457,10 +539,17 @@ handle_ssh_option({password, Value} = Opt) when is_list(Value) ->
Opt;
handle_ssh_option({user_passwords, Value} = Opt) when is_list(Value)->
Opt;
-handle_ssh_option({pwdfun, Value} = Opt) when is_function(Value) ->
+handle_ssh_option({pwdfun, Value} = Opt) when is_function(Value,2) ->
+ Opt;
+handle_ssh_option({pwdfun, Value} = Opt) when is_function(Value,4) ->
Opt;
handle_ssh_option({key_cb, Value} = Opt) when is_atom(Value) ->
Opt;
+handle_ssh_option({key_cb, {CallbackMod, CallbackOptions}} = Opt) when is_atom(CallbackMod),
+ is_list(CallbackOptions) ->
+ Opt;
+handle_ssh_option({keyboard_interact_fun, Value} = Opt) when is_function(Value,3) ->
+ Opt;
handle_ssh_option({compression, Value} = Opt) when is_atom(Value) ->
Opt;
handle_ssh_option({exec, {Module, Function, _}} = Opt) when is_atom(Module),
@@ -525,6 +614,9 @@ handle_ssh_option({profile, Value} = Opt) when is_atom(Value) ->
handle_ssh_option(Opt) ->
throw({error, {eoptions, Opt}}).
+handle_ssh_priv_option({key_cb_private, Value} = Opt) when is_list(Value) ->
+ Opt.
+
handle_inet_option({active, _} = Opt) ->
throw({error, {{eoptions, Opt}, "SSH has built in flow control, "
"and active is handled internally, user is not allowed"
@@ -655,3 +747,46 @@ directory_exist_readable(Dir) ->
+collect_per_size(L) ->
+ lists:foldr(
+ fun({Sz,GP}, [{Sz,GPs}|Acc]) -> [{Sz,[GP|GPs]}|Acc];
+ ({Sz,GP}, Acc) -> [{Sz,[GP]}|Acc]
+ end, [], lists:sort(L)).
+
+read_moduli_file(D, I, Acc) ->
+ case io:get_line(D,"") of
+ {error,Error} ->
+ {error,Error};
+ eof ->
+ {ok, Acc};
+ "#" ++ _ -> read_moduli_file(D, I+1, Acc);
+ <<"#",_/binary>> -> read_moduli_file(D, I+1, Acc);
+ Data ->
+ Line = if is_binary(Data) -> binary_to_list(Data);
+ is_list(Data) -> Data
+ end,
+ try
+ [_Time,_Type,_Tests,_Tries,Size,G,P] = string:tokens(Line," \r\n"),
+ M = {list_to_integer(Size),
+ {list_to_integer(G), list_to_integer(P,16)}
+ },
+ read_moduli_file(D, I+1, [M|Acc])
+ catch
+ _:_ ->
+ read_moduli_file(D, I+1, Acc)
+ end
+ end.
+
+handle_user_pref_pubkey_algs([], Acc) ->
+ {true, lists:reverse(Acc)};
+handle_user_pref_pubkey_algs([H|T], Acc) ->
+ case lists:member(H, ?SUPPORTED_USER_KEYS) of
+ true ->
+ handle_user_pref_pubkey_algs(T, [H| Acc]);
+
+ false when H==ssh_dsa -> handle_user_pref_pubkey_algs(T, ['ssh-dss'| Acc]);
+ false when H==ssh_rsa -> handle_user_pref_pubkey_algs(T, ['ssh-rsa'| Acc]);
+
+ false ->
+ false
+ end.
diff --git a/lib/ssh/src/ssh.hrl b/lib/ssh/src/ssh.hrl
index 462c98f503..f88098819d 100644
--- a/lib/ssh/src/ssh.hrl
+++ b/lib/ssh/src/ssh.hrl
@@ -29,21 +29,26 @@
-define(SSH_DEFAULT_PORT, 22).
-define(SSH_MAX_PACKET_SIZE, (256*1024)).
--define(SSH_LENGHT_INDICATOR_SIZE, 4).
-define(REKEY_TIMOUT, 3600000).
-define(REKEY_DATA_TIMOUT, 60000).
-define(DEFAULT_PROFILE, default).
+-define(SUPPORTED_AUTH_METHODS, "publickey,keyboard-interactive,password").
+-define(SUPPORTED_USER_KEYS, ['ssh-rsa','ssh-dss','ecdsa-sha2-nistp256','ecdsa-sha2-nistp384','ecdsa-sha2-nistp521']).
+
-define(FALSE, 0).
-define(TRUE, 1).
%% basic binary constructors
--define(BOOLEAN(X), X:8/unsigned-big-integer).
--define(BYTE(X), X:8/unsigned-big-integer).
--define(UINT16(X), X:16/unsigned-big-integer).
--define(UINT32(X), X:32/unsigned-big-integer).
--define(UINT64(X), X:64/unsigned-big-integer).
+-define(BOOLEAN(X), (X):8/unsigned-big-integer).
+-define(BYTE(X), (X):8/unsigned-big-integer).
+-define(UINT16(X), (X):16/unsigned-big-integer).
+-define(UINT32(X), (X):32/unsigned-big-integer).
+-define(UINT64(X), (X):64/unsigned-big-integer).
-define(STRING(X), ?UINT32((size(X))), (X)/binary).
+-define(DEC_BIN(X,Len), ?UINT32(Len), X:Len/binary ).
+-define(DEC_MPINT(I,Len), ?UINT32(Len), I:Len/big-signed-integer-unit:8 ).
+
%% building macros
-define(boolean(X),
case X of
@@ -133,9 +138,9 @@
userauth_supported_methods, % string() eg "keyboard-interactive,password"
userauth_methods, % list( string() ) eg ["keyboard-interactive", "password"]
kb_tries_left = 0, % integer(), num tries left for "keyboard-interactive"
- kb_data,
userauth_preference,
available_host_keys,
+ pwdfun_user_state,
authenticated = false
}).
diff --git a/lib/ssh/src/ssh_acceptor.erl b/lib/ssh/src/ssh_acceptor.erl
index c5ad1d7b6c..d94dedf1bf 100644
--- a/lib/ssh/src/ssh_acceptor.erl
+++ b/lib/ssh/src/ssh_acceptor.erl
@@ -56,7 +56,12 @@ acceptor_init(Parent, Port, Address, SockOpts, Opts, AcceptTimeout) ->
error
end.
-do_socket_listen(Callback, Port, Opts) ->
+do_socket_listen(Callback, Port0, Opts) ->
+ Port =
+ case proplists:get_value(fd, Opts) of
+ undefined -> Port0;
+ _ -> 0
+ end,
case Callback:listen(Port, Opts) of
{error, nxdomain} ->
Callback:listen(Port, lists:delete(inet6, Opts));
diff --git a/lib/ssh/src/ssh_auth.erl b/lib/ssh/src/ssh_auth.erl
index a91b8c200e..fdbb5c152a 100644
--- a/lib/ssh/src/ssh_auth.erl
+++ b/lib/ssh/src/ssh_auth.erl
@@ -31,8 +31,7 @@
-export([publickey_msg/1, password_msg/1, keyboard_interactive_msg/1,
service_request_msg/1, init_userauth_request_msg/1,
userauth_request_msg/1, handle_userauth_request/3,
- handle_userauth_info_request/3, handle_userauth_info_response/2,
- default_public_key_algorithms/0
+ handle_userauth_info_request/3, handle_userauth_info_response/2
]).
%%--------------------------------------------------------------------
@@ -42,27 +41,29 @@ publickey_msg([Alg, #ssh{user = User,
session_id = SessionId,
service = Service,
opts = Opts} = Ssh]) ->
-
Hash = sha, %% Maybe option?!
KeyCb = proplists:get_value(key_cb, Opts, ssh_file),
-
case KeyCb:user_key(Alg, Opts) of
- {ok, Key} ->
- StrAlgo = algorithm_string(Alg),
- PubKeyBlob = encode_public_key(Key),
- SigData = build_sig_data(SessionId,
- User, Service, PubKeyBlob, StrAlgo),
- Sig = ssh_transport:sign(SigData, Hash, Key),
- SigBlob = list_to_binary([?string(StrAlgo), ?binary(Sig)]),
- ssh_transport:ssh_packet(
- #ssh_msg_userauth_request{user = User,
- service = Service,
- method = "publickey",
- data = [?TRUE,
- ?string(StrAlgo),
- ?binary(PubKeyBlob),
- ?binary(SigBlob)]},
- Ssh);
+ {ok, PrivKey} ->
+ StrAlgo = atom_to_list(Alg),
+ case encode_public_key(StrAlgo, ssh_transport:extract_public_key(PrivKey)) of
+ not_ok ->
+ not_ok;
+ PubKeyBlob ->
+ SigData = build_sig_data(SessionId,
+ User, Service, PubKeyBlob, StrAlgo),
+ Sig = ssh_transport:sign(SigData, Hash, PrivKey),
+ SigBlob = list_to_binary([?string(StrAlgo), ?binary(Sig)]),
+ ssh_transport:ssh_packet(
+ #ssh_msg_userauth_request{user = User,
+ service = Service,
+ method = "publickey",
+ data = [?TRUE,
+ ?string(StrAlgo),
+ ?binary(PubKeyBlob),
+ ?binary(SigBlob)]},
+ Ssh)
+ end;
_Error ->
not_ok
end.
@@ -117,11 +118,16 @@ init_userauth_request_msg(#ssh{opts = Opts} = Ssh) ->
service = "ssh-connection",
method = "none",
data = <<>>},
+ Algs0 = proplists:get_value(pref_public_key_algs, Opts, ?SUPPORTED_USER_KEYS),
+ %% The following line is not strictly correct. The call returns the
+ %% supported HOST key types while we are interested in USER keys. However,
+ %% they "happens" to be the same (for now). This could change....
+ %% There is no danger as long as the set of user keys is a subset of the set
+ %% of host keys.
+ CryptoSupported = ssh_transport:supported_algorithms(public_key),
+ Algs = [A || A <- Algs0,
+ lists:member(A, CryptoSupported)],
-
- Algs = proplists:get_value(public_key,
- proplists:get_value(preferred_algorithms, Opts, []),
- default_public_key_algorithms()),
Prefs = method_preference(Algs),
ssh_transport:ssh_packet(Msg, Ssh#ssh{user = User,
userauth_preference = Prefs,
@@ -153,7 +159,7 @@ userauth_request_msg(#ssh{userauth_methods = Methods,
not_ok ->
userauth_request_msg(Ssh);
Result ->
- Result
+ {Pref,Result}
end;
false ->
userauth_request_msg(Ssh)
@@ -173,15 +179,15 @@ handle_userauth_request(#ssh_msg_userauth_request{user = User,
#ssh{opts = Opts,
userauth_supported_methods = Methods} = Ssh) ->
Password = unicode:characters_to_list(BinPwd),
- case check_password(User, Password, Opts) of
- true ->
+ case check_password(User, Password, Opts, Ssh) of
+ {true,Ssh1} ->
{authorized, User,
- ssh_transport:ssh_packet(#ssh_msg_userauth_success{}, Ssh)};
- false ->
+ ssh_transport:ssh_packet(#ssh_msg_userauth_success{}, Ssh1)};
+ {false,Ssh1} ->
{not_authorized, {User, {error,"Bad user or password"}},
ssh_transport:ssh_packet(#ssh_msg_userauth_failure{
authentications = Methods,
- partial_success = false}, Ssh)}
+ partial_success = false}, Ssh1)}
end;
handle_userauth_request(#ssh_msg_userauth_request{user = User,
@@ -299,8 +305,7 @@ handle_userauth_request(#ssh_msg_userauth_request{user = User,
>>
},
{not_authorized, {User, undefined},
- ssh_transport:ssh_packet(Msg, Ssh#ssh{user = User,
- kb_data = Msg
+ ssh_transport:ssh_packet(Msg, Ssh#ssh{user = User
})}
end;
@@ -313,6 +318,8 @@ handle_userauth_request(#ssh_msg_userauth_request{user = User,
#ssh_msg_userauth_failure{authentications = Methods,
partial_success = false}, Ssh)}.
+
+
handle_userauth_info_request(
#ssh_msg_userauth_info_request{name = Name,
instruction = Instr,
@@ -330,36 +337,19 @@ handle_userauth_info_request(
handle_userauth_info_response(#ssh_msg_userauth_info_response{num_responses = 1,
data = <<?UINT32(Sz), Password:Sz/binary>>},
#ssh{opts = Opts,
- kb_tries_left = KbTriesLeft0,
- kb_data = InfoMsg,
+ kb_tries_left = KbTriesLeft,
user = User,
userauth_supported_methods = Methods} = Ssh) ->
- KbTriesLeft = KbTriesLeft0 - 1,
- case check_password(User, unicode:characters_to_list(Password), Opts) of
- true ->
+ case check_password(User, unicode:characters_to_list(Password), Opts, Ssh) of
+ {true,Ssh1} ->
{authorized, User,
- ssh_transport:ssh_packet(#ssh_msg_userauth_success{}, Ssh)};
- false when KbTriesLeft > 0 ->
- UserAuthInfoMsg =
- InfoMsg#ssh_msg_userauth_info_request{
- name = "",
- instruction =
- lists:concat(
- ["Bad user or password, try again. ",
- integer_to_list(KbTriesLeft),
- " tries left."])
- },
- {not_authorized, {User, undefined},
- ssh_transport:ssh_packet(UserAuthInfoMsg,
- Ssh#ssh{kb_tries_left = KbTriesLeft})};
-
- false ->
+ ssh_transport:ssh_packet(#ssh_msg_userauth_success{}, Ssh1)};
+ {false,Ssh1} ->
{not_authorized, {User, {error,"Bad user or password"}},
ssh_transport:ssh_packet(#ssh_msg_userauth_failure{
authentications = Methods,
partial_success = false},
- Ssh#ssh{kb_data = undefined,
- kb_tries_left = 0}
+ Ssh1#ssh{kb_tries_left = max(KbTriesLeft-1, 0)}
)}
end;
@@ -371,8 +361,6 @@ handle_userauth_info_response(#ssh_msg_userauth_info_response{},
language = "en"}).
-default_public_key_algorithms() -> ?PREFERRED_PK_ALGS.
-
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
@@ -381,6 +369,11 @@ method_preference(Algs) ->
[{"publickey", ?MODULE, publickey_msg, [A]} | Acc]
end,
[{"password", ?MODULE, password_msg, []},
+ {"keyboard-interactive", ?MODULE, keyboard_interactive_msg, []},
+ {"keyboard-interactive", ?MODULE, keyboard_interactive_msg, []},
+ {"keyboard-interactive", ?MODULE, keyboard_interactive_msg, []},
+ {"keyboard-interactive", ?MODULE, keyboard_interactive_msg, []},
+ {"keyboard-interactive", ?MODULE, keyboard_interactive_msg, []},
{"keyboard-interactive", ?MODULE, keyboard_interactive_msg, []}
],
Algs).
@@ -404,13 +397,34 @@ user_name(Opts) ->
{ok, User}
end.
-check_password(User, Password, Opts) ->
+check_password(User, Password, Opts, Ssh) ->
case proplists:get_value(pwdfun, Opts) of
undefined ->
Static = get_password_option(Opts, User),
- Password == Static;
- Cheker ->
- Cheker(User, Password)
+ {Password == Static, Ssh};
+
+ Checker when is_function(Checker,2) ->
+ {Checker(User, Password), Ssh};
+
+ Checker when is_function(Checker,4) ->
+ #ssh{pwdfun_user_state = PrivateState,
+ peer = {_,PeerAddr={_,_}}
+ } = Ssh,
+ case Checker(User, Password, PeerAddr, PrivateState) of
+ true ->
+ {true,Ssh};
+ false ->
+ {false,Ssh};
+ {true,NewState} ->
+ {true, Ssh#ssh{pwdfun_user_state=NewState}};
+ {false,NewState} ->
+ {false, Ssh#ssh{pwdfun_user_state=NewState}};
+ disconnect ->
+ throw(#ssh_msg_disconnect{code = ?SSH_DISCONNECT_SERVICE_NOT_AVAILABLE,
+ description =
+ "Unable to connect using the available authentication methods",
+ language = ""})
+ end
end.
get_password_option(Opts, User) ->
@@ -447,10 +461,7 @@ build_sig_data(SessionId, User, Service, KeyBlob, Alg) ->
?binary(KeyBlob)],
list_to_binary(Sig).
-algorithm_string('ssh-rsa') ->
- "ssh-rsa";
-algorithm_string('ssh-dss') ->
- "ssh-dss".
+
decode_keyboard_interactive_prompts(_NumPrompts, Data) ->
ssh_message:decode_keyboard_interactive_prompts(Data, []).
@@ -471,14 +482,14 @@ keyboard_interact_get_responses(false, undefined, undefined, _, _, _, [Prompt|_]
ssh_no_io:read_line(Prompt, Opts); %% Throws error as keyboard interaction is not allowed
keyboard_interact_get_responses(true, undefined, _,IoCb, Name, Instr, PromptInfos, Opts, _) ->
keyboard_interact(IoCb, Name, Instr, PromptInfos, Opts);
-keyboard_interact_get_responses(true, Fun, _, Name, Instr, PromptInfos, _, _, NumPrompts) ->
+keyboard_interact_get_responses(true, Fun, _Pwd, _IoCb, Name, Instr, PromptInfos, _Opts, NumPrompts) ->
keyboard_interact_fun(Fun, Name, Instr, PromptInfos, NumPrompts).
keyboard_interact(IoCb, Name, Instr, Prompts, Opts) ->
- if Name /= "" -> IoCb:format("~s", [Name]);
+ if Name /= "" -> IoCb:format("~s~n", [Name]);
true -> ok
end,
- if Instr /= "" -> IoCb:format("~s", [Instr]);
+ if Instr /= "" -> IoCb:format("~s~n", [Instr]);
true -> ok
end,
lists:map(fun({Prompt, true}) -> IoCb:read_line(Prompt, Opts);
@@ -501,23 +512,18 @@ keyboard_interact_fun(KbdInteractFun, Name, Instr, PromptInfos, NumPrompts) ->
language = "en"}})
end.
-decode_public_key_v2(<<?UINT32(Len0), _:Len0/binary,
- ?UINT32(Len1), E:Len1/big-signed-integer-unit:8,
- ?UINT32(Len2), N:Len2/big-signed-integer-unit:8>>
- ,"ssh-rsa") ->
- {ok, #'RSAPublicKey'{publicExponent = E, modulus = N}};
-decode_public_key_v2(<<?UINT32(Len0), _:Len0/binary,
- ?UINT32(Len1), P:Len1/big-signed-integer-unit:8,
- ?UINT32(Len2), Q:Len2/big-signed-integer-unit:8,
- ?UINT32(Len3), G:Len3/big-signed-integer-unit:8,
- ?UINT32(Len4), Y:Len4/big-signed-integer-unit:8>>
- , "ssh-dss") ->
- {ok, {Y, #'Dss-Parms'{p = P, q = Q, g = G}}};
-
-decode_public_key_v2(_, _) ->
- {error, bad_format}.
-
-encode_public_key(#'RSAPrivateKey'{publicExponent = E, modulus = N}) ->
- ssh_bits:encode(["ssh-rsa",E,N], [string,mpint,mpint]);
-encode_public_key(#'DSAPrivateKey'{p = P, q = Q, g = G, y = Y}) ->
- ssh_bits:encode(["ssh-dss",P,Q,G,Y], [string,mpint,mpint,mpint,mpint]).
+decode_public_key_v2(Bin, _Type) ->
+ try
+ public_key:ssh_decode(Bin, ssh2_pubkey)
+ of
+ Key -> {ok, Key}
+ catch
+ _:_ -> {error, bad_format}
+ end.
+
+encode_public_key(_Alg, Key) ->
+ try
+ public_key:ssh_encode(Key, ssh2_pubkey)
+ catch
+ _:_ -> not_ok
+ end.
diff --git a/lib/ssh/src/ssh_auth.hrl b/lib/ssh/src/ssh_auth.hrl
index 71f222f6d7..449bc4fa45 100644
--- a/lib/ssh/src/ssh_auth.hrl
+++ b/lib/ssh/src/ssh_auth.hrl
@@ -22,9 +22,6 @@
%%% Description: Ssh User Authentication Protocol
--define(SUPPORTED_AUTH_METHODS, "publickey,keyboard-interactive,password").
-
--define(PREFERRED_PK_ALGS, ['ssh-rsa','ssh-dss']).
-define(SSH_MSG_USERAUTH_REQUEST, 50).
-define(SSH_MSG_USERAUTH_FAILURE, 51).
diff --git a/lib/ssh/src/ssh_connect.hrl b/lib/ssh/src/ssh_connect.hrl
index 6db89c5d80..9f9f3de8fa 100644
--- a/lib/ssh/src/ssh_connect.hrl
+++ b/lib/ssh/src/ssh_connect.hrl
@@ -248,6 +248,9 @@
local_id, %% local channel id
recv_window_size,
+ recv_window_pending = 0, %% Sum of window size updates that has not
+ %% yet been sent. This limits the number
+ %% of sent update msgs.
recv_packet_size,
recv_close = false,
diff --git a/lib/ssh/src/ssh_connection.erl b/lib/ssh/src/ssh_connection.erl
index 64d2113125..a34478732c 100644
--- a/lib/ssh/src/ssh_connection.erl
+++ b/lib/ssh/src/ssh_connection.erl
@@ -662,7 +662,7 @@ handle_msg(#ssh_msg_channel_request{recipient_channel = ChannelId,
ReplyMsg = {subsystem, ChannelId, WantReply, binary_to_list(SsName)},
try
- {ok, Pid} = start_subsytem(SsName, Connection, Channel0, ReplyMsg),
+ {ok, Pid} = start_subsystem(SsName, Connection, Channel0, ReplyMsg),
erlang:monitor(process, Pid),
Channel = Channel0#channel{user = Pid},
ssh_channel:cache_update(Cache, Channel),
@@ -935,14 +935,27 @@ encode_ip(Addr) when is_list(Addr) ->
end
end.
-start_channel(Cb, Id, Args, SubSysSup) ->
- start_channel(Cb, Id, Args, SubSysSup, undefined).
+start_channel(Cb, Id, Args, SubSysSup, Opts) ->
+ start_channel(Cb, Id, Args, SubSysSup, undefined, Opts).
-start_channel(Cb, Id, Args, SubSysSup, Exec) ->
+start_channel(Cb, Id, Args, SubSysSup, Exec, Opts) ->
ChildSpec = child_spec(Cb, Id, Args, Exec),
ChannelSup = ssh_subsystem_sup:channel_supervisor(SubSysSup),
+ assert_limit_num_channels_not_exceeded(ChannelSup, Opts),
ssh_channel_sup:start_child(ChannelSup, ChildSpec).
+assert_limit_num_channels_not_exceeded(ChannelSup, Opts) ->
+ MaxNumChannels = proplists:get_value(max_channels, Opts, infinity),
+ NumChannels = length([x || {_,_,worker,[ssh_channel]} <-
+ supervisor:which_children(ChannelSup)]),
+ if
+ %% Note that NumChannels is BEFORE starting a new one
+ NumChannels < MaxNumChannels ->
+ ok;
+ true ->
+ throw(max_num_channels_exceeded)
+ end.
+
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
@@ -998,17 +1011,19 @@ child_spec(Callback, Id, Args, Exec) ->
start_cli(#connection{cli_spec = no_cli}, _) ->
{error, cli_disabled};
-start_cli(#connection{cli_spec = {CbModule, Args}, exec = Exec,
+start_cli(#connection{options = Options,
+ cli_spec = {CbModule, Args},
+ exec = Exec,
sub_system_supervisor = SubSysSup}, ChannelId) ->
- start_channel(CbModule, ChannelId, Args, SubSysSup, Exec).
+ start_channel(CbModule, ChannelId, Args, SubSysSup, Exec, Options).
-start_subsytem(BinName, #connection{options = Options,
+start_subsystem(BinName, #connection{options = Options,
sub_system_supervisor = SubSysSup},
#channel{local_id = ChannelId}, _ReplyMsg) ->
Name = binary_to_list(BinName),
case check_subsystem(Name, Options) of
{Callback, Opts} when is_atom(Callback), Callback =/= none ->
- start_channel(Callback, ChannelId, Opts, SubSysSup);
+ start_channel(Callback, ChannelId, Opts, SubSysSup, Options);
{Other, _} when Other =/= none ->
{error, legacy_option_not_supported}
end.
diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl
index fcd66b80c0..516a09bf6a 100644
--- a/lib/ssh/src/ssh_connection_handler.erl
+++ b/lib/ssh/src/ssh_connection_handler.erl
@@ -49,7 +49,10 @@
-export([hello/2, kexinit/2, key_exchange/2,
key_exchange_dh_gex_init/2, key_exchange_dh_gex_reply/2,
new_keys/2,
- userauth/2, connected/2,
+ service_request/2, connected/2,
+ userauth/2,
+ userauth_keyboard_interactive/2,
+ userauth_keyboard_interactive_info_response/2,
error/2]).
-export([init/1, handle_event/3,
@@ -82,7 +85,12 @@
recbuf
}).
--type state_name() :: hello | kexinit | key_exchange | new_keys | userauth | connection.
+-type state_name() :: hello | kexinit | key_exchange | key_exchange_dh_gex_init |
+ key_exchange_dh_gex_reply | new_keys | service_request |
+ userauth | userauth_keyboard_interactive |
+ userauth_keyboard_interactive_info_response |
+ connection.
+
-type gen_fsm_state_return() :: {next_state, state_name(), term()} |
{next_state, state_name(), term(), timeout()} |
{stop, term(), term()}.
@@ -425,6 +433,12 @@ key_exchange(#ssh_msg_kex_dh_gex_request{} = Msg,
send_msg(GexGroup, State),
{next_state, key_exchange_dh_gex_init, next_packet(State#state{ssh_params = Ssh})};
+key_exchange(#ssh_msg_kex_dh_gex_request_old{} = Msg,
+ #state{ssh_params = #ssh{role = server} = Ssh0} = State) ->
+ {ok, GexGroup, Ssh} = ssh_transport:handle_kex_dh_gex_request(Msg, Ssh0),
+ send_msg(GexGroup, State),
+ {next_state, key_exchange_dh_gex_init, next_packet(State#state{ssh_params = Ssh})};
+
key_exchange(#ssh_msg_kex_dh_gex_group{} = Msg,
#state{ssh_params = #ssh{role = client} = Ssh0} = State) ->
{ok, KexGexInit, Ssh} = ssh_transport:handle_kex_dh_gex_group(Msg, Ssh0),
@@ -474,28 +488,30 @@ new_keys(#ssh_msg_newkeys{} = Msg, #state{ssh_params = Ssh0} = State0) ->
after_new_keys(next_packet(State0#state{ssh_params = Ssh})).
%%--------------------------------------------------------------------
--spec userauth(#ssh_msg_service_request{} | #ssh_msg_service_accept{} |
- #ssh_msg_userauth_request{} | #ssh_msg_userauth_info_request{} |
- #ssh_msg_userauth_info_response{} | #ssh_msg_userauth_success{} |
- #ssh_msg_userauth_failure{} | #ssh_msg_userauth_banner{},
- #state{}) -> gen_fsm_state_return().
+-spec service_request(#ssh_msg_service_request{} | #ssh_msg_service_accept{},
+ #state{}) -> gen_fsm_state_return().
%%--------------------------------------------------------------------
-
-userauth(#ssh_msg_service_request{name = "ssh-userauth"} = Msg,
+service_request(#ssh_msg_service_request{name = "ssh-userauth"} = Msg,
#state{ssh_params = #ssh{role = server,
session_id = SessionId} = Ssh0} = State) ->
{ok, {Reply, Ssh}} = ssh_auth:handle_userauth_request(Msg, SessionId, Ssh0),
send_msg(Reply, State),
{next_state, userauth, next_packet(State#state{ssh_params = Ssh})};
-userauth(#ssh_msg_service_accept{name = "ssh-userauth"},
- #state{ssh_params = #ssh{role = client,
- service = "ssh-userauth"} = Ssh0} =
- State) ->
+service_request(#ssh_msg_service_accept{name = "ssh-userauth"},
+ #state{ssh_params = #ssh{role = client,
+ service = "ssh-userauth"} = Ssh0} =
+ State) ->
{Msg, Ssh} = ssh_auth:init_userauth_request_msg(Ssh0),
send_msg(Msg, State),
- {next_state, userauth, next_packet(State#state{auth_user = Ssh#ssh.user, ssh_params = Ssh})};
+ {next_state, userauth, next_packet(State#state{auth_user = Ssh#ssh.user, ssh_params = Ssh})}.
+%%--------------------------------------------------------------------
+-spec userauth(#ssh_msg_userauth_request{} | #ssh_msg_userauth_info_request{} |
+ #ssh_msg_userauth_info_response{} | #ssh_msg_userauth_success{} |
+ #ssh_msg_userauth_failure{} | #ssh_msg_userauth_banner{},
+ #state{}) -> gen_fsm_state_return().
+%%--------------------------------------------------------------------
userauth(#ssh_msg_userauth_request{service = "ssh-connection",
method = "none"} = Msg,
#state{ssh_params = #ssh{session_id = SessionId, role = server,
@@ -520,7 +536,11 @@ userauth(#ssh_msg_userauth_request{service = "ssh-connection",
Pid ! ssh_connected,
connected_fun(User, Address, Method, Opts),
{next_state, connected,
- next_packet(State#state{auth_user = User, ssh_params = Ssh})};
+ next_packet(State#state{auth_user = User, ssh_params = Ssh#ssh{authenticated = true}})};
+ {not_authorized, {User, Reason}, {Reply, Ssh}} when Method == "keyboard-interactive" ->
+ retry_fun(User, Address, Reason, Opts),
+ send_msg(Reply, State),
+ {next_state, userauth_keyboard_interactive, next_packet(State#state{ssh_params = Ssh})};
{not_authorized, {User, Reason}, {Reply, Ssh}} ->
retry_fun(User, Address, Reason, Opts),
send_msg(Reply, State),
@@ -530,30 +550,6 @@ userauth(#ssh_msg_userauth_request{service = "ssh-connection",
userauth(Msg#ssh_msg_userauth_request{method="none"}, State)
end;
-userauth(#ssh_msg_userauth_info_request{} = Msg,
- #state{ssh_params = #ssh{role = client,
- io_cb = IoCb} = Ssh0} = State) ->
- {ok, {Reply, Ssh}} = ssh_auth:handle_userauth_info_request(Msg, IoCb, Ssh0),
- send_msg(Reply, State),
- {next_state, userauth, next_packet(State#state{ssh_params = Ssh})};
-
-userauth(#ssh_msg_userauth_info_response{} = Msg,
- #state{ssh_params = #ssh{role = server,
- peer = {_, Address}} = Ssh0,
- opts = Opts, starter = Pid} = State) ->
- case ssh_auth:handle_userauth_info_response(Msg, Ssh0) of
- {authorized, User, {Reply, Ssh}} ->
- send_msg(Reply, State),
- Pid ! ssh_connected,
- connected_fun(User, Address, "keyboard-interactive", Opts),
- {next_state, connected,
- next_packet(State#state{auth_user = User, ssh_params = Ssh})};
- {not_authorized, {User, Reason}, {Reply, Ssh}} ->
- retry_fun(User, Address, Reason, Opts),
- send_msg(Reply, State),
- {next_state, userauth, next_packet(State#state{ssh_params = Ssh})}
- end;
-
userauth(#ssh_msg_userauth_success{}, #state{ssh_params = #ssh{role = client} = Ssh,
starter = Pid} = State) ->
Pid ! ssh_connected,
@@ -580,19 +576,25 @@ userauth(#ssh_msg_userauth_failure{authentications = Methodes},
{disconnect, DisconnectMsg, {Msg, Ssh}} ->
send_msg(Msg, State),
handle_disconnect(DisconnectMsg, State#state{ssh_params = Ssh});
- {Msg, Ssh} ->
+ {"keyboard-interactive", {Msg, Ssh}} ->
+ send_msg(Msg, State),
+ {next_state, userauth_keyboard_interactive, next_packet(State#state{ssh_params = Ssh})};
+ {_Method, {Msg, Ssh}} ->
send_msg(Msg, State),
{next_state, userauth, next_packet(State#state{ssh_params = Ssh})}
end;
%% The prefered authentication method failed try next method
-userauth(#ssh_msg_userauth_failure{},
+userauth(#ssh_msg_userauth_failure{},
#state{ssh_params = #ssh{role = client} = Ssh0} = State) ->
case ssh_auth:userauth_request_msg(Ssh0) of
{disconnect, DisconnectMsg,{Msg, Ssh}} ->
send_msg(Msg, State),
handle_disconnect(DisconnectMsg, State#state{ssh_params = Ssh});
- {Msg, Ssh} ->
+ {"keyboard-interactive", {Msg, Ssh}} ->
+ send_msg(Msg, State),
+ {next_state, userauth_keyboard_interactive, next_packet(State#state{ssh_params = Ssh})};
+ {_Method, {Msg, Ssh}} ->
send_msg(Msg, State),
{next_state, userauth, next_packet(State#state{ssh_params = Ssh})}
end;
@@ -607,6 +609,50 @@ userauth(#ssh_msg_userauth_banner{message = Msg},
io:format("~s", [Msg]),
{next_state, userauth, next_packet(State)}.
+
+
+userauth_keyboard_interactive(#ssh_msg_userauth_info_request{} = Msg,
+ #state{ssh_params = #ssh{role = client,
+ io_cb = IoCb} = Ssh0} = State) ->
+ {ok, {Reply, Ssh}} = ssh_auth:handle_userauth_info_request(Msg, IoCb, Ssh0),
+ send_msg(Reply, State),
+ {next_state, userauth_keyboard_interactive_info_response, next_packet(State#state{ssh_params = Ssh})};
+
+userauth_keyboard_interactive(#ssh_msg_userauth_info_response{} = Msg,
+ #state{ssh_params = #ssh{role = server,
+ peer = {_, Address}} = Ssh0,
+ opts = Opts, starter = Pid} = State) ->
+ case ssh_auth:handle_userauth_info_response(Msg, Ssh0) of
+ {authorized, User, {Reply, Ssh}} ->
+ send_msg(Reply, State),
+ Pid ! ssh_connected,
+ connected_fun(User, Address, "keyboard-interactive", Opts),
+ {next_state, connected,
+ next_packet(State#state{auth_user = User, ssh_params = Ssh#ssh{authenticated = true}})};
+ {not_authorized, {User, Reason}, {Reply, Ssh}} ->
+ retry_fun(User, Address, Reason, Opts),
+ send_msg(Reply, State),
+ {next_state, userauth, next_packet(State#state{ssh_params = Ssh})}
+ end;
+userauth_keyboard_interactive(Msg = #ssh_msg_userauth_failure{},
+ #state{ssh_params = Ssh0 =
+ #ssh{role = client,
+ userauth_preference = Prefs0}}
+ = State) ->
+ Prefs = [{Method,M,F,A} || {Method,M,F,A} <- Prefs0,
+ Method =/= "keyboard-interactive"],
+ userauth(Msg, State#state{ssh_params = Ssh0#ssh{userauth_preference=Prefs}}).
+
+
+
+userauth_keyboard_interactive_info_response(Msg=#ssh_msg_userauth_failure{},
+ #state{ssh_params = #ssh{role = client}} = State) ->
+ userauth(Msg, State);
+
+userauth_keyboard_interactive_info_response(Msg=#ssh_msg_userauth_success{},
+ #state{ssh_params = #ssh{role = client}} = State) ->
+ userauth(Msg, State).
+
%%--------------------------------------------------------------------
-spec connected({#ssh_msg_kexinit{}, binary()}, %%| %% #ssh_msg_kexdh_init{},
#state{}) -> gen_fsm_state_return().
@@ -691,13 +737,28 @@ handle_event({adjust_window, ChannelId, Bytes}, StateName,
#connection{channel_cache = Cache}} = State0) ->
State =
case ssh_channel:cache_lookup(Cache, ChannelId) of
- #channel{recv_window_size = WinSize, remote_id = Id} = Channel ->
- ssh_channel:cache_update(Cache, Channel#channel{recv_window_size =
- WinSize + Bytes}),
- Msg = ssh_connection:channel_adjust_window_msg(Id, Bytes),
+ #channel{recv_window_size = WinSize,
+ recv_window_pending = Pending,
+ recv_packet_size = PktSize} = Channel
+ when (WinSize-Bytes) >= 2*PktSize ->
+ %% The peer can send at least two more *full* packet, no hurry.
+ ssh_channel:cache_update(Cache,
+ Channel#channel{recv_window_pending = Pending + Bytes}),
+ State0;
+
+ #channel{recv_window_size = WinSize,
+ recv_window_pending = Pending,
+ remote_id = Id} = Channel ->
+ %% Now we have to update the window - we can't receive so many more pkts
+ ssh_channel:cache_update(Cache,
+ Channel#channel{recv_window_size =
+ WinSize + Bytes + Pending,
+ recv_window_pending = 0}),
+ Msg = ssh_connection:channel_adjust_window_msg(Id, Bytes + Pending),
send_replies([{connection_reply, Msg}], State0);
- undefined ->
- State0
+
+ undefined ->
+ State0
end,
{next_state, StateName, next_packet(State)};
@@ -930,57 +991,39 @@ handle_info({Protocol, Socket, Info}, hello,
transport_protocol = Protocol} = State) ->
event({info_line, Info}, hello, State);
-handle_info({Protocol, Socket, Data}, Statename,
+handle_info({Protocol, Socket, Data}, StateName,
#state{socket = Socket,
transport_protocol = Protocol,
- ssh_params = #ssh{decrypt_block_size = BlockSize,
- recv_mac_size = MacSize} = Ssh0,
- decoded_data_buffer = <<>>,
- encoded_data_buffer = EncData0} = State0) ->
-
- %% Implementations SHOULD decrypt the length after receiving the
- %% first 8 (or cipher block size, whichever is larger) bytes of a
- %% packet. (RFC 4253: Section 6 - Binary Packet Protocol)
- case size(EncData0) + size(Data) >= erlang:max(8, BlockSize) of
- true ->
- {Ssh, SshPacketLen, DecData, EncData} =
-
- ssh_transport:decrypt_first_block(<<EncData0/binary,
- Data/binary>>, Ssh0),
- case SshPacketLen > ?SSH_MAX_PACKET_SIZE of
- true ->
- DisconnectMsg =
- #ssh_msg_disconnect{code =
- ?SSH_DISCONNECT_PROTOCOL_ERROR,
- description = "Bad packet length "
- ++ integer_to_list(SshPacketLen),
- language = "en"},
- handle_disconnect(DisconnectMsg, State0);
- false ->
- RemainingSshPacketLen =
- (SshPacketLen + ?SSH_LENGHT_INDICATOR_SIZE) -
- BlockSize + MacSize,
- State = State0#state{ssh_params = Ssh},
- handle_ssh_packet_data(RemainingSshPacketLen,
- DecData, EncData, Statename,
- State)
- end;
- false ->
- {next_state, Statename,
- next_packet(State0#state{encoded_data_buffer =
- <<EncData0/binary, Data/binary>>})}
+ ssh_params = Ssh0,
+ decoded_data_buffer = DecData0,
+ encoded_data_buffer = EncData0,
+ undecoded_packet_length = RemainingSshPacketLen0} = State0) ->
+ Encoded = <<EncData0/binary, Data/binary>>,
+ case ssh_transport:handle_packet_part(DecData0, Encoded, RemainingSshPacketLen0, Ssh0) of
+ {get_more, DecBytes, EncDataRest, RemainingSshPacketLen, Ssh1} ->
+ {next_state, StateName,
+ next_packet(State0#state{encoded_data_buffer = EncDataRest,
+ decoded_data_buffer = DecBytes,
+ undecoded_packet_length = RemainingSshPacketLen,
+ ssh_params = Ssh1})};
+ {decoded, MsgBytes, EncDataRest, Ssh1} ->
+ generate_event(MsgBytes, StateName,
+ State0#state{ssh_params = Ssh1,
+ %% Important to be set for
+ %% next_packet
+%%% FIXME: the following three seem to always be set in generate_event!
+ decoded_data_buffer = <<>>,
+ undecoded_packet_length = undefined,
+ encoded_data_buffer = EncDataRest},
+ EncDataRest);
+ {bad_mac, Ssh1} ->
+ DisconnectMsg =
+ #ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
+ description = "Bad mac",
+ language = ""},
+ handle_disconnect(DisconnectMsg, State0#state{ssh_params=Ssh1})
end;
-
-handle_info({Protocol, Socket, Data}, Statename,
- #state{socket = Socket,
- transport_protocol = Protocol,
- decoded_data_buffer = DecData,
- encoded_data_buffer = EncData,
- undecoded_packet_length = Len} =
- State) when is_integer(Len) ->
- handle_ssh_packet_data(Len, DecData, <<EncData/binary, Data/binary>>,
- Statename, State);
-
+
handle_info({CloseTag, _Socket}, _StateName,
#state{transport_close_tag = CloseTag,
ssh_params = #ssh{role = _Role, opts = _Opts}} = State) ->
@@ -1058,7 +1101,7 @@ handle_info(UnexpectedMessage, StateName, #state{opts = Opts,
terminate(normal, _, #state{transport_cb = Transport,
connection_state = Connection,
socket = Socket}) ->
- terminate_subsytem(Connection),
+ terminate_subsystem(Connection),
(catch Transport:close(Socket)),
ok;
@@ -1087,7 +1130,7 @@ terminate({shutdown, _}, StateName, State) ->
terminate(Reason, StateName, #state{ssh_params = Ssh0, starter = _Pid,
connection_state = Connection} = State) ->
- terminate_subsytem(Connection),
+ terminate_subsystem(Connection),
log_error(Reason),
DisconnectMsg =
#ssh_msg_disconnect{code = ?SSH_DISCONNECT_BY_APPLICATION,
@@ -1098,10 +1141,10 @@ terminate(Reason, StateName, #state{ssh_params = Ssh0, starter = _Pid,
terminate(normal, StateName, State#state{ssh_params = Ssh}).
-terminate_subsytem(#connection{system_supervisor = SysSup,
+terminate_subsystem(#connection{system_supervisor = SysSup,
sub_system_supervisor = SubSysSup}) when is_pid(SubSysSup) ->
ssh_system_sup:stop_subsystem(SysSup, SubSysSup);
-terminate_subsytem(_) ->
+terminate_subsystem(_) ->
ok.
format_status(normal, [_, State]) ->
@@ -1236,9 +1279,9 @@ supported_host_keys(client, _, Options) ->
proplists:get_value(preferred_algorithms,Options,[])
) of
undefined ->
- ssh_auth:default_public_key_algorithms();
+ ssh_transport:default_algorithms(public_key);
L ->
- L -- (L--ssh_auth:default_public_key_algorithms())
+ L -- (L--ssh_transport:default_algorithms(public_key))
end
of
[] ->
@@ -1250,21 +1293,17 @@ supported_host_keys(client, _, Options) ->
{stop, {shutdown, Reason}}
end;
supported_host_keys(server, KeyCb, Options) ->
- Algs=
[atom_to_list(A) || A <- proplists:get_value(public_key,
proplists:get_value(preferred_algorithms,Options,[]),
- ssh_auth:default_public_key_algorithms()
+ ssh_transport:default_algorithms(public_key)
),
available_host_key(KeyCb, A, Options)
- ],
- Algs.
-
+ ].
%% Alg :: atom()
available_host_key(KeyCb, Alg, Opts) ->
element(1, catch KeyCb:host_key(Alg, Opts)) == ok.
-
send_msg(Msg, #state{socket = Socket, transport_cb = Transport}) ->
Transport:send(Socket, Msg).
@@ -1563,10 +1602,10 @@ after_new_keys(#state{renegotiate = false,
ssh_params = #ssh{role = client} = Ssh0} = State) ->
{Msg, Ssh} = ssh_auth:service_request_msg(Ssh0),
send_msg(Msg, State),
- {next_state, userauth, State#state{ssh_params = Ssh}};
+ {next_state, service_request, State#state{ssh_params = Ssh}};
after_new_keys(#state{renegotiate = false,
ssh_params = #ssh{role = server}} = State) ->
- {next_state, userauth, State}.
+ {next_state, service_request, State}.
after_new_keys_events({sync, _Event, From}, {stop, _Reason, _StateData}=Terminator) ->
gen_fsm:reply(From, {error, closed}),
@@ -1595,57 +1634,6 @@ after_new_keys_events({connection_reply, _Data} = Reply, {StateName, State}) ->
NewState = send_replies([Reply], State),
{next_state, StateName, NewState}.
-handle_ssh_packet_data(RemainingSshPacketLen, DecData, EncData, StateName,
- State) ->
- EncSize = size(EncData),
- case RemainingSshPacketLen > EncSize of
- true ->
- {next_state, StateName,
- next_packet(State#state{decoded_data_buffer = DecData,
- encoded_data_buffer = EncData,
- undecoded_packet_length =
- RemainingSshPacketLen})};
- false ->
- handle_ssh_packet(RemainingSshPacketLen, StateName,
- State#state{decoded_data_buffer = DecData,
- encoded_data_buffer = EncData})
-
- end.
-
-handle_ssh_packet(Length, StateName, #state{decoded_data_buffer = DecData0,
- encoded_data_buffer = EncData0,
- ssh_params = Ssh0,
- transport_protocol = _Protocol,
- socket = _Socket} = State0) ->
- try
- {Ssh1, DecData, EncData, Mac} =
- ssh_transport:unpack(EncData0, Length, Ssh0),
- SshPacket = <<DecData0/binary, DecData/binary>>,
- case ssh_transport:is_valid_mac(Mac, SshPacket, Ssh1) of
- true ->
- PacketData = ssh_transport:msg_data(SshPacket),
- {Ssh1, Msg} = ssh_transport:decompress(Ssh1, PacketData),
- generate_event(Msg, StateName,
- State0#state{ssh_params = Ssh1,
- %% Important to be set for
- %% next_packet
- decoded_data_buffer = <<>>},
- EncData);
- false ->
- DisconnectMsg =
- #ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
- description = "Bad mac",
- language = "en"},
- handle_disconnect(DisconnectMsg, State0)
- end
- catch _:_ ->
- Disconnect =
- #ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
- description = "Bad input",
- language = "en"},
- handle_disconnect(Disconnect, State0)
- end.
-
handle_disconnect(DisconnectMsg, State) ->
handle_disconnect(own, DisconnectMsg, State).
diff --git a/lib/ssh/src/ssh_file.erl b/lib/ssh/src/ssh_file.erl
index b98a8a8410..3e066c453d 100644
--- a/lib/ssh/src/ssh_file.erl
+++ b/lib/ssh/src/ssh_file.erl
@@ -52,8 +52,20 @@ host_key(Algorithm, Opts) ->
%% so probably we could hardcod Password = ignore, but
%% we keep it as an undocumented option for now.
Password = proplists:get_value(identity_pass_phrase(Algorithm), Opts, ignore),
- decode(File, Password).
-
+ case decode(File, Password) of
+ {ok,Key} ->
+ case {Key,Algorithm} of
+ {#'RSAPrivateKey'{}, 'ssh-rsa'} -> {ok,Key};
+ {#'DSAPrivateKey'{}, 'ssh-dss'} -> {ok,Key};
+ {#'ECPrivateKey'{parameters = {namedCurve, ?'secp256r1'}}, 'ecdsa-sha2-nistp256'} -> {ok,Key};
+ {#'ECPrivateKey'{parameters = {namedCurve, ?'secp384r1'}}, 'ecdsa-sha2-nistp384'} -> {ok,Key};
+ {#'ECPrivateKey'{parameters = {namedCurve, ?'secp521r1'}}, 'ecdsa-sha2-nistp521'} -> {ok,Key};
+ _ ->
+ {error,bad_keytype_in_file}
+ end;
+ Other ->
+ Other
+ end.
is_auth_key(Key, User,Opts) ->
case lookup_user_key(Key, User, Opts) of
@@ -81,16 +93,15 @@ user_key(Algorithm, Opts) ->
%% Internal functions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-file_base_name('ssh-rsa') ->
- "ssh_host_rsa_key";
-file_base_name('ssh-dss') ->
- "ssh_host_dsa_key";
-file_base_name(_) ->
- "ssh_host_key".
+file_base_name('ssh-rsa' ) -> "ssh_host_rsa_key";
+file_base_name('ssh-dss' ) -> "ssh_host_dsa_key";
+file_base_name('ecdsa-sha2-nistp256') -> "ssh_host_ecdsa_key";
+file_base_name('ecdsa-sha2-nistp384') -> "ssh_host_ecdsa_key";
+file_base_name('ecdsa-sha2-nistp521') -> "ssh_host_ecdsa_key";
+file_base_name(_ ) -> "ssh_host_key".
decode(File, Password) ->
- try
- {ok, decode_ssh_file(read_ssh_file(File), Password)}
+ try {ok, decode_ssh_file(read_ssh_file(File), Password)}
catch
throw:Reason ->
{error, Reason};
@@ -210,29 +221,32 @@ do_lookup_host_key(KeyToMatch, Host, Alg, Opts) ->
{ok, Fd} ->
Res = lookup_host_key_fd(Fd, KeyToMatch, Host, Alg),
file:close(Fd),
- {ok, Res};
- {error, enoent} -> {error, not_found};
- Error -> Error
+ Res;
+ {error, enoent} ->
+ {error, not_found};
+ Error ->
+ Error
end.
-identity_key_filename('ssh-dss') ->
- "id_dsa";
-identity_key_filename('ssh-rsa') ->
- "id_rsa".
-
-identity_pass_phrase("ssh-dss") ->
- dsa_pass_phrase;
-identity_pass_phrase('ssh-dss') ->
- dsa_pass_phrase;
-identity_pass_phrase('ssh-rsa') ->
- rsa_pass_phrase;
-identity_pass_phrase("ssh-rsa") ->
- rsa_pass_phrase.
-
+identity_key_filename('ssh-dss' ) -> "id_dsa";
+identity_key_filename('ssh-rsa' ) -> "id_rsa";
+identity_key_filename('ecdsa-sha2-nistp256') -> "id_ecdsa";
+identity_key_filename('ecdsa-sha2-nistp384') -> "id_ecdsa";
+identity_key_filename('ecdsa-sha2-nistp521') -> "id_ecdsa".
+
+identity_pass_phrase("ssh-dss" ) -> dsa_pass_phrase;
+identity_pass_phrase("ssh-rsa" ) -> rsa_pass_phrase;
+identity_pass_phrase("ecdsa-sha2-"++_) -> ecdsa_pass_phrase;
+identity_pass_phrase(P) when is_atom(P) ->
+ identity_pass_phrase(atom_to_list(P)).
+
lookup_host_key_fd(Fd, KeyToMatch, Host, KeyType) ->
case io:get_line(Fd, '') of
eof ->
{error, not_found};
+ {error,Error} ->
+ %% Rare... For example NFS errors
+ {error,Error};
Line ->
case ssh_decode_line(Line, known_hosts) of
[{Key, Attributes}] ->
@@ -253,7 +267,7 @@ handle_host(Fd, KeyToMatch, Host, HostList, Key, KeyType) ->
Host1 = host_name(Host),
case lists:member(Host1, HostList) andalso key_match(Key, KeyType) of
true when KeyToMatch == Key ->
- Key;
+ {ok,Key};
_ ->
lookup_host_key_fd(Fd, KeyToMatch, Host, KeyType)
end.
@@ -267,6 +281,13 @@ key_match(#'RSAPublicKey'{}, 'ssh-rsa') ->
true;
key_match({_, #'Dss-Parms'{}}, 'ssh-dss') ->
true;
+key_match({#'ECPoint'{},{namedCurve,Curve}}, Alg) ->
+ case atom_to_list(Alg) of
+ "ecdsa-sha2-"++IdS ->
+ Curve == public_key:ssh_curvename2oid(list_to_binary(IdS));
+ _ ->
+ false
+ end;
key_match(_, _) ->
false.
@@ -293,6 +314,9 @@ lookup_user_key_fd(Fd, Key) ->
case io:get_line(Fd, '') of
eof ->
{error, not_found};
+ {error,Error} ->
+ %% Rare... For example NFS errors
+ {error,Error};
Line ->
case ssh_decode_line(Line, auth_keys) of
[{AuthKey, _}] ->
@@ -312,8 +336,18 @@ is_auth_key(Key, Key) ->
is_auth_key(_,_) ->
false.
-default_user_dir()->
- {ok,[[Home|_]]} = init:get_argument(home),
+
+default_user_dir() ->
+ try
+ default_user_dir(os:getenv("HOME"))
+ catch
+ _:_ ->
+ default_user_dir(init:get_argument(home))
+ end.
+
+default_user_dir({ok,[[Home|_]]}) ->
+ default_user_dir(Home);
+default_user_dir(Home) when is_list(Home) ->
UserDir = filename:join(Home, ".ssh"),
ok = filelib:ensure_dir(filename:join(UserDir, "dummy")),
{ok,Info} = file:read_file_info(UserDir),
diff --git a/lib/ssh/src/ssh_message.erl b/lib/ssh/src/ssh_message.erl
index cb1dcb67c5..b6c4496be2 100644
--- a/lib/ssh/src/ssh_message.erl
+++ b/lib/ssh/src/ssh_message.erl
@@ -30,7 +30,7 @@
-include("ssh_auth.hrl").
-include("ssh_transport.hrl").
--export([encode/1, decode/1, encode_host_key/1, decode_keyboard_interactive_prompts/2]).
+-export([encode/1, decode/1, decode_keyboard_interactive_prompts/2]).
encode(#ssh_msg_global_request{
name = Name,
@@ -227,8 +227,8 @@ encode(#ssh_msg_kexdh_reply{
f = F,
h_sig = Signature
}) ->
- EncKey = encode_host_key(Key),
- EncSign = encode_sign(Key, Signature),
+ EncKey = public_key:ssh_encode(Key, ssh2_pubkey),
+ EncSign = encode_signature(Key, Signature),
ssh_bits:encode([?SSH_MSG_KEXDH_REPLY, EncKey, F, EncSign], [byte, binary, mpint, binary]);
encode(#ssh_msg_kex_dh_gex_request{
@@ -255,16 +255,16 @@ encode(#ssh_msg_kex_dh_gex_reply{
f = F,
h_sig = Signature
}) ->
- EncKey = encode_host_key(Key),
- EncSign = encode_sign(Key, Signature),
+ EncKey = public_key:ssh_encode(Key, ssh2_pubkey),
+ EncSign = encode_signature(Key, Signature),
ssh_bits:encode([?SSH_MSG_KEX_DH_GEX_REPLY, EncKey, F, EncSign], [byte, binary, mpint, binary]);
encode(#ssh_msg_kex_ecdh_init{q_c = Q_c}) ->
ssh_bits:encode([?SSH_MSG_KEX_ECDH_INIT, Q_c], [byte, mpint]);
encode(#ssh_msg_kex_ecdh_reply{public_host_key = Key, q_s = Q_s, h_sig = Sign}) ->
- EncKey = encode_host_key(Key),
- EncSign = encode_sign(Key, Sign),
+ EncKey = public_key:ssh_encode(Key, ssh2_pubkey),
+ EncSign = encode_signature(Key, Sign),
ssh_bits:encode([?SSH_MSG_KEX_ECDH_REPLY, EncKey, Q_s, EncSign], [byte, binary, mpint, binary]);
encode(#ssh_msg_ignore{data = Data}) ->
@@ -280,8 +280,7 @@ encode(#ssh_msg_debug{always_display = Bool,
%% Connection Messages
-decode(<<?BYTE(?SSH_MSG_GLOBAL_REQUEST), ?UINT32(Len), Name:Len/binary,
- ?BYTE(Bool), Data/binary>>) ->
+decode(<<?BYTE(?SSH_MSG_GLOBAL_REQUEST), ?DEC_BIN(Name,__0), ?BYTE(Bool), Data/binary>>) ->
#ssh_msg_global_request{
name = Name,
want_reply = erl_boolean(Bool),
@@ -292,8 +291,7 @@ decode(<<?BYTE(?SSH_MSG_REQUEST_SUCCESS), Data/binary>>) ->
decode(<<?BYTE(?SSH_MSG_REQUEST_FAILURE)>>) ->
#ssh_msg_request_failure{};
decode(<<?BYTE(?SSH_MSG_CHANNEL_OPEN),
- ?UINT32(Len), Type:Len/binary,
- ?UINT32(Sender), ?UINT32(Window), ?UINT32(Max),
+ ?DEC_BIN(Type,__0), ?UINT32(Sender), ?UINT32(Window), ?UINT32(Max),
Data/binary>>) ->
#ssh_msg_channel_open{
channel_type = binary_to_list(Type),
@@ -313,7 +311,7 @@ decode(<<?BYTE(?SSH_MSG_CHANNEL_OPEN_CONFIRMATION), ?UINT32(Recipient), ?UINT32(
data = Data
};
decode(<<?BYTE(?SSH_MSG_CHANNEL_OPEN_FAILURE), ?UINT32(Recipient), ?UINT32(Reason),
- ?UINT32(Len0), Desc:Len0/binary, ?UINT32(Len1), Lang:Len1/binary >>) ->
+ ?DEC_BIN(Desc,__0), ?DEC_BIN(Lang,__1) >> ) ->
#ssh_msg_channel_open_failure{
recipient_channel = Recipient,
reason = Reason,
@@ -326,13 +324,13 @@ decode(<<?BYTE(?SSH_MSG_CHANNEL_WINDOW_ADJUST), ?UINT32(Recipient), ?UINT32(Byte
bytes_to_add = Bytes
};
-decode(<<?BYTE(?SSH_MSG_CHANNEL_DATA), ?UINT32(Recipient), ?UINT32(Len), Data:Len/binary>>) ->
+decode(<<?BYTE(?SSH_MSG_CHANNEL_DATA), ?UINT32(Recipient), ?DEC_BIN(Data,__0)>>) ->
#ssh_msg_channel_data{
recipient_channel = Recipient,
data = Data
};
decode(<<?BYTE(?SSH_MSG_CHANNEL_EXTENDED_DATA), ?UINT32(Recipient),
- ?UINT32(DataType), ?UINT32(Len), Data:Len/binary>>) ->
+ ?UINT32(DataType), ?DEC_BIN(Data,__0)>>) ->
#ssh_msg_channel_extended_data{
recipient_channel = Recipient,
data_type_code = DataType,
@@ -347,8 +345,7 @@ decode(<<?BYTE(?SSH_MSG_CHANNEL_CLOSE), ?UINT32(Recipient)>>) ->
recipient_channel = Recipient
};
decode(<<?BYTE(?SSH_MSG_CHANNEL_REQUEST), ?UINT32(Recipient),
- ?UINT32(Len), RequestType:Len/binary,
- ?BYTE(Bool), Data/binary>>) ->
+ ?DEC_BIN(RequestType,__0), ?BYTE(Bool), Data/binary>>) ->
#ssh_msg_channel_request{
recipient_channel = Recipient,
request_type = unicode:characters_to_list(RequestType),
@@ -366,9 +363,7 @@ decode(<<?BYTE(?SSH_MSG_CHANNEL_FAILURE), ?UINT32(Recipient)>>) ->
%%% Auth Messages
decode(<<?BYTE(?SSH_MSG_USERAUTH_REQUEST),
- ?UINT32(Len0), User:Len0/binary,
- ?UINT32(Len1), Service:Len1/binary,
- ?UINT32(Len2), Method:Len2/binary,
+ ?DEC_BIN(User,__0), ?DEC_BIN(Service,__1), ?DEC_BIN(Method,__2),
Data/binary>>) ->
#ssh_msg_userauth_request{
user = unicode:characters_to_list(User),
@@ -378,7 +373,7 @@ decode(<<?BYTE(?SSH_MSG_USERAUTH_REQUEST),
};
decode(<<?BYTE(?SSH_MSG_USERAUTH_FAILURE),
- ?UINT32(Len0), Auths:Len0/binary,
+ ?DEC_BIN(Auths,__0),
?BYTE(Bool)>>) ->
#ssh_msg_userauth_failure {
authentications = unicode:characters_to_list(Auths),
@@ -388,16 +383,14 @@ decode(<<?BYTE(?SSH_MSG_USERAUTH_FAILURE),
decode(<<?BYTE(?SSH_MSG_USERAUTH_SUCCESS)>>) ->
#ssh_msg_userauth_success{};
-decode(<<?BYTE(?SSH_MSG_USERAUTH_BANNER),
- ?UINT32(Len0), Banner:Len0/binary,
- ?UINT32(Len1), Lang:Len1/binary>>) ->
+decode(<<?BYTE(?SSH_MSG_USERAUTH_BANNER), ?DEC_BIN(Banner,__0), ?DEC_BIN(Lang,__1) >>) ->
#ssh_msg_userauth_banner{
message = Banner,
language = Lang
};
-decode(<<?BYTE(?SSH_MSG_USERAUTH_INFO_REQUEST), ?UINT32(Len0), Name:Len0/binary,
- ?UINT32(Len1), Inst:Len1/binary, ?UINT32(Len2), Lang:Len2/binary,
+decode(<<?BYTE(?SSH_MSG_USERAUTH_INFO_REQUEST),
+ ?DEC_BIN(Name,__0), ?DEC_BIN(Inst,__1), ?DEC_BIN(Lang,__2),
?UINT32(NumPromtps), Data/binary>>) ->
#ssh_msg_userauth_info_request{
name = Name,
@@ -407,15 +400,14 @@ decode(<<?BYTE(?SSH_MSG_USERAUTH_INFO_REQUEST), ?UINT32(Len0), Name:Len0/binary,
data = Data};
%%% Unhandled message, also masked by same 1:st byte value as ?SSH_MSG_USERAUTH_INFO_REQUEST:
-decode(<<?BYTE(?SSH_MSG_USERAUTH_PASSWD_CHANGEREQ), ?UINT32(Len0), Prompt:Len0/binary,
- ?UINT32(Len1), Lang:Len1/binary>>) ->
+decode(<<?BYTE(?SSH_MSG_USERAUTH_PASSWD_CHANGEREQ), ?DEC_BIN(Prompt,__0), ?DEC_BIN(Lang,__1) >>) ->
#ssh_msg_userauth_passwd_changereq{
prompt = Prompt,
languge = Lang
};
%%% Unhandled message, also masked by same 1:st byte value as ?SSH_MSG_USERAUTH_INFO_REQUEST:
-decode(<<?BYTE(?SSH_MSG_USERAUTH_PK_OK), ?UINT32(Len), Alg:Len/binary, KeyBlob/binary>>) ->
+decode(<<?BYTE(?SSH_MSG_USERAUTH_PK_OK), ?DEC_BIN(Alg,__0), KeyBlob/binary>>) ->
#ssh_msg_userauth_pk_ok{
algorithm_name = Alg,
key_blob = KeyBlob
@@ -430,18 +422,15 @@ decode(<<?BYTE(?SSH_MSG_USERAUTH_INFO_RESPONSE), ?UINT32(Num), Data/binary>>) ->
decode(<<?BYTE(?SSH_MSG_KEXINIT), Cookie:128, Data/binary>>) ->
decode_kex_init(Data, [Cookie, ssh_msg_kexinit], 10);
-decode(<<"dh",?BYTE(?SSH_MSG_KEXDH_INIT), ?UINT32(Len), E:Len/big-signed-integer-unit:8>>) ->
+decode(<<"dh",?BYTE(?SSH_MSG_KEXDH_INIT), ?DEC_MPINT(E,__0)>>) ->
#ssh_msg_kexdh_init{e = E
};
-decode(<<"dh", ?BYTE(?SSH_MSG_KEXDH_REPLY),
- ?UINT32(Len0), Key:Len0/binary,
- ?UINT32(Len1), F:Len1/big-signed-integer-unit:8,
- ?UINT32(Len2), Hashsign:Len2/binary>>) ->
+decode(<<"dh", ?BYTE(?SSH_MSG_KEXDH_REPLY), ?DEC_BIN(Key,__0), ?DEC_MPINT(F,__1), ?DEC_BIN(Hashsign,__2)>>) ->
#ssh_msg_kexdh_reply{
- public_host_key = decode_host_key(Key),
+ public_host_key = public_key:ssh_decode(Key, ssh2_pubkey),
f = F,
- h_sig = decode_sign(Hashsign)
+ h_sig = decode_signature(Hashsign)
};
decode(<<?BYTE(?SSH_MSG_KEX_DH_GEX_REQUEST), ?UINT32(Min), ?UINT32(N), ?UINT32(Max)>>) ->
@@ -456,57 +445,48 @@ decode(<<"dh_gex",?BYTE(?SSH_MSG_KEX_DH_GEX_REQUEST_OLD), ?UINT32(N)>>) ->
n = N
};
-decode(<<"dh_gex",?BYTE(?SSH_MSG_KEX_DH_GEX_GROUP),
- ?UINT32(Len0), Prime:Len0/big-signed-integer-unit:8,
- ?UINT32(Len1), Generator:Len1/big-signed-integer-unit:8>>) ->
+decode(<<"dh_gex",?BYTE(?SSH_MSG_KEX_DH_GEX_GROUP), ?DEC_MPINT(Prime,__0), ?DEC_MPINT(Generator,__1) >>) ->
#ssh_msg_kex_dh_gex_group{
p = Prime,
g = Generator
};
-decode(<<?BYTE(?SSH_MSG_KEX_DH_GEX_INIT), ?UINT32(Len), E:Len/big-signed-integer-unit:8>>) ->
+decode(<<?BYTE(?SSH_MSG_KEX_DH_GEX_INIT), ?DEC_MPINT(E,__0)>>) ->
#ssh_msg_kex_dh_gex_init{
e = E
};
-decode(<<?BYTE(?SSH_MSG_KEX_DH_GEX_REPLY),
- ?UINT32(Len0), Key:Len0/binary,
- ?UINT32(Len1), F:Len1/big-signed-integer-unit:8,
- ?UINT32(Len2), Hashsign:Len2/binary>>) ->
+decode(<<?BYTE(?SSH_MSG_KEX_DH_GEX_REPLY), ?DEC_BIN(Key,__0), ?DEC_MPINT(F,__1), ?DEC_BIN(Hashsign,__2)>>) ->
#ssh_msg_kex_dh_gex_reply{
- public_host_key = decode_host_key(Key),
+ public_host_key = public_key:ssh_decode(Key, ssh2_pubkey),
f = F,
- h_sig = decode_sign(Hashsign)
+ h_sig = decode_signature(Hashsign)
};
-decode(<<"ecdh",?BYTE(?SSH_MSG_KEX_ECDH_INIT),
- ?UINT32(Len0), Q_c:Len0/big-signed-integer-unit:8>>) ->
+decode(<<"ecdh",?BYTE(?SSH_MSG_KEX_ECDH_INIT), ?DEC_MPINT(Q_c,__0)>>) ->
#ssh_msg_kex_ecdh_init{
q_c = Q_c
};
decode(<<"ecdh",?BYTE(?SSH_MSG_KEX_ECDH_REPLY),
- ?UINT32(Len1), Key:Len1/binary,
- ?UINT32(Len2), Q_s:Len2/big-signed-integer-unit:8,
- ?UINT32(Len3), Sig:Len3/binary>>) ->
+ ?DEC_BIN(Key,__1), ?DEC_MPINT(Q_s,__2), ?DEC_BIN(Sig,__3)>>) ->
#ssh_msg_kex_ecdh_reply{
- public_host_key = decode_host_key(Key),
+ public_host_key = public_key:ssh_decode(Key, ssh2_pubkey),
q_s = Q_s,
- h_sig = decode_sign(Sig)
+ h_sig = decode_signature(Sig)
};
-decode(<<?SSH_MSG_SERVICE_REQUEST, ?UINT32(Len0), Service:Len0/binary>>) ->
+decode(<<?SSH_MSG_SERVICE_REQUEST, ?DEC_BIN(Service,__0)>>) ->
#ssh_msg_service_request{
name = unicode:characters_to_list(Service)
};
-decode(<<?SSH_MSG_SERVICE_ACCEPT, ?UINT32(Len0), Service:Len0/binary>>) ->
+decode(<<?SSH_MSG_SERVICE_ACCEPT, ?DEC_BIN(Service,__0)>>) ->
#ssh_msg_service_accept{
name = unicode:characters_to_list(Service)
};
-decode(<<?BYTE(?SSH_MSG_DISCONNECT), ?UINT32(Code),
- ?UINT32(Len0), Desc:Len0/binary, ?UINT32(Len1), Lang:Len1/binary>>) ->
+decode(<<?BYTE(?SSH_MSG_DISCONNECT), ?UINT32(Code), ?DEC_BIN(Desc,__0), ?DEC_BIN(Lang,__1)>>) ->
#ssh_msg_disconnect{
code = Code,
description = unicode:characters_to_list(Desc),
@@ -514,8 +494,7 @@ decode(<<?BYTE(?SSH_MSG_DISCONNECT), ?UINT32(Code),
};
%% Accept bad disconnects from ancient openssh clients that doesn't send language tag. Use english as a work-around.
-decode(<<?BYTE(?SSH_MSG_DISCONNECT), ?UINT32(Code),
- ?UINT32(Len0), Desc:Len0/binary>>) ->
+decode(<<?BYTE(?SSH_MSG_DISCONNECT), ?UINT32(Code), ?DEC_BIN(Desc,__0)>>) ->
#ssh_msg_disconnect{
code = Code,
description = unicode:characters_to_list(Desc),
@@ -525,21 +504,25 @@ decode(<<?BYTE(?SSH_MSG_DISCONNECT), ?UINT32(Code),
decode(<<?SSH_MSG_NEWKEYS>>) ->
#ssh_msg_newkeys{};
-decode(<<?BYTE(?SSH_MSG_IGNORE), ?UINT32(Len), Data:Len/binary>>) ->
+decode(<<?BYTE(?SSH_MSG_IGNORE), ?DEC_BIN(Data,__0)>>) ->
#ssh_msg_ignore{data = Data};
decode(<<?BYTE(?SSH_MSG_UNIMPLEMENTED), ?UINT32(Seq)>>) ->
#ssh_msg_unimplemented{sequence = Seq};
-decode(<<?BYTE(?SSH_MSG_DEBUG), ?BYTE(Bool), ?UINT32(Len0), Msg:Len0/binary,
- ?UINT32(Len1), Lang:Len1/binary>>) ->
+decode(<<?BYTE(?SSH_MSG_DEBUG), ?BYTE(Bool), ?DEC_BIN(Msg,__0), ?DEC_BIN(Lang,__1)>>) ->
#ssh_msg_debug{always_display = erl_boolean(Bool),
message = Msg,
language = Lang}.
+%%%================================================================
+%%%
+%%% Helper functions
+%%%
+
decode_keyboard_interactive_prompts(<<>>, Acc) ->
lists:reverse(Acc);
-decode_keyboard_interactive_prompts(<<?UINT32(Len), Prompt:Len/binary, ?BYTE(Bool), Bin/binary>>,
+decode_keyboard_interactive_prompts(<<?DEC_BIN(Prompt,__0), ?BYTE(Bool), Bin/binary>>,
Acc) ->
decode_keyboard_interactive_prompts(Bin, [{Prompt, erl_boolean(Bool)} | Acc]).
@@ -555,43 +538,25 @@ decode_kex_init(<<?BYTE(Bool)>>, Acc, 0) ->
%% See rfc 4253 7.1
X = 0,
list_to_tuple(lists:reverse([X, erl_boolean(Bool) | Acc]));
-decode_kex_init(<<?UINT32(Len), Data:Len/binary, Rest/binary>>, Acc, N) ->
+decode_kex_init(<<?DEC_BIN(Data,__0), Rest/binary>>, Acc, N) ->
Names = string:tokens(unicode:characters_to_list(Data), ","),
decode_kex_init(Rest, [Names | Acc], N -1).
+%%%================================================================
+%%%
+%%% Signature decode/encode
+%%%
-decode_sign(<<?UINT32(Len), _Alg:Len/binary, ?UINT32(_), Signature/binary>>) ->
+decode_signature(<<?DEC_BIN(_Alg,__0), ?UINT32(_), Signature/binary>>) ->
Signature.
-decode_host_key(<<?UINT32(Len), Alg:Len/binary, Rest/binary>>) ->
- decode_host_key(Alg, Rest).
-
-decode_host_key(<<"ssh-rsa">>, <<?UINT32(Len0), E:Len0/big-signed-integer-unit:8,
- ?UINT32(Len1), N:Len1/big-signed-integer-unit:8>>) ->
- #'RSAPublicKey'{publicExponent = E,
- modulus = N};
-
-decode_host_key(<<"ssh-dss">>,
- <<?UINT32(Len0), P:Len0/big-signed-integer-unit:8,
- ?UINT32(Len1), Q:Len1/big-signed-integer-unit:8,
- ?UINT32(Len2), G:Len2/big-signed-integer-unit:8,
- ?UINT32(Len3), Y:Len3/big-signed-integer-unit:8>>) ->
- {Y, #'Dss-Parms'{p = P,
- q = Q,
- g = G}}.
-
-encode_host_key(#'RSAPublicKey'{modulus = N, publicExponent = E}) ->
- ssh_bits:encode(["ssh-rsa", E, N], [string, mpint, mpint]);
-encode_host_key({Y, #'Dss-Parms'{p = P, q = Q, g = G}}) ->
- ssh_bits:encode(["ssh-dss", P, Q, G, Y],
- [string, mpint, mpint, mpint, mpint]);
-encode_host_key(#'RSAPrivateKey'{modulus = N, publicExponent = E}) ->
- ssh_bits:encode(["ssh-rsa", E, N], [string, mpint, mpint]);
-encode_host_key(#'DSAPrivateKey'{y = Y, p = P, q = Q, g = G}) ->
- ssh_bits:encode(["ssh-dss", P, Q, G, Y],
- [string, mpint, mpint, mpint, mpint]).
-encode_sign(#'RSAPrivateKey'{}, Signature) ->
+
+encode_signature(#'RSAPublicKey'{}, Signature) ->
ssh_bits:encode(["ssh-rsa", Signature],[string, binary]);
-encode_sign(#'DSAPrivateKey'{}, Signature) ->
- ssh_bits:encode(["ssh-dss", Signature],[string, binary]).
+encode_signature({_, #'Dss-Parms'{}}, Signature) ->
+ ssh_bits:encode(["ssh-dss", Signature],[string, binary]);
+encode_signature({#'ECPoint'{}, {namedCurve,OID}}, Signature) ->
+ CurveName = public_key:oid2ssh_curvename(OID),
+ ssh_bits:encode([<<"ecdsa-sha2-",CurveName/binary>>, Signature], [binary,binary]).
+
diff --git a/lib/ssh/src/ssh_sftpd.erl b/lib/ssh/src/ssh_sftpd.erl
index a6549f1c73..819cba697e 100644
--- a/lib/ssh/src/ssh_sftpd.erl
+++ b/lib/ssh/src/ssh_sftpd.erl
@@ -30,6 +30,7 @@
-include("ssh.hrl").
-include("ssh_xfer.hrl").
+-include("ssh_connect.hrl"). %% For ?DEFAULT_PACKET_SIZE and ?DEFAULT_WINDOW_SIZE
%%--------------------------------------------------------------------
%% External exports
@@ -47,6 +48,7 @@
file_handler, % atom() - callback module
file_state, % state for the file callback module
max_files, % integer >= 0 max no files sent during READDIR
+ options, % from the subsystem declaration
handles % list of open handles
%% handle is either {<int>, directory, {Path, unread|eof}} or
%% {<int>, file, {Path, IoDevice}}
@@ -121,6 +123,7 @@ init(Options) ->
MaxLength = proplists:get_value(max_files, Options, 0),
Vsn = proplists:get_value(sftpd_vsn, Options, 5),
{ok, State#state{cwd = CWD, root = Root, max_files = MaxLength,
+ options = Options,
handles = [], pending = <<>>,
xf = #ssh_xfer{vsn = Vsn, ext = []}}}.
@@ -164,7 +167,9 @@ handle_ssh_msg({ssh_cm, _, {exit_status, ChannelId, Status}}, State) ->
%% Description: Handles other messages
%%--------------------------------------------------------------------
handle_msg({ssh_channel_up, ChannelId, ConnectionManager},
- #state{xf =Xf} = State) ->
+ #state{xf = Xf,
+ options = Options} = State) ->
+ maybe_increase_recv_window(ConnectionManager, ChannelId, Options),
{ok, State#state{xf = Xf#ssh_xfer{cm = ConnectionManager,
channel = ChannelId}}}.
@@ -934,3 +939,18 @@ rename(Path, Path2, ReqId, State0) ->
{Status, FS1} = FileMod:rename(Path, Path2, FS0),
State1 = State0#state{file_state = FS1},
send_status(Status, ReqId, State1).
+
+
+maybe_increase_recv_window(ConnectionManager, ChannelId, Options) ->
+ WantedRecvWindowSize =
+ proplists:get_value(recv_window_size, Options, 1000000),
+ NumPkts = WantedRecvWindowSize div ?DEFAULT_PACKET_SIZE,
+ Increment = NumPkts*?DEFAULT_PACKET_SIZE - ?DEFAULT_WINDOW_SIZE,
+
+ if
+ Increment > 0 ->
+ ssh_connection:adjust_window(ConnectionManager, ChannelId,
+ Increment);
+ Increment =< 0 ->
+ do_nothing
+ end.
diff --git a/lib/ssh/src/ssh_transport.erl b/lib/ssh/src/ssh_transport.erl
index 2b6f0a3cdc..67a0d29bb8 100644
--- a/lib/ssh/src/ssh_transport.erl
+++ b/lib/ssh/src/ssh_transport.erl
@@ -31,10 +31,10 @@
-include("ssh.hrl").
-export([versions/2, hello_version_msg/1]).
--export([next_seqnum/1, decrypt_first_block/2, decrypt_blocks/3,
+-export([next_seqnum/1,
supported_algorithms/0, supported_algorithms/1,
default_algorithms/0, default_algorithms/1,
- is_valid_mac/3,
+ handle_packet_part/4,
handle_hello_version/1,
key_exchange_init_msg/1,
key_init/3, new_keys_message/1,
@@ -44,9 +44,14 @@
handle_kexdh_reply/2,
handle_kex_ecdh_init/2,
handle_kex_ecdh_reply/2,
- unpack/3, decompress/2, ssh_packet/2, pack/2, msg_data/1,
+ extract_public_key/1,
+ ssh_packet/2, pack/2,
sign/3, verify/4]).
+%%% For test suites
+-export([pack/3]).
+-export([decompress/2, decrypt_blocks/3, is_valid_mac/3 ]). % FIXME: remove
+
%%%----------------------------------------------------------------------------
%%%
%%% There is a difference between supported and default algorithms. The
@@ -65,11 +70,15 @@ default_algorithms() -> [{K,default_algorithms(K)} || K <- algo_classes()].
algo_classes() -> [kex, public_key, cipher, mac, compression].
-default_algorithms(compression) ->
- %% Do not announce '[email protected]' because there seem to be problems
- supported_algorithms(compression, same(['[email protected]']));
+
+default_algorithms(cipher) ->
+ supported_algorithms(cipher, same(['AEAD_AES_128_GCM',
+ 'AEAD_AES_256_GCM']));
+default_algorithms(mac) ->
+ supported_algorithms(mac, same(['AEAD_AES_128_GCM',
+ 'AEAD_AES_256_GCM']));
default_algorithms(Alg) ->
- supported_algorithms(Alg).
+ supported_algorithms(Alg, []).
supported_algorithms() -> [{K,supported_algorithms(K)} || K <- algo_classes()].
@@ -79,58 +88,50 @@ supported_algorithms(kex) ->
[
{'ecdh-sha2-nistp256', [{public_keys,ecdh}, {ec_curve,secp256r1}, {hashs,sha256}]},
{'ecdh-sha2-nistp384', [{public_keys,ecdh}, {ec_curve,secp384r1}, {hashs,sha384}]},
+ {'diffie-hellman-group14-sha1', [{public_keys,dh}, {hashs,sha}]},
+ {'diffie-hellman-group-exchange-sha256', [{public_keys,dh}, {hashs,sha256}]},
+ {'diffie-hellman-group-exchange-sha1', [{public_keys,dh}, {hashs,sha}]},
{'ecdh-sha2-nistp521', [{public_keys,ecdh}, {ec_curve,secp521r1}, {hashs,sha512}]},
- {'diffie-hellman-group14-sha1', [{public_keys,dh}, {hashs,sha}]},
- {'diffie-hellman-group-exchange-sha256', [{public_keys,dh}, {hashs,sha256}]},
- {'diffie-hellman-group-exchange-sha1', [{public_keys,dh}, {hashs,sha}]},
- {'diffie-hellman-group1-sha1', [{public_keys,dh}, {hashs,sha}]}
+ {'diffie-hellman-group1-sha1', [{public_keys,dh}, {hashs,sha}]}
]);
supported_algorithms(public_key) ->
- ssh_auth:default_public_key_algorithms();
+ select_crypto_supported(
+ [{'ecdsa-sha2-nistp256', [{public_keys,ecdsa}, {hashs,sha256}, {ec_curve,secp256r1}]},
+ {'ecdsa-sha2-nistp384', [{public_keys,ecdsa}, {hashs,sha384}, {ec_curve,secp384r1}]},
+ {'ecdsa-sha2-nistp521', [{public_keys,ecdsa}, {hashs,sha512}, {ec_curve,secp521r1}]},
+ {'ssh-rsa', [{public_keys,rsa}, {hashs,sha} ]},
+ {'ssh-dss', [{public_keys,dss}, {hashs,sha} ]}
+ ]);
+
supported_algorithms(cipher) ->
same(
select_crypto_supported(
- [{'aes128-ctr', [{ciphers,aes_ctr}]},
- {'aes128-cbc', [{ciphers,aes_cbc128}]},
- {'3des-cbc', [{ciphers,des3_cbc}]}
+ [{'aes256-ctr', [{ciphers,{aes_ctr,256}}]},
+ {'aes192-ctr', [{ciphers,{aes_ctr,192}}]},
+ {'aes128-ctr', [{ciphers,{aes_ctr,128}}]},
+ {'aes128-cbc', [{ciphers,aes_cbc128}]},
+ {'[email protected]', [{ciphers,{aes_gcm,128}}]},
+ {'[email protected]', [{ciphers,{aes_gcm,256}}]},
+ {'AEAD_AES_128_GCM', [{ciphers,{aes_gcm,128}}]},
+ {'AEAD_AES_256_GCM', [{ciphers,{aes_gcm,256}}]},
+ {'3des-cbc', [{ciphers,des3_cbc}]}
]
));
supported_algorithms(mac) ->
same(
select_crypto_supported(
- [{'hmac-sha2-512', [{hashs,sha512}]},
- {'hmac-sha2-256', [{hashs,sha256}]},
- {'hmac-sha1', [{hashs,sha}]}
+ [{'hmac-sha2-256', [{hashs,sha256}]},
+ {'hmac-sha2-512', [{hashs,sha512}]},
+ {'hmac-sha1', [{hashs,sha}]},
+ {'AEAD_AES_128_GCM', [{ciphers,{aes_gcm,128}}]},
+ {'AEAD_AES_256_GCM', [{ciphers,{aes_gcm,256}}]}
]
));
supported_algorithms(compression) ->
- same(['none','zlib','[email protected]']).
-
-
-supported_algorithms(Key, [{client2server,BL1},{server2client,BL2}]) ->
- [{client2server,As1},{server2client,As2}] = supported_algorithms(Key),
- [{client2server,As1--BL1},{server2client,As2--BL2}];
-supported_algorithms(Key, BlackList) ->
- supported_algorithms(Key) -- BlackList.
-
-select_crypto_supported(L) ->
- Sup = [{ec_curve,crypto_supported_curves()} | crypto:supports()],
- [Name || {Name,CryptoRequires} <- L,
- crypto_supported(CryptoRequires, Sup)].
-
-crypto_supported_curves() ->
- try crypto:ec_curves()
- catch _:_ -> []
- end.
-
-crypto_supported(Conditions, Supported) ->
- lists:all( fun({Tag,CryptoName}) ->
- lists:member(CryptoName, proplists:get_value(Tag,Supported,[]))
- end, Conditions).
-
-
-same(Algs) -> [{client2server,Algs}, {server2client,Algs}].
-
+ same(['none',
+ 'zlib'
+ ]).
%%%----------------------------------------------------------------------------
versions(client, Options)->
@@ -170,12 +171,6 @@ hello_version_msg(Data) ->
next_seqnum(SeqNum) ->
(SeqNum + 1) band 16#ffffffff.
-decrypt_first_block(Bin, #ssh{decrypt_block_size = BlockSize} = Ssh0) ->
- <<EncBlock:BlockSize/binary, EncData/binary>> = Bin,
- {Ssh, <<?UINT32(PacketLen), _/binary>> = DecData} =
- decrypt(Ssh0, EncBlock),
- {Ssh, PacketLen, DecData, EncData}.
-
decrypt_blocks(Bin, Length, Ssh0) ->
<<EncBlocks:Length/binary, EncData/binary>> = Bin,
{Ssh, DecData} = decrypt(Ssh0, EncBlocks),
@@ -303,9 +298,7 @@ verify_algorithm(#alg{encrypt = undefined}) -> false;
verify_algorithm(#alg{decrypt = undefined}) -> false;
verify_algorithm(#alg{compress = undefined}) -> false;
verify_algorithm(#alg{decompress = undefined}) -> false;
-
-verify_algorithm(#alg{kex = Kex}) -> lists:member(Kex, supported_algorithms(kex));
-verify_algorithm(_) -> false.
+verify_algorithm(#alg{kex = Kex}) -> lists:member(Kex, supported_algorithms(kex)).
%%%----------------------------------------------------------------
%%%
@@ -319,11 +312,12 @@ key_exchange_first_msg(Kex, Ssh0) when Kex == 'diffie-hellman-group1-sha1' ;
{ok, SshPacket,
Ssh1#ssh{keyex_key = {{Private, Public}, {G, P}}}};
-key_exchange_first_msg(Kex, Ssh0) when Kex == 'diffie-hellman-group-exchange-sha1' ;
- Kex == 'diffie-hellman-group-exchange-sha256' ->
- Min = ?DEFAULT_DH_GROUP_MIN,
- NBits = ?DEFAULT_DH_GROUP_NBITS,
- Max = ?DEFAULT_DH_GROUP_MAX,
+key_exchange_first_msg(Kex, Ssh0=#ssh{opts=Opts}) when Kex == 'diffie-hellman-group-exchange-sha1' ;
+ Kex == 'diffie-hellman-group-exchange-sha256' ->
+ {Min,NBits,Max} =
+ proplists:get_value(dh_gex_limits, Opts, {?DEFAULT_DH_GROUP_MIN,
+ ?DEFAULT_DH_GROUP_NBITS,
+ ?DEFAULT_DH_GROUP_MAX}),
{SshPacket, Ssh1} =
ssh_packet(#ssh_msg_kex_dh_gex_request{min = Min,
n = NBits,
@@ -354,13 +348,15 @@ handle_kexdh_init(#ssh_msg_kexdh_init{e = E},
1=<E, E=<(P-1) ->
{Public, Private} = generate_key(dh, [P,G]),
K = compute_key(dh, E, Private, [P,G]),
- Key = get_host_key(Ssh0),
- H = kex_h(Ssh0, Key, E, Public, K),
- H_SIG = sign_host_key(Ssh0, Key, H),
- {SshPacket, Ssh1} = ssh_packet(#ssh_msg_kexdh_reply{public_host_key = Key,
- f = Public,
- h_sig = H_SIG
- }, Ssh0),
+ MyPrivHostKey = get_host_key(Ssh0),
+ MyPubHostKey = extract_public_key(MyPrivHostKey),
+ H = kex_h(Ssh0, MyPubHostKey, E, Public, K),
+ H_SIG = sign_host_key(Ssh0, MyPrivHostKey, H),
+ {SshPacket, Ssh1} =
+ ssh_packet(#ssh_msg_kexdh_reply{public_host_key = MyPubHostKey,
+ f = Public,
+ h_sig = H_SIG
+ }, Ssh0),
{ok, SshPacket, Ssh1#ssh{keyex_key = {{Private, Public}, {G, P}},
shared_secret = K,
exchanged_hash = H,
@@ -375,7 +371,7 @@ handle_kexdh_init(#ssh_msg_kexdh_init{e = E},
})
end.
-handle_kexdh_reply(#ssh_msg_kexdh_reply{public_host_key = HostKey,
+handle_kexdh_reply(#ssh_msg_kexdh_reply{public_host_key = PeerPubHostKey,
f = F,
h_sig = H_SIG},
#ssh{keyex_key = {{Private, Public}, {G, P}}} = Ssh0) ->
@@ -383,9 +379,9 @@ handle_kexdh_reply(#ssh_msg_kexdh_reply{public_host_key = HostKey,
if
1=<F, F=<(P-1)->
K = compute_key(dh, F, Private, [P,G]),
- H = kex_h(Ssh0, HostKey, Public, F, K),
+ H = kex_h(Ssh0, PeerPubHostKey, Public, F, K),
- case verify_host_key(Ssh0, HostKey, H, H_SIG) of
+ case verify_host_key(Ssh0, PeerPubHostKey, H, H_SIG) of
ok ->
{SshPacket, Ssh} = ssh_packet(#ssh_msg_newkeys{}, Ssh0),
{ok, SshPacket, Ssh#ssh{shared_secret = K,
@@ -414,19 +410,63 @@ handle_kexdh_reply(#ssh_msg_kexdh_reply{public_host_key = HostKey,
%%%
%%% diffie-hellman-group-exchange-sha1
%%%
-handle_kex_dh_gex_request(#ssh_msg_kex_dh_gex_request{min = Min,
+handle_kex_dh_gex_request(#ssh_msg_kex_dh_gex_request{min = Min0,
n = NBits,
- max = Max},
- Ssh0=#ssh{opts=Opts}) when Min=<NBits, NBits=<Max ->
+ max = Max0},
+ Ssh0=#ssh{opts=Opts}) when Min0=<NBits, NBits=<Max0 ->
%% server
- {G, P} = dh_gex_group(Min, NBits, Max, proplists:get_value(dh_gex_groups,Opts)),
- {Public, Private} = generate_key(dh, [P,G]),
- {SshPacket, Ssh} =
- ssh_packet(#ssh_msg_kex_dh_gex_group{p = P, g = G}, Ssh0),
- {ok, SshPacket,
- Ssh#ssh{keyex_key = {{Private, Public}, {G, P}},
- keyex_info = {Min, Max, NBits}
- }};
+ {Min, Max} = adjust_gex_min_max(Min0, Max0, Opts),
+ case public_key:dh_gex_group(Min, NBits, Max,
+ proplists:get_value(dh_gex_groups,Opts)) of
+ {ok, {_Sz, {G,P}}} ->
+ {Public, Private} = generate_key(dh, [P,G]),
+ {SshPacket, Ssh} =
+ ssh_packet(#ssh_msg_kex_dh_gex_group{p = P, g = G}, Ssh0),
+ {ok, SshPacket,
+ Ssh#ssh{keyex_key = {{Private, Public}, {G, P}},
+ keyex_info = {Min, Max, NBits}
+ }};
+ {error,_} ->
+ throw(#ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
+ description = "No possible diffie-hellman-group-exchange group found",
+ language = ""})
+ end;
+
+handle_kex_dh_gex_request(#ssh_msg_kex_dh_gex_request_old{n = NBits},
+ Ssh0=#ssh{opts=Opts}) ->
+ %% server
+ %%
+ %% This message was in the draft-00 of rfc4419
+ %% (https://tools.ietf.org/html/draft-ietf-secsh-dh-group-exchange-00)
+ %% In later drafts and the rfc is "is used for backward compatibility".
+ %% Unfortunatly the rfc does not specify how to treat the parameter n
+ %% if there is no group of that modulus length :(
+ %% The draft-00 however specifies that n is the "... number of bits
+ %% the subgroup should have at least".
+ %% Further, it says that "Servers and clients SHOULD support groups
+ %% with a modulus length of k bits, where 1024 <= k <= 8192."
+ %%
+ Min0 = NBits,
+ Max0 = 8192,
+ {Min, Max} = adjust_gex_min_max(Min0, Max0, Opts),
+ case public_key:dh_gex_group(Min, NBits, Max,
+ proplists:get_value(dh_gex_groups,Opts)) of
+ {ok, {_Sz, {G,P}}} ->
+ {Public, Private} = generate_key(dh, [P,G]),
+ {SshPacket, Ssh} =
+ ssh_packet(#ssh_msg_kex_dh_gex_group{p = P, g = G}, Ssh0),
+ {ok, SshPacket,
+ Ssh#ssh{keyex_key = {{Private, Public}, {G, P}},
+ keyex_info = {-1, -1, NBits} % flag for kex_h hash calc
+ }};
+ {error,_} ->
+ throw(#ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
+ description = "No possible diffie-hellman-group-exchange group found",
+ language = ""})
+ end;
+
handle_kex_dh_gex_request(_, _) ->
throw({{error,bad_ssh_msg_kex_dh_gex_request},
#ssh_msg_disconnect{
@@ -435,6 +475,26 @@ handle_kex_dh_gex_request(_, _) ->
language = ""}
}).
+
+adjust_gex_min_max(Min0, Max0, Opts) ->
+ case proplists:get_value(dh_gex_limits, Opts) of
+ undefined ->
+ {Min0, Max0};
+ {Min1, Max1} ->
+ Min2 = max(Min0, Min1),
+ Max2 = min(Max0, Max1),
+ if
+ Min2 =< Max2 ->
+ {Min2, Max2};
+ Max2 < Min2 ->
+ throw(#ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
+ description = "No possible diffie-hellman-group-exchange group possible",
+ language = ""})
+ end
+ end.
+
+
handle_kex_dh_gex_group(#ssh_msg_kex_dh_gex_group{p = P, g = G}, Ssh0) ->
%% client
{Public, Private} = generate_key(dh, [P,G]),
@@ -454,11 +514,12 @@ handle_kex_dh_gex_init(#ssh_msg_kex_dh_gex_init{e = E},
K = compute_key(dh, E, Private, [P,G]),
if
1<K, K<(P-1) ->
- HostKey = get_host_key(Ssh0),
- H = kex_h(Ssh0, HostKey, Min, NBits, Max, P, G, E, Public, K),
- H_SIG = sign_host_key(Ssh0, HostKey, H),
+ MyPrivHostKey = get_host_key(Ssh0),
+ MyPubHostKey = extract_public_key(MyPrivHostKey),
+ H = kex_h(Ssh0, MyPubHostKey, Min, NBits, Max, P, G, E, Public, K),
+ H_SIG = sign_host_key(Ssh0, MyPrivHostKey, H),
{SshPacket, Ssh} =
- ssh_packet(#ssh_msg_kex_dh_gex_reply{public_host_key = HostKey,
+ ssh_packet(#ssh_msg_kex_dh_gex_reply{public_host_key = MyPubHostKey,
f = Public,
h_sig = H_SIG}, Ssh0),
{ok, SshPacket, Ssh#ssh{shared_secret = K,
@@ -482,7 +543,7 @@ handle_kex_dh_gex_init(#ssh_msg_kex_dh_gex_init{e = E},
})
end.
-handle_kex_dh_gex_reply(#ssh_msg_kex_dh_gex_reply{public_host_key = HostKey,
+handle_kex_dh_gex_reply(#ssh_msg_kex_dh_gex_reply{public_host_key = PeerPubHostKey,
f = F,
h_sig = H_SIG},
#ssh{keyex_key = {{Private, Public}, {G, P}},
@@ -494,9 +555,9 @@ handle_kex_dh_gex_reply(#ssh_msg_kex_dh_gex_reply{public_host_key = HostKey,
K = compute_key(dh, F, Private, [P,G]),
if
1<K, K<(P-1) ->
- H = kex_h(Ssh0, HostKey, Min, NBits, Max, P, G, Public, F, K),
+ H = kex_h(Ssh0, PeerPubHostKey, Min, NBits, Max, P, G, Public, F, K),
- case verify_host_key(Ssh0, HostKey, H, H_SIG) of
+ case verify_host_key(Ssh0, PeerPubHostKey, H, H_SIG) of
ok ->
{SshPacket, Ssh} = ssh_packet(#ssh_msg_newkeys{}, Ssh0),
{ok, SshPacket, Ssh#ssh{shared_secret = K,
@@ -535,24 +596,26 @@ handle_kex_ecdh_init(#ssh_msg_kex_ecdh_init{q_c = PeerPublic},
Ssh0 = #ssh{algorithms = #alg{kex=Kex}}) ->
%% at server
Curve = ecdh_curve(Kex),
- case ecdh_validate_public_key(PeerPublic, Curve) of
- true ->
- {MyPublic, MyPrivate} = generate_key(ecdh, Curve),
- K = compute_key(ecdh, PeerPublic, MyPrivate, Curve),
- HostKey = get_host_key(Ssh0),
- H = kex_h(Ssh0, Curve, HostKey, PeerPublic, MyPublic, K),
- H_SIG = sign_host_key(Ssh0, HostKey, H),
+ {MyPublic, MyPrivate} = generate_key(ecdh, Curve),
+ try
+ compute_key(ecdh, PeerPublic, MyPrivate, Curve)
+ of
+ K ->
+ MyPrivHostKey = get_host_key(Ssh0),
+ MyPubHostKey = extract_public_key(MyPrivHostKey),
+ H = kex_h(Ssh0, Curve, MyPubHostKey, PeerPublic, MyPublic, K),
+ H_SIG = sign_host_key(Ssh0, MyPrivHostKey, H),
{SshPacket, Ssh1} =
- ssh_packet(#ssh_msg_kex_ecdh_reply{public_host_key = HostKey,
+ ssh_packet(#ssh_msg_kex_ecdh_reply{public_host_key = MyPubHostKey,
q_s = MyPublic,
h_sig = H_SIG},
Ssh0),
{ok, SshPacket, Ssh1#ssh{keyex_key = {{MyPublic,MyPrivate},Curve},
shared_secret = K,
exchanged_hash = H,
- session_id = sid(Ssh1, H)}};
-
- false ->
+ session_id = sid(Ssh1, H)}}
+ catch
+ _:_ ->
throw({{error,invalid_peer_public_key},
#ssh_msg_disconnect{
code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
@@ -561,17 +624,18 @@ handle_kex_ecdh_init(#ssh_msg_kex_ecdh_init{q_c = PeerPublic},
})
end.
-handle_kex_ecdh_reply(#ssh_msg_kex_ecdh_reply{public_host_key = HostKey,
+handle_kex_ecdh_reply(#ssh_msg_kex_ecdh_reply{public_host_key = PeerPubHostKey,
q_s = PeerPublic,
h_sig = H_SIG},
#ssh{keyex_key = {{MyPublic,MyPrivate}, Curve}} = Ssh0
) ->
%% at client
- case ecdh_validate_public_key(PeerPublic, Curve) of
- true ->
- K = compute_key(ecdh, PeerPublic, MyPrivate, Curve),
- H = kex_h(Ssh0, Curve, HostKey, MyPublic, PeerPublic, K),
- case verify_host_key(Ssh0, HostKey, H, H_SIG) of
+ try
+ compute_key(ecdh, PeerPublic, MyPrivate, Curve)
+ of
+ K ->
+ H = kex_h(Ssh0, Curve, PeerPubHostKey, MyPublic, PeerPublic, K),
+ case verify_host_key(Ssh0, PeerPubHostKey, H, H_SIG) of
ok ->
{SshPacket, Ssh} = ssh_packet(#ssh_msg_newkeys{}, Ssh0),
{ok, SshPacket, Ssh#ssh{shared_secret = K,
@@ -584,9 +648,9 @@ handle_kex_ecdh_reply(#ssh_msg_kex_ecdh_reply{public_host_key = HostKey,
description = "Key exchange failed",
language = ""}
})
- end;
-
- false ->
+ end
+ catch
+ _:_ ->
throw({{error,invalid_peer_public_key},
#ssh_msg_disconnect{
code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
@@ -596,8 +660,6 @@ handle_kex_ecdh_reply(#ssh_msg_kex_ecdh_reply{public_host_key = HostKey,
end.
-ecdh_validate_public_key(_, _) -> true. % FIXME: Far too many false positives :)
-
%%%----------------------------------------------------------------
handle_new_keys(#ssh_msg_newkeys{}, Ssh0) ->
try install_alg(Ssh0) of
@@ -623,33 +685,49 @@ get_host_key(SSH) ->
#ssh{key_cb = Mod, opts = Opts, algorithms = ALG} = SSH,
case Mod:host_key(ALG#alg.hkey, Opts) of
- {ok, #'RSAPrivateKey'{} = Key} ->
- Key;
- {ok, #'DSAPrivateKey'{} = Key} ->
- Key;
+ {ok, #'RSAPrivateKey'{} = Key} -> Key;
+ {ok, #'DSAPrivateKey'{} = Key} -> Key;
+ {ok, #'ECPrivateKey'{} = Key} -> Key;
Result ->
exit({error, {Result, unsupported_key_type}})
end.
-sign_host_key(_Ssh, #'RSAPrivateKey'{} = Private, H) ->
- Hash = sha,
- _Signature = sign(H, Hash, Private);
-sign_host_key(_Ssh, #'DSAPrivateKey'{} = Private, H) ->
- Hash = sha,
- _RawSignature = sign(H, Hash, Private).
+sign_host_key(_Ssh, PrivateKey, H) ->
+ sign(H, sign_host_key_sha(PrivateKey), PrivateKey).
+
+sign_host_key_sha(#'ECPrivateKey'{parameters = {namedCurve,OID}}) -> sha(OID);
+sign_host_key_sha(#'RSAPrivateKey'{}) -> sha;
+sign_host_key_sha(#'DSAPrivateKey'{}) -> sha.
+
+
+extract_public_key(#'RSAPrivateKey'{modulus = N, publicExponent = E}) ->
+ #'RSAPublicKey'{modulus = N, publicExponent = E};
+extract_public_key(#'DSAPrivateKey'{y = Y, p = P, q = Q, g = G}) ->
+ {Y, #'Dss-Parms'{p=P, q=Q, g=G}};
+extract_public_key(#'ECPrivateKey'{parameters = {namedCurve,OID},
+ publicKey = Q}) ->
+ {#'ECPoint'{point=Q}, {namedCurve,OID}}.
+
verify_host_key(SSH, PublicKey, Digest, Signature) ->
- case verify(Digest, sha, Signature, PublicKey) of
+ case verify(Digest, host_key_sha(PublicKey), Signature, PublicKey) of
false ->
{error, bad_signature};
true ->
known_host_key(SSH, PublicKey, public_algo(PublicKey))
end.
-public_algo(#'RSAPublicKey'{}) ->
- 'ssh-rsa';
-public_algo({_, #'Dss-Parms'{}}) ->
- 'ssh-dss'.
+
+host_key_sha(#'RSAPublicKey'{}) -> sha;
+host_key_sha({_, #'Dss-Parms'{}}) -> sha;
+host_key_sha({#'ECPoint'{},{namedCurve,OID}}) -> sha(OID).
+
+public_algo(#'RSAPublicKey'{}) -> 'ssh-rsa';
+public_algo({_, #'Dss-Parms'{}}) -> 'ssh-dss';
+public_algo({#'ECPoint'{},{namedCurve,OID}}) ->
+ Curve = public_key:oid2ssh_curvename(OID),
+ list_to_atom("ecdsa-sha2-" ++ binary_to_list(Curve)).
+
accepted_host(Ssh, PeerName, Opts) ->
case proplists:get_value(silently_accept_hosts, Opts, false) of
@@ -682,8 +760,12 @@ known_host_key(#ssh{opts = Opts, key_cb = Mod, peer = Peer} = Ssh,
%% The first algorithm in each list MUST be the preferred (guessed)
%% algorithm. Each string MUST contain at least one algorithm name.
select_algorithm(Role, Client, Server) ->
- {Encrypt, Decrypt} = select_encrypt_decrypt(Role, Client, Server),
- {SendMac, RecvMac} = select_send_recv_mac(Role, Client, Server),
+ {Encrypt0, Decrypt0} = select_encrypt_decrypt(Role, Client, Server),
+ {SendMac0, RecvMac0} = select_send_recv_mac(Role, Client, Server),
+
+ {Encrypt, SendMac} = aead_gcm_simultan(Encrypt0, SendMac0),
+ {Decrypt, RecvMac} = aead_gcm_simultan(Decrypt0, RecvMac0),
+
{Compression, Decompression} =
select_compression_decompression(Role, Client, Server),
@@ -714,6 +796,38 @@ select_algorithm(Role, Client, Server) ->
s_lng = S_Lng},
{ok, Alg}.
+
+%%% It is an agreed problem with RFC 5674 that if the selection is
+%%% Cipher = AEAD_AES_x_GCM and
+%%% Mac = AEAD_AES_y_GCM (where x =/= y)
+%%% then it is undefined what length should be selected.
+%%%
+%%% If only one of the two lengths (128,256) is available, I claim that
+%%% there is no such ambiguity.
+
+%%% From https://anongit.mindrot.org/openssh.git/plain/PROTOCOL
+%%% (read Nov 20, 2015)
+%%% 1.6 transport: AES-GCM
+%%%
+%%% OpenSSH supports the AES-GCM algorithm as specified in RFC 5647.
+%%% Because of problems with the specification of the key exchange
+%%% the behaviour of OpenSSH differs from the RFC as follows:
+%%%
+%%% AES-GCM is only negotiated as the cipher algorithms
+%%% "[email protected]" or "[email protected]" and never as
+%%% an MAC algorithm. Additionally, if AES-GCM is selected as the cipher
+%%% the exchanged MAC algorithms are ignored and there doesn't have to be
+%%% a matching MAC.
+
+aead_gcm_simultan('[email protected]', _) -> {'AEAD_AES_128_GCM', 'AEAD_AES_128_GCM'};
+aead_gcm_simultan('[email protected]', _) -> {'AEAD_AES_256_GCM', 'AEAD_AES_256_GCM'};
+aead_gcm_simultan('AEAD_AES_128_GCM', _) -> {'AEAD_AES_128_GCM', 'AEAD_AES_128_GCM'};
+aead_gcm_simultan('AEAD_AES_256_GCM', _) -> {'AEAD_AES_256_GCM', 'AEAD_AES_256_GCM'};
+aead_gcm_simultan(_, 'AEAD_AES_128_GCM') -> {'AEAD_AES_128_GCM', 'AEAD_AES_128_GCM'};
+aead_gcm_simultan(_, 'AEAD_AES_256_GCM') -> {'AEAD_AES_256_GCM', 'AEAD_AES_256_GCM'};
+aead_gcm_simultan(Cipher, Mac) -> {Cipher,Mac}.
+
+
select_encrypt_decrypt(client, Client, Server) ->
Encrypt =
select(Client#ssh_msg_kexinit.encryption_algorithms_client_to_server,
@@ -748,18 +862,18 @@ select_compression_decompression(client, Client, Server) ->
Compression =
select(Client#ssh_msg_kexinit.compression_algorithms_client_to_server,
Server#ssh_msg_kexinit.compression_algorithms_client_to_server),
- Decomprssion =
+ Decompression =
select(Client#ssh_msg_kexinit.compression_algorithms_server_to_client,
Server#ssh_msg_kexinit.compression_algorithms_server_to_client),
- {Compression, Decomprssion};
+ {Compression, Decompression};
select_compression_decompression(server, Client, Server) ->
- Decomprssion =
+ Decompression =
select(Client#ssh_msg_kexinit.compression_algorithms_client_to_server,
Server#ssh_msg_kexinit.compression_algorithms_client_to_server),
Compression =
select(Client#ssh_msg_kexinit.compression_algorithms_server_to_client,
Server#ssh_msg_kexinit.compression_algorithms_server_to_client),
- {Compression, Decomprssion}.
+ {Compression, Decompression}.
install_alg(SSH) ->
SSH1 = alg_final(SSH),
@@ -830,13 +944,45 @@ ssh_packet(Msg, Ssh) ->
BinMsg = ssh_message:encode(Msg),
pack(BinMsg, Ssh).
-pack(Data0, #ssh{encrypt_block_size = BlockSize,
- send_sequence = SeqNum, send_mac = MacAlg,
- send_mac_key = MacKey,
- random_length_padding = RandomLengthPadding}
- = Ssh0) when is_binary(Data0) ->
- {Ssh1, Data} = compress(Ssh0, Data0),
- PL = (BlockSize - ((4 + 1 + size(Data)) rem BlockSize)) rem BlockSize,
+pack(Data, Ssh=#ssh{}) ->
+ pack(Data, Ssh, 0).
+
+%%% Note: pack/3 is only to be called from tests that wants
+%%% to deliberetly send packets with wrong PacketLength!
+%%% Use pack/2 for all other purposes!
+pack(PlainText,
+ #ssh{send_sequence = SeqNum,
+ send_mac = MacAlg,
+ send_mac_key = MacKey,
+ encrypt = CryptoAlg} = Ssh0, PacketLenDeviationForTests) when is_binary(PlainText) ->
+
+ {Ssh1, CompressedPlainText} = compress(Ssh0, PlainText),
+ {EcryptedPacket, MAC, Ssh3} =
+ case pkt_type(CryptoAlg) of
+ common ->
+ PaddingLen = padding_length(4+1+size(CompressedPlainText), Ssh0),
+ Padding = ssh_bits:random(PaddingLen),
+ PlainPacketLen = 1 + PaddingLen + size(CompressedPlainText) + PacketLenDeviationForTests,
+ PlainPacketData = <<?UINT32(PlainPacketLen),?BYTE(PaddingLen), CompressedPlainText/binary, Padding/binary>>,
+ {Ssh2, EcryptedPacket0} = encrypt(Ssh1, PlainPacketData),
+ MAC0 = mac(MacAlg, MacKey, SeqNum, PlainPacketData),
+ {EcryptedPacket0, MAC0, Ssh2};
+ aead ->
+ PaddingLen = padding_length(1+size(CompressedPlainText), Ssh0),
+ Padding = ssh_bits:random(PaddingLen),
+ PlainPacketLen = 1 + PaddingLen + size(CompressedPlainText) + PacketLenDeviationForTests,
+ PlainPacketData = <<?BYTE(PaddingLen), CompressedPlainText/binary, Padding/binary>>,
+ {Ssh2, {EcryptedPacket0,MAC0}} = encrypt(Ssh1, {<<?UINT32(PlainPacketLen)>>,PlainPacketData}),
+ {<<?UINT32(PlainPacketLen),EcryptedPacket0/binary>>, MAC0, Ssh2}
+ end,
+ FinalPacket = [EcryptedPacket, MAC],
+ Ssh = Ssh3#ssh{send_sequence = (SeqNum+1) band 16#ffffffff},
+ {FinalPacket, Ssh}.
+
+
+padding_length(Size, #ssh{encrypt_block_size = BlockSize,
+ random_length_padding = RandomLengthPadding}) ->
+ PL = (BlockSize - (Size rem BlockSize)) rem BlockSize,
MinPaddingLen = if PL < 4 -> PL + BlockSize;
true -> PL
end,
@@ -845,50 +991,103 @@ pack(Data0, #ssh{encrypt_block_size = BlockSize,
ExtraPaddingLen = try crypto:rand_uniform(0,MaxExtraBlocks)*PadBlockSize
catch _:_ -> 0
end,
- PaddingLen = MinPaddingLen + ExtraPaddingLen,
- Padding = ssh_bits:random(PaddingLen),
- PacketLen = 1 + PaddingLen + size(Data),
- PacketData = <<?UINT32(PacketLen),?BYTE(PaddingLen),
- Data/binary, Padding/binary>>,
- {Ssh2, EncPacket} = encrypt(Ssh1, PacketData),
- MAC = mac(MacAlg, MacKey, SeqNum, PacketData),
- Packet = [EncPacket, MAC],
- Ssh = Ssh2#ssh{send_sequence = (SeqNum+1) band 16#ffffffff},
- {Packet, Ssh}.
-
-unpack(EncodedSoFar, ReminingLenght, #ssh{recv_mac_size = MacSize} = Ssh0) ->
- SshLength = ReminingLenght - MacSize,
- {NoMac, Mac, Rest} = case MacSize of
- 0 ->
- <<NoMac0:SshLength/binary,
- Rest0/binary>> = EncodedSoFar,
- {NoMac0, <<>>, Rest0};
- _ ->
- <<NoMac0:SshLength/binary,
- Mac0:MacSize/binary,
- Rest0/binary>> = EncodedSoFar,
- {NoMac0, Mac0, Rest0}
- end,
- {Ssh1, DecData, <<>>} =
- case SshLength of
- 0 ->
- {Ssh0, <<>>, <<>>};
- _ ->
- decrypt_blocks(NoMac, SshLength, Ssh0)
- end,
- {Ssh1, DecData, Rest, Mac}.
+ MinPaddingLen + ExtraPaddingLen.
+
+
+
+handle_packet_part(<<>>, Encrypted0, undefined, #ssh{decrypt = CryptoAlg} = Ssh0) ->
+ %% New ssh packet
+ case get_length(pkt_type(CryptoAlg), Encrypted0, Ssh0) of
+ get_more ->
+ %% too short to get the length
+ {get_more, <<>>, Encrypted0, undefined, Ssh0};
+
+ {ok, PacketLen, _, _, _} when PacketLen > ?SSH_MAX_PACKET_SIZE ->
+ %% far too long message than expected
+ throw(#ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
+ description = "Bad packet length "
+ ++ integer_to_list(PacketLen),
+ language = ""});
+
+ {ok, PacketLen, Decrypted, Encrypted1,
+ #ssh{recv_mac_size = MacSize} = Ssh1} ->
+ %% enough bytes so we got the length and can calculate how many
+ %% more bytes to expect for a full packet
+ TotalNeeded = (4 + PacketLen + MacSize),
+ handle_packet_part(Decrypted, Encrypted1, TotalNeeded, Ssh1)
+ end;
+
+handle_packet_part(DecryptedPfx, EncryptedBuffer, TotalNeeded, Ssh0)
+ when (size(DecryptedPfx)+size(EncryptedBuffer)) < TotalNeeded ->
+ %% need more bytes to finalize the packet
+ {get_more, DecryptedPfx, EncryptedBuffer, TotalNeeded, Ssh0};
+
+handle_packet_part(DecryptedPfx, EncryptedBuffer, TotalNeeded,
+ #ssh{recv_mac_size = MacSize,
+ decrypt = CryptoAlg} = Ssh0) ->
+ %% enough bytes to decode the packet.
+ DecryptLen = TotalNeeded - size(DecryptedPfx) - MacSize,
+ <<EncryptedSfx:DecryptLen/binary, Mac:MacSize/binary, NextPacketBytes/binary>> = EncryptedBuffer,
+ case pkt_type(CryptoAlg) of
+ common ->
+ {Ssh1, DecryptedSfx} = decrypt(Ssh0, EncryptedSfx),
+ DecryptedPacket = <<DecryptedPfx/binary, DecryptedSfx/binary>>,
+ case is_valid_mac(Mac, DecryptedPacket, Ssh1) of
+ false ->
+ {bad_mac, Ssh1};
+ true ->
+ {Ssh, DecompressedPayload} = decompress(Ssh1, payload(DecryptedPacket)),
+ {decoded, DecompressedPayload, NextPacketBytes, Ssh}
+ end;
+ aead ->
+ PacketLenBin = DecryptedPfx,
+ case decrypt(Ssh0, {PacketLenBin,EncryptedSfx,Mac}) of
+ {Ssh1, error} ->
+ {bad_mac, Ssh1};
+ {Ssh1, DecryptedSfx} ->
+ DecryptedPacket = <<DecryptedPfx/binary, DecryptedSfx/binary>>,
+ {Ssh, DecompressedPayload} = decompress(Ssh1, payload(DecryptedPacket)),
+ {decoded, DecompressedPayload, NextPacketBytes, Ssh}
+ end
+ end.
+
+
+get_length(common, EncryptedBuffer, #ssh{decrypt_block_size = BlockSize} = Ssh0) ->
+ case size(EncryptedBuffer) >= erlang:max(8, BlockSize) of
+ true ->
+ <<EncBlock:BlockSize/binary, EncryptedRest/binary>> = EncryptedBuffer,
+ {Ssh,
+ <<?UINT32(PacketLen),_/binary>> = Decrypted} = decrypt(Ssh0, EncBlock),
+ {ok, PacketLen, Decrypted, EncryptedRest, Ssh};
+ false ->
+ get_more
+ end;
+get_length(aead, EncryptedBuffer, Ssh) ->
+ case size(EncryptedBuffer) >= 4 of
+ true ->
+ <<?UINT32(PacketLen), EncryptedRest/binary>> = EncryptedBuffer,
+ {ok, PacketLen, <<?UINT32(PacketLen)>>, EncryptedRest, Ssh};
+ false ->
+ get_more
+ end.
-msg_data(PacketData) ->
- <<Len:32, PaddingLen:8, _/binary>> = PacketData,
- DataLen = Len - PaddingLen - 1,
- <<_:32, _:8, Data:DataLen/binary,
- _:PaddingLen/binary>> = PacketData,
- Data.
+pkt_type('AEAD_AES_128_GCM') -> aead;
+pkt_type('AEAD_AES_256_GCM') -> aead;
+pkt_type(_) -> common.
+
+payload(<<PacketLen:32, PaddingLen:8, PayloadAndPadding/binary>>) ->
+ PayloadLen = PacketLen - PaddingLen - 1,
+ <<Payload:PayloadLen/binary, _/binary>> = PayloadAndPadding,
+ Payload.
sign(SigData, Hash, #'DSAPrivateKey'{} = Key) ->
DerSignature = public_key:sign(SigData, Hash, Key),
#'Dss-Sig-Value'{r = R, s = S} = public_key:der_decode('Dss-Sig-Value', DerSignature),
<<R:160/big-unsigned-integer, S:160/big-unsigned-integer>>;
+sign(SigData, Hash, Key = #'ECPrivateKey'{}) ->
+ DerEncodedSign = public_key:sign(SigData, Hash, Key),
+ #'ECDSA-Sig-Value'{r=R, s=S} = public_key:der_decode('ECDSA-Sig-Value', DerEncodedSign),
+ ssh_bits:encode([R,S], [mpint,mpint]);
sign(SigData, Hash, Key) ->
public_key:sign(SigData, Hash, Key).
@@ -896,60 +1095,48 @@ verify(PlainText, Hash, Sig, {_, #'Dss-Parms'{}} = Key) ->
<<R:160/big-unsigned-integer, S:160/big-unsigned-integer>> = Sig,
Signature = public_key:der_encode('Dss-Sig-Value', #'Dss-Sig-Value'{r = R, s = S}),
public_key:verify(PlainText, Hash, Signature, Key);
+verify(PlainText, Hash, Sig, {#'ECPoint'{},_} = Key) ->
+ <<?UINT32(Rlen),R:Rlen/big-signed-integer-unit:8,
+ ?UINT32(Slen),S:Slen/big-signed-integer-unit:8>> = Sig,
+ Sval = #'ECDSA-Sig-Value'{r=R, s=S},
+ DerEncodedSig = public_key:der_encode('ECDSA-Sig-Value',Sval),
+ public_key:verify(PlainText, Hash, DerEncodedSig, Key);
verify(PlainText, Hash, Sig, Key) ->
public_key:verify(PlainText, Hash, Sig, Key).
-%% public key algorithms
-%%
-%% ssh-dss REQUIRED sign Raw DSS Key
-%% ssh-rsa RECOMMENDED sign Raw RSA Key
-%% x509v3-sign-rsa OPTIONAL sign X.509 certificates (RSA key)
-%% x509v3-sign-dss OPTIONAL sign X.509 certificates (DSS key)
-%% spki-sign-rsa OPTIONAL sign SPKI certificates (RSA key)
-%% spki-sign-dss OPTIONAL sign SPKI certificates (DSS key)
-%% pgp-sign-rsa OPTIONAL sign OpenPGP certificates (RSA key)
-%% pgp-sign-dss OPTIONAL sign OpenPGP certificates (DSS key)
-%%
-
-%% key exchange
-%%
-%% diffie-hellman-group1-sha1 REQUIRED
-%% diffie-hellman-group14-sha1 REQUIRED
-%%
-%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Encryption
%%
-%% chiphers
-%%
-%% 3des-cbc REQUIRED
-%% three-key 3DES in CBC mode
-%% blowfish-cbc OPTIONAL Blowfish in CBC mode
-%% twofish256-cbc OPTIONAL Twofish in CBC mode,
-%% with 256-bit key
-%% twofish-cbc OPTIONAL alias for "twofish256-cbc" (this
-%% is being retained for
-%% historical reasons)
-%% twofish192-cbc OPTIONAL Twofish with 192-bit key
-%% twofish128-cbc OPTIONAL Twofish with 128-bit key
-%% aes256-cbc OPTIONAL AES in CBC mode,
-%% with 256-bit key
-%% aes192-cbc OPTIONAL AES with 192-bit key
-%% aes128-cbc RECOMMENDED AES with 128-bit key
-%% serpent256-cbc OPTIONAL Serpent in CBC mode, with
-%% 256-bit key
-%% serpent192-cbc OPTIONAL Serpent with 192-bit key
-%% serpent128-cbc OPTIONAL Serpent with 128-bit key
-%% arcfour OPTIONAL the ARCFOUR stream cipher
-%% idea-cbc OPTIONAL IDEA in CBC mode
-%% cast128-cbc OPTIONAL CAST-128 in CBC mode
-%% none OPTIONAL no encryption; NOT RECOMMENDED
+%% Encryption
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
encrypt_init(#ssh{encrypt = none} = Ssh) ->
{ok, Ssh};
+encrypt_init(#ssh{encrypt = 'AEAD_AES_128_GCM', role = client} = Ssh) ->
+ IV = hash(Ssh, "A", 12*8),
+ <<K:16/binary>> = hash(Ssh, "C", 128),
+ {ok, Ssh#ssh{encrypt_keys = K,
+ encrypt_block_size = 16,
+ encrypt_ctx = IV}};
+encrypt_init(#ssh{encrypt = 'AEAD_AES_128_GCM', role = server} = Ssh) ->
+ IV = hash(Ssh, "B", 12*8),
+ <<K:16/binary>> = hash(Ssh, "D", 128),
+ {ok, Ssh#ssh{encrypt_keys = K,
+ encrypt_block_size = 16,
+ encrypt_ctx = IV}};
+encrypt_init(#ssh{encrypt = 'AEAD_AES_256_GCM', role = client} = Ssh) ->
+ IV = hash(Ssh, "A", 12*8),
+ <<K:32/binary>> = hash(Ssh, "C", 256),
+ {ok, Ssh#ssh{encrypt_keys = K,
+ encrypt_block_size = 16,
+ encrypt_ctx = IV}};
+encrypt_init(#ssh{encrypt = 'AEAD_AES_256_GCM', role = server} = Ssh) ->
+ IV = hash(Ssh, "B", 12*8),
+ <<K:32/binary>> = hash(Ssh, "D", 256),
+ {ok, Ssh#ssh{encrypt_keys = K,
+ encrypt_block_size = 16,
+ encrypt_ctx = IV}};
encrypt_init(#ssh{encrypt = '3des-cbc', role = client} = Ssh) ->
IV = hash(Ssh, "A", 64),
<<K1:8/binary, K2:8/binary, K3:8/binary>> = hash(Ssh, "C", 192),
@@ -975,18 +1162,46 @@ encrypt_init(#ssh{encrypt = 'aes128-cbc', role = server} = Ssh) ->
encrypt_block_size = 16,
encrypt_ctx = IV}};
encrypt_init(#ssh{encrypt = 'aes128-ctr', role = client} = Ssh) ->
- IV = hash(Ssh, "A", 128),
+ IV = hash(Ssh, "A", 128),
<<K:16/binary>> = hash(Ssh, "C", 128),
State = crypto:stream_init(aes_ctr, K, IV),
{ok, Ssh#ssh{encrypt_keys = K,
encrypt_block_size = 16,
encrypt_ctx = State}};
+encrypt_init(#ssh{encrypt = 'aes192-ctr', role = client} = Ssh) ->
+ IV = hash(Ssh, "A", 128),
+ <<K:24/binary>> = hash(Ssh, "C", 192),
+ State = crypto:stream_init(aes_ctr, K, IV),
+ {ok, Ssh#ssh{encrypt_keys = K,
+ encrypt_block_size = 16,
+ encrypt_ctx = State}};
+encrypt_init(#ssh{encrypt = 'aes256-ctr', role = client} = Ssh) ->
+ IV = hash(Ssh, "A", 128),
+ <<K:32/binary>> = hash(Ssh, "C", 256),
+ State = crypto:stream_init(aes_ctr, K, IV),
+ {ok, Ssh#ssh{encrypt_keys = K,
+ encrypt_block_size = 16,
+ encrypt_ctx = State}};
encrypt_init(#ssh{encrypt = 'aes128-ctr', role = server} = Ssh) ->
- IV = hash(Ssh, "B", 128),
+ IV = hash(Ssh, "B", 128),
<<K:16/binary>> = hash(Ssh, "D", 128),
State = crypto:stream_init(aes_ctr, K, IV),
{ok, Ssh#ssh{encrypt_keys = K,
encrypt_block_size = 16,
+ encrypt_ctx = State}};
+encrypt_init(#ssh{encrypt = 'aes192-ctr', role = server} = Ssh) ->
+ IV = hash(Ssh, "B", 128),
+ <<K:24/binary>> = hash(Ssh, "D", 192),
+ State = crypto:stream_init(aes_ctr, K, IV),
+ {ok, Ssh#ssh{encrypt_keys = K,
+ encrypt_block_size = 16,
+ encrypt_ctx = State}};
+encrypt_init(#ssh{encrypt = 'aes256-ctr', role = server} = Ssh) ->
+ IV = hash(Ssh, "B", 128),
+ <<K:32/binary>> = hash(Ssh, "D", 256),
+ State = crypto:stream_init(aes_ctr, K, IV),
+ {ok, Ssh#ssh{encrypt_keys = K,
+ encrypt_block_size = 16,
encrypt_ctx = State}}.
encrypt_final(Ssh) ->
@@ -998,6 +1213,18 @@ encrypt_final(Ssh) ->
encrypt(#ssh{encrypt = none} = Ssh, Data) ->
{Ssh, Data};
+encrypt(#ssh{encrypt = 'AEAD_AES_128_GCM',
+ encrypt_keys = K,
+ encrypt_ctx = IV0} = Ssh, Data={_AAD,_Ptext}) ->
+ Enc = {_Ctext,_Ctag} = crypto:block_encrypt(aes_gcm, K, IV0, Data),
+ IV = next_gcm_iv(IV0),
+ {Ssh#ssh{encrypt_ctx = IV}, Enc};
+encrypt(#ssh{encrypt = 'AEAD_AES_256_GCM',
+ encrypt_keys = K,
+ encrypt_ctx = IV0} = Ssh, Data={_AAD,_Ptext}) ->
+ Enc = {_Ctext,_Ctag} = crypto:block_encrypt(aes_gcm, K, IV0, Data),
+ IV = next_gcm_iv(IV0),
+ {Ssh#ssh{encrypt_ctx = IV}, Enc};
encrypt(#ssh{encrypt = '3des-cbc',
encrypt_keys = {K1,K2,K3},
encrypt_ctx = IV0} = Ssh, Data) ->
@@ -1013,6 +1240,14 @@ encrypt(#ssh{encrypt = 'aes128-cbc',
encrypt(#ssh{encrypt = 'aes128-ctr',
encrypt_ctx = State0} = Ssh, Data) ->
{State, Enc} = crypto:stream_encrypt(State0,Data),
+ {Ssh#ssh{encrypt_ctx = State}, Enc};
+encrypt(#ssh{encrypt = 'aes192-ctr',
+ encrypt_ctx = State0} = Ssh, Data) ->
+ {State, Enc} = crypto:stream_encrypt(State0,Data),
+ {Ssh#ssh{encrypt_ctx = State}, Enc};
+encrypt(#ssh{encrypt = 'aes256-ctr',
+ encrypt_ctx = State0} = Ssh, Data) ->
+ {State, Enc} = crypto:stream_encrypt(State0,Data),
{Ssh#ssh{encrypt_ctx = State}, Enc}.
@@ -1022,6 +1257,30 @@ encrypt(#ssh{encrypt = 'aes128-ctr',
decrypt_init(#ssh{decrypt = none} = Ssh) ->
{ok, Ssh};
+decrypt_init(#ssh{decrypt = 'AEAD_AES_128_GCM', role = client} = Ssh) ->
+ IV = hash(Ssh, "B", 12*8),
+ <<K:16/binary>> = hash(Ssh, "D", 128),
+ {ok, Ssh#ssh{decrypt_keys = K,
+ decrypt_block_size = 16,
+ decrypt_ctx = IV}};
+decrypt_init(#ssh{decrypt = 'AEAD_AES_128_GCM', role = server} = Ssh) ->
+ IV = hash(Ssh, "A", 12*8),
+ <<K:16/binary>> = hash(Ssh, "C", 128),
+ {ok, Ssh#ssh{decrypt_keys = K,
+ decrypt_block_size = 16,
+ decrypt_ctx = IV}};
+decrypt_init(#ssh{decrypt = 'AEAD_AES_256_GCM', role = client} = Ssh) ->
+ IV = hash(Ssh, "B", 12*8),
+ <<K:32/binary>> = hash(Ssh, "D", 256),
+ {ok, Ssh#ssh{decrypt_keys = K,
+ decrypt_block_size = 16,
+ decrypt_ctx = IV}};
+decrypt_init(#ssh{decrypt = 'AEAD_AES_256_GCM', role = server} = Ssh) ->
+ IV = hash(Ssh, "A", 12*8),
+ <<K:32/binary>> = hash(Ssh, "C", 256),
+ {ok, Ssh#ssh{decrypt_keys = K,
+ decrypt_block_size = 16,
+ decrypt_ctx = IV}};
decrypt_init(#ssh{decrypt = '3des-cbc', role = client} = Ssh) ->
{IV, KD} = {hash(Ssh, "B", 64),
hash(Ssh, "D", 192)},
@@ -1053,12 +1312,40 @@ decrypt_init(#ssh{decrypt = 'aes128-ctr', role = client} = Ssh) ->
{ok, Ssh#ssh{decrypt_keys = K,
decrypt_block_size = 16,
decrypt_ctx = State}};
+decrypt_init(#ssh{decrypt = 'aes192-ctr', role = client} = Ssh) ->
+ IV = hash(Ssh, "B", 128),
+ <<K:24/binary>> = hash(Ssh, "D", 192),
+ State = crypto:stream_init(aes_ctr, K, IV),
+ {ok, Ssh#ssh{decrypt_keys = K,
+ decrypt_block_size = 16,
+ decrypt_ctx = State}};
+decrypt_init(#ssh{decrypt = 'aes256-ctr', role = client} = Ssh) ->
+ IV = hash(Ssh, "B", 128),
+ <<K:32/binary>> = hash(Ssh, "D", 256),
+ State = crypto:stream_init(aes_ctr, K, IV),
+ {ok, Ssh#ssh{decrypt_keys = K,
+ decrypt_block_size = 16,
+ decrypt_ctx = State}};
decrypt_init(#ssh{decrypt = 'aes128-ctr', role = server} = Ssh) ->
IV = hash(Ssh, "A", 128),
<<K:16/binary>> = hash(Ssh, "C", 128),
State = crypto:stream_init(aes_ctr, K, IV),
{ok, Ssh#ssh{decrypt_keys = K,
decrypt_block_size = 16,
+ decrypt_ctx = State}};
+decrypt_init(#ssh{decrypt = 'aes192-ctr', role = server} = Ssh) ->
+ IV = hash(Ssh, "A", 128),
+ <<K:24/binary>> = hash(Ssh, "C", 192),
+ State = crypto:stream_init(aes_ctr, K, IV),
+ {ok, Ssh#ssh{decrypt_keys = K,
+ decrypt_block_size = 16,
+ decrypt_ctx = State}};
+decrypt_init(#ssh{decrypt = 'aes256-ctr', role = server} = Ssh) ->
+ IV = hash(Ssh, "A", 128),
+ <<K:32/binary>> = hash(Ssh, "C", 256),
+ State = crypto:stream_init(aes_ctr, K, IV),
+ {ok, Ssh#ssh{decrypt_keys = K,
+ decrypt_block_size = 16,
decrypt_ctx = State}}.
@@ -1068,8 +1355,22 @@ decrypt_final(Ssh) ->
decrypt_ctx = undefined,
decrypt_block_size = 8}}.
+decrypt(Ssh, <<>>) ->
+ {Ssh, <<>>};
decrypt(#ssh{decrypt = none} = Ssh, Data) ->
{Ssh, Data};
+decrypt(#ssh{decrypt = 'AEAD_AES_128_GCM',
+ decrypt_keys = K,
+ decrypt_ctx = IV0} = Ssh, Data = {_AAD,_Ctext,_Ctag}) ->
+ Dec = crypto:block_decrypt(aes_gcm, K, IV0, Data), % Dec = PlainText | error
+ IV = next_gcm_iv(IV0),
+ {Ssh#ssh{decrypt_ctx = IV}, Dec};
+decrypt(#ssh{decrypt = 'AEAD_AES_256_GCM',
+ decrypt_keys = K,
+ decrypt_ctx = IV0} = Ssh, Data = {_AAD,_Ctext,_Ctag}) ->
+ Dec = crypto:block_decrypt(aes_gcm, K, IV0, Data), % Dec = PlainText | error
+ IV = next_gcm_iv(IV0),
+ {Ssh#ssh{decrypt_ctx = IV}, Dec};
decrypt(#ssh{decrypt = '3des-cbc', decrypt_keys = Keys,
decrypt_ctx = IV0} = Ssh, Data) ->
{K1, K2, K3} = Keys,
@@ -1084,8 +1385,20 @@ decrypt(#ssh{decrypt = 'aes128-cbc', decrypt_keys = Key,
decrypt(#ssh{decrypt = 'aes128-ctr',
decrypt_ctx = State0} = Ssh, Data) ->
{State, Enc} = crypto:stream_decrypt(State0,Data),
+ {Ssh#ssh{decrypt_ctx = State}, Enc};
+decrypt(#ssh{decrypt = 'aes192-ctr',
+ decrypt_ctx = State0} = Ssh, Data) ->
+ {State, Enc} = crypto:stream_decrypt(State0,Data),
+ {Ssh#ssh{decrypt_ctx = State}, Enc};
+decrypt(#ssh{decrypt = 'aes256-ctr',
+ decrypt_ctx = State0} = Ssh, Data) ->
+ {State, Enc} = crypto:stream_decrypt(State0,Data),
{Ssh#ssh{decrypt_ctx = State}, Enc}.
+
+next_gcm_iv(<<Fixed:32, InvCtr:64>>) -> <<Fixed:32, (InvCtr+1):64>>.
+
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Compression
%%
@@ -1168,43 +1481,48 @@ decompress(#ssh{decompress = '[email protected]', decompress_ctx = Context, authe
{Ssh, list_to_binary(Decompressed)}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% MAC calculation
%%
-%% hmac-sha1 REQUIRED HMAC-SHA1 (digest length = key
-%% length = 20)
-%% hmac-sha1-96 RECOMMENDED first 96 bits of HMAC-SHA1 (digest
-%% length = 12, key length = 20)
-%% hmac-md5 OPTIONAL HMAC-MD5 (digest length = key
-%% length = 16)
-%% hmac-md5-96 OPTIONAL first 96 bits of HMAC-MD5 (digest
-%% length = 12, key length = 16)
-%% none OPTIONAL no MAC; NOT RECOMMENDED
+%% MAC calculation
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
send_mac_init(SSH) ->
- case SSH#ssh.role of
- client ->
- KeySize =mac_key_size(SSH#ssh.send_mac),
- Key = hash(SSH, "E", KeySize),
- {ok, SSH#ssh { send_mac_key = Key }};
- server ->
- KeySize = mac_key_size(SSH#ssh.send_mac),
- Key = hash(SSH, "F", KeySize),
- {ok, SSH#ssh { send_mac_key = Key }}
+ case pkt_type(SSH#ssh.send_mac) of
+ common ->
+ case SSH#ssh.role of
+ client ->
+ KeySize = mac_key_size(SSH#ssh.send_mac),
+ Key = hash(SSH, "E", KeySize),
+ {ok, SSH#ssh { send_mac_key = Key }};
+ server ->
+ KeySize = mac_key_size(SSH#ssh.send_mac),
+ Key = hash(SSH, "F", KeySize),
+ {ok, SSH#ssh { send_mac_key = Key }}
+ end;
+ aead ->
+ %% Not applicable
+ {ok, SSH}
end.
send_mac_final(SSH) ->
- {ok, SSH#ssh { send_mac = none, send_mac_key = undefined }}.
+ {ok, SSH#ssh {send_mac = none,
+ send_mac_key = undefined }}.
+
recv_mac_init(SSH) ->
- case SSH#ssh.role of
- client ->
- Key = hash(SSH, "F", mac_key_size(SSH#ssh.recv_mac)),
- {ok, SSH#ssh { recv_mac_key = Key }};
- server ->
- Key = hash(SSH, "E", mac_key_size(SSH#ssh.recv_mac)),
- {ok, SSH#ssh { recv_mac_key = Key }}
+ case pkt_type(SSH#ssh.recv_mac) of
+ common ->
+ case SSH#ssh.role of
+ client ->
+ Key = hash(SSH, "F", mac_key_size(SSH#ssh.recv_mac)),
+ {ok, SSH#ssh { recv_mac_key = Key }};
+ server ->
+ Key = hash(SSH, "E", mac_key_size(SSH#ssh.recv_mac)),
+ {ok, SSH#ssh { recv_mac_key = Key }}
+ end;
+ aead ->
+ %% Not applicable
+ {ok, SSH}
end.
recv_mac_final(SSH) ->
@@ -1268,30 +1586,36 @@ hash(K, H, Ki, N, HASH) ->
hash(K, H, <<Ki/binary, Kj/binary>>, N-128, HASH).
kex_h(SSH, Key, E, F, K) ->
+ KeyBin = public_key:ssh_encode(Key, ssh2_pubkey),
L = ssh_bits:encode([SSH#ssh.c_version, SSH#ssh.s_version,
SSH#ssh.c_keyinit, SSH#ssh.s_keyinit,
- ssh_message:encode_host_key(Key), E,F,K],
+ KeyBin, E,F,K],
[string,string,binary,binary,binary,
mpint,mpint,mpint]),
crypto:hash(sha((SSH#ssh.algorithms)#alg.kex), L).
%% crypto:hash(sha,L).
kex_h(SSH, Curve, Key, Q_c, Q_s, K) ->
+ KeyBin = public_key:ssh_encode(Key, ssh2_pubkey),
L = ssh_bits:encode([SSH#ssh.c_version, SSH#ssh.s_version,
SSH#ssh.c_keyinit, SSH#ssh.s_keyinit,
- ssh_message:encode_host_key(Key), Q_c, Q_s, K],
+ KeyBin, Q_c, Q_s, K],
[string,string,binary,binary,binary,
mpint,mpint,mpint]),
crypto:hash(sha(Curve), L).
kex_h(SSH, Key, Min, NBits, Max, Prime, Gen, E, F, K) ->
+ KeyBin = public_key:ssh_encode(Key, ssh2_pubkey),
L = if Min==-1; Max==-1 ->
+ %% flag from 'ssh_msg_kex_dh_gex_request_old'
+ %% It was like this before that message was supported,
+ %% why?
Ts = [string,string,binary,binary,binary,
uint32,
mpint,mpint,mpint,mpint,mpint],
ssh_bits:encode([SSH#ssh.c_version,SSH#ssh.s_version,
SSH#ssh.c_keyinit,SSH#ssh.s_keyinit,
- ssh_message:encode_host_key(Key), NBits, Prime, Gen, E,F,K],
+ KeyBin, NBits, Prime, Gen, E,F,K],
Ts);
true ->
Ts = [string,string,binary,binary,binary,
@@ -1299,21 +1623,23 @@ kex_h(SSH, Key, Min, NBits, Max, Prime, Gen, E, F, K) ->
mpint,mpint,mpint,mpint,mpint],
ssh_bits:encode([SSH#ssh.c_version,SSH#ssh.s_version,
SSH#ssh.c_keyinit,SSH#ssh.s_keyinit,
- ssh_message:encode_host_key(Key), Min, NBits, Max,
+ KeyBin, Min, NBits, Max,
Prime, Gen, E,F,K], Ts)
end,
crypto:hash(sha((SSH#ssh.algorithms)#alg.kex), L).
-sha('nistp256') -> sha256;
-sha('secp256r1')-> sha256;
-sha('nistp384') -> sha384;
-sha('secp384r1')-> sha384;
-sha('nistp521') -> sha512;
-sha('secp521r1')-> sha512;
+
+sha(secp256r1) -> sha256;
+sha(secp384r1) -> sha384;
+sha(secp521r1) -> sha512;
sha('diffie-hellman-group1-sha1') -> sha;
sha('diffie-hellman-group14-sha1') -> sha;
sha('diffie-hellman-group-exchange-sha1') -> sha;
-sha('diffie-hellman-group-exchange-sha256') -> sha256.
+sha('diffie-hellman-group-exchange-sha256') -> sha256;
+sha(?'secp256r1') -> sha(secp256r1);
+sha(?'secp384r1') -> sha(secp384r1);
+sha(?'secp521r1') -> sha(secp521r1).
+
mac_key_size('hmac-sha1') -> 20*8;
mac_key_size('hmac-sha1-96') -> 20*8;
@@ -1329,6 +1655,8 @@ mac_digest_size('hmac-md5') -> 20;
mac_digest_size('hmac-md5-96') -> 12;
mac_digest_size('hmac-sha2-256') -> 32;
mac_digest_size('hmac-sha2-512') -> 64;
+mac_digest_size('AEAD_AES_128_GCM') -> 16;
+mac_digest_size('AEAD_AES_256_GCM') -> 16;
mac_digest_size(none) -> 0.
peer_name({Host, _}) ->
@@ -1340,44 +1668,10 @@ peer_name({Host, _}) ->
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-dh_group('diffie-hellman-group1-sha1') -> element(2, ?dh_group1);
-dh_group('diffie-hellman-group14-sha1') -> element(2, ?dh_group14).
-
-dh_gex_default_groups() -> ?dh_default_groups.
-
-
-dh_gex_group(Min, N, Max, undefined) ->
- dh_gex_group(Min, N, Max, dh_gex_default_groups());
-dh_gex_group(Min, N, Max, Groups) ->
- %% First try to find an exact match. If not an exact match, select the largest possible.
- {_,Group} =
- lists:foldl(
- fun(_, {I,G}) when I==N ->
- %% If we have an exact match already: use that one
- {I,G};
- ({I,G}, _) when I==N ->
- %% If we now found an exact match: use that very one
- {I,G};
- ({I,G}, {Imax,_Gmax}) when Min=<I,I=<Max, % a) {I,G} fullfills the requirements
- I>Imax -> % b) {I,G} is larger than current max
- %% A group within the limits and better than the one we have
- {I,G};
- (_, IGmax) ->
- %% Keep the one we have
- IGmax
- end, {-1,undefined}, Groups),
-
- case Group of
- undefined ->
- throw(#ssh_msg_disconnect{
- code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
- description = "No possible diffie-hellman-group-exchange group found",
- language = ""});
- _ ->
- Group
- end.
-
+dh_group('diffie-hellman-group1-sha1') -> ?dh_group1;
+dh_group('diffie-hellman-group14-sha1') -> ?dh_group14.
+%%%----------------------------------------------------------------
generate_key(Algorithm, Args) ->
{Public,Private} = crypto:generate_key(Algorithm, Args),
{crypto:bytes_to_integer(Public), crypto:bytes_to_integer(Private)}.
@@ -1392,6 +1686,68 @@ ecdh_curve('ecdh-sha2-nistp256') -> secp256r1;
ecdh_curve('ecdh-sha2-nistp384') -> secp384r1;
ecdh_curve('ecdh-sha2-nistp521') -> secp521r1.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Utils for default_algorithms/1 and supported_algorithms/1
+%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+supported_algorithms(Key, [{client2server,BL1},{server2client,BL2}]) ->
+ [{client2server,As1},{server2client,As2}] = supported_algorithms(Key),
+ [{client2server,As1--BL1},{server2client,As2--BL2}];
+supported_algorithms(Key, BlackList) ->
+ supported_algorithms(Key) -- BlackList.
+
+
+select_crypto_supported(L) ->
+ Sup = [{ec_curve,crypto_supported_curves()} | crypto:supports()],
+ [Name || {Name,CryptoRequires} <- L,
+ crypto_supported(CryptoRequires, Sup)].
+
+crypto_supported_curves() ->
+ try crypto:ec_curves()
+ catch _:_ -> []
+ end.
+
+crypto_supported(Conditions, Supported) ->
+ lists:all( fun({Tag,CryptoName}) when is_atom(CryptoName) ->
+ crypto_name_supported(Tag,CryptoName,Supported);
+ ({Tag,{Name,Len}}) when is_integer(Len) ->
+ crypto_name_supported(Tag,Name,Supported) andalso
+ len_supported(Name,Len)
+ end, Conditions).
+
+crypto_name_supported(Tag, CryptoName, Supported) ->
+ lists:member(CryptoName, proplists:get_value(Tag,Supported,[])).
+
+len_supported(Name, Len) ->
+ try
+ case Name of
+ aes_ctr ->
+ {_, <<_/binary>>} =
+ %% Test encryption
+ crypto:stream_encrypt(crypto:stream_init(Name, <<0:Len>>, <<0:128>>), <<"">>);
+ aes_gcm ->
+ {<<_/binary>>, <<_/binary>>} =
+ crypto:block_encrypt(Name,
+ _Key = <<0:Len>>,
+ _IV = <<0:12/unsigned-unit:8>>,
+ {<<"AAD">>,"PT"})
+ end
+ of
+ _ -> true
+ catch
+ _:_ -> false
+ end.
+
+
+same(Algs) -> [{client2server,Algs}, {server2client,Algs}].
+
+
+%% default_algorithms(kex) -> % Example of how to disable an algorithm
+%% supported_algorithms(kex, ['ecdh-sha2-nistp521']);
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% Other utils
diff --git a/lib/ssh/src/ssh_transport.hrl b/lib/ssh/src/ssh_transport.hrl
index 96ab1bb668..fd43326f0d 100644
--- a/lib/ssh/src/ssh_transport.hrl
+++ b/lib/ssh/src/ssh_transport.hrl
@@ -33,7 +33,7 @@
-define(MAX_NUM_ALGORITHMS, 200).
-define(DEFAULT_DH_GROUP_MIN, 1024).
--define(DEFAULT_DH_GROUP_NBITS, 6144).
+-define(DEFAULT_DH_GROUP_NBITS, 2048).
-define(DEFAULT_DH_GROUP_MAX, 8192).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -229,39 +229,13 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% rfc 2489, ch 6.2
+%%% Size 1024
-define(dh_group1,
- {1024,
- {2, 16#FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF}}).
+ {2, 16#FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF}).
%%% rfc 3526, ch3
+%%% Size 2048
-define(dh_group14,
- {2048,
- {2, 16#FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF}}).
-
-%%% rfc 3526, ch4
--define(dh_group15,
- {3072,
- {2, 16#FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF}}).
-
-%%% rfc 3526, ch5
--define(dh_group16,
- {4096,
- {2, 16#FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF}}).
-
-%%% rfc 3526, ch6
--define(dh_group17,
- {6144,
- {2, 16#FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AACC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E6DCC4024FFFFFFFFFFFFFFFF}}).
-
-%%% rfc 3526, ch7
--define(dh_group18,
- {8192,
- {2, 16#FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AACC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E438777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F5683423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD922222E04A4037C0713EB57A81A23F0C73473FC646CEA306B4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A364597E899A0255DC164F31CC50846851DF9AB48195DED7EA1B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F924009438B481C6CD7889A002ED5EE382BC9190DA6FC026E479558E4475677E9AA9E3050E2765694DFC81F56E880B96E7160C980DD98EDD3DFFFFFFFFFFFFFFFFF}}).
-
--define(dh_default_groups, [?dh_group14,
- ?dh_group15,
- ?dh_group16,
- ?dh_group17,
- ?dh_group18] ).
+ {2, 16#FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF}).
-endif. % -ifdef(ssh_transport).
diff --git a/lib/ssh/test/Makefile b/lib/ssh/test/Makefile
index 96c74c6c8a..781a876723 100644
--- a/lib/ssh/test/Makefile
+++ b/lib/ssh/test/Makefile
@@ -47,6 +47,8 @@ MODULES= \
ssh_to_openssh_SUITE \
ssh_upgrade_SUITE \
ssh_test_lib \
+ ssh_key_cb \
+ ssh_key_cb_options \
ssh_trpt_test_lib \
ssh_echo_server \
ssh_peername_sockname_server \
diff --git a/lib/ssh/test/ssh_algorithms_SUITE.erl b/lib/ssh/test/ssh_algorithms_SUITE.erl
index e67fa2469f..f0ac92fef6 100644
--- a/lib/ssh/test/ssh_algorithms_SUITE.erl
+++ b/lib/ssh/test/ssh_algorithms_SUITE.erl
@@ -23,6 +23,7 @@
-module(ssh_algorithms_SUITE).
-include_lib("common_test/include/ct.hrl").
+-include_lib("ssh/src/ssh_transport.hrl").
%% Note: This directive should only be used in test suites.
-compile(export_all).
@@ -57,7 +58,7 @@ groups() ->
],
AlgoTcSet =
- [{Alg, [], specific_test_cases(Tag,Alg,SshcAlgos,SshdAlgos)}
+ [{Alg, [parallel], specific_test_cases(Tag,Alg,SshcAlgos,SshdAlgos)}
|| {Tag,Algs} <- ErlAlgos ++ DoubleAlgos,
Alg <- Algs],
@@ -68,15 +69,26 @@ two_way_tags() -> [cipher,mac,compression].
%%--------------------------------------------------------------------
init_per_suite(Config) ->
+ ct:log("os:getenv(\"HOME\") = ~p~n"
+ "init:get_argument(home) = ~p",
+ [os:getenv("HOME"), init:get_argument(home)]),
ct:log("~n~n"
"OS ssh:~n=======~n~p~n~n~n"
"Erl ssh:~n========~n~p~n~n~n"
"Installed ssh client:~n=====================~n~p~n~n~n"
- "Installed ssh server:~n=====================~n~p~n~n~n",
- [os:cmd("ssh -V"),
+ "Installed ssh server:~n=====================~n~p~n~n~n"
+ "Misc values:~n============~n"
+ " -- Default dh group exchange parameters ({min,def,max}): ~p~n"
+ " -- dh_default_groups: ~p~n"
+ " -- Max num algorithms: ~p~n"
+ ,[os:cmd("ssh -V"),
ssh:default_algorithms(),
ssh_test_lib:default_algorithms(sshc),
- ssh_test_lib:default_algorithms(sshd)]),
+ ssh_test_lib:default_algorithms(sshd),
+ {?DEFAULT_DH_GROUP_MIN,?DEFAULT_DH_GROUP_NBITS,?DEFAULT_DH_GROUP_MAX},
+ public_key:dh_gex_group_sizes(),
+ ?MAX_NUM_ALGORITHMS
+ ]),
ct:log("all() ->~n ~p.~n~ngroups()->~n ~p.~n",[all(),groups()]),
catch crypto:stop(),
case catch crypto:start() of
@@ -101,7 +113,8 @@ init_per_group(Group, Config) ->
Config;
false ->
%% An algorithm group
- [[{name,Tag}]|_] = ?config(tc_group_path, Config),
+ Tag = proplists:get_value(name,
+ hd(?config(tc_group_path, Config))),
Alg = Group,
PA =
case split(Alg) of
@@ -162,6 +175,52 @@ simple_exec(Config) ->
ssh_test_lib:std_simple_exec(Host, Port, Config).
%%--------------------------------------------------------------------
+%% Testing if no group matches
+simple_exec_groups_no_match_too_small(Config) ->
+ try simple_exec_group({400,500,600}, Config)
+ of
+ _ -> ct:fail("Exec though no group available")
+ catch
+ error:{badmatch,{error,"No possible diffie-hellman-group-exchange group found"}} ->
+ ok
+ end.
+
+simple_exec_groups_no_match_too_large(Config) ->
+ try simple_exec_group({9200,9500,9700}, Config)
+ of
+ _ -> ct:fail("Exec though no group available")
+ catch
+ error:{badmatch,{error,"No possible diffie-hellman-group-exchange group found"}} ->
+ ok
+ end.
+
+%%--------------------------------------------------------------------
+%% Testing all default groups
+simple_exec_groups(Config) ->
+ Sizes = interpolate( public_key:dh_gex_group_sizes() ),
+ lists:foreach(
+ fun(Sz) ->
+ ct:log("Try size ~p",[Sz]),
+ ct:comment(Sz),
+ case simple_exec_group(Sz, Config) of
+ expected -> ct:log("Size ~p ok",[Sz]);
+ _ -> ct:log("Size ~p not ok",[Sz])
+ end
+ end, Sizes),
+ ct:comment("~p",[lists:map(fun({_,I,_}) -> I;
+ (I) -> I
+ end,Sizes)]).
+
+
+interpolate([I1,I2|Is]) ->
+ OneThird = (I2-I1) div 3,
+ [I1,
+ {I1, I1 + OneThird, I2},
+ {I1, I1 + 2*OneThird, I2} | interpolate([I2|Is])];
+interpolate(Is) ->
+ Is.
+
+%%--------------------------------------------------------------------
%% Use the ssh client of the OS to connect
sshc_simple_exec(Config) ->
PrivDir = ?config(priv_dir, Config),
@@ -254,6 +313,16 @@ specific_test_cases(Tag, Alg, SshcAlgos, SshdAlgos) ->
[sshd_simple_exec];
_ ->
[]
+ end ++
+ case {Tag,Alg} of
+ {kex,_} when Alg == 'diffie-hellman-group-exchange-sha1' ;
+ Alg == 'diffie-hellman-group-exchange-sha256' ->
+ [simple_exec_groups,
+ simple_exec_groups_no_match_too_large,
+ simple_exec_groups_no_match_too_small
+ ];
+ _ ->
+ []
end.
supports(Tag, Alg, Algos) ->
@@ -292,6 +361,16 @@ start_pubkey_daemon(Opts, Config) ->
setup_pubkey(Config) ->
DataDir = ?config(data_dir, Config),
UserDir = ?config(priv_dir, Config),
- ssh_test_lib:setup_dsa_known_host(DataDir, UserDir),
+ ssh_test_lib:setup_dsa(DataDir, UserDir),
+ ssh_test_lib:setup_rsa(DataDir, UserDir),
+ ssh_test_lib:setup_ecdsa("256", DataDir, UserDir),
Config.
+
+simple_exec_group(I, Config) when is_integer(I) ->
+ simple_exec_group({I,I,I}, Config);
+simple_exec_group({Min,I,Max}, Config) ->
+ {Host,Port} = ?config(srvr_addr, Config),
+ ssh_test_lib:std_simple_exec(Host, Port, Config,
+ [{dh_gex_limits,{Min,I,Max}}]).
+
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa
new file mode 100644
index 0000000000..4b1eb12eaa
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIJfCaBKIIKhjbJl5F8BedqlXOQYDX5ba9Skypllmx/w+oAoGCCqGSM49
+AwEHoUQDQgAE49RbK2xQ/19ji3uDPM7uT4692LbwWF1TiaA9vUuebMGazoW/98br
+N9xZu0L1AWwtEjs3kmJDTB7eJEGXnjUAcQ==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa.pub b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa.pub
new file mode 100644
index 0000000000..a0147e60fa
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOPUWytsUP9fY4t7gzzO7k+Ovdi28FhdU4mgPb1LnmzBms6Fv/fG6zfcWbtC9QFsLRI7N5JiQ0we3iRBl541AHE= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa256 b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa256
new file mode 100644
index 0000000000..4b1eb12eaa
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa256
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIJfCaBKIIKhjbJl5F8BedqlXOQYDX5ba9Skypllmx/w+oAoGCCqGSM49
+AwEHoUQDQgAE49RbK2xQ/19ji3uDPM7uT4692LbwWF1TiaA9vUuebMGazoW/98br
+N9xZu0L1AWwtEjs3kmJDTB7eJEGXnjUAcQ==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa256.pub b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa256.pub
new file mode 100644
index 0000000000..a0147e60fa
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa256.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOPUWytsUP9fY4t7gzzO7k+Ovdi28FhdU4mgPb1LnmzBms6Fv/fG6zfcWbtC9QFsLRI7N5JiQ0we3iRBl541AHE= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key256 b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key256
new file mode 100644
index 0000000000..2979ea88ed
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key256
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIMe4MDoit0t8RzSVPwkCBemQ9fhXL+xnTSAWISw8HNCioAoGCCqGSM49
+AwEHoUQDQgAEo2q7U3P6r0W5WGOLtM78UQtofM9UalEhiZeDdiyylsR/RR17Op0s
+VPGSADLmzzgcucLEKy17j2S+oz42VUJy5A==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key256.pub b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key256.pub
new file mode 100644
index 0000000000..85dc419345
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key256.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKNqu1Nz+q9FuVhji7TO/FELaHzPVGpRIYmXg3YsspbEf0UdezqdLFTxkgAy5s84HLnCxCste49kvqM+NlVCcuQ= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_basic_SUITE.erl b/lib/ssh/test/ssh_basic_SUITE.erl
index 51431da48e..85a6bac972 100644
--- a/lib/ssh/test/ssh_basic_SUITE.erl
+++ b/lib/ssh/test/ssh_basic_SUITE.erl
@@ -36,9 +36,15 @@
cli/1,
close/1,
daemon_already_started/1,
+ daemon_opt_fd/1,
+ multi_daemon_opt_fd/1,
double_close/1,
exec/1,
exec_compressed/1,
+ exec_key_differs1/1,
+ exec_key_differs2/1,
+ exec_key_differs3/1,
+ exec_key_differs_fail/1,
idle_time/1,
inet6_option/1,
inet_option/1,
@@ -52,8 +58,10 @@
send/1,
shell/1,
shell_no_unicode/1,
- shell_unicode_string/1,
- ssh_info_print/1
+ shell_unicode_string/1,
+ ssh_info_print/1,
+ key_callback/1,
+ key_callback_options/1
]).
%%% Common test callbacks
@@ -77,11 +85,18 @@ all() ->
appup_test,
{group, dsa_key},
{group, rsa_key},
+ {group, ecdsa_sha2_nistp256_key},
+ {group, ecdsa_sha2_nistp384_key},
+ {group, ecdsa_sha2_nistp521_key},
{group, dsa_pass_key},
{group, rsa_pass_key},
+ {group, host_user_key_differs},
+ {group, key_cb},
{group, internal_error},
daemon_already_started,
double_close,
+ daemon_opt_fd,
+ multi_daemon_opt_fd,
packet_size_zero,
ssh_info_print
].
@@ -89,8 +104,16 @@ all() ->
groups() ->
[{dsa_key, [], basic_tests()},
{rsa_key, [], basic_tests()},
+ {ecdsa_sha2_nistp256_key, [], basic_tests()},
+ {ecdsa_sha2_nistp384_key, [], basic_tests()},
+ {ecdsa_sha2_nistp521_key, [], basic_tests()},
+ {host_user_key_differs, [], [exec_key_differs1,
+ exec_key_differs2,
+ exec_key_differs3,
+ exec_key_differs_fail]},
{dsa_pass_key, [], [pass_phrase]},
{rsa_pass_key, [], [pass_phrase]},
+ {key_cb, [], [key_callback, key_callback_options]},
{internal_error, [], [internal_error]}
].
@@ -117,8 +140,6 @@ end_per_suite(_Config) ->
ssh:stop(),
crypto:stop().
%%--------------------------------------------------------------------
-init_per_group(hardening_tests, Config) ->
- init_per_group(dsa_key, Config);
init_per_group(dsa_key, Config) ->
DataDir = ?config(data_dir, Config),
PrivDir = ?config(priv_dir, Config),
@@ -129,6 +150,39 @@ init_per_group(rsa_key, Config) ->
PrivDir = ?config(priv_dir, Config),
ssh_test_lib:setup_rsa(DataDir, PrivDir),
Config;
+init_per_group(ecdsa_sha2_nistp256_key, Config) ->
+ case lists:member('ecdsa-sha2-nistp256',
+ ssh_transport:default_algorithms(public_key)) of
+ true ->
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ ssh_test_lib:setup_ecdsa("256", DataDir, PrivDir),
+ Config;
+ false ->
+ {skip, unsupported_pub_key}
+ end;
+init_per_group(ecdsa_sha2_nistp384_key, Config) ->
+ case lists:member('ecdsa-sha2-nistp384',
+ ssh_transport:default_algorithms(public_key)) of
+ true ->
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ ssh_test_lib:setup_ecdsa("384", DataDir, PrivDir),
+ Config;
+ false ->
+ {skip, unsupported_pub_key}
+ end;
+init_per_group(ecdsa_sha2_nistp521_key, Config) ->
+ case lists:member('ecdsa-sha2-nistp521',
+ ssh_transport:default_algorithms(public_key)) of
+ true ->
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ ssh_test_lib:setup_ecdsa("521", DataDir, PrivDir),
+ Config;
+ false ->
+ {skip, unsupported_pub_key}
+ end;
init_per_group(rsa_pass_key, Config) ->
DataDir = ?config(data_dir, Config),
PrivDir = ?config(priv_dir, Config),
@@ -139,6 +193,26 @@ init_per_group(dsa_pass_key, Config) ->
PrivDir = ?config(priv_dir, Config),
ssh_test_lib:setup_dsa_pass_pharse(DataDir, PrivDir, "Password"),
[{pass_phrase, {dsa_pass_phrase, "Password"}}| Config];
+init_per_group(host_user_key_differs, Config) ->
+ Data = ?config(data_dir, Config),
+ Sys = filename:join(?config(priv_dir, Config), system_rsa),
+ SysUsr = filename:join(Sys, user),
+ Usr = filename:join(?config(priv_dir, Config), user_ecdsa_256),
+ file:make_dir(Sys),
+ file:make_dir(SysUsr),
+ file:make_dir(Usr),
+ file:copy(filename:join(Data, "ssh_host_rsa_key"), filename:join(Sys, "ssh_host_rsa_key")),
+ file:copy(filename:join(Data, "ssh_host_rsa_key.pub"), filename:join(Sys, "ssh_host_rsa_key.pub")),
+ file:copy(filename:join(Data, "id_ecdsa256"), filename:join(Usr, "id_ecdsa")),
+ file:copy(filename:join(Data, "id_ecdsa256.pub"), filename:join(Usr, "id_ecdsa.pub")),
+ ssh_test_lib:setup_ecdsa_auth_keys("256", Usr, SysUsr),
+ ssh_test_lib:setup_rsa_known_host(Sys, Usr),
+ Config;
+init_per_group(key_cb, Config) ->
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ ssh_test_lib:setup_dsa(DataDir, PrivDir),
+ Config;
init_per_group(internal_error, Config) ->
DataDir = ?config(data_dir, Config),
PrivDir = ?config(priv_dir, Config),
@@ -190,8 +264,6 @@ init_per_group(dir_options, Config) ->
init_per_group(_, Config) ->
Config.
-end_per_group(hardening_tests, Config) ->
- end_per_group(dsa_key, Config);
end_per_group(dsa_key, Config) ->
PrivDir = ?config(priv_dir, Config),
ssh_test_lib:clean_dsa(PrivDir),
@@ -208,6 +280,10 @@ end_per_group(rsa_pass_key, Config) ->
PrivDir = ?config(priv_dir, Config),
ssh_test_lib:clean_rsa(PrivDir),
Config;
+end_per_group(key_cb, Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ ssh_test_lib:clean_dsa(PrivDir),
+ Config;
end_per_group(internal_error, Config) ->
PrivDir = ?config(priv_dir, Config),
ssh_test_lib:clean_dsa(PrivDir),
@@ -362,30 +438,36 @@ exec(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
%%% Test that compression option works
exec_compressed(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- SystemDir = filename:join(?config(priv_dir, Config), system),
- UserDir = ?config(priv_dir, Config),
-
- {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},{user_dir, UserDir},
- {preferred_algorithms,[{compression, [zlib]}]},
- {failfun, fun ssh_test_lib:failfun/2}]),
+ case ssh_test_lib:ssh_supports(zlib, compression) of
+ false ->
+ {skip, "zlib compression is not supported"};
+
+ true ->
+ process_flag(trap_exit, true),
+ SystemDir = filename:join(?config(priv_dir, Config), system),
+ UserDir = ?config(priv_dir, Config),
+
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},{user_dir, UserDir},
+ {preferred_algorithms,[{compression, [zlib]}]},
+ {failfun, fun ssh_test_lib:failfun/2}]),
- ConnectionRef =
- ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
- {user_dir, UserDir},
- {user_interaction, false}]),
- {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity),
- success = ssh_connection:exec(ConnectionRef, ChannelId,
- "1+1.", infinity),
- Data = {ssh_cm, ConnectionRef, {data, ChannelId, 0, <<"2\n">>}},
- case ssh_test_lib:receive_exec_result(Data) of
- expected ->
- ok;
- Other ->
- ct:fail(Other)
- end,
- ssh_test_lib:receive_exec_end(ConnectionRef, ChannelId),
- ssh:stop_daemon(Pid).
+ ConnectionRef =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user_dir, UserDir},
+ {user_interaction, false}]),
+ {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity),
+ success = ssh_connection:exec(ConnectionRef, ChannelId,
+ "1+1.", infinity),
+ Data = {ssh_cm, ConnectionRef, {data, ChannelId, 0, <<"2\n">>}},
+ case ssh_test_lib:receive_exec_result(Data) of
+ expected ->
+ ok;
+ Other ->
+ ct:fail(Other)
+ end,
+ ssh_test_lib:receive_exec_end(ConnectionRef, ChannelId),
+ ssh:stop_daemon(Pid)
+ end.
%%--------------------------------------------------------------------
%%% Idle timeout test
@@ -428,6 +510,82 @@ shell(Config) when is_list(Config) ->
ErlShellStart ->
ct:log("Erlang shell start: ~p~n", [ErlShellStart]),
do_shell(IO, Shell)
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
+ end.
+
+%%--------------------------------------------------------------------
+%%% Test that we could user different types of host pubkey and user pubkey
+exec_key_differs1(Config) -> exec_key_differs(Config, ['ecdsa-sha2-nistp256']).
+
+exec_key_differs2(Config) -> exec_key_differs(Config, ['ssh-dss','ecdsa-sha2-nistp256']).
+
+exec_key_differs3(Config) -> exec_key_differs(Config, ['ecdsa-sha2-nistp384','ecdsa-sha2-nistp256']).
+
+
+
+exec_key_differs(Config, UserPKAlgs) ->
+ case lists:usort(['ssh-rsa'|UserPKAlgs])
+ -- ssh_transport:supported_algorithms(public_key)
+ of
+ [] ->
+ process_flag(trap_exit, true),
+ SystemDir = filename:join(?config(priv_dir, Config), system_rsa),
+ SystemUserDir = filename:join(SystemDir, user),
+ UserDir = filename:join(?config(priv_dir, Config), user_ecdsa_256),
+
+ {_Pid, _Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
+ {user_dir, SystemUserDir},
+ {preferred_algorithms,
+ [{public_key,['ssh-rsa']}]}]),
+ ct:sleep(500),
+
+ IO = ssh_test_lib:start_io_server(),
+ Shell = ssh_test_lib:start_shell(Port, IO, UserDir,
+ [{preferred_algorithms,[{public_key,['ssh-rsa']}]},
+ {pref_public_key_algs,UserPKAlgs}
+ ]),
+
+
+ receive
+ {'EXIT', _, _} ->
+ ct:fail(no_ssh_connection);
+ ErlShellStart ->
+ ct:log("Erlang shell start: ~p~n", [ErlShellStart]),
+ do_shell(IO, Shell)
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
+ end;
+
+ UnsupportedPubKeys ->
+ {skip, io_lib:format("~p unsupported",[UnsupportedPubKeys])}
+ end.
+
+%%--------------------------------------------------------------------
+exec_key_differs_fail(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ SystemDir = filename:join(?config(priv_dir, Config), system_rsa),
+ SystemUserDir = filename:join(SystemDir, user),
+ UserDir = filename:join(?config(priv_dir, Config), user_ecdsa_256),
+
+ {_Pid, _Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
+ {user_dir, SystemUserDir},
+ {preferred_algorithms,
+ [{public_key,['ssh-rsa']}]}]),
+ ct:sleep(500),
+
+ IO = ssh_test_lib:start_io_server(),
+ ssh_test_lib:start_shell(Port, IO, UserDir,
+ [{preferred_algorithms,[{public_key,['ssh-rsa']}]},
+ {pref_public_key_algs,['ssh-dss']}]),
+ receive
+ {'EXIT', _, _} ->
+ ok;
+ ErlShellStart ->
+ ct:log("Erlang shell start: ~p~n", [ErlShellStart]),
+ ct:fail(connection_not_rejected)
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
%%--------------------------------------------------------------------
@@ -456,11 +614,15 @@ cli(Config) when is_list(Config) ->
{ssh_cm, ConnectionRef,
{data,0,0, <<"\r\nYou are accessing a dummy, type \"q\" to exit\r\n\n">>}} ->
ok = ssh_connection:send(ConnectionRef, ChannelId, <<"q">>)
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
receive
{ssh_cm, ConnectionRef,{closed, ChannelId}} ->
ok
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
%%--------------------------------------------------------------------
@@ -524,6 +686,56 @@ pass_phrase(Config) when is_list(Config) ->
{ok, _ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity),
ssh:stop_daemon(Pid).
+%%--------------------------------------------------------------------
+%%% Test that we can use key callback
+key_callback(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ SystemDir = filename:join(?config(priv_dir, Config), system),
+ UserDir = ?config(priv_dir, Config),
+ NoPubKeyDir = filename:join(UserDir, "nopubkey"),
+ file:make_dir(NoPubKeyDir),
+
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
+ {user_dir, UserDir},
+ {failfun, fun ssh_test_lib:failfun/2}]),
+
+ ConnectOpts = [{silently_accept_hosts, true},
+ {user_dir, NoPubKeyDir},
+ {user_interaction, false},
+ {key_cb, ssh_key_cb}],
+
+ ConnectionRef = ssh_test_lib:connect(Host, Port, ConnectOpts),
+
+ {ok, _ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity),
+ ssh:stop_daemon(Pid).
+
+
+%%--------------------------------------------------------------------
+%%% Test that we can use key callback with callback options
+key_callback_options(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ SystemDir = filename:join(?config(priv_dir, Config), system),
+ UserDir = ?config(priv_dir, Config),
+
+ NoPubKeyDir = filename:join(UserDir, "nopubkey"),
+ file:make_dir(NoPubKeyDir),
+
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
+ {user_dir, UserDir},
+ {failfun, fun ssh_test_lib:failfun/2}]),
+
+ {ok, PrivKey} = file:read_file(filename:join(UserDir, "id_dsa")),
+
+ ConnectOpts = [{silently_accept_hosts, true},
+ {user_dir, NoPubKeyDir},
+ {user_interaction, false},
+ {key_cb, {ssh_key_cb_options, [{priv_key, PrivKey}]}}],
+
+ ConnectionRef = ssh_test_lib:connect(Host, Port, ConnectOpts),
+
+ {ok, _ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity),
+ ssh:stop_daemon(Pid).
+
%%--------------------------------------------------------------------
%%% Test that client does not hang if disconnects due to internal error
@@ -599,7 +811,7 @@ peername_sockname(Config) when is_list(Config) ->
host_equal(HostSockSrv, Host),
PortSockSrv = Port
after 10000 ->
- throw(timeout)
+ ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
host_equal(H1, H2) ->
@@ -633,7 +845,7 @@ close(Config) when is_list(Config) ->
{ssh_cm, Client,{closed, ChannelId}} ->
ok
after 5000 ->
- ct:fail(timeout)
+ ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
%%--------------------------------------------------------------------
@@ -658,6 +870,68 @@ double_close(Config) when is_list(Config) ->
ok = ssh:close(CM).
%%--------------------------------------------------------------------
+daemon_opt_fd(Config) ->
+ SystemDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+
+ {ok,S1} = gen_tcp:listen(0,[]),
+ {ok,Fd1} = prim_inet:getfd(S1),
+
+ {ok,Pid1} = ssh:daemon(0, [{system_dir, SystemDir},
+ {fd,Fd1},
+ {user_dir, UserDir},
+ {user_passwords, [{"vego", "morot"}]},
+ {failfun, fun ssh_test_lib:failfun/2}]),
+
+ {ok,{_Host1,Port1}} = inet:sockname(S1),
+ {ok, C1} = ssh:connect("localhost", Port1, [{silently_accept_hosts, true},
+ {user_dir, UserDir},
+ {user, "vego"},
+ {password, "morot"},
+ {user_interaction, false}]),
+ exit(C1, {shutdown, normal}),
+ ssh:stop_daemon(Pid1),
+ gen_tcp:close(S1).
+
+
+%%--------------------------------------------------------------------
+multi_daemon_opt_fd(Config) ->
+ SystemDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+
+ Test =
+ fun() ->
+ {ok,S} = gen_tcp:listen(0,[]),
+ {ok,Fd} = prim_inet:getfd(S),
+
+ {ok,Pid} = ssh:daemon(0, [{system_dir, SystemDir},
+ {fd,Fd},
+ {user_dir, UserDir},
+ {user_passwords, [{"vego", "morot"}]},
+ {failfun, fun ssh_test_lib:failfun/2}]),
+
+ {ok,{_Host,Port}} = inet:sockname(S),
+ {ok, C} = ssh:connect("localhost", Port, [{silently_accept_hosts, true},
+ {user_dir, UserDir},
+ {user, "vego"},
+ {password, "morot"},
+ {user_interaction, false}]),
+ {S,Pid,C}
+ end,
+
+ Tests = [Test(),Test(),Test(),Test(),Test(),Test()],
+
+ [begin
+ gen_tcp:close(S),
+ ssh:stop_daemon(Pid),
+ exit(C, {shutdown, normal})
+ end || {S,Pid,C} <- Tests].
+
+%%--------------------------------------------------------------------
packet_size_zero(Config) ->
SystemDir = ?config(data_dir, Config),
PrivDir = ?config(priv_dir, Config),
@@ -708,22 +982,28 @@ shell_unicode_string(Config) ->
%%--------------------------------------------------------------------
%%% Test basic connection with openssh_zlib
openssh_zlib_basic_test(Config) ->
- SystemDir = filename:join(?config(priv_dir, Config), system),
- UserDir = ?config(priv_dir, Config),
+ case ssh_test_lib:ssh_supports(['[email protected]',none], compression) of
+ {false,L} ->
+ {skip, io_lib:format("~p compression is not supported",[L])};
- {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
- {user_dir, UserDir},
- {preferred_algorithms,[{compression, ['[email protected]']}]},
- {failfun, fun ssh_test_lib:failfun/2}]),
- ConnectionRef =
- ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
- {user_dir, UserDir},
- {user_interaction, false},
- {preferred_algorithms,[{compression, ['[email protected]',
- none]}]}
- ]),
- ok = ssh:close(ConnectionRef),
- ssh:stop_daemon(Pid).
+ true ->
+ SystemDir = filename:join(?config(priv_dir, Config), system),
+ UserDir = ?config(priv_dir, Config),
+
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
+ {user_dir, UserDir},
+ {preferred_algorithms,[{compression, ['[email protected]']}]},
+ {failfun, fun ssh_test_lib:failfun/2}]),
+ ConnectionRef =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user_dir, UserDir},
+ {user_interaction, false},
+ {preferred_algorithms,[{compression, ['[email protected]',
+ none]}]}
+ ]),
+ ok = ssh:close(ConnectionRef),
+ ssh:stop_daemon(Pid)
+ end.
%%--------------------------------------------------------------------
ssh_info_print(Config) ->
@@ -825,22 +1105,32 @@ do_shell(IO, Shell) ->
receive
Echo0 ->
ct:log("Echo: ~p ~n", [Echo0])
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
receive
?NEWLINE ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
receive
Result0 = <<"2">> ->
ct:log("Result: ~p~n", [Result0])
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
receive
?NEWLINE ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
receive
ErlPrompt1 ->
ct:log("Erlang prompt: ~p~n", [ErlPrompt1])
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
exit(Shell, kill).
%%Does not seem to work in the testserver!
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa256 b/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa256
new file mode 100644
index 0000000000..4b1eb12eaa
--- /dev/null
+++ b/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa256
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIJfCaBKIIKhjbJl5F8BedqlXOQYDX5ba9Skypllmx/w+oAoGCCqGSM49
+AwEHoUQDQgAE49RbK2xQ/19ji3uDPM7uT4692LbwWF1TiaA9vUuebMGazoW/98br
+N9xZu0L1AWwtEjs3kmJDTB7eJEGXnjUAcQ==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa256.pub b/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa256.pub
new file mode 100644
index 0000000000..a0147e60fa
--- /dev/null
+++ b/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa256.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOPUWytsUP9fY4t7gzzO7k+Ovdi28FhdU4mgPb1LnmzBms6Fv/fG6zfcWbtC9QFsLRI7N5JiQ0we3iRBl541AHE= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa384 b/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa384
new file mode 100644
index 0000000000..4e8aa40959
--- /dev/null
+++ b/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa384
@@ -0,0 +1,6 @@
+-----BEGIN EC PRIVATE KEY-----
+MIGkAgEBBDCYXb6OSAZyXRfLXOtMo43za197Hdc/T0YKjgQQjwDt6rlRwqTh7v7S
+PV2kXwNGdWigBwYFK4EEACKhZANiAARN2khlJUOOIiwsWHEALwDieeZR96qL4pUd
+ci7aeGaczdUK5jOA9D9zmBZtSYTfO8Cr7ekVghDlcWAIJ/BXcswgQwSEQ6wyfaTF
+8FYfyr4l3u9IirsnyaFzeIgeoNis8Gw=
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa384.pub b/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa384.pub
new file mode 100644
index 0000000000..41e722e545
--- /dev/null
+++ b/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa384.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBE3aSGUlQ44iLCxYcQAvAOJ55lH3qovilR1yLtp4ZpzN1QrmM4D0P3OYFm1JhN87wKvt6RWCEOVxYAgn8FdyzCBDBIRDrDJ9pMXwVh/KviXe70iKuyfJoXN4iB6g2KzwbA== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa521 b/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa521
new file mode 100644
index 0000000000..7196f46e97
--- /dev/null
+++ b/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa521
@@ -0,0 +1,7 @@
+-----BEGIN EC PRIVATE KEY-----
+MIHbAgEBBEFMadoz4ckEcClfqXa2tiUuYkJdDfwq+/iFQcpt8ESuEd26IY/vm47Q
+9UzbPkO4ou8xkNsQ3WvCRQBBWtn5O2kUU6AHBgUrgQQAI6GBiQOBhgAEAde5BRu5
+01/jS0jRk212xsb2DxPrxNpgp6IMCV8TA4Eps+8bSqHB091nLiBcP422HXYfuCd7
+XDjSs8ihcmhp0hCRASLqZR9EzW9W/SOt876May1Huj5X+WSO6RLe7vPn9vmf7kHf
+pip6m7M7qp2qGgQ3q2vRwS2K/O6156ohiOlmuuFs
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa521.pub b/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa521.pub
new file mode 100644
index 0000000000..8f059120bc
--- /dev/null
+++ b/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa521.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAHXuQUbudNf40tI0ZNtdsbG9g8T68TaYKeiDAlfEwOBKbPvG0qhwdPdZy4gXD+Nth12H7gne1w40rPIoXJoadIQkQEi6mUfRM1vVv0jrfO+jGstR7o+V/lkjukS3u7z5/b5n+5B36YqepuzO6qdqhoEN6tr0cEtivzuteeqIYjpZrrhbA== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key256 b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key256
new file mode 100644
index 0000000000..2979ea88ed
--- /dev/null
+++ b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key256
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIMe4MDoit0t8RzSVPwkCBemQ9fhXL+xnTSAWISw8HNCioAoGCCqGSM49
+AwEHoUQDQgAEo2q7U3P6r0W5WGOLtM78UQtofM9UalEhiZeDdiyylsR/RR17Op0s
+VPGSADLmzzgcucLEKy17j2S+oz42VUJy5A==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key256.pub b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key256.pub
new file mode 100644
index 0000000000..85dc419345
--- /dev/null
+++ b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key256.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKNqu1Nz+q9FuVhji7TO/FELaHzPVGpRIYmXg3YsspbEf0UdezqdLFTxkgAy5s84HLnCxCste49kvqM+NlVCcuQ= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key384 b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key384
new file mode 100644
index 0000000000..fb1a862ded
--- /dev/null
+++ b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key384
@@ -0,0 +1,6 @@
+-----BEGIN EC PRIVATE KEY-----
+MIGkAgEBBDArxbDfh3p1okrD9wQw6jJ4d4DdlBPD5GqXE8bIeRJiK41Sh40LgvPw
+mkqEDSXK++CgBwYFK4EEACKhZANiAAScl43Ih2lWTDKrSox5ve5uiTXil4smsup3
+CfS1XPjKxgBAmlfBim8izbdrT0BFdQzz2joduNMtpt61wO4rGs6jm0UP7Kim9PC7
+Hneb/99fIYopdMH5NMnk60zGO1uZ2vc=
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key384.pub b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key384.pub
new file mode 100644
index 0000000000..428d5fb7d7
--- /dev/null
+++ b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key384.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBJyXjciHaVZMMqtKjHm97m6JNeKXiyay6ncJ9LVc+MrGAECaV8GKbyLNt2tPQEV1DPPaOh240y2m3rXA7isazqObRQ/sqKb08Lsed5v/318hiil0wfk0yeTrTMY7W5na9w== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key521 b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key521
new file mode 100644
index 0000000000..3e51ec2ecd
--- /dev/null
+++ b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key521
@@ -0,0 +1,7 @@
+-----BEGIN EC PRIVATE KEY-----
+MIHcAgEBBEIB8O1BFkl2HQjQLRLonEZ97da/h39DMa9/0/hvPZWAI8gUPEQcHxRx
+U7b09p3Zh+EBbMFq8+1ae9ds+ZTxE4WFSvKgBwYFK4EEACOhgYkDgYYABAAlWVjq
+Bzg7Wt4gE6UNb1lRE2cnlmH2L/A5uo6qZRx5lPnSKOxEhxSb/Oay1+9d6KRdrh6/
+vlhd9SHDBhLcAPDvWgBnJIEj92Q3pXX4JtoitL0yl+SvvU+vUh966mzHShHzj8p5
+ccOgPkPNoA70yrpGzkIhPezpZOQdCaOXj/jFqNCTDg==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key521.pub b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key521.pub
new file mode 100644
index 0000000000..017a29f4da
--- /dev/null
+++ b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key521.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAAlWVjqBzg7Wt4gE6UNb1lRE2cnlmH2L/A5uo6qZRx5lPnSKOxEhxSb/Oay1+9d6KRdrh6/vlhd9SHDBhLcAPDvWgBnJIEj92Q3pXX4JtoitL0yl+SvvU+vUh966mzHShHzj8p5ccOgPkPNoA70yrpGzkIhPezpZOQdCaOXj/jFqNCTDg== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_connection_SUITE.erl b/lib/ssh/test/ssh_connection_SUITE.erl
index fbcf06290a..1b93cc9c32 100644
--- a/lib/ssh/test/ssh_connection_SUITE.erl
+++ b/lib/ssh/test/ssh_connection_SUITE.erl
@@ -48,7 +48,8 @@ all() ->
gracefull_invalid_long_start,
gracefull_invalid_long_start_no_nl,
stop_listener,
- start_subsystem_on_closed_channel
+ start_subsystem_on_closed_channel,
+ max_channels_option
].
groups() ->
[{openssh, [], payload() ++ ptty()}].
@@ -119,20 +120,28 @@ simple_exec(Config) when is_list(Config) ->
receive
{ssh_cm, ConnectionRef, {data, ChannelId0, 0, <<"testing\n">>}} ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
%% receive close messages
receive
{ssh_cm, ConnectionRef, {eof, ChannelId0}} ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
receive
{ssh_cm, ConnectionRef, {exit_status, ChannelId0, 0}} ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
receive
{ssh_cm, ConnectionRef,{closed, ChannelId0}} ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
%%--------------------------------------------------------------------
@@ -154,20 +163,28 @@ small_cat(Config) when is_list(Config) ->
receive
{ssh_cm, ConnectionRef, {data, ChannelId0, 0, Data}} ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
%% receive close messages
receive
{ssh_cm, ConnectionRef, {eof, ChannelId0}} ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
receive
{ssh_cm, ConnectionRef, {exit_status, ChannelId0, 0}} ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
receive
{ssh_cm, ConnectionRef,{closed, ChannelId0}} ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
%%--------------------------------------------------------------------
big_cat() ->
@@ -211,11 +228,15 @@ big_cat(Config) when is_list(Config) ->
%% receive close messages (eof already consumed)
receive
{ssh_cm, ConnectionRef, {exit_status, ChannelId0, 0}} ->
- ok
+ ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
receive
{ssh_cm, ConnectionRef,{closed, ChannelId0}} ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
%%--------------------------------------------------------------------
@@ -234,14 +255,20 @@ send_after_exit(Config) when is_list(Config) ->
receive
{ssh_cm, ConnectionRef, {eof, ChannelId0}} ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
receive
{ssh_cm, ConnectionRef, {exit_status, ChannelId0, _ExitStatus}} ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
receive
{ssh_cm, ConnectionRef,{closed, ChannelId0}} ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
case ssh_connection:send(ConnectionRef, ChannelId0, Data, 2000) of
{error, closed} -> ok;
@@ -455,6 +482,8 @@ gracefull_invalid_version(Config) when is_list(Config) ->
{tcp_closed, S} ->
ok
end
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
gracefull_invalid_start(Config) when is_list(Config) ->
@@ -475,6 +504,8 @@ gracefull_invalid_start(Config) when is_list(Config) ->
{tcp_closed, S} ->
ok
end
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
gracefull_invalid_long_start(Config) when is_list(Config) ->
@@ -495,6 +526,8 @@ gracefull_invalid_long_start(Config) when is_list(Config) ->
{tcp_closed, S} ->
ok
end
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
@@ -516,6 +549,8 @@ gracefull_invalid_long_start_no_nl(Config) when is_list(Config) ->
{tcp_closed, S} ->
ok
end
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
stop_listener() ->
@@ -606,6 +641,88 @@ start_subsystem_on_closed_channel(Config) ->
ssh:stop_daemon(Pid).
%%--------------------------------------------------------------------
+max_channels_option() ->
+ [{doc, "Test max_channels option"}].
+
+max_channels_option(Config) when is_list(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, UserDir},
+ {password, "morot"},
+ {max_channels, 3},
+ {subsystems, [{"echo_n", {ssh_echo_server, [4000000]}}]}
+ ]),
+
+ ConnectionRef = ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_interaction, true},
+ {user_dir, UserDir}]),
+
+ {ok, ChannelId0} = ssh_connection:session_channel(ConnectionRef, infinity),
+ {ok, ChannelId1} = ssh_connection:session_channel(ConnectionRef, infinity),
+ {ok, ChannelId2} = ssh_connection:session_channel(ConnectionRef, infinity),
+ {ok, ChannelId3} = ssh_connection:session_channel(ConnectionRef, infinity),
+ {ok, ChannelId4} = ssh_connection:session_channel(ConnectionRef, infinity),
+ {ok, ChannelId5} = ssh_connection:session_channel(ConnectionRef, infinity),
+ {ok, _ChannelId6} = ssh_connection:session_channel(ConnectionRef, infinity),
+
+ %%%---- shell
+ ok = ssh_connection:shell(ConnectionRef,ChannelId0),
+ receive
+ {ssh_cm,ConnectionRef, {data, ChannelId0, 0, <<"Eshell",_/binary>>}} ->
+ ok
+ after 5000 ->
+ ct:fail("CLI Timeout")
+ end,
+
+ %%%---- subsystem "echo_n"
+ success = ssh_connection:subsystem(ConnectionRef, ChannelId1, "echo_n", infinity),
+
+ %%%---- exec #1
+ success = ssh_connection:exec(ConnectionRef, ChannelId2, "testing1.\n", infinity),
+ receive
+ {ssh_cm, ConnectionRef, {data, ChannelId2, 0, <<"testing1",_/binary>>}} ->
+ ok
+ after 5000 ->
+ ct:fail("Exec #1 Timeout")
+ end,
+
+ %%%---- ptty
+ success = ssh_connection:ptty_alloc(ConnectionRef, ChannelId3, []),
+
+ %%%---- exec #2
+ failure = ssh_connection:exec(ConnectionRef, ChannelId4, "testing2.\n", infinity),
+
+ %%%---- close the shell
+ ok = ssh_connection:send(ConnectionRef, ChannelId0, "exit().\n", 5000),
+
+ %%%---- wait for the subsystem to terminate
+ receive
+ {ssh_cm,ConnectionRef,{closed,ChannelId0}} -> ok
+ after 5000 ->
+ ct:log("Timeout waiting for '{ssh_cm,~p,{closed,~p}}'~n"
+ "Message queue:~n~p",
+ [ConnectionRef,ChannelId0,erlang:process_info(self(),messages)]),
+ ct:fail("exit Timeout",[])
+ end,
+
+ %%%---- exec #3
+ success = ssh_connection:exec(ConnectionRef, ChannelId5, "testing3.\n", infinity),
+ receive
+ {ssh_cm, ConnectionRef, {data, ChannelId5, 0, <<"testing3",_/binary>>}} ->
+ ok
+ after 5000 ->
+ ct:fail("Exec #3 Timeout")
+ end,
+
+ ssh:close(ConnectionRef),
+ ssh:stop_daemon(Pid).
+
+%%--------------------------------------------------------------------
%% Internal functions ------------------------------------------------
%%--------------------------------------------------------------------
big_cat_rx(ConnectionRef, ChannelId) ->
diff --git a/lib/ssh/test/ssh_key_cb.erl b/lib/ssh/test/ssh_key_cb.erl
new file mode 100644
index 0000000000..388ec2ecc1
--- /dev/null
+++ b/lib/ssh/test/ssh_key_cb.erl
@@ -0,0 +1,45 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2015. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%%----------------------------------------------------------------------
+
+%% Note: This module is used by ssh_basic_SUITE
+
+-module(ssh_key_cb).
+-behaviour(ssh_client_key_api).
+-compile(export_all).
+
+add_host_key(_, _, _) ->
+ ok.
+
+is_host_key(_, _, _, _) ->
+ true.
+
+user_key('ssh-dss', Opts) ->
+ UserDir = proplists:get_value(user_dir, Opts),
+ KeyFile = filename:join(filename:dirname(UserDir), "id_dsa"),
+ {ok, KeyBin} = file:read_file(KeyFile),
+ [Entry] = public_key:pem_decode(KeyBin),
+ Key = public_key:pem_entry_decode(Entry),
+ {ok, Key};
+
+user_key(_Alg, _Opt) ->
+ {error, "Not Supported"}.
diff --git a/lib/ssh/test/ssh_key_cb_options.erl b/lib/ssh/test/ssh_key_cb_options.erl
new file mode 100644
index 0000000000..afccb34f0f
--- /dev/null
+++ b/lib/ssh/test/ssh_key_cb_options.erl
@@ -0,0 +1,44 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2015. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%%----------------------------------------------------------------------
+
+%% Note: This module is used by ssh_basic_SUITE
+
+-module(ssh_key_cb_options).
+-behaviour(ssh_client_key_api).
+-compile(export_all).
+
+add_host_key(_, _, _) ->
+ ok.
+
+is_host_key(_, _, _, _) ->
+ true.
+
+user_key('ssh-dss', Opts) ->
+ KeyCbOpts = proplists:get_value(key_cb_private, Opts),
+ KeyBin = proplists:get_value(priv_key, KeyCbOpts),
+ [Entry] = public_key:pem_decode(KeyBin),
+ Key = public_key:pem_entry_decode(Entry),
+ {ok, Key};
+
+user_key(_Alg, _Opt) ->
+ {error, "Not Supported"}.
diff --git a/lib/ssh/test/ssh_options_SUITE.erl b/lib/ssh/test/ssh_options_SUITE.erl
index d64c78da35..6a201d401f 100644
--- a/lib/ssh/test/ssh_options_SUITE.erl
+++ b/lib/ssh/test/ssh_options_SUITE.erl
@@ -45,6 +45,9 @@
max_sessions_ssh_connect_sequential/1,
server_password_option/1,
server_userpassword_option/1,
+ server_pwdfun_option/1,
+ server_pwdfun_4_option/1,
+ server_pwdfun_4_option_repeat/1,
ssh_connect_arg4_timeout/1,
ssh_connect_negtimeout_parallel/1,
ssh_connect_negtimeout_sequential/1,
@@ -83,6 +86,9 @@ all() ->
connectfun_disconnectfun_client,
server_password_option,
server_userpassword_option,
+ server_pwdfun_option,
+ server_pwdfun_4_option,
+ server_pwdfun_4_option_repeat,
{group, dir_options},
ssh_connect_timeout,
ssh_connect_arg4_timeout,
@@ -188,7 +194,9 @@ init_per_testcase(_TestCase, Config) ->
Config.
end_per_testcase(TestCase, Config) when TestCase == server_password_option;
- TestCase == server_userpassword_option ->
+ TestCase == server_userpassword_option;
+ TestCase == server_pwdfun_option;
+ TestCase == server_pwdfun_4_option ->
UserDir = filename:join(?config(priv_dir, Config), nopubkey),
ssh_test_lib:del_dirs(UserDir),
end_per_testcase(Config);
@@ -272,6 +280,157 @@ server_userpassword_option(Config) when is_list(Config) ->
ssh:stop_daemon(Pid).
%%--------------------------------------------------------------------
+%%% validate to server that uses the 'pwdfun' option
+server_pwdfun_option(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+ CHKPWD = fun("foo",Pwd) -> Pwd=="bar";
+ (_,_) -> false
+ end,
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, PrivDir},
+ {pwdfun,CHKPWD}]),
+ ConnectionRef =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "bar"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
+ ssh:close(ConnectionRef),
+
+ Reason = "Unable to connect using the available authentication methods",
+
+ {error, Reason} =
+ ssh:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
+ {error, Reason} =
+ ssh:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "vego"},
+ {password, "foo"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
+ ssh:stop_daemon(Pid).
+
+
+%%--------------------------------------------------------------------
+%%% validate to server that uses the 'pwdfun/4' option
+server_pwdfun_4_option(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+ PWDFUN = fun("foo",Pwd,{_,_},undefined) -> Pwd=="bar";
+ ("fie",Pwd,{_,_},undefined) -> {Pwd=="bar",new_state};
+ ("bandit",_,_,_) -> disconnect;
+ (_,_,_,_) -> false
+ end,
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, PrivDir},
+ {pwdfun,PWDFUN}]),
+ ConnectionRef1 =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "bar"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
+ ssh:close(ConnectionRef1),
+
+ ConnectionRef2 =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "fie"},
+ {password, "bar"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
+ ssh:close(ConnectionRef2),
+
+ Reason = "Unable to connect using the available authentication methods",
+
+ {error, Reason} =
+ ssh:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
+ {error, Reason} =
+ ssh:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "fie"},
+ {password, "morot"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
+ {error, Reason} =
+ ssh:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "vego"},
+ {password, "foo"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
+
+ {error, Reason} =
+ ssh:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "bandit"},
+ {password, "pwd breaking"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
+ ssh:stop_daemon(Pid).
+
+
+%%--------------------------------------------------------------------
+server_pwdfun_4_option_repeat(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+ %% Test that the state works
+ Parent = self(),
+ PWDFUN = fun("foo",P="bar",_,S) -> Parent!{P,S},true;
+ (_,P,_,S=undefined) -> Parent!{P,S},{false,1};
+ (_,P,_,S) -> Parent!{P,S}, {false,S+1}
+ end,
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, PrivDir},
+ {auth_methods,"keyboard-interactive"},
+ {pwdfun,PWDFUN}]),
+
+ %% Try with passwords "incorrect", "Bad again" and finally "bar"
+ KIFFUN = fun(_,_,_) ->
+ K={k,self()},
+ case get(K) of
+ undefined ->
+ put(K,1),
+ ["incorrect"];
+ 2 ->
+ put(K,3),
+ ["bar"];
+ S->
+ put(K,S+1),
+ ["Bad again"]
+ end
+ end,
+
+ ConnectionRef2 =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {keyboard_interact_fun, KIFFUN},
+ {user_dir, UserDir}]),
+ ssh:close(ConnectionRef2),
+ ssh:stop_daemon(Pid),
+
+ lists:foreach(fun(Expect) ->
+ receive
+ Expect -> ok;
+ Other -> ct:fail("Expect: ~p~nReceived ~p",[Expect,Other])
+ after
+ 2000 -> ct:fail("Timeout expecting ~p",[Expect])
+ end
+ end, [{"incorrect",undefined},
+ {"Bad again",1},
+ {"bar",2}]).
+
+%%--------------------------------------------------------------------
system_dir_option(Config) ->
DirUnread = proplists:get_value(unreadable_dir,Config),
FileRead = proplists:get_value(readable_file,Config),
@@ -656,6 +815,8 @@ ssh_connect_arg4_timeout(_Config) ->
%% Get listening port
Port = receive
{port,Server,ServerPort} -> ServerPort
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
%% try to connect with a timeout, but "supervise" it
@@ -861,6 +1022,8 @@ ssh_connect_nonegtimeout_connected(Config, Parallel) ->
ct:sleep(round(Factor * NegTimeOut)),
one_shell_op(IO, NegTimeOut)
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
exit(Shell, kill).
@@ -869,13 +1032,13 @@ one_shell_op(IO, TimeOut) ->
ct:log("One shell op: Waiting for prompter"),
receive
ErlPrompt0 -> ct:log("Erlang prompt: ~p~n", [ErlPrompt0])
- after TimeOut -> ct:fail("Timeout waiting for promter")
+ after TimeOut -> ct:fail("Timeout waiting for promter")
end,
IO ! {input, self(), "2*3*7.\r\n"},
receive
Echo0 -> ct:log("Echo: ~p ~n", [Echo0])
- after TimeOut -> ct:fail("Timeout waiting for echo")
+ after TimeOut -> ct:fail("Timeout waiting for echo")
end,
receive
@@ -888,7 +1051,7 @@ one_shell_op(IO, TimeOut) ->
receive
Result0 -> ct:log("Result: ~p~n", [Result0])
- after TimeOut -> ct:fail("Timeout waiting for result")
+ after TimeOut -> ct:fail("Timeout waiting for result")
end.
%%--------------------------------------------------------------------
@@ -1016,9 +1179,13 @@ fake_daemon(_Config) ->
{ok,S} = Rsa,
receive
{tcp, S, Id} -> Parent ! {id,self(),Id}
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end
end),
%% Get listening host and port
receive
{sockname,Server,ServerHost,ServerPort} -> {Server, ServerHost, ServerPort}
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
diff --git a/lib/ssh/test/ssh_protocol_SUITE.erl b/lib/ssh/test/ssh_protocol_SUITE.erl
index d8e99799e2..4639904061 100644
--- a/lib/ssh/test/ssh_protocol_SUITE.erl
+++ b/lib/ssh/test/ssh_protocol_SUITE.erl
@@ -46,7 +46,10 @@ suite() ->
all() ->
[{group,tool_tests},
- {group,kex}
+ {group,kex},
+ {group,service_requests},
+ {group,packet_size_error},
+ {group,field_size_error}
].
groups() ->
@@ -55,13 +58,27 @@ groups() ->
lib_match,
lib_no_match
]},
+ {packet_size_error, [], [packet_length_too_large,
+ packet_length_too_short]},
+
+ {field_size_error, [], [service_name_length_too_large,
+ service_name_length_too_short]},
+
{kex, [], [no_common_alg_server_disconnects,
no_common_alg_client_disconnects,
- gex_client_init_default_noexact,
- gex_client_init_default_exact,
gex_client_init_option_groups,
- gex_client_init_option_groups_file
- ]}
+ gex_server_gex_limit,
+ gex_client_init_option_groups_moduli_file,
+ gex_client_init_option_groups_file,
+ gex_client_old_request_exact,
+ gex_client_old_request_noexact
+ ]},
+ {service_requests, [], [bad_service_name,
+ bad_long_service_name,
+ bad_very_long_service_name,
+ empty_service_name,
+ bad_service_name_then_correct
+ ]}
].
@@ -76,10 +93,12 @@ end_per_suite(Config) ->
init_per_testcase(no_common_alg_server_disconnects, Config) ->
start_std_daemon(Config, [{preferred_algorithms,[{public_key,['ssh-rsa']}]}]);
-init_per_testcase(TC, Config) when TC == gex_client_init_default_noexact ;
- TC == gex_client_init_default_exact ;
- TC == gex_client_init_option_groups ;
- TC == gex_client_init_option_groups_file ->
+init_per_testcase(TC, Config) when TC == gex_client_init_option_groups ;
+ TC == gex_client_init_option_groups_moduli_file ;
+ TC == gex_client_init_option_groups_file ;
+ TC == gex_server_gex_limit ;
+ TC == gex_client_old_request_exact ;
+ TC == gex_client_old_request_noexact ->
Opts = case TC of
gex_client_init_option_groups ->
[{dh_gex_groups, [{2345, 3, 41}]}];
@@ -87,21 +106,35 @@ init_per_testcase(TC, Config) when TC == gex_client_init_default_noexact ;
DataDir = ?config(data_dir, Config),
F = filename:join(DataDir, "dh_group_test"),
[{dh_gex_groups, {file,F}}];
+ gex_client_init_option_groups_moduli_file ->
+ DataDir = ?config(data_dir, Config),
+ F = filename:join(DataDir, "dh_group_test.moduli"),
+ [{dh_gex_groups, {ssh_moduli_file,F}}];
+ _ when TC == gex_server_gex_limit ;
+ TC == gex_client_old_request_exact ;
+ TC == gex_client_old_request_noexact ->
+ [{dh_gex_groups, [{ 500, 3, 17},
+ {1000, 7, 91},
+ {3000, 5, 61}]},
+ {dh_gex_limits,{500,1500}}
+ ];
_ ->
[]
end,
start_std_daemon(Config,
- [{preferred_algorithms, ssh_transport:supported_algorithms()}
+ [{preferred_algorithms, ssh:default_algorithms()}
| Opts]);
init_per_testcase(_TestCase, Config) ->
check_std_daemon_works(Config, ?LINE).
end_per_testcase(no_common_alg_server_disconnects, Config) ->
stop_std_daemon(Config);
-end_per_testcase(TC, Config) when TC == gex_client_init_default_noexact ;
- TC == gex_client_init_default_exact ;
- TC == gex_client_init_option_groups ;
- TC == gex_client_init_option_groups_file ->
+end_per_testcase(TC, Config) when TC == gex_client_init_option_groups ;
+ TC == gex_client_init_option_groups_moduli_file ;
+ TC == gex_client_init_option_groups_file ;
+ TC == gex_server_gex_limit ;
+ TC == gex_client_old_request_exact ;
+ TC == gex_client_old_request_noexact ->
stop_std_daemon(Config);
end_per_testcase(_TestCase, Config) ->
check_std_daemon_works(Config, ?LINE).
@@ -114,25 +147,10 @@ end_per_testcase(_TestCase, Config) ->
%%% Connect to an erlang server and check that the testlib acts as a client.
lib_works_as_client(Config) ->
%% Connect and negotiate keys
- {ok,InitialState} =
- ssh_trpt_test_lib:exec(
- [{set_options, [print_ops, print_seqnums, print_messages]},
- {connect,
- server_host(Config),server_port(Config),
- [{preferred_algorithms,[{kex,['diffie-hellman-group1-sha1']}]},
- {silently_accept_hosts, true},
- {user_dir, user_dir(Config)},
- {user_interaction, false}]},
- receive_hello,
- {send, hello},
- {send, ssh_msg_kexinit},
- {match, #ssh_msg_kexinit{_='_'}, receive_msg},
- {send, ssh_msg_kexdh_init},
- {match,# ssh_msg_kexdh_reply{_='_'}, receive_msg},
- {send, #ssh_msg_newkeys{}},
- {match, #ssh_msg_newkeys{_='_'}, receive_msg}
- ]
- ),
+ {ok,InitialState} = ssh_trpt_test_lib:exec(
+ [{set_options, [print_ops, print_seqnums, print_messages]}]
+ ),
+ {ok,AfterKexState} = connect_and_kex(Config, InitialState),
%% Do the authentcation
{User,Pwd} = server_user_password(Config),
@@ -147,7 +165,7 @@ lib_works_as_client(Config) ->
?STRING(unicode:characters_to_binary(Pwd))>>
}},
{match, #ssh_msg_userauth_success{_='_'}, receive_msg}
- ], InitialState),
+ ], AfterKexState),
%% Disconnect
{ok,_} =
@@ -327,31 +345,29 @@ no_common_alg_client_disconnects(Config) ->
X ->
ct:log("¤¤¤¤¤"),
ct:fail(X)
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
%%%--------------------------------------------------------------------
-gex_client_init_default_noexact(Config) ->
- do_gex_client_init(Config, {2000, 3000, 4000},
- %% Warning, app knowledege:
- ?dh_group15).
-
-
-gex_client_init_default_exact(Config) ->
- do_gex_client_init(Config, {2000, 2048, 4000},
- %% Warning, app knowledege:
- ?dh_group14).
-
-
gex_client_init_option_groups(Config) ->
do_gex_client_init(Config, {2000, 2048, 4000},
- {'n/a',{3,41}}).
-
+ {3,41}).
gex_client_init_option_groups_file(Config) ->
do_gex_client_init(Config, {2000, 2048, 4000},
- {'n/a',{5,61}}).
+ {5,61}).
-do_gex_client_init(Config, {Min,N,Max}, {_,{G,P}}) ->
+gex_client_init_option_groups_moduli_file(Config) ->
+ do_gex_client_init(Config, {2000, 2048, 4000},
+ {5,16#B7}).
+
+gex_server_gex_limit(Config) ->
+ do_gex_client_init(Config, {1000, 3000, 4000},
+ {7,91}).
+
+
+do_gex_client_init(Config, {Min,N,Max}, {G,P}) ->
{ok,_} =
ssh_trpt_test_lib:exec(
[{set_options, [print_ops, print_seqnums, print_messages]},
@@ -373,6 +389,129 @@ do_gex_client_init(Config, {Min,N,Max}, {_,{G,P}}) ->
]
).
+%%%--------------------------------------------------------------------
+gex_client_old_request_exact(Config) -> do_gex_client_init_old(Config, 500, {3,17}).
+gex_client_old_request_noexact(Config) -> do_gex_client_init_old(Config, 800, {7,91}).
+
+do_gex_client_init_old(Config, N, {G,P}) ->
+ {ok,_} =
+ ssh_trpt_test_lib:exec(
+ [{set_options, [print_ops, print_seqnums, print_messages]},
+ {connect,
+ server_host(Config),server_port(Config),
+ [{silently_accept_hosts, true},
+ {user_dir, user_dir(Config)},
+ {user_interaction, false},
+ {preferred_algorithms,[{kex,['diffie-hellman-group-exchange-sha1']}]}
+ ]},
+ receive_hello,
+ {send, hello},
+ {send, ssh_msg_kexinit},
+ {match, #ssh_msg_kexinit{_='_'}, receive_msg},
+ {send, #ssh_msg_kex_dh_gex_request_old{n = N}},
+ {match, #ssh_msg_kex_dh_gex_group{p=P, g=G, _='_'}, receive_msg}
+ ]
+ ).
+
+%%%--------------------------------------------------------------------
+bad_service_name(Config) ->
+ bad_service_name(Config, "kfglkjf").
+
+bad_long_service_name(Config) ->
+ bad_service_name(Config,
+ lists:duplicate(?SSH_MAX_PACKET_SIZE div 2, $a)).
+
+bad_very_long_service_name(Config) ->
+ bad_service_name(Config,
+ lists:duplicate(4*?SSH_MAX_PACKET_SIZE, $a)).
+
+empty_service_name(Config) ->
+ bad_service_name(Config, "").
+
+bad_service_name_then_correct(Config) ->
+ {ok,InitialState} = connect_and_kex(Config),
+ {ok,_} =
+ ssh_trpt_test_lib:exec(
+ [{set_options, [print_ops, print_seqnums, print_messages]},
+ {send, #ssh_msg_service_request{name = "kdjglkfdjgkldfjglkdfjglkfdjglkj"}},
+ {send, #ssh_msg_service_request{name = "ssh-connection"}},
+ {match, {'or',[#ssh_msg_disconnect{_='_'},
+ tcp_closed
+ ]},
+ receive_msg}
+ ], InitialState).
+
+
+bad_service_name(Config, Name) ->
+ {ok,InitialState} = connect_and_kex(Config),
+ {ok,_} =
+ ssh_trpt_test_lib:exec(
+ [{set_options, [print_ops, print_seqnums, print_messages]},
+ {send, #ssh_msg_service_request{name = Name}},
+ {match, {'or',[#ssh_msg_disconnect{_='_'},
+ tcp_closed
+ ]},
+ receive_msg}
+ ], InitialState).
+
+%%%--------------------------------------------------------------------
+packet_length_too_large(Config) -> bad_packet_length(Config, +4).
+
+packet_length_too_short(Config) -> bad_packet_length(Config, -4).
+
+bad_packet_length(Config, LengthExcess) ->
+ PacketFun =
+ fun(Msg, Ssh) ->
+ BinMsg = ssh_message:encode(Msg),
+ ssh_transport:pack(BinMsg, Ssh, LengthExcess)
+ end,
+ {ok,InitialState} = connect_and_kex(Config),
+ {ok,_} =
+ ssh_trpt_test_lib:exec(
+ [{set_options, [print_ops, print_seqnums, print_messages]},
+ {send, {special,
+ #ssh_msg_service_request{name="ssh-userauth"},
+ PacketFun}},
+ %% Prohibit remote decoder starvation:
+ {send, #ssh_msg_service_request{name="ssh-userauth"}},
+ {match, {'or',[#ssh_msg_disconnect{_='_'},
+ tcp_closed
+ ]},
+ receive_msg}
+ ], InitialState).
+
+%%%--------------------------------------------------------------------
+service_name_length_too_large(Config) -> bad_service_name_length(Config, +4).
+
+service_name_length_too_short(Config) -> bad_service_name_length(Config, -4).
+
+
+bad_service_name_length(Config, LengthExcess) ->
+ PacketFun =
+ fun(#ssh_msg_service_request{name=Service}, Ssh) ->
+ BinName = list_to_binary(Service),
+ BinMsg =
+ <<?BYTE(?SSH_MSG_SERVICE_REQUEST),
+ %% A bad string encoding of Service:
+ ?UINT32(size(BinName)+LengthExcess), BinName/binary
+ >>,
+ ssh_transport:pack(BinMsg, Ssh)
+ end,
+ {ok,InitialState} = connect_and_kex(Config),
+ {ok,_} =
+ ssh_trpt_test_lib:exec(
+ [{set_options, [print_ops, print_seqnums, print_messages]},
+ {send, {special,
+ #ssh_msg_service_request{name="ssh-userauth"},
+ PacketFun} },
+ %% Prohibit remote decoder starvation:
+ {send, #ssh_msg_service_request{name="ssh-userauth"}},
+ {match, {'or',[#ssh_msg_disconnect{_='_'},
+ tcp_closed
+ ]},
+ receive_msg}
+ ], InitialState).
+
%%%================================================================
%%%==== Internal functions ========================================
%%%================================================================
@@ -480,3 +619,24 @@ std_connect(Host, Port, Config, Opts) ->
30000).
%%%----------------------------------------------------------------
+connect_and_kex(Config) ->
+ connect_and_kex(Config, ssh_trpt_test_lib:exec([]) ).
+
+connect_and_kex(Config, InitialState) ->
+ ssh_trpt_test_lib:exec(
+ [{connect,
+ server_host(Config),server_port(Config),
+ [{preferred_algorithms,[{kex,['diffie-hellman-group1-sha1']}]},
+ {silently_accept_hosts, true},
+ {user_dir, user_dir(Config)},
+ {user_interaction, false}]},
+ receive_hello,
+ {send, hello},
+ {send, ssh_msg_kexinit},
+ {match, #ssh_msg_kexinit{_='_'}, receive_msg},
+ {send, ssh_msg_kexdh_init},
+ {match,# ssh_msg_kexdh_reply{_='_'}, receive_msg},
+ {send, #ssh_msg_newkeys{}},
+ {match, #ssh_msg_newkeys{_='_'}, receive_msg}
+ ],
+ InitialState).
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/dh_group_test.moduli b/lib/ssh/test/ssh_protocol_SUITE_data/dh_group_test.moduli
new file mode 100644
index 0000000000..f6995ba4c9
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/dh_group_test.moduli
@@ -0,0 +1,3 @@
+20151021104105 2 6 100 2222 5 B7
+20151021104106 2 6 100 1111 5 4F
+
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE.erl b/lib/ssh/test/ssh_renegotiate_SUITE.erl
index 9daa6efc02..e5cfa58bad 100644
--- a/lib/ssh/test/ssh_renegotiate_SUITE.erl
+++ b/lib/ssh/test/ssh_renegotiate_SUITE.erl
@@ -32,9 +32,15 @@
suite() -> [{ct_hooks,[ts_install_cth]}].
-all() -> [rekey, rekey_limit, renegotiate1, renegotiate2].
+all() -> [{group,default_algs},
+ {group,aes_gcm}
+ ].
-groups() -> [].
+groups() -> [{default_algs, [], tests()},
+ {aes_gcm, [], tests()}
+ ].
+
+tests() -> [rekey, rekey_limit, renegotiate1, renegotiate2].
%%--------------------------------------------------------------------
init_per_suite(Config) ->
@@ -50,6 +56,24 @@ end_per_suite(_Config) ->
crypto:stop().
%%--------------------------------------------------------------------
+init_per_group(aes_gcm, Config) ->
+ case lists:member({client2server,['[email protected]']},
+ ssh_transport:supported_algorithms(cipher)) of
+ true ->
+ [{preferred_algorithms, [{cipher,[{client2server,['[email protected]']},
+ {server2client,['[email protected]']}]}]}
+ | Config];
+ false ->
+ {skip, "aes_gcm not supported"}
+ end;
+init_per_group(_, Config) ->
+ [{preferred_algorithms, ssh:default_algorithms()} | Config].
+
+
+end_per_group(_, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
init_per_testcase(_TestCase, Config) ->
ssh:start(),
Config.
@@ -89,9 +113,12 @@ rekey_limit(Config) ->
UserDir = ?config(priv_dir, Config),
DataFile = filename:join(UserDir, "rekey.data"),
- {Pid, Host, Port} = ssh_test_lib:std_daemon(Config,[]),
+ Algs = ?config(preferred_algorithms, Config),
+ {Pid, Host, Port} = ssh_test_lib:std_daemon(Config,[{max_random_length_padding,0},
+ {preferred_algorithms,Algs}]),
- ConnectionRef = ssh_test_lib:std_connect(Config, Host, Port, [{rekey_limit, 4500}]),
+ ConnectionRef = ssh_test_lib:std_connect(Config, Host, Port, [{rekey_limit, 6000},
+ {max_random_length_padding,0}]),
{ok, SftpPid} = ssh_sftp:start_channel(ConnectionRef),
Kex1 = get_kex_init(ConnectionRef),
@@ -132,13 +159,15 @@ renegotiate1(Config) ->
UserDir = ?config(priv_dir, Config),
DataFile = filename:join(UserDir, "renegotiate1.data"),
- {Pid, Host, DPort} = ssh_test_lib:std_daemon(Config,[]),
+ Algs = ?config(preferred_algorithms, Config),
+ {Pid, Host, DPort} = ssh_test_lib:std_daemon(Config,[{max_random_length_padding,0},
+ {preferred_algorithms,Algs}]),
RPort = ssh_test_lib:inet_port(),
{ok,RelayPid} = ssh_relay:start_link({0,0,0,0}, RPort, Host, DPort),
- ConnectionRef = ssh_test_lib:std_connect(Config, Host, RPort, []),
+ ConnectionRef = ssh_test_lib:std_connect(Config, Host, RPort, [{max_random_length_padding,0}]),
{ok, SftpPid} = ssh_sftp:start_channel(ConnectionRef),
Kex1 = get_kex_init(ConnectionRef),
@@ -170,12 +199,14 @@ renegotiate2(Config) ->
UserDir = ?config(priv_dir, Config),
DataFile = filename:join(UserDir, "renegotiate2.data"),
- {Pid, Host, DPort} = ssh_test_lib:std_daemon(Config,[]),
+ Algs = ?config(preferred_algorithms, Config),
+ {Pid, Host, DPort} = ssh_test_lib:std_daemon(Config,[{max_random_length_padding,0},
+ {preferred_algorithms,Algs}]),
RPort = ssh_test_lib:inet_port(),
{ok,RelayPid} = ssh_relay:start_link({0,0,0,0}, RPort, Host, DPort),
- ConnectionRef = ssh_test_lib:std_connect(Config, Host, RPort, []),
+ ConnectionRef = ssh_test_lib:std_connect(Config, Host, RPort, [{max_random_length_padding,0}]),
{ok, SftpPid} = ssh_sftp:start_channel(ConnectionRef),
Kex1 = get_kex_init(ConnectionRef),
diff --git a/lib/ssh/test/ssh_sftp_SUITE.erl b/lib/ssh/test/ssh_sftp_SUITE.erl
index 32fdec9842..698af259c8 100644
--- a/lib/ssh/test/ssh_sftp_SUITE.erl
+++ b/lib/ssh/test/ssh_sftp_SUITE.erl
@@ -526,6 +526,8 @@ async_read(Config) when is_list(Config) ->
ok;
Msg ->
ct:fail(Msg)
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
%%--------------------------------------------------------------------
async_write() ->
@@ -593,6 +595,8 @@ pos_read(Config) when is_list(Config) ->
ok;
Msg ->
ct:fail(Msg)
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
NewData1 = "hopp",
@@ -618,6 +622,8 @@ pos_write(Config) when is_list(Config) ->
ok;
Msg ->
ct:fail(Msg)
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
ok = ssh_sftp:pwrite(Sftp, Handle, eof, list_to_binary("!")),
diff --git a/lib/ssh/test/ssh_sftpd_SUITE.erl b/lib/ssh/test/ssh_sftpd_SUITE.erl
index 94a54ec9db..6b03a2b763 100644
--- a/lib/ssh/test/ssh_sftpd_SUITE.erl
+++ b/lib/ssh/test/ssh_sftpd_SUITE.erl
@@ -683,6 +683,8 @@ reply(Cm, Channel, RBuf) ->
closed;
{ssh_cm, Cm, Msg} ->
ct:fail(Msg)
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
diff --git a/lib/ssh/test/ssh_test_lib.erl b/lib/ssh/test/ssh_test_lib.erl
index 6d568125bb..424afc76fe 100644
--- a/lib/ssh/test/ssh_test_lib.erl
+++ b/lib/ssh/test/ssh_test_lib.erl
@@ -93,9 +93,12 @@ std_connect(Config, Host, Port, ExtraOpts) ->
| ExtraOpts]).
std_simple_sftp(Host, Port, Config) ->
+ std_simple_sftp(Host, Port, Config, []).
+
+std_simple_sftp(Host, Port, Config, Opts) ->
UserDir = ?config(priv_dir, Config),
DataFile = filename:join(UserDir, "test.data"),
- ConnectionRef = ssh_test_lib:std_connect(Config, Host, Port, []),
+ ConnectionRef = ssh_test_lib:std_connect(Config, Host, Port, Opts),
{ok, ChannelRef} = ssh_sftp:start_channel(ConnectionRef),
Data = crypto:rand_bytes(proplists:get_value(std_simple_sftp_size,Config,10)),
ok = ssh_sftp:write_file(ChannelRef, DataFile, Data),
@@ -104,7 +107,10 @@ std_simple_sftp(Host, Port, Config) ->
Data == ReadData.
std_simple_exec(Host, Port, Config) ->
- ConnectionRef = ssh_test_lib:std_connect(Config, Host, Port, []),
+ std_simple_exec(Host, Port, Config, []).
+
+std_simple_exec(Host, Port, Config, Opts) ->
+ ConnectionRef = ssh_test_lib:std_connect(Config, Host, Port, Opts),
{ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity),
success = ssh_connection:exec(ConnectionRef, ChannelId, "23+21-2.", infinity),
Data = {ssh_cm, ConnectionRef, {data, ChannelId, 0, <<"42\n">>}},
@@ -157,7 +163,9 @@ loop_io_server(TestCase, Buff0) ->
{'EXIT',_, _} ->
erlang:display('ssh_test_lib:loop_io_server/2 EXIT'),
ok
- end.
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
+ end.
io_request({put_chars, Chars}, TestCase, _, _, Buff) ->
reply(TestCase, Chars),
@@ -206,6 +214,8 @@ receive_exec_result(Msg) ->
Other ->
ct:log("Other ~p", [Other]),
{unexpected_msg, Other}
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
@@ -286,6 +296,7 @@ setup_dsa(DataDir, UserDir) ->
file:make_dir(System),
file:copy(filename:join(DataDir, "ssh_host_dsa_key"), filename:join(System, "ssh_host_dsa_key")),
file:copy(filename:join(DataDir, "ssh_host_dsa_key.pub"), filename:join(System, "ssh_host_dsa_key.pub")),
+ct:log("DataDir ~p:~n ~p~n~nSystDir ~p:~n ~p~n~nUserDir ~p:~n ~p",[DataDir, file:list_dir(DataDir), System, file:list_dir(System), UserDir, file:list_dir(UserDir)]),
setup_dsa_known_host(DataDir, UserDir),
setup_dsa_auth_keys(DataDir, UserDir).
@@ -294,10 +305,21 @@ setup_rsa(DataDir, UserDir) ->
System = filename:join(UserDir, "system"),
file:make_dir(System),
file:copy(filename:join(DataDir, "ssh_host_rsa_key"), filename:join(System, "ssh_host_rsa_key")),
- file:copy(filename:join(DataDir, "ssh_host_rsa_key"), filename:join(System, "ssh_host_rsa_key.pub")),
+ file:copy(filename:join(DataDir, "ssh_host_rsa_key.pub"), filename:join(System, "ssh_host_rsa_key.pub")),
+ct:log("DataDir ~p:~n ~p~n~nSystDir ~p:~n ~p~n~nUserDir ~p:~n ~p",[DataDir, file:list_dir(DataDir), System, file:list_dir(System), UserDir, file:list_dir(UserDir)]),
setup_rsa_known_host(DataDir, UserDir),
setup_rsa_auth_keys(DataDir, UserDir).
+setup_ecdsa(Size, DataDir, UserDir) ->
+ file:copy(filename:join(DataDir, "id_ecdsa"++Size), filename:join(UserDir, "id_ecdsa")),
+ System = filename:join(UserDir, "system"),
+ file:make_dir(System),
+ file:copy(filename:join(DataDir, "ssh_host_ecdsa_key"++Size), filename:join(System, "ssh_host_ecdsa_key")),
+ file:copy(filename:join(DataDir, "ssh_host_ecdsa_key"++Size++".pub"), filename:join(System, "ssh_host_ecdsa_key.pub")),
+ct:log("DataDir ~p:~n ~p~n~nSystDir ~p:~n ~p~n~nUserDir ~p:~n ~p",[DataDir, file:list_dir(DataDir), System, file:list_dir(System), UserDir, file:list_dir(UserDir)]),
+ setup_ecdsa_known_host(Size, System, UserDir),
+ setup_ecdsa_auth_keys(Size, UserDir, UserDir).
+
clean_dsa(UserDir) ->
del_dirs(filename:join(UserDir, "system")),
file:delete(filename:join(UserDir,"id_dsa")),
@@ -349,6 +371,11 @@ setup_rsa_known_host(SystemDir, UserDir) ->
[{Key, _}] = public_key:ssh_decode(SshBin, public_key),
setup_known_hosts(Key, UserDir).
+setup_ecdsa_known_host(_Size, SystemDir, UserDir) ->
+ {ok, SshBin} = file:read_file(filename:join(SystemDir, "ssh_host_ecdsa_key.pub")),
+ [{Key, _}] = public_key:ssh_decode(SshBin, public_key),
+ setup_known_hosts(Key, UserDir).
+
setup_known_hosts(Key, UserDir) ->
{ok, Hostname} = inet:gethostname(),
{ok, {A, B, C, D}} = inet:getaddr(Hostname, inet),
@@ -376,6 +403,14 @@ setup_rsa_auth_keys(Dir, UserDir) ->
PKey = #'RSAPublicKey'{publicExponent = E, modulus = N},
setup_auth_keys([{ PKey, [{comment, "Test"}]}], UserDir).
+setup_ecdsa_auth_keys(_Size, Dir, UserDir) ->
+ {ok, Pem} = file:read_file(filename:join(Dir, "id_ecdsa")),
+ ECDSA = public_key:pem_entry_decode(hd(public_key:pem_decode(Pem))),
+ #'ECPrivateKey'{publicKey = Q,
+ parameters = Param = {namedCurve,_Id0}} = ECDSA,
+ PKey = #'ECPoint'{point = Q},
+ setup_auth_keys([{ {PKey,Param}, [{comment, "Test"}]}], UserDir).
+
setup_auth_keys(Keys, Dir) ->
AuthKeys = public_key:ssh_encode(Keys, auth_keys),
AuthKeysFile = filename:join(Dir, "authorized_keys"),
@@ -424,6 +459,14 @@ openssh_sanity_check(Config) ->
{skip, Str}
end.
+openssh_supports(ClientOrServer, Tag, Alg) when ClientOrServer == sshc ;
+ ClientOrServer == sshd ->
+ SSH_algos = ssh_test_lib:default_algorithms(ClientOrServer),
+ L = proplists:get_value(Tag, SSH_algos, []),
+ lists:member(Alg, L) orelse
+ lists:member(Alg, proplists:get_value(client2server, L, [])) orelse
+ lists:member(Alg, proplists:get_value(server2client, L, [])).
+
%%--------------------------------------------------------------------
%% Check if we have a "newer" ssh client that supports these test cases
@@ -443,7 +486,63 @@ check_ssh_client_support2(P) ->
-1
end.
-default_algorithms(Host, Port) ->
+%%%--------------------------------------------------------------------
+%%% Probe a server or a client about algorithm support
+
+default_algorithms(sshd) ->
+ default_algorithms(sshd, "localhost", 22);
+
+default_algorithms(sshc) ->
+ default_algorithms(sshc, []).
+
+default_algorithms(sshd, Host, Port) ->
+ try run_fake_ssh(
+ ssh_trpt_test_lib:exec(
+ [{connect,Host,Port, [{silently_accept_hosts, true},
+ {user_interaction, false}]}]))
+ catch
+ _C:_E ->
+ ct:log("***~p:~p: ~p:~p",[?MODULE,?LINE,_C,_E]),
+ []
+ end.
+
+default_algorithms(sshc, DaemonOptions) ->
+ Parent = self(),
+ %% Start a process handling one connection on the server side:
+ Srvr =
+ spawn_link(
+ fun() ->
+ Parent !
+ {result, self(),
+ try
+ {ok,InitialState} = ssh_trpt_test_lib:exec(listen),
+ Parent ! {hostport,self(),ssh_trpt_test_lib:server_host_port(InitialState)},
+ run_fake_ssh(
+ ssh_trpt_test_lib:exec([{accept, DaemonOptions}],
+ InitialState))
+ catch
+ _C:_E ->
+ ct:log("***~p:~p: ~p:~p",[?MODULE,?LINE,_C,_E]),
+ []
+ end}
+ end),
+
+ receive
+ {hostport,Srvr,{_Host,Port}} ->
+ spawn(fun()-> os:cmd(lists:concat(["ssh -o \"StrictHostKeyChecking no\" -p ",Port," localhost"])) end)
+ after ?TIMEOUT ->
+ ct:fail("No server respons 1")
+ end,
+
+ receive
+ {result,Srvr,L} ->
+ L
+ after ?TIMEOUT ->
+ ct:fail("No server respons 2")
+ end.
+
+
+run_fake_ssh({ok,InitialState}) ->
KexInitPattern =
#ssh_msg_kexinit{
kex_algorithms = '$kex_algorithms',
@@ -456,61 +555,35 @@ default_algorithms(Host, Port) ->
compression_algorithms_server_to_client = '$compression_algorithms_server_to_client',
_ = '_'
},
+ {ok,E} = ssh_trpt_test_lib:exec([{set_options,[silent]},
+ {send, hello},
+ receive_hello,
+ {send, ssh_msg_kexinit},
+ {match, KexInitPattern, receive_msg},
+ close_socket
+ ],
+ InitialState),
+ [Kex, PubKey, EncC2S, EncS2C, MacC2S, MacS2C, CompC2S, CompS2C] =
+ ssh_trpt_test_lib:instantiate(['$kex_algorithms',
+ '$server_host_key_algorithms',
+ '$encryption_algorithms_client_to_server',
+ '$encryption_algorithms_server_to_client',
+ '$mac_algorithms_client_to_server',
+ '$mac_algorithms_server_to_client',
+ '$compression_algorithms_client_to_server',
+ '$compression_algorithms_server_to_client'
+ ], E),
+ [{kex, to_atoms(Kex)},
+ {public_key, to_atoms(PubKey)},
+ {cipher, [{client2server, to_atoms(EncC2S)},
+ {server2client, to_atoms(EncS2C)}]},
+ {mac, [{client2server, to_atoms(MacC2S)},
+ {server2client, to_atoms(MacS2C)}]},
+ {compression, [{client2server, to_atoms(CompC2S)},
+ {server2client, to_atoms(CompS2C)}]}].
+
- try ssh_trpt_test_lib:exec(
- [{connect,Host,Port, [{silently_accept_hosts, true},
- {user_interaction, false}]},
- {send,hello},
- receive_hello,
- {send, ssh_msg_kexinit},
- {match, KexInitPattern, receive_msg},
- close_socket])
- of
- {ok,E} ->
- [Kex, PubKey, EncC2S, EncS2C, MacC2S, MacS2C, CompC2S, CompS2C] =
- ssh_trpt_test_lib:instantiate(['$kex_algorithms',
- '$server_host_key_algorithms',
- '$encryption_algorithms_client_to_server',
- '$encryption_algorithms_server_to_client',
- '$mac_algorithms_client_to_server',
- '$mac_algorithms_server_to_client',
- '$compression_algorithms_client_to_server',
- '$compression_algorithms_server_to_client'
- ], E),
- [{kex, to_atoms(Kex)},
- {public_key, to_atoms(PubKey)},
- {cipher, [{client2server, to_atoms(EncC2S)},
- {server2client, to_atoms(EncS2C)}]},
- {mac, [{client2server, to_atoms(MacC2S)},
- {server2client, to_atoms(MacS2C)}]},
- {compression, [{client2server, to_atoms(CompC2S)},
- {server2client, to_atoms(CompS2C)}]}];
- _ ->
- []
- catch
- _:_ ->
- []
- end.
-
-
-default_algorithms(sshd) ->
- default_algorithms("localhost", 22);
-default_algorithms(sshc) ->
- case os:find_executable("ssh") of
- false ->
- [];
- _ ->
- Cipher = sshc(cipher),
- Mac = sshc(mac),
- [{kex, sshc(kex)},
- {public_key, sshc(key)},
- {cipher, [{client2server, Cipher},
- {server2client, Cipher}]},
- {mac, [{client2server, Mac},
- {server2client, Mac}]}
- ]
- end.
-
+%%--------------------------------------------------------------------
sshc(Tag) ->
to_atoms(
string:tokens(os:cmd(lists:concat(["ssh -Q ",Tag])), "\n")
@@ -552,4 +625,24 @@ algo_intersection(_, _) ->
to_atoms(L) -> lists:map(fun erlang:list_to_atom/1, L).
-
+%%%----------------------------------------------------------------
+ssh_supports(Alg, SshDefaultAlg_tag) ->
+ SupAlgs =
+ case proplists:get_value(SshDefaultAlg_tag,
+ ssh:default_algorithms()) of
+ [{_K1,L1}, {_K2,L2}] ->
+ lists:usort(L1++L2);
+ L ->
+ L
+ end,
+ if
+ is_atom(Alg) ->
+ lists:member(Alg, SupAlgs);
+ is_list(Alg) ->
+ case Alg--SupAlgs of
+ [] ->
+ true;
+ UnSup ->
+ {false,UnSup}
+ end
+ end.
diff --git a/lib/ssh/test/ssh_to_openssh_SUITE.erl b/lib/ssh/test/ssh_to_openssh_SUITE.erl
index 104c1f9107..d1dfa2efdf 100644
--- a/lib/ssh/test/ssh_to_openssh_SUITE.erl
+++ b/lib/ssh/test/ssh_to_openssh_SUITE.erl
@@ -45,7 +45,6 @@ all() ->
groups() ->
[{erlang_client, [], [erlang_shell_client_openssh_server,
- erlang_client_openssh_server_exec,
erlang_client_openssh_server_exec_compressed,
erlang_client_openssh_server_setenv,
erlang_client_openssh_server_publickey_rsa,
@@ -54,12 +53,7 @@ groups() ->
erlang_client_openssh_server_kexs,
erlang_client_openssh_server_nonexistent_subsystem
]},
- {erlang_server, [], [erlang_server_openssh_client_exec,
- erlang_server_openssh_client_exec_compressed,
- erlang_server_openssh_client_pulic_key_dsa,
- erlang_server_openssh_client_cipher_suites,
- erlang_server_openssh_client_macs,
- erlang_server_openssh_client_kexs]}
+ {erlang_server, [], [erlang_server_openssh_client_public_key_dsa]}
].
init_per_suite(Config) ->
@@ -88,7 +82,7 @@ init_per_group(erlang_server, Config) ->
init_per_group(erlang_client, Config) ->
CommonAlgs = ssh_test_lib:algo_intersection(
ssh:default_algorithms(),
- ssh_test_lib:default_algorithms("localhost", 22)),
+ ssh_test_lib:default_algorithms(sshd)),
[{common_algs,CommonAlgs} | Config];
init_per_group(_, Config) ->
Config.
@@ -100,18 +94,21 @@ end_per_group(erlang_server, Config) ->
end_per_group(_, Config) ->
Config.
-init_per_testcase(erlang_server_openssh_client_cipher_suites, Config) ->
- check_ssh_client_support(Config);
-
-init_per_testcase(erlang_server_openssh_client_macs, Config) ->
- check_ssh_client_support(Config);
-
-init_per_testcase(erlang_server_openssh_client_kexs, Config) ->
- check_ssh_client_support(Config);
-
-init_per_testcase(erlang_client_openssh_server_kexs, Config) ->
- check_ssh_client_support(Config);
+init_per_testcase(erlang_server_openssh_client_public_key_dsa, Config) ->
+ case ssh_test_lib:openssh_supports(sshc, public_key, 'ssh-dss') of
+ true ->
+ init_per_testcase('__default__',Config);
+ false ->
+ {skip,"openssh client does not support DSA"}
+ end;
+init_per_testcase(erlang_client_openssh_server_publickey_dsa, Config) ->
+ case ssh_test_lib:openssh_supports(sshd, public_key, 'ssh-dss') of
+ true ->
+ init_per_testcase('__default__',Config);
+ false ->
+ {skip,"openssh client does not support DSA"}
+ end;
init_per_testcase(_TestCase, Config) ->
ssh:start(),
Config.
@@ -182,23 +179,29 @@ erlang_client_openssh_server_exec_compressed() ->
erlang_client_openssh_server_exec_compressed(Config) when is_list(Config) ->
CompressAlgs = [zlib, '[email protected]',none],
- ConnectionRef = ssh_test_lib:connect(?SSH_DEFAULT_PORT, [{silently_accept_hosts, true},
- {user_interaction, false},
- {preferred_algorithms,
- [{compression,CompressAlgs}]}]),
- {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity),
- success = ssh_connection:exec(ConnectionRef, ChannelId,
- "echo testing", infinity),
- Data = {ssh_cm, ConnectionRef, {data, ChannelId, 0, <<"testing\n">>}},
- case ssh_test_lib:receive_exec_result(Data) of
- expected ->
- ssh_test_lib:receive_exec_end(ConnectionRef, ChannelId);
- {unexpected_msg,{ssh_cm, ConnectionRef,
- {exit_status, ChannelId, 0}} = ExitStatus} ->
- ct:log("0: Collected data ~p", [ExitStatus]),
- ssh_test_lib:receive_exec_result(Data, ConnectionRef, ChannelId);
- Other ->
- ct:fail(Other)
+ case ssh_test_lib:ssh_supports(CompressAlgs, compression) of
+ {false,L} ->
+ {skip, io_lib:format("~p compression is not supported",[L])};
+
+ true ->
+ ConnectionRef = ssh_test_lib:connect(?SSH_DEFAULT_PORT, [{silently_accept_hosts, true},
+ {user_interaction, false},
+ {preferred_algorithms,
+ [{compression,CompressAlgs}]}]),
+ {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity),
+ success = ssh_connection:exec(ConnectionRef, ChannelId,
+ "echo testing", infinity),
+ Data = {ssh_cm, ConnectionRef, {data, ChannelId, 0, <<"testing\n">>}},
+ case ssh_test_lib:receive_exec_result(Data) of
+ expected ->
+ ssh_test_lib:receive_exec_end(ConnectionRef, ChannelId);
+ {unexpected_msg,{ssh_cm, ConnectionRef,
+ {exit_status, ChannelId, 0}} = ExitStatus} ->
+ ct:log("0: Collected data ~p", [ExitStatus]),
+ ssh_test_lib:receive_exec_result(Data, ConnectionRef, ChannelId);
+ Other ->
+ ct:fail(Other)
+ end
end.
%%--------------------------------------------------------------------
@@ -252,202 +255,6 @@ erlang_client_openssh_server_kexs(Config) when is_list(Config) ->
end.
%%--------------------------------------------------------------------
-erlang_server_openssh_client_exec() ->
- [{doc, "Test that exec command works."}].
-
-erlang_server_openssh_client_exec(Config) when is_list(Config) ->
- SystemDir = ?config(data_dir, Config),
- PrivDir = ?config(priv_dir, Config),
- KnownHosts = filename:join(PrivDir, "known_hosts"),
-
- {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
- {failfun, fun ssh_test_lib:failfun/2}]),
-
-
- ct:sleep(500),
-
- Cmd = "ssh -p " ++ integer_to_list(Port) ++
- " -o UserKnownHostsFile=" ++ KnownHosts ++ " " ++ Host ++ " 1+1.",
-
- ct:log("Cmd: ~p~n", [Cmd]),
-
- SshPort = open_port({spawn, Cmd}, [binary]),
-
- receive
- {SshPort,{data, <<"2\n">>}} ->
- ok
- after ?TIMEOUT ->
- ct:fail("Did not receive answer")
-
- end,
- ssh:stop_daemon(Pid).
-
-%%--------------------------------------------------------------------
-erlang_server_openssh_client_cipher_suites() ->
- [{doc, "Test that we can connect with different cipher suites."}].
-
-erlang_server_openssh_client_cipher_suites(Config) when is_list(Config) ->
- SystemDir = ?config(data_dir, Config),
- PrivDir = ?config(priv_dir, Config),
- KnownHosts = filename:join(PrivDir, "known_hosts"),
-
- {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
- {failfun, fun ssh_test_lib:failfun/2}]),
-
- ct:sleep(500),
-
- OpenSshCiphers =
- ssh_test_lib:to_atoms(
- string:tokens(os:cmd("ssh -Q cipher"), "\n")),
- ErlCiphers =
- proplists:get_value(client2server,
- proplists:get_value(cipher, ssh:default_algorithms())),
- CommonCiphers =
- ssh_test_lib:algo_intersection(ErlCiphers, OpenSshCiphers),
-
- comment(CommonCiphers),
-
- lists:foreach(
- fun(Cipher) ->
- Cmd = lists:concat(["ssh -p ",Port,
- " -o UserKnownHostsFile=",KnownHosts," ",Host," ",
- " -c ",Cipher," 1+1."]),
- ct:log("Cmd: ~p~n", [Cmd]),
-
- SshPort = open_port({spawn, Cmd}, [binary, stderr_to_stdout]),
-
- receive
- {SshPort,{data, <<"2\n">>}} ->
- ok
- after ?TIMEOUT ->
- ct:fail("~p Did not receive answer",[Cipher])
- end
- end, CommonCiphers),
-
- ssh:stop_daemon(Pid).
-
-%%--------------------------------------------------------------------
-erlang_server_openssh_client_macs() ->
- [{doc, "Test that we can connect with different MACs."}].
-
-erlang_server_openssh_client_macs(Config) when is_list(Config) ->
- SystemDir = ?config(data_dir, Config),
- PrivDir = ?config(priv_dir, Config),
- KnownHosts = filename:join(PrivDir, "known_hosts"),
-
- {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
- {failfun, fun ssh_test_lib:failfun/2}]),
-
-
- ct:sleep(500),
-
- OpenSshMacs =
- ssh_test_lib:to_atoms(
- string:tokens(os:cmd("ssh -Q mac"), "\n")),
- ErlMacs =
- proplists:get_value(client2server,
- proplists:get_value(mac, ssh:default_algorithms())),
- CommonMacs =
- ssh_test_lib:algo_intersection(ErlMacs, OpenSshMacs),
-
- comment(CommonMacs),
-
- lists:foreach(
- fun(MAC) ->
- Cmd = lists:concat(["ssh -p ",Port,
- " -o UserKnownHostsFile=",KnownHosts," ",Host," ",
- " -o MACs=",MAC," 1+1."]),
- ct:log("Cmd: ~p~n", [Cmd]),
-
- SshPort = open_port({spawn, Cmd}, [binary, stderr_to_stdout]),
-
- receive
- {SshPort,{data, <<"2\n">>}} ->
- ok
- after ?TIMEOUT ->
- ct:fail("~p Did not receive answer",[MAC])
- end
- end, CommonMacs),
-
- ssh:stop_daemon(Pid).
-
-%%--------------------------------------------------------------------
-erlang_server_openssh_client_kexs() ->
- [{doc, "Test that we can connect with different KEXs."}].
-
-erlang_server_openssh_client_kexs(Config) when is_list(Config) ->
- SystemDir = ?config(data_dir, Config),
- PrivDir = ?config(priv_dir, Config),
- KnownHosts = filename:join(PrivDir, "known_hosts"),
-
- {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
- {failfun, fun ssh_test_lib:failfun/2},
- {preferred_algorithms,
- [{kex,ssh_transport:supported_algorithms(kex)}]}
- ]),
- ct:sleep(500),
-
- OpenSshKexs =
- ssh_test_lib:to_atoms(
- string:tokens(os:cmd("ssh -Q kex"), "\n")),
- ErlKexs =
- proplists:get_value(kex, ssh:default_algorithms()),
- CommonKexs =
- ssh_test_lib:algo_intersection(ErlKexs, OpenSshKexs),
-
- comment(CommonKexs),
-
- lists:foreach(
- fun(Kex) ->
- Cmd = lists:concat(["ssh -p ",Port,
- " -o UserKnownHostsFile=",KnownHosts," ",Host," ",
- " -o KexAlgorithms=",Kex," 1+1."]),
- ct:log("Cmd: ~p~n", [Cmd]),
-
- SshPort = open_port({spawn, Cmd}, [binary, stderr_to_stdout]),
-
- receive
- {SshPort,{data, <<"2\n">>}} ->
- ok
- after ?TIMEOUT ->
- ct:log("~p Did not receive answer",[Kex])
- end
- end, CommonKexs),
-
- ssh:stop_daemon(Pid).
-
-%%--------------------------------------------------------------------
-erlang_server_openssh_client_exec_compressed() ->
- [{doc, "Test that exec command works."}].
-
-erlang_server_openssh_client_exec_compressed(Config) when is_list(Config) ->
- SystemDir = ?config(data_dir, Config),
- PrivDir = ?config(priv_dir, Config),
- KnownHosts = filename:join(PrivDir, "known_hosts"),
-
-%% CompressAlgs = [zlib, '[email protected]'], % Does not work
- CompressAlgs = [zlib],
- {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
- {preferred_algorithms,
- [{compression, CompressAlgs}]},
- {failfun, fun ssh_test_lib:failfun/2}]),
-
- ct:sleep(500),
-
- Cmd = "ssh -p " ++ integer_to_list(Port) ++
- " -o UserKnownHostsFile=" ++ KnownHosts ++ " -C "++ Host ++ " 1+1.",
- SshPort = open_port({spawn, Cmd}, [binary]),
-
- receive
- {SshPort,{data, <<"2\n">>}} ->
- ok
- after ?TIMEOUT ->
- ct:fail("Did not receive answer")
-
- end,
- ssh:stop_daemon(Pid).
-
-%%--------------------------------------------------------------------
erlang_client_openssh_server_setenv() ->
[{doc, "Test api function ssh_connection:setenv"}].
@@ -543,9 +350,9 @@ erlang_client_openssh_server_publickey_dsa(Config) when is_list(Config) ->
{skip, "no ~/.ssh/id_dsa"}
end.
%%--------------------------------------------------------------------
-erlang_server_openssh_client_pulic_key_dsa() ->
+erlang_server_openssh_client_public_key_dsa() ->
[{doc, "Validate using dsa publickey."}].
-erlang_server_openssh_client_pulic_key_dsa(Config) when is_list(Config) ->
+erlang_server_openssh_client_public_key_dsa(Config) when is_list(Config) ->
SystemDir = ?config(data_dir, Config),
PrivDir = ?config(priv_dir, Config),
KnownHosts = filename:join(PrivDir, "known_hosts"),
@@ -642,6 +449,8 @@ receive_hej() ->
ct:log("Extra info: ~p~n", [Info]),
receive_hej()
end
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
receive_logout() ->
@@ -651,11 +460,15 @@ receive_logout() ->
receive
<<"Connection closed">> ->
ok
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end;
Info ->
ct:log("Extra info when logging out: ~p~n", [Info]),
receive_logout()
- end.
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
+ end.
receive_normal_exit(Shell) ->
receive
@@ -665,6 +478,8 @@ receive_normal_exit(Shell) ->
receive_normal_exit(Shell);
Other ->
ct:fail({unexpected_msg, Other})
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
extra_logout() ->
diff --git a/lib/ssh/test/ssh_trpt_test_lib.erl b/lib/ssh/test/ssh_trpt_test_lib.erl
index caf9bac3b6..4269529ae8 100644
--- a/lib/ssh/test/ssh_trpt_test_lib.erl
+++ b/lib/ssh/test/ssh_trpt_test_lib.erl
@@ -73,7 +73,10 @@ exec(Op, S0=#s{}) ->
op(Op, S1))
of
S = #s{} ->
- print_traces(S),
+ case proplists:get_value(silent,S#s.opts) of
+ true -> ok;
+ _ -> print_traces(S)
+ end,
{ok,S}
catch
{fail,Reason,Se} ->
@@ -383,7 +386,14 @@ send(S0, Line) when is_binary(Line) ->
fun(X) when X==true;X==detail -> {"Send line~n~p~n",[Line]} end),
send_bytes(Line, S#s{return_value = Line});
-%%% Msg = #ssh_msg_*{}
+send(S0, {special,Msg,PacketFun}) when is_tuple(Msg),
+ is_function(PacketFun,2) ->
+ S = opt(print_messages, S0,
+ fun(X) when X==true;X==detail -> {"Send~n~s~n",[format_msg(Msg)]} end),
+ {Packet, C} = PacketFun(Msg, S#s.ssh),
+ send_bytes(Packet, S#s{ssh = C, %%inc_send_seq_num(C),
+ return_value = Msg});
+
send(S0, Msg) when is_tuple(Msg) ->
S = opt(print_messages, S0,
fun(X) when X==true;X==detail -> {"Send~n~s~n",[format_msg(Msg)]} end),
@@ -743,7 +753,7 @@ print_traces(S) ->
[case Len-length(Acc)-1 of
0 ->
io_lib:format(Fmt,Args);
- N ->
+ _N ->
io_lib:format(lists:concat(['~p --------~n',Fmt]),
[Len-length(Acc)-1|Args])
end | Acc]
diff --git a/lib/ssh/vsn.mk b/lib/ssh/vsn.mk
index b305eedcdc..25b19133b1 100644
--- a/lib/ssh/vsn.mk
+++ b/lib/ssh/vsn.mk
@@ -1,4 +1,5 @@
#-*-makefile-*- ; force emacs to enter makefile-mode
-SSH_VSN = 4.1
+SSH_VSN = 4.2
+
APP_VSN = "ssh-$(SSH_VSN)"
diff --git a/lib/ssl/doc/src/notes.xml b/lib/ssl/doc/src/notes.xml
index 6faa3d5f9a..4d4a219b4f 100644
--- a/lib/ssl/doc/src/notes.xml
+++ b/lib/ssl/doc/src/notes.xml
@@ -26,8 +26,9 @@
<file>notes.xml</file>
</header>
<p>This document describes the changes made to the SSL application.</p>
- <section><title>SSL 7.1</title>
+
+<section><title>SSL 7.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
<item>
@@ -107,12 +108,6 @@
<p>
Own Id: OTP-12815</p>
</item>
- <item>
- <p>
- Gracefully ignore proprietary hash_sign algorithms</p>
- <p>
- Own Id: OTP-12829</p>
- </item>
</list>
</section>
@@ -163,6 +158,20 @@
</section>
+<section><title>SSL 6.0.1.1</title>
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Gracefully ignore proprietary hash_sign algorithms</p>
+ <p>
+ Own Id: OTP-12829</p>
+ </item>
+ </list>
+ </section>
+</section>
+
+
<section><title>SSL 6.0.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/ssl/doc/src/ssl.xml b/lib/ssl/doc/src/ssl.xml
index 22ac98c24e..3a541ed162 100644
--- a/lib/ssl/doc/src/ssl.xml
+++ b/lib/ssl/doc/src/ssl.xml
@@ -84,7 +84,7 @@
<seealso marker="kernel:gen_tcp">gen_tcp(3)</seealso> manual pages
in Kernel.</p></item>
- <tag><marker id="type-ssloption"></marker><c>ssloption() =</c></tag>
+ <tag><marker id="type-ssloption"/><c>ssloption() =</c></tag>
<item>
<p><c>{verify, verify_type()}</c></p>
<p><c>| {verify_fun, {fun(), term()}}</c></p>
@@ -160,7 +160,7 @@
<tag><c>sslsocket() =</c></tag>
<item><p>opaque()</p></item>
- <tag><c>protocol() =</c></tag>
+ <tag><marker id="type-protocol"/><c>protocol() =</c></tag>
<item><p><c>sslv3 | tlsv1 | 'tlsv1.1' | 'tlsv1.2'</c></p></item>
<tag><c>ciphers() =</c></tag>
diff --git a/lib/ssl/doc/src/ssl_app.xml b/lib/ssl/doc/src/ssl_app.xml
index 51ce0cedf1..24b0f5300e 100644
--- a/lib/ssl/doc/src/ssl_app.xml
+++ b/lib/ssl/doc/src/ssl_app.xml
@@ -58,7 +58,7 @@
<p><c>erl -ssl protocol_version "['tlsv1.2', 'tlsv1.1']"</c></p>
<taglist>
- <tag><c><![CDATA[protocol_version = <seealso marker="kernel:error_logger">ssl:protocol()</seealso> <optional>]]></c>.</tag>
+ <tag><c> protocol_version = <seealso marker="ssl#type-protocol">ssl:protocol()</seealso> <![CDATA[<optional>]]></c></tag>
<item><p>Protocol supported by started clients and
servers. If this option is not set, it defaults to all
protocols currently supported by the SSL application.
@@ -66,17 +66,24 @@
to <c>ssl:connect/[2,3]</c> and <c>ssl:listen/2</c>.</p></item>
<tag><c><![CDATA[session_lifetime = integer() <optional>]]></c></tag>
- <item><p>Lifetime of the session data in seconds.</p></item>
+ <item><p>Maximum lifetime of the session data in seconds.</p></item>
<tag><c><![CDATA[session_cb = atom() <optional>]]></c></tag>
<item><p>Name of the session cache callback module that implements
the <c>ssl_session_cache_api</c> behavior. Defaults to
- <c>ssl_session_cache.erl</c>.</p></item>
+ <c>ssl_session_cache</c>.</p></item>
<tag><c><![CDATA[session_cb_init_args = proplist:proplist() <optional>]]></c></tag>
<item><p>List of extra user-defined arguments to the <c>init</c> function
in the session cache callback module. Defaults to <c>[]</c>.</p></item>
+
+ <tag><c><![CDATA[session_cache_client_max = integer() <optional>]]></c></tag>
+ <tag><c><![CDATA[session_cache_server_max = integer() <optional>]]></c></tag>
+ <item><p>Limits the growth of the clients/servers session cache,
+ if the maximum number of sessions is reached, the current cache entries will
+ be invalidated regardless of their remaining lifetime. Defaults to 1000.
+ </p></item>
<tag><c><![CDATA[ssl_pem_cache_clean = integer() <optional>]]></c></tag>
<item>
@@ -103,7 +110,10 @@
<section>
<title>ERROR LOGGER AND EVENT HANDLERS</title>
- <p>The SSL application uses the default <seealso marker="kernel:error_logger">OTP error logger</seealso> to log unexpected errors and TLS alerts. The logging of TLS alerts may be turned off with the <c>log_alert</c> option. </p>
+ <p>The SSL application uses the default <seealso
+ marker="kernel:error_logger">OTP error logger</seealso> to log
+ unexpected errors and TLS alerts. The logging of TLS alerts may be
+ turned off with the <c>log_alert</c> option. </p>
</section>
<section>
diff --git a/lib/ssl/src/dtls_connection.erl b/lib/ssl/src/dtls_connection.erl
index 78662e0ea2..153d3fef48 100644
--- a/lib/ssl/src/dtls_connection.erl
+++ b/lib/ssl/src/dtls_connection.erl
@@ -145,7 +145,7 @@ init([Role, Host, Port, Socket, {SSLOpts0, _} = Options, User, CbInfo]) ->
process_flag(trap_exit, true),
State0 = initial_state(Role, Host, Port, Socket, Options, User, CbInfo),
Handshake = ssl_handshake:init_handshake_history(),
- TimeStamp = calendar:datetime_to_gregorian_seconds({date(), time()}),
+ TimeStamp = erlang:monotonic_time(),
try ssl_config:init(SSLOpts0, Role) of
{ok, Ref, CertDbHandle, FileRefHandle, CacheHandle, CRLDbInfo, OwnCert, Key, DHParams} ->
Session = State0#state.session,
diff --git a/lib/ssl/src/inet_tls_dist.erl b/lib/ssl/src/inet_tls_dist.erl
index b6e62a18c9..404ae93d20 100644
--- a/lib/ssl/src/inet_tls_dist.erl
+++ b/lib/ssl/src/inet_tls_dist.erl
@@ -30,7 +30,7 @@
childspecs() ->
{ok, [{ssl_dist_sup,{ssl_dist_sup, start_link, []},
- permanent, 2000, worker, [ssl_dist_sup]}]}.
+ permanent, infinity, supervisor, [ssl_dist_sup]}]}.
select(Node) ->
case split_node(atom_to_list(Node), $@, []) of
diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl
index f8afbdb41d..241871dc38 100644
--- a/lib/ssl/src/ssl_connection.erl
+++ b/lib/ssl/src/ssl_connection.erl
@@ -974,7 +974,7 @@ ssl_config(Opts, Role, State) ->
{ok, Ref, CertDbHandle, FileRefHandle, CacheHandle, CRLDbInfo, OwnCert, Key, DHParams} =
ssl_config:init(Opts, Role),
Handshake = ssl_handshake:init_handshake_history(),
- TimeStamp = calendar:datetime_to_gregorian_seconds({date(), time()}),
+ TimeStamp = erlang:monotonic_time(),
Session = State#state.session,
State#state{tls_handshake_history = Handshake,
session = Session#session{own_certificate = OwnCert,
@@ -1781,7 +1781,7 @@ handle_trusted_certs_db(#state{ssl_options = #ssl_options{cacertfile = <<>>, cac
ok;
handle_trusted_certs_db(#state{cert_db_ref = Ref,
cert_db = CertDb,
- ssl_options = #ssl_options{cacertfile = <<>>}}) ->
+ ssl_options = #ssl_options{cacertfile = <<>>}}) when CertDb =/= undefined ->
%% Certs provided as DER directly can not be shared
%% with other connections and it is safe to delete them when the connection ends.
ssl_pkix_db:remove_trusted_certs(Ref, CertDb);
diff --git a/lib/ssl/src/ssl_dist_sup.erl b/lib/ssl/src/ssl_dist_sup.erl
index aa1fa57db8..435ad27a44 100644
--- a/lib/ssl/src/ssl_dist_sup.erl
+++ b/lib/ssl/src/ssl_dist_sup.erl
@@ -70,7 +70,7 @@ connection_manager_child_spec() ->
Name = ssl_connection_dist,
StartFunc = {tls_connection_sup, start_link_dist, []},
Restart = permanent,
- Shutdown = 4000,
+ Shutdown = infinity,
Modules = [tls_connection_sup],
Type = supervisor,
{Name, StartFunc, Restart, Shutdown, Type, Modules}.
diff --git a/lib/ssl/src/ssl_internal.hrl b/lib/ssl/src/ssl_internal.hrl
index 3851b2bc6e..8c7ed9c0d1 100644
--- a/lib/ssl/src/ssl_internal.hrl
+++ b/lib/ssl/src/ssl_internal.hrl
@@ -78,6 +78,9 @@
-define(ALL_DATAGRAM_SUPPORTED_VERSIONS, ['dtlsv1.2', dtlsv1]).
-define(MIN_DATAGRAM_SUPPORTED_VERSIONS, ['dtlsv1.2', dtlsv1]).
+-define('24H_in_msec', 86400000).
+-define('24H_in_sec', 86400).
+
-record(ssl_options, {
protocol :: tls | dtls,
versions :: [ssl_record:ssl_version()], %% ssl_record:atom_version() in API
diff --git a/lib/ssl/src/ssl_manager.erl b/lib/ssl/src/ssl_manager.erl
index 2e05ba5aa5..00e95f5c5b 100644
--- a/lib/ssl/src/ssl_manager.erl
+++ b/lib/ssl/src/ssl_manager.erl
@@ -46,25 +46,27 @@
-include_lib("kernel/include/file.hrl").
-record(state, {
- session_cache_client,
- session_cache_server,
- session_cache_cb,
- session_lifetime,
- certificate_db,
- session_validation_timer,
+ session_cache_client :: db_handle(),
+ session_cache_server :: db_handle(),
+ session_cache_cb :: atom(),
+ session_lifetime :: integer(),
+ certificate_db :: db_handle(),
+ session_validation_timer :: reference(),
last_delay_timer = {undefined, undefined},%% Keep for testing purposes
- last_pem_check,
- clear_pem_cache
+ last_pem_check :: erlang:timestamp(),
+ clear_pem_cache :: integer(),
+ session_cache_client_max :: integer(),
+ session_cache_server_max :: integer(),
+ session_server_invalidator :: undefined | pid(),
+ session_client_invalidator :: undefined | pid()
}).
--define('24H_in_msec', 86400000).
--define('24H_in_sec', 86400).
-define(GEN_UNIQUE_ID_MAX_TRIES, 10).
-define(SESSION_VALIDATION_INTERVAL, 60000).
-define(CLEAR_PEM_CACHE, 120000).
-define(CLEAN_SESSION_DB, 60000).
-define(CLEAN_CERT_DB, 500).
--define(NOT_TO_BIG, 10).
+-define(DEFAULT_MAX_SESSION_CACHE, 1000).
%%====================================================================
%% API
@@ -89,7 +91,8 @@ manager_name(dist) ->
%%--------------------------------------------------------------------
start_link(Opts) ->
DistMangerName = manager_name(normal),
- gen_server:start_link({local, DistMangerName}, ?MODULE, [DistMangerName, Opts], []).
+ gen_server:start_link({local, DistMangerName},
+ ?MODULE, [DistMangerName, Opts], []).
%%--------------------------------------------------------------------
-spec start_link_dist(list()) -> {ok, pid()} | ignore | {error, term()}.
@@ -99,7 +102,8 @@ start_link(Opts) ->
%%--------------------------------------------------------------------
start_link_dist(Opts) ->
DistMangerName = manager_name(dist),
- gen_server:start_link({local, DistMangerName}, ?MODULE, [DistMangerName, Opts], []).
+ gen_server:start_link({local, DistMangerName},
+ ?MODULE, [DistMangerName, Opts], []).
%%--------------------------------------------------------------------
-spec connection_init(binary()| {der, list()}, client | server,
@@ -169,7 +173,8 @@ new_session_id(Port) ->
%% be called by ssl-connection processes.
%%--------------------------------------------------------------------
clean_cert_db(Ref, File) ->
- erlang:send_after(?CLEAN_CERT_DB, get(ssl_manager), {clean_cert_db, Ref, File}),
+ erlang:send_after(?CLEAN_CERT_DB, get(ssl_manager),
+ {clean_cert_db, Ref, File}),
ok.
%%--------------------------------------------------------------------
@@ -237,10 +242,12 @@ init([Name, Opts]) ->
SessionLifeTime =
proplists:get_value(session_lifetime, Opts, ?'24H_in_sec'),
CertDb = ssl_pkix_db:create(),
- ClientSessionCache = CacheCb:init([{role, client} |
- proplists:get_value(session_cb_init_args, Opts, [])]),
- ServerSessionCache = CacheCb:init([{role, server} |
- proplists:get_value(session_cb_init_args, Opts, [])]),
+ ClientSessionCache =
+ CacheCb:init([{role, client} |
+ proplists:get_value(session_cb_init_args, Opts, [])]),
+ ServerSessionCache =
+ CacheCb:init([{role, server} |
+ proplists:get_value(session_cb_init_args, Opts, [])]),
Timer = erlang:send_after(SessionLifeTime * 1000 + 5000,
self(), validate_sessions),
Interval = pem_check_interval(),
@@ -252,7 +259,11 @@ init([Name, Opts]) ->
session_lifetime = SessionLifeTime,
session_validation_timer = Timer,
last_pem_check = os:timestamp(),
- clear_pem_cache = Interval
+ clear_pem_cache = Interval,
+ session_cache_client_max =
+ max_session_cache_size(session_cache_client_max),
+ session_cache_server_max =
+ max_session_cache_size(session_cache_server_max)
}}.
%%--------------------------------------------------------------------
@@ -269,7 +280,8 @@ init([Name, Opts]) ->
handle_call({{connection_init, <<>>, Role, {CRLCb, UserCRLDb}}, _Pid}, _From,
#state{certificate_db = [CertDb, FileRefDb, PemChace | _] = Db} = State) ->
Ref = make_ref(),
- Result = {ok, Ref, CertDb, FileRefDb, PemChace, session_cache(Role, State), {CRLCb, crl_db_info(Db, UserCRLDb)}},
+ Result = {ok, Ref, CertDb, FileRefDb, PemChace,
+ session_cache(Role, State), {CRLCb, crl_db_info(Db, UserCRLDb)}},
{reply, Result, State#state{certificate_db = Db}};
handle_call({{connection_init, Trustedcerts, Role, {CRLCb, UserCRLDb}}, Pid}, _From,
@@ -307,7 +319,8 @@ handle_call({{cache_pem,File}, _Pid}, _,
_:Reason ->
{reply, {error, Reason}, State}
end;
-handle_call({unconditionally_clear_pem_cache, _},_, #state{certificate_db = [_,_,PemChace | _]} = State) ->
+handle_call({unconditionally_clear_pem_cache, _},_,
+ #state{certificate_db = [_,_,PemChace | _]} = State) ->
ssl_pkix_db:clear(PemChace),
{reply, ok, State}.
@@ -319,27 +332,12 @@ handle_call({unconditionally_clear_pem_cache, _},_, #state{certificate_db = [_,_
%%
%% Description: Handling cast messages
%%--------------------------------------------------------------------
-handle_cast({register_session, Host, Port, Session},
- #state{session_cache_client = Cache,
- session_cache_cb = CacheCb} = State) ->
- TimeStamp = calendar:datetime_to_gregorian_seconds({date(), time()}),
- NewSession = Session#session{time_stamp = TimeStamp},
-
- case CacheCb:select_session(Cache, {Host, Port}) of
- no_session ->
- CacheCb:update(Cache, {{Host, Port},
- NewSession#session.session_id}, NewSession);
- Sessions ->
- register_unique_session(Sessions, NewSession, CacheCb, Cache, {Host, Port})
- end,
+handle_cast({register_session, Host, Port, Session}, State0) ->
+ State = ssl_client_register_session(Host, Port, Session, State0),
{noreply, State};
-handle_cast({register_session, Port, Session},
- #state{session_cache_server = Cache,
- session_cache_cb = CacheCb} = State) ->
- TimeStamp = calendar:datetime_to_gregorian_seconds({date(), time()}),
- NewSession = Session#session{time_stamp = TimeStamp},
- CacheCb:update(Cache, {Port, NewSession#session.session_id}, NewSession),
+handle_cast({register_session, Port, Session}, State0) ->
+ State = server_register_session(Port, Session, State0),
{noreply, State};
handle_cast({invalidate_session, Host, Port,
@@ -413,10 +411,10 @@ handle_info({clean_cert_db, Ref, File},
end,
{noreply, State};
-handle_info({'EXIT', _, _}, State) ->
- %% Session validator died!! Do we need to take any action?
- %% maybe error log
- {noreply, State};
+handle_info({'EXIT', Pid, _}, #state{session_client_invalidator = Pid} = State) ->
+ {noreply, State#state{session_client_invalidator = undefined}};
+handle_info({'EXIT', Pid, _}, #state{session_server_invalidator = Pid} = State) ->
+ {noreply, State#state{session_server_invalidator = undefined}};
handle_info(_Info, State) ->
{noreply, State}.
@@ -497,7 +495,15 @@ delay_time() ->
?CLEAN_SESSION_DB
end.
-invalidate_session(Cache, CacheCb, Key, Session, #state{last_delay_timer = LastTimer} = State) ->
+max_session_cache_size(CacheType) ->
+ case application:get_env(ssl, CacheType) of
+ {ok, Size} when is_integer(Size) ->
+ Size;
+ _ ->
+ ?DEFAULT_MAX_SESSION_CACHE
+ end.
+
+invalidate_session(Cache, CacheCb, Key, Session, State) ->
case CacheCb:lookup(Cache, Key) of
undefined -> %% Session is already invalidated
{noreply, State};
@@ -505,15 +511,23 @@ invalidate_session(Cache, CacheCb, Key, Session, #state{last_delay_timer = LastT
CacheCb:delete(Cache, Key),
{noreply, State};
_ ->
- %% When a registered session is invalidated we need to wait a while before deleting
- %% it as there might be pending connections that rightfully needs to look
- %% up the session data but new connections should not get to use this session.
- CacheCb:update(Cache, Key, Session#session{is_resumable = false}),
- TRef =
- erlang:send_after(delay_time(), self(), {delayed_clean_session, Key, Cache}),
- {noreply, State#state{last_delay_timer = last_delay_timer(Key, TRef, LastTimer)}}
+ delayed_invalidate_session(CacheCb, Cache, Key, Session, State)
end.
+delayed_invalidate_session(CacheCb, Cache, Key, Session,
+ #state{last_delay_timer = LastTimer} = State) ->
+ %% When a registered session is invalidated we need to
+ %% wait a while before deleting it as there might be
+ %% pending connections that rightfully needs to look up
+ %% the session data but new connections should not get to
+ %% use this session.
+ CacheCb:update(Cache, Key, Session#session{is_resumable = false}),
+ TRef =
+ erlang:send_after(delay_time(), self(),
+ {delayed_clean_session, Key, Cache}),
+ {noreply, State#state{last_delay_timer =
+ last_delay_timer(Key, TRef, LastTimer)}}.
+
last_delay_timer({{_,_},_}, TRef, {LastServer, _}) ->
{LastServer, TRef};
last_delay_timer({_,_}, TRef, {_, LastClient}) ->
@@ -532,12 +546,12 @@ new_id(Port, Tries, Cache, CacheCb) ->
Id = crypto:rand_bytes(?NUM_OF_SESSION_ID_BYTES),
case CacheCb:lookup(Cache, {Port, Id}) of
undefined ->
- Now = calendar:datetime_to_gregorian_seconds({date(), time()}),
+ Now = erlang:monotonic_time(),
%% New sessions can not be set to resumable
%% until handshake is compleate and the
%% other session values are set.
CacheCb:update(Cache, {Port, Id}, #session{session_id = Id,
- is_resumable = false,
+ is_resumable = new,
time_stamp = Now}),
Id;
_ ->
@@ -559,15 +573,62 @@ clean_cert_db(Ref, CertDb, RefDb, PemCache, File) ->
ok
end.
+ssl_client_register_session(Host, Port, Session, #state{session_cache_client = Cache,
+ session_cache_cb = CacheCb,
+ session_cache_client_max = Max,
+ session_client_invalidator = Pid0} = State) ->
+ TimeStamp = erlang:monotonic_time(),
+ NewSession = Session#session{time_stamp = TimeStamp},
+
+ case CacheCb:select_session(Cache, {Host, Port}) of
+ no_session ->
+ Pid = do_register_session({{Host, Port},
+ NewSession#session.session_id},
+ NewSession, Max, Pid0, Cache, CacheCb),
+ State#state{session_client_invalidator = Pid};
+ Sessions ->
+ register_unique_session(Sessions, NewSession, {Host, Port}, State)
+ end.
+
+server_register_session(Port, Session, #state{session_cache_server_max = Max,
+ session_cache_server = Cache,
+ session_cache_cb = CacheCb,
+ session_server_invalidator = Pid0} = State) ->
+ TimeStamp = erlang:monotonic_time(),
+ NewSession = Session#session{time_stamp = TimeStamp},
+ Pid = do_register_session({Port, NewSession#session.session_id},
+ NewSession, Max, Pid0, Cache, CacheCb),
+ State#state{session_server_invalidator = Pid}.
+
+do_register_session(Key, Session, Max, Pid, Cache, CacheCb) ->
+ try CacheCb:size(Cache) of
+ N when N > Max ->
+ invalidate_session_cache(Pid, CacheCb, Cache);
+ _ ->
+ CacheCb:update(Cache, Key, Session),
+ Pid
+ catch
+ error:undef ->
+ CacheCb:update(Cache, Key, Session),
+ Pid
+ end.
+
+
%% Do not let dumb clients create a gigantic session table
%% for itself creating big delays at connection time.
-register_unique_session(Sessions, Session, CacheCb, Cache, PartialKey) ->
+register_unique_session(Sessions, Session, PartialKey,
+ #state{session_cache_client_max = Max,
+ session_cache_client = Cache,
+ session_cache_cb = CacheCb,
+ session_client_invalidator = Pid0} = State) ->
case exists_equivalent(Session , Sessions) of
true ->
- ok;
+ State;
false ->
- CacheCb:update(Cache, {PartialKey,
- Session#session.session_id}, Session)
+ Pid = do_register_session({PartialKey,
+ Session#session.session_id},
+ Session, Max, Pid0, Cache, CacheCb),
+ State#state{session_client_invalidator = Pid}
end.
exists_equivalent(_, []) ->
@@ -622,7 +683,8 @@ pem_check_interval() ->
end.
is_before_checkpoint(Time, CheckPoint) ->
- calendar:datetime_to_gregorian_seconds(calendar:now_to_datetime(CheckPoint)) -
+ calendar:datetime_to_gregorian_seconds(
+ calendar:now_to_datetime(CheckPoint)) -
calendar:datetime_to_gregorian_seconds(Time) > 0.
add_trusted_certs(Pid, Trustedcerts, Db) ->
@@ -643,3 +705,9 @@ crl_db_info([_,_,_,Local], {internal, Info}) ->
crl_db_info(_, UserCRLDb) ->
UserCRLDb.
+%% Only start a session invalidator if there is not
+%% one already active
+invalidate_session_cache(undefined, CacheCb, Cache) ->
+ start_session_validator(Cache, CacheCb, {invalidate_before, erlang:monotonic_time()});
+invalidate_session_cache(Pid, _CacheCb, _Cache) ->
+ Pid.
diff --git a/lib/ssl/src/ssl_session.erl b/lib/ssl/src/ssl_session.erl
index 0d6cc93a20..2b24bff5ff 100644
--- a/lib/ssl/src/ssl_session.erl
+++ b/lib/ssl/src/ssl_session.erl
@@ -31,8 +31,6 @@
%% Internal application API
-export([is_new/2, client_id/4, server_id/6, valid_session/2]).
--define('24H_in_sec', 8640).
-
-type seconds() :: integer().
%%--------------------------------------------------------------------
@@ -63,13 +61,16 @@ client_id(ClientInfo, Cache, CacheCb, OwnCert) ->
SessionId
end.
--spec valid_session(#session{}, seconds()) -> boolean().
+-spec valid_session(#session{}, seconds() | {invalidate_before, integer()}) -> boolean().
%%
%% Description: Check that the session has not expired
%%--------------------------------------------------------------------
+valid_session(#session{time_stamp = TimeStamp}, {invalidate_before, Before}) ->
+ TimeStamp > Before;
valid_session(#session{time_stamp = TimeStamp}, LifeTime) ->
- Now = calendar:datetime_to_gregorian_seconds({date(), time()}),
- Now - TimeStamp < LifeTime.
+ Now = erlang:monotonic_time(),
+ Lived = erlang:convert_time_unit(Now-TimeStamp, native, seconds),
+ Lived < LifeTime.
server_id(Port, <<>>, _SslOpts, _Cert, _, _) ->
{ssl_manager:new_session_id(Port), undefined};
diff --git a/lib/ssl/src/ssl_session_cache.erl b/lib/ssl/src/ssl_session_cache.erl
index cfc48cd935..9585e613e6 100644
--- a/lib/ssl/src/ssl_session_cache.erl
+++ b/lib/ssl/src/ssl_session_cache.erl
@@ -27,7 +27,7 @@
-include("ssl_internal.hrl").
-export([init/1, terminate/1, lookup/2, update/3, delete/2, foldl/3,
- select_session/2]).
+ select_session/2, size/1]).
%%--------------------------------------------------------------------
%% Description: Return table reference. Called by ssl_manager process.
@@ -86,6 +86,12 @@ select_session(Cache, PartialKey) ->
[{{{PartialKey,'_'}, '$1'},[],['$1']}]).
%%--------------------------------------------------------------------
+%% Description: Returns the cache size
+%%--------------------------------------------------------------------
+size(Cache) ->
+ ets:info(Cache, size).
+
+%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
cache_name(Name) ->
diff --git a/lib/ssl/src/ssl_session_cache_api.erl b/lib/ssl/src/ssl_session_cache_api.erl
index 536b52c44b..8f62c25be5 100644
--- a/lib/ssl/src/ssl_session_cache_api.erl
+++ b/lib/ssl/src/ssl_session_cache_api.erl
@@ -33,3 +33,4 @@
-callback delete(db_handle(), key()) -> any().
-callback foldl(fun(), term(), db_handle()) -> term().
-callback select_session(db_handle(), {host(), inet:port_number()} | inet:port_number()) -> [#session{}].
+-callback size(db_handle()) -> integer().
diff --git a/lib/ssl/src/ssl_tls_dist_proxy.erl b/lib/ssl/src/ssl_tls_dist_proxy.erl
index 273d3b5521..d384264b53 100644
--- a/lib/ssl/src/ssl_tls_dist_proxy.erl
+++ b/lib/ssl/src/ssl_tls_dist_proxy.erl
@@ -48,6 +48,47 @@ accept(Listen) ->
connect(Ip, Port) ->
gen_server:call(?MODULE, {connect, Ip, Port}, infinity).
+
+do_listen(Options) ->
+ {First,Last} = case application:get_env(kernel,inet_dist_listen_min) of
+ {ok,N} when is_integer(N) ->
+ case application:get_env(kernel,
+ inet_dist_listen_max) of
+ {ok,M} when is_integer(M) ->
+ {N,M};
+ _ ->
+ {N,N}
+ end;
+ _ ->
+ {0,0}
+ end,
+ do_listen(First, Last, listen_options([{backlog,128}|Options])).
+
+do_listen(First,Last,_) when First > Last ->
+ {error,eaddrinuse};
+do_listen(First,Last,Options) ->
+ case gen_tcp:listen(First, Options) of
+ {error, eaddrinuse} ->
+ do_listen(First+1,Last,Options);
+ Other ->
+ Other
+ end.
+
+listen_options(Opts0) ->
+ Opts1 =
+ case application:get_env(kernel, inet_dist_use_interface) of
+ {ok, Ip} ->
+ [{ip, Ip} | Opts0];
+ _ ->
+ Opts0
+ end,
+ case application:get_env(kernel, inet_dist_listen_options) of
+ {ok,ListenOpts} ->
+ ListenOpts ++ Opts1;
+ _ ->
+ Opts1
+ end.
+
%%====================================================================
%% gen_server callbacks
%%====================================================================
@@ -62,13 +103,17 @@ init([]) ->
handle_call({listen, Name}, _From, State) ->
case gen_tcp:listen(0, [{active, false}, {packet,?PPRE}]) of
{ok, Socket} ->
- {ok, World} = gen_tcp:listen(0, [{active, false}, binary, {packet,?PPRE}]),
+ {ok, World} = do_listen([{active, false}, binary, {packet,?PPRE}, {reuseaddr, true}]),
{ok, TcpAddress} = get_tcp_address(Socket),
{ok, WorldTcpAddress} = get_tcp_address(World),
{_,Port} = WorldTcpAddress#net_address.address,
- {ok, Creation} = erl_epmd:register_node(Name, Port),
- {reply, {ok, {Socket, TcpAddress, Creation}},
- State#state{listen={Socket, World}}};
+ case erl_epmd:register_node(Name, Port) of
+ {ok, Creation} ->
+ {reply, {ok, {Socket, TcpAddress, Creation}},
+ State#state{listen={Socket, World}}};
+ {error, _} = Error ->
+ {reply, Error, State}
+ end;
Error ->
{reply, Error, State}
end;
@@ -134,6 +179,7 @@ accept_loop(Proxy, erts = Type, Listen, Extra) ->
Extra ! {accept,self(),Socket,inet,proxy},
receive
{_Kernel, controller, Pid} ->
+ inet:setopts(Socket, [nodelay()]),
ok = gen_tcp:controlling_process(Socket, Pid),
flush_old_controller(Pid, Socket),
Pid ! {self(), controller};
@@ -167,7 +213,7 @@ accept_loop(Proxy, world = Type, Listen, Extra) ->
accept_loop(Proxy, Type, Listen, Extra).
try_connect(Port) ->
- case gen_tcp:connect({127,0,0,1}, Port, [{active, false}, {packet,?PPRE}]) of
+ case gen_tcp:connect({127,0,0,1}, Port, [{active, false}, {packet,?PPRE}, nodelay()]) of
R = {ok, _S} ->
R;
{error, _R} ->
@@ -177,7 +223,7 @@ try_connect(Port) ->
setup_proxy(Ip, Port, Parent) ->
process_flag(trap_exit, true),
Opts = get_ssl_options(client),
- case ssl:connect(Ip, Port, [{active, true}, binary, {packet,?PPRE}] ++ Opts) of
+ case ssl:connect(Ip, Port, [{active, true}, binary, {packet,?PPRE}, nodelay()] ++ Opts) of
{ok, World} ->
{ok, ErtsL} = gen_tcp:listen(0, [{active, true}, {ip, {127,0,0,1}}, binary, {packet,?PPRE}]),
{ok, #net_address{address={_,LPort}}} = get_tcp_address(ErtsL),
@@ -193,25 +239,41 @@ setup_proxy(Ip, Port, Parent) ->
Parent ! {self(), Err}
end.
+
+%% we may not always want the nodelay behaviour
+%% %% for performance reasons
+
+nodelay() ->
+ case application:get_env(kernel, dist_nodelay) of
+ undefined ->
+ {nodelay, true};
+ {ok, true} ->
+ {nodelay, true};
+ {ok, false} ->
+ {nodelay, false};
+ _ ->
+ {nodelay, true}
+ end.
+
setup_connection(World, ErtsListen) ->
process_flag(trap_exit, true),
{ok, TcpAddress} = get_tcp_address(ErtsListen),
{_Addr,Port} = TcpAddress#net_address.address,
- {ok, Erts} = gen_tcp:connect({127,0,0,1}, Port, [{active, true}, binary, {packet,?PPRE}]),
- ssl:setopts(World, [{active,true}, {packet,?PPRE}]),
+ {ok, Erts} = gen_tcp:connect({127,0,0,1}, Port, [{active, true}, binary, {packet,?PPRE}, nodelay()]),
+ ssl:setopts(World, [{active,true}, {packet,?PPRE}, nodelay()]),
loop_conn_setup(World, Erts).
loop_conn_setup(World, Erts) ->
receive
{ssl, World, Data = <<$a, _/binary>>} ->
gen_tcp:send(Erts, Data),
- ssl:setopts(World, [{packet,?PPOST}]),
- inet:setopts(Erts, [{packet,?PPOST}]),
+ ssl:setopts(World, [{packet,?PPOST}, nodelay()]),
+ inet:setopts(Erts, [{packet,?PPOST}, nodelay()]),
loop_conn(World, Erts);
{tcp, Erts, Data = <<$a, _/binary>>} ->
ssl:send(World, Data),
- ssl:setopts(World, [{packet,?PPOST}]),
- inet:setopts(Erts, [{packet,?PPOST}]),
+ ssl:setopts(World, [{packet,?PPOST}, nodelay()]),
+ inet:setopts(Erts, [{packet,?PPOST}, nodelay()]),
loop_conn(World, Erts);
{ssl, World, Data = <<_, _/binary>>} ->
gen_tcp:send(Erts, Data),
diff --git a/lib/ssl/src/ssl_v3.erl b/lib/ssl/src/ssl_v3.erl
index 5e043624a7..f169059a75 100644
--- a/lib/ssl/src/ssl_v3.erl
+++ b/lib/ssl/src/ssl_v3.erl
@@ -144,6 +144,7 @@ suites() ->
?TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
?TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
?TLS_RSA_WITH_AES_128_CBC_SHA,
+ ?TLS_DHE_RSA_WITH_DES_CBC_SHA,
?TLS_RSA_WITH_DES_CBC_SHA
].
diff --git a/lib/ssl/src/tls_connection.erl b/lib/ssl/src/tls_connection.erl
index 3093508f61..a468c131ce 100644
--- a/lib/ssl/src/tls_connection.erl
+++ b/lib/ssl/src/tls_connection.erl
@@ -168,9 +168,10 @@ hello(start, #state{host = Host, port = Port, role = client,
Cache, CacheCb, Renegotiation, Cert),
Version = Hello#client_hello.client_version,
+ HelloVersion = tls_record:lowest_protocol_version(SslOpts#ssl_options.versions),
Handshake0 = ssl_handshake:init_handshake_history(),
{BinMsg, ConnectionStates, Handshake} =
- encode_handshake(Hello, Version, ConnectionStates0, Handshake0),
+ encode_handshake(Hello, HelloVersion, ConnectionStates0, Handshake0),
Transport:send(Socket, BinMsg),
State1 = State0#state{connection_states = ConnectionStates,
negotiated_version = Version, %% Requested version
diff --git a/lib/ssl/src/tls_record.erl b/lib/ssl/src/tls_record.erl
index aa524f0225..1e266ed424 100644
--- a/lib/ssl/src/tls_record.erl
+++ b/lib/ssl/src/tls_record.erl
@@ -41,8 +41,9 @@
-export([encode_plain_text/4]).
%% Protocol version handling
--export([protocol_version/1, lowest_protocol_version/2,
- highest_protocol_version/1, is_higher/2, supported_protocol_versions/0,
+-export([protocol_version/1, lowest_protocol_version/1, lowest_protocol_version/2,
+ highest_protocol_version/1, highest_protocol_version/2,
+ is_higher/2, supported_protocol_versions/0,
is_acceptable_version/1, is_acceptable_version/2]).
-export_type([tls_version/0, tls_atom_version/0]).
@@ -257,6 +258,18 @@ lowest_protocol_version(Version = {M,_},
Version;
lowest_protocol_version(_,Version) ->
Version.
+
+%%--------------------------------------------------------------------
+-spec lowest_protocol_version([tls_version()]) -> tls_version().
+%%
+%% Description: Lowest protocol version present in a list
+%%--------------------------------------------------------------------
+lowest_protocol_version([]) ->
+ lowest_protocol_version();
+lowest_protocol_version(Versions) ->
+ [Ver | Vers] = Versions,
+ lowest_list_protocol_version(Ver, Vers).
+
%%--------------------------------------------------------------------
-spec highest_protocol_version([tls_version()]) -> tls_version().
%%
@@ -266,19 +279,29 @@ highest_protocol_version([]) ->
highest_protocol_version();
highest_protocol_version(Versions) ->
[Ver | Vers] = Versions,
- highest_protocol_version(Ver, Vers).
+ highest_list_protocol_version(Ver, Vers).
-highest_protocol_version(Version, []) ->
+%%--------------------------------------------------------------------
+-spec highest_protocol_version(tls_version(), tls_version()) -> tls_version().
+%%
+%% Description: Highest protocol version of two given versions
+%%--------------------------------------------------------------------
+highest_protocol_version(Version = {M, N}, {M, O}) when N > O ->
+ Version;
+highest_protocol_version({M, _},
+ Version = {M, _}) ->
Version;
-highest_protocol_version(Version = {N, M}, [{N, O} | Rest]) when M > O ->
- highest_protocol_version(Version, Rest);
-highest_protocol_version({M, _}, [Version = {M, _} | Rest]) ->
- highest_protocol_version(Version, Rest);
-highest_protocol_version(Version = {M,_}, [{N,_} | Rest]) when M > N ->
- highest_protocol_version(Version, Rest);
-highest_protocol_version(_, [Version | Rest]) ->
- highest_protocol_version(Version, Rest).
+highest_protocol_version(Version = {M,_},
+ {N, _}) when M > N ->
+ Version;
+highest_protocol_version(_,Version) ->
+ Version.
+%%--------------------------------------------------------------------
+-spec is_higher(V1 :: tls_version(), V2::tls_version()) -> tls_version().
+%%
+%% Description: Is V1 > V2
+%%--------------------------------------------------------------------
is_higher({M, N}, {M, O}) when N > O ->
true;
is_higher({M, _}, {N, _}) when M > N ->
@@ -352,6 +375,17 @@ is_acceptable_version(_,_) ->
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
+
+lowest_list_protocol_version(Ver, []) ->
+ Ver;
+lowest_list_protocol_version(Ver1, [Ver2 | Rest]) ->
+ lowest_list_protocol_version(lowest_protocol_version(Ver1, Ver2), Rest).
+
+highest_list_protocol_version(Ver, []) ->
+ Ver;
+highest_list_protocol_version(Ver1, [Ver2 | Rest]) ->
+ highest_list_protocol_version(highest_protocol_version(Ver1, Ver2), Rest).
+
encode_tls_cipher_text(Type, {MajVer, MinVer}, Fragment) ->
Length = erlang:iolist_size(Fragment),
[<<?BYTE(Type), ?BYTE(MajVer), ?BYTE(MinVer), ?UINT16(Length)>>, Fragment].
@@ -370,6 +404,10 @@ mac_hash({3, N} = Version, MacAlg, MacSecret, SeqNo, Type, Length, Fragment)
highest_protocol_version() ->
highest_protocol_version(supported_protocol_versions()).
+lowest_protocol_version() ->
+ lowest_protocol_version(supported_protocol_versions()).
+
+
sufficient_tlsv1_2_crypto_support() ->
CryptoSupport = crypto:supports(),
proplists:get_bool(sha256, proplists:get_value(hashs, CryptoSupport)).
diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl
index 6f6107de2c..f032c769e2 100644
--- a/lib/ssl/test/ssl_basic_SUITE.erl
+++ b/lib/ssl/test/ssl_basic_SUITE.erl
@@ -35,7 +35,6 @@
-include("tls_record.hrl").
-include("tls_handshake.hrl").
--define('24H_in_sec', 86400).
-define(TIMEOUT, 20000).
-define(EXPIRE, 10).
-define(SLEEP, 500).
diff --git a/lib/ssl/test/ssl_dist_SUITE.erl b/lib/ssl/test/ssl_dist_SUITE.erl
index 72d62b29a7..092015d3d8 100644
--- a/lib/ssl/test/ssl_dist_SUITE.erl
+++ b/lib/ssl/test/ssl_dist_SUITE.erl
@@ -40,7 +40,8 @@
%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
all() ->
- [basic, payload, plain_options, plain_verify_options].
+ [basic, payload, plain_options, plain_verify_options, nodelay_option,
+ listen_port_options, listen_options, use_interface].
groups() ->
[].
@@ -250,6 +251,146 @@ plain_verify_options(Config) when is_list(Config) ->
stop_ssl_node(NH1),
stop_ssl_node(NH2),
success(Config).
+%%--------------------------------------------------------------------
+nodelay_option() ->
+ [{doc,"Test specifying dist_nodelay option"}].
+nodelay_option(Config) ->
+ try
+ %% The default is 'true', so try setting it to 'false'.
+ application:set_env(kernel, dist_nodelay, false),
+ basic(Config)
+ after
+ application:unset_env(kernel, dist_nodelay)
+ end.
+
+listen_port_options() ->
+ [{doc, "Test specifying listening ports"}].
+listen_port_options(Config) when is_list(Config) ->
+ %% Start a node, and get the port number it's listening on.
+ NH1 = start_ssl_node(Config),
+ Node1 = NH1#node_handle.nodename,
+ Name1 = lists:takewhile(fun(C) -> C =/= $@ end, atom_to_list(Node1)),
+ {ok, NodesPorts} = apply_on_ssl_node(NH1, fun net_adm:names/0),
+ {Name1, Port1} = lists:keyfind(Name1, 1, NodesPorts),
+
+ %% Now start a second node, configuring it to use the same port
+ %% number.
+ PortOpt1 = "-kernel inet_dist_listen_min " ++ integer_to_list(Port1) ++
+ " inet_dist_listen_max " ++ integer_to_list(Port1),
+
+ try start_ssl_node([{additional_dist_opts, PortOpt1} | Config]) of
+ #node_handle{} ->
+ %% If the node was able to start, it didn't take the port
+ %% option into account.
+ exit(unexpected_success)
+ catch
+ exit:{accept_failed, timeout} ->
+ %% The node failed to start, as expected.
+ ok
+ end,
+
+ %% Try again, now specifying a high max port.
+ PortOpt2 = "-kernel inet_dist_listen_min " ++ integer_to_list(Port1) ++
+ " inet_dist_listen_max 65535",
+ NH2 = start_ssl_node([{additional_dist_opts, PortOpt2} | Config]),
+ Node2 = NH2#node_handle.nodename,
+ Name2 = lists:takewhile(fun(C) -> C =/= $@ end, atom_to_list(Node2)),
+ {ok, NodesPorts2} = apply_on_ssl_node(NH2, fun net_adm:names/0),
+ {Name2, Port2} = lists:keyfind(Name2, 1, NodesPorts2),
+
+ %% The new port should be higher:
+ if Port2 > Port1 ->
+ ok;
+ true ->
+ error({port, Port2, not_higher_than, Port1})
+ end,
+
+ stop_ssl_node(NH1),
+ stop_ssl_node(NH2),
+ success(Config).
+%%--------------------------------------------------------------------
+listen_options() ->
+ [{doc, "Test inet_dist_listen_options"}].
+listen_options(Config) when is_list(Config) ->
+ Prio = 1,
+ case gen_udp:open(0, [{priority,Prio}]) of
+ {ok,Socket} ->
+ case inet:getopts(Socket, [priority]) of
+ {ok,[{priority,Prio}]} ->
+ ok = gen_udp:close(Socket),
+ do_listen_options(Prio, Config);
+ _ ->
+ ok = gen_udp:close(Socket),
+ {skip,
+ "Can not set priority "++integer_to_list(Prio)++
+ " on socket"}
+ end;
+ {error,_} ->
+ {skip, "Can not set priority on socket"}
+ end.
+
+do_listen_options(Prio, Config) ->
+ PriorityString0 = "[{priority,"++integer_to_list(Prio)++"}]",
+ PriorityString =
+ case os:cmd("echo [{a,1}]") of
+ "[{a,1}]"++_ ->
+ PriorityString0;
+ _ ->
+ %% Some shells need quoting of [{}]
+ "'"++PriorityString0++"'"
+ end,
+
+ Options = "-kernel inet_dist_listen_options " ++ PriorityString,
+
+ NH1 = start_ssl_node([{additional_dist_opts, Options} | Config]),
+ NH2 = start_ssl_node([{additional_dist_opts, Options} | Config]),
+ Node2 = NH2#node_handle.nodename,
+
+ pong = apply_on_ssl_node(NH1, fun () -> net_adm:ping(Node2) end),
+
+ PrioritiesNode1 =
+ apply_on_ssl_node(NH1, fun get_socket_priorities/0),
+ PrioritiesNode2 =
+ apply_on_ssl_node(NH2, fun get_socket_priorities/0),
+
+ Elevated1 = [P || P <- PrioritiesNode1, P =:= Prio],
+ ?t:format("Elevated1: ~p~n", [Elevated1]),
+ Elevated2 = [P || P <- PrioritiesNode2, P =:= Prio],
+ ?t:format("Elevated2: ~p~n", [Elevated2]),
+ [_|_] = Elevated1,
+ [_|_] = Elevated2,
+
+ stop_ssl_node(NH1),
+ stop_ssl_node(NH2),
+ success(Config).
+%%--------------------------------------------------------------------
+use_interface() ->
+ [{doc, "Test inet_dist_use_interface"}].
+use_interface(Config) when is_list(Config) ->
+ %% Force the node to listen only on the loopback interface.
+ IpString = "'{127,0,0,1}'",
+ Options = "-kernel inet_dist_use_interface " ++ IpString,
+
+ %% Start a node, and get the port number it's listening on.
+ NH1 = start_ssl_node([{additional_dist_opts, Options} | Config]),
+ Node1 = NH1#node_handle.nodename,
+ Name = lists:takewhile(fun(C) -> C =/= $@ end, atom_to_list(Node1)),
+ {ok, NodesPorts} = apply_on_ssl_node(NH1, fun net_adm:names/0),
+ {Name, Port} = lists:keyfind(Name, 1, NodesPorts),
+
+ %% Now find the socket listening on that port, and check its sockname.
+ Sockets = apply_on_ssl_node(
+ NH1,
+ fun() ->
+ [inet:sockname(P) ||
+ P <- erlang:ports(),
+ {ok, Port} =:= (catch inet:port(P))]
+ end),
+ %% And check that it's actually listening on localhost.
+ [{ok,{{127,0,0,1},Port}}] = Sockets,
+
+ stop_ssl_node(NH1),
+ success(Config).
%%--------------------------------------------------------------------
%%% Internal functions -----------------------------------------------
@@ -264,6 +405,12 @@ tstsrvr_format(Fmt, ArgList) ->
send_to_tstcntrl(Message) ->
send_to_tstsrvr({message, Message}).
+get_socket_priorities() ->
+ [Priority ||
+ {ok,[{priority,Priority}]} <-
+ [inet:getopts(Port, [priority]) ||
+ Port <- erlang:ports(),
+ element(2, erlang:port_info(Port, name)) =:= "tcp_inet"]].
%%
%% test_server side api
diff --git a/lib/ssl/test/ssl_session_cache_SUITE.erl b/lib/ssl/test/ssl_session_cache_SUITE.erl
index 924898f6fa..85345c814f 100644
--- a/lib/ssl/test/ssl_session_cache_SUITE.erl
+++ b/lib/ssl/test/ssl_session_cache_SUITE.erl
@@ -31,6 +31,7 @@
-define(SLEEP, 500).
-define(TIMEOUT, 60000).
-define(LONG_TIMEOUT, 600000).
+-define(MAX_TABLE_SIZE, 5).
-behaviour(ssl_session_cache_api).
@@ -46,7 +47,9 @@ all() ->
[session_cleanup,
session_cache_process_list,
session_cache_process_mnesia,
- client_unique_session].
+ client_unique_session,
+ max_table_size
+ ].
groups() ->
[].
@@ -92,7 +95,17 @@ init_per_testcase(session_cleanup, Config) ->
Config;
init_per_testcase(client_unique_session, Config) ->
- ct:timetrap({seconds, 20}),
+ ct:timetrap({seconds, 40}),
+ Config;
+
+init_per_testcase(max_table_size, Config) ->
+ ssl:stop(),
+ application:load(ssl),
+ application:set_env(ssl, session_cache_server_max, ?MAX_TABLE_SIZE),
+ application:set_env(ssl, session_cache_client_max, ?MAX_TABLE_SIZE),
+ application:set_env(ssl, session_delay_cleanup_time, ?DELAY),
+ ssl:start(),
+ ct:timetrap({seconds, 40}),
Config.
init_customized_session_cache(Type, Config) ->
@@ -122,6 +135,10 @@ end_per_testcase(session_cleanup, Config) ->
application:unset_env(ssl, session_delay_cleanup_time),
application:unset_env(ssl, session_lifetime),
end_per_testcase(default_action, Config);
+end_per_testcase(max_table_size, Config) ->
+ application:unset_env(ssl, session_cach_server_max),
+ application:unset_env(ssl, session_cach_client_max),
+ end_per_testcase(default_action, Config);
end_per_testcase(Case, Config) when Case == session_cache_process_list;
Case == session_cache_process_mnesia ->
ets:delete(ssl_test),
@@ -148,7 +165,7 @@ client_unique_session(Config) when is_list(Config) ->
{options, ServerOpts}]),
Port = ssl_test_lib:inet_port(Server),
LastClient = clients_start(Server,
- ClientNode, Hostname, Port, ClientOpts, 20),
+ ClientNode, Hostname, Port, ClientOpts, client_unique_session, 20),
receive
{LastClient, {ok, _}} ->
ok
@@ -157,7 +174,8 @@ client_unique_session(Config) when is_list(Config) ->
[_, _,_, _, Prop] = StatusInfo,
State = ssl_test_lib:state(Prop),
ClientCache = element(2, State),
- 1 = ets:info(ClientCache, size),
+
+ 1 = ssl_session_cache:size(ClientCache),
ssl_test_lib:close(Server, 500),
ssl_test_lib:close(LastClient).
@@ -223,35 +241,7 @@ session_cleanup(Config) when is_list(Config) ->
ssl_test_lib:close(Server),
ssl_test_lib:close(Client).
-check_timer(Timer) ->
- case erlang:read_timer(Timer) of
- false ->
- {status, _, _, _} = sys:get_status(whereis(ssl_manager)),
- timer:sleep(?SLEEP),
- {status, _, _, _} = sys:get_status(whereis(ssl_manager)),
- ok;
- Int ->
- ct:sleep(Int),
- check_timer(Timer)
- end.
-get_delay_timers() ->
- {status, _, _, StatusInfo} = sys:get_status(whereis(ssl_manager)),
- [_, _,_, _, Prop] = StatusInfo,
- State = ssl_test_lib:state(Prop),
- case element(8, State) of
- {undefined, undefined} ->
- ct:sleep(?SLEEP),
- get_delay_timers();
- {undefined, _} ->
- ct:sleep(?SLEEP),
- get_delay_timers();
- {_, undefined} ->
- ct:sleep(?SLEEP),
- get_delay_timers();
- DelayTimers ->
- DelayTimers
- end.
%%--------------------------------------------------------------------
session_cache_process_list() ->
[{doc,"Test reuse of sessions (short handshake)"}].
@@ -264,6 +254,42 @@ session_cache_process_mnesia(Config) when is_list(Config) ->
session_cache_process(mnesia,Config).
%%--------------------------------------------------------------------
+
+max_table_size() ->
+ [{doc,"Test max limit on session table"}].
+max_table_size(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ClientOpts = ?config(client_verification_opts, Config),
+ ServerOpts = ?config(server_verification_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {tcp_options, [{active, false}]},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ LastClient = clients_start(Server,
+ ClientNode, Hostname, Port, ClientOpts, max_table_size, 20),
+ receive
+ {LastClient, {ok, _}} ->
+ ok
+ end,
+ ct:sleep(1000),
+ {status, _, _, StatusInfo} = sys:get_status(whereis(ssl_manager)),
+ [_, _,_, _, Prop] = StatusInfo,
+ State = ssl_test_lib:state(Prop),
+ ClientCache = element(2, State),
+ ServerCache = element(3, State),
+ N = ssl_session_cache:size(ServerCache),
+ M = ssl_session_cache:size(ClientCache),
+ ct:pal("~p",[{N, M}]),
+ ssl_test_lib:close(Server, 500),
+ ssl_test_lib:close(LastClient),
+ true = N =< ?MAX_TABLE_SIZE,
+ true = M =< ?MAX_TABLE_SIZE.
+
+%%--------------------------------------------------------------------
%%% Session cache API callbacks
%%--------------------------------------------------------------------
@@ -403,21 +429,73 @@ session_cache_process(_Type,Config) when is_list(Config) ->
ssl_basic_SUITE:reuse_session(Config).
-clients_start(_Server, ClientNode, Hostname, Port, ClientOpts, 0) ->
+clients_start(_Server, ClientNode, Hostname, Port, ClientOpts, Test, 0) ->
%% Make sure session is registered
ct:sleep(?SLEEP * 2),
ssl_test_lib:start_client([{node, ClientNode},
{port, Port}, {host, Hostname},
{mfa, {?MODULE, connection_info_result, []}},
- {from, self()}, {options, ClientOpts}]);
-clients_start(Server, ClientNode, Hostname, Port, ClientOpts, N) ->
+ {from, self()}, {options, test_copts(Test, 0, ClientOpts)}]);
+clients_start(Server, ClientNode, Hostname, Port, ClientOpts, Test, N) ->
spawn_link(ssl_test_lib, start_client,
[[{node, ClientNode},
{port, Port}, {host, Hostname},
{mfa, {ssl_test_lib, no_result, []}},
- {from, self()}, {options, ClientOpts}]]),
+ {from, self()}, {options, test_copts(Test, N, ClientOpts)}]]),
Server ! listen,
- clients_start(Server, ClientNode, Hostname, Port, ClientOpts, N-1).
+ wait_for_server(),
+ clients_start(Server, ClientNode, Hostname, Port, ClientOpts, Test, N-1).
connection_info_result(Socket) ->
ssl:connection_information(Socket, [protocol, cipher_suite]).
+
+check_timer(Timer) ->
+ case erlang:read_timer(Timer) of
+ false ->
+ {status, _, _, _} = sys:get_status(whereis(ssl_manager)),
+ timer:sleep(?SLEEP),
+ {status, _, _, _} = sys:get_status(whereis(ssl_manager)),
+ ok;
+ Int ->
+ ct:sleep(Int),
+ check_timer(Timer)
+ end.
+
+get_delay_timers() ->
+ {status, _, _, StatusInfo} = sys:get_status(whereis(ssl_manager)),
+ [_, _,_, _, Prop] = StatusInfo,
+ State = ssl_test_lib:state(Prop),
+ case element(8, State) of
+ {undefined, undefined} ->
+ ct:sleep(?SLEEP),
+ get_delay_timers();
+ {undefined, _} ->
+ ct:sleep(?SLEEP),
+ get_delay_timers();
+ {_, undefined} ->
+ ct:sleep(?SLEEP),
+ get_delay_timers();
+ DelayTimers ->
+ DelayTimers
+ end.
+
+wait_for_server() ->
+ ct:sleep(100).
+
+
+test_copts(_, 0, ClientOpts) ->
+ ClientOpts;
+test_copts(max_table_size, N, ClientOpts) ->
+ Version = tls_record:highest_protocol_version([]),
+ CipherSuites = %%lists:map(fun(X) -> ssl_cipher:suite_definition(X) end, ssl_cipher:filter_suites(ssl_cipher:suites(Version))),
+[ Y|| Y = {Alg,_, _, _} <- lists:map(fun(X) -> ssl_cipher:suite_definition(X) end, ssl_cipher:filter_suites(ssl_cipher:suites(Version))), Alg =/= ecdhe_ecdsa, Alg =/= ecdh_ecdsa, Alg =/= ecdh_rsa, Alg =/= ecdhe_rsa, Alg =/= dhe_dss, Alg =/= dss],
+ case length(CipherSuites) of
+ M when M >= N ->
+ Cipher = lists:nth(N, CipherSuites),
+ ct:pal("~p",[Cipher]),
+ [{ciphers, [Cipher]} | ClientOpts];
+ _ ->
+ ClientOpts
+ end;
+test_copts(_, _, ClientOpts) ->
+ ClientOpts.
diff --git a/lib/stdlib/doc/src/array.xml b/lib/stdlib/doc/src/array.xml
index 28b4435938..0f33e2621c 100644
--- a/lib/stdlib/doc/src/array.xml
+++ b/lib/stdlib/doc/src/array.xml
@@ -164,7 +164,7 @@ the default value cannot be confused with the values of set entries.</p>
</fsummary>
<desc><marker id="from_list-1"/>
-<p>Equivalent to <seealso marker="#from_list-2">from_list(<anno>List</anno>, undefined)</seealso>.</p>
+<p>Equivalent to <seealso marker="#from_list-2">from_list(<c><anno>List</anno></c>, undefined)</seealso>.</p>
</desc></func>
<func>
<name name="from_list" arity="2"/>
@@ -184,7 +184,7 @@ the default value cannot be confused with the values of set entries.</p>
</fsummary>
<desc><marker id="from_orddict-1"/>
-<p>Equivalent to <seealso marker="#from_orddict-2">from_orddict(<anno>Orddict</anno>, undefined)</seealso>.</p>
+<p>Equivalent to <seealso marker="#from_orddict-2">from_orddict(<c><anno>Orddict</anno></c>, undefined)</seealso>.</p>
</desc></func>
<func>
<name name="from_orddict" arity="2"/>
diff --git a/lib/stdlib/doc/src/assert_hrl.xml b/lib/stdlib/doc/src/assert_hrl.xml
index b85be514d8..ef4f928e57 100644
--- a/lib/stdlib/doc/src/assert_hrl.xml
+++ b/lib/stdlib/doc/src/assert_hrl.xml
@@ -77,9 +77,6 @@ erlc -DNOASSERT=true *.erl</code>
</description>
<section>
- </section>
-
- <section>
<title>Macros</title>
<taglist>
<tag><c>assert(BoolExpr)</c></tag>
@@ -94,12 +91,12 @@ erlc -DNOASSERT=true *.erl</code>
<tag><c>assertMatch(GuardedPattern, Expr)</c></tag>
<item><p>Tests that <c>Expr</c> completes normally yielding a value
- that matches <c>GuardedPattern</c>. For example:
+ that matches <c>GuardedPattern</c>. For example:</p>
<code type="none">
- ?assertMatch({bork, _}, f())</code></p>
- <p>Note that a guard <c>when ...</c> can be included:
+ ?assertMatch({bork, _}, f())</code>
+ <p>Note that a guard <c>when ...</c> can be included:</p>
<code type="none">
- ?assertMatch({bork, X} when X > 0, f())</code></p>
+ ?assertMatch({bork, X} when X > 0, f())</code>
</item>
<tag><c>assertNotMatch(GuardedPattern, Expr)</c></tag>
diff --git a/lib/stdlib/doc/src/beam_lib.xml b/lib/stdlib/doc/src/beam_lib.xml
index c556180b8b..7c89c8b43e 100644
--- a/lib/stdlib/doc/src/beam_lib.xml
+++ b/lib/stdlib/doc/src/beam_lib.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2000</year><year>2013</year>
+ <year>2000</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -71,6 +71,7 @@
using <seealso marker="#strip/1">strip/1</seealso>,
<seealso marker="#strip_files/1">strip_files/1</seealso> and/or
<seealso marker="#strip_release/1">strip_release/1</seealso>.</p>
+ </section>
<section>
<title>Reconstructing source code</title>
<p>Here is an example of how to reconstruct source code from
@@ -152,7 +153,6 @@
keys.</p>
</note>
</section>
- </section>
<datatypes>
<datatype>
@@ -224,6 +224,13 @@
<funcs>
<func>
+ <name name="all_chunks" arity="1"/>
+ <fsummary>Read all chunks from a BEAM file or binary</fsummary>
+ <desc>
+ <p>Reads chunk data for all chunks.</p>
+ </desc>
+ </func>
+ <func>
<name name="chunks" arity="2"/>
<fsummary>Read selected chunks from a BEAM file or binary</fsummary>
<desc>
@@ -251,6 +258,13 @@
</desc>
</func>
<func>
+ <name name="build_module" arity="1"/>
+ <fsummary>Creates a BEAM module from a list of chunks</fsummary>
+ <desc>
+ <p>Builds a BEAM module (as a binary) from a list of chunks.</p>
+ </desc>
+ </func>
+ <func>
<name name="version" arity="1"/>
<fsummary>Read the BEAM file's module version</fsummary>
<desc>
diff --git a/lib/stdlib/doc/src/binary.xml b/lib/stdlib/doc/src/binary.xml
index 063f3048e0..2682198fe5 100644
--- a/lib/stdlib/doc/src/binary.xml
+++ b/lib/stdlib/doc/src/binary.xml
@@ -299,8 +299,8 @@
</func>
<func>
<name name="match" arity="3"/>
- <type name="part"/>
<fsummary>Searches for the first match of a pattern in a binary</fsummary>
+ <type name="part"/>
<desc>
<p>Searches for the first occurrence of <c><anno>Pattern</anno></c> in <c><anno>Subject</anno></c> and
@@ -353,8 +353,8 @@
</func>
<func>
<name name="matches" arity="3"/>
- <type name="part"/>
<fsummary>Searches for all matches of a pattern in a binary</fsummary>
+ <type name="part"/>
<desc>
<p>Works like <c>match/2</c>, but the <c><anno>Subject</anno></c> is searched until
diff --git a/lib/stdlib/doc/src/c.xml b/lib/stdlib/doc/src/c.xml
index a0f18bd899..e5238fa7db 100644
--- a/lib/stdlib/doc/src/c.xml
+++ b/lib/stdlib/doc/src/c.xml
@@ -121,12 +121,12 @@ compile:file(<anno>File</anno>, <anno>Options</anno> ++ [report_errors, report_w
</func>
<func>
<name>lc(Files) -> ok</name>
+ <fsummary>Compile a list of files</fsummary>
<type>
<v>Files = [File]</v>
<v>File = <seealso marker="file#type-filename">file:filename()
</seealso></v>
</type>
- <fsummary>Compile a list of files</fsummary>
<desc>
<p>Compiles a list of files by calling <c>compile:file(File, [report_errors, report_warnings])</c> for each <c>File</c>
in <c>Files</c>.</p>
diff --git a/lib/stdlib/doc/src/calendar.xml b/lib/stdlib/doc/src/calendar.xml
index a8d933dc83..853184dc0f 100644
--- a/lib/stdlib/doc/src/calendar.xml
+++ b/lib/stdlib/doc/src/calendar.xml
@@ -130,11 +130,11 @@
<func>
<name name="date_to_gregorian_days" arity="1"/>
<name name="date_to_gregorian_days" arity="3"/>
+ <fsummary>Compute the number of days from year 0 up to the given date</fsummary>
<type variable="Date" name_i="1"/>
<type variable="Year"/>
<type variable="Month"/>
<type variable="Day"/>
- <fsummary>Compute the number of days from year 0 up to the given date</fsummary>
<desc>
<p>This function computes the number of gregorian days starting
with year 0 and ending at the given date.</p>
@@ -347,11 +347,11 @@
<func>
<name name="valid_date" arity="1"/>
<name name="valid_date" arity="3"/>
+ <fsummary>Check if a date is valid</fsummary>
<type variable="Date" name_i="1"/>
<type variable="Year"/>
<type variable="Month"/>
<type variable="Day"/>
- <fsummary>Check if a date is valid</fsummary>
<desc>
<p>This function checks if a date is a valid.</p>
</desc>
diff --git a/lib/stdlib/doc/src/dets.xml b/lib/stdlib/doc/src/dets.xml
index 14237b6f90..a0d3f95b6a 100644
--- a/lib/stdlib/doc/src/dets.xml
+++ b/lib/stdlib/doc/src/dets.xml
@@ -316,20 +316,20 @@
bytes.</p>
</item>
<item>
- <p><c>{filename, <seealso marker="file#type-name">file:name()</seealso>}</c>,
+ <p><c>{filename, </c><seealso marker="file#type-name">file:name()</seealso><c>}</c>,
the name of the file where objects are stored.</p>
</item>
<item>
- <p><c>{keypos, <seealso marker="#type-keypos">keypos()</seealso>}
- </c>, the position of the key.</p>
+ <p><c>{keypos, </c><seealso marker="#type-keypos">keypos()</seealso>
+ <c>}</c>, the position of the key.</p>
</item>
<item>
<p><c>{size, integer() >= 0}</c>, the number of objects stored
in the table.</p>
</item>
<item>
- <p><c>{type, <seealso marker="#type-type">type()</seealso>}</c>,
- the type of the table.</p>
+ <p><c>{type, </c><seealso marker="#type-type">type()</seealso>
+ <c>}</c>, the type of the table.</p>
</item>
</list>
</desc>
@@ -345,12 +345,12 @@
allowed:</p>
<list type="bulleted">
<item>
- <p><c>{access, <seealso marker="#type-access">access()</seealso>}
- </c>, the access mode.</p>
+ <p><c>{access, </c><seealso marker="#type-access">access()</seealso>
+ <c>}</c>, the access mode.</p>
</item>
<item>
- <p><c>{auto_save, <seealso marker="#type-auto_save">
- auto_save()</seealso>}</c>, the auto save interval.</p>
+ <p><c>{auto_save, </c><seealso marker="#type-auto_save">
+ auto_save()</seealso><c>}</c>, the auto save interval.</p>
</item>
<item>
<p><c>{bchunk_format, binary()}</c>, an opaque binary
@@ -730,16 +730,16 @@ ok
tuples where the following values are allowed:</p>
<list type="bulleted">
<item>
- <p><c>{access, <seealso marker="#type-access">
- access()</seealso>}</c>. It is possible to open
+ <p><c>{access, </c><seealso marker="#type-access">
+ access()</seealso><c>}</c>. It is possible to open
existing tables in read-only mode. A table which is opened
in read-only mode is not subjected to the automatic file
reparation algorithm if it is later opened after a crash.
The default value is <c>read_write</c>.</p>
</item>
<item>
- <p><c>{auto_save, <seealso marker="#type-auto_save">
- auto_save()</seealso>}</c>, the auto save
+ <p><c>{auto_save, </c><seealso marker="#type-auto_save">
+ auto_save()</seealso><c>}</c>, the auto save
interval. If the interval is an integer <c>Time</c>, the
table is flushed to disk whenever it is not accessed for
<c>Time</c> milliseconds. A table that has been flushed
@@ -749,18 +749,18 @@ ok
is 180000 (3 minutes).</p>
</item>
<item>
- <p><c>{estimated_no_objects, <seealso marker="#type-no_slots">
- no_slots()</seealso>}</c>. Equivalent to the
+ <p><c>{estimated_no_objects, </c><seealso marker="#type-no_slots">
+ no_slots()</seealso><c>}</c>. Equivalent to the
<c>min_no_slots</c> option.</p>
</item>
<item>
- <p><c>{file, <seealso marker="file#type-name">
- file:name()</seealso>}</c>, the name of the file to be
+ <p><c>{file, </c><seealso marker="file#type-name">
+ file:name()</seealso><c>}</c>, the name of the file to be
opened. The default value is the name of the table.</p>
</item>
<item>
- <p><c>{max_no_slots, <seealso marker="#type-no_slots">
- no_slots()</seealso>}</c>, the maximum number
+ <p><c>{max_no_slots, </c><seealso marker="#type-no_slots">
+ no_slots()</seealso><c>}</c>, the maximum number
of slots that will be used. The default value as well as
the maximal value is 32 M. Note that a higher value may
increase the fragmentation of the table, and conversely,
@@ -769,16 +769,16 @@ ok
9 tables.</p>
</item>
<item>
- <p><c>{min_no_slots, <seealso marker="#type-no_slots">
- no_slots()</seealso>}</c>. Application
+ <p><c>{min_no_slots, </c><seealso marker="#type-no_slots">
+ no_slots()</seealso><c>}</c>. Application
performance can be enhanced with this flag by specifying,
when the table is created, the estimated number of
different keys that will be stored in the table. The
default value as well as the minimum value is 256.</p>
</item>
<item>
- <p><c>{keypos, <seealso marker="#type-keypos">
- keypos()</seealso>}</c>, the position of the
+ <p><c>{keypos, </c><seealso marker="#type-keypos">
+ keypos()</seealso><c>}</c>, the position of the
element of each object to be used as key. The default
value is 1. The ability to explicitly state the key
position is most convenient when we want to store Erlang
@@ -815,12 +815,12 @@ ok
already open.</p>
</item>
<item>
- <p><c>{type, <seealso marker="#type-type">type()</seealso>}</c>,
+ <p><c>{type, </c><seealso marker="#type-type">type()</seealso><c>}</c>,
the type of the table. The default value is <c>set</c>.</p>
</item>
<item>
- <p><c>{version, <seealso marker="#type-version">
- version()</seealso>}</c>, the version of the format
+ <p><c>{version, </c><seealso marker="#type-version">
+ version()</seealso><c>}</c>, the version of the format
used for the table. The default value is <c>9</c>. Tables
on the format used before OTP R8 can be created by giving
the value <c>8</c>. A version 8 table can be converted to
@@ -1036,8 +1036,8 @@ ok
specification that matches all objects.</p>
</item>
<item>
- <p><c>{select, <seealso marker="#type-match_spec">
- match_spec()}</seealso></c>. As for <c>select</c>
+ <p><c>{select, </c><seealso marker="#type-match_spec">
+ match_spec()</seealso><c>}</c>. As for <c>select</c>
the table is traversed by calling <c>dets:select/3</c>
and <c>dets:select/1</c>. The difference is that the
match specification is explicitly given. This is how to
diff --git a/lib/stdlib/doc/src/digraph.xml b/lib/stdlib/doc/src/digraph.xml
index 49dc68e103..291be6c08b 100644
--- a/lib/stdlib/doc/src/digraph.xml
+++ b/lib/stdlib/doc/src/digraph.xml
@@ -103,13 +103,15 @@
<desc><p>A digraph as returned by <c>new/0,1</c>.</p></desc>
</datatype>
<datatype>
- <name><marker id="type-edge">edge()</marker></name>
+ <name>edge()</name>
+ <desc><p><marker id="type-edge"/></p></desc>
</datatype>
<datatype>
<name name="label"/>
</datatype>
<datatype>
- <name><marker id="type-vertex">vertex()</marker></name>
+ <name>vertex()</name>
+ <desc><p><marker id="type-vertex"/></p></desc>
</datatype>
</datatypes>
<funcs>
diff --git a/lib/stdlib/doc/src/digraph_utils.xml b/lib/stdlib/doc/src/digraph_utils.xml
index 6a4db2e963..639069543c 100644
--- a/lib/stdlib/doc/src/digraph_utils.xml
+++ b/lib/stdlib/doc/src/digraph_utils.xml
@@ -122,8 +122,9 @@
<datatypes>
<datatype>
- <name><marker id="type-digraph">digraph()</marker></name>
- <desc><p>A digraph as returned by <c>digraph:new/0,1</c>.</p></desc>
+ <name>digraph()</name>
+ <desc><p><marker id="type-digraph"/>
+ A digraph as returned by <c>digraph:new/0,1</c>.</p></desc>
</datatype>
</datatypes>
<funcs>
diff --git a/lib/stdlib/doc/src/epp.xml b/lib/stdlib/doc/src/epp.xml
index fe2944bbf7..8c901f57ec 100644
--- a/lib/stdlib/doc/src/epp.xml
+++ b/lib/stdlib/doc/src/epp.xml
@@ -39,7 +39,7 @@
by <c>compile</c> to preprocess macros and include files before
the actual parsing takes place.</p>
<p>The Erlang source file <marker
- id="encoding"><em>encoding</em></marker> is selected by a
+ id="encoding"/><em>encoding</em> is selected by a
comment in one of the first two lines of the source file. The
first string that matches the regular expression
<c>coding\s*[:=]\s*([-a-zA-Z0-9])+</c> selects the encoding. If
diff --git a/lib/stdlib/doc/src/erl_anno.xml b/lib/stdlib/doc/src/erl_anno.xml
index be0ffe6f4d..ddc8b8c765 100644
--- a/lib/stdlib/doc/src/erl_anno.xml
+++ b/lib/stdlib/doc/src/erl_anno.xml
@@ -44,7 +44,7 @@
<p>This module implements an abstract type that is used by the
Erlang Compiler and its helper modules for holding data such as
column, line number, and text. The data type is a collection of
- <marker id="annotations"><em>annotations</em></marker> as
+ <marker id="annotations"/><em>annotations</em> as
described in the following.</p>
<p>The Erlang Token Scanner returns tokens with a subset of
the following annotations, depending on the options:</p>
@@ -102,8 +102,8 @@
<datatypes>
<datatype>
- <name><marker id="type-anno">anno()</marker></name>
- <desc><p>A collection of annotations.</p>
+ <name>anno()</name>
+ <desc><p><marker id="type-anno"/>A collection of annotations.</p>
</desc>
</datatype>
<datatype>
@@ -133,8 +133,8 @@
<funcs>
<func>
<name name="column" arity="1"/>
- <type name="column"></type>
<fsummary>Return the column</fsummary>
+ <type name="column"></type>
<desc>
<p>Returns the column of the annotations <anno>Anno</anno>.
</p>
@@ -142,8 +142,8 @@
</func>
<func>
<name name="end_location" arity="1"/>
- <type name="location"></type>
<fsummary>Return the end location of the text</fsummary>
+ <type name="location"></type>
<desc>
<p>Returns the end location of the text of the
annotations <anno>Anno</anno>. If there is no text,
@@ -153,8 +153,8 @@
</func>
<func>
<name name="file" arity="1"/>
- <type name="filename"></type>
<fsummary>Return the filename</fsummary>
+ <type name="filename"></type>
<desc>
<p>Returns the filename of the annotations <anno>Anno</anno>.
If there is no filename, <c>undefined</c> is returned.
@@ -180,8 +180,8 @@
</func>
<func>
<name name="generated" arity="1"/>
- <type name="generated"></type>
<fsummary>Return the generated Boolean</fsummary>
+ <type name="generated"></type>
<desc>
<p>Returns <c>true</c> if the annotations <anno>Anno</anno>
has been marked as generated. The default is to return
@@ -199,8 +199,8 @@
</func>
<func>
<name name="line" arity="1"/>
- <type name="line"></type>
<fsummary>Return the line</fsummary>
+ <type name="line"></type>
<desc>
<p>Returns the line of the annotations <anno>Anno</anno>.
</p>
@@ -208,8 +208,8 @@
</func>
<func>
<name name="location" arity="1"/>
- <type name="location"></type>
<fsummary>Return the location</fsummary>
+ <type name="location"></type>
<desc>
<p>Returns the location of the annotations <anno>Anno</anno>.
</p>
@@ -217,16 +217,16 @@
</func>
<func>
<name name="new" arity="1"/>
- <type name="location"></type>
<fsummary>Create a new collection of annotations</fsummary>
+ <type name="location"></type>
<desc>
<p>Creates a new collection of annotations given a location.</p>
</desc>
</func>
<func>
<name name="set_file" arity="2"/>
- <type name="filename"></type>
<fsummary>Modify the filename</fsummary>
+ <type name="filename"></type>
<desc>
<p>Modifies the filename of the annotations <anno>Anno</anno>.
</p>
@@ -234,8 +234,8 @@
</func>
<func>
<name name="set_generated" arity="2"/>
- <type name="generated"></type>
<fsummary>Modify the generated marker</fsummary>
+ <type name="generated"></type>
<desc>
<p>Modifies the generated marker of the annotations
<anno>Anno</anno>.
@@ -244,8 +244,8 @@
</func>
<func>
<name name="set_line" arity="2"/>
- <type name="line"></type>
<fsummary>Modify the line</fsummary>
+ <type name="line"></type>
<desc>
<p>Modifies the line of the annotations <anno>Anno</anno>.
</p>
@@ -253,8 +253,8 @@
</func>
<func>
<name name="set_location" arity="2"/>
- <type name="location"></type>
<fsummary>Modify the location</fsummary>
+ <type name="location"></type>
<desc>
<p>Modifies the location of the annotations <anno>Anno</anno>.
</p>
@@ -262,8 +262,8 @@
</func>
<func>
<name name="set_record" arity="2"/>
- <type name="record"></type>
<fsummary>Modify the record marker</fsummary>
+ <type name="record"></type>
<desc>
<p>Modifies the record marker of the annotations <anno>Anno</anno>.
</p>
@@ -271,8 +271,8 @@
</func>
<func>
<name name="set_text" arity="2"/>
- <type name="text"></type>
<fsummary>Modify the text</fsummary>
+ <type name="text"></type>
<desc>
<p>Modifies the text of the annotations <anno>Anno</anno>.
</p>
@@ -280,8 +280,8 @@
</func>
<func>
<name name="text" arity="1"/>
- <type name="text"></type>
<fsummary>Return the text</fsummary>
+ <type name="text"></type>
<desc>
<p>Returns the text of the annotations <anno>Anno</anno>.
If there is no text, <c>undefined</c> is returned.
diff --git a/lib/stdlib/doc/src/erl_parse.xml b/lib/stdlib/doc/src/erl_parse.xml
index fdd776b7f1..0938b5dec3 100644
--- a/lib/stdlib/doc/src/erl_parse.xml
+++ b/lib/stdlib/doc/src/erl_parse.xml
@@ -174,8 +174,8 @@
</func>
<func>
<name name="abstract" arity="2"/>
- <type name="encoding_func"/>
<fsummary>Convert an Erlang term into an abstract form</fsummary>
+ <type name="encoding_func"/>
<desc>
<p>Converts the Erlang data structure <c><anno>Data</anno></c> into an
abstract form of type <c><anno>AbsTerm</anno></c>.</p>
diff --git a/lib/stdlib/doc/src/erl_pp.xml b/lib/stdlib/doc/src/erl_pp.xml
index c9d9e2723d..4b8a571c81 100644
--- a/lib/stdlib/doc/src/erl_pp.xml
+++ b/lib/stdlib/doc/src/erl_pp.xml
@@ -48,8 +48,8 @@
<datatype>
<name name="hook_function"/>
<desc>
- <p>The optional argument <marker id="hook_function">
- <c>HookFunction</c></marker>, shown in the functions described below,
+ <p>The optional argument <marker id="hook_function"/>
+ <c>HookFunction</c>, shown in the functions described below,
defines a function which is called when an unknown form occurs where there
should be a valid expression.</p>
diff --git a/lib/stdlib/doc/src/erl_scan.xml b/lib/stdlib/doc/src/erl_scan.xml
index 18e988e286..342f491dd0 100644
--- a/lib/stdlib/doc/src/erl_scan.xml
+++ b/lib/stdlib/doc/src/erl_scan.xml
@@ -181,10 +181,10 @@
<func>
<name name="tokens" arity="3"/>
<name name="tokens" arity="4"/>
+ <fsummary>Re-entrant scanner</fsummary>
<type name="char_spec"/>
<type name="return_cont"/>
<type_desc name="return_cont">An opaque continuation</type_desc>
- <fsummary>Re-entrant scanner</fsummary>
<desc>
<p>This is the re-entrant scanner which scans characters until
a <em>dot</em> ('.' followed by a white space) or
@@ -324,9 +324,9 @@
<func>
<name name="token_info" arity="2" clause_i="1"/>
<name name="token_info" arity="2" clause_i="2"/>
+ <fsummary>Return information about a token</fsummary>
<type name="token_item"/>
<type name="attribute_item"/>
- <fsummary>Return information about a token</fsummary>
<desc>
<p>Returns a list containing information about the token
<c><anno>Token</anno></c>. If one single
@@ -345,28 +345,28 @@
<p>The following <c><anno>TokenInfoTuple</anno></c>s with corresponding
<c><anno>TokenItem</anno></c>s are valid:</p>
<taglist>
- <tag><c>{category, <seealso marker="#type-category">
- category()</seealso>}</c></tag>
+ <tag><c>{category, </c><seealso marker="#type-category">
+ category()</seealso><c>}</c></tag>
<item><p>The category of the token.</p>
</item>
- <tag><c>{column, <seealso marker="#type-column">
- column()</seealso>}</c></tag>
+ <tag><c>{column, </c><seealso marker="#type-column">
+ column()</seealso><c>}</c></tag>
<item><p>The column where the token begins.</p>
</item>
<tag><c>{length, integer() > 0}</c></tag>
<item><p>The length of the token's text.</p>
</item>
- <tag><c>{line, <seealso marker="#type-line">
- line()</seealso>}</c></tag>
+ <tag><c>{line, </c><seealso marker="#type-line">
+ line()</seealso><c>}</c></tag>
<item><p>The line where the token begins.</p>
</item>
- <tag><c>{location, <seealso marker="#type-location">
- location()</seealso>}</c></tag>
+ <tag><c>{location, </c><seealso marker="#type-location">
+ location()</seealso><c>}</c></tag>
<item><p>The line and column where the token begins, or
just the line if the column unknown.</p>
</item>
- <tag><c>{symbol, <seealso marker="#type-symbol">
- symbol()</seealso>}</c></tag>
+ <tag><c>{symbol, </c><seealso marker="#type-symbol">
+ symbol()</seealso><c>}</c></tag>
<item><p>The token's symbol.</p>
</item>
<tag><c>{text, string()}</c></tag>
@@ -416,19 +416,19 @@
<p>The following <c><anno>AttributeInfoTuple</anno></c>s with
corresponding <c><anno>AttributeItem</anno></c>s are valid:</p>
<taglist>
- <tag><c>{column, <seealso marker="#type-column">
- column()</seealso>}</c></tag>
+ <tag><c>{column, </c><seealso marker="#type-column">
+ column()</seealso><c>}</c></tag>
<item><p>The column where the token begins.</p>
</item>
<tag><c>{length, integer() > 0}</c></tag>
<item><p>The length of the token's text.</p>
</item>
- <tag><c>{line, <seealso marker="#type-line">
- line()</seealso>}</c></tag>
+ <tag><c>{line, </c><seealso marker="#type-line">
+ line()</seealso><c>}</c></tag>
<item><p>The line where the token begins.</p>
</item>
- <tag><c>{location, <seealso marker="#type-location">
- location()</seealso>}</c></tag>
+ <tag><c>{location, </c><seealso marker="#type-location">
+ location()</seealso><c>}</c></tag>
<item><p>The line and column where the token begins, or
just the line if the column unknown.</p>
</item>
diff --git a/lib/stdlib/doc/src/erl_tar.xml b/lib/stdlib/doc/src/erl_tar.xml
index 0fa5a55c5b..898b55df72 100644
--- a/lib/stdlib/doc/src/erl_tar.xml
+++ b/lib/stdlib/doc/src/erl_tar.xml
@@ -442,7 +442,7 @@
structure like a file descriptor, a sftp channel id or such. The different <c>Fun</c>
clauses operates on that very term.
</p>
- <p>The fun clauses parameter lists are:
+ <p>The fun clauses parameter lists are:</p>
<taglist>
<tag><c>(write, {UserPrivate,DataToWrite})</c></tag>
<item>Write the term <c>DataToWrite</c> using <c>UserPrivate</c></item>
@@ -457,7 +457,6 @@
<tag><c></c></tag>
<item></item>
</taglist>
- </p>
<p>A complete <c>Fun</c> parameter for reading and writing on files using the
<seealso marker="kernel:file">file module</seealso> could be:
</p>
diff --git a/lib/stdlib/doc/src/ets.xml b/lib/stdlib/doc/src/ets.xml
index 03b995e4de..7b01109ff8 100644
--- a/lib/stdlib/doc/src/ets.xml
+++ b/lib/stdlib/doc/src/ets.xml
@@ -132,9 +132,10 @@
<name name="access"/>
</datatype>
<datatype>
- <name><marker id="type-continuation">continuation()</marker></name>
+ <name>continuation()</name>
<desc>
- <p>Opaque continuation used by <seealso marker="#select/1">
+ <p><marker id="type-continuation"/>
+ Opaque continuation used by <seealso marker="#select/1">
<c>select/1,3</c></seealso>, <seealso marker="#select_reverse/1">
<c>select_reverse/1,3</c></seealso>, <seealso
marker="#match/1">
@@ -448,13 +449,13 @@ Error: fun containing local Erlang function calls
<item><c>{owner, pid()}</c> <br></br>
The pid of the owner of the table.</item>
- <item><c>{protection, <seealso marker="#type-access">access()</seealso>}</c> <br></br>
+ <item><c>{protection, </c><seealso marker="#type-access">access()</seealso><c>}</c> <br></br>
The table access rights.</item>
<item><c>{size, integer() >= 0</c> <br></br>
The number of objects inserted in the table.</item>
- <item><c>{type, <seealso marker="#type-type">type()</seealso>}</c> <br></br>
+ <item><c>{type, </c><seealso marker="#type-type">type()</seealso><c>}</c> <br></br>
The table type.</item>
<item><c>{read_concurrency, boolean()}</c> <br></br>
@@ -916,7 +917,7 @@ ets:select(Table,MatchSpec),</code>
</item>
<item>
<p><c>{keypos,<anno>Pos</anno>}</c>
- Specfies which element in the stored tuples should be
+ Specifies which element in the stored tuples should be
used as key. By default, it is the first element, i.e.
<c><anno>Pos</anno>=1</c>. However, this is not always appropriate. In
particular, we do not want the first element to be the
@@ -1626,6 +1627,7 @@ true</pre>
<name name="update_counter" arity="4" clause_i="2"/>
<name name="update_counter" arity="3" clause_i="3"/>
<name name="update_counter" arity="4" clause_i="3"/>
+ <fsummary>Update a counter object in an ETS table.</fsummary>
<type variable="Tab"/>
<type variable="Key"/>
<type variable="UpdateOp" name_i="1"/>
@@ -1633,7 +1635,6 @@ true</pre>
<type variable="Threshold" name_i="1"/>
<type variable="SetValue" name_i="1"/>
<type variable="Default"/>
- <fsummary>Update a counter object in an ETS table.</fsummary>
<desc>
<p>This function provides an efficient way to update one or more
counters, without the hassle of having to look up an object, update
@@ -1700,11 +1701,11 @@ true</pre>
<func>
<name name="update_element" arity="3" clause_i="1"/>
<name name="update_element" arity="3" clause_i="2"/>
+ <fsummary>Updates the <c>Pos</c>:th element of the object with a given key in an ETS table.</fsummary>
<type variable="Tab"/>
<type variable="Key"/>
<type variable="Value"/>
<type variable="Pos"/>
- <fsummary>Updates the <c>Pos</c>:th element of the object with a given key in an ETS table.</fsummary>
<desc>
<p>This function provides an efficient way to update one or more
elements within an object, without the hassle of having to look up,
diff --git a/lib/stdlib/doc/src/file_sorter.xml b/lib/stdlib/doc/src/file_sorter.xml
index 30e09c17b0..f033eebec7 100644
--- a/lib/stdlib/doc/src/file_sorter.xml
+++ b/lib/stdlib/doc/src/file_sorter.xml
@@ -223,82 +223,82 @@ output(L) ->
<datatypes>
<datatype>
- <name name="file_name"/><br/>
+ <name name="file_name"/>
</datatype>
<datatype>
- <name name="file_names"/><br/>
+ <name name="file_names"/>
</datatype>
<datatype>
- <name name="i_command"/><br/>
+ <name name="i_command"/>
</datatype>
<datatype>
- <name name="i_reply"/><br/>
+ <name name="i_reply"/>
</datatype>
<datatype>
- <name name="infun"/><br/>
+ <name name="infun"/>
</datatype>
<datatype>
- <name name="input"/><br/>
+ <name name="input"/>
</datatype>
<datatype>
- <name name="input_reply"/><br/>
+ <name name="input_reply"/>
</datatype>
<datatype>
- <name name="o_command"/><br/>
+ <name name="o_command"/>
</datatype>
<datatype>
- <name name="o_reply"/><br/>
+ <name name="o_reply"/>
</datatype>
<datatype>
- <name name="object"/><br/>
+ <name name="object"/>
</datatype>
<datatype>
- <name name="outfun"/><br/>
+ <name name="outfun"/>
</datatype>
<datatype>
- <name name="output"/><br/>
+ <name name="output"/>
</datatype>
<datatype>
- <name name="output_reply"/><br/>
+ <name name="output_reply"/>
</datatype>
<datatype>
- <name name="value"/><br/>
+ <name name="value"/>
</datatype>
<datatype>
- <name name="options"/><br/>
+ <name name="options"/>
</datatype>
<datatype>
- <name name="option"/><br/>
+ <name name="option"/>
</datatype>
<datatype>
- <name name="format"/><br/>
+ <name name="format"/>
</datatype>
<datatype>
- <name name="format_fun"/><br/>
+ <name name="format_fun"/>
</datatype>
<datatype>
- <name name="header_length"/><br/>
+ <name name="header_length"/>
</datatype>
<datatype>
- <name name="key_pos"/><br/>
+ <name name="key_pos"/>
</datatype>
<datatype>
- <name name="no_files"/><br/>
+ <name name="no_files"/>
</datatype>
<datatype>
- <name name="order"/><br/>
+ <name name="order"/>
</datatype>
<datatype>
- <name name="order_fun"/><br/>
+ <name name="order_fun"/>
</datatype>
<datatype>
- <name name="size"/><br/>
+ <name name="size"/>
</datatype>
<datatype>
- <name name="tmp_directory"/><br/>
+ <name name="tmp_directory"/>
</datatype>
<datatype>
- <name name="reason"/><br/>
+ <name name="reason"/>
</datatype>
</datatypes>
diff --git a/lib/stdlib/doc/src/gen_event.xml b/lib/stdlib/doc/src/gen_event.xml
index 1efac1535a..c4bab45781 100644
--- a/lib/stdlib/doc/src/gen_event.xml
+++ b/lib/stdlib/doc/src/gen_event.xml
@@ -716,7 +716,7 @@ gen_event:stop -----> Module:terminate/2
the purposes described below.</p>
</note>
<p>This function is called by a gen_event process when:</p>
- <list typed="bulleted">
+ <list type="bulleted">
<item>One
of <seealso marker="sys#get_status/1">sys:get_status/1,2</seealso>
is invoked to get the gen_event status. <c>Opt</c> is set
@@ -740,7 +740,7 @@ gen_event:stop -----> Module:terminate/2
customises the details of the current state of the event
handler. Any term is allowed for <c>Status</c>. The
gen_event module uses <c>Status</c> as follows:</p>
- <list typed="bulleted">
+ <list type="bulleted">
<item>When <c>sys:get_status/1,2</c> is called, gen_event
ensures that its return value contains <c>Status</c> in
place of the event handler's actual state term.</item>
diff --git a/lib/stdlib/doc/src/gen_fsm.xml b/lib/stdlib/doc/src/gen_fsm.xml
index a8d7fadeb4..4d594b8eb2 100644
--- a/lib/stdlib/doc/src/gen_fsm.xml
+++ b/lib/stdlib/doc/src/gen_fsm.xml
@@ -805,7 +805,7 @@ gen_fsm:sync_send_all_state_event -----> Module:handle_sync_event/4
module state data.</p>
</note>
<p>This function is called by a gen_fsm process when:</p>
- <list typed="bulleted">
+ <list type="bulleted">
<item>One
of <seealso marker="sys#get_status/1">sys:get_status/1,2</seealso>
is invoked to get the gen_fsm status. <c>Opt</c> is set to
diff --git a/lib/stdlib/doc/src/gen_server.xml b/lib/stdlib/doc/src/gen_server.xml
index c31e869db8..6d04771cd4 100644
--- a/lib/stdlib/doc/src/gen_server.xml
+++ b/lib/stdlib/doc/src/gen_server.xml
@@ -673,7 +673,7 @@ gen_server:abcast -----> Module:handle_cast/2
module state.</p>
</note>
<p>This function is called by a gen_server process when:</p>
- <list typed="bulleted">
+ <list type="bulleted">
<item>One
of <seealso marker="sys#get_status/1">sys:get_status/1,2</seealso>
is invoked to get the gen_server status. <c>Opt</c> is set
diff --git a/lib/stdlib/doc/src/io.xml b/lib/stdlib/doc/src/io.xml
index edf3c51b4c..4655c8662f 100644
--- a/lib/stdlib/doc/src/io.xml
+++ b/lib/stdlib/doc/src/io.xml
@@ -132,8 +132,8 @@
<func>
<name name="get_chars" arity="2"/>
<name name="get_chars" arity="3"/>
- <type name="server_no_data"/>
<fsummary>Read a specified number of characters</fsummary>
+ <type name="server_no_data"/>
<desc>
<p>Reads <c><anno>Count</anno></c> characters from standard input
(<c><anno>IoDevice</anno></c>), prompting it with <c><anno>Prompt</anno></c>. It
@@ -162,8 +162,8 @@
<func>
<name name="get_line" arity="1"/>
<name name="get_line" arity="2"/>
- <type name="server_no_data"/>
<fsummary>Read a line</fsummary>
+ <type name="server_no_data"/>
<desc>
<p>Reads a line from the standard input (<c><anno>IoDevice</anno></c>),
prompting it with <c><anno>Prompt</anno></c>. It returns:</p>
@@ -300,8 +300,8 @@
<func>
<name name="read" arity="1"/>
<name name="read" arity="2"/>
- <type name="server_no_data"/>
<fsummary>Read a term</fsummary>
+ <type name="server_no_data"/>
<desc>
<p>Reads a term <c><anno>Term</anno></c> from the standard input
(<c><anno>IoDevice</anno></c>), prompting it with <c><anno>Prompt</anno></c>. It
@@ -330,8 +330,8 @@
<func>
<name name="read" arity="3"/>
<name name="read" arity="4"/>
- <type name="server_no_data"/>
<fsummary>Read a term</fsummary>
+ <type name="server_no_data"/>
<desc>
<p>Reads a term <c><anno>Term</anno></c> from <c><anno>IoDevice</anno></c>, prompting it
with <c><anno>Prompt</anno></c>. Reading starts at location
@@ -698,8 +698,8 @@ ok
<func>
<name name="fread" arity="2"/>
<name name="fread" arity="3"/>
- <type name="server_no_data"/>
<fsummary>Read formatted input</fsummary>
+ <type name="server_no_data"/>
<desc>
<p>Reads characters from the standard input (<c><anno>IoDevice</anno></c>),
prompting it with <c><anno>Prompt</anno></c>. Interprets the characters in
@@ -870,8 +870,8 @@ enter><input>:</input> <input>alan</input> <input>:</input> <input>joe</in
<name name="scan_erl_exprs" arity="2"/>
<name name="scan_erl_exprs" arity="3"/>
<name name="scan_erl_exprs" arity="4"/>
- <type name="server_no_data"/>
<fsummary>Read and tokenize Erlang expressions</fsummary>
+ <type name="server_no_data"/>
<desc>
<p>Reads data from the standard input (<c>IoDevice</c>),
prompting it with <c>Prompt</c>. Reading starts at location
@@ -919,8 +919,8 @@ enter><input>1.0er.</input>
<name name="scan_erl_form" arity="2"/>
<name name="scan_erl_form" arity="3"/>
<name name="scan_erl_form" arity="4"/>
- <type name="server_no_data"/>
<fsummary>Read and tokenize an Erlang form</fsummary>
+ <type name="server_no_data"/>
<desc>
<p>Reads data from the standard input (<c><anno>IoDevice</anno></c>),
prompting it with <c><anno>Prompt</anno></c>. Starts reading
@@ -939,9 +939,9 @@ enter><input>1.0er.</input>
<name name="parse_erl_exprs" arity="2"/>
<name name="parse_erl_exprs" arity="3"/>
<name name="parse_erl_exprs" arity="4"/>
+ <fsummary>Read, tokenize and parse Erlang expressions</fsummary>
<type name="parse_ret"/>
<type name="server_no_data"/>
- <fsummary>Read, tokenize and parse Erlang expressions</fsummary>
<desc>
<p>Reads data from the standard input
(<c><anno>IoDevice</anno></c>), prompting it with
@@ -990,9 +990,9 @@ enter><input>abc("hey".</input>
<name name="parse_erl_form" arity="2"/>
<name name="parse_erl_form" arity="3"/>
<name name="parse_erl_form" arity="4"/>
+ <fsummary>Read, tokenize and parse an Erlang form</fsummary>
<type name="parse_form_ret"/>
<type name="server_no_data"/>
- <fsummary>Read, tokenize and parse an Erlang form</fsummary>
<desc>
<p>Reads data from the standard input (<c><anno>IoDevice</anno></c>),
prompting it with <c><anno>Prompt</anno></c>. Starts reading at
diff --git a/lib/stdlib/doc/src/lists.xml b/lib/stdlib/doc/src/lists.xml
index 46edd9fe16..89ba5238b5 100644
--- a/lib/stdlib/doc/src/lists.xml
+++ b/lib/stdlib/doc/src/lists.xml
@@ -283,8 +283,8 @@ flatmap(Fun, List1) ->
</func>
<func>
<name name="keyfind" arity="3"/>
- <type_desc variable="N">1..tuple_size(<anno>Tuple</anno>)</type_desc>
<fsummary>Search for an element in a list of tuples</fsummary>
+ <type_desc variable="N">1..tuple_size(<anno>Tuple</anno>)</type_desc>
<desc>
<p>Searches the list of tuples <c><anno>TupleList</anno></c> for a
tuple whose <c><anno>N</anno></c>th element compares equal to <c><anno>Key</anno></c>.
@@ -311,8 +311,8 @@ flatmap(Fun, List1) ->
</func>
<func>
<name name="keymember" arity="3"/>
- <type_desc variable="N">1..tuple_size(<anno>Tuple</anno>)</type_desc>
<fsummary>Test for membership of a list of tuples</fsummary>
+ <type_desc variable="N">1..tuple_size(<anno>Tuple</anno>)</type_desc>
<desc>
<p>Returns <c>true</c> if there is a tuple in <c><anno>TupleList</anno></c>
whose <c><anno>N</anno></c>th element compares equal to <c><anno>Key</anno></c>, otherwise
@@ -346,8 +346,8 @@ flatmap(Fun, List1) ->
</func>
<func>
<name name="keysearch" arity="3"/>
- <type_desc variable="N">1..tuple_size(<anno>Tuple</anno>)</type_desc>
<fsummary>Search for an element in a list of tuples</fsummary>
+ <type_desc variable="N">1..tuple_size(<anno>Tuple</anno>)</type_desc>
<desc>
<p>Searches the list of tuples <c><anno>TupleList</anno></c> for a
tuple whose <c><anno>N</anno></c>th element compares equal to <c><anno>Key</anno></c>.
diff --git a/lib/stdlib/doc/src/math.xml b/lib/stdlib/doc/src/math.xml
index 31e838d741..aee6c3f238 100644
--- a/lib/stdlib/doc/src/math.xml
+++ b/lib/stdlib/doc/src/math.xml
@@ -72,9 +72,9 @@
<name name="log10" arity="1"/>
<name name="pow" arity="2"/>
<name name="sqrt" arity="1"/>
+ <fsummary>Diverse math functions</fsummary>
<type variable="X" name_i="7"/>
<type variable="Y" name_i="7"/>
- <fsummary>Diverse math functions</fsummary>
<desc>
<p>A collection of math functions which return floats. Arguments
are numbers. </p>
diff --git a/lib/stdlib/doc/src/notes.xml b/lib/stdlib/doc/src/notes.xml
index bdd0680038..c84ca9c8ad 100644
--- a/lib/stdlib/doc/src/notes.xml
+++ b/lib/stdlib/doc/src/notes.xml
@@ -154,8 +154,9 @@
Correct <c>maps</c> module error exceptions </p>
<p>
Bad input to maps module function will now yield the
- following exceptions: <list> <item>{badmap,NotMap}
- or,</item> <item>badarg</item> </list></p>
+ following exceptions:</p>
+ <list> <item>{badmap, NotMap}, or </item> <item>badarg.</item>
+ </list>
<p>
Own Id: OTP-12657</p>
</item>
@@ -253,12 +254,11 @@
<p>
<c>proc_lib:stop/1,3</c> is used by the following
functions:</p>
- <p>
<list> <item><c>gen_server:stop/1,3</c> (new)</item>
<item><c>gen_fsm:stop/1,3</c> (new)</item>
<item><c>gen_event:stop/1,3</c> (modified to be
synchronous)</item> <item><c>wx_object:stop/1,3</c>
- (new)</item> </list></p>
+ (new)</item> </list>
<p>
Own Id: OTP-11173 Aux Id: seq12353 </p>
</item>
@@ -865,8 +865,7 @@
also implemented by the generic behaviours
<c>gen_server</c>, <c>gen_event</c> and <c>gen_fsm</c>.</p>
<p>
- The potential incompatibility refers to</p>
- <p>
+ The potential incompatibility refers to:</p>
<list> <item>The previous behaviour of intercepting the
system message and passing a tuple of size 2 as the last
argument to <c>sys:handle_system_msg/6</c> is no longer
@@ -874,7 +873,7 @@
<c>StateFun</c> in <c>sys:replace_state/2,3</c> fails is
changed from being totally silent to possibly (if the
callback module does not catch) throw an exception in the
- client process.</item> </list></p>
+ client process.</item> </list>
<p>
(Thanks to James Fish and Steve Vinoski)</p>
<p>
@@ -1036,22 +1035,28 @@
<p>
EEP43: New data type - Maps</p>
<p>
- With Maps you may for instance: <taglist> <item><c>M0 =
- #{ a =&gt; 1, b =&gt; 2}, % create
- associations</c></item> <item><c>M1 = M0#{ a := 10 }, %
- update values</c></item> <item><c>M2 = M1#{ "hi" =&gt;
- "hello"}, % add new associations</c></item> <item><c>#{
- "hi" := V1, a := V2, b := V3} = M2. % match keys with
- values</c></item> </taglist></p>
+ With Maps you may for instance:</p>
+ <taglist>
+ <tag/> <item><c>M0 = #{ a =&gt; 1, b =&gt; 2}, % create
+ associations</c></item>
+ <tag/><item><c>M1 = M0#{ a := 10 }, % update values</c></item>
+ <tag/><item><c>M2 = M1#{ "hi" =&gt;
+ "hello"}, % add new associations</c></item>
+ <tag/><item><c>#{ "hi" := V1, a := V2, b := V3} = M2.
+ % match keys with values</c></item>
+ </taglist>
<p>
For information on how to use Maps please see Map Expressions in the
<seealso marker="doc/reference_manual:expressions#map_expressions">
Reference Manual</seealso>.</p>
<p>
The current implementation is without the following
- features: <taglist> <item>No variable keys</item>
- <item>No single value access</item> <item>No map
- comprehensions</item> </taglist></p>
+ features:</p>
+ <taglist>
+ <tag/><item>No variable keys</item>
+ <tag/><item>No single value access</item>
+ <tag/><item>No map comprehensions</item>
+ </taglist>
<p>
Note that Maps is <em>experimental</em> during OTP 17.0.</p>
<p>
@@ -1802,13 +1807,15 @@
supervisor or for the problematic child.</p>
<p>
This introduces some incompatibilities in stdlib due to
- new return values from supervisor: <list>
+ new return values from supervisor:</p>
+ <list>
<item>restart_child/2 can now return
{error,restarting}</item> <item>delete_child/2 can now
return {error,restarting}</item> <item>which_children/1
returns a list of {Id,Child,Type,Mods}, where Child, in
addition to the old pid() or 'undefined', now also can be
- 'restarting'.</item> </list></p>
+ 'restarting'.</item>
+ </list>
<p>
*** POTENTIAL INCOMPATIBILITY ***</p>
<p>
@@ -1824,10 +1831,10 @@
Own Id: OTP-9782 Aux Id: seq11964 </p>
</item>
<item>
- <p> Use universal time as base in error logger
+ <p> Use universal time as base in error logger</p>
<p>
Previous conversion used the deprecated
- calendar:local_time_to_universal_time/1 </p></p>
+ calendar:local_time_to_universal_time/1 </p>
<p>
Own Id: OTP-9854</p>
</item>
@@ -2584,10 +2591,10 @@
Own Id: OTP-8989 Aux Id: seq11741 </p>
</item>
<item>
- <p>Fix exception generation in the io module
+ <p>Fix exception generation in the io module</p>
<p>
Some functions did not generate correct badarg exception
- on a badarg exception.</p></p>
+ on a badarg exception.</p>
<p>
Own Id: OTP-9045</p>
</item>
diff --git a/lib/stdlib/doc/src/rand.xml b/lib/stdlib/doc/src/rand.xml
index e7d4728ef7..50057259c6 100644
--- a/lib/stdlib/doc/src/rand.xml
+++ b/lib/stdlib/doc/src/rand.xml
@@ -104,7 +104,7 @@
strong. If a strong cryptographic random number generator is
needed, use one of functions in the
<seealso marker="crypto:crypto">crypto</seealso>
- module, for example <c>crypto:rand_bytes/1</c>.</p></note>
+ module, for example <c>crypto:strong_rand_bytes/1</c>.</p></note>
</description>
<datatypes>
<datatype>
diff --git a/lib/stdlib/doc/src/random.xml b/lib/stdlib/doc/src/random.xml
index 91a4012ce9..fc4f796863 100644
--- a/lib/stdlib/doc/src/random.xml
+++ b/lib/stdlib/doc/src/random.xml
@@ -48,7 +48,7 @@
tuple of three integers.</p>
<p>It should be noted that this random number generator is not cryptographically
strong. If a strong cryptographic random number generator is needed for
- example <c>crypto:rand_bytes/1</c> could be used instead.</p>
+ example <c>crypto:strong_rand_bytes/1</c> could be used instead.</p>
<note><p>The new and improved <seealso
marker="stdlib:rand">rand</seealso> module should be used
instead of this module.</p></note>
@@ -76,9 +76,15 @@
dictionary, and returns the old state.</p>
<p>One easy way of obtaining a unique value to seed with is to:</p>
<code type="none">
- random:seed(<seealso marker="erts:erlang#phash2/1">erlang:phash2</seealso>([<seealso marker="erts:erlang#node/0">node()</seealso>]),
- <seealso marker="erts:erlang#monotonic_time/0">erlang:monotonic_time()</seealso>,
- <seealso marker="erts:erlang#unique_integer/0">erlang:unique_integer()</seealso>)</code>
+random:seed(erlang:phash2([node()]),
+ erlang:monotonic_time(),
+ erlang:unique_integer())</code>
+ <p>See <seealso marker="erts:erlang#phash2/1">
+ erlang:phash2/1</seealso>, <seealso marker="erts:erlang#node/0">
+ node/0</seealso>, <seealso marker="erts:erlang#monotonic_time/0">
+ erlang:monotonic_time/0</seealso>, and
+ <seealso marker="erts:erlang#unique_integer/0">
+ erlang:unique_integer/0</seealso>) for details.</p>
</desc>
</func>
<func>
@@ -142,7 +148,7 @@
<p>The implementation changed in R15. Upgrading to R15 will break
applications that expect a specific output for a given seed. The output
is still deterministic number series, but different compared to releases
- older than R15. The seed <c>{0,0,0}</c> will for example no longer
+ older than R15. The seed <c>{0,0,0}</c> will, for example, no longer
produce a flawed series of only zeros.</p>
</section>
</erlref>
diff --git a/lib/stdlib/doc/src/re.xml b/lib/stdlib/doc/src/re.xml
index 46b382a6be..8c19926b10 100644
--- a/lib/stdlib/doc/src/re.xml
+++ b/lib/stdlib/doc/src/re.xml
@@ -205,8 +205,8 @@ This option makes it possible to include comments inside complicated patterns. N
</func>
<func>
<name name="run" arity="3"/>
- <type_desc variable="CompileOpt">See <seealso marker="#compile_options">compile/2</seealso> above.</type_desc>
<fsummary>Match a subject against regular expression and capture subpatterns</fsummary>
+ <type_desc variable="CompileOpt">See <seealso marker="#compile_options">compile/2</seealso> above.</type_desc>
<desc>
<p>Executes a regexp matching, returning <c>match/{match,
@@ -881,11 +881,11 @@ nomatch
</desc>
</func>
</funcs>
-
- <marker id="regexp_syntax"></marker>
+
<section>
<title>PERL LIKE REGULAR EXPRESSIONS SYNTAX</title>
- <p>The following sections contain reference material for the
+ <p><marker id="regexp_syntax"></marker>
+ The following sections contain reference material for the
regular expressions used by this module. The regular expression
reference is based on the PCRE documentation, with changes in
cases where the re module behaves differently to the PCRE library.</p>
@@ -2070,7 +2070,7 @@ supported, and an error is given if they are encountered.</p>
<p>By default, in UTF modes, characters with values greater than 255 do not match
any of the POSIX character classes. However, if the PCRE_UCP option is passed
-to <b>pcre_compile()</b>, some of the classes are changed so that Unicode
+to <em>pcre_compile()</em>, some of the classes are changed so that Unicode
character properties are used. This is achieved by replacing the POSIX classes
by other sequences, as follows:</p>
@@ -2078,10 +2078,10 @@ by other sequences, as follows:</p>
<tag>[:alnum:]</tag> <item>becomes <em>\p{Xan}</em></item>
<tag>[:alpha:]</tag> <item>becomes <em>\p{L}</em></item>
<tag>[:blank:]</tag> <item>becomes <em>\h</em></item>
- <tag>[:digit:</tag>] <item>becomes <em>\p{Nd}</em></item>
+ <tag>[:digit:]</tag> <item>becomes <em>\p{Nd}</em></item>
<tag>[:lower:]</tag> <item>becomes <em>\p{Ll}</em></item>
<tag>[:space:]</tag> <item>becomes <em>\p{Xps}</em></item>
- <tag>[:upper:</tag>] <item>becomes <em>\p{Lu}</em></item>
+ <tag>[:upper:]</tag> <item>becomes <em>\p{Lu}</em></item>
<tag>[:word:]</tag> <item>becomes <em>\p{Xwd}</em></item>
</taglist>
@@ -3059,7 +3059,7 @@ default newline convention is in force:</p>
<quote><p> abc #comment \n still comment</p></quote>
-<p>On encountering the # character, <b>pcre_compile()</b> skips along, looking for
+<p>On encountering the # character, <em>pcre_compile()</em> skips along, looking for
a newline in the pattern. The sequence \n is still literal at this stage, so
it does not terminate the comment. Only an actual character with the code value
0x0a (the default newline) does so.</p>
diff --git a/lib/stdlib/doc/src/sofs.xml b/lib/stdlib/doc/src/sofs.xml
index 5d7648d9a1..53f6ca957a 100644
--- a/lib/stdlib/doc/src/sofs.xml
+++ b/lib/stdlib/doc/src/sofs.xml
@@ -398,8 +398,9 @@ fun(S) -> sofs:partition(1, S) end
</datatype>
<datatype>
<!-- Parameterized opaque types are NYI: -->
- <name><marker id="type-tuple_of">tuple_of(T)</marker></name>
- <desc><p>A tuple where the elements are of type <c>T</c>.</p></desc>
+ <name>tuple_of(T)</name>
+ <desc><p><marker id="type-tuple_of"/>
+ A tuple where the elements are of type <c>T</c>.</p></desc>
</datatype>
</datatypes>
<funcs>
diff --git a/lib/stdlib/doc/src/supervisor.xml b/lib/stdlib/doc/src/supervisor.xml
index f08b752998..24ff251ce3 100644
--- a/lib/stdlib/doc/src/supervisor.xml
+++ b/lib/stdlib/doc/src/supervisor.xml
@@ -353,7 +353,7 @@
<desc>
<p>Dynamically adds a child specification to the supervisor
<c><anno>SupRef</anno></c> which starts the corresponding child process.</p>
- <p><marker id="SupRef"><c><anno>SupRef</anno></c></marker> can be:</p>
+ <p><marker id="SupRef"/><c><anno>SupRef</anno></c> can be:</p>
<list type="bulleted">
<item>the pid,</item>
<item><c>Name</c>, if the supervisor is locally registered,</item>
diff --git a/lib/stdlib/doc/src/sys.xml b/lib/stdlib/doc/src/sys.xml
index 6ec515849e..d400f72e1d 100644
--- a/lib/stdlib/doc/src/sys.xml
+++ b/lib/stdlib/doc/src/sys.xml
@@ -238,8 +238,8 @@
<p>These functions are intended only to help with debugging. They are provided for
convenience, allowing developers to avoid having to create their own state extraction
functions and also avoid having to interactively extract state from the return values of
- <c><seealso marker="#get_status-1">get_status/1</seealso></c> or
- <c><seealso marker="#get_status-2">get_status/2</seealso></c> while debugging.</p>
+ <seealso marker="#get_status-1"><c>get_status/1</c></seealso> or
+ <seealso marker="#get_status-2"><c>get_status/2</c></seealso> while debugging.</p>
</note>
<p>The value of <c><anno>State</anno></c> varies for different types of
processes. For a <c>gen_server</c> process, the returned <c><anno>State</anno></c>
diff --git a/lib/stdlib/doc/src/timer.xml b/lib/stdlib/doc/src/timer.xml
index e002f519b9..7609487300 100644
--- a/lib/stdlib/doc/src/timer.xml
+++ b/lib/stdlib/doc/src/timer.xml
@@ -85,7 +85,6 @@
<name name="send_after" arity="3"/>
<fsummary>Send <c>Message</c>to <c>Pid</c>after a specified <c>Time</c>.</fsummary>
<desc>
- <p>
<taglist>
<tag><c>send_after/3</c></tag>
<item>
@@ -99,7 +98,6 @@
<p>Same as <c>send_after(<anno>Time</anno>, self(), <anno>Message</anno>)</c>.</p>
</item>
</taglist>
- </p>
</desc>
</func>
<func>
@@ -109,7 +107,6 @@
<name name="exit_after" arity="3"/>
<fsummary>Send an exit signal with <c>Reason</c>after a specified <c>Time</c>.</fsummary>
<desc>
- <p>
<taglist>
<tag><c>exit_after/3</c></tag>
<item>
@@ -130,7 +127,6 @@
<p>Same as <c>exit_after(<anno>Time</anno>, self(), kill)</c>. </p>
</item>
</taglist>
- </p>
</desc>
</func>
<func>
@@ -147,7 +143,6 @@
<name name="send_interval" arity="3"/>
<fsummary>Send <c>Message</c>repeatedly at intervals of <c>Time</c>.</fsummary>
<desc>
- <p>
<taglist>
<tag><c>send_interval/3</c></tag>
<item>
@@ -161,7 +156,6 @@
<p>Same as <c>send_interval(<anno>Time</anno>, self(), <anno>Message</anno>)</c>.</p>
</item>
</taglist>
- </p>
</desc>
</func>
<func>
@@ -192,7 +186,6 @@
Function, Arguments)</c> or <c>apply(Fun, Arguments)</c></fsummary>
<type_desc variable="Time">In microseconds</type_desc>
<desc>
- <p>
<taglist>
<tag><c>tc/3</c></tag>
<item>
@@ -213,7 +206,6 @@
</item>
</taglist>
- </p>
</desc>
</func>
<func>
diff --git a/lib/stdlib/doc/src/unicode.xml b/lib/stdlib/doc/src/unicode.xml
index 19ddf1cbd6..966eec49f5 100644
--- a/lib/stdlib/doc/src/unicode.xml
+++ b/lib/stdlib/doc/src/unicode.xml
@@ -133,7 +133,7 @@
<c>latin1</c>, or have characters encoded as one of the
UTF-encodings, which is given as the <c><anno>InEncoding</anno></c>
parameter. Only when the <c><anno>InEncoding</anno></c> is one of the UTF
- encodings, integers in the list are allowed to be grater than
+ encodings, integers in the list are allowed to be greater than
255.</p>
<p>If <c><anno>InEncoding</anno></c> is <c>latin1</c>, the <c><anno>Data</anno></c> parameter
diff --git a/lib/stdlib/doc/src/zip.xml b/lib/stdlib/doc/src/zip.xml
index 4500995c34..186c8ac724 100644
--- a/lib/stdlib/doc/src/zip.xml
+++ b/lib/stdlib/doc/src/zip.xml
@@ -126,7 +126,7 @@
</datatype>
<datatype>
<name name="filename"/>
- <p>The name of a zip file.</p>
+ <desc><p>The name of a zip file.</p></desc>
</datatype>
<datatype><name name="extension"/></datatype>
<datatype><name name="extension_spec"/></datatype>
diff --git a/lib/stdlib/src/beam_lib.erl b/lib/stdlib/src/beam_lib.erl
index b93ce97cd3..cbbab088f4 100644
--- a/lib/stdlib/src/beam_lib.erl
+++ b/lib/stdlib/src/beam_lib.erl
@@ -308,6 +308,17 @@ make_crypto_key(des3_cbc=Type, String) ->
<<K3:8/binary,IVec:8/binary>> = erlang:md5([First|reverse(String)]),
{Type,[K1,K2,K3],IVec,8}.
+-spec build_module(Chunks) -> {'ok', Binary} when
+ Chunks :: [{chunkid(), dataB()}],
+ Binary :: binary().
+
+build_module(Chunks0) ->
+ Chunks = list_to_binary(build_chunks(Chunks0)),
+ Size = byte_size(Chunks),
+ 0 = Size rem 4, % Assertion: correct padding?
+ {ok, <<"FOR1", (Size+4):32, "BEAM", Chunks/binary>>}.
+
+
%%
%% Local functions
%%
@@ -419,12 +430,6 @@ strip_file(File) ->
end
end.
-build_module(Chunks0) ->
- Chunks = list_to_binary(build_chunks(Chunks0)),
- Size = byte_size(Chunks),
- 0 = Size rem 4, % Assertion: correct padding?
- {ok, <<"FOR1", (Size+4):32, "BEAM", Chunks/binary>>}.
-
build_chunks([{Id, Data} | Chunks]) ->
BId = list_to_binary(Id),
Size = byte_size(Data),
diff --git a/lib/stdlib/src/edlin.erl b/lib/stdlib/src/edlin.erl
index 8c7a984f1c..19444c0502 100644
--- a/lib/stdlib/src/edlin.erl
+++ b/lib/stdlib/src/edlin.erl
@@ -227,6 +227,8 @@ key_map($F, meta_o) -> end_of_line;
key_map($\177, none) -> backward_delete_char;
key_map($\177, meta) -> backward_kill_word;
key_map($[, meta) -> meta_left_sq_bracket;
+key_map($H, meta_left_sq_bracket) -> beginning_of_line;
+key_map($F, meta_left_sq_bracket) -> end_of_line;
key_map($D, meta_left_sq_bracket) -> backward_char;
key_map($C, meta_left_sq_bracket) -> forward_char;
% support a few <CTRL>+<CURSOR LEFT|RIGHT> combinations...
@@ -237,8 +239,10 @@ key_map($[, meta_meta) -> meta_csi;
key_map($C, meta_csi) -> forward_word;
key_map($D, meta_csi) -> backward_word;
key_map($1, meta_left_sq_bracket) -> {csi, "1"};
+key_map($3, meta_left_sq_bracket) -> {csi, "3"};
key_map($5, meta_left_sq_bracket) -> {csi, "5"};
key_map($5, {csi, "1;"}) -> {csi, "1;5"};
+key_map($~, {csi, "3"}) -> forward_delete_char;
key_map($C, {csi, "5"}) -> forward_word;
key_map($C, {csi, "1;5"}) -> forward_word;
key_map($D, {csi, "5"}) -> backward_word;
diff --git a/lib/stdlib/src/erl_lint.erl b/lib/stdlib/src/erl_lint.erl
index c4cb5fdc80..5678e7eebe 100644
--- a/lib/stdlib/src/erl_lint.erl
+++ b/lib/stdlib/src/erl_lint.erl
@@ -293,6 +293,9 @@ format_error({variable_in_record_def,V}) ->
%% --- binaries ---
format_error({undefined_bittype,Type}) ->
io_lib:format("bit type ~w undefined", [Type]);
+format_error({bittype_mismatch,Val1,Val2,What}) ->
+ io_lib:format("conflict in ~s specification for bit field: '~p' and '~p'",
+ [What,Val1,Val2]);
format_error(bittype_unit) ->
"a bit unit size must not be specified unless a size is specified too";
format_error(illegal_bitsize) ->
diff --git a/lib/stdlib/src/erl_pp.erl b/lib/stdlib/src/erl_pp.erl
index f7a969977a..c5177aca90 100644
--- a/lib/stdlib/src/erl_pp.erl
+++ b/lib/stdlib/src/erl_pp.erl
@@ -253,6 +253,8 @@ lattribute(import, Name, _Opts, _State) when is_list(Name) ->
attr("import", [{var,a0(),pname(Name)}]);
lattribute(import, {From,Falist}, _Opts, _State) ->
attr("import",[{var,a0(),pname(From)},falist(Falist)]);
+lattribute(export_type, Talist, _Opts, _State) ->
+ call({var,a0(),"-export_type"}, [falist(Talist)], 0, options(none));
lattribute(optional_callbacks, Falist, Opts, _State) ->
ArgL = try falist(Falist)
catch _:_ -> abstract(Falist, Opts)
@@ -321,7 +323,6 @@ ltype({type,_,'fun',[{type,_,any},_]}=FunType, _) ->
ltype({type,_Line,'fun',[{type,_,product,_},_]}=FunType, _) ->
[fun_type(['fun',$(], FunType),$)];
ltype({type,Line,T,Ts}, _) ->
- %% Compatibility. Before 18.0.
simple_type({atom,Line,T}, Ts);
ltype({user_type,Line,T,Ts}, _) ->
simple_type({atom,Line,T}, Ts);
@@ -346,16 +347,8 @@ map_type(Fs) ->
map_pair_types(Fs) ->
tuple_type(Fs, fun map_pair_type/2).
-map_pair_type({type,_Line,map_field_assoc,[Ktype,Vtype]}, Prec) ->
- map_assoc_typed(ltype(Ktype), Vtype, Prec).
-
-map_assoc_typed(B, {type,_,union,Ts}, Prec) ->
- {first,[B,$\s],{seq,[],[],[],map_assoc_union_type(Ts, Prec)}};
-map_assoc_typed(B, Type, Prec) ->
- {list,[{cstep,[B," =>"],ltype(Type, Prec)}]}.
-
-map_assoc_union_type([T|Ts], Prec) ->
- [[leaf("=> "),ltype(T)] | ltypes(Ts, fun union_elem/2, Prec)].
+map_pair_type({type,_Line,map_field_assoc,[KType,VType]}, Prec) ->
+ {list,[{cstep,[ltype(KType, Prec),leaf(" =>")],ltype(VType, Prec)}]}.
record_type(Name, Fields) ->
{first,[record_name(Name)],field_types(Fields)}.
@@ -370,9 +363,6 @@ typed(B, Type) ->
{_L,_P,R} = type_inop_prec('::'),
{list,[{cstep,[B,' ::'],ltype(Type, R)}]}.
-union_elem(T, Prec) ->
- [leaf(" | "),ltype(T, Prec)].
-
tuple_type(Ts, F) ->
{seq,${,$},[$,],ltypes(Ts, F, 0)}.
@@ -399,6 +389,9 @@ guard_type(Before, Gs) ->
Gl = {list,[{step,'when',expr_list(Gs, [$,], fun constraint/2, Opts)}]},
{list,[{step,Before,Gl}]}.
+constraint({type,_Line,constraint,[{atom,_,is_subtype},[{var,_,_}=V,Type]]},
+ _Opts) ->
+ typed(lexpr(V, options(none)), Type);
constraint({type,_Line,constraint,[Tag,As]}, _Opts) ->
simple_type(Tag, As).
diff --git a/lib/stdlib/src/rand.erl b/lib/stdlib/src/rand.erl
index 8e8d0bc801..dc060e82d9 100644
--- a/lib/stdlib/src/rand.erl
+++ b/lib/stdlib/src/rand.erl
@@ -63,7 +63,7 @@
%% Return algorithm and seed so that RNG state can be recreated with seed/1
-spec export_seed() -> undefined | export_state().
export_seed() ->
- case seed_get() of
+ case get(?SEED_DICT) of
{#{type:=Alg}, Seed} -> {Alg, Seed};
_ -> undefined
end.
diff --git a/lib/stdlib/src/shell.erl b/lib/stdlib/src/shell.erl
index f215a66812..ce1d9eb0ff 100644
--- a/lib/stdlib/src/shell.erl
+++ b/lib/stdlib/src/shell.erl
@@ -999,12 +999,7 @@ local_func(rl, [A], Bs0, _Shell, RT, Lf, Ef) ->
{value,list_records(record_defs(RT, listify(Recs))),Bs};
local_func(rp, [A], Bs0, _Shell, RT, Lf, Ef) ->
{[V],Bs} = expr_list([A], Bs0, Lf, Ef),
- Cs = io_lib_pretty:print(V, ([{column, 1},
- {line_length, columns()},
- {depth, -1},
- {max_chars, ?CHAR_MAX},
- {record_print_fun, record_print_fun(RT)}]
- ++ enc())),
+ Cs = pp(V, _Column=1, _Depth=-1, RT),
io:requests([{put_chars, unicode, Cs}, nl]),
{value,ok,Bs};
local_func(rr, [A], Bs0, _Shell, RT, Lf, Ef) ->
@@ -1397,9 +1392,9 @@ get_history_and_results() ->
{History, erlang:min(Results, History)}.
pp(V, I, RT) ->
- pp(V, I, RT, enc()).
+ pp(V, I, _Depth=?LINEMAX, RT).
-pp(V, I, RT, Enc) ->
+pp(V, I, D, RT) ->
Strings =
case application:get_env(stdlib, shell_strings) of
{ok, false} ->
@@ -1408,10 +1403,10 @@ pp(V, I, RT, Enc) ->
true
end,
io_lib_pretty:print(V, ([{column, I}, {line_length, columns()},
- {depth, ?LINEMAX}, {max_chars, ?CHAR_MAX},
+ {depth, D}, {max_chars, ?CHAR_MAX},
{strings, Strings},
{record_print_fun, record_print_fun(RT)}]
- ++ Enc)).
+ ++ enc())).
columns() ->
case io:columns() of
diff --git a/lib/stdlib/src/supervisor.erl b/lib/stdlib/src/supervisor.erl
index 3c77501c0f..92a0c29011 100644
--- a/lib/stdlib/src/supervisor.erl
+++ b/lib/stdlib/src/supervisor.erl
@@ -1083,7 +1083,7 @@ wait_dynamic_children(#child{restart_type=RType} = Child, Pids, Sz,
{timeout, TRef, kill} ->
?SETS:fold(fun(P, _) -> exit(P, kill) end, ok, Pids),
- wait_dynamic_children(Child, Pids, Sz-1, undefined, EStack)
+ wait_dynamic_children(Child, Pids, Sz, undefined, EStack)
end.
%%-----------------------------------------------------------------
diff --git a/lib/stdlib/test/erl_lint_SUITE.erl b/lib/stdlib/test/erl_lint_SUITE.erl
index 0424e2b967..5347ccaf1f 100644
--- a/lib/stdlib/test/erl_lint_SUITE.erl
+++ b/lib/stdlib/test/erl_lint_SUITE.erl
@@ -3604,7 +3604,10 @@ bin_syntax_errors(Config) ->
t(<<X/unit:8>>) -> X;
t(<<X:7/float>>) -> X;
t(<< <<_:8>> >>) -> ok;
- t(<<(x ! y):8/integer>>) -> ok.
+ t(<<(x ! y):8/integer>>) -> ok;
+ t(X) ->
+ {<<X/binary-integer>>,<<X/signed-unsigned-integer>>,
+ <<X/little-big>>,<<X/unit:4-unit:8>>}.
">>,
[],
{error,[{1,erl_lint,illegal_bitsize},
@@ -3613,7 +3616,12 @@ bin_syntax_errors(Config) ->
{4,erl_lint,{undefined_bittype,bad_type}},
{5,erl_lint,bittype_unit},
{7,erl_lint,illegal_pattern},
- {8,erl_lint,illegal_pattern}],
+ {8,erl_lint,illegal_pattern},
+ {10,erl_lint,{bittype_mismatch,integer,binary,"type"}},
+ {10,erl_lint,{bittype_mismatch,unsigned,signed,"sign"}},
+ {11,erl_lint,{bittype_mismatch,8,4,"unit"}},
+ {11,erl_lint,{bittype_mismatch,big,little,"endianness"}}
+ ],
[{6,erl_lint,{bad_bitsize,"float"}}]}}
],
[] = run(Config, Ts),
@@ -3920,22 +3928,35 @@ run_test2(Conf, Test, Warnings0) ->
%% is no reason to produce an output file since we are only
%% interested in the errors and warnings.
- %% Print warnings, call erl_lint:format_error/1.
+ %% Print warnings, call erl_lint:format_error/1. (But note that
+ %% the compiler will ignore failing calls to erl_lint:format_error/1.)
compile:file(File, [binary,report|Opts]),
case compile:file(File, [binary|Opts]) of
- {ok, _M, Code, Ws} when is_binary(Code) -> warnings(File, Ws);
- {error, [{File,Es}], []} -> {errors, Es, []};
- {error, [{File,Es}], [{File,Ws}]} -> {error, Es, Ws};
- {error, [{File,Es1},{File,Es2}], []} -> {errors2, Es1, Es2}
+ {ok, _M, Code, Ws} when is_binary(Code) ->
+ warnings(File, Ws);
+ {error, [{File,Es}], []} ->
+ {errors, call_format_error(Es), []};
+ {error, [{File,Es}], [{File,Ws}]} ->
+ {error, call_format_error(Es), call_format_error(Ws)};
+ {error, [{File,Es1},{File,Es2}], []} ->
+ {errors2, Es1, Es2}
end.
warnings(File, Ws) ->
case lists:append([W || {F, W} <- Ws, F =:= File]) of
- [] -> [];
- L -> {warnings, L}
+ [] ->
+ [];
+ L ->
+ {warnings, call_format_error(L)}
end.
+call_format_error(L) ->
+ %% Smoke test of format_error/1 to make sure that no crashes
+ %% slip through.
+ _ = [Mod:format_error(Term) || {_,Mod,Term} <- L],
+ L.
+
fail() ->
io:format("failed~n"),
?t:fail().
diff --git a/lib/stdlib/test/erl_pp_SUITE.erl b/lib/stdlib/test/erl_pp_SUITE.erl
index 389fd059f6..92e2764c65 100644
--- a/lib/stdlib/test/erl_pp_SUITE.erl
+++ b/lib/stdlib/test/erl_pp_SUITE.erl
@@ -960,6 +960,9 @@ maps_syntax(Config) when is_list(Config) ->
"-compile(export_all).\n"
"-type t1() :: map().\n"
"-type t2() :: #{ atom() => integer(), atom() => float() }.\n"
+ "-type u() :: #{a => (I :: integer()) | (A :: atom()),\n"
+ " (X :: atom()) | (Y :: atom()) =>\n"
+ " (I :: integer()) | (A :: atom())}.\n"
"-spec f1(t1()) -> 'true'.\n"
"f1(M) when is_map(M) -> true.\n"
"-spec f2(t2()) -> integer().\n"
diff --git a/lib/stdlib/test/rand_SUITE.erl b/lib/stdlib/test/rand_SUITE.erl
index 111bf620de..03b5ce1a25 100644
--- a/lib/stdlib/test/rand_SUITE.erl
+++ b/lib/stdlib/test/rand_SUITE.erl
@@ -126,6 +126,9 @@ seed_1(Alg) ->
false = (S1 =:= rand:seed_s(Alg)),
%% Negative integers works
_ = rand:seed_s(Alg, {-1,-1,-1}),
+ %% Check that export_seed/1 returns 'undefined' if there is no seed
+ erase(rand_seed),
+ undefined = rand:export_seed(),
%% Other term do not work
{'EXIT', _} = (catch rand:seed_s(foobar, os:timestamp())),
diff --git a/lib/test_server/doc/src/notes.xml b/lib/test_server/doc/src/notes.xml
index 939a07dcef..da956de9ef 100644
--- a/lib/test_server/doc/src/notes.xml
+++ b/lib/test_server/doc/src/notes.xml
@@ -298,7 +298,7 @@
configuration function or test specification term), the
affected test cases get the status <c>user_skipped</c>
instead.</p> <p>This update has meant a few changes that
- may affect Common Test users in various ways: <list>
+ may affect Common Test users in various ways:</p> <list>
<item>The test results and statistics will be affected,
which is important to know when running regression tests
and comparing results to previous test runs.</item>
@@ -318,7 +318,7 @@
<c>auto_skipped</c> rather than <c>user_skipped</c> as
before.</item> <item>The event messages that Common Test
generates during test runs have been affected by this
- update. For details see OTP-11524.</item> </list> </p>
+ update. For details see OTP-11524.</item> </list>
<p>
Own Id: OTP-11305 Aux Id: OTP-11524 </p>
</item>
@@ -445,7 +445,7 @@
that were not opened with the {encoding,utf8} option. If
then the argument contained unicode characters above 255,
the file descriptor would crash. This has been corrected
- by the following modifications: <list> <item> Since the
+ by the following modifications:</p> <list> <item> Since the
'unexpected_io' log file is used only when the test case
HTML file is not available (e.g. between test cases),
this file is now also a HTML file and as other
@@ -467,7 +467,7 @@
path to the last run.&lt;timestamp&gt; directory, is now
dependent on the file name mode of the VM. If file names
are expected to be unicode, then the 'last_name' file is
- UTF-8 encoded, else it is latin1 encoded. </item> </list></p>
+ UTF-8 encoded, else it is latin1 encoded. </item> </list>
<p>
Also, ~tp has been changed back to ~p unless it is
somehow likely that the argument includes strings. It is
@@ -615,7 +615,7 @@
</item>
<item>
<p>
- Update common test modules to handle unicode <list>
+ Update common test modules to handle Unicode:</p> <list>
<item> Use UTF-8 encoding for all HTML files, except the
HTML version of the test suite generated with
erl2html2:convert, which will have the same encoding as
@@ -626,7 +626,7 @@
unicode:characters_to_list and
unicode:characters_to_binary for conversion between
binaries and strings instead of binary_to_list and
- list_to_binary. </item> </list></p>
+ list_to_binary. </item> </list>
</item>
</list>
</section>
diff --git a/lib/test_server/src/ts_lib.erl b/lib/test_server/src/ts_lib.erl
index 61bd55a654..7c3f450194 100644
--- a/lib/test_server/src/ts_lib.erl
+++ b/lib/test_server/src/ts_lib.erl
@@ -250,12 +250,10 @@ do_test(Rest, Vars, Test) ->
{Result,Comment,Rest2}.
%% extract an argument
-get_arg([$ |Rest], Vars, Stop, Acc) ->
- get_arg(Rest, Vars, Stop, Acc);
get_arg([$(|Rest], Vars, Stop, _) ->
get_arg(Rest, Vars, Stop, []);
get_arg([Stop|Rest], Vars, Stop, Acc) ->
- Arg = lists:reverse(Acc),
+ Arg = string:strip(lists:reverse(Acc)),
Subst = subst(Arg, Vars),
{Subst,Rest};
get_arg([C|Rest], Vars, Stop, Acc) ->
diff --git a/lib/tools/doc/src/eprof.xml b/lib/tools/doc/src/eprof.xml
index 7dccd927ca..8e37d49c99 100644
--- a/lib/tools/doc/src/eprof.xml
+++ b/lib/tools/doc/src/eprof.xml
@@ -131,13 +131,13 @@
<name>analyze() -> ok</name>
<name>analyze(Type) -> ok</name>
<name>analyze(Type,Options) -> ok</name>
+ <fsummary>Display profiling results per process.</fsummary>
<type>
<v>Type = procs | total</v>
<v>Options = [{filter, Filter} | {sort, Sort}</v>
<v>Filter = [{calls, integer()} | {time, float()}]</v>
<v>Sort = time | calls | mfa</v>
</type>
- <fsummary>Display profiling results per process.</fsummary>
<desc>
<p>Call this function when profiling has been stopped to display
the results per process, that is:</p>
diff --git a/lib/tools/emacs/erlang.el b/lib/tools/emacs/erlang.el
index 4aa1ab7d38..466bf139b9 100644
--- a/lib/tools/emacs/erlang.el
+++ b/lib/tools/emacs/erlang.el
@@ -4236,7 +4236,7 @@ This function is designed to be a member of a criteria list."
This function is designed to be a member of a criteria list."
(save-excursion
(beginning-of-line)
- (when (save-match-data (looking-at "-\\(spec\\|type\\)"))
+ (when (save-match-data (looking-at "-\\(spec\\|type\\|callback\\)"))
'stop)))
diff --git a/lib/tools/src/make.erl b/lib/tools/src/make.erl
index 96c3e0e506..5d5a1ef2bd 100644
--- a/lib/tools/src/make.erl
+++ b/lib/tools/src/make.erl
@@ -25,12 +25,20 @@
%% If Emakefile is missing the current directory is used.
-module(make).
--export([all/0,all/1,files/1,files/2]).
+-export([all_or_nothing/0,all/0,all/1,files/1,files/2]).
-include_lib("kernel/include/file.hrl").
-define(MakeOpts,[noexec,load,netload,noload]).
+all_or_nothing() ->
+ case all() of
+ up_to_date ->
+ up_to_date;
+ error ->
+ halt(1)
+ end.
+
all() ->
all([]).
diff --git a/lib/typer/src/typer.erl b/lib/typer/src/typer.erl
index ec00bfaba0..562530c868 100644
--- a/lib/typer/src/typer.erl
+++ b/lib/typer/src/typer.erl
@@ -1012,15 +1012,7 @@ compile_error(Reason) ->
-spec msg(string()) -> 'ok'.
msg(Msg) ->
- case os:type() of
- {unix, _} -> % Output a message on 'stderr', if possible
- P = open_port({fd, 0, 2}, [out]),
- port_command(P, Msg),
- true = port_close(P),
- ok;
- _ -> % win32
- io:format("~s", [Msg])
- end.
+ io:format(standard_error, "~s", [Msg]).
%%--------------------------------------------------------------------
%% Version and help messages.
diff --git a/lib/wx/api_gen/gl_gen_erl.erl b/lib/wx/api_gen/gl_gen_erl.erl
index 20406a8d05..84e9600bc0 100644
--- a/lib/wx/api_gen/gl_gen_erl.erl
+++ b/lib/wx/api_gen/gl_gen_erl.erl
@@ -226,10 +226,14 @@ gen_types(Where) ->
w("-type clamp() :: float(). %% 0.0..1.0~n", []),
w("-type offset() :: non_neg_integer(). %% Offset in memory block~n", [])
end,
- w("-type matrix() :: {float(),float(),float(),float(),~n", []),
+ w("-type matrix12() :: {float(),float(),float(),float(),~n", []),
+ w(" float(),float(),float(),float(),~n", []),
+ w(" float(),float(),float(),float()}.~n", []),
+ w("-type matrix16() :: {float(),float(),float(),float(),~n", []),
w(" float(),float(),float(),float(),~n", []),
w(" float(),float(),float(),float(),~n", []),
w(" float(),float(),float(),float()}.~n", []),
+ w("-type matrix() :: matrix12() | matrix16().~n", []),
w("-type mem() :: binary() | tuple(). %% Memory block~n", []),
ok.
@@ -480,10 +484,12 @@ doc_arg_type2(T=#type{single=true}) ->
doc_arg_type3(T);
doc_arg_type2(T=#type{single=undefined}) ->
doc_arg_type3(T);
-doc_arg_type2(T=#type{single={tuple,undefined}}) ->
- "{" ++ doc_arg_type3(T) ++ "}";
+doc_arg_type2(_T=#type{single={tuple,undefined}}) ->
+ "tuple()";
doc_arg_type2(#type{base=float, single={tuple,16}}) ->
"matrix()";
+doc_arg_type2(#type{base=string, single=list}) ->
+ "iolist()";
doc_arg_type2(T=#type{single={tuple,Sz}}) ->
"{" ++ args(fun doc_arg_type3/1, ",", lists:duplicate(Sz,T)) ++ "}";
doc_arg_type2(T=#type{single=list}) ->
diff --git a/lib/wx/api_gen/wx_extra/wxEvtHandler.c_src b/lib/wx/api_gen/wx_extra/wxEvtHandler.c_src
index 5e02066309..08fef1c2ff 100644
--- a/lib/wx/api_gen/wx_extra/wxEvtHandler.c_src
+++ b/lib/wx/api_gen/wx_extra/wxEvtHandler.c_src
@@ -42,11 +42,15 @@ case 101: { // wxEvtHandler::Disconnect
int eventType = wxeEventTypeFromAtom(bp); bp += *eventTypeLen;
if(eventType > 0) {
+ if(recurse_level > 1) {
+ delayed_delete->Append(Ecmd.Save());
+ } else {
bool Result = This->Disconnect((int) *winid,(int) *lastId,eventType,
(wxObjectEventFunction)(wxEventFunction)
&wxeEvtListener::forward,
NULL, Listener);
rt.addBool(Result);
+ }
} else {
rt.addAtom("badarg");
rt.addAtom("event_type");
diff --git a/lib/wx/api_gen/wx_gen_cpp.erl b/lib/wx/api_gen/wx_gen_cpp.erl
index 5649336b5d..ed7b27f3bf 100644
--- a/lib/wx/api_gen/wx_gen_cpp.erl
+++ b/lib/wx/api_gen/wx_gen_cpp.erl
@@ -1141,6 +1141,7 @@ gen_macros() ->
w("#include <wx/html/htmlcell.h>~n"),
w("#include <wx/filename.h>~n"),
w("#include <wx/sysopt.h>~n"),
+ w("#include <wx/overlay.h>~n"),
w("~n~n", []),
w("#ifndef wxICON_DEFAULT_BITMAP_TYPE~n",[]),
@@ -1276,6 +1277,11 @@ encode_events(Evs) ->
w(" } else {~n"),
w(" send_res = rt.send();~n"),
w(" if(cb->skip) event->Skip();~n"),
+ w(" if(app->recurse_level < 1) {~n"),
+ w(" app->recurse_level++;~n"),
+ w(" app->dispatch_cmds();~n"),
+ w(" app->recurse_level--;~n"),
+ w(" }~n"),
w(" };~n"),
w(" return send_res;~n"),
w(" }~n").
diff --git a/lib/wx/api_gen/wxapi.conf b/lib/wx/api_gen/wxapi.conf
index f076323bea..eabbec3297 100644
--- a/lib/wx/api_gen/wxapi.conf
+++ b/lib/wx/api_gen/wxapi.conf
@@ -367,7 +367,7 @@
{class,wxMirrorDC, wxDC, [], ['wxMirrorDC', '~wxMirrorDC']}.
{class,wxScreenDC, wxDC, [], ['wxScreenDC', '~wxScreenDC']}.
-{class,wxPostScriptDC,wxDC,[],
+{class,wxPostScriptDC,wxDC,[{ifdef, wxUSE_POSTSCRIPT}],
['wxPostScriptDC','~wxPostScriptDC',
{'SetResolution', [{deprecated, "!wxCHECK_VERSION(2,9,0)"}]},
{'GetResolution', [{deprecated, "!wxCHECK_VERSION(2,9,0)"}]}]}.
@@ -1975,3 +1975,9 @@
{class, wxMouseCaptureLostEvent, wxEvent,
[{event,[wxEVT_MOUSE_CAPTURE_LOST]}],[]}.
+
+{class, wxOverlay, root, [],
+ ['wxOverlay', '~wxOverlay', 'Reset']}.
+
+{class, wxDCOverlay, root, [],
+ ['wxDCOverlay', '~wxDCOverlay', 'Clear']}.
diff --git a/lib/wx/c_src/gen/wxe_derived_dest.h b/lib/wx/c_src/gen/wxe_derived_dest.h
index 03d1502c2a..1dcf029244 100644
--- a/lib/wx/c_src/gen/wxe_derived_dest.h
+++ b/lib/wx/c_src/gen/wxe_derived_dest.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2008-2014. All Rights Reserved.
+ * Copyright Ericsson AB 2008-2015. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -86,11 +86,13 @@ class EwxScreenDC : public wxScreenDC {
EwxScreenDC() : wxScreenDC() {};
};
+#if wxUSE_POSTSCRIPT
class EwxPostScriptDC : public wxPostScriptDC {
public: ~EwxPostScriptDC() {((WxeApp *)wxTheApp)->clearPtr(this);};
EwxPostScriptDC(const wxPrintData& printData) : wxPostScriptDC(printData) {};
EwxPostScriptDC() : wxPostScriptDC() {};
};
+#endif // wxUSE_POSTSCRIPT
class EwxWindowDC : public wxWindowDC {
public: ~EwxWindowDC() {((WxeApp *)wxTheApp)->clearPtr(this);};
@@ -787,3 +789,9 @@ class EwxPopupTransientWindow : public wxPopupTransientWindow {
};
#endif // wxUSE_POPUPWIN
+class EwxDCOverlay : public wxDCOverlay {
+ public: ~EwxDCOverlay() {((WxeApp *)wxTheApp)->clearPtr(this);};
+ EwxDCOverlay(wxOverlay& overlay,wxWindowDC * dc,int x,int y,int width,int height) : wxDCOverlay(overlay,dc,x,y,width,height) {};
+ EwxDCOverlay(wxOverlay& overlay,wxWindowDC * dc) : wxDCOverlay(overlay,dc) {};
+};
+
diff --git a/lib/wx/c_src/gen/wxe_events.cpp b/lib/wx/c_src/gen/wxe_events.cpp
index a532ee985d..4affe2ba53 100644
--- a/lib/wx/c_src/gen/wxe_events.cpp
+++ b/lib/wx/c_src/gen/wxe_events.cpp
@@ -897,6 +897,11 @@ case 235: {// wxMouseCaptureLostEvent
} else {
send_res = rt.send();
if(cb->skip) event->Skip();
+ if(app->recurse_level < 1) {
+ app->recurse_level++;
+ app->dispatch_cmds();
+ app->recurse_level--;
+ }
};
return send_res;
}
diff --git a/lib/wx/c_src/gen/wxe_funcs.cpp b/lib/wx/c_src/gen/wxe_funcs.cpp
index 3211664499..4025fb1c16 100644
--- a/lib/wx/c_src/gen/wxe_funcs.cpp
+++ b/lib/wx/c_src/gen/wxe_funcs.cpp
@@ -113,11 +113,15 @@ case 101: { // wxEvtHandler::Disconnect
int eventType = wxeEventTypeFromAtom(bp); bp += *eventTypeLen;
if(eventType > 0) {
+ if(recurse_level > 1) {
+ delayed_delete->Append(Ecmd.Save());
+ } else {
bool Result = This->Disconnect((int) *winid,(int) *lastId,eventType,
(wxObjectEventFunction)(wxEventFunction)
&wxeEvtListener::forward,
NULL, Listener);
rt.addBool(Result);
+ }
} else {
rt.addAtom("badarg");
rt.addAtom("event_type");
@@ -5856,6 +5860,7 @@ case wxScreenDC_new: { // wxScreenDC::wxScreenDC
rt.addRef(getRef((void *)Result,memenv), "wxScreenDC");
break;
}
+#if wxUSE_POSTSCRIPT
case wxPostScriptDC_new_0: { // wxPostScriptDC::wxPostScriptDC
wxPostScriptDC * Result = new EwxPostScriptDC();
newPtr((void *) Result, 4, memenv);
@@ -5883,6 +5888,7 @@ case wxPostScriptDC_GetResolution: { // wxPostScriptDC::GetResolution
break;
}
#endif
+#endif // wxUSE_POSTSCRIPT
#if !wxCHECK_VERSION(2,9,0)
case wxWindowDC_new_0: { // wxWindowDC::wxWindowDC
wxWindowDC * Result = new EwxWindowDC();
@@ -31959,6 +31965,56 @@ case wxPopupTransientWindow_Dismiss: { // wxPopupTransientWindow::Dismiss
break;
}
#endif // wxUSE_POPUPWIN
+case wxOverlay_new: { // wxOverlay::wxOverlay
+ wxOverlay * Result = new wxOverlay();
+ newPtr((void *) Result, 236, memenv);
+ rt.addRef(getRef((void *)Result,memenv), "wxOverlay");
+ break;
+}
+case wxOverlay_destruct: { // wxOverlay::~wxOverlay
+ wxOverlay *This = (wxOverlay *) getPtr(bp,memenv); bp += 4;
+ if(This) { ((WxeApp *) wxTheApp)->clearPtr((void *) This);
+ delete This;}
+ break;
+}
+case wxOverlay_Reset: { // wxOverlay::Reset
+ wxOverlay *This = (wxOverlay *) getPtr(bp,memenv); bp += 4;
+ if(!This) throw wxe_badarg(0);
+ This->Reset();
+ break;
+}
+case wxDCOverlay_new_6: { // wxDCOverlay::wxDCOverlay
+ wxOverlay *overlay = (wxOverlay *) getPtr(bp,memenv); bp += 4;
+ wxWindowDC *dc = (wxWindowDC *) getPtr(bp,memenv); bp += 4;
+ int * x = (int *) bp; bp += 4;
+ int * y = (int *) bp; bp += 4;
+ int * width = (int *) bp; bp += 4;
+ int * height = (int *) bp; bp += 4;
+ wxDCOverlay * Result = new EwxDCOverlay(*overlay,dc,*x,*y,*width,*height);
+ newPtr((void *) Result, 237, memenv);
+ rt.addRef(getRef((void *)Result,memenv), "wxDCOverlay");
+ break;
+}
+case wxDCOverlay_new_2: { // wxDCOverlay::wxDCOverlay
+ wxOverlay *overlay = (wxOverlay *) getPtr(bp,memenv); bp += 4;
+ wxWindowDC *dc = (wxWindowDC *) getPtr(bp,memenv); bp += 4;
+ wxDCOverlay * Result = new EwxDCOverlay(*overlay,dc);
+ newPtr((void *) Result, 237, memenv);
+ rt.addRef(getRef((void *)Result,memenv), "wxDCOverlay");
+ break;
+}
+case wxDCOverlay_destruct: { // wxDCOverlay::~wxDCOverlay
+ wxDCOverlay *This = (wxDCOverlay *) getPtr(bp,memenv); bp += 4;
+ if(This) { ((WxeApp *) wxTheApp)->clearPtr((void *) This);
+ delete This;}
+ break;
+}
+case wxDCOverlay_Clear: { // wxDCOverlay::Clear
+ wxDCOverlay *This = (wxDCOverlay *) getPtr(bp,memenv); bp += 4;
+ if(!This) throw wxe_badarg(0);
+ This->Clear();
+ break;
+}
default: {
wxeReturn error = wxeReturn(WXE_DRV_PORT, Ecmd.caller, false); error.addAtom("_wxe_error_");
error.addInt((int) Ecmd.op);
@@ -32005,6 +32061,8 @@ bool WxeApp::delete_object(void *ptr, wxeRefData *refd) {
case 215: /* delete (wxBitmapDataObject *) ptr;These objects must be deleted by owner object */ break;
case 227: delete (wxLogNull *) ptr; break;
case 231: delete (EwxLocale *) ptr; return false;
+ case 236: delete (wxOverlay *) ptr; break;
+ case 237: delete (EwxDCOverlay *) ptr; return false;
default: delete (wxObject *) ptr; return false;
}
return true;
diff --git a/lib/wx/c_src/gen/wxe_macros.h b/lib/wx/c_src/gen/wxe_macros.h
index 59f9c7054e..5f51ac5f91 100644
--- a/lib/wx/c_src/gen/wxe_macros.h
+++ b/lib/wx/c_src/gen/wxe_macros.h
@@ -64,6 +64,7 @@
#include <wx/html/htmlcell.h>
#include <wx/filename.h>
#include <wx/sysopt.h>
+#include <wx/overlay.h>
#ifndef wxICON_DEFAULT_BITMAP_TYPE
@@ -3411,5 +3412,12 @@
#define wxPopupTransientWindow_destruct 3583
#define wxPopupTransientWindow_Popup 3584
#define wxPopupTransientWindow_Dismiss 3585
+#define wxOverlay_new 3586
+#define wxOverlay_destruct 3587
+#define wxOverlay_Reset 3588
+#define wxDCOverlay_new_6 3589
+#define wxDCOverlay_new_2 3590
+#define wxDCOverlay_destruct 3591
+#define wxDCOverlay_Clear 3592
diff --git a/lib/wx/c_src/wxe_helpers.cpp b/lib/wx/c_src/wxe_helpers.cpp
index cc57374d5b..1696b8bd50 100644
--- a/lib/wx/c_src/wxe_helpers.cpp
+++ b/lib/wx/c_src/wxe_helpers.cpp
@@ -61,6 +61,7 @@ wxeFifo::wxeFifo(unsigned int sz)
m_max = sz;
m_n = 0;
m_first = 0;
+ cb_start = 0;
m_old = NULL;
for(unsigned int i = 0; i < sz; i++) {
m_q[i].buffer = NULL;
@@ -76,15 +77,30 @@ wxeFifo::~wxeFifo() {
wxeCommand * wxeFifo::Get()
{
unsigned int pos;
- if(m_n > 0) {
+ do {
+ if(m_n <= 0)
+ return NULL;
+
pos = m_first++;
m_n--;
m_first %= m_max;
- return &m_q[pos];
- }
- return NULL;
+ } while(m_q[pos].op == -1);
+ return &m_q[pos];
+}
+
+wxeCommand * wxeFifo::Peek(unsigned int *i)
+{
+ unsigned int pos;
+ do {
+ if(*i >= m_n || m_n <= 0)
+ return NULL;
+ pos = (m_first+*i) % m_max;
+ (*i)++;
+ } while(m_q[pos].op == -1);
+ return &m_q[pos];
}
+
void wxeFifo::Add(int fc, char * cbuf,int buflen, wxe_data *sd)
{
unsigned int pos;
@@ -140,10 +156,12 @@ void wxeFifo::Append(wxeCommand *orig)
pos = (m_first + m_n) % m_max;
m_n++;
+
curr = &m_q[pos];
+ curr->op = orig->op;
+ if(curr->op == -1) return;
curr->caller = orig->caller;
curr->port = orig->port;
- curr->op = orig->op;
curr->len = orig->len;
curr->bin[0] = orig->bin[0];
curr->bin[1] = orig->bin[1];
@@ -171,17 +189,19 @@ void wxeFifo::Realloc()
wxeCommand * old = m_q;
wxeCommand * queue = (wxeCommand *)driver_alloc(new_sz*sizeof(wxeCommand));
+ // fprintf(stderr, "\r\nrealloc qsz %d\r\n", new_sz);fflush(stderr);
+
m_max=new_sz;
m_first = 0;
m_n=0;
m_q = queue;
for(i=0; i < n; i++) {
- unsigned int pos = i+first;
- if(old[pos%max].op >= 0) {
- Append(&old[pos%max]);
- }
+ unsigned int pos = (i+first)%max;
+ if(old[pos].op >= 0)
+ Append(&old[pos]);
}
+
for(i = m_n; i < new_sz; i++) { // Reset the rest
m_q[i].buffer = NULL;
m_q[i].op = -1;
@@ -190,6 +210,26 @@ void wxeFifo::Realloc()
m_old = old;
}
+// Strip end of queue if ops are already taken care of, avoids reallocs
+void wxeFifo::Strip()
+{
+ while((m_n > 0) && (m_q[(m_first + m_n - 1)%m_max].op == -1)) {
+ m_n--;
+ }
+}
+
+unsigned int wxeFifo::Cleanup(unsigned int def)
+{
+ if(m_old) {
+ driver_free(m_old);
+ m_old = NULL;
+ // Realloced we need to start from the beginning
+ return 0;
+ } else {
+ return def;
+ }
+}
+
/* ****************************************************************************
* TreeItemData
* ****************************************************************************/
diff --git a/lib/wx/c_src/wxe_helpers.h b/lib/wx/c_src/wxe_helpers.h
index 4f9d9ca9c3..ff949e332b 100644
--- a/lib/wx/c_src/wxe_helpers.h
+++ b/lib/wx/c_src/wxe_helpers.h
@@ -67,9 +67,13 @@ class wxeFifo {
void Append(wxeCommand *Other);
wxeCommand * Get();
+ wxeCommand * Peek(unsigned int *item);
void Realloc();
+ void Strip();
+ unsigned int Cleanup(unsigned int peek=0);
+ unsigned int cb_start;
unsigned int m_max;
unsigned int m_first;
unsigned int m_n;
diff --git a/lib/wx/c_src/wxe_impl.cpp b/lib/wx/c_src/wxe_impl.cpp
index 5b34f08704..c5bad41573 100644
--- a/lib/wx/c_src/wxe_impl.cpp
+++ b/lib/wx/c_src/wxe_impl.cpp
@@ -57,10 +57,8 @@ extern ErlDrvTermData init_caller;
extern int wxe_status;
wxeFifo * wxe_queue = NULL;
-wxeFifo * wxe_queue_cb_saved = NULL;
unsigned int wxe_needs_signal = 0; // inside batch if larger than 0
-unsigned int wxe_cb_invoked = 0;
/* ************************************************************
* Commands from erlang
@@ -123,11 +121,10 @@ bool WxeApp::OnInit()
{
global_me = new wxeMemEnv();
- wxe_queue = new wxeFifo(1000);
- wxe_queue_cb_saved = new wxeFifo(200);
+ wxe_queue = new wxeFifo(2000);
cb_buff = NULL;
recurse_level = 0;
- delayed_delete = new wxeFifo(10);
+ delayed_delete = new wxeFifo(100);
delayed_cleanup = new wxList;
wxe_ps_init2();
@@ -173,7 +170,6 @@ void WxeApp::shutdown(wxeMetaCommand& Ecmd) {
wxe_status = WXE_EXITING;
ExitMainLoop();
delete wxe_queue;
- delete wxe_queue_cb_saved;
}
void WxeApp::dummy_close(wxEvent& Ev) {
@@ -229,12 +225,11 @@ void handle_event_callback(ErlDrvPort port, ErlDrvTermData process)
if(driver_monitor_process(port, process, &monitor) == 0) {
// Should we be able to handle commands when recursing? probably
// fprintf(stderr, "\r\nCB EV Start %lu \r\n", process);fflush(stderr);
- app->recurse_level++;
- app->dispatch_cb(wxe_queue, wxe_queue_cb_saved, process);
- app->recurse_level--;
+ app->recurse_level += 2;
+ app->dispatch_cb(wxe_queue, process);
+ app->recurse_level -= 2;
// fprintf(stderr, "CB EV done %lu \r\n", process);fflush(stderr);
driver_demonitor_process(port, &monitor);
- wxe_cb_invoked = 1;
}
}
@@ -242,16 +237,11 @@ void WxeApp::dispatch_cmds()
{
if(wxe_status != WXE_INITIATED)
return;
- do {
- wxe_cb_invoked = 0;
- recurse_level++;
- // fprintf(stderr, "\r\ndispatch_saved 0 \r\n");fflush(stderr);
- int level = dispatch(wxe_queue_cb_saved, 0, WXE_STORED);
- // fprintf(stderr, "\r\ndispatch_normal %d\r\n", level);fflush(stderr);
- dispatch(wxe_queue, level, WXE_NORMAL);
- // fprintf(stderr, "\r\ndispatch_done \r\n");fflush(stderr);
- recurse_level--;
- } while(wxe_cb_invoked);
+ recurse_level++;
+ // fprintf(stderr, "\r\ndispatch_normal %d\r\n", level);fflush(stderr);
+ dispatch(wxe_queue);
+ // fprintf(stderr, "\r\ndispatch_done \r\n");fflush(stderr);
+ recurse_level--;
// Cleanup old memenv's and deleted objects
if(recurse_level == 0) {
@@ -260,6 +250,7 @@ void WxeApp::dispatch_cmds()
wxe_dispatch(*curr);
curr->Delete();
}
+ delayed_delete->Cleanup();
if(delayed_cleanup->size() > 0)
for( wxList::compatibility_iterator node = delayed_cleanup->GetFirst();
node;
@@ -269,28 +260,19 @@ void WxeApp::dispatch_cmds()
destroyMemEnv(*event);
delete event;
}
- if(wxe_queue_cb_saved->m_old) {
- driver_free(wxe_queue_cb_saved->m_old);
- wxe_queue_cb_saved->m_old = NULL;
- }
- if(delayed_delete->m_old) {
- driver_free(delayed_delete->m_old);
- delayed_delete->m_old = NULL;
- }
}
}
-int WxeApp::dispatch(wxeFifo * batch, int blevel, int list_type)
+int WxeApp::dispatch(wxeFifo * batch)
{
int ping = 0;
+ int blevel = 0;
wxeCommand *event;
- if(list_type == WXE_NORMAL) erl_drv_mutex_lock(wxe_batch_locker_m);
+ erl_drv_mutex_lock(wxe_batch_locker_m);
while(true) {
while((event = batch->Get()) != NULL) {
- if(list_type == WXE_NORMAL) erl_drv_mutex_unlock(wxe_batch_locker_m);
+ erl_drv_mutex_unlock(wxe_batch_locker_m);
switch(event->op) {
- case -1:
- break;
case WXE_BATCH_END:
{--blevel; }
break;
@@ -321,20 +303,10 @@ int WxeApp::dispatch(wxeFifo * batch, int blevel, int list_type)
break;
}
event->Delete();
- if(list_type == WXE_NORMAL) {
- if(wxe_cb_invoked)
- return blevel;
- else
- erl_drv_mutex_lock(wxe_batch_locker_m);
- }
+ erl_drv_mutex_lock(wxe_batch_locker_m);
+ batch->Cleanup();
}
- if(list_type == WXE_STORED)
- return blevel;
- if(blevel <= 0) { // list_type == WXE_NORMAL
- if(wxe_queue->m_old) {
- driver_free(wxe_queue->m_old);
- wxe_queue->m_old = NULL;
- }
+ if(blevel <= 0) {
erl_drv_mutex_unlock(wxe_batch_locker_m);
return blevel;
}
@@ -348,12 +320,13 @@ int WxeApp::dispatch(wxeFifo * batch, int blevel, int list_type)
}
}
-void WxeApp::dispatch_cb(wxeFifo * batch, wxeFifo * temp, ErlDrvTermData process) {
+void WxeApp::dispatch_cb(wxeFifo * batch, ErlDrvTermData process) {
wxeCommand *event;
+ unsigned int peek;
erl_drv_mutex_lock(wxe_batch_locker_m);
+ peek = batch->Cleanup(batch->cb_start);
while(true) {
- while((event = batch->Get()) != NULL) {
- erl_drv_mutex_unlock(wxe_batch_locker_m);
+ while((event = batch->Peek(&peek)) != NULL) {
wxeMemEnv *memenv = getMemEnv(event->port);
// fprintf(stderr, " Ev %d %lu\r\n", event->op, event->caller);
if(event->caller == process || // Callbacks from CB process only
@@ -361,8 +334,8 @@ void WxeApp::dispatch_cb(wxeFifo * batch, wxeFifo * temp, ErlDrvTermData process
event->op == WXE_CB_DIED || // Event callback process died
// Allow connect_cb during CB i.e. msg from wxe_server.
(memenv && event->caller == memenv->owner)) {
+ erl_drv_mutex_unlock(wxe_batch_locker_m);
switch(event->op) {
- case -1:
case WXE_BATCH_END:
case WXE_BATCH_BEGIN:
case WXE_DEBUG_PING:
@@ -373,52 +346,42 @@ void WxeApp::dispatch_cb(wxeFifo * batch, wxeFifo * temp, ErlDrvTermData process
memcpy(cb_buff, event->buffer, event->len);
} // continue
case WXE_CB_DIED:
+ batch->cb_start = 0;
event->Delete();
+ erl_drv_mutex_lock(wxe_batch_locker_m);
+ batch->Strip();
+ erl_drv_mutex_unlock(wxe_batch_locker_m);
return;
case WXE_CB_START:
// CB start from now accept message from CB process only
process = event->caller;
break;
default:
- size_t start=temp->m_n;
+ batch->cb_start = peek; // In case of recursive callbacks
if(event->op < OPENGL_START) {
- // fprintf(stderr, " cb %d \r\n", event->op);
wxe_dispatch(*event);
} else {
gl_dispatch(event->op,event->buffer,event->caller,event->bin);
}
- if(temp->m_n > start) {
- erl_drv_mutex_lock(wxe_batch_locker_m);
- // We have recursed dispatch_cb and messages for this
- // callback may be saved on temp list move them
- // to orig list
- for(unsigned int i=start; i < temp->m_n; i++) {
- wxeCommand *ev = &temp->m_q[(temp->m_first+i) % temp->m_max];
- if(ev->caller == process) {
- batch->Append(ev);
- }
- }
- erl_drv_mutex_unlock(wxe_batch_locker_m);
- }
break;
}
event->Delete();
- } else {
- // fprintf(stderr, " save %d %lu\r\n", event->op, event->caller);
- temp->Append(event);
+ erl_drv_mutex_lock(wxe_batch_locker_m);
+ peek = batch->Cleanup(peek);
}
- erl_drv_mutex_lock(wxe_batch_locker_m);
}
// sleep until something happens
// fprintf(stderr, "%s:%d sleep %d %d\r\n", __FILE__, __LINE__,
- // batch->m_n, temp->m_n);fflush(stderr);
+ // peek, batch->m_n);fflush(stderr);
wxe_needs_signal = 1;
- while(batch->m_n == 0) {
+ while(peek >= batch->m_n) {
erl_drv_cond_wait(wxe_batch_locker_c, wxe_batch_locker_m);
+ peek = batch->Cleanup(peek);
}
wxe_needs_signal = 0;
}
}
+
/* Memory handling */
void WxeApp::newMemEnv(wxeMetaCommand& Ecmd) {
diff --git a/lib/wx/c_src/wxe_impl.h b/lib/wx/c_src/wxe_impl.h
index d6d3095a0f..fd25296c73 100644
--- a/lib/wx/c_src/wxe_impl.h
+++ b/lib/wx/c_src/wxe_impl.h
@@ -67,8 +67,8 @@ public:
void shutdown(wxeMetaCommand& event);
- int dispatch(wxeFifo *, int, int);
- void dispatch_cb(wxeFifo * batch, wxeFifo * temp, ErlDrvTermData process);
+ int dispatch(wxeFifo *);
+ void dispatch_cb(wxeFifo * batch, ErlDrvTermData process);
void wxe_dispatch(wxeCommand& event);
diff --git a/lib/wx/examples/demo/ex_canvas.erl b/lib/wx/examples/demo/ex_canvas.erl
index 1cbb96de1f..cdc783055c 100644
--- a/lib/wx/examples/demo/ex_canvas.erl
+++ b/lib/wx/examples/demo/ex_canvas.erl
@@ -35,7 +35,9 @@
parent,
config,
canvas,
- bitmap
+ bitmap,
+ overlay,
+ pos
}).
start(Config) ->
@@ -60,6 +62,10 @@ do_init(Config) ->
wxPanel:connect(Canvas, paint, [callback]),
wxPanel:connect(Canvas, size),
+ wxPanel:connect(Canvas, left_down),
+ wxPanel:connect(Canvas, left_up),
+ wxPanel:connect(Canvas, motion),
+
wxPanel:connect(Button, command_button_clicked),
%% Add to sizers
@@ -78,7 +84,9 @@ do_init(Config) ->
Bitmap = wxBitmap:new(erlang:max(W,30),erlang:max(30,H)),
{Panel, #state{parent=Panel, config=Config,
- canvas = Canvas, bitmap = Bitmap}}.
+ canvas = Canvas, bitmap = Bitmap,
+ overlay = wxOverlay:new()
+ }}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Sync event from callback events, paint event must be handled in callbacks
@@ -127,11 +135,39 @@ handle_event(#wx{event = #wxCommand{type = command_button_clicked}},
wxBitmap:destroy(Bmp),
{noreply, State};
handle_event(#wx{event = #wxSize{size={W,H}}},
- State = #state{bitmap=Prev}) ->
+ State = #state{bitmap=Prev, canvas=Canvas}) ->
Bitmap = wxBitmap:new(W,H),
- draw(State#state.canvas, Bitmap, fun(DC) -> wxDC:clear(DC) end),
+ draw(Canvas, Bitmap, fun(DC) -> wxDC:clear(DC) end),
wxBitmap:destroy(Prev),
{noreply, State#state{bitmap = Bitmap}};
+
+handle_event(#wx{event = #wxMouse{type=left_down, x=X, y=Y}}, State) ->
+ {noreply, State#state{pos={X,Y}}};
+handle_event(#wx{event = #wxMouse{type=motion, x=X1, y=Y1}},
+ #state{pos=Start, overlay=Overlay, canvas=Canvas} = State) ->
+ case Start of
+ undefined -> ignore;
+ {X0,Y0} ->
+ DC = wxClientDC:new(Canvas),
+ DCO = wxDCOverlay:new(Overlay, DC),
+ wxDCOverlay:clear(DCO),
+ wxDC:setPen(DC, ?wxLIGHT_GREY_PEN),
+ wxDC:setBrush(DC, ?wxTRANSPARENT_BRUSH),
+ wxDC:drawRectangle(DC, {X0,Y0, X1-X0, Y1-Y0}),
+ wxDCOverlay:destroy(DCO),
+ wxClientDC:destroy(DC)
+ end,
+ {noreply, State};
+handle_event(#wx{event = #wxMouse{type=left_up}},
+ #state{overlay=Overlay, canvas=Canvas} = State) ->
+ DC = wxClientDC:new(Canvas),
+ DCO = wxDCOverlay:new(Overlay, DC),
+ wxDCOverlay:clear(DCO),
+ wxDCOverlay:destroy(DCO),
+ wxClientDC:destroy(DC),
+ wxOverlay:reset(Overlay),
+ {noreply, State#state{pos=undefined}};
+
handle_event(Ev = #wx{}, State = #state{}) ->
demo:format(State#state.config, "Got Event ~p\n", [Ev]),
{noreply, State}.
@@ -155,7 +191,8 @@ handle_cast(Msg, State) ->
code_change(_, _, State) ->
{stop, ignore, State}.
-terminate(_Reason, _) ->
+terminate(_Reason, #state{overlay=Overlay}) ->
+ wxOverlay:destroy(Overlay),
ok.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/wx/src/gen/gl.erl b/lib/wx/src/gen/gl.erl
index 58cdb59aa2..bedd4e9cca 100644
--- a/lib/wx/src/gen/gl.erl
+++ b/lib/wx/src/gen/gl.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -53,10 +53,14 @@
-type enum() :: non_neg_integer(). %% See wx/include/gl.hrl
-type clamp() :: float(). %% 0.0..1.0
-type offset() :: non_neg_integer(). %% Offset in memory block
--type matrix() :: {float(),float(),float(),float(),
+-type matrix12() :: {float(),float(),float(),float(),
+ float(),float(),float(),float(),
+ float(),float(),float(),float()}.
+-type matrix16() :: {float(),float(),float(),float(),
float(),float(),float(),float(),
float(),float(),float(),float(),
float(),float(),float(),float()}.
+-type matrix() :: matrix12() | matrix16().
-type mem() :: binary() | tuple(). %% Memory block
-export([clearIndex/1,clearColor/4,clear/1,indexMask/1,colorMask/4,alphaFunc/2,
@@ -4289,14 +4293,14 @@ lighti(Light,Pname,Param) ->
%% @doc
%% See {@link lightf/3}
--spec lightfv(Light, Pname, Params) -> ok when Light :: enum(),Pname :: enum(),Params :: {float()}.
+-spec lightfv(Light, Pname, Params) -> ok when Light :: enum(),Pname :: enum(),Params :: tuple().
lightfv(Light,Pname,Params) ->
cast(5207, <<Light:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLfloat>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
%% @doc
%% See {@link lightf/3}
--spec lightiv(Light, Pname, Params) -> ok when Light :: enum(),Pname :: enum(),Params :: {integer()}.
+-spec lightiv(Light, Pname, Params) -> ok when Light :: enum(),Pname :: enum(),Params :: tuple().
lightiv(Light,Pname,Params) ->
cast(5208, <<Light:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
@@ -4460,14 +4464,14 @@ lightModeli(Pname,Param) ->
%% @doc
%% See {@link lightModelf/2}
--spec lightModelfv(Pname, Params) -> ok when Pname :: enum(),Params :: {float()}.
+-spec lightModelfv(Pname, Params) -> ok when Pname :: enum(),Params :: tuple().
lightModelfv(Pname,Params) ->
cast(5213, <<Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLfloat>> ||C <- tuple_to_list(Params)>>)/binary,0:(((0+size(Params)) rem 2)*32)>>).
%% @doc
%% See {@link lightModelf/2}
--spec lightModeliv(Pname, Params) -> ok when Pname :: enum(),Params :: {integer()}.
+-spec lightModeliv(Pname, Params) -> ok when Pname :: enum(),Params :: tuple().
lightModeliv(Pname,Params) ->
cast(5214, <<Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((0+size(Params)) rem 2)*32)>>).
@@ -4547,14 +4551,14 @@ materiali(Face,Pname,Param) ->
%% @doc
%% See {@link materialf/3}
--spec materialfv(Face, Pname, Params) -> ok when Face :: enum(),Pname :: enum(),Params :: {float()}.
+-spec materialfv(Face, Pname, Params) -> ok when Face :: enum(),Pname :: enum(),Params :: tuple().
materialfv(Face,Pname,Params) ->
cast(5217, <<Face:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLfloat>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
%% @doc
%% See {@link materialf/3}
--spec materialiv(Face, Pname, Params) -> ok when Face :: enum(),Pname :: enum(),Params :: {integer()}.
+-spec materialiv(Face, Pname, Params) -> ok when Face :: enum(),Pname :: enum(),Params :: tuple().
materialiv(Face,Pname,Params) ->
cast(5218, <<Face:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
@@ -5890,21 +5894,21 @@ texGeni(Coord,Pname,Param) ->
%% @doc
%% See {@link texGend/3}
--spec texGendv(Coord, Pname, Params) -> ok when Coord :: enum(),Pname :: enum(),Params :: {float()}.
+-spec texGendv(Coord, Pname, Params) -> ok when Coord :: enum(),Pname :: enum(),Params :: tuple().
texGendv(Coord,Pname,Params) ->
cast(5246, <<Coord:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,0:32,
(<< <<C:?GLdouble>> ||C <- tuple_to_list(Params)>>)/binary>>).
%% @doc
%% See {@link texGend/3}
--spec texGenfv(Coord, Pname, Params) -> ok when Coord :: enum(),Pname :: enum(),Params :: {float()}.
+-spec texGenfv(Coord, Pname, Params) -> ok when Coord :: enum(),Pname :: enum(),Params :: tuple().
texGenfv(Coord,Pname,Params) ->
cast(5247, <<Coord:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLfloat>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
%% @doc
%% See {@link texGend/3}
--spec texGeniv(Coord, Pname, Params) -> ok when Coord :: enum(),Pname :: enum(),Params :: {integer()}.
+-spec texGeniv(Coord, Pname, Params) -> ok when Coord :: enum(),Pname :: enum(),Params :: tuple().
texGeniv(Coord,Pname,Params) ->
cast(5248, <<Coord:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
@@ -6123,14 +6127,14 @@ texEnvi(Target,Pname,Param) ->
%% replacement. The default value is `?GL_FALSE'.
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexEnv.xml">external</a> documentation.
--spec texEnvfv(Target, Pname, Params) -> ok when Target :: enum(),Pname :: enum(),Params :: {float()}.
+-spec texEnvfv(Target, Pname, Params) -> ok when Target :: enum(),Pname :: enum(),Params :: tuple().
texEnvfv(Target,Pname,Params) ->
cast(5254, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLfloat>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
%% @doc
%% See {@link texEnvfv/3}
--spec texEnviv(Target, Pname, Params) -> ok when Target :: enum(),Pname :: enum(),Params :: {integer()}.
+-spec texEnviv(Target, Pname, Params) -> ok when Target :: enum(),Pname :: enum(),Params :: tuple().
texEnviv(Target,Pname,Params) ->
cast(5255, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
@@ -6455,14 +6459,14 @@ texParameteri(Target,Pname,Param) ->
%% @doc
%% See {@link texParameterf/3}
--spec texParameterfv(Target, Pname, Params) -> ok when Target :: enum(),Pname :: enum(),Params :: {float()}.
+-spec texParameterfv(Target, Pname, Params) -> ok when Target :: enum(),Pname :: enum(),Params :: tuple().
texParameterfv(Target,Pname,Params) ->
cast(5260, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLfloat>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
%% @doc
%% See {@link texParameterf/3}
--spec texParameteriv(Target, Pname, Params) -> ok when Target :: enum(),Pname :: enum(),Params :: {integer()}.
+-spec texParameteriv(Target, Pname, Params) -> ok when Target :: enum(),Pname :: enum(),Params :: tuple().
texParameteriv(Target,Pname,Params) ->
cast(5261, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
@@ -7609,14 +7613,14 @@ fogi(Pname,Param) ->
%% @doc
%% See {@link fogf/2}
--spec fogfv(Pname, Params) -> ok when Pname :: enum(),Params :: {float()}.
+-spec fogfv(Pname, Params) -> ok when Pname :: enum(),Params :: tuple().
fogfv(Pname,Params) ->
cast(5306, <<Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLfloat>> ||C <- tuple_to_list(Params)>>)/binary,0:(((0+size(Params)) rem 2)*32)>>).
%% @doc
%% See {@link fogf/2}
--spec fogiv(Pname, Params) -> ok when Pname :: enum(),Params :: {integer()}.
+-spec fogiv(Pname, Params) -> ok when Pname :: enum(),Params :: tuple().
fogiv(Pname,Params) ->
cast(5307, <<Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((0+size(Params)) rem 2)*32)>>).
@@ -8522,24 +8526,24 @@ convolutionFilter2D(Target,Internalformat,Width,Height,Format,Type,Image) ->
%% image were replicated.
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glConvolutionParameter.xml">external</a> documentation.
--spec convolutionParameterf(Target, Pname, Params) -> ok when Target :: enum(),Pname :: enum(),Params :: {float()}.
+-spec convolutionParameterf(Target, Pname, Params) -> ok when Target :: enum(),Pname :: enum(),Params :: tuple().
convolutionParameterf(Target,Pname,Params) ->
cast(5339, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLfloat>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
%% @equiv convolutionParameterf(Target,Pname,Params)
--spec convolutionParameterfv(Target :: enum(),Pname :: enum(),Params) -> ok when Params :: {Params :: {float()}}.
+-spec convolutionParameterfv(Target :: enum(),Pname :: enum(),Params) -> ok when Params :: {Params :: tuple()}.
convolutionParameterfv(Target,Pname,{Params}) -> convolutionParameterf(Target,Pname,Params).
%% @doc
%% See {@link convolutionParameterf/3}
--spec convolutionParameteri(Target, Pname, Params) -> ok when Target :: enum(),Pname :: enum(),Params :: {integer()}.
+-spec convolutionParameteri(Target, Pname, Params) -> ok when Target :: enum(),Pname :: enum(),Params :: tuple().
convolutionParameteri(Target,Pname,Params) ->
cast(5340, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
%% @equiv convolutionParameteri(Target,Pname,Params)
--spec convolutionParameteriv(Target :: enum(),Pname :: enum(),Params) -> ok when Params :: {Params :: {integer()}}.
+-spec convolutionParameteriv(Target :: enum(),Pname :: enum(),Params) -> ok when Params :: {Params :: tuple()}.
convolutionParameteriv(Target,Pname,{Params}) -> convolutionParameteri(Target,Pname,Params).
%% @doc Copy pixels into a one-dimensional convolution filter
@@ -9671,7 +9675,7 @@ pointParameterf(Pname,Param) ->
%% @doc
%% See {@link pointParameterf/2}
--spec pointParameterfv(Pname, Params) -> ok when Pname :: enum(),Params :: {float()}.
+-spec pointParameterfv(Pname, Params) -> ok when Pname :: enum(),Params :: tuple().
pointParameterfv(Pname,Params) ->
cast(5397, <<Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLfloat>> ||C <- tuple_to_list(Params)>>)/binary,0:(((0+size(Params)) rem 2)*32)>>).
@@ -9684,7 +9688,7 @@ pointParameteri(Pname,Param) ->
%% @doc
%% See {@link pointParameterf/2}
--spec pointParameteriv(Pname, Params) -> ok when Pname :: enum(),Params :: {integer()}.
+-spec pointParameteriv(Pname, Params) -> ok when Pname :: enum(),Params :: tuple().
pointParameteriv(Pname,Params) ->
cast(5399, <<Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((0+size(Params)) rem 2)*32)>>).
@@ -11529,7 +11533,7 @@ linkProgram(Program) ->
%% scanned or parsed at this time; they are simply copied into the specified shader object.
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glShaderSource.xml">external</a> documentation.
--spec shaderSource(Shader, String) -> ok when Shader :: integer(),String :: [string()].
+-spec shaderSource(Shader, String) -> ok when Shader :: integer(),String :: iolist().
shaderSource(Shader,String) ->
StringTemp = list_to_binary([[Str|[0]] || Str <- String ]),
cast(5473, <<Shader:?GLuint,(length(String)):?GLuint,(size(StringTemp)):?GLuint,(StringTemp)/binary,0:((8-((size(StringTemp)+0) rem 8)) rem 8)>>).
@@ -12278,7 +12282,7 @@ bindBufferBase(Target,Index,Buffer) ->
%% and the buffer mode is `?GL_INTERLEAVED_ATTRIBS'.
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTransformFeedbackVaryings.xml">external</a> documentation.
--spec transformFeedbackVaryings(Program, Varyings, BufferMode) -> ok when Program :: integer(),Varyings :: [string()],BufferMode :: enum().
+-spec transformFeedbackVaryings(Program, Varyings, BufferMode) -> ok when Program :: integer(),Varyings :: iolist(),BufferMode :: enum().
transformFeedbackVaryings(Program,Varyings,BufferMode) ->
VaryingsTemp = list_to_binary([[Str|[0]] || Str <- Varyings ]),
cast(5536, <<Program:?GLuint,(length(Varyings)):?GLuint,(size(VaryingsTemp)):?GLuint,(VaryingsTemp)/binary,0:((8-((size(VaryingsTemp)+0) rem 8)) rem 8),BufferMode:?GLenum>>).
@@ -12596,7 +12600,7 @@ uniform4uiv(Location,Value) ->
%% @doc
%% See {@link texParameterf/3}
--spec texParameterIiv(Target, Pname, Params) -> ok when Target :: enum(),Pname :: enum(),Params :: {integer()}.
+-spec texParameterIiv(Target, Pname, Params) -> ok when Target :: enum(),Pname :: enum(),Params :: tuple().
texParameterIiv(Target,Pname,Params) ->
cast(5568, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
@@ -12604,7 +12608,7 @@ texParameterIiv(Target,Pname,Params) ->
%% @doc glTexParameterI
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexParameterI.xml">external</a> documentation.
--spec texParameterIuiv(Target, Pname, Params) -> ok when Target :: enum(),Pname :: enum(),Params :: {integer()}.
+-spec texParameterIuiv(Target, Pname, Params) -> ok when Target :: enum(),Pname :: enum(),Params :: tuple().
texParameterIuiv(Target,Pname,Params) ->
cast(5569, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLuint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
@@ -12651,21 +12655,21 @@ getTexParameterIuiv(Target,Pname) ->
%% and the buffer being cleared is defined. However, this is not an error.
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClearBuffer.xml">external</a> documentation.
--spec clearBufferiv(Buffer, Drawbuffer, Value) -> ok when Buffer :: enum(),Drawbuffer :: integer(),Value :: {integer()}.
+-spec clearBufferiv(Buffer, Drawbuffer, Value) -> ok when Buffer :: enum(),Drawbuffer :: integer(),Value :: tuple().
clearBufferiv(Buffer,Drawbuffer,Value) ->
cast(5572, <<Buffer:?GLenum,Drawbuffer:?GLint,(size(Value)):?GLuint,
(<< <<C:?GLint>> ||C <- tuple_to_list(Value)>>)/binary,0:(((1+size(Value)) rem 2)*32)>>).
%% @doc
%% See {@link clearBufferiv/3}
--spec clearBufferuiv(Buffer, Drawbuffer, Value) -> ok when Buffer :: enum(),Drawbuffer :: integer(),Value :: {integer()}.
+-spec clearBufferuiv(Buffer, Drawbuffer, Value) -> ok when Buffer :: enum(),Drawbuffer :: integer(),Value :: tuple().
clearBufferuiv(Buffer,Drawbuffer,Value) ->
cast(5573, <<Buffer:?GLenum,Drawbuffer:?GLint,(size(Value)):?GLuint,
(<< <<C:?GLuint>> ||C <- tuple_to_list(Value)>>)/binary,0:(((1+size(Value)) rem 2)*32)>>).
%% @doc
%% See {@link clearBufferiv/3}
--spec clearBufferfv(Buffer, Drawbuffer, Value) -> ok when Buffer :: enum(),Drawbuffer :: integer(),Value :: {float()}.
+-spec clearBufferfv(Buffer, Drawbuffer, Value) -> ok when Buffer :: enum(),Drawbuffer :: integer(),Value :: tuple().
clearBufferfv(Buffer,Drawbuffer,Value) ->
cast(5574, <<Buffer:?GLenum,Drawbuffer:?GLint,(size(Value)):?GLuint,
(<< <<C:?GLfloat>> ||C <- tuple_to_list(Value)>>)/binary,0:(((1+size(Value)) rem 2)*32)>>).
@@ -13219,7 +13223,7 @@ createShaderObjectARB(ShaderType) ->
%% @doc glShaderSourceARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glShaderSourceARB.xml">external</a> documentation.
--spec shaderSourceARB(ShaderObj, String) -> ok when ShaderObj :: integer(),String :: [string()].
+-spec shaderSourceARB(ShaderObj, String) -> ok when ShaderObj :: integer(),String :: iolist().
shaderSourceARB(ShaderObj,String) ->
StringTemp = list_to_binary([[Str|[0]] || Str <- String ]),
cast(5630, <<ShaderObj:?GLhandleARB,(length(String)):?GLuint,(size(StringTemp)):?GLuint,(StringTemp)/binary,0:((8-((size(StringTemp)+4) rem 8)) rem 8)>>).
@@ -13927,7 +13931,7 @@ isVertexArray(Array) ->
%% If an error occurs, nothing is written to `UniformIndices' .
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniformIndices.xml">external</a> documentation.
--spec getUniformIndices(Program, UniformNames) -> [integer()] when Program :: integer(),UniformNames :: [string()].
+-spec getUniformIndices(Program, UniformNames) -> [integer()] when Program :: integer(),UniformNames :: iolist().
getUniformIndices(Program,UniformNames) ->
UniformNamesTemp = list_to_binary([[Str|[0]] || Str <- UniformNames ]),
call(5675, <<Program:?GLuint,(length(UniformNames)):?GLuint,(size(UniformNamesTemp)):?GLuint,(UniformNamesTemp)/binary,0:((8-((size(UniformNamesTemp)+0) rem 8)) rem 8)>>).
@@ -14458,7 +14462,7 @@ deleteNamedStringARB(Name) ->
%% @doc glCompileShaderIncludeARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCompileShaderIncludeARB.xml">external</a> documentation.
--spec compileShaderIncludeARB(Shader, Path) -> ok when Shader :: integer(),Path :: [string()].
+-spec compileShaderIncludeARB(Shader, Path) -> ok when Shader :: integer(),Path :: iolist().
compileShaderIncludeARB(Shader,Path) ->
PathTemp = list_to_binary([[Str|[0]] || Str <- Path ]),
cast(5703, <<Shader:?GLuint,(length(Path)):?GLuint,(size(PathTemp)):?GLuint,(PathTemp)/binary,0:((8-((size(PathTemp)+0) rem 8)) rem 8)>>).
@@ -15617,7 +15621,7 @@ activeShaderProgram(Pipeline,Program) ->
%% @doc glCreateShaderProgramv
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCreateShaderProgramv.xml">external</a> documentation.
--spec createShaderProgramv(Type, Strings) -> integer() when Type :: enum(),Strings :: [string()].
+-spec createShaderProgramv(Type, Strings) -> integer() when Type :: enum(),Strings :: iolist().
createShaderProgramv(Type,Strings) ->
StringsTemp = list_to_binary([[Str|[0]] || Str <- Strings ]),
call(5778, <<Type:?GLenum,(length(Strings)):?GLuint,(size(StringsTemp)):?GLuint,(StringsTemp)/binary,0:((8-((size(StringsTemp)+0) rem 8)) rem 8)>>).
diff --git a/lib/wx/src/gen/glu.erl b/lib/wx/src/gen/glu.erl
index 6a6e20b3e4..5faba48930 100644
--- a/lib/wx/src/gen/glu.erl
+++ b/lib/wx/src/gen/glu.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -51,10 +51,14 @@
-define(GLint64,64/native-signed).
-type vertex() :: {float(), float(), float()}.
-type enum() :: non_neg_integer(). %% See wx/include/gl.hrl or glu.hrl
--type matrix() :: {float(),float(),float(),float(),
+-type matrix12() :: {float(),float(),float(),float(),
+ float(),float(),float(),float(),
+ float(),float(),float(),float()}.
+-type matrix16() :: {float(),float(),float(),float(),
float(),float(),float(),float(),
float(),float(),float(),float(),
float(),float(),float(),float()}.
+-type matrix() :: matrix12() | matrix16().
-type mem() :: binary() | tuple(). %% Memory block
-export([tesselate/2,build1DMipmapLevels/9,build1DMipmaps/6,build2DMipmapLevels/10,
diff --git a/lib/wx/src/gen/wxDCOverlay.erl b/lib/wx/src/gen/wxDCOverlay.erl
new file mode 100644
index 0000000000..f98e310ba6
--- /dev/null
+++ b/lib/wx/src/gen/wxDCOverlay.erl
@@ -0,0 +1,70 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%% This file is generated DO NOT EDIT
+
+%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxdcoverlay.html">wxDCOverlay</a>.
+%% @type wxDCOverlay(). An object reference, The representation is internal
+%% and can be changed without notice. It can't be used for comparsion
+%% stored on disc or distributed for use on other nodes.
+
+-module(wxDCOverlay).
+-include("wxe.hrl").
+-export([clear/1,destroy/1,new/2,new/6]).
+
+%% inherited exports
+-export([parent_class/1]).
+
+-export_type([wxDCOverlay/0]).
+%% @hidden
+parent_class(_Class) -> erlang:error({badtype, ?MODULE}).
+
+-type wxDCOverlay() :: wx:wx_object().
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxdcoverlay.html#wxdcoverlaywxdcoverlay">external documentation</a>.
+-spec new(Overlay, Dc) -> wxDCOverlay() when
+ Overlay::wxOverlay:wxOverlay(), Dc::wxWindowDC:wxWindowDC().
+new(#wx_ref{type=OverlayT,ref=OverlayRef},#wx_ref{type=DcT,ref=DcRef}) ->
+ ?CLASS(OverlayT,wxOverlay),
+ ?CLASS(DcT,wxWindowDC),
+ wxe_util:construct(?wxDCOverlay_new_2,
+ <<OverlayRef:32/?UI,DcRef:32/?UI>>).
+
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxdcoverlay.html#wxdcoverlaywxdcoverlay">external documentation</a>.
+-spec new(Overlay, Dc, X, Y, Width, Height) -> wxDCOverlay() when
+ Overlay::wxOverlay:wxOverlay(), Dc::wxWindowDC:wxWindowDC(), X::integer(), Y::integer(), Width::integer(), Height::integer().
+new(#wx_ref{type=OverlayT,ref=OverlayRef},#wx_ref{type=DcT,ref=DcRef},X,Y,Width,Height)
+ when is_integer(X),is_integer(Y),is_integer(Width),is_integer(Height) ->
+ ?CLASS(OverlayT,wxOverlay),
+ ?CLASS(DcT,wxWindowDC),
+ wxe_util:construct(?wxDCOverlay_new_6,
+ <<OverlayRef:32/?UI,DcRef:32/?UI,X:32/?UI,Y:32/?UI,Width:32/?UI,Height:32/?UI>>).
+
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxdcoverlay.html#wxdcoverlayclear">external documentation</a>.
+-spec clear(This) -> ok when
+ This::wxDCOverlay().
+clear(#wx_ref{type=ThisT,ref=ThisRef}) ->
+ ?CLASS(ThisT,wxDCOverlay),
+ wxe_util:cast(?wxDCOverlay_Clear,
+ <<ThisRef:32/?UI>>).
+
+%% @doc Destroys this object, do not use object again
+-spec destroy(This::wxDCOverlay()) -> ok.
+destroy(Obj=#wx_ref{type=Type}) ->
+ ?CLASS(Type,wxDCOverlay),
+ wxe_util:destroy(?wxDCOverlay_destruct,Obj),
+ ok.
diff --git a/lib/wx/src/gen/wxOverlay.erl b/lib/wx/src/gen/wxOverlay.erl
new file mode 100644
index 0000000000..7da3ece657
--- /dev/null
+++ b/lib/wx/src/gen/wxOverlay.erl
@@ -0,0 +1,57 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%% This file is generated DO NOT EDIT
+
+%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxoverlay.html">wxOverlay</a>.
+%% @type wxOverlay(). An object reference, The representation is internal
+%% and can be changed without notice. It can't be used for comparsion
+%% stored on disc or distributed for use on other nodes.
+
+-module(wxOverlay).
+-include("wxe.hrl").
+-export([destroy/1,new/0,reset/1]).
+
+%% inherited exports
+-export([parent_class/1]).
+
+-export_type([wxOverlay/0]).
+%% @hidden
+parent_class(_Class) -> erlang:error({badtype, ?MODULE}).
+
+-type wxOverlay() :: wx:wx_object().
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxoverlay.html#wxoverlaywxoverlay">external documentation</a>.
+-spec new() -> wxOverlay().
+new() ->
+ wxe_util:construct(?wxOverlay_new,
+ <<>>).
+
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxoverlay.html#wxoverlayreset">external documentation</a>.
+-spec reset(This) -> ok when
+ This::wxOverlay().
+reset(#wx_ref{type=ThisT,ref=ThisRef}) ->
+ ?CLASS(ThisT,wxOverlay),
+ wxe_util:cast(?wxOverlay_Reset,
+ <<ThisRef:32/?UI>>).
+
+%% @doc Destroys this object, do not use object again
+-spec destroy(This::wxOverlay()) -> ok.
+destroy(Obj=#wx_ref{type=Type}) ->
+ ?CLASS(Type,wxOverlay),
+ wxe_util:destroy(?wxOverlay_destruct,Obj),
+ ok.
diff --git a/lib/wx/src/gen/wxe_debug.hrl b/lib/wx/src/gen/wxe_debug.hrl
index 2cb73c0fed..6c7602acd3 100644
--- a/lib/wx/src/gen/wxe_debug.hrl
+++ b/lib/wx/src/gen/wxe_debug.hrl
@@ -3363,6 +3363,13 @@ wxdebug_table() ->
{3583, {wxPopupTransientWindow, destruct, 0}},
{3584, {wxPopupTransientWindow, popup, 1}},
{3585, {wxPopupTransientWindow, dismiss, 0}},
+ {3586, {wxOverlay, new, 0}},
+ {3587, {wxOverlay, destruct, 0}},
+ {3588, {wxOverlay, reset, 0}},
+ {3589, {wxDCOverlay, new_6, 6}},
+ {3590, {wxDCOverlay, new_2, 2}},
+ {3591, {wxDCOverlay, destruct, 0}},
+ {3592, {wxDCOverlay, clear, 0}},
{-1, {mod, func, -1}}
].
diff --git a/lib/wx/src/gen/wxe_funcs.hrl b/lib/wx/src/gen/wxe_funcs.hrl
index d8c2ba9171..3a34cd494d 100644
--- a/lib/wx/src/gen/wxe_funcs.hrl
+++ b/lib/wx/src/gen/wxe_funcs.hrl
@@ -3360,3 +3360,10 @@
-define(wxPopupTransientWindow_destruct, 3583).
-define(wxPopupTransientWindow_Popup, 3584).
-define(wxPopupTransientWindow_Dismiss, 3585).
+-define(wxOverlay_new, 3586).
+-define(wxOverlay_destruct, 3587).
+-define(wxOverlay_Reset, 3588).
+-define(wxDCOverlay_new_6, 3589).
+-define(wxDCOverlay_new_2, 3590).
+-define(wxDCOverlay_destruct, 3591).
+-define(wxDCOverlay_Clear, 3592).
diff --git a/lib/wx/src/wxe_server.erl b/lib/wx/src/wxe_server.erl
index cc253b1143..ae9440f890 100644
--- a/lib/wx/src/wxe_server.erl
+++ b/lib/wx/src/wxe_server.erl
@@ -352,25 +352,8 @@ handle_disconnect(Object, Evh = #evh{cb=Fun}, From,
State0 = #state{users=Users0, cb=Callbacks}) ->
#user{events=Evs0} = gb_trees:get(From, Users0),
FunId = gb_trees:lookup(Fun, Callbacks),
- case find_handler(Evs0, Object, Evh#evh{cb=FunId}) of
- [] ->
- {reply, false, State0};
- Handlers ->
- case disconnect(Object,Handlers) of
- #evh{} -> {reply, true, State0};
- Result -> {reply, Result, State0}
- end
- end.
-
-disconnect(Object,[Ev|Evs]) ->
- try wxEvtHandler:disconnect_impl(Object,Ev) of
- true -> Ev;
- false -> disconnect(Object, Evs);
- Error -> Error
- catch _:_ ->
- false
- end;
-disconnect(_, []) -> false.
+ Handlers = find_handler(Evs0, Object, Evh#evh{cb=FunId}),
+ {reply, {try_in_order, Handlers}, State0}.
find_handler([{Object,Evh}|Evs], Object, Match) ->
case match_handler(Match, Evh) of
diff --git a/lib/wx/src/wxe_util.erl b/lib/wx/src/wxe_util.erl
index 1983e6783a..398ceddd4f 100644
--- a/lib/wx/src/wxe_util.erl
+++ b/lib/wx/src/wxe_util.erl
@@ -127,8 +127,21 @@ connect_cb(Object,EvData0 = #evh{cb=Callback}) ->
disconnect_cb(Object,EvData) ->
Server = (wx:get_env())#wx_env.sv,
- gen_server:call(Server, {disconnect_cb,Object,EvData}, infinity).
-
+ {try_in_order, Handlers} =
+ gen_server:call(Server, {disconnect_cb,Object,EvData}, infinity),
+ disconnect(Object, Handlers).
+
+disconnect(Object,[Ev|Evs]) ->
+ try wxEvtHandler:disconnect_impl(Object,Ev) of
+ true -> true;
+ false -> disconnect(Object, Evs);
+ Error -> Error
+ catch _:_ ->
+ false
+ end;
+disconnect(_, []) -> false.
+
+
debug_cast(1, Op, _Args, _Port) ->
check_previous(),
case ets:lookup(wx_debug_info,Op) of
diff --git a/lib/xmerl/src/xmerl_xsd.erl b/lib/xmerl/src/xmerl_xsd.erl
index 847161e844..3038a54ee6 100644
--- a/lib/xmerl/src/xmerl_xsd.erl
+++ b/lib/xmerl/src/xmerl_xsd.erl
@@ -4888,7 +4888,6 @@ mk_EII_Att_QName(AttName,XMLEl,S) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
create_tables(S=#xsd_state{table=undefined}) ->
Tid=ets:new(xmerl_schema_tab,[]),
- initial_tab_data(Tid),
S#xsd_state{table=Tid};
create_tables(S) ->
S.
@@ -5617,131 +5616,5 @@ format_error(Err) ->
%% {shema_el_pathname(SchemaE,Env),
%% xml_el_pathname(E)}.
-initial_tab_data(Tab) ->
- ets:insert(Tab,
- binary_to_term(
- <<131,108,0,0,0,9,104,2,104,2,100,0,9,97,116,116,114,105,98,117,116,
- 101,104,3,100,0,5,115,112,97,99,101,106,100,0,36,104,116,116,112,58,
- 47,47,119,119,119,46,119,51,46,111,114,103,47,88,77,76,47,49,57,57,
- 56,47,110,97,109,101,115,112,97,99,101,104,9,100,0,16,115,99,104,101,
- 109,97,95,97,116,116,114,105,98,117,116,101,104,3,100,0,5,115,112,97,
- 99,101,106,100,0,36,104,116,116,112,58,47,47,119,119,119,46,119,51,
- 46,111,114,103,47,88,77,76,47,49,57,57,56,47,110,97,109,101,115,112,
- 97,99,101,108,0,0,0,1,104,2,100,0,10,115,105,109,112,108,101,84,121,
- 112,101,104,3,100,0,15,95,120,109,101,114,108,95,110,111,95,110,97,
- 109,101,95,108,0,0,0,1,100,0,5,115,112,97,99,101,106,106,106,100,0,5,
- 102,97,108,115,101,106,100,0,8,111,112,116,105,111,110,97,108,100,0,9,
- 117,110,100,101,102,105,110,101,100,100,0,9,117,110,100,101,102,105,
- 110,101,100,100,0,9,117,110,100,101,102,105,110,101,100,104,2,104,2,
- 100,0,6,115,99,104,101,109,97,107,0,7,120,109,108,46,120,115,100,104,
- 7,100,0,6,115,99,104,101,109,97,100,0,11,117,110,113,117,97,108,105,
- 102,105,101,100,100,0,11,117,110,113,117,97,108,105,102,105,101,100,
- 100,0,36,104,116,116,112,58,47,47,119,119,119,46,119,51,46,111,114,
- 103,47,88,77,76,47,49,57,57,56,47,110,97,109,101,115,112,97,99,101,
- 106,106,106,104,2,104,2,100,0,9,97,116,116,114,105,98,117,116,101,
- 104,3,100,0,4,98,97,115,101,106,100,0,36,104,116,116,112,58,47,47,
- 119,119,119,46,119,51,46,111,114,103,47,88,77,76,47,49,57,57,56,47,
- 110,97,109,101,115,112,97,99,101,104,9,100,0,16,115,99,104,101,109,
- 97,95,97,116,116,114,105,98,117,116,101,104,3,100,0,4,98,97,115,101,
- 106,100,0,36,104,116,116,112,58,47,47,119,119,119,46,119,51,46,111,
- 114,103,47,88,77,76,47,49,57,57,56,47,110,97,109,101,115,112,97,99,
- 101,108,0,0,0,1,104,2,100,0,10,115,105,109,112,108,101,84,121,112,101,
- 104,3,100,0,6,97,110,121,85,82,73,106,100,0,32,104,116,116,112,58,47,
- 47,119,119,119,46,119,51,46,111,114,103,47,50,48,48,49,47,88,77,76,83,
- 99,104,101,109,97,106,100,0,5,102,97,108,115,101,106,100,0,8,111,112,
- 116,105,111,110,97,108,100,0,9,117,110,100,101,102,105,110,101,100,
- 100,0,9,117,110,100,101,102,105,110,101,100,100,0,9,117,110,100,101,
- 102,105,110,101,100,104,2,104,2,100,0,14,97,116,116,114,105,98,117,
- 116,101,71,114,111,117,112,104,3,100,0,12,115,112,101,99,105,97,108,
- 65,116,116,114,115,106,100,0,36,104,116,116,112,58,47,47,119,119,119,
- 46,119,51,46,111,114,103,47,88,77,76,47,49,57,57,56,47,110,97,109,101,
- 115,112,97,99,101,104,5,100,0,22,115,99,104,101,109,97,95,97,116,116,
- 114,105,98,117,116,101,95,103,114,111,117,112,104,3,100,0,12,115,112,
- 101,99,105,97,108,65,116,116,114,115,106,100,0,36,104,116,116,112,58,
- 47,47,119,119,119,46,119,51,46,111,114,103,47,88,77,76,47,49,57,57,
- 56,47,110,97,109,101,115,112,97,99,101,100,0,9,117,110,100,101,102,
- 105,110,101,100,100,0,9,117,110,100,101,102,105,110,101,100,108,0,0,
- 0,3,104,2,100,0,9,97,116,116,114,105,98,117,116,101,104,3,100,0,4,98,
- 97,115,101,106,106,104,2,100,0,9,97,116,116,114,105,98,117,116,101,
- 104,3,100,0,4,108,97,110,103,106,106,104,2,100,0,9,97,116,116,114,
- 105,98,117,116,101,104,3,100,0,5,115,112,97,99,101,106,106,106,104,
- 2,104,2,100,0,10,115,105,109,112,108,101,84,121,112,101,104,3,100,0,
- 15,95,120,109,101,114,108,95,110,111,95,110,97,109,101,95,108,0,0,0,
- 1,100,0,5,115,112,97,99,101,106,106,104,9,100,0,18,115,99,104,101,
- 109,97,95,115,105,109,112,108,101,95,116,121,112,101,104,3,100,0,15,
- 95,120,109,101,114,108,95,110,111,95,110,97,109,101,95,108,0,0,0,1,
- 100,0,5,115,112,97,99,101,106,106,108,0,0,0,1,100,0,5,115,112,97,99,
- 101,106,104,3,100,0,6,78,67,78,97,109,101,106,100,0,32,104,116,116,
- 112,58,47,47,119,119,119,46,119,51,46,111,114,103,47,50,48,48,49,47,
- 88,77,76,83,99,104,101,109,97,100,0,5,102,97,108,115,101,106,108,0,0,
- 0,1,104,2,100,0,11,101,110,117,109,101,114,97,116,105,111,110,108,0,0,
- 0,2,107,0,7,100,101,102,97,117,108,116,107,0,8,112,114,101,115,101,
- 114,118,101,106,106,100,0,6,97,116,111,109,105,99,108,0,0,0,1,104,2,
- 100,0,11,114,101,115,116,114,105,99,116,105,111,110,104,2,104,3,100,
- 0,6,78,67,78,97,109,101,106,100,0,32,104,116,116,112,58,47,47,119,
- 119,119,46,119,51,46,111,114,103,47,50,48,48,49,47,88,77,76,83,99,
- 104,101,109,97,108,0,0,0,2,104,2,100,0,11,101,110,117,109,101,114,
- 97,116,105,111,110,107,0,7,100,101,102,97,117,108,116,104,2,100,0,
- 11,101,110,117,109,101,114,97,116,105,111,110,107,0,8,112,114,101,
- 115,101,114,118,101,106,106,104,2,104,2,100,0,10,115,105,109,112,
- 108,101,84,121,112,101,104,3,100,0,15,95,120,109,101,114,108,95,110,
- 111,95,110,97,109,101,95,108,0,0,0,1,100,0,4,108,97,110,103,106,106,
- 104,9,100,0,18,115,99,104,101,109,97,95,115,105,109,112,108,101,95,
- 116,121,112,101,104,3,100,0,15,95,120,109,101,114,108,95,110,111,95,
- 110,97,109,101,95,108,0,0,0,1,100,0,4,108,97,110,103,106,106,108,0,0,
- 0,1,100,0,4,108,97,110,103,106,100,0,9,117,110,100,101,102,105,110,
- 101,100,100,0,5,102,97,108,115,101,106,106,100,0,6,97,116,111,109,
- 105,99,108,0,0,0,1,104,2,100,0,5,117,110,105,111,110,108,0,0,0,2,104,
- 2,100,0,10,115,105,109,112,108,101,84,121,112,101,104,3,100,0,8,108,
- 97,110,103,117,97,103,101,106,100,0,32,104,116,116,112,58,47,47,119,
- 119,119,46,119,51,46,111,114,103,47,50,48,48,49,47,88,77,76,83,99,104,
- 101,109,97,104,2,100,0,10,115,105,109,112,108,101,84,121,112,101,104,
- 3,100,0,15,95,120,109,101,114,108,95,110,111,95,110,97,109,101,95,108,
- 0,0,0,2,100,0,15,95,120,109,101,114,108,95,110,111,95,110,97,109,101,
- 95,100,0,4,108,97,110,103,106,106,106,106,104,2,104,2,100,0,9,97,116,
- 116,114,105,98,117,116,101,104,3,100,0,2,105,100,106,100,0,36,104,116,
- 116,112,58,47,47,119,119,119,46,119,51,46,111,114,103,47,88,77,76,47,
- 49,57,57,56,47,110,97,109,101,115,112,97,99,101,104,9,100,0,16,115,99,
- 104,101,109,97,95,97,116,116,114,105,98,117,116,101,104,3,100,0,2,105,
- 100,106,100,0,36,104,116,116,112,58,47,47,119,119,119,46,119,51,46,
- 111,114,103,47,88,77,76,47,49,57,57,56,47,110,97,109,101,115,112,97,
- 99,101,108,0,0,0,1,104,2,100,0,10,115,105,109,112,108,101,84,121,112,
- 101,104,3,100,0,2,73,68,106,100,0,32,104,116,116,112,58,47,47,119,119,
- 119,46,119,51,46,111,114,103,47,50,48,48,49,47,88,77,76,83,99,104,101,
- 109,97,106,100,0,5,102,97,108,115,101,106,100,0,8,111,112,116,105,111,
- 110,97,108,100,0,9,117,110,100,101,102,105,110,101,100,100,0,9,117,
- 110,100,101,102,105,110,101,100,100,0,9,117,110,100,101,102,105,110,
- 101,100,104,2,104,2,100,0,9,97,116,116,114,105,98,117,116,101,104,3,
- 100,0,4,108,97,110,103,106,100,0,36,104,116,116,112,58,47,47,119,119,
- 119,46,119,51,46,111,114,103,47,88,77,76,47,49,57,57,56,47,110,97,109,
- 101,115,112,97,99,101,104,9,100,0,16,115,99,104,101,109,97,95,97,116,
- 116,114,105,98,117,116,101,104,3,100,0,4,108,97,110,103,106,100,0,36,
- 104,116,116,112,58,47,47,119,119,119,46,119,51,46,111,114,103,47,88,
- 77,76,47,49,57,57,56,47,110,97,109,101,115,112,97,99,101,108,0,0,0,1,
- 104,2,100,0,10,115,105,109,112,108,101,84,121,112,101,104,3,100,0,15,
- 95,120,109,101,114,108,95,110,111,95,110,97,109,101,95,108,0,0,0,1,
- 100,0,4,108,97,110,103,106,106,106,100,0,5,102,97,108,115,101,106,
- 100,0,8,111,112,116,105,111,110,97,108,100,0,9,117,110,100,101,102,
- 105,110,101,100,100,0,9,117,110,100,101,102,105,110,101,100,100,0,9,
- 117,110,100,101,102,105,110,101,100,104,2,104,2,100,0,10,115,105,109,
- 112,108,101,84,121,112,101,104,3,100,0,15,95,120,109,101,114,108,95,
- 110,111,95,110,97,109,101,95,108,0,0,0,2,100,0,15,95,120,109,101,114,
- 108,95,110,111,95,110,97,109,101,95,100,0,4,108,97,110,103,106,106,
- 104,9,100,0,18,115,99,104,101,109,97,95,115,105,109,112,108,101,95,
- 116,121,112,101,104,3,100,0,15,95,120,109,101,114,108,95,110,111,95,
- 110,97,109,101,95,108,0,0,0,2,100,0,15,95,120,109,101,114,108,95,110,
- 111,95,110,97,109,101,95,100,0,4,108,97,110,103,106,106,108,0,0,0,2,
- 100,0,15,95,120,109,101,114,108,95,110,111,95,110,97,109,101,95,100,
- 0,4,108,97,110,103,106,104,3,100,0,6,115,116,114,105,110,103,106,100,
- 0,32,104,116,116,112,58,47,47,119,119,119,46,119,51,46,111,114,103,47,
- 50,48,48,49,47,88,77,76,83,99,104,101,109,97,100,0,5,102,97,108,115,
- 101,106,108,0,0,0,1,104,2,100,0,11,101,110,117,109,101,114,97,116,105,
- 111,110,108,0,0,0,1,106,106,106,100,0,6,97,116,111,109,105,99,108,0,0,
- 0,1,104,2,100,0,11,114,101,115,116,114,105,99,116,105,111,110,104,2,
- 104,3,100,0,6,115,116,114,105,110,103,106,100,0,32,104,116,116,112,58,
- 47,47,119,119,119,46,119,51,46,111,114,103,47,50,48,48,49,47,88,77,76,
- 83,99,104,101,109,97,108,0,0,0,1,104,2,100,0,11,101,110,117,109,101,
- 114,97,116,105,111,110,106,106,106,106>>)).
-
default_namespace_by_convention() ->
[{xml,'http://www.w3.org/XML/1998/namespace'}].
diff --git a/lib/xmerl/test/xmerl_xsd_SUITE.erl b/lib/xmerl/test/xmerl_xsd_SUITE.erl
index 101fbcd50f..92c8287782 100644
--- a/lib/xmerl/test/xmerl_xsd_SUITE.erl
+++ b/lib/xmerl/test/xmerl_xsd_SUITE.erl
@@ -41,7 +41,8 @@ groups() ->
[{group, primitive_datatypes},
{group, derived_datatypes}]},
{validation_tests, [],
- [{group, xmlSchemaPrimerExamples},
+ [{group, xmlXsdAndExample},
+ {group, xmlSchemaPrimerExamples},
{group, miscXMLexamples}]},
{primitive_datatypes, [],
[string, boolean, decimal, float, double, duration,
@@ -55,6 +56,8 @@ groups() ->
negativeInteger, long, int, short, byte,
nonNegativeInteger, unsignedLong, unsignedInt,
unsignedShort, unsignedByte, positiveInteger]},
+ {xmlXsdAndExample, [],
+ [xml_xsd, xml_lang_attr]},
{xmlSchemaPrimerExamples, [],
[po, po1, po2, ipo, ipo_redefine, '4Q99']},
{miscXMLexamples, [],
@@ -863,6 +866,19 @@ compare_duration(_Config) ->
?line indefinite = xmerl_xsd_type:compare_durations("P5M","P153D"),
?line lt = xmerl_xsd_type:compare_durations("P5M","P154D").
+xml_xsd(suite) -> [];
+xml_xsd(Config) ->
+ DataDir = ?config(data_dir, Config),
+ Options = [{fetch_path, [DataDir]}],
+ {ok, _} = xmerl_xsd:process_schema("xml.xsd", Options).
+
+xml_lang_attr(suite) -> [];
+xml_lang_attr(Config) ->
+ DataDir = ?config(data_dir, Config),
+ {Element, _} = xmerl_scan:file(filename:join([DataDir, "book.xml"])),
+ Options = [{fetch_path, [DataDir]}],
+ {ok, Schema} = xmerl_xsd:process_schema("book.xsd", Options),
+ {Element, _} = xmerl_xsd:validate(Element, Schema).
po(suite) -> [];
po(Config) ->
diff --git a/lib/xmerl/test/xmerl_xsd_SUITE_data/book.xml b/lib/xmerl/test/xmerl_xsd_SUITE_data/book.xml
new file mode 100644
index 0000000000..17d7ceffee
--- /dev/null
+++ b/lib/xmerl/test/xmerl_xsd_SUITE_data/book.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<book title="Title" xml:lang="EN">
+ <author>Author1</author>
+ <author>Author2</author>
+</book>
diff --git a/lib/xmerl/test/xmerl_xsd_SUITE_data/book.xsd b/lib/xmerl/test/xmerl_xsd_SUITE_data/book.xsd
new file mode 100644
index 0000000000..830951ec1b
--- /dev/null
+++ b/lib/xmerl/test/xmerl_xsd_SUITE_data/book.xsd
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
+ <xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="xml.xsd"/>
+ <xs:element name="book">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="author" type="xs:string" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:attribute name="title" type="xs:string"/>
+ <xs:attribute ref="xml:lang"/>
+ </xs:complexType>
+ </xs:element>
+</xs:schema>
diff --git a/lib/xmerl/test/xmerl_xsd_SUITE_data/xml.xsd b/lib/xmerl/test/xmerl_xsd_SUITE_data/xml.xsd
new file mode 100644
index 0000000000..aea7d0db0a
--- /dev/null
+++ b/lib/xmerl/test/xmerl_xsd_SUITE_data/xml.xsd
@@ -0,0 +1,287 @@
+<?xml version='1.0'?>
+<?xml-stylesheet href="../2008/09/xsd.xsl" type="text/xsl"?>
+<xs:schema targetNamespace="http://www.w3.org/XML/1998/namespace"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns ="http://www.w3.org/1999/xhtml"
+ xml:lang="en">
+
+ <xs:annotation>
+ <xs:documentation>
+ <div>
+ <h1>About the XML namespace</h1>
+
+ <div class="bodytext">
+ <p>
+ This schema document describes the XML namespace, in a form
+ suitable for import by other schema documents.
+ </p>
+ <p>
+ See <a href="http://www.w3.org/XML/1998/namespace.html">
+ http://www.w3.org/XML/1998/namespace.html</a> and
+ <a href="http://www.w3.org/TR/REC-xml">
+ http://www.w3.org/TR/REC-xml</a> for information
+ about this namespace.
+ </p>
+ <p>
+ Note that local names in this namespace are intended to be
+ defined only by the World Wide Web Consortium or its subgroups.
+ The names currently defined in this namespace are listed below.
+ They should not be used with conflicting semantics by any Working
+ Group, specification, or document instance.
+ </p>
+ <p>
+ See further below in this document for more information about <a
+ href="#usage">how to refer to this schema document from your own
+ XSD schema documents</a> and about <a href="#nsversioning">the
+ namespace-versioning policy governing this schema document</a>.
+ </p>
+ </div>
+ </div>
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:attribute name="lang">
+ <xs:annotation>
+ <xs:documentation>
+ <div>
+
+ <h3>lang (as an attribute name)</h3>
+ <p>
+ denotes an attribute whose value
+ is a language code for the natural language of the content of
+ any element; its value is inherited. This name is reserved
+ by virtue of its definition in the XML specification.</p>
+
+ </div>
+ <div>
+ <h4>Notes</h4>
+ <p>
+ Attempting to install the relevant ISO 2- and 3-letter
+ codes as the enumerated possible values is probably never
+ going to be a realistic possibility.
+ </p>
+ <p>
+ See BCP 47 at <a href="http://www.rfc-editor.org/rfc/bcp/bcp47.txt">
+ http://www.rfc-editor.org/rfc/bcp/bcp47.txt</a>
+ and the IANA language subtag registry at
+ <a href="http://www.iana.org/assignments/language-subtag-registry">
+ http://www.iana.org/assignments/language-subtag-registry</a>
+ for further information.
+ </p>
+ <p>
+ The union allows for the 'un-declaration' of xml:lang with
+ the empty string.
+ </p>
+ </div>
+ </xs:documentation>
+ </xs:annotation>
+ <xs:simpleType>
+ <xs:union memberTypes="xs:language">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value=""/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:union>
+ </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="space">
+ <xs:annotation>
+ <xs:documentation>
+ <div>
+
+ <h3>space (as an attribute name)</h3>
+ <p>
+ denotes an attribute whose
+ value is a keyword indicating what whitespace processing
+ discipline is intended for the content of the element; its
+ value is inherited. This name is reserved by virtue of its
+ definition in the XML specification.</p>
+
+ </div>
+ </xs:documentation>
+ </xs:annotation>
+ <xs:simpleType>
+ <xs:restriction base="xs:NCName">
+ <xs:enumeration value="default"/>
+ <xs:enumeration value="preserve"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="base" type="xs:anyURI"> <xs:annotation>
+ <xs:documentation>
+ <div>
+
+ <h3>base (as an attribute name)</h3>
+ <p>
+ denotes an attribute whose value
+ provides a URI to be used as the base for interpreting any
+ relative URIs in the scope of the element on which it
+ appears; its value is inherited. This name is reserved
+ by virtue of its definition in the XML Base specification.</p>
+
+ <p>
+ See <a
+ href="http://www.w3.org/TR/xmlbase/">http://www.w3.org/TR/xmlbase/</a>
+ for information about this attribute.
+ </p>
+ </div>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="id" type="xs:ID">
+ <xs:annotation>
+ <xs:documentation>
+ <div>
+
+ <h3>id (as an attribute name)</h3>
+ <p>
+ denotes an attribute whose value
+ should be interpreted as if declared to be of type ID.
+ This name is reserved by virtue of its definition in the
+ xml:id specification.</p>
+
+ <p>
+ See <a
+ href="http://www.w3.org/TR/xml-id/">http://www.w3.org/TR/xml-id/</a>
+ for information about this attribute.
+ </p>
+ </div>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attributeGroup name="specialAttrs">
+ <xs:attribute ref="xml:base"/>
+ <xs:attribute ref="xml:lang"/>
+ <xs:attribute ref="xml:space"/>
+ <xs:attribute ref="xml:id"/>
+ </xs:attributeGroup>
+
+ <xs:annotation>
+ <xs:documentation>
+ <div>
+
+ <h3>Father (in any context at all)</h3>
+
+ <div class="bodytext">
+ <p>
+ denotes Jon Bosak, the chair of
+ the original XML Working Group. This name is reserved by
+ the following decision of the W3C XML Plenary and
+ XML Coordination groups:
+ </p>
+ <blockquote>
+ <p>
+ In appreciation for his vision, leadership and
+ dedication the W3C XML Plenary on this 10th day of
+ February, 2000, reserves for Jon Bosak in perpetuity
+ the XML name "xml:Father".
+ </p>
+ </blockquote>
+ </div>
+ </div>
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:annotation>
+ <xs:documentation>
+ <div xml:id="usage" id="usage">
+ <h2><a name="usage">About this schema document</a></h2>
+
+ <div class="bodytext">
+ <p>
+ This schema defines attributes and an attribute group suitable
+ for use by schemas wishing to allow <code>xml:base</code>,
+ <code>xml:lang</code>, <code>xml:space</code> or
+ <code>xml:id</code> attributes on elements they define.
+ </p>
+ <p>
+ To enable this, such a schema must import this schema for
+ the XML namespace, e.g. as follows:
+ </p>
+ <pre>
+ &lt;schema . . .>
+ . . .
+ &lt;import namespace="http://www.w3.org/XML/1998/namespace"
+ schemaLocation="http://www.w3.org/2001/xml.xsd"/>
+ </pre>
+ <p>
+ or
+ </p>
+ <pre>
+ &lt;import namespace="http://www.w3.org/XML/1998/namespace"
+ schemaLocation="http://www.w3.org/2009/01/xml.xsd"/>
+ </pre>
+ <p>
+ Subsequently, qualified reference to any of the attributes or the
+ group defined below will have the desired effect, e.g.
+ </p>
+ <pre>
+ &lt;type . . .>
+ . . .
+ &lt;attributeGroup ref="xml:specialAttrs"/>
+ </pre>
+ <p>
+ will define a type which will schema-validate an instance element
+ with any of those attributes.
+ </p>
+ </div>
+ </div>
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:annotation>
+ <xs:documentation>
+ <div id="nsversioning" xml:id="nsversioning">
+ <h2><a name="nsversioning">Versioning policy for this schema document</a></h2>
+ <div class="bodytext">
+ <p>
+ In keeping with the XML Schema WG's standard versioning
+ policy, this schema document will persist at
+ <a href="http://www.w3.org/2009/01/xml.xsd">
+ http://www.w3.org/2009/01/xml.xsd</a>.
+ </p>
+ <p>
+ At the date of issue it can also be found at
+ <a href="http://www.w3.org/2001/xml.xsd">
+ http://www.w3.org/2001/xml.xsd</a>.
+ </p>
+ <p>
+ The schema document at that URI may however change in the future,
+ in order to remain compatible with the latest version of XML
+ Schema itself, or with the XML namespace itself. In other words,
+ if the XML Schema or XML namespaces change, the version of this
+ document at <a href="http://www.w3.org/2001/xml.xsd">
+ http://www.w3.org/2001/xml.xsd
+ </a>
+ will change accordingly; the version at
+ <a href="http://www.w3.org/2009/01/xml.xsd">
+ http://www.w3.org/2009/01/xml.xsd
+ </a>
+ will not change.
+ </p>
+ <p>
+ Previous dated (and unchanging) versions of this schema
+ document are at:
+ </p>
+ <ul>
+ <li><a href="http://www.w3.org/2009/01/xml.xsd">
+ http://www.w3.org/2009/01/xml.xsd</a></li>
+ <li><a href="http://www.w3.org/2007/08/xml.xsd">
+ http://www.w3.org/2007/08/xml.xsd</a></li>
+ <li><a href="http://www.w3.org/2004/10/xml.xsd">
+ http://www.w3.org/2004/10/xml.xsd</a></li>
+ <li><a href="http://www.w3.org/2001/03/xml.xsd">
+ http://www.w3.org/2001/03/xml.xsd</a></li>
+ </ul>
+ </div>
+ </div>
+ </xs:documentation>
+ </xs:annotation>
+
+</xs:schema>
+
diff --git a/make/otp_release_targets.mk b/make/otp_release_targets.mk
index 97e9e4bb43..e104b68991 100644
--- a/make/otp_release_targets.mk
+++ b/make/otp_release_targets.mk
@@ -113,7 +113,16 @@ $(HTMLDIR)/$(APPLICATION).eix: $(XML_FILES) $(SPECS_FILES)
docs: $(HTMLDIR)/$(APPLICATION).eix
xmllint: $(XML_FILES)
- $(XMLLINT) --noout --valid --nodefdtd --loaddtd --path $(DOCGEN)/priv/dtd:$(DOCGEN)/priv/dtd_html_entities $(XML_FILES)
+ @echo "Running xmllint"
+ @BookFiles=`awk -F\" '/xi:include/ {print $$2}' book.xml`; \
+ for i in $$BookFiles; do \
+ if [ $$i = "notes.xml" ]; then \
+ echo Checking $$i; \
+ xmllint --noout --valid --nodefdtd --loaddtd --path $(DOCGEN)/priv/dtd:$(DOCGEN)/priv/dtd_html_entities $$i; \
+ else\
+ awk -F\" '/xi:include/ {print "echo Checking " $$2 ;print "xmllint --noout --valid --nodefdtd --loaddtd --path $(DOCGEN)/priv/dtd:$(DOCGEN)/priv/dtd_html_entities " $$2}' $$i |sh; \
+ fi \
+ done
# ----------------------------------------------------
# Local documentation target for testing
diff --git a/otp_build b/otp_build
index e6eb048a14..ac99ced42a 100755
--- a/otp_build
+++ b/otp_build
@@ -1443,13 +1443,13 @@ case "$1" in
do_debuginfo_win32 "$2";;
env_win32)
if [ x"$2" = x"x64" -o x"$2" = x"amd64" ]; then
- if [ -x /usr/bin/msysinfo ]; then
+ if [ -x /usr/bin/msys-?.0.dll ]; then
echo_env_msys64
else
echo_env_win64
fi
else
- if [ -x /usr/bin/msysinfo ]; then
+ if [ -x /usr/bin/msys-?.0.dll ]; then
echo_env_msys32
else
echo_env_win32
diff --git a/otp_versions.table b/otp_versions.table
index 8a4393c3c3..e31f5e425a 100644
--- a/otp_versions.table
+++ b/otp_versions.table
@@ -1,8 +1,15 @@
+OTP-18.1.5 : ssh-4.1.3 # asn1-4.0 common_test-1.11 compiler-6.0.1 cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosNotification-1.2 cosProperty-1.2 cosTime-1.2 cosTransactions-1.3 crypto-3.6.1 debugger-4.1.1 dialyzer-2.8.1 diameter-1.11 edoc-0.7.17 eldap-1.2 erl_docgen-0.4 erl_interface-3.8 erts-7.1 et-1.5.1 eunit-2.2.11 gs-1.6 hipe-3.13 ic-4.4 inets-6.0.3 jinterface-1.6 kernel-4.1 megaco-3.18 mnesia-4.13.2 observer-2.1 odbc-2.11.1 orber-3.8 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1 percept-0.8.11 public_key-1.0.1 reltool-0.7 runtime_tools-1.9.1 sasl-2.6 snmp-5.2 ssl-7.1 stdlib-2.6 syntax_tools-1.7 test_server-3.9 tools-2.8.1 typer-0.9.9 webtool-0.9 wx-1.5 xmerl-1.3.8 :
+OTP-18.1.4 : inets-6.0.3 # asn1-4.0 common_test-1.11 compiler-6.0.1 cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosNotification-1.2 cosProperty-1.2 cosTime-1.2 cosTransactions-1.3 crypto-3.6.1 debugger-4.1.1 dialyzer-2.8.1 diameter-1.11 edoc-0.7.17 eldap-1.2 erl_docgen-0.4 erl_interface-3.8 erts-7.1 et-1.5.1 eunit-2.2.11 gs-1.6 hipe-3.13 ic-4.4 jinterface-1.6 kernel-4.1 megaco-3.18 mnesia-4.13.2 observer-2.1 odbc-2.11.1 orber-3.8 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1 percept-0.8.11 public_key-1.0.1 reltool-0.7 runtime_tools-1.9.1 sasl-2.6 snmp-5.2 ssh-4.1.2 ssl-7.1 stdlib-2.6 syntax_tools-1.7 test_server-3.9 tools-2.8.1 typer-0.9.9 webtool-0.9 wx-1.5 xmerl-1.3.8 :
+OTP-18.1.3 : ssh-4.1.2 # asn1-4.0 common_test-1.11 compiler-6.0.1 cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosNotification-1.2 cosProperty-1.2 cosTime-1.2 cosTransactions-1.3 crypto-3.6.1 debugger-4.1.1 dialyzer-2.8.1 diameter-1.11 edoc-0.7.17 eldap-1.2 erl_docgen-0.4 erl_interface-3.8 erts-7.1 et-1.5.1 eunit-2.2.11 gs-1.6 hipe-3.13 ic-4.4 inets-6.0.2 jinterface-1.6 kernel-4.1 megaco-3.18 mnesia-4.13.2 observer-2.1 odbc-2.11.1 orber-3.8 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1 percept-0.8.11 public_key-1.0.1 reltool-0.7 runtime_tools-1.9.1 sasl-2.6 snmp-5.2 ssl-7.1 stdlib-2.6 syntax_tools-1.7 test_server-3.9 tools-2.8.1 typer-0.9.9 webtool-0.9 wx-1.5 xmerl-1.3.8 :
+OTP-18.1.2 : ssh-4.1.1 # asn1-4.0 common_test-1.11 compiler-6.0.1 cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosNotification-1.2 cosProperty-1.2 cosTime-1.2 cosTransactions-1.3 crypto-3.6.1 debugger-4.1.1 dialyzer-2.8.1 diameter-1.11 edoc-0.7.17 eldap-1.2 erl_docgen-0.4 erl_interface-3.8 erts-7.1 et-1.5.1 eunit-2.2.11 gs-1.6 hipe-3.13 ic-4.4 inets-6.0.2 jinterface-1.6 kernel-4.1 megaco-3.18 mnesia-4.13.2 observer-2.1 odbc-2.11.1 orber-3.8 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1 percept-0.8.11 public_key-1.0.1 reltool-0.7 runtime_tools-1.9.1 sasl-2.6 snmp-5.2 ssl-7.1 stdlib-2.6 syntax_tools-1.7 test_server-3.9 tools-2.8.1 typer-0.9.9 webtool-0.9 wx-1.5 xmerl-1.3.8 :
+OTP-18.1.1 : inets-6.0.2 mnesia-4.13.2 # asn1-4.0 common_test-1.11 compiler-6.0.1 cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosNotification-1.2 cosProperty-1.2 cosTime-1.2 cosTransactions-1.3 crypto-3.6.1 debugger-4.1.1 dialyzer-2.8.1 diameter-1.11 edoc-0.7.17 eldap-1.2 erl_docgen-0.4 erl_interface-3.8 erts-7.1 et-1.5.1 eunit-2.2.11 gs-1.6 hipe-3.13 ic-4.4 jinterface-1.6 kernel-4.1 megaco-3.18 observer-2.1 odbc-2.11.1 orber-3.8 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1 percept-0.8.11 public_key-1.0.1 reltool-0.7 runtime_tools-1.9.1 sasl-2.6 snmp-5.2 ssh-4.1 ssl-7.1 stdlib-2.6 syntax_tools-1.7 test_server-3.9 tools-2.8.1 typer-0.9.9 webtool-0.9 wx-1.5 xmerl-1.3.8 :
OTP-18.1 : compiler-6.0.1 crypto-3.6.1 debugger-4.1.1 dialyzer-2.8.1 diameter-1.11 erts-7.1 eunit-2.2.11 hipe-3.13 inets-6.0.1 kernel-4.1 mnesia-4.13.1 odbc-2.11.1 public_key-1.0.1 sasl-2.6 ssh-4.1 ssl-7.1 stdlib-2.6 tools-2.8.1 wx-1.5 # asn1-4.0 common_test-1.11 cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosNotification-1.2 cosProperty-1.2 cosTime-1.2 cosTransactions-1.3 edoc-0.7.17 eldap-1.2 erl_docgen-0.4 erl_interface-3.8 et-1.5.1 gs-1.6 ic-4.4 jinterface-1.6 megaco-3.18 observer-2.1 orber-3.8 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1 percept-0.8.11 reltool-0.7 runtime_tools-1.9.1 snmp-5.2 syntax_tools-1.7 test_server-3.9 typer-0.9.9 webtool-0.9 xmerl-1.3.8 :
OTP-18.0.3 : erts-7.0.3 # asn1-4.0 common_test-1.11 compiler-6.0 cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosNotification-1.2 cosProperty-1.2 cosTime-1.2 cosTransactions-1.3 crypto-3.6 debugger-4.1 dialyzer-2.8 diameter-1.10 edoc-0.7.17 eldap-1.2 erl_docgen-0.4 erl_interface-3.8 et-1.5.1 eunit-2.2.10 gs-1.6 hipe-3.12 ic-4.4 inets-6.0 jinterface-1.6 kernel-4.0 megaco-3.18 mnesia-4.13 observer-2.1 odbc-2.11 orber-3.8 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1 percept-0.8.11 public_key-1.0 reltool-0.7 runtime_tools-1.9.1 sasl-2.5 snmp-5.2 ssh-4.0 ssl-7.0 stdlib-2.5 syntax_tools-1.7 test_server-3.9 tools-2.8 typer-0.9.9 webtool-0.9 wx-1.4 xmerl-1.3.8 :
OTP-18.0.2 : erts-7.0.2 runtime_tools-1.9.1 # asn1-4.0 common_test-1.11 compiler-6.0 cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosNotification-1.2 cosProperty-1.2 cosTime-1.2 cosTransactions-1.3 crypto-3.6 debugger-4.1 dialyzer-2.8 diameter-1.10 edoc-0.7.17 eldap-1.2 erl_docgen-0.4 erl_interface-3.8 et-1.5.1 eunit-2.2.10 gs-1.6 hipe-3.12 ic-4.4 inets-6.0 jinterface-1.6 kernel-4.0 megaco-3.18 mnesia-4.13 observer-2.1 odbc-2.11 orber-3.8 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1 percept-0.8.11 public_key-1.0 reltool-0.7 sasl-2.5 snmp-5.2 ssh-4.0 ssl-7.0 stdlib-2.5 syntax_tools-1.7 test_server-3.9 tools-2.8 typer-0.9.9 webtool-0.9 wx-1.4 xmerl-1.3.8 :
OTP-18.0.1 : erts-7.0.1 # asn1-4.0 common_test-1.11 compiler-6.0 cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosNotification-1.2 cosProperty-1.2 cosTime-1.2 cosTransactions-1.3 crypto-3.6 debugger-4.1 dialyzer-2.8 diameter-1.10 edoc-0.7.17 eldap-1.2 erl_docgen-0.4 erl_interface-3.8 et-1.5.1 eunit-2.2.10 gs-1.6 hipe-3.12 ic-4.4 inets-6.0 jinterface-1.6 kernel-4.0 megaco-3.18 mnesia-4.13 observer-2.1 odbc-2.11 orber-3.8 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1 percept-0.8.11 public_key-1.0 reltool-0.7 runtime_tools-1.9 sasl-2.5 snmp-5.2 ssh-4.0 ssl-7.0 stdlib-2.5 syntax_tools-1.7 test_server-3.9 tools-2.8 typer-0.9.9 webtool-0.9 wx-1.4 xmerl-1.3.8 :
OTP-18.0 : asn1-4.0 common_test-1.11 compiler-6.0 cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosNotification-1.2 cosProperty-1.2 cosTime-1.2 cosTransactions-1.3 crypto-3.6 debugger-4.1 dialyzer-2.8 diameter-1.10 edoc-0.7.17 eldap-1.2 erl_docgen-0.4 erl_interface-3.8 erts-7.0 et-1.5.1 eunit-2.2.10 gs-1.6 hipe-3.12 ic-4.4 inets-6.0 jinterface-1.6 kernel-4.0 megaco-3.18 mnesia-4.13 observer-2.1 odbc-2.11 orber-3.8 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1 percept-0.8.11 public_key-1.0 reltool-0.7 runtime_tools-1.9 sasl-2.5 snmp-5.2 ssh-4.0 ssl-7.0 stdlib-2.5 syntax_tools-1.7 test_server-3.9 tools-2.8 typer-0.9.9 webtool-0.9 wx-1.4 xmerl-1.3.8 # :
+OTP-17.5.6.5 : erts-6.4.1.4 kernel-3.2.0.1 ssl-6.0.1.1 # asn1-3.0.4 common_test-1.10.1 compiler-5.0.4 cosEvent-2.1.15 cosEventDomain-1.1.14 cosFileTransfer-1.1.16 cosNotification-1.1.21 cosProperty-1.1.17 cosTime-1.1.14 cosTransactions-1.2.14 crypto-3.5 debugger-4.0.3.1 dialyzer-2.7.4 diameter-1.9.2.1 edoc-0.7.16 eldap-1.1.1 erl_docgen-0.3.7 erl_interface-3.7.20 et-1.5 eunit-2.2.9 gs-1.5.16 hipe-3.11.3 ic-4.3.6 inets-5.10.9 jinterface-1.5.12 megaco-3.17.3 mnesia-4.12.5 observer-2.0.4 odbc-2.10.22 orber-3.7.1 os_mon-2.3.1 ose-1.0.2 otp_mibs-1.0.10 parsetools-2.0.12 percept-0.8.10 public_key-0.23 reltool-0.6.6 runtime_tools-1.8.16.1 sasl-2.4.1 snmp-5.1.2 ssh-3.2.4 stdlib-2.4 syntax_tools-1.6.18 test_server-3.8.1 tools-2.7.2 typer-0.9.8 webtool-0.8.10 wx-1.3.3 xmerl-1.3.7 :
+OTP-17.5.6.4 : debugger-4.0.3.1 erts-6.4.1.3 # asn1-3.0.4 common_test-1.10.1 compiler-5.0.4 cosEvent-2.1.15 cosEventDomain-1.1.14 cosFileTransfer-1.1.16 cosNotification-1.1.21 cosProperty-1.1.17 cosTime-1.1.14 cosTransactions-1.2.14 crypto-3.5 dialyzer-2.7.4 diameter-1.9.2.1 edoc-0.7.16 eldap-1.1.1 erl_docgen-0.3.7 erl_interface-3.7.20 et-1.5 eunit-2.2.9 gs-1.5.16 hipe-3.11.3 ic-4.3.6 inets-5.10.9 jinterface-1.5.12 kernel-3.2 megaco-3.17.3 mnesia-4.12.5 observer-2.0.4 odbc-2.10.22 orber-3.7.1 os_mon-2.3.1 ose-1.0.2 otp_mibs-1.0.10 parsetools-2.0.12 percept-0.8.10 public_key-0.23 reltool-0.6.6 runtime_tools-1.8.16.1 sasl-2.4.1 snmp-5.1.2 ssh-3.2.4 ssl-6.0.1 stdlib-2.4 syntax_tools-1.6.18 test_server-3.8.1 tools-2.7.2 typer-0.9.8 webtool-0.8.10 wx-1.3.3 xmerl-1.3.7 :
OTP-17.5.6.3 : diameter-1.9.2.1 # asn1-3.0.4 common_test-1.10.1 compiler-5.0.4 cosEvent-2.1.15 cosEventDomain-1.1.14 cosFileTransfer-1.1.16 cosNotification-1.1.21 cosProperty-1.1.17 cosTime-1.1.14 cosTransactions-1.2.14 crypto-3.5 debugger-4.0.3 dialyzer-2.7.4 edoc-0.7.16 eldap-1.1.1 erl_docgen-0.3.7 erl_interface-3.7.20 erts-6.4.1.2 et-1.5 eunit-2.2.9 gs-1.5.16 hipe-3.11.3 ic-4.3.6 inets-5.10.9 jinterface-1.5.12 kernel-3.2 megaco-3.17.3 mnesia-4.12.5 observer-2.0.4 odbc-2.10.22 orber-3.7.1 os_mon-2.3.1 ose-1.0.2 otp_mibs-1.0.10 parsetools-2.0.12 percept-0.8.10 public_key-0.23 reltool-0.6.6 runtime_tools-1.8.16.1 sasl-2.4.1 snmp-5.1.2 ssh-3.2.4 ssl-6.0.1 stdlib-2.4 syntax_tools-1.6.18 test_server-3.8.1 tools-2.7.2 typer-0.9.8 webtool-0.8.10 wx-1.3.3 xmerl-1.3.7 :
OTP-17.5.6.2 : erts-6.4.1.2 runtime_tools-1.8.16.1 # asn1-3.0.4 common_test-1.10.1 compiler-5.0.4 cosEvent-2.1.15 cosEventDomain-1.1.14 cosFileTransfer-1.1.16 cosNotification-1.1.21 cosProperty-1.1.17 cosTime-1.1.14 cosTransactions-1.2.14 crypto-3.5 debugger-4.0.3 dialyzer-2.7.4 diameter-1.9.2 edoc-0.7.16 eldap-1.1.1 erl_docgen-0.3.7 erl_interface-3.7.20 et-1.5 eunit-2.2.9 gs-1.5.16 hipe-3.11.3 ic-4.3.6 inets-5.10.9 jinterface-1.5.12 kernel-3.2 megaco-3.17.3 mnesia-4.12.5 observer-2.0.4 odbc-2.10.22 orber-3.7.1 os_mon-2.3.1 ose-1.0.2 otp_mibs-1.0.10 parsetools-2.0.12 percept-0.8.10 public_key-0.23 reltool-0.6.6 sasl-2.4.1 snmp-5.1.2 ssh-3.2.4 ssl-6.0.1 stdlib-2.4 syntax_tools-1.6.18 test_server-3.8.1 tools-2.7.2 typer-0.9.8 webtool-0.8.10 wx-1.3.3 xmerl-1.3.7 :
OTP-17.5.6.1 : erts-6.4.1.1 # asn1-3.0.4 common_test-1.10.1 compiler-5.0.4 cosEvent-2.1.15 cosEventDomain-1.1.14 cosFileTransfer-1.1.16 cosNotification-1.1.21 cosProperty-1.1.17 cosTime-1.1.14 cosTransactions-1.2.14 crypto-3.5 debugger-4.0.3 dialyzer-2.7.4 diameter-1.9.2 edoc-0.7.16 eldap-1.1.1 erl_docgen-0.3.7 erl_interface-3.7.20 et-1.5 eunit-2.2.9 gs-1.5.16 hipe-3.11.3 ic-4.3.6 inets-5.10.9 jinterface-1.5.12 kernel-3.2 megaco-3.17.3 mnesia-4.12.5 observer-2.0.4 odbc-2.10.22 orber-3.7.1 os_mon-2.3.1 ose-1.0.2 otp_mibs-1.0.10 parsetools-2.0.12 percept-0.8.10 public_key-0.23 reltool-0.6.6 runtime_tools-1.8.16 sasl-2.4.1 snmp-5.1.2 ssh-3.2.4 ssl-6.0.1 stdlib-2.4 syntax_tools-1.6.18 test_server-3.8.1 tools-2.7.2 typer-0.9.8 webtool-0.8.10 wx-1.3.3 xmerl-1.3.7 :
diff --git a/system/doc/design_principles/des_princ.xml b/system/doc/design_principles/des_princ.xml
index ba67a49585..0e087cf843 100644
--- a/system/doc/design_principles/des_princ.xml
+++ b/system/doc/design_principles/des_princ.xml
@@ -183,7 +183,7 @@ handle_cast({free, Ch}, Chs) ->
<item>The server name, in this example the atom
<c>ch2</c>, is hidden from the users of the client functions. This
means that the name can be changed without affecting them.</item>
- <item>The protcol (messages sent to and received from the server)
+ <item>The protocol (messages sent to and received from the server)
is also hidden. This is good programming practice and allows
one to change the protocol without changing the code using
the interface functions.</item>
diff --git a/system/doc/efficiency_guide/binaryhandling.xml b/system/doc/efficiency_guide/binaryhandling.xml
index 51f8c4ebf0..0964b759d8 100644
--- a/system/doc/efficiency_guide/binaryhandling.xml
+++ b/system/doc/efficiency_guide/binaryhandling.xml
@@ -190,15 +190,15 @@ Bin4 = <<Bin1/binary,17>>, %% 5 !!!
its size set to the size of the data stored in the binary, while
the binary object has extra space allocated.
The size of the binary object is either twice the
- size of <c>Bin0</c> or 256, whichever is larger. In this case
+ size of <c>Bin1</c> or 256, whichever is larger. In this case
it is 256.</item>
<item>Line 3 is more interesting.
<c>Bin1</c> <em>has</em> been used in an append operation,
- and it has 255 bytes of unused storage at the end, so the 3 new
+ and it has 252 bytes of unused storage at the end, so the 3 new
bytes are stored there.</item>
- <item>Line 4. The same applies here. There are 252 bytes left,
+ <item>Line 4. The same applies here. There are 249 bytes left,
so there is no problem storing another 3 bytes.</item>
<item>Line 5. Here, something <em>interesting</em> happens. Notice
diff --git a/system/doc/reference_manual/processes.xml b/system/doc/reference_manual/processes.xml
index 6755bd8be6..f656d0318e 100644
--- a/system/doc/reference_manual/processes.xml
+++ b/system/doc/reference_manual/processes.xml
@@ -100,11 +100,9 @@ spawn(Module, Name, Args) -> pid()
<item><c>exit(Reason)</c></item>
<item><c>erlang:error(Reason)</c></item>
<item><c>erlang:error(Reason, Args)</c></item>
- <item><c>erlang:fault(Reason)</c></item>
- <item><c>erlang:fault(Reason, Args)</c></item>
</list>
<p>The process then terminates with reason <c>Reason</c> for
- <c>exit/1</c> or <c>{Reason,Stack} for the others</c>.</p>
+ <c>exit/1</c> or <c>{Reason,Stack}</c> for the others.</p>
<p>A process can also be terminated if it receives an exit signal
with another exit reason than <c>normal</c>, see
<seealso marker="#errors">Error Handling</seealso>.</p>
diff --git a/system/doc/reference_manual/typespec.xml b/system/doc/reference_manual/typespec.xml
index 7891f3a6b9..22627058c1 100644
--- a/system/doc/reference_manual/typespec.xml
+++ b/system/doc/reference_manual/typespec.xml
@@ -197,6 +197,9 @@
<cell><c>char()</c></cell><cell><c>0..16#10ffff</c></cell>
</row>
<row>
+ <cell><c>nil()</c></cell><cell><c>[]</c></cell>
+ </row>
+ <row>
<cell><c>number()</c></cell><cell><c>integer() | float()</c></cell>
</row>
<row>
@@ -312,7 +315,7 @@
<p>
As seen, the basic syntax of a type is an atom followed by closed
parentheses. New types are declared using <c>-type</c> and <c>-opaque</c>
- compiler attributes as in the following:
+ attributes as in the following:
</p>
<pre>
-type my_struct_type() :: Type.
@@ -435,8 +438,8 @@
<section>
<title>Specifications for Functions</title>
<p>
- A specification (or contract) for a function is given using the new
- compiler attribute <c>-spec</c>. The general format is as follows:
+ A specification (or contract) for a function is given using the
+ <c>-spec</c> attribute. The general format is as follows:
</p>
<pre>
-spec Module:Function(ArgType1, ..., ArgTypeN) -> ReturnType.</pre>
@@ -451,7 +454,7 @@
explicitly) import these functions.
</p>
<p>
- Within a given module, the following shorthand suffice in most cases:
+ Within a given module, the following shorthand suffices in most cases:
</p>
<pre>
-spec Function(ArgType1, ..., ArgTypeN) -> ReturnType.</pre>
diff --git a/system/doc/tutorial/ei.c b/system/doc/tutorial/ei.c
index b234a00768..c33e3fb78e 100644
--- a/system/doc/tutorial/ei.c
+++ b/system/doc/tutorial/ei.c
@@ -21,7 +21,7 @@ int main() {
if (strncmp(ERL_ATOM_PTR(fnp), "foo", 3) == 0) {
res = foo(ERL_INT_VALUE(argp));
- } else if (strncmp(ERL_ATOM_PTR(fnp), "bar", 17) == 0) {
+ } else if (strncmp(ERL_ATOM_PTR(fnp), "bar", 3) == 0) {
res = bar(ERL_INT_VALUE(argp));
}
diff --git a/system/doc/tutorial/example.xmlsrc b/system/doc/tutorial/example.xmlsrc
index d49c7fe88c..91f09ec522 100644
--- a/system/doc/tutorial/example.xmlsrc
+++ b/system/doc/tutorial/example.xmlsrc
@@ -11,7 +11,7 @@
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
-
+
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
@@ -19,7 +19,7 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-
+
</legalnotice>
<title>Problem Example</title>
@@ -39,7 +39,7 @@
<codeinclude file="complex.c" tag="" type="none"></codeinclude>
<p>The functions are deliberately kept as simple as possible, for
readability reasons.</p>
- <p>From an Erlang perspektive, it is preferable to be able to call
+ <p>From an Erlang perspective, it is preferable to be able to call
<c>foo</c> and <c>bar</c> without having to bother about that
they are C functions:</p>
<pre>