 # Note that it's a plain JavaScript file, not a CoffeeScript file.
 protodef = require('./proto-def')
 
+crypto = require("crypto")
+
 # Each version of the protocol has a magic number specified in
 # `./proto-def.coffee`. The most recent version is 4. Generally the
 # official driver will always be updated to the newest version of the
 # protocol, though RethinkDB supports older versions for some time.
-protoVersion = protodef.VersionDummy.Version.V0_4
+protoVersion = protodef.VersionDummy.Version.V1_0
+protoVersionNumber = 0
 
 # We are using the JSON protocol for RethinkDB, which is the most
 # recent version. The older protocol is based on Protocol Buffers, and

                            # callback passed to the `r.connect`
                            # function.
                            @emit 'connect'
                            return
                        else if status_str == HANDSHAKE_AUTHFAIL
                            # Since there's a special error for
                            # authorization failure, we have to look
                            # for this specific error message.
                            @emit 'error',
                                new err.ReqlAuthError(
                                    """Could not connect to #{@host}:#{@port}, \
                                    incorrect authentication key.""")
                        else
                            # The protocol dictates that any other
                            # string but `SUCCESS` is an error
                            # indicating the problem, and that we
                            # should report the error to the user.
                            @emit 'error', new err.ReqlDriverError "Server dropped connection with message: \"" + status_str.trim() + "\""
                            return

            # Register the handshake callback on the socket. Once the
            # handshake completes, it will unregister itself and

                # response, and only disable this event listener at
                # that time.
                @buffer = Buffer.concat([@buffer, buf])
                # Next we read bytes until we get a null byte. Then we follow
                # the new handshake logic to authenticate the user with the
                # server.

                j = 0
                for b,i in @buffer
                    if b is 0
                        # Here we pull the status string out of the
                        # buffer and convert it into a string.
                        status_buf = @buffer.slice(j, i)
                        j = i+1
                        status_str = status_buf.toString()
                        # Get the reply from the server, and parse it as JSON
                        server_reply = JSON.parse(status_str)

                        if state is 1
                            if not server_reply.success
                                handshake_error(server_reply.error_code, server_reply.error)
                            min = server_reply.min_protocol_version
                            max = server_reply.max_protocol_version

                            if min > protoVersionNumber or max < protoVersionNumber
                                # We don't actually support changing the protocol yet, so just error.
                                throw new err.ReqlDriverError(
                                    """Unsupported protocol version #{protoVersionNumber}, \
                                    expected between #{min} and #{max}.""")
                            state = 2
                        else if state is 2
                            if not server_reply.success
                                handshake_error(server_reply.error_code, server_reply.error)

                            authentication = {}
                            server_first_message = server_reply.authentication

                            for item in server_first_message.split(",")
                                i = item.indexOf("=")
                                authentication[item.slice(0, i)] = item.slice(i+1)
                            auth_r = authentication.r
                            auth_salt = new Buffer(authentication.s, 'base64')
                            auth_i = parseInt(authentication.i)

                            if not auth_r.substr(0, r_string) == r_string
                                throw new err.ReqlAuthError("Invalid nonce from server")

                            client_final_message_without_proof = "c=biws,r=" + auth_r

                            salted_password = crypto.pbkdf2Sync(@rawSocket.password, auth_salt, auth_i, 32, "sha256")
                            client_key = crypto.createHmac("sha256", salted_password).update("Client Key").digest()
                            stored_key = crypto.createHash("sha256").update(client_key).digest()

                            auth_message =
                                client_first_message_bare + "," +
                                server_first_message + "," +
                                client_final_message_without_proof

                            client_signature = crypto.createHmac("sha256", stored_key).update(auth_message).digest()
                            client_proof = xor_bytes(client_key, client_signature)

                            server_key = crypto.createHmac("sha256", salted_password).update("Server Key").digest()
                            server_signature = crypto.createHmac("sha256", server_key).update(auth_message).digest()

                            state = 3

                            message = JSON.stringify({authentication: client_final_message_without_proof + ",p=" + client_proof.toString("base64")})

                            nullbyte = new Buffer('\0', "binary")

                            @rawSocket.write Buffer.concat([Buffer(message.toString()), nullbyte])
                        else if state is 3
                            if not server_reply.success
                                handshake_error(server_reply.error_code, server_reply.error)

                            first_equals = server_reply.authentication.indexOf('=')
                            v = server_reply.authentication.slice(first_equals+1)

                            if not compare_digest(v, server_signature.toString("base64"))
                                throw new err.ReqlAuthError("Invalid server signature")

                            state = 4
                            @rawSocket.removeListener('data', handshake_callback)
                            @rawSocket.on 'data', (buf) => @_data(buf)

                            # We also want to cancel the timeout error
                            # callback that we set earlier. Even though we
                            # haven't checked `status_str` yet, we've
                            # gotten a response so it isn't a timeout.
                            clearTimeout(timeout)

                            # Notify listeners we've connected
                            # successfully. Notably, the Connection
