{
    "mode": "man",
    "parameter": "SUDO_LOGSRV.PROTO",
    "section": "5",
    "url": "https://www.chedong.com/phpMan.php/man/SUDO_LOGSRV.PROTO/5/json",
    "generated": "2026-06-14T12:38:33Z",
    "sections": {
        "NAME": {
            "content": "sudologsrv.proto — Sudo log server protocol\n",
            "subsections": []
        },
        "DESCRIPTION": {
            "content": "Starting with version 1.9.0, sudo supports sending event and I/O logs to a log server.  The\nprotocol used is written in Google's Protocol Buffers domain specific language.  The EXAMPLES\nsection includes a complete description of the protocol in Protocol Buffers format.\n\nBecause there is no way to determine message boundaries when using Protocol Buffers, the wire\nsize of each message is sent immediately preceding the message itself as a 32-bit unsigned in‐\nteger in network byte order.  This is referred to as “length-prefix framing” and is how Google\nsuggests handling the lack of message delimiters.\n\nThe protocol is made up of two basic messages, ClientMessage and ServerMessage, described be‐\nlow.  The server must accept messages up to two megabytes in size.  The server may return an\nerror if the client tries to send a message larger than two megabytes.\n",
            "subsections": [
                {
                    "name": "Client Messages",
                    "content": "A ClientMessage is a container used to encapsulate all the possible message types a client may\nsend to the server.\n\nmessage ClientMessage {\noneof type {\nAcceptMessage acceptmsg = 1;\nRejectMessage rejectmsg = 2;\nExitMessage exitmsg = 3;\nRestartMessage restartmsg = 4;\nAlertMessage alertmsg = 5;\nIoBuffer ttyinbuf = 6;\nIoBuffer ttyoutbuf = 7;\nIoBuffer stdinbuf = 8;\nIoBuffer stdoutbuf = 9;\nIoBuffer stderrbuf = 10;\nChangeWindowSize winsizeevent = 11;\nCommandSuspend suspendevent = 12;\nClientHello hellomsg = 13;\n}\n}\n\nThe different ClientMessage sub-messages the client may sent to the server are described below.\n"
                },
                {
                    "name": "TimeSpec",
                    "content": "message TimeSpec {\nint64 tvsec = 1;\nint32 tvnsec = 2;\n}\n\nA TimeSpec is the equivalent of a POSIX struct timespec, containing seconds and nanoseconds\nmembers.  The tvsec member is a 64-bit integer to support dates after the year 2038.\n"
                },
                {
                    "name": "InfoMessage",
                    "content": "message InfoMessage {\nmessage StringList {\nrepeated string strings = 1;\n}\nmessage NumberList {\nrepeated int64 numbers = 1;\n}\nstring key = 1;\noneof value {\nint64 numval = 2;\nstring strval = 3;\nStringList strlistval = 4;\nNumberList numlistval = 5;\n}\n}\n\nAn InfoMessage is used to represent information about the invoking user as well as the execu‐\ntion environment the command runs in the form of key-value pairs.  The key is always a string\nbut the value may be a 64-bit integer, a string, an array of strings, or an array of 64-bit in‐\ntegers.  The event log data is composed of InfoMessage entries.  See the EVENT LOG VARIABLES\nsection for more information.\n\nClientHello hellomsg\nmessage ClientHello {\nstring clientid = 1;\n}\n\nA ClientHello message consists of client information that may be sent to the server when the\nclient first connects.\n\nclientid\nA free-form client description.  This usually includes the name and version of the\nclient implementation.\n\nAcceptMessage acceptmsg\nmessage AcceptMessage {\nTimeSpec submittime = 1;\nrepeated InfoMessage infomsgs = 2;\nbool expectiobufs = 3;\n}\n\nAn AcceptMessage is sent by the client when a command is allowed by the security policy.  It\ncontains the following members:\n\nsubmittime\nThe wall clock time when the command was submitted to the security policy.\n\ninfomsgs\nAn array of InfoMessage describing the user who submitted the command as well as the\nexecution environment of the command.  This information is used to generate an event\nlog entry and may also be used by server to determine where and how the I/O log is\nstored.\n\nexpectiobufs\nSet to true if the server should expect IoBuffer messages to follow (for I/O logging)\nor false if the server should only store the event log.\n\nIf an AcceptMessage is sent, the client must not send a RejectMessage or RestartMessage.\n\nRejectMessage rejectmsg\nmessage RejectMessage {\nTimeSpec submittime = 1;\nstring reason = 2;\nrepeated InfoMessage infomsgs = 3;\n}\n\nA RejectMessage is sent by the client when a command is denied by the security policy.  It con‐\ntains the following members:\n\nsubmittime\nThe wall clock time when the command was submitted to the security policy.\n\nreason  The reason the security policy gave for denying the command.\n\ninfomsgs\nAn array of InfoMessage describing the user who submitted the command as well as the\nexecution environment of the command.  This information is used to generate an event\nlog entry.\n\nIf a RejectMessage is sent, the client must not send an AcceptMessage or RestartMessage.\n\nExitMessage exitmsg\nmessage ExitMessage {\nTimeSpec runtime = 1;\nint32 exitvalue = 2;\nbool dumpedcore = 3;\nstring signal = 4;\nstring error = 5;\n}\n\nAn ExitMessage is sent by the client after the command has exited or has been terminated by a\nsignal.  It contains the following members:\n\nruntime\nThe total amount of elapsed time since the command started, calculated using a mono‐\ntonic clock where possible.  This is not the wall clock time.\n\nexitvalue\nThe command's exit value in the range 0-255.\n\ndumpedcore\nTrue if the command was terminated by a signal and dumped core.\n\nsignal  If the command was terminated by a signal, this is set to the name of the signal with‐\nout the leading “SIG”.  For example, INT, TERM, KILL, SEGV.\n\nerror   A message from the client indicating that the command was terminated unexpectedly due\nto an error.\n\nWhen performing I/O logging, the client should wait for a commitpoint corresponding to the fi‐\nnal IoBuffer before closing the connection unless the final commitpoint has already been re‐\nceived.\n\nRestartMessage restartmsg\nmessage RestartMessage {\nstring logid = 1;\nTimeSpec resumepoint = 2;\n}\n\nA RestartMessage is sent by the client to resume sending an existing I/O log that was previ‐\nously interrupted.  It contains the following members:\n\nlogid  The the server-side name for an I/O log that was previously sent to the client by the\nserver.  This may be a path name on the server or some other kind of server-side iden‐\ntifier.\n\nresumepoint\nThe point in time after which to resume the I/O log.  This is in the form of a TimeSpec\nrepresenting the amount of time since the command started, not the wall clock time.\nThe resumepoint should correspond to a commitpoint previously sent to the client by\nthe server.  If the server receives a RestartMessage containing a resumepoint it has\nnot previously seen, an error will be returned to the client and the connection will be\ndropped.\n\nIf a RestartMessage is sent, the client must not send an AcceptMessage or RejectMessage.\n\nAlertMessage alertmsg\nmessage AlertMessage {\nTimeSpec alerttime = 1;\nstring reason = 2;\nrepeated InfoMessage infomsgs = 3;\n}\n\nAn AlertMessage is sent by the client to indicate a problem detected by the security policy\nwhile the command is running that should be stored in the event log.  It contains the following\nmembers:\n\nalerttime\nThe wall clock time when the alert occurred.\n\nreason  The reason for the alert.\n\ninfomsgs\nAn optional array of InfoMessage describing the user who submitted the command as well\nas the execution environment of the command.  This information is used to generate an\nevent log entry.\n\nIoBuffer ttyinbuf | ttyoutbuf | stdinbuf | stdoutbuf | stderrbuf\nmessage IoBuffer {\nTimeSpec delay = 1;\nbytes data = 2;\n}\n\nAn IoBuffer is used to represent data from terminal input, terminal output, standard input,\nstandard output, or standard error.  It contains the following members:\n\ndelay   The elapsed time since the last record in the form of a TimeSpec.  The delay should be\ncalculated using a monotonic clock where possible.\n\ndata    The binary I/O log data from terminal input, terminal output, standard input, standard\noutput, or standard error.\n\nChangeWindowSize winsizeevent\nmessage ChangeWindowSize {\nTimeSpec delay = 1;\nint32 rows = 2;\nint32 cols = 3;\n}\n\nA ChangeWindowSize message is sent by the client when the terminal running the command changes\nsize.  It contains the following members:\n\ndelay   The elapsed time since the last record in the form of a TimeSpec.  The delay should be\ncalculated using a monotonic clock where possible.\n\nrows    The new number of terminal rows.\n\ncols    The new number of terminal columns.\n\nCommandSuspend suspendevent\nmessage CommandSuspend {\nTimeSpec delay = 1;\nstring signal = 2;\n}\n\nA CommandSuspend message is sent by the client when the command is either suspended or resumed.\nIt contains the following members:\n\ndelay   The elapsed time since the last record in the form of a TimeSpec.  The delay should be\ncalculated using a monotonic clock where possible.\n\nsignal  The signal name without the leading “SIG”.  For example, STOP, TSTP, CONT.\n"
                },
                {
                    "name": "Server Messages",
                    "content": "A ServerMessage is a container used to encapsulate all the possible message types the server\nmay send to a client.\n\nmessage ServerMessage {\noneof type {\nServerHello hello = 1;\nTimeSpec commitpoint = 2;\nstring logid = 3;\nstring error = 4;\nstring abort = 5;\n}\n}\n\nThe different ServerMessage sub-messages the server may sent to the client are described below.\n"
                },
                {
                    "name": "ServerHello hello",
                    "content": "message ServerHello {\nstring serverid = 1;\nstring redirect = 2;\nrepeated string servers = 3;\nbool subcommands = 4;\n}\n\nThe ServerHello message consists of server information sent when the client first connects.  It\ncontains the following members:\n\nserverid\nA free-form server description.  Usually this includes the name and version of the im‐\nplementation running on the log server.  This member is always present.\n\nredirect\nA host and port separated by a colon (‘’): that the client should connect to instead.\nThe host may be a host name, an IPv4 address, or an IPv6 address in square brackets.\nThis may be used for server load balancing.  The server will disconnect after sending\nthe ServerHello when it includes a redirect.\n\nservers\nA list of other known log servers.  This can be used to implement log server redundancy\nand allows the client to discover all other log servers simply by connecting to one\nknown server.  This member may be omitted when there is only a single log server.\n\nsubcommands\nIf set, the server supports logging additional commands during a session.  The client\nmay send an AcceptMessage or RejectMessage when sudo is running in intercept mode.  In\nthis mode, commands spawned from the initial command authorized by sudo are subject to\npolicy restrictions and/or are logged.  If subcommands is false, the client must not\nattempt to log additional commands.\n\nTimeSpec commitpoint\nA periodic time stamp sent by the server to indicate when I/O log buffers have been committed\nto storage.  This message is not sent after every IoBuffer but rather at a server-configurable\ninterval.  When the server receives an ExitMessage, it will respond with a commitpoint corre‐\nsponding to the last received IoBuffer before closing the connection.\n\nstring logid\nThe server-side ID of the I/O log being stored, sent in response to an AcceptMessage where\nexpectiobufs is true.\n"
                },
                {
                    "name": "string error",
                    "content": "A fatal server-side error.  The server will close the connection after sending the error mes‐\nsage.\n"
                },
                {
                    "name": "string abort",
                    "content": "An abort message from the server indicates that the client should kill the command and termi‐\nnate the session.  It may be used to implement simple server-side policy.  The server will\nclose the connection after sending the abort message.\n"
                },
                {
                    "name": "Protocol flow of control",
                    "content": "The expected protocol flow is as follows:\n\n1.   Client connects to the first available server.  If the client is configured to use TLS, a\nTLS handshake will be attempted.\n\n2.   Client sends ClientHello.  This is currently optional but allows the server to detect a\nnon-TLS connection on the TLS port.\n\n3.   Server sends ServerHello.\n\n4.   Client responds with either AcceptMessage, RejectMessage, or RestartMessage.\n\n5.   If client sent a AcceptMessage with expectiobufs set, server creates a new I/O log and\nresponds with a logid.\n\n6.   Client sends zero or more IoBuffer messages.\n\n7.   Server periodically responds to IoBuffer messages with a commitpoint.\n\n8.   Client sends an ExitMessage when the command exits or is killed.\n\n9.   Server sends the final commitpoint if one is pending.\n\n10.  Server closes the connection.  After receiving the final commitpoint, the client shuts\ndown its side of the TLS connection if TLS is in use, and closes the connection.\n\n11.  Server shuts down its side of the TLS connection if TLS is in use, and closes the connec‐\ntion.\n\nAt any point, the server may send an error or abort message to the client at which point the\nserver will close the connection.  If an abort message is received, the client should terminate\nthe running command.\n"
                }
            ]
        },
        "EVENT LOG VARIABLES": {
            "content": "AcceptMessage, AlertMessage and RejectMessage classes contain an array of InfoMessage that\nshould contain information about the user who submitted the command as well as information\nabout the execution environment of the command if it was accepted.\n\nSome variables have a client, run, or submit prefix.  These prefixes are used to eliminate am‐\nbiguity for variables that could apply to the client program, the user submitting the command,\nor the command being run.  Variables with a client prefix pertain to the program performing the\nconnection to the log server, for example sudo.  Variables with a run prefix pertain to the\ncommand that the user requested be run.  Variables with a submit prefix pertain to the user\nsubmitting the request (the user running sudo).\n\nThe following InfoMessage entries are required:\n",
            "subsections": [
                {
                    "name": "Key            Type          Description",
                    "content": "command        string        command that was submitted\nrunuser        string        name of user the command was run as\nsubmithost     string        name of host the command was submitted on\nsubmituser     string        name of user submitting the command\n\nThe following InfoMessage entries are recognized, but not required:\n"
                },
                {
                    "name": "Key            Type          Description",
                    "content": "clientargv     StringList    client's original argument vector\nclientpid      int64         client's process ID\nclientppid     int64         client's parent process ID\nclientsid      int64         client's terminal session ID\ncolumns        int64         number of columns in the terminal\nlines          int64         number of lines in the terminal\nrunargv        StringList    argument vector of command to run\nrunchroot      string        root directory of command to run\nruncwd         string        running command's working directory\nrunenv         StringList    the running command's environment\nrungid         int64         primary group-ID of the command\nrungids        NumberList    supplementary group-IDs for the command\nrungroup       string        primary group name of the command\nrungroups      StringList    supplementary group names for the command\nrunuid         int64         run user's user-ID\nsubmitcwd      string        submit user's current working directory\nsubmitenv      StringList    the submit user's environment\nsubmitgid      int64         submit user's primary group-ID\nsubmitgids     NumberList    submit user's supplementary group-IDs\nsubmitgroup    string        submitting user's primary group name\nsubmitgroups   StringList    submit user's supplementary group names\nsubmituid      int64         submit user's user-ID\nttyname        string        the terminal the command was submitted from\n\nThe server must accept other variables not listed above but may ignore them.\n"
                }
            ]
        },
        "EXAMPLES": {
            "content": "The Protocol Buffers description of the log server protocol is included in full below.  Note\nthat this uses the newer “proto3” syntax.\n\nsyntax = \"proto3\";\n\n/*\n* Client message to the server.  Messages on the wire are\n* prefixed with a 32-bit size in network byte order.\n*/\nmessage ClientMessage {\noneof type {\nAcceptMessage acceptmsg = 1;\nRejectMessage rejectmsg = 2;\nExitMessage exitmsg = 3;\nRestartMessage restartmsg = 4;\nAlertMessage alertmsg = 5;\nIoBuffer ttyinbuf = 6;\nIoBuffer ttyoutbuf = 7;\nIoBuffer stdinbuf = 8;\nIoBuffer stdoutbuf = 9;\nIoBuffer stderrbuf = 10;\nChangeWindowSize winsizeevent = 11;\nCommandSuspend suspendevent = 12;\n}\n}\n\n/* Equivalent of POSIX struct timespec */\nmessage TimeSpec {\nint64 tvsec = 1;           /* seconds */\nint32 tvnsec = 2;          /* nanoseconds */\n}\n\n/* I/O buffer with keystroke data */\nmessage IoBuffer {\nTimeSpec delay = 1;           /* elapsed time since last record */\nbytes data = 2;               /* keystroke data */\n}\n\n/*\n* Key/value pairs, like Privilege Manager struct info.\n* The value may be a number, a string, or a list of strings.\n*/\nmessage InfoMessage {\nmessage StringList {\nrepeated string strings = 1;\n}\nmessage NumberList {\nrepeated int64 numbers = 1;\n}\nstring key = 1;\noneof value {\nint64 numval = 2;\nstring strval = 3;\nStringList strlistval = 4;\nNumberList numlistval = 5;\n}\n}\n\n/*\n* Event log data for command accepted by the policy.\n*/\nmessage AcceptMessage {\nTimeSpec submittime = 1;             /* when command was submitted */\nrepeated InfoMessage infomsgs = 2;   /* key,value event log data */\nbool expectiobufs = 3;               /* true if I/O logging enabled */\n}\n\n/*\n* Event log data for command rejected by the policy.\n*/\nmessage RejectMessage {\nTimeSpec submittime = 1;             /* when command was submitted */\nstring reason = 2;                    /* reason command was rejected */\nrepeated InfoMessage infomsgs = 3;   /* key,value event log data */\n}\n\n/* Message sent by client when command exits. */\n/* Might revisit runtime and use endtime instead */\nmessage ExitMessage {\nTimeSpec runtime = 1;        /* total elapsed run time */\nint32 exitvalue = 2;         /* 0-255 */\nbool dumpedcore = 3;         /* true if command dumped core */\nstring signal = 4;            /* signal name if killed by signal */\nstring error = 5;             /* if killed due to other error */\n}\n\n/* Alert message, policy module-specific. */\nmessage AlertMessage {\nTimeSpec alerttime = 1;              /* time alert message occurred */\nstring reason = 2;                    /* policy alert error string */\nrepeated InfoMessage infomsgs = 3;   /* key,value event log data */\n}\n\n/* Used to restart an existing I/O log on the server. */\nmessage RestartMessage {\nstring logid = 1;            /* ID of log being restarted */\nTimeSpec resumepoint = 2;    /* resume point (elapsed time) */\n}\n\n/* Window size change event. */\nmessage ChangeWindowSize {\nTimeSpec delay = 1;           /* elapsed time since last record */\nint32 rows = 2;               /* new number of rows */\nint32 cols = 3;               /* new number of columns */\n}\n\n/* Command suspend/resume event. */\nmessage CommandSuspend {\nTimeSpec delay = 1;           /* elapsed time since last record */\nstring signal = 2;            /* signal that caused suspend/resume */\n}\n\n/*\n* Server messages to the client.  Messages on the wire are\n* prefixed with a 32-bit size in network byte order.\n*/\nmessage ServerMessage {\noneof type {\nServerHello hello = 1;      /* server hello message */\nTimeSpec commitpoint = 2;  /* cumulative time of records stored */\nstring logid = 3;          /* ID of server-side I/O log */\nstring error = 4;           /* error message from server */\nstring abort = 5;           /* abort message, kill command */\n}\n}\n\n/* Hello message from server when client connects. */\nmessage ServerHello {\nstring serverid = 1;         /* free-form server description */\nstring redirect = 2;          /* optional redirect if busy */\nrepeated string servers = 3;  /* optional list of known servers */\n}\n",
            "subsections": []
        },
        "SEE ALSO": {
            "content": "sudologsrvd.conf(5), sudoers(5), sudo(8), sudologsrvd(8)\n\nProtocol Buffers, https://developers.google.com/protocol-buffers/.\n",
            "subsections": []
        },
        "HISTORY": {
            "content": "See the HISTORY file in the sudo distribution (https://www.sudo.ws/history.html) for a brief\nhistory of sudo.\n",
            "subsections": []
        },
        "AUTHORS": {
            "content": "Many people have worked on sudo over the years; this version consists of code written primarily\nby:\n\nTodd C. Miller\n\nSee the CONTRIBUTORS file in the sudo distribution (https://www.sudo.ws/contributors.html) for\nan exhaustive list of people who have contributed to sudo.\n",
            "subsections": []
        },
        "BUGS": {
            "content": "If you feel you have found a bug in sudo, please submit a bug report at\nhttps://bugzilla.sudo.ws/\n",
            "subsections": []
        },
        "SUPPORT": {
            "content": "Limited free support is available via the sudo-users mailing list, see\nhttps://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or search the archives.\n",
            "subsections": []
        },
        "DISCLAIMER": {
            "content": "sudo is provided “AS IS” and any express or implied warranties, including, but not limited to,\nthe implied warranties of merchantability and fitness for a particular purpose are disclaimed.\nSee the LICENSE file distributed with sudo or https://www.sudo.ws/license.html for complete de‐\ntails.\n",
            "subsections": []
        },
        "Sudo 1.9.9                     January 19, 2022                     Sudo 1.9.9": {
            "content": "",
            "subsections": []
        }
    },
    "summary": "sudologsrv.proto — Sudo log server protocol",
    "flags": [],
    "examples": [
        "The Protocol Buffers description of the log server protocol is included in full below.  Note",
        "that this uses the newer “proto3” syntax.",
        "syntax = \"proto3\";",
        "/*",
        "* Client message to the server.  Messages on the wire are",
        "* prefixed with a 32-bit size in network byte order.",
        "*/",
        "message ClientMessage {",
        "oneof type {",
        "AcceptMessage acceptmsg = 1;",
        "RejectMessage rejectmsg = 2;",
        "ExitMessage exitmsg = 3;",
        "RestartMessage restartmsg = 4;",
        "AlertMessage alertmsg = 5;",
        "IoBuffer ttyinbuf = 6;",
        "IoBuffer ttyoutbuf = 7;",
        "IoBuffer stdinbuf = 8;",
        "IoBuffer stdoutbuf = 9;",
        "IoBuffer stderrbuf = 10;",
        "ChangeWindowSize winsizeevent = 11;",
        "CommandSuspend suspendevent = 12;",
        "/* Equivalent of POSIX struct timespec */",
        "message TimeSpec {",
        "int64 tvsec = 1;           /* seconds */",
        "int32 tvnsec = 2;          /* nanoseconds */",
        "/* I/O buffer with keystroke data */",
        "message IoBuffer {",
        "TimeSpec delay = 1;           /* elapsed time since last record */",
        "bytes data = 2;               /* keystroke data */",
        "/*",
        "* Key/value pairs, like Privilege Manager struct info.",
        "* The value may be a number, a string, or a list of strings.",
        "*/",
        "message InfoMessage {",
        "message StringList {",
        "repeated string strings = 1;",
        "message NumberList {",
        "repeated int64 numbers = 1;",
        "string key = 1;",
        "oneof value {",
        "int64 numval = 2;",
        "string strval = 3;",
        "StringList strlistval = 4;",
        "NumberList numlistval = 5;",
        "/*",
        "* Event log data for command accepted by the policy.",
        "*/",
        "message AcceptMessage {",
        "TimeSpec submittime = 1;             /* when command was submitted */",
        "repeated InfoMessage infomsgs = 2;   /* key,value event log data */",
        "bool expectiobufs = 3;               /* true if I/O logging enabled */",
        "/*",
        "* Event log data for command rejected by the policy.",
        "*/",
        "message RejectMessage {",
        "TimeSpec submittime = 1;             /* when command was submitted */",
        "string reason = 2;                    /* reason command was rejected */",
        "repeated InfoMessage infomsgs = 3;   /* key,value event log data */",
        "/* Message sent by client when command exits. */",
        "/* Might revisit runtime and use endtime instead */",
        "message ExitMessage {",
        "TimeSpec runtime = 1;        /* total elapsed run time */",
        "int32 exitvalue = 2;         /* 0-255 */",
        "bool dumpedcore = 3;         /* true if command dumped core */",
        "string signal = 4;            /* signal name if killed by signal */",
        "string error = 5;             /* if killed due to other error */",
        "/* Alert message, policy module-specific. */",
        "message AlertMessage {",
        "TimeSpec alerttime = 1;              /* time alert message occurred */",
        "string reason = 2;                    /* policy alert error string */",
        "repeated InfoMessage infomsgs = 3;   /* key,value event log data */",
        "/* Used to restart an existing I/O log on the server. */",
        "message RestartMessage {",
        "string logid = 1;            /* ID of log being restarted */",
        "TimeSpec resumepoint = 2;    /* resume point (elapsed time) */",
        "/* Window size change event. */",
        "message ChangeWindowSize {",
        "TimeSpec delay = 1;           /* elapsed time since last record */",
        "int32 rows = 2;               /* new number of rows */",
        "int32 cols = 3;               /* new number of columns */",
        "/* Command suspend/resume event. */",
        "message CommandSuspend {",
        "TimeSpec delay = 1;           /* elapsed time since last record */",
        "string signal = 2;            /* signal that caused suspend/resume */",
        "/*",
        "* Server messages to the client.  Messages on the wire are",
        "* prefixed with a 32-bit size in network byte order.",
        "*/",
        "message ServerMessage {",
        "oneof type {",
        "ServerHello hello = 1;      /* server hello message */",
        "TimeSpec commitpoint = 2;  /* cumulative time of records stored */",
        "string logid = 3;          /* ID of server-side I/O log */",
        "string error = 4;           /* error message from server */",
        "string abort = 5;           /* abort message, kill command */",
        "/* Hello message from server when client connects. */",
        "message ServerHello {",
        "string serverid = 1;         /* free-form server description */",
        "string redirect = 2;          /* optional redirect if busy */",
        "repeated string servers = 3;  /* optional list of known servers */"
    ],
    "see_also": [
        {
            "name": "sudologsrvd.conf",
            "section": "5",
            "url": "https://www.chedong.com/phpMan.php/man/sudologsrvd.conf/5/json"
        },
        {
            "name": "sudoers",
            "section": "5",
            "url": "https://www.chedong.com/phpMan.php/man/sudoers/5/json"
        },
        {
            "name": "sudo",
            "section": "8",
            "url": "https://www.chedong.com/phpMan.php/man/sudo/8/json"
        },
        {
            "name": "sudologsrvd",
            "section": "8",
            "url": "https://www.chedong.com/phpMan.php/man/sudologsrvd/8/json"
        }
    ]
}