Skip to documentation
SLOP

tiny.stun.Builder

Reference tiny.stun Builder

Defined in tiny.stun.

API (18)

Actions

Public operations.

Fields and members

Public fields and members.

No direct callersNo direct callstiny.stunBuilder
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Source: lib/stun/src/message.zig:266

zig
pub const Builder = struct {    storage: []u8,    capacity: Capacity,    transaction_id: TransactionId,    index: usize = header_bytes,    attribute_count: u14 = 0,    state: BuilderState = .attributes,    pub fn init(        storage: []u8,        limits: Limits,        class: Class,        method: Method,        transaction_id: TransactionId,    ) EncodeError!Builder {        const capacity = try Capacity.derive(limits);        if (storage.len < capacity.message_bytes) return error.StorageTooSmall;        var builder = Builder{            .storage = storage[0..capacity.message_bytes],            .capacity = capacity,            .transaction_id = transaction_id,        };        std.mem.writeInt(u16, builder.storage[0..2], encodeType(method, class), .big);        std.mem.writeInt(u16, builder.storage[2..4], 0, .big);        std.mem.writeInt(u32, builder.storage[4..8], magic_cookie, .big);        @memcpy(builder.storage[8..20], &transaction_id);        return builder;    }    pub fn appendRaw(        self: *Builder,        type_code: u16,        value: []const u8,    ) EncodeError!void {        const zeros = [_]u8{ 0, 0, 0 };        const padding_len = attribute.paddingLength(value.len);        try self.appendRawPadded(type_code, value, zeros[0..padding_len]);    }    pub fn appendRawPadded(        self: *Builder,        type_code: u16,        value: []const u8,        padding: []const u8,    ) EncodeError!void {        if (self.state != .attributes) return error.InvalidBuilderState;        if (isIntegrityOrFingerprint(type_code)) return error.UseFinishFunction;        if (padding.len != attribute.paddingLength(value.len)) {            return error.InvalidAttributePadding;        }        const region = try self.reserve(value.len, padding.len);        std.mem.writeInt(u16, self.storage[region.start..][0..2], type_code, .big);        std.mem.writeInt(u16, self.storage[region.start + 2 ..][0..2], @intCast(value.len), .big);        @memcpy(self.storage[region.value_start..region.value_end], value);        @memcpy(self.storage[region.value_end..region.end], padding);        self.commit(region.end);    }    pub fn appendDecoded(self: *Builder, value: attribute.Attribute) EncodeError!void {        try self.appendRawPadded(value.type_code, value.raw_value, value.padding);    }    pub fn appendUsername(self: *Builder, username: []const u8) EncodeError!void {        _ = try integrity.shortTermKey(username);        try self.appendRaw(@backingInt(attribute.Type.username), username);    }    pub fn appendAddress(        self: *Builder,        attribute_type: attribute.Type,        address: attribute.Address,    ) EncodeError!void {        const xor_cookie: ?u32 = switch (attribute_type) {            .xor_mapped_address => magic_cookie,            .mapped_address, .alternate_server, .response_origin, .other_address => null,            else => return error.InvalidAttributeType,        };        var encoded: [20]u8 = undefined;        const length = attribute.encodeAddress(            &encoded,            address,            xor_cookie,            self.transaction_id,        );        try self.appendRaw(@backingInt(attribute_type), encoded[0..length]);    }    pub fn appendChangeRequest(        self: *Builder,        request: attribute.ChangeRequest,    ) EncodeError!void {        var encoded: [4]u8 = @splat(0);        if (request.change_ip) encoded[3] |= 0x04;        if (request.change_port) encoded[3] |= 0x02;        try self.appendRaw(@backingInt(attribute.Type.change_request), &encoded);    }    pub fn appendResponsePort(self: *Builder, port: u16) EncodeError!void {        var encoded: [2]u8 = undefined;        std.mem.writeInt(u16, &encoded, port, .big);        try self.appendRaw(@backingInt(attribute.Type.response_port), &encoded);    }    pub fn finishIntegrity(self: *Builder, key: []const u8) EncodeError!void {        if (self.state != .attributes) return error.InvalidBuilderState;        const region = try self.reserve(integrity.sha1_bytes, 0);        writeAttributeHeader(            self.storage,            region.start,            @backingInt(attribute.Type.message_integrity),            integrity.sha1_bytes,        );        @memset(self.storage[region.value_start..region.value_end], 0);        const adjusted_len: u16 = @intCast(region.end - header_bytes);        var digest: [integrity.sha1_bytes]u8 = undefined;        integrity.hmacSha1Adjusted(&digest, self.storage, region.start, adjusted_len, key);        @memcpy(self.storage[region.value_start..region.value_end], &digest);        self.state = .sha1;        self.commit(region.end);    }    pub fn finishIntegritySha256(self: *Builder, key: []const u8) EncodeError!void {        if (self.state != .attributes and self.state != .sha1) {            return error.InvalidBuilderState;        }        const region = try self.reserve(integrity.sha256_bytes, 0);        writeAttributeHeader(            self.storage,            region.start,            @backingInt(attribute.Type.message_integrity_sha256),            integrity.sha256_bytes,        );        @memset(self.storage[region.value_start..region.value_end], 0);        const adjusted_len: u16 = @intCast(region.end - header_bytes);        var digest: [integrity.sha256_bytes]u8 = undefined;        integrity.hmacSha256Adjusted(&digest, self.storage, region.start, adjusted_len, key);        @memcpy(self.storage[region.value_start..region.value_end], &digest);        self.state = .sha256;        self.commit(region.end);    }    pub fn finishFingerprint(self: *Builder) EncodeError!void {        if (self.state == .fingerprint) return error.InvalidBuilderState;        const region = try self.reserve(4, 0);        writeAttributeHeader(            self.storage,            region.start,            @backingInt(attribute.Type.fingerprint),            4,        );        @memset(self.storage[region.value_start..region.value_end], 0);        self.patchLength(region.end);        const value = integrity.fingerprint(self.storage[0..region.start]);        std.mem.writeInt(u32, self.storage[region.value_start..][0..4], value, .big);        self.state = .fingerprint;        self.commit(region.end);    }    pub fn finish(self: *Builder) []const u8 {        self.patchLength(self.index);        return self.storage[0..self.index];    }    fn reserve(self: *Builder, value_len: usize, padding_len: usize) EncodeError!BuilderRegion {        if (self.attribute_count == self.capacity.attributes) {            return error.AttributeLimitExceeded;        }        if (value_len > std.math.maxInt(u16)) return error.MessageTooLarge;        const value_start = std.math.add(usize, self.index, 4) catch            return error.CapacityOverflow;        const value_end = std.math.add(usize, value_start, value_len) catch            return error.CapacityOverflow;        const end = std.math.add(usize, value_end, padding_len) catch            return error.CapacityOverflow;        if (end > self.capacity.message_bytes) return error.MessageTooLarge;        if (end - header_bytes > max_payload_bytes) return error.MessageTooLarge;        return .{            .start = self.index,            .value_start = value_start,            .value_end = value_end,            .end = end,        };    }    fn commit(self: *Builder, end: usize) void {        std.debug.assert(end > self.index);        std.debug.assert(end <= self.capacity.message_bytes);        self.index = end;        self.attribute_count += 1;        self.patchLength(end);    }    fn patchLength(self: *Builder, end: usize) void {        std.debug.assert(end >= header_bytes);        std.debug.assert(end - header_bytes <= max_payload_bytes);        std.mem.writeInt(u16, self.storage[2..4], @intCast(end - header_bytes), .big);    }};

Source: lib/stun/src/root.zig:31

zig
pub const Builder = message_mod.Builder;
Called byCallsNo direct callersprivate sourcelib.stun.src.attributeencodeAddressBuilderappendRawBuilderappendAddress
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callersBuilderappendRawBuilderappendChangeRequest
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callersBuilderappendRawPaddedBuilderappendDecoded
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsBuilderappendAddressBuilderappendChangeRequestBuilderappendResponsePortBuilderappendUsernameprivate sourcelib.stun.src.attributepaddingLengthBuilderappendRawPaddedBuilderappendRaw
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsBuilderappendDecodedBuilderappendRawprivate sourcelib.stun.src.attributepaddingLengthprivate sourcelib.stun.src.message.Buildercommitprivate sourcelib.stun.src.message.Builderreserveprivate sourcelib.stun.src.messageisIntegrityOrFingerprintBuilderappendRawPadded
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callersBuilderappendRawBuilderappendResponsePort
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callerstiny.stunshortTermKeyBuilderappendRawBuilderappendUsername
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callersprivate sourcelib.stun.src.message.BuilderpatchLengthBuilderfinish
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callersprivate sourcelib.stun.src.integrityfingerprintprivate sourcelib.stun.src.message.Buildercommitprivate sourcelib.stun.src.message.BuilderpatchLengthprivate sourcelib.stun.src.message.Builderreserveprivate sourcelib.stun.src.messagewriteAttributeHeaderBuilderfinishFingerprint
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callersprivate sourcelib.stun.src.integrityhmacSha1Adjustedprivate sourcelib.stun.src.message.Buildercommitprivate sourcelib.stun.src.message.Builderreserveprivate sourcelib.stun.src.messagewriteAttributeHeaderBuilderfinishIntegrity
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callersprivate sourcelib.stun.src.integrityhmacSha256Adjustedprivate sourcelib.stun.src.message.Buildercommitprivate sourcelib.stun.src.message.Builderreserveprivate sourcelib.stun.src.messagewriteAttributeHeaderBuilderfinishIntegritySha256
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callersCapacityderiveprivate sourcelib.stun.src.messageencodeTypeBuilderinit
Static calls · unresolved targets: 0 · external targets: 0.

Audit

Definitions13
Public names13
Members6
Version26.7.0
Revisiondaab053ee433