├── .clangd ├── .github └── workflows │ ├── abi.yml │ ├── android.yml │ ├── build.yml │ ├── clang-analyze.yml │ ├── cmake_win.yml │ ├── codeql.yml │ ├── coverage.yml │ ├── coverity.yml │ ├── fedora.yml │ ├── freebsd.yml │ ├── ios.yml │ ├── lint.yml │ ├── mingw.yml │ ├── musl.yml │ ├── run-on-arch.yml │ ├── sanitizers.yml │ ├── sonar.yml │ ├── ssl.yml │ ├── strict-c.yml │ └── valgrind.yml ├── .gitignore ├── CHANGELOG.md ├── CMakeLists.txt ├── LICENSE ├── Makefile ├── README.md ├── cmake ├── FindMBEDTLS.cmake ├── libre-config.cmake ├── re-config.cmake └── sanitizer.cmake ├── docs ├── ChangeLog ├── TODO └── main.dox ├── include ├── re.h ├── re_aes.h ├── re_async.h ├── re_atomic.h ├── re_av1.h ├── re_base64.h ├── re_bfcp.h ├── re_btrace.h ├── re_conf.h ├── re_convert.h ├── re_crc32.h ├── re_dbg.h ├── re_dd.h ├── re_dns.h ├── re_fmt.h ├── re_h264.h ├── re_h265.h ├── re_hash.h ├── re_hmac.h ├── re_http.h ├── re_httpauth.h ├── re_ice.h ├── re_json.h ├── re_list.h ├── re_main.h ├── re_mbuf.h ├── re_md5.h ├── re_mem.h ├── re_mod.h ├── re_mqueue.h ├── re_msg.h ├── re_net.h ├── re_odict.h ├── re_pcp.h ├── re_rtmp.h ├── re_rtp.h ├── re_rtpext.h ├── re_sa.h ├── re_sdp.h ├── re_sha.h ├── re_shim.h ├── re_sip.h ├── re_sipevent.h ├── re_sipreg.h ├── re_sipsess.h ├── re_srtp.h ├── re_stun.h ├── re_sys.h ├── re_tcp.h ├── re_telev.h ├── re_thread.h ├── re_tls.h ├── re_tmr.h ├── re_trace.h ├── re_trice.h ├── re_turn.h ├── re_types.h ├── re_udp.h ├── re_unixsock.h ├── re_uri.h ├── re_websock.h ├── rem.h ├── rem_aac.h ├── rem_au.h ├── rem_aubuf.h ├── rem_auconv.h ├── rem_audio.h ├── rem_aufile.h ├── rem_auframe.h ├── rem_aulevel.h ├── rem_aumix.h ├── rem_auresamp.h ├── rem_autone.h ├── rem_avc.h ├── rem_dsp.h ├── rem_dtmf.h ├── rem_fir.h ├── rem_flv.h ├── rem_g711.h ├── rem_goertzel.h ├── rem_vid.h ├── rem_vidconv.h ├── rem_video.h └── rem_vidmix.h ├── mk └── Doxyfile ├── packaging ├── CMakeLists.txt └── libre.pc.in ├── rem ├── aac │ └── aac.c ├── au │ ├── fmt.c │ └── util.c ├── aubuf │ ├── ajb.c │ ├── ajb.h │ └── aubuf.c ├── auconv │ └── auconv.c ├── aufile │ ├── aufile.c │ ├── aufile.h │ └── wave.c ├── auframe │ └── auframe.c ├── aulevel │ └── aulevel.c ├── aumix │ └── aumix.c ├── auresamp │ └── resamp.c ├── autone │ └── tone.c ├── avc │ └── config.c ├── dtmf │ └── dec.c ├── fir │ └── fir.c ├── g711 │ └── g711.c ├── goertzel │ └── goertzel.c ├── vid │ ├── draw.c │ ├── fmt.c │ └── frame.c ├── vidconv │ └── vconv.c └── vidmix │ └── vidmix.c ├── sonar-project.properties ├── src ├── aes │ ├── apple │ │ └── aes.c │ ├── openssl │ │ └── aes.c │ └── stub.c ├── async │ └── async.c ├── av1 │ ├── depack.c │ ├── obu.c │ └── pkt.c ├── base64 │ └── b64.c ├── bfcp │ ├── attr.c │ ├── bfcp.h │ ├── conn.c │ ├── msg.c │ ├── reply.c │ └── request.c ├── btrace │ └── btrace.c ├── conf │ └── conf.c ├── crc32 │ └── crc32.c ├── dbg │ └── dbg.c ├── dd │ ├── dd.c │ ├── dd_enc.c │ └── putbit.c ├── dns │ ├── client.c │ ├── cstr.c │ ├── darwin │ │ └── srv.c │ ├── dname.c │ ├── dns.h │ ├── hdr.c │ ├── ns.c │ ├── res.c │ ├── rr.c │ ├── rrlist.c │ └── win32 │ │ └── srv.c ├── fmt │ ├── ch.c │ ├── hexdump.c │ ├── pl.c │ ├── print.c │ ├── prm.c │ ├── regex.c │ ├── str.c │ ├── str_error.c │ ├── text2pcap.c │ ├── time.c │ └── unicode.c ├── h264 │ ├── getbit.c │ ├── h264.h │ ├── nal.c │ └── sps.c ├── h265 │ └── nal.c ├── hash │ ├── func.c │ └── hash.c ├── hmac │ ├── apple │ │ └── hmac.c │ ├── hmac.c │ ├── hmac_sha1.c │ └── openssl │ │ └── hmac.c ├── http │ ├── auth.c │ ├── chunk.c │ ├── client.c │ ├── http.h │ ├── msg.c │ ├── request.c │ └── server.c ├── httpauth │ ├── basic.c │ └── digest.c ├── ice │ ├── cand.c │ ├── candpair.c │ ├── chklist.c │ ├── comp.c │ ├── connchk.c │ ├── ice.h │ ├── icem.c │ ├── icesdp.c │ ├── icestr.c │ ├── stunsrv.c │ └── util.c ├── json │ ├── decode.c │ ├── decode_odict.c │ └── encode.c ├── list │ └── list.c ├── main │ ├── init.c │ ├── main.c │ ├── main.h │ ├── method.c │ └── openssl.c ├── mbuf │ └── mbuf.c ├── md5 │ └── wrap.c ├── mem │ ├── mem.c │ ├── mem_pool.c │ └── secure.c ├── mod │ ├── dl.c │ ├── mod.c │ ├── mod_internal.h │ └── win32 │ │ └── dll.c ├── mqueue │ ├── mqueue.c │ ├── mqueue.h │ └── win32 │ │ └── pipe.c ├── msg │ ├── ctype.c │ └── param.c ├── net │ ├── bsd │ │ └── brt.c │ ├── if.c │ ├── ifaddrs.c │ ├── linux │ │ ├── addrs.c │ │ ├── macros.h │ │ └── rt.c │ ├── net.c │ ├── netstr.c │ ├── posix │ │ └── pif.c │ ├── rt.c │ ├── sock.c │ ├── sockopt.c │ └── win32 │ │ └── wif.c ├── odict │ ├── entry.c │ ├── get.c │ ├── odict.c │ ├── odict.h │ └── type.c ├── pcp │ ├── README │ ├── msg.c │ ├── option.c │ ├── payload.c │ ├── pcp.c │ ├── pcp.h │ ├── reply.c │ └── request.c ├── rtmp │ ├── README.md │ ├── amf.c │ ├── amf_dec.c │ ├── amf_enc.c │ ├── chunk.c │ ├── conn.c │ ├── control.c │ ├── ctrans.c │ ├── dechunk.c │ ├── hdr.c │ ├── rtmp.h │ └── stream.c ├── rtp │ ├── fb.c │ ├── member.c │ ├── ntp.c │ ├── pkt.c │ ├── rr.c │ ├── rtcp.c │ ├── rtcp.h │ ├── rtp.c │ ├── sdes.c │ ├── sess.c │ └── source.c ├── rtpext │ └── rtpext.c ├── sa │ ├── printaddr.c │ └── sa.c ├── sdp │ ├── attr.c │ ├── format.c │ ├── media.c │ ├── msg.c │ ├── sdp.h │ ├── session.c │ ├── str.c │ └── util.c ├── sha │ └── wrap.c ├── shim │ └── shim.c ├── sip │ ├── addr.c │ ├── auth.c │ ├── contact.c │ ├── cseq.c │ ├── ctrans.c │ ├── dialog.c │ ├── keepalive.c │ ├── keepalive_udp.c │ ├── msg.c │ ├── rack.c │ ├── reply.c │ ├── request.c │ ├── sip.c │ ├── sip.h │ ├── strans.c │ ├── transp.c │ └── via.c ├── sipevent │ ├── listen.c │ ├── msg.c │ ├── notify.c │ ├── sipevent.h │ └── subscribe.c ├── sipreg │ └── reg.c ├── sipsess │ ├── accept.c │ ├── ack.c │ ├── close.c │ ├── connect.c │ ├── info.c │ ├── listen.c │ ├── modify.c │ ├── prack.c │ ├── reply.c │ ├── request.c │ ├── sess.c │ ├── sipsess.h │ └── update.c ├── srtp │ ├── README │ ├── misc.c │ ├── replay.c │ ├── srtcp.c │ ├── srtp.c │ ├── srtp.h │ └── stream.c ├── stun │ ├── addr.c │ ├── attr.c │ ├── ctrans.c │ ├── dnsdisc.c │ ├── hdr.c │ ├── ind.c │ ├── keepalive.c │ ├── msg.c │ ├── rep.c │ ├── req.c │ ├── stun.c │ ├── stun.h │ └── stunstr.c ├── sys │ ├── daemon.c │ ├── endian.c │ ├── fs.c │ ├── rand.c │ ├── sleep.c │ └── sys.c ├── tcp │ ├── tcp.c │ └── tcp_high.c ├── telev │ └── telev.c ├── thread │ ├── posix.c │ ├── thread.c │ └── win32.c ├── tls │ ├── openssl │ │ ├── sni.c │ │ ├── tls.c │ │ ├── tls.h │ │ ├── tls_tcp.c │ │ └── tls_udp.c │ └── stub.c ├── tmr │ └── tmr.c ├── trace │ └── trace.c ├── trice │ ├── README.md │ ├── cand.c │ ├── candpair.c │ ├── chklist.c │ ├── connchk.c │ ├── lcand.c │ ├── rcand.c │ ├── stunsrv.c │ ├── tcpconn.c │ ├── trice.c │ └── trice.h ├── turn │ ├── chan.c │ ├── perm.c │ ├── turnc.c │ └── turnc.h ├── udp │ ├── mcast.c │ └── udp.c ├── unixsock │ └── unixsock.c ├── uri │ ├── uri.c │ └── uric.c └── websock │ └── websock.c └── test ├── CMakeLists.txt ├── aac.c ├── aes.c ├── async.c ├── au.c ├── aubuf.c ├── aulength.c ├── aulevel.c ├── aupos.c ├── auresamp.c ├── av1.c ├── base64.c ├── bfcp.c ├── combo └── dtls_turn.c ├── conf.c ├── convert.c ├── cplusplus.cpp ├── crc32.c ├── data ├── beep.wav ├── client.pem ├── client_wrongkey.pem ├── fstab.json ├── menu.json ├── rfc7159.json ├── server-ecdsa.pem ├── sni │ ├── client-interm.pem │ ├── root-ca.pem │ └── server-interm.pem ├── utf8.json ├── webapp.json └── widget.json ├── dd.c ├── dns.c ├── dsp.c ├── dtls.c ├── dtmf.c ├── fir.c ├── fmt.c ├── g711.c ├── h264.c ├── h265.c ├── hash.c ├── hmac.c ├── http.c ├── httpauth.c ├── ice.c ├── json.c ├── list.c ├── main.c ├── mbuf.c ├── md5.c ├── mem.c ├── mem_pool.c ├── mock ├── cert.c ├── dnssrv.c ├── nat.c ├── sipsrv.c ├── stunsrv.c └── turnsrv.c ├── mqueue.c ├── net.c ├── odict.c ├── pcp.c ├── remain.c ├── rtcp.c ├── rtmp.c ├── rtp.c ├── rtpext.c ├── sa.c ├── sdp.c ├── sha.c ├── sip.c ├── sipauth.c ├── sipevent.c ├── sipreg.c ├── sipsess.c ├── srtp.c ├── stun.c ├── sys.c ├── tcp.c ├── telev.c ├── test.c ├── test.h ├── thread.c ├── tls.c ├── tmr.c ├── trace.c ├── trice.c ├── turn.c ├── types.c ├── udp.c ├── unixsock.c ├── uri.c ├── vid.c ├── vidconv.c └── websock.c /.clangd: -------------------------------------------------------------------------------- 1 | If: 2 | PathMatch: [include/.*\.h] 3 | CompileFlags: 4 | Add: [-Wall, -DHAVE_INTTYPES_H, -include re.h] 5 | Remove: [-xobjective-c++-header] 6 | --- 7 | Diagnostics: 8 | Suppress: "-Wgnu-zero-variadic-macro-arguments" 9 | -------------------------------------------------------------------------------- /.github/workflows/abi.yml: -------------------------------------------------------------------------------- 1 | name: ABI Checks 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | 11 | jobs: 12 | abicheck: 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v4 17 | with: 18 | ref: 'v3.21.1' 19 | path: old 20 | 21 | - uses: actions/checkout@v4 22 | with: 23 | path: current 24 | 25 | - name: fix flaky azure mirrors 26 | if: ${{ runner.os == 'Linux' }} 27 | run: | 28 | sudo sed -i 's/azure\./de\./' /etc/apt/sources.list 29 | 30 | - name: install abidiff 31 | run: sudo apt-get update && sudo apt-get install -y abigail-tools 32 | 33 | - name: make shared lib 34 | run: | 35 | cmake -S old -B old/build && cmake --build old/build 36 | 37 | - name: make current shared lib 38 | run: | 39 | cmake -S current -B current/build && cmake --build current/build 40 | 41 | - name: abidiff compare 42 | id: abidiff 43 | run: abidiff old/build/libre.so current/build/libre.so 44 | continue-on-error: true 45 | 46 | - name: display warning 47 | if: steps.abidiff.outcome != 'success' 48 | run: echo "::warning::ABI Check failed - bump ABI version" 49 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | 11 | jobs: 12 | build: 13 | runs-on: ${{ matrix.os }} 14 | 15 | strategy: 16 | matrix: 17 | build_type: [Release, Debug] 18 | compiler: [gcc, clang, gcc-14] 19 | os: [ubuntu-22.04, ubuntu-24.04, macos-latest] 20 | exclude: 21 | - os: macos-latest 22 | compiler: gcc 23 | - os: macos-latest 24 | compiler: gcc-14 25 | - os: ubuntu-22.04 26 | compiler: gcc-14 27 | env: 28 | CC: ${{ matrix.compiler }} 29 | CMAKE_GENERATOR: Ninja 30 | 31 | steps: 32 | - uses: actions/checkout@v4 33 | 34 | - name: openssl path macos 35 | if: ${{ runner.os == 'macOS' }} 36 | run: | 37 | echo "OPENSSL_ROOT_DIR=$(brew --prefix openssl)" >> $GITHUB_ENV 38 | 39 | - name: fix flaky azure mirrors 40 | if: ${{ runner.os == 'Linux' }} 41 | run: | 42 | sudo sed -i 's/azure\./de\./' /etc/apt/sources.list 43 | 44 | - name: install packages 45 | if: ${{ runner.os == 'Linux' }} 46 | run: | 47 | sudo apt-get update && sudo apt-get install -y ninja-build 48 | 49 | - name: make info 50 | run: | 51 | echo "OS: ${{ matrix.os }}" 52 | echo "--- ${{ matrix.compiler }} DEBUG VERSION ---" 53 | ${{ matrix.compiler }} - --version 54 | 55 | - name: cmake 56 | run: | 57 | cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DCMAKE_C_FLAGS="-Werror" -DCMAKE_CXX_FLAGS="-Werror" 58 | cmake --build build -t retest 59 | 60 | - name: retest 61 | run: | 62 | ./build/test/retest -r -v 63 | -------------------------------------------------------------------------------- /.github/workflows/clang-analyze.yml: -------------------------------------------------------------------------------- 1 | name: clang analyze 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | 11 | jobs: 12 | clang-analyze: 13 | runs-on: ubuntu-24.04 14 | 15 | steps: 16 | - uses: actions/checkout@v4 17 | 18 | - name: fix flaky azure mirrors 19 | if: ${{ runner.os == 'Linux' }} 20 | run: | 21 | sudo sed -i 's/azure\./de\./' /etc/apt/sources.list 22 | 23 | - name: Install clang-tools 24 | run: | 25 | wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - 26 | sudo add-apt-repository "deb http://apt.llvm.org/noble/ llvm-toolchain-noble-18 main" 27 | sudo apt-get update && sudo apt-get install -y clang-tools-18 28 | 29 | - name: analyze 30 | run: | 31 | cmake -B build -DCMAKE_C_COMPILER=clang-18 32 | analyze-build-18 --cdb build/compile_commands.json --status-bugs -v 33 | -------------------------------------------------------------------------------- /.github/workflows/codeql.yml: -------------------------------------------------------------------------------- 1 | name: "CodeQL" 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | 11 | jobs: 12 | analyze: 13 | name: CodeQL Analyze 14 | runs-on: ubuntu-latest 15 | 16 | env: 17 | CMAKE_GENERATOR: Ninja 18 | 19 | steps: 20 | - name: Checkout repository 21 | uses: actions/checkout@v4 22 | 23 | - name: Initialize CodeQL 24 | uses: github/codeql-action/init@v3 25 | with: 26 | languages: cpp 27 | queries: security-extended 28 | 29 | - name: install packages 30 | run: | 31 | sudo apt-get update && sudo apt-get install -y ninja-build 32 | 33 | - run: | 34 | cmake -B build && cmake --build build 35 | 36 | - name: Perform CodeQL Analysis 37 | uses: github/codeql-action/analyze@v3 38 | 39 | -------------------------------------------------------------------------------- /.github/workflows/coverage.yml: -------------------------------------------------------------------------------- 1 | name: Coverage 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | 11 | jobs: 12 | coverage: 13 | runs-on: ubuntu-22.04 14 | 15 | env: 16 | CMAKE_GENERATOR: Ninja 17 | 18 | steps: 19 | - uses: actions/checkout@v4 20 | 21 | - name: fix flaky azure mirrors 22 | if: ${{ runner.os == 'Linux' }} 23 | run: | 24 | sudo sed -i 's/azure\./de\./' /etc/apt/sources.list 25 | 26 | - name: install packages 27 | run: | 28 | sudo apt-get update && sudo apt-get install -y ninja-build 29 | 30 | - name: make 31 | run: | 32 | cmake -B build -DCMAKE_C_FLAGS="--coverage" -DCMAKE_EXE_LINKER_FLAGS="--coverage" -DUSE_TRACE=ON 33 | cmake --build build -j -t retest 34 | 35 | - name: retest 36 | run: | 37 | ./build/test/retest -a -v 38 | ./build/test/retest -r -m select -v 39 | 40 | - name: gcov 41 | run: | 42 | gcov build/**/*.o 43 | 44 | - name: install gcovr 45 | run: | 46 | pip install gcovr==5.0 47 | 48 | - name: coverage check 49 | run: | 50 | min_cov="67.2" 51 | mkdir html 52 | cov=$(~/.local/bin/gcovr -r . --html-details html/index.html --json-summary | jq .line_percent) 53 | echo "Coverage: ${cov}% (min $min_cov%)" 54 | exit $(echo "$cov < $min_cov" | bc -l) 55 | 56 | - name: coverage zip 57 | run: | 58 | zip -r coverage.zip html 59 | 60 | - uses: actions/upload-artifact@v4 61 | with: 62 | name: coverage 63 | path: coverage.zip 64 | retention-days: 7 65 | -------------------------------------------------------------------------------- /.github/workflows/coverity.yml: -------------------------------------------------------------------------------- 1 | name: Coverity Check 2 | 3 | on: 4 | push: 5 | tags: 6 | - "*" 7 | branches: 8 | - coverity 9 | workflow_dispatch: 10 | 11 | jobs: 12 | coverity: 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v4 17 | - name: Prepare 18 | run: cmake -B ${{github.workspace}}/build 19 | - uses: vapier/coverity-scan-action@v1 20 | with: 21 | project: 'baresip%2Fre' 22 | token: ${{ secrets.COVERITY_SCAN_TOKEN }} 23 | command: make -C ${{github.workspace}}/build 24 | email: 'hallo@studio-link.de' 25 | -------------------------------------------------------------------------------- /.github/workflows/fedora.yml: -------------------------------------------------------------------------------- 1 | name: Fedora 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | 11 | jobs: 12 | build: 13 | runs-on: ${{ matrix.os }} 14 | container: fedora 15 | 16 | strategy: 17 | matrix: 18 | compiler: [clang] 19 | os: [ubuntu-latest] 20 | 21 | env: 22 | CC: ${{ matrix.compiler }} 23 | CMAKE_GENERATOR: Ninja 24 | 25 | steps: 26 | - uses: actions/checkout@v4 27 | - name: install devel tools 28 | run: | 29 | yum -y install gcc clang cmake make openssl-devel zlib-devel ninja-build 30 | 31 | - name: make info 32 | run: | 33 | echo "OS: ${{ matrix.os }}" 34 | echo "--- ${{ matrix.compiler }} DEBUG VERSION ---" 35 | ${{ matrix.compiler }} - --version 36 | cmake --version 37 | 38 | - name: make 39 | run: | 40 | cmake -B build -DCMAKE_C_FLAGS="-Werror" && cmake --build build -j 16 -t retest 41 | 42 | - name: retest 43 | run: | 44 | ./build/test/retest -r -v 45 | -------------------------------------------------------------------------------- /.github/workflows/freebsd.yml: -------------------------------------------------------------------------------- 1 | name: FreeBSD 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | timeout-minutes: 20 15 | 16 | env: 17 | CMAKE_GENERATOR: Ninja 18 | 19 | steps: 20 | - uses: actions/checkout@v4 21 | 22 | - name: Test in FreeBSD 23 | id: test 24 | uses: vmactions/freebsd-vm@v1 25 | with: 26 | usesh: true 27 | prepare: | 28 | pkg install -y ninja cmake 29 | 30 | run: | 31 | freebsd-version 32 | cmake -B build && cmake --build build -t retest 33 | ./build/test/retest -r -v 34 | -------------------------------------------------------------------------------- /.github/workflows/ios.yml: -------------------------------------------------------------------------------- 1 | name: iOS 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | 11 | jobs: 12 | ios: 13 | runs-on: macos-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v4 17 | 18 | - name: build Xcode 19 | run: | 20 | cmake -B build_xcode -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DCMAKE_DISABLE_FIND_PACKAGE_OpenSSL=ON -DUSE_OPENSSL=OFF -DCMAKE_C_FLAGS="-Werror" 21 | cmake --build build_xcode -- CODE_SIGNING_ALLOWED=NO 22 | 23 | - name: normal build 24 | run: | 25 | cmake -B build -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DCMAKE_DISABLE_FIND_PACKAGE_OpenSSL=ON -DUSE_OPENSSL=OFF -DCMAKE_C_FLAGS="-Werror" 26 | cmake --build build -j 27 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: lint 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | 11 | jobs: 12 | lint: 13 | 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - uses: actions/checkout@v4 18 | - name: ccheck 19 | run: | 20 | wget "https://raw.githubusercontent.com/baresip/baresip/main/test/ccheck.py" 21 | python3 ccheck.py 22 | - name: CMakeLint 23 | run: | 24 | pip install cmakelint 25 | find . -name "CMakeLists.txt" -exec ~/.local/bin/cmakelint {} + 26 | -------------------------------------------------------------------------------- /.github/workflows/musl.yml: -------------------------------------------------------------------------------- 1 | name: Alpine (musl) 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | container: alpine 15 | 16 | env: 17 | CMAKE_GENERATOR: Ninja 18 | 19 | steps: 20 | - uses: actions/checkout@v4 21 | - name: install devel tools 22 | run: | 23 | apk add musl-dev git cmake gcc g++ make binutils openssl-dev linux-headers zlib-dev ninja 24 | 25 | - name: make 26 | run: | 27 | cmake -B build -DCMAKE_C_FLAGS="-Werror" 28 | cmake --build build -j 29 | -------------------------------------------------------------------------------- /.github/workflows/run-on-arch.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - main 5 | pull_request: 6 | branches: 7 | - main 8 | 9 | jobs: 10 | build_job: 11 | # The host should always be linux 12 | runs-on: ubuntu-22.04 13 | name: Build on ${{ matrix.distro }} ${{ matrix.arch }} 14 | 15 | strategy: 16 | matrix: 17 | include: 18 | - arch: aarch64 19 | distro: bullseye 20 | - arch: armv7 21 | distro: ubuntu22.04 22 | 23 | steps: 24 | - uses: actions/checkout@v4 25 | 26 | - uses: uraimo/run-on-arch-action@v3 27 | name: Build artifact 28 | id: build 29 | with: 30 | arch: ${{ matrix.arch }} 31 | distro: ${{ matrix.distro }} 32 | 33 | # Not required, but speeds up builds 34 | githubToken: ${{ github.token }} 35 | 36 | install: | 37 | case "${{ matrix.distro }}" in 38 | ubuntu*|jessie|stretch|buster|bullseye) 39 | apt-get update -q -y 40 | apt-get install -q -y cmake gcc g++ libssl-dev ninja-build 41 | ;; 42 | esac 43 | 44 | run: | 45 | cmake -G Ninja -B build -DCMAKE_C_FLAGS="-Werror" 46 | cmake --build build -j --target retest 47 | ./build/test/retest -r -v 48 | -------------------------------------------------------------------------------- /.github/workflows/sanitizers.yml: -------------------------------------------------------------------------------- 1 | name: Sanitizers 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | 11 | jobs: 12 | sanitizers: 13 | runs-on: ${{ matrix.os }} 14 | 15 | strategy: 16 | matrix: 17 | os: [ubuntu-24.04] 18 | sanitizer: [thread, address, undefined] 19 | env: 20 | CC: clang-18 21 | CXX: clang++-18 22 | CMAKE_GENERATOR: Ninja 23 | CFLAGS: "-fsanitize=${{ matrix.sanitizer }} -fno-sanitize-recover=all -fno-sanitize=function" 24 | CXXFLAGS: "-fsanitize=${{ matrix.sanitizer }} -fno-sanitize-recover=all -fno-sanitize=function" 25 | ASAN_OPTIONS: fast_unwind_on_malloc=0 26 | 27 | steps: 28 | - uses: actions/checkout@v4 29 | 30 | - name: fix flaky azure mirrors 31 | if: ${{ runner.os == 'Linux' }} 32 | run: | 33 | sudo sed -i 's/azure\./de\./' /etc/apt/sources.list 34 | 35 | - name: mmap rnd_bits workaround 36 | run: | 37 | sudo sysctl -w vm.mmap_rnd_bits=28 38 | 39 | - name: install packages 40 | run: | 41 | sudo apt-get update && sudo apt-get install -y ninja-build 42 | 43 | - name: Install clang-tools 44 | run: | 45 | wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - 46 | sudo add-apt-repository "deb http://apt.llvm.org/noble/ llvm-toolchain-noble-18 main" 47 | sudo apt-get update && sudo apt-get install -y clang-tools-18 48 | 49 | - name: make info 50 | run: | 51 | echo "OS: ${{ matrix.os }}" 52 | clang - --version 53 | 54 | - name: cmake 55 | run: | 56 | cmake -B build -DHAVE_THREADS= && cmake --build build -j -t retest 57 | 58 | - name: retest 59 | run: | 60 | ./build/test/retest -av 61 | -------------------------------------------------------------------------------- /.github/workflows/sonar.yml: -------------------------------------------------------------------------------- 1 | name: Sonarcloud 2 | on: 3 | push: 4 | branches: 5 | - main 6 | workflow_dispatch: 7 | 8 | jobs: 9 | build: 10 | name: Build 11 | runs-on: ubuntu-latest 12 | env: 13 | SONAR_SCANNER_VERSION: 5.0.1.3006 14 | SONAR_SERVER_URL: "https://sonarcloud.io" 15 | BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed 16 | steps: 17 | - uses: actions/checkout@v4 18 | with: 19 | fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis 20 | - name: Set up JDK 17 21 | uses: actions/setup-java@v3 22 | with: 23 | java-version: 17 24 | distribution: 'oracle' 25 | - name: Download and set up sonar-scanner 26 | env: 27 | SONAR_SCANNER_DOWNLOAD_URL: https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-${{ env.SONAR_SCANNER_VERSION }}-linux.zip 28 | run: | 29 | mkdir -p $HOME/.sonar 30 | curl -sSLo $HOME/.sonar/sonar-scanner.zip ${{ env.SONAR_SCANNER_DOWNLOAD_URL }} 31 | unzip -o $HOME/.sonar/sonar-scanner.zip -d $HOME/.sonar/ 32 | echo "$HOME/.sonar/sonar-scanner-${{ env.SONAR_SCANNER_VERSION }}-linux/bin" >> $GITHUB_PATH 33 | - name: Download and set up build-wrapper 34 | env: 35 | BUILD_WRAPPER_DOWNLOAD_URL: ${{ env.SONAR_SERVER_URL }}/static/cpp/build-wrapper-linux-x86.zip 36 | run: | 37 | curl -sSLo $HOME/.sonar/build-wrapper-linux-x86.zip ${{ env.BUILD_WRAPPER_DOWNLOAD_URL }} 38 | unzip -o $HOME/.sonar/build-wrapper-linux-x86.zip -d $HOME/.sonar/ 39 | echo "$HOME/.sonar/build-wrapper-linux-x86" >> $GITHUB_PATH 40 | - name: Run build-wrapper 41 | run: | 42 | cmake -S . -B build 43 | build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build/ 44 | - name: Run sonar-scanner 45 | env: 46 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 47 | SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} 48 | run: | 49 | sonar-scanner --define sonar.host.url="${{ env.SONAR_SERVER_URL }}" --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}" 50 | 51 | -------------------------------------------------------------------------------- /.github/workflows/ssl.yml: -------------------------------------------------------------------------------- 1 | name: OpenSSL no-deprecated and LibreSSL 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | 11 | jobs: 12 | ssl: 13 | runs-on: ubuntu-latest 14 | 15 | strategy: 16 | matrix: 17 | ssl: [libressl, openssl] 18 | 19 | env: 20 | CMAKE_GENERATOR: Ninja 21 | OPENSSL_ROOT_DIR: "assets/${{ matrix.ssl }}" 22 | 23 | steps: 24 | - uses: actions/checkout@v4 25 | 26 | - name: fix flaky azure mirrors 27 | if: ${{ runner.os == 'Linux' }} 28 | run: | 29 | sudo sed -i 's/azure\./de\./' /etc/apt/sources.list 30 | 31 | - name: install packages 32 | run: | 33 | sudo apt-get update && sudo apt-get install -y ninja-build 34 | 35 | - name: Download pre-compiled OpenSSL/LibreSSL 36 | run: | 37 | wget "https://github.com/baresip/tools/releases/download/v2023.11.0/assets.tar.gz" 38 | tar -xf assets.tar.gz 39 | - name: make 40 | run: cmake -B build -DCMAKE_C_FLAGS="-Werror" && cmake --build build -j 41 | -------------------------------------------------------------------------------- /.github/workflows/strict-c.yml: -------------------------------------------------------------------------------- 1 | name: Strict C checks 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | 11 | jobs: 12 | strict-c: 13 | runs-on: ubuntu-latest 14 | 15 | env: 16 | CMAKE_GENERATOR: Ninja 17 | 18 | steps: 19 | - uses: actions/checkout@v4 20 | 21 | - name: fix flaky azure mirrors 22 | if: ${{ runner.os == 'Linux' }} 23 | run: | 24 | sudo sed -i 's/azure\./de\./' /etc/apt/sources.list 25 | 26 | - name: install packages 27 | run: | 28 | sudo apt-get update && sudo apt-get install -y ninja-build 29 | 30 | - name: make strict C99 31 | run: | 32 | cmake -DCMAKE_C_STANDARD=99 -DCMAKE_C_EXTENSIONS=OFF -DCMAKE_C_FLAGS="-Werror" -B build 33 | cmake --build build 34 | rm -Rf build 35 | 36 | - name: make strict C11 37 | run: | 38 | cmake -DCMAKE_C_STANDARD=11 -DCMAKE_C_EXTENSIONS=OFF -DCMAKE_C_FLAGS="-Werror" -B build 39 | cmake --build build 40 | rm -Rf build 41 | -------------------------------------------------------------------------------- /.github/workflows/valgrind.yml: -------------------------------------------------------------------------------- 1 | name: valgrind leak check 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | 11 | jobs: 12 | valgrind: 13 | runs-on: ubuntu-latest 14 | 15 | env: 16 | CMAKE_GENERATOR: Ninja 17 | 18 | steps: 19 | - uses: actions/checkout@v4 20 | 21 | - name: fix flaky azure mirrors 22 | if: ${{ runner.os == 'Linux' }} 23 | run: | 24 | sudo sed -i 's/azure\./de\./' /etc/apt/sources.list 25 | 26 | - name: install packages 27 | run: | 28 | sudo apt-get update && sudo apt-get install -y libssl-dev valgrind ninja-build 29 | 30 | - name: make 31 | run: | 32 | cmake -B build && cmake --build build -j -t retest 33 | 34 | - name: retest 35 | run: | 36 | valgrind --leak-check=full --show-reachable=yes --error-exitcode=42 ./build/test/retest -r -v 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /build* 2 | /dist 3 | test.d 4 | test.o 5 | *stamp 6 | *.previous 7 | libre.a 8 | libre.*dylib 9 | libre.pc 10 | libre.so* 11 | *.gcov 12 | 13 | # Windows build folder 14 | Win32/* 15 | 16 | # Visual studio config 17 | mk/win32/baresip.vcxproj.user 18 | 19 | # ctags 20 | tags 21 | 22 | # Vim swp files 23 | *.swp 24 | 25 | # clangd 26 | .cache 27 | compile_commands.json 28 | 29 | # Visual studio config 30 | mk/win32/*.vcxproj.user 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2020 - 2025, Baresip Foundation (https://github.com/baresip) 2 | Copyright (c) 2010 - 2024, Alfred E. Heggestad 3 | Copyright (c) 2010 - 2020, Richard Aas 4 | Copyright (c) 2010 - 2020, Creytiv.com 5 | All rights reserved. 6 | 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions 10 | are met: 11 | 12 | 1. Redistributions of source code must retain the above copyright 13 | notice, this list of conditions and the following disclaimer. 14 | 15 | 2. Redistributions in binary form must reproduce the above copyright 16 | notice, this list of conditions and the following disclaimer in the 17 | documentation and/or other materials provided with the distribution. 18 | 19 | 3. Neither the name of the copyright holder nor the names of its contributors 20 | may be used to endorse or promote products derived from this software 21 | without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 27 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 29 | GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 32 | OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: build 2 | build: 3 | [ -d build ] || cmake -B build 4 | cmake --build build --parallel 5 | 6 | .PHONY: ninja 7 | ninja: 8 | [ -d build ] || cmake -B build -G Ninja 9 | make build 10 | 11 | .PHONY: release 12 | release: 13 | [ -d build ] || cmake -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo 14 | cmake --build build --parallel 15 | 16 | .PHONY: dist 17 | dist: build 18 | cmake --install build --prefix dist 19 | 20 | .PHONY: deb 21 | deb: release 22 | cd build && cpack -G DEB 23 | 24 | .PHONY: test 25 | test: build 26 | cmake --build build --parallel -t retest 27 | build/test/retest -rv 28 | 29 | .PHONY: clean 30 | clean: 31 | @rm -Rf build dist CMakeCache.txt CMakeFiles 32 | 33 | 34 | ############################################################################### 35 | # 36 | # Documentation section 37 | # 38 | DOX_DIR=../re-dox 39 | 40 | $(DOX_DIR): 41 | @mkdir $@ 42 | 43 | $(DOX_DIR)/Doxyfile: mk/Doxyfile Makefile 44 | @cp $< $@ 45 | @perl -pi -e 's/PROJECT_NUMBER\s*=.*/PROJECT_NUMBER = $(VERSION)/' \ 46 | $(DOX_DIR)/Doxyfile 47 | 48 | .PHONY: 49 | dox: $(DOX_DIR) $(DOX_DIR)/Doxyfile 50 | @doxygen $(DOX_DIR)/Doxyfile 2>&1 | grep -v DEBUG_ ; true 51 | echo "Doxygen docs in $(DOX_DIR)" 52 | -------------------------------------------------------------------------------- /cmake/FindMBEDTLS.cmake: -------------------------------------------------------------------------------- 1 | find_path(MBEDTLS_INCLUDE_DIR 2 | NAMES mbedtls/ssl.h mbedtls/md.h mbedtls/md5.h mbedtls/error.h 3 | mbedtls/sha1.h mbedtls/sha256.h 4 | HINTS 5 | "${MBEDTLS_INCLUDE_DIRS}" 6 | "${MBEDTLS_HINTS}/include" 7 | PATHS /usr/local/include /usr/include 8 | ) 9 | 10 | find_library(MBEDTLS_LIBRARY 11 | NAMES mbedtls mbedx509 mbedcrypto 12 | HINTS 13 | "${MBEDTLS_LIBRARY_DIRS}" 14 | "${MBEDTLS_HINTS}/lib" 15 | PATHS /usr/local/lib /usr/lib 16 | ) 17 | 18 | include(FindPackageHandleStandardArgs) 19 | find_package_handle_standard_args(MBEDTLS DEFAULT_MSG 20 | MBEDTLS_INCLUDE_DIR MBEDTLS_LIBRARY) 21 | 22 | if(MBEDTLS_FOUND) 23 | set( MBEDTLS_INCLUDE_DIRS ${MBEDTLS_INCLUDE_DIR} ) 24 | set( MBEDTLS_LIBRARIES ${MBEDTLS_LIBRARY} ) 25 | else() 26 | set( MBEDTLS_INCLUDE_DIRS ) 27 | set( MBEDTLS_LIBRARIES ) 28 | endif() 29 | 30 | mark_as_advanced(MBEDTLS_INCLUDE_DIRS MBEDTLS_LIBRARIES) 31 | -------------------------------------------------------------------------------- /cmake/libre-config.cmake: -------------------------------------------------------------------------------- 1 | if("@LIBRE_BUILD_STATIC@") 2 | include(CMakeFindDependencyMacro) 3 | find_dependency(Threads) 4 | if("@USE_OPENSSL@") 5 | find_dependency(OpenSSL) 6 | endif() 7 | if("@ZLIB_FOUND@") 8 | find_dependency(ZLIB) 9 | endif() 10 | endif() 11 | 12 | include("${CMAKE_CURRENT_LIST_DIR}/libre-targets.cmake") 13 | 14 | # convenience target libre::libre for uniform usage 15 | if(NOT TARGET libre::libre) 16 | if(TARGET libre::re_shared AND (BUILD_SHARED_LIBS OR NOT TARGET libre::re)) 17 | add_library(libre::libre INTERFACE IMPORTED) 18 | set_target_properties(libre::libre PROPERTIES INTERFACE_LINK_LIBRARIES libre::re_shared) 19 | elseif(TARGET libre::re AND (NOT BUILD_SHARED_LIBS OR NOT TARGET libre::re_shared)) 20 | add_library(libre::libre INTERFACE IMPORTED) 21 | set_target_properties(libre::libre PROPERTIES INTERFACE_LINK_LIBRARIES libre::re) 22 | endif() 23 | endif() 24 | -------------------------------------------------------------------------------- /cmake/sanitizer.cmake: -------------------------------------------------------------------------------- 1 | if(USE_SANITIZER STREQUAL "address") 2 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address") 3 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") 4 | elseif(USE_SANITIZER STREQUAL "thread") 5 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=thread") 6 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread") 7 | elseif(USE_SANITIZER STREQUAL "undefined") 8 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined") 9 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined") 10 | elseif(USE_SANITIZER STREQUAL "memory") 11 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=memory") 12 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=memory") 13 | endif() 14 | -------------------------------------------------------------------------------- /docs/TODO: -------------------------------------------------------------------------------- 1 | TODO 2 | 3 | ------------------------------------------------------------------------------- 4 | Version v0.x.y 5 | 6 | tmr: scaling using binary heap or hash 7 | 8 | ------------------------------------------------------------------------------- 9 | -------------------------------------------------------------------------------- /docs/main.dox: -------------------------------------------------------------------------------- 1 | /** 2 | * \mainpage libre Development Documentation 3 | * 4 | * Development documentation for libre 5 | * 6 | * 7 | * \include README.md 8 | * 9 | * 10 | * \section modules modules 11 | */ 12 | -------------------------------------------------------------------------------- /include/re.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file re.h Wrapper for all header files 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | #ifndef RE_H__ 8 | #define RE_H__ 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | /* Basic types */ 15 | #include "re_types.h" 16 | #include "re_fmt.h" 17 | #include "re_mbuf.h" 18 | #include "re_msg.h" 19 | #include "re_list.h" 20 | #include "re_sa.h" 21 | 22 | /* Library modules */ 23 | #include "re_aes.h" 24 | #include "re_async.h" 25 | #include "re_base64.h" 26 | #include "re_bfcp.h" 27 | #include "re_btrace.h" 28 | #include "re_conf.h" 29 | #include "re_convert.h" 30 | #include "re_crc32.h" 31 | #include "re_dns.h" 32 | #include "re_h264.h" 33 | #include "re_hash.h" 34 | #include "re_hmac.h" 35 | #include "re_http.h" 36 | #include "re_httpauth.h" 37 | #include "re_ice.h" 38 | #include "re_net.h" 39 | #include "re_main.h" 40 | #include "re_md5.h" 41 | #include "re_mem.h" 42 | #include "re_mod.h" 43 | #include "re_mqueue.h" 44 | #include "re_odict.h" 45 | #include "re_json.h" 46 | #include "re_rtmp.h" 47 | #include "re_rtp.h" 48 | #include "re_rtpext.h" 49 | #include "re_sdp.h" 50 | #include "re_uri.h" 51 | #include "re_sip.h" 52 | #include "re_sipevent.h" 53 | #include "re_sipreg.h" 54 | #include "re_sipsess.h" 55 | #include "re_stun.h" 56 | #include "re_srtp.h" 57 | #include "re_sys.h" 58 | #include "re_tcp.h" 59 | #include "re_telev.h" 60 | #include "re_thread.h" 61 | #include "re_tmr.h" 62 | #include "re_trace.h" 63 | #include "re_tls.h" 64 | #include "re_turn.h" 65 | #include "re_udp.h" 66 | #include "re_unixsock.h" 67 | #include "re_websock.h" 68 | #include "re_shim.h" 69 | #include "re_trice.h" 70 | #include "re_pcp.h" 71 | 72 | #ifdef __cplusplus 73 | } 74 | #endif 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /include/re_aes.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file re_aes.h Interface to AES (Advanced Encryption Standard) 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | 8 | #ifndef AES_BLOCK_SIZE 9 | #define AES_BLOCK_SIZE 16 10 | #endif 11 | 12 | /** AES mode */ 13 | enum aes_mode { 14 | AES_MODE_CTR, /**< AES Counter mode (CTR) */ 15 | AES_MODE_GCM, /**< AES Galois Counter Mode (GCM) */ 16 | }; 17 | 18 | struct aes; 19 | 20 | int aes_alloc(struct aes **stp, enum aes_mode mode, 21 | const uint8_t *key, size_t key_bits, 22 | const uint8_t *iv); 23 | void aes_set_iv(struct aes *aes, const uint8_t *iv); 24 | int aes_encr(struct aes *aes, uint8_t *out, const uint8_t *in, size_t len); 25 | int aes_decr(struct aes *aes, uint8_t *out, const uint8_t *in, size_t len); 26 | int aes_get_authtag(struct aes *aes, uint8_t *tag, size_t taglen); 27 | int aes_authenticate(struct aes *aes, const uint8_t *tag, size_t taglen); 28 | -------------------------------------------------------------------------------- /include/re_async.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file re_async.h async 3 | * 4 | * Copyright (C) 2022 Sebastian Reimers 5 | */ 6 | 7 | #ifndef RE_H_ASYNC__ 8 | #define RE_H_ASYNC__ 9 | struct re_async; 10 | 11 | typedef int(re_async_work_h)(void *arg); 12 | typedef void(re_async_h)(int err, void *arg); 13 | 14 | int re_async_alloc(struct re_async **asyncp, uint16_t workers); 15 | int re_async(struct re_async *a, intptr_t id, re_async_work_h *workh, 16 | re_async_h *cb, void *arg); 17 | void re_async_cancel(struct re_async *async, intptr_t id); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /include/re_base64.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file re_base64.h Interface to Base64 encoding/decoding functions 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | 8 | int base64_encode(const uint8_t *in, size_t ilen, char *out, size_t *olen); 9 | int base64url_encode(const uint8_t *in, size_t ilen, char *out, size_t *olen); 10 | int base64_print(struct re_printf *pf, const uint8_t *ptr, size_t len); 11 | int base64_decode(const char *in, size_t ilen, uint8_t *out, size_t *olen); 12 | -------------------------------------------------------------------------------- /include/re_btrace.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file re_btrace.h Backtrace API 3 | * 4 | */ 5 | #define BTRACE_SZ 16 6 | 7 | struct btrace { 8 | void *stack[BTRACE_SZ]; 9 | size_t len; 10 | }; 11 | 12 | int btrace_print(struct re_printf *pf, struct btrace *bt); 13 | int btrace_println(struct re_printf *pf, struct btrace *bt); 14 | int btrace_print_json(struct re_printf *pf, struct btrace *bt); 15 | 16 | #if defined(HAVE_EXECINFO) && !defined(RELEASE) 17 | #include 18 | static inline int btrace(struct btrace *bt) 19 | { 20 | if (!bt) 21 | return EINVAL; 22 | 23 | bt->len = backtrace(bt->stack, BTRACE_SZ); 24 | 25 | return 0; 26 | } 27 | #elif defined(WIN32) 28 | #ifndef WIN32_LEAN_AND_MEAN 29 | #define WIN32_LEAN_AND_MEAN 30 | #endif 31 | #include 32 | static inline int btrace(struct btrace *bt) 33 | { 34 | if (!bt) 35 | return EINVAL; 36 | 37 | bt->len = CaptureStackBackTrace(0, BTRACE_SZ, bt->stack, NULL); 38 | 39 | return 0; 40 | } 41 | #else 42 | static inline int btrace(struct btrace *bt) 43 | { 44 | (void)bt; 45 | return 0; 46 | } 47 | #endif 48 | -------------------------------------------------------------------------------- /include/re_conf.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file re_conf.h Interface to configuration 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | 8 | struct conf; 9 | 10 | typedef int (conf_h)(const struct pl *val, void *arg); 11 | 12 | int conf_alloc(struct conf **confp, const char *filename); 13 | int conf_alloc_buf(struct conf **confp, const uint8_t *buf, size_t sz); 14 | int conf_get(const struct conf *conf, const char *name, struct pl *pl); 15 | int conf_get_str(const struct conf *conf, const char *name, char *str, 16 | size_t size); 17 | int conf_get_u32(const struct conf *conf, const char *name, uint32_t *num); 18 | int conf_get_i32(const struct conf *conf, const char *name, int32_t *num); 19 | int conf_get_float(const struct conf *conf, const char *name, double *num); 20 | int conf_get_bool(const struct conf *conf, const char *name, bool *val); 21 | int conf_apply(const struct conf *conf, const char *name, 22 | conf_h *ch, void *arg); 23 | -------------------------------------------------------------------------------- /include/re_convert.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file re_convert.h Conversion helpers 3 | * 4 | * Copyright (C) 2022 Sebastian Reimers 5 | */ 6 | #include 7 | 8 | static inline int try_into_u16_from_size(uint16_t *dest, const size_t src) 9 | { 10 | *dest = 0; 11 | 12 | if (src > UINT16_MAX) 13 | return ERANGE; 14 | 15 | *dest = (uint16_t)src; 16 | 17 | return 0; 18 | } 19 | 20 | 21 | static inline int try_into_u16_from_int(uint16_t *dest, const int src) 22 | { 23 | *dest = 0; 24 | 25 | if (src > UINT16_MAX) 26 | return ERANGE; 27 | 28 | if (src < 0) 29 | return ERANGE; 30 | 31 | *dest = (uint16_t)src; 32 | 33 | return 0; 34 | } 35 | 36 | 37 | static inline int try_into_int_from_size(int *dest, const size_t src) 38 | { 39 | *dest = 0; 40 | 41 | if (src > INT_MAX) 42 | return ERANGE; 43 | 44 | *dest = (int)src; 45 | 46 | return 0; 47 | } 48 | 49 | 50 | static inline int try_into_err(void *dest, ...) 51 | { 52 | (void)dest; 53 | 54 | return ENOTSUP; 55 | } 56 | 57 | 58 | #if __STDC_VERSION__ >= 201112L /* Needs C11 support */ 59 | /** 60 | * Try to convert safely from one type (src) into another (dest). 61 | * Types are auto detected. 62 | * 63 | * @param dest Destination 64 | * @param src Source value 65 | * 66 | * @return 0 if success, ERANGE if value overflow and ENOTSUP if not supported 67 | */ 68 | #define try_into(dest, src) \ 69 | _Generic((dest), \ 70 | uint16_t: _Generic((src), \ 71 | size_t: try_into_u16_from_size, \ 72 | int: try_into_u16_from_int, \ 73 | default: try_into_err \ 74 | ), \ 75 | int: _Generic((src), \ 76 | size_t: try_into_int_from_size, \ 77 | default: try_into_err \ 78 | ) \ 79 | ) \ 80 | (&(dest), (src)) 81 | #endif 82 | -------------------------------------------------------------------------------- /include/re_crc32.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file re_crc32.h Interface to CRC-32 functions 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | 8 | uint32_t re_crc32(uint32_t crc, const void *buf, uint32_t size); 9 | -------------------------------------------------------------------------------- /include/re_hash.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file re_hash.h Interface to hashmap table 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | 8 | struct hash; 9 | struct pl; 10 | 11 | 12 | int hash_alloc(struct hash **hp, uint32_t bsize); 13 | void hash_append(struct hash *h, uint32_t key, struct le *le, void *data); 14 | void hash_unlink(struct le *le); 15 | struct le *hash_lookup(const struct hash *h, uint32_t key, list_apply_h *ah, 16 | void *arg); 17 | struct le *hash_apply(const struct hash *h, list_apply_h *ah, void *arg); 18 | struct list *hash_list_idx(const struct hash *h, uint32_t i); 19 | struct list *hash_list(const struct hash *h, uint32_t key); 20 | uint32_t hash_bsize(const struct hash *h); 21 | void hash_flush(struct hash *h); 22 | void hash_clear(struct hash *h); 23 | uint32_t hash_valid_size(uint32_t size); 24 | int hash_debug(struct re_printf *pf, struct hash *h); 25 | 26 | 27 | /* Hash functions */ 28 | uint32_t hash_joaat(const uint8_t *key, size_t len); 29 | uint32_t hash_joaat_ci(const char *str, size_t len); 30 | uint32_t hash_joaat_str(const char *str); 31 | uint32_t hash_joaat_str_ci(const char *str); 32 | uint32_t hash_joaat_pl(const struct pl *pl); 33 | uint32_t hash_joaat_pl_ci(const struct pl *pl); 34 | uint32_t hash_fast(const char *k, size_t len); 35 | uint32_t hash_fast_str(const char *str); 36 | -------------------------------------------------------------------------------- /include/re_hmac.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file re_hmac.h Interface to HMAC functions 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | 8 | void hmac_sha1(const uint8_t *k, /* secret key */ 9 | size_t lk, /* length of the key in bytes */ 10 | const uint8_t *d, /* data */ 11 | size_t ld, /* length of data in bytes */ 12 | uint8_t* out, /* output buffer, at least "t" bytes */ 13 | size_t t); 14 | 15 | void hmac_sha256(const uint8_t *key, 16 | size_t key_len, 17 | const uint8_t *data, 18 | size_t data_len, 19 | uint8_t *out, 20 | size_t out_len); 21 | 22 | 23 | enum hmac_hash { 24 | HMAC_HASH_SHA1, 25 | HMAC_HASH_SHA256 26 | }; 27 | 28 | struct hmac; 29 | 30 | int hmac_create(struct hmac **hmacp, enum hmac_hash hash, 31 | const uint8_t *key, size_t key_len); 32 | int hmac_digest(struct hmac *hmac, uint8_t *md, size_t md_len, 33 | const uint8_t *data, size_t data_len); 34 | -------------------------------------------------------------------------------- /include/re_json.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file re_json.h Interface to JavaScript Object Notation (JSON) -- RFC 7159 3 | * 4 | * Copyright (C) 2010 - 2015 Creytiv.com 5 | */ 6 | 7 | enum json_typ { 8 | JSON_STRING, 9 | JSON_INT, 10 | JSON_DOUBLE, 11 | JSON_BOOL, 12 | JSON_NULL, 13 | }; 14 | 15 | struct json_value { 16 | union { 17 | char *str; 18 | int64_t integer; 19 | double dbl; 20 | bool boolean; 21 | } v; 22 | enum json_typ type; 23 | }; 24 | 25 | struct json_handlers; 26 | 27 | typedef int (json_object_entry_h)(const char *name, 28 | const struct json_value *value, void *arg); 29 | typedef int (json_array_entry_h)(unsigned idx, 30 | const struct json_value *value, void *arg); 31 | typedef int (json_object_h)(const char *name, unsigned idx, 32 | struct json_handlers *h); 33 | typedef int (json_array_h)(const char *name, unsigned idx, 34 | struct json_handlers *h); 35 | 36 | struct json_handlers { 37 | json_object_h *oh; 38 | json_array_h *ah; 39 | json_object_entry_h *oeh; 40 | json_array_entry_h *aeh; 41 | void *arg; 42 | }; 43 | 44 | int json_decode(const char *str, size_t len, unsigned maxdepth, 45 | json_object_h *oh, json_array_h *ah, 46 | json_object_entry_h *oeh, json_array_entry_h *aeh, void *arg); 47 | 48 | int json_decode_odict(struct odict **op, uint32_t hash_size, const char *str, 49 | size_t len, unsigned maxdepth); 50 | int json_encode_odict(struct re_printf *pf, const struct odict *o); 51 | -------------------------------------------------------------------------------- /include/re_md5.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file re_md5.h Interface to MD5 functions 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | 8 | /** MD5 values */ 9 | enum { 10 | MD5_SIZE = 16, /**< Number of bytes in MD5 hash */ 11 | MD5_STR_SIZE = 2*MD5_SIZE + 1 /**< Number of bytes in MD5 string */ 12 | }; 13 | 14 | void md5(const uint8_t *d, size_t n, uint8_t *md); 15 | int md5_printf(uint8_t *md, const char *fmt, ...); 16 | -------------------------------------------------------------------------------- /include/re_mem.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file re_mem.h Interface to Memory management with reference counting 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | 8 | /** 9 | * Defines the memory destructor handler, which is called when the reference 10 | * of a memory object goes down to zero 11 | * 12 | * @param data Pointer to memory object 13 | */ 14 | typedef void (mem_destroy_h)(void *data); 15 | 16 | /** Memory Statistics */ 17 | struct memstat { 18 | size_t bytes_cur; /**< Current bytes allocated */ 19 | size_t blocks_cur; /**< Current blocks allocated */ 20 | }; 21 | 22 | void *mem_alloc(size_t size, mem_destroy_h *dh); 23 | void *mem_zalloc(size_t size, mem_destroy_h *dh); 24 | void *mem_realloc(void *data, size_t size); 25 | void *mem_reallocarray(void *ptr, size_t nmemb, 26 | size_t membsize, mem_destroy_h *dh); 27 | void mem_destructor(void *data, mem_destroy_h *dh); 28 | void *mem_ref(void *data); 29 | void *mem_deref(void *data); 30 | uint32_t mem_nrefs(const void *data); 31 | 32 | void mem_debug(void); 33 | void mem_threshold_set(ssize_t n); 34 | struct re_printf; 35 | int mem_status(struct re_printf *pf, void *unused); 36 | int mem_get_stat(struct memstat *mstat); 37 | 38 | 39 | /* Secure memory functions */ 40 | int mem_seccmp(const uint8_t *s1, const uint8_t *s2, size_t n); 41 | void mem_secclean(void *data, size_t size); 42 | 43 | 44 | /* Mem Pool */ 45 | struct mem_pool; 46 | struct mem_pool_entry; 47 | int mem_pool_alloc(struct mem_pool **poolp, size_t nmemb, size_t membsize, 48 | mem_destroy_h *dh); 49 | int mem_pool_extend(struct mem_pool *pool, size_t num); 50 | struct mem_pool_entry *mem_pool_borrow(struct mem_pool *pool); 51 | struct mem_pool_entry *mem_pool_borrow_extend(struct mem_pool *pool); 52 | void *mem_pool_release(struct mem_pool *pool, struct mem_pool_entry *e); 53 | void *mem_pool_member(const struct mem_pool_entry *entry); 54 | void mem_pool_flush(struct mem_pool *pool); 55 | -------------------------------------------------------------------------------- /include/re_mod.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file re_mod.h Interface to loadable modules 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | 8 | /** 9 | * @def MOD_PRE 10 | * 11 | * Module Prefix 12 | * 13 | * @def MOD_EXT 14 | * 15 | * Module Extension 16 | */ 17 | #if defined (WIN32) 18 | #define MOD_PRE "" 19 | #define MOD_EXT ".dll" 20 | #else 21 | #define MOD_PRE "" 22 | #define MOD_EXT ".so" 23 | #endif 24 | 25 | 26 | /** Symbol to enable exporting of functions from a module */ 27 | #ifdef WIN32 28 | #define EXPORT_SYM __declspec(dllexport) 29 | #else 30 | #define EXPORT_SYM 31 | #endif 32 | 33 | 34 | /* ----- Module API ----- */ 35 | 36 | 37 | /** 38 | * Defines the module initialisation handler 39 | * 40 | * @return 0 for success, otherwise errorcode 41 | */ 42 | typedef int (mod_init_h)(void); 43 | 44 | /** 45 | * Defines the module close handler 46 | * 47 | * @return 0 for success, otherwise errorcode 48 | */ 49 | typedef int (mod_close_h)(void); 50 | 51 | 52 | struct mod; 53 | struct re_printf; 54 | 55 | 56 | /** Defines the module export */ 57 | struct mod_export { 58 | const char *name; /**< Module name */ 59 | const char *type; /**< Module type */ 60 | mod_init_h *init; /**< Module init handler */ 61 | mod_close_h *close; /**< Module close handler */ 62 | }; 63 | 64 | 65 | /* ----- Application API ----- */ 66 | 67 | void mod_init(void); 68 | void mod_close(void); 69 | 70 | int mod_load(struct mod **mp, const char *name); 71 | int mod_add(struct mod **mp, const struct mod_export *me); 72 | struct mod *mod_find(const char *name); 73 | const struct mod_export *mod_export(const struct mod *m); 74 | struct list *mod_list(void); 75 | int mod_debug(struct re_printf *pf, void *unused); 76 | -------------------------------------------------------------------------------- /include/re_mqueue.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file re_mqueue.h Thread Safe Message Queue 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | struct mqueue; 8 | 9 | typedef void (mqueue_h)(int id, void *data, void *arg); 10 | 11 | int mqueue_alloc(struct mqueue **mqp, mqueue_h *h, void *arg); 12 | int mqueue_push(struct mqueue *mq, int id, void *data); 13 | -------------------------------------------------------------------------------- /include/re_msg.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file re_msg.h Interface to generic message components 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | 8 | /** Content-Type */ 9 | struct msg_ctype { 10 | struct pl type; 11 | struct pl subtype; 12 | struct pl params; 13 | }; 14 | 15 | 16 | int msg_ctype_decode(struct msg_ctype *ctype, const struct pl *pl); 17 | bool msg_ctype_cmp(const struct msg_ctype *ctype, 18 | const char *type, const char *subtype); 19 | 20 | int msg_param_decode(const struct pl *pl, const char *name, struct pl *val); 21 | int msg_param_exists(const struct pl *pl, const char *name, struct pl *end); 22 | -------------------------------------------------------------------------------- /include/re_rtpext.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file re_rtpext.h Interface to RTP Header Extensions 3 | * 4 | * Copyright (C) 2010 - 2022 Alfred E. Heggestad 5 | */ 6 | 7 | 8 | /* 9 | * RTP Header Extensions 10 | */ 11 | 12 | #define RTPEXT_HDR_SIZE 4 13 | #define RTPEXT_TYPE_MAGIC 0xbede /* One-Byte header */ 14 | #define RTPEXT_TYPE_MAGIC_LONG 0x1000 /* Two-Byte header */ 15 | 16 | enum { 17 | RTPEXT_ID_MIN = 1, 18 | RTPEXT_ID_MAX = 14, 19 | }; 20 | 21 | enum { 22 | RTPEXT_LEN_MIN = 1, 23 | RTPEXT_LEN_MAX = 16, 24 | RTPEXT_LEN_MAX_LONG = 256, 25 | }; 26 | 27 | 28 | /** Defines an RTP header extension */ 29 | struct rtpext { 30 | uint8_t id; /**< Identifier */ 31 | uint8_t len; /**< Length of data [bytes] */ 32 | uint8_t data[RTPEXT_LEN_MAX_LONG]; /**< Data field */ 33 | }; 34 | 35 | 36 | int rtpext_hdr_encode(struct mbuf *mb, size_t num_bytes); 37 | int rtpext_hdr_encode_long(struct mbuf *mb, size_t num_bytes); 38 | int rtpext_encode(struct mbuf *mb, uint8_t id, size_t len, 39 | const uint8_t *data); 40 | int rtpext_encode_long(struct mbuf *mb, uint8_t id, uint8_t len, 41 | const uint8_t *data); 42 | int rtpext_decode(struct rtpext *ext, struct mbuf *mb); 43 | int rtpext_decode_long(struct rtpext *ext, struct mbuf *mb); 44 | const struct rtpext *rtpext_find(const struct rtpext *extv, size_t extc, 45 | uint8_t id); 46 | -------------------------------------------------------------------------------- /include/re_sha.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file re_sha.h Interface to SHA (Secure Hash Standard) functions 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | /** SHA-1 Digest size in bytes */ 8 | #define SHA1_DIGEST_SIZE 20 9 | #define SHA256_DIGEST_SIZE 32 10 | #define SHA512_DIGEST_SIZE 64 11 | 12 | #ifndef SHA_DIGEST_LENGTH 13 | /** SHA-1 Digest size in bytes (OpenSSL compat) */ 14 | #define SHA_DIGEST_LENGTH SHA1_DIGEST_SIZE 15 | #endif 16 | 17 | #ifndef SHA256_DIGEST_LENGTH 18 | /** SHA-256 Digest size in bytes (OpenSSL compat) */ 19 | #define SHA256_DIGEST_LENGTH SHA256_DIGEST_SIZE 20 | #endif 21 | 22 | #ifndef SHA512_DIGEST_LENGTH 23 | /** SHA-512 Digest size in bytes (OpenSSL compat) */ 24 | #define SHA512_DIGEST_LENGTH SHA512_DIGEST_SIZE 25 | #endif 26 | 27 | void sha1(const uint8_t *d, size_t n, uint8_t *md); 28 | void sha256(const uint8_t *d, size_t n, uint8_t *md); 29 | int sha256_printf(uint8_t md[32], const char *fmt, ...); 30 | -------------------------------------------------------------------------------- /include/re_shim.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file re_shim.h Interface to SHIM layer 3 | * 4 | * Copyright (C) 2015 - 2022 Alfred E. Heggestad 5 | */ 6 | 7 | 8 | /* RFC 4571 */ 9 | 10 | 11 | enum { SHIM_HDR_SIZE = 2 }; 12 | 13 | struct shim; 14 | 15 | typedef bool (shim_frame_h)(struct mbuf *mb, void *arg); 16 | 17 | 18 | int shim_insert(struct shim **shimp, struct tcp_conn *tc, int layer, 19 | shim_frame_h *frameh, void *arg); 20 | int shim_debug(struct re_printf *pf, const struct shim *shim); 21 | -------------------------------------------------------------------------------- /include/re_sipreg.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file re_sipreg.h SIP Registration 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | struct sipreg; 8 | 9 | 10 | int sipreg_register(struct sipreg **regp, struct sip *sip, const char *reg_uri, 11 | const char *to_uri, const char *from_name, 12 | const char *from_uri, uint32_t expires, 13 | const char *cuser, const char *routev[], uint32_t routec, 14 | int regid, sip_auth_h *authh, void *aarg, bool aref, 15 | sip_resp_h *resph, void *arg, 16 | const char *params, const char *fmt, ...); 17 | void sipreg_unregister(struct sipreg *reg); 18 | int sipreg_alloc(struct sipreg **regp, struct sip *sip, const char *reg_uri, 19 | const char *to_uri, const char *from_name, 20 | const char *from_uri, uint32_t expires, 21 | const char *cuser, const char *routev[], uint32_t routec, 22 | int regid, sip_auth_h *authh, void *aarg, bool aref, 23 | sip_resp_h *resph, void *arg, 24 | const char *params, const char *fmt, ...); 25 | int sipreg_send(struct sipreg *reg); 26 | 27 | int sipreg_set_rwait(struct sipreg *reg, uint32_t rwait); 28 | 29 | const struct sa *sipreg_laddr(const struct sipreg *reg); 30 | 31 | uint32_t sipreg_proxy_expires(const struct sipreg *reg); 32 | bool sipreg_registered(const struct sipreg *reg); 33 | bool sipreg_failed(const struct sipreg *reg); 34 | void sipreg_incfailc(struct sipreg *reg); 35 | 36 | int sipreg_set_fbregint(struct sipreg *reg, uint32_t fbregint); 37 | void sipreg_set_srcport(struct sipreg *reg, uint16_t srcport); 38 | int sipreg_set_contact_params(struct sipreg *reg, const char *cparams); 39 | -------------------------------------------------------------------------------- /include/re_srtp.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file re_srtp.h Secure Real-time Transport Protocol (SRTP) 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | 8 | enum srtp_suite { 9 | SRTP_AES_CM_128_HMAC_SHA1_32, 10 | SRTP_AES_CM_128_HMAC_SHA1_80, 11 | SRTP_AES_256_CM_HMAC_SHA1_32, 12 | SRTP_AES_256_CM_HMAC_SHA1_80, 13 | SRTP_AES_128_GCM, 14 | SRTP_AES_256_GCM, 15 | }; 16 | 17 | enum srtp_flags { 18 | SRTP_UNENCRYPTED_SRTCP = 1<<1, 19 | }; 20 | 21 | struct srtp; 22 | 23 | int srtp_alloc(struct srtp **srtpp, enum srtp_suite suite, 24 | const uint8_t *key, size_t key_bytes, int flags); 25 | int srtp_encrypt(struct srtp *srtp, struct mbuf *mb); 26 | int srtp_decrypt(struct srtp *srtp, struct mbuf *mb); 27 | int srtcp_encrypt(struct srtp *srtp, struct mbuf *mb); 28 | int srtcp_decrypt(struct srtp *srtp, struct mbuf *mb); 29 | 30 | const char *srtp_suite_name(enum srtp_suite suite); 31 | -------------------------------------------------------------------------------- /include/re_sys.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file re_sys.h Interface to system module 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | 8 | #ifndef RE_VERSION 9 | #define RE_VERSION "?" 10 | #endif 11 | 12 | /** 13 | * @def ARCH 14 | * 15 | * Architecture 16 | */ 17 | #ifndef ARCH 18 | #define ARCH "?" 19 | #endif 20 | 21 | /** 22 | * @def OS 23 | * 24 | * Operating System 25 | */ 26 | #ifndef OS 27 | #ifdef WIN32 28 | #define OS "win32" 29 | #else 30 | #define OS "?" 31 | #endif 32 | #endif 33 | 34 | struct re_printf; 35 | struct mbuf; 36 | 37 | int sys_kernel_get(struct re_printf *pf, void *unused); 38 | int sys_build_get(struct re_printf *pf, void *unused); 39 | const char *sys_arch_get(void); 40 | const char *sys_os_get(void); 41 | const char *sys_libre_version_get(void); 42 | const char *sys_username(void); 43 | int sys_getenv(char **env, const char *name); 44 | int sys_coredump_set(bool enable); 45 | int sys_daemon(void); 46 | void sys_usleep(unsigned int us); 47 | 48 | static inline void sys_msleep(unsigned int ms) 49 | { 50 | sys_usleep(ms * 1000); 51 | } 52 | 53 | 54 | uint16_t sys_htols(uint16_t v); 55 | uint32_t sys_htoll(uint32_t v); 56 | uint16_t sys_ltohs(uint16_t v); 57 | uint32_t sys_ltohl(uint32_t v); 58 | uint64_t sys_htonll(uint64_t v); 59 | uint64_t sys_ntohll(uint64_t v); 60 | 61 | 62 | /* Random */ 63 | uint16_t rand_u16(void); 64 | uint32_t rand_u32(void); 65 | uint64_t rand_u64(void); 66 | char rand_char(void); 67 | void rand_str(char *str, size_t size); 68 | void rand_bytes(uint8_t *p, size_t size); 69 | 70 | 71 | /* File-System */ 72 | int fs_mkdir(const char *path, uint16_t mode); 73 | int fs_gethome(char *path, size_t sz); 74 | bool fs_isdir(const char *path); 75 | bool fs_isfile(const char *file); 76 | int fs_fopen(FILE **fp, const char *file, const char *mode); 77 | int fs_fread(struct mbuf **mbp, const char *path); 78 | 79 | void fs_stdio_hide(void); 80 | void fs_stdio_restore(void); 81 | -------------------------------------------------------------------------------- /include/re_telev.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file re_telev.h Interface to Telephony Events (RFC 4733) 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | enum { 8 | TELEV_PTIME = 50, 9 | TELEV_SRATE = 8000 10 | }; 11 | 12 | struct telev; 13 | 14 | extern const char telev_rtpfmt[]; 15 | 16 | int telev_alloc(struct telev **tp, uint32_t ptime); 17 | int telev_set_srate(struct telev *tel, uint32_t srate); 18 | int telev_send(struct telev *tel, int event, bool end); 19 | int telev_recv(struct telev *tel, struct mbuf *mb, int *event, bool *end); 20 | int telev_poll(struct telev *tel, bool *marker, struct mbuf *mb); 21 | bool telev_is_empty(const struct telev *tel); 22 | 23 | int telev_digit2code(int digit); 24 | int telev_code2digit(int code); 25 | -------------------------------------------------------------------------------- /include/re_turn.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file re_turn.h Interface to TURN implementation 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | 8 | /** TURN Protocol values */ 9 | enum { 10 | TURN_DEFAULT_LIFETIME = 600, /**< Default lifetime is 10 minutes */ 11 | TURN_MAX_LIFETIME = 3600 /**< Maximum lifetime is 1 hour */ 12 | }; 13 | 14 | typedef void(turnc_h)(int err, uint16_t scode, const char *reason, 15 | const struct sa *relay_addr, 16 | const struct sa *mapped_addr, 17 | const struct stun_msg *msg, 18 | void *arg); 19 | typedef void(turnc_perm_h)(void *arg); 20 | typedef void(turnc_chan_h)(void *arg); 21 | 22 | struct turnc; 23 | 24 | int turnc_alloc(struct turnc **turncp, const struct stun_conf *conf, int proto, 25 | void *sock, int layer, const struct sa *srv, 26 | const char *username, const char *password, 27 | uint32_t lifetime, turnc_h *th, void *arg); 28 | int turnc_send(struct turnc *turnc, const struct sa *dst, struct mbuf *mb); 29 | int turnc_recv(struct turnc *turnc, struct sa *src, struct mbuf *mb); 30 | int turnc_add_perm(struct turnc *turnc, const struct sa *peer, 31 | turnc_perm_h *ph, void *arg); 32 | int turnc_add_chan(struct turnc *turnc, const struct sa *peer, 33 | turnc_chan_h *ch, void *arg); 34 | -------------------------------------------------------------------------------- /include/re_unixsock.h: -------------------------------------------------------------------------------- 1 | 2 | int unixsock_listen_fd(re_sock_t *fdp, const struct sa *sock); 3 | -------------------------------------------------------------------------------- /include/rem.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file rem.h Wrapper for librem headers 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | #ifndef REM_H__ 8 | #define REM_H__ 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | 15 | #include "rem_audio.h" 16 | #include "rem_video.h" 17 | #include "rem_dsp.h" 18 | #include "rem_flv.h" 19 | 20 | 21 | #ifdef __cplusplus 22 | } 23 | #endif 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /include/rem_aac.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file rem_aac.h Advanced Audio Coding 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | 8 | /** Defines the AAC header */ 9 | struct aac_header { 10 | unsigned sample_rate; /**< Audio sample rate in [Hz] */ 11 | unsigned channels; /**< Number of audio channels */ 12 | unsigned frame_size; /**< Frame size, 960 or 1024 bits */ 13 | }; 14 | 15 | int aac_header_decode(struct aac_header *hdr, const uint8_t *p, size_t len); 16 | -------------------------------------------------------------------------------- /include/rem_au.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file rem_au.h Basic audio types 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | 8 | /** Audio formats */ 9 | enum aufmt { 10 | AUFMT_S16LE, /**< Signed 16-bit PCM */ 11 | AUFMT_S32LE, /**< Signed 32-bit PCM */ 12 | AUFMT_PCMA, /**< G.711 A-law */ 13 | AUFMT_PCMU, /**< G.711 U-law */ 14 | AUFMT_FLOAT, /**< Float 32 bit (CPU endian) */ 15 | AUFMT_S24_3LE,/**< Signed 24bit Little Endian in 3bytes format */ 16 | AUFMT_RAW, /**< RAW PCM */ 17 | }; 18 | 19 | size_t aufmt_sample_size(enum aufmt fmt); 20 | const char *aufmt_name(enum aufmt fmt); 21 | 22 | uint32_t au_calc_nsamp(uint32_t srate, uint8_t channels, uint16_t ptime); 23 | 24 | /* todo: remove backwards wrapper later */ 25 | static inline uint32_t calc_nsamp(uint32_t srate, uint8_t channels, 26 | uint16_t ptime) 27 | { 28 | return au_calc_nsamp(srate, channels, ptime); 29 | } 30 | -------------------------------------------------------------------------------- /include/rem_auconv.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file rem_auconv.h Audio sample format conversion 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | 8 | void auconv_from_s16(enum aufmt dst_fmt, void *dst_sampv, 9 | const int16_t *src_sampv, size_t sampc); 10 | void auconv_to_s16(int16_t *dst_sampv, enum aufmt src_fmt, 11 | void *src_sampv, size_t sampc); 12 | void auconv_to_float(float *dst_sampv, enum aufmt src_fmt, 13 | const void *src_sampv, size_t sampc); 14 | -------------------------------------------------------------------------------- /include/rem_audio.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file rem_audio.h Wrapper for all Audio header files 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | 8 | #include "rem_au.h" 9 | #include "rem_aulevel.h" 10 | #include "rem_auframe.h" 11 | #include "rem_aubuf.h" 12 | #include "rem_auconv.h" 13 | #include "rem_aufile.h" 14 | #include "rem_autone.h" 15 | #include "rem_aumix.h" 16 | #include "rem_dtmf.h" 17 | #include "rem_fir.h" 18 | #include "rem_goertzel.h" 19 | #include "rem_auresamp.h" 20 | #include "rem_g711.h" 21 | #include "rem_aac.h" 22 | -------------------------------------------------------------------------------- /include/rem_aufile.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file rem_aufile.h Audio File interface 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | 8 | /** Audio file mode */ 9 | enum aufile_mode { 10 | AUFILE_READ, 11 | AUFILE_WRITE, 12 | }; 13 | 14 | /** Audio file parameters */ 15 | struct aufile_prm { 16 | uint32_t srate; 17 | uint8_t channels; 18 | enum aufmt fmt; 19 | }; 20 | 21 | struct aufile; 22 | 23 | int aufile_open(struct aufile **afp, struct aufile_prm *prm, 24 | const char *filename, enum aufile_mode mode); 25 | int aufile_read(struct aufile *af, uint8_t *p, size_t *sz); 26 | int aufile_write(struct aufile *af, const uint8_t *p, size_t sz); 27 | size_t aufile_get_size(struct aufile *af); 28 | size_t aufile_get_length(struct aufile *af, const struct aufile_prm *prm); 29 | int aufile_set_position(struct aufile *af, const struct aufile_prm *prm, 30 | size_t pos_ms); 31 | -------------------------------------------------------------------------------- /include/rem_auframe.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Audio frame 3 | */ 4 | 5 | #define AUDIO_TIMEBASE 1000000U 6 | 7 | /** 8 | * Defines a frame of audio samples 9 | */ 10 | struct auframe { 11 | enum aufmt fmt; /**< Sample format (enum aufmt) */ 12 | uint32_t srate; /**< Samplerate */ 13 | void *sampv; /**< Audio samples (must be mem_ref'd) */ 14 | size_t sampc; /**< Total number of audio samples */ 15 | uint64_t timestamp; /**< Timestamp in AUDIO_TIMEBASE units */ 16 | double level; /**< Audio level in dBov */ 17 | uint16_t id; /**< Frame/Channel identifier */ 18 | uint8_t ch; /**< Channels */ 19 | uint8_t padding[5]; 20 | }; 21 | 22 | void auframe_init(struct auframe *af, enum aufmt fmt, void *sampv, 23 | size_t sampc, uint32_t srate, uint8_t ch); 24 | 25 | /** 26 | * Update an audio frame 27 | * 28 | * @param af Audio frame 29 | * @param sampv Audio samples 30 | * @param sampc Total number of audio samples 31 | * @param timestamp Timestamp in AUDIO_TIMEBASE units 32 | */ 33 | static inline void auframe_update(struct auframe *af, void *sampv, 34 | size_t sampc, uint64_t timestamp) 35 | { 36 | if (!af) 37 | return; 38 | 39 | af->sampv = sampv; 40 | af->sampc = sampc; 41 | af->timestamp = timestamp; 42 | af->level = AULEVEL_UNDEF; 43 | } 44 | 45 | size_t auframe_size(const struct auframe *af); 46 | void auframe_mute(struct auframe *af); 47 | double auframe_level(struct auframe *af); 48 | uint64_t auframe_bytes_to_timestamp(const struct auframe *af, size_t n); 49 | uint64_t auframe_bytes_to_ms(const struct auframe *af, size_t n); 50 | -------------------------------------------------------------------------------- /include/rem_aulevel.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | /* 4 | * Audio-level 5 | */ 6 | 7 | 8 | #define AULEVEL_UNDEF (-128.0) 9 | #define AULEVEL_MIN (-96.0) 10 | #define AULEVEL_MAX (0.0) 11 | 12 | 13 | double aulevel_calc_dbov(int fmt, const void *sampv, size_t sampc); 14 | -------------------------------------------------------------------------------- /include/rem_aumix.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file rem_aumix.h Audio Mixer 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | struct aumix; 8 | struct aumix_source; 9 | 10 | /** 11 | * Audio mixer frame handler 12 | * 13 | * @param sampv Buffer with audio samples 14 | * @param sampc Number of samples 15 | * @param arg Handler argument 16 | */ 17 | typedef void (aumix_frame_h)(const int16_t *sampv, size_t sampc, void *arg); 18 | typedef void (aumix_record_h)(struct auframe *af); 19 | typedef void (aumix_read_h)(struct auframe *af, void *arg); 20 | 21 | int aumix_alloc(struct aumix **mixp, uint32_t srate, 22 | uint8_t ch, uint32_t ptime); 23 | void aumix_recordh(struct aumix *mix, aumix_record_h *recordh); 24 | void aumix_record_sumh(struct aumix *mix, aumix_record_h *recordh); 25 | int aumix_playfile(struct aumix *mix, const char *filepath); 26 | uint32_t aumix_source_count(const struct aumix *mix); 27 | int aumix_source_alloc(struct aumix_source **srcp, struct aumix *mix, 28 | aumix_frame_h *fh, void *arg); 29 | void aumix_source_set_id(struct aumix_source *src, uint16_t id); 30 | void aumix_source_enable(struct aumix_source *src, bool enable); 31 | void aumix_source_mute(struct aumix_source *src, bool mute); 32 | int aumix_source_put(struct aumix_source *src, const int16_t *sampv, 33 | size_t sampc); 34 | void aumix_source_readh(struct aumix_source *src, aumix_read_h *readh); 35 | void aumix_source_flush(struct aumix_source *src); 36 | int aumix_debug(struct re_printf *pf, const struct aumix *mix); 37 | -------------------------------------------------------------------------------- /include/rem_auresamp.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file rem_auresamp.h Audio Resampling 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | /** 8 | * Defines the audio resampler handler 9 | * 10 | * @param outv Output samples 11 | * @param inv Input samples 12 | * @param inc Number of input samples 13 | * @param ratio Resample ratio 14 | */ 15 | typedef void (auresamp_h)(int16_t *outv, const int16_t *inv, 16 | size_t inc, unsigned ratio); 17 | 18 | /** Defines the resampler state */ 19 | struct auresamp { 20 | struct fir fir; /**< FIR filter state */ 21 | auresamp_h *resample; /**< Resample handler */ 22 | const int16_t *tapv; /**< FIR filter taps */ 23 | size_t tapc; /**< FIR filter tap count */ 24 | uint32_t orate, irate; /**< Input/output sample rate */ 25 | unsigned och, ich; /**< Input/output channel count */ 26 | unsigned ratio; /**< Resample ratio */ 27 | bool up; /**< Up/down sample flag */ 28 | }; 29 | 30 | void auresamp_init(struct auresamp *rs); 31 | int auresamp_setup(struct auresamp *rs, uint32_t irate, unsigned ich, 32 | uint32_t orate, unsigned och); 33 | int auresamp(struct auresamp *rs, int16_t *outv, size_t *outc, 34 | const int16_t *inv, size_t inc); 35 | -------------------------------------------------------------------------------- /include/rem_autone.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file rem_autone.h Audio Tones 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | 8 | int autone_sine(struct mbuf *mb, uint32_t srate, 9 | uint32_t f1, int l1, uint32_t f2, int l2); 10 | int autone_dtmf(struct mbuf *mb, uint32_t srate, int digit); 11 | -------------------------------------------------------------------------------- /include/rem_avc.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file rem_avc.h Advanced Video Coding 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | 8 | struct avc_config { 9 | uint8_t profile_ind; 10 | uint8_t profile_compat; 11 | uint8_t level_ind; 12 | uint16_t sps_len; 13 | uint8_t sps[256]; 14 | uint16_t pps_len; 15 | uint8_t pps[64]; 16 | }; 17 | 18 | 19 | int avc_config_encode(struct mbuf *mb, uint8_t profile_ind, 20 | uint8_t profile_compat, uint8_t level_ind, 21 | uint16_t sps_length, const uint8_t *sps, 22 | uint16_t pps_length, const uint8_t *pps); 23 | int avc_config_decode(struct avc_config *conf, struct mbuf *mb); 24 | -------------------------------------------------------------------------------- /include/rem_dtmf.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file rem_dtmf.h DTMF Decoder 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | struct dtmf_dec; 8 | 9 | /** 10 | * Defines the DTMF decode handler 11 | * 12 | * @param digit Decoded DTMF digit 13 | * @param arg Handler argument 14 | */ 15 | typedef void (dtmf_dec_h)(char digit, void *arg); 16 | 17 | 18 | int dtmf_dec_alloc(struct dtmf_dec **decp, unsigned srate, unsigned ch, 19 | dtmf_dec_h *dech, void *arg); 20 | void dtmf_dec_reset(struct dtmf_dec *dec, unsigned srate, unsigned ch); 21 | void dtmf_dec_probe(struct dtmf_dec *dec, const int16_t *sampv, size_t sampc); 22 | -------------------------------------------------------------------------------- /include/rem_fir.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file rem_fir.h Finite Impulse Response (FIR) functions 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | /** Defines the fir filter state */ 8 | struct fir { 9 | int16_t history[256]; /**< Previous samples */ 10 | unsigned index; /**< Sample index */ 11 | }; 12 | 13 | void fir_reset(struct fir *fir); 14 | void fir_filter(struct fir *fir, int16_t *outv, const int16_t *inv, size_t inc, 15 | unsigned ch, const int16_t *tapv, size_t tapc); 16 | -------------------------------------------------------------------------------- /include/rem_flv.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file rem_flv.h Flash Video File Format 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | 8 | /* 9 | * Audio 10 | */ 11 | 12 | enum flv_aucodec { 13 | FLV_AUCODEC_PCM = 0, 14 | FLV_AUCODEC_MP3 = 2, 15 | FLV_AUCODEC_PCM_LE = 3, 16 | FLV_AUCODEC_ALAW = 7, 17 | FLV_AUCODEC_ULAW = 8, 18 | FLV_AUCODEC_AAC = 10, 19 | }; 20 | 21 | enum flv_srate { 22 | FLV_SRATE_5500HZ = 0, 23 | FLV_SRATE_11000HZ = 1, 24 | FLV_SRATE_22000HZ = 2, 25 | FLV_SRATE_44000HZ = 3, 26 | }; 27 | 28 | enum flv_aac_packet_type { 29 | FLV_AAC_SEQUENCE_HEADER = 0, 30 | FLV_AAC_RAW = 1, 31 | }; 32 | 33 | 34 | /* 35 | * Video 36 | */ 37 | 38 | enum flv_vidframe { 39 | FLV_VIDFRAME_KEY = 1, 40 | FLV_VIDFRAME_INTER = 2, 41 | FLV_VIDFRAME_DISP_INTER = 3, 42 | FLV_VIDFRAME_GENERATED_KEY = 4, 43 | FLV_VIDFRAME_VIDEO_INFO_CMD = 5, 44 | }; 45 | 46 | enum flv_vidcodec { 47 | FLV_VIDCODEC_H263 = 2, 48 | FLV_VIDCODEC_H264 = 7, 49 | FLV_VIDCODEC_MPEG4 = 9, 50 | }; 51 | 52 | enum flv_avc_packet_type { 53 | FLV_AVC_SEQUENCE = 0, 54 | FLV_AVC_NALU = 1, 55 | FLV_AVC_EOS = 2, 56 | }; 57 | -------------------------------------------------------------------------------- /include/rem_g711.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file rem_g711.h Interface to G.711 codec 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | 8 | extern const uint8_t g711_l2u[4096]; 9 | extern const uint8_t g711_l2A[2048]; 10 | extern const int16_t g711_u2l[256]; 11 | extern const int16_t g711_A2l[256]; 12 | 13 | 14 | /** 15 | * Encode one 16-bit PCM sample to U-law format 16 | * 17 | * @param l Signed PCM sample 18 | * 19 | * @return U-law byte 20 | */ 21 | static inline uint8_t g711_pcm2ulaw(int16_t lx) 22 | { 23 | int32_t l = lx; 24 | const uint8_t mask = (l < 0) ? 0x7f : 0xff; 25 | if (l < 0) 26 | l = -l; 27 | if (l < 4) 28 | return 0xff & mask; 29 | l -= 4; 30 | l >>= 3; 31 | 32 | return g711_l2u[l] & mask; 33 | } 34 | 35 | 36 | /** 37 | * Encode one 16-bit PCM sample to A-law format 38 | * 39 | * @param l Signed PCM sample 40 | * 41 | * @return A-law byte 42 | */ 43 | static inline uint8_t g711_pcm2alaw(int16_t l) 44 | { 45 | const uint8_t mask = (l < 0) ? 0x7f : 0xff; 46 | if (l < 0) 47 | l = ~l; 48 | l >>= 4; 49 | 50 | return g711_l2A[l] & mask; 51 | } 52 | 53 | 54 | /** 55 | * Decode one U-law sample to 16-bit PCM sample 56 | * 57 | * @param u U-law byte 58 | * 59 | * @return Signed PCM sample 60 | */ 61 | static inline int16_t g711_ulaw2pcm(uint8_t u) 62 | { 63 | return g711_u2l[u]; 64 | } 65 | 66 | 67 | /** 68 | * Decode one A-law sample to 16-bit PCM sample 69 | * 70 | * @param A A-law byte 71 | * 72 | * @return Signed PCM sample 73 | */ 74 | static inline int16_t g711_alaw2pcm(uint8_t a) 75 | { 76 | return g711_A2l[a]; 77 | } 78 | -------------------------------------------------------------------------------- /include/rem_goertzel.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file rem_goertzel.h Goertzel algorithm 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | /** Defines the goertzel algorithm state */ 8 | struct goertzel { 9 | double q1; /**< current state */ 10 | double q2; /**< previous state */ 11 | double coef; /**< coefficient */ 12 | }; 13 | 14 | 15 | void goertzel_init(struct goertzel *g, double freq, unsigned srate); 16 | void goertzel_reset(struct goertzel *g); 17 | double goertzel_result(struct goertzel *g); 18 | 19 | 20 | /** 21 | * Process sample 22 | * 23 | * @param g Goertzel state 24 | * @param samp Sample value 25 | */ 26 | static inline void goertzel_update(struct goertzel *g, int16_t samp) 27 | { 28 | double q0 = g->coef*g->q1 - g->q2 + (double)samp; 29 | 30 | g->q2 = g->q1; 31 | g->q1 = q0; 32 | } 33 | -------------------------------------------------------------------------------- /include/rem_vidconv.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file rem_vidconv.h Video colorspace conversion 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | 8 | void vidconv(struct vidframe *dst, const struct vidframe *src, 9 | struct vidrect *r); 10 | void vidconv_aspect(struct vidframe *dst, const struct vidframe *src, 11 | struct vidrect *r); 12 | void vidconv_center(struct vidframe *dst, const struct vidframe *src, 13 | struct vidrect *r); 14 | -------------------------------------------------------------------------------- /include/rem_video.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file rem_video.h Wrapper for all Video header files 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | 8 | #include "rem_vid.h" 9 | #include "rem_vidmix.h" 10 | #include "rem_vidconv.h" 11 | #include "rem_avc.h" 12 | -------------------------------------------------------------------------------- /include/rem_vidmix.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file rem_vidmix.h Video Mixer 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | 8 | struct vidmix; 9 | struct vidmix_source; 10 | 11 | /** 12 | * Video mixer frame handler 13 | * 14 | * @param ts Timestamp 15 | * @param frame Video frame 16 | * @param arg Handler argument 17 | */ 18 | typedef void (vidmix_frame_h)(uint64_t ts, const struct vidframe *frame, 19 | void *arg); 20 | 21 | int vidmix_alloc(struct vidmix **mixp); 22 | void vidmix_set_fmt(struct vidmix *mix, enum vidfmt fmt); 23 | int vidmix_source_alloc(struct vidmix_source **srcp, struct vidmix *mix, 24 | const struct vidsz *sz, unsigned fps, bool content, 25 | vidmix_frame_h *fh, void *arg); 26 | bool vidmix_source_isenabled(const struct vidmix_source *src); 27 | bool vidmix_source_isrunning(const struct vidmix_source *src); 28 | uint32_t vidmix_source_get_pidx(const struct vidmix_source *src); 29 | void *vidmix_source_get_focus(const struct vidmix_source *src); 30 | void vidmix_source_enable(struct vidmix_source *src, bool enable); 31 | int vidmix_source_start(struct vidmix_source *src); 32 | void vidmix_source_stop(struct vidmix_source *src); 33 | int vidmix_source_set_size(struct vidmix_source *src, const struct vidsz *sz); 34 | void vidmix_source_set_rate(struct vidmix_source *src, unsigned fps); 35 | void vidmix_source_set_content_hide(struct vidmix_source *src, bool hide); 36 | void vidmix_source_toggle_selfview(struct vidmix_source *src); 37 | void vidmix_source_set_focus(struct vidmix_source *src, 38 | const struct vidmix_source *focus_src, 39 | bool focus_full); 40 | void vidmix_source_set_focus_idx(struct vidmix_source *src, uint32_t pidx); 41 | void vidmix_source_put(struct vidmix_source *src, 42 | const struct vidframe *frame); 43 | -------------------------------------------------------------------------------- /packaging/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(CPACK_PACKAGE_NAME libre) 2 | set(CPACK_PACKAGE_CONTACT "sreimers") 3 | set(CPACK_PACKAGE_VENDOR baresip) 4 | set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Library for Real-Time Communications") 5 | set(CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME}) 6 | set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR}) 7 | set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR}) 8 | set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH}) 9 | set(CPACK_VERBATIM_VARIABLES YES) 10 | set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE") 11 | set(CPACK_RESOURCE_FILE_README "${CMAKE_SOURCE_DIR}/README.md") 12 | 13 | # Debian 14 | set(CPACK_DEB_COMPONENT_INSTALL ON) 15 | set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT) 16 | set(CPACK_DEBIAN_LIBRARIES_PACKAGE_NAME "libre") 17 | set(CPACK_DEBIAN_DEVELOPMENT_PACKAGE_NAME "libre-dev") 18 | set(CPACK_DEBIAN_PACKAGE_DEPENDS "libssl3, zlib1g, libc6") 19 | 20 | include(CPack) 21 | -------------------------------------------------------------------------------- /packaging/libre.pc.in: -------------------------------------------------------------------------------- 1 | prefix="@CMAKE_INSTALL_PREFIX@" 2 | exec_prefix=${prefix} 3 | libdir=${prefix}/lib 4 | includedir=${prefix}/include/re 5 | 6 | Name: libre 7 | Description: @CMAKE_PROJECT_DESCRIPTION@ 8 | Version: @PROJECT_VERSION@ 9 | URL: @CMAKE_PROJECT_HOMEPAGE_URL@ 10 | Libs: -L${libdir} -l@PC_LIBNAME@ 11 | Libs.private: @PC_LINKLIBS@ 12 | Requires.private: @PC_REQUIRES@ 13 | Cflags: -I${includedir} 14 | -------------------------------------------------------------------------------- /rem/aac/aac.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file aac.c Advanced Audio Coding 3 | * 4 | * Copyright (C) 2018 Creytiv.com 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | 11 | /* 12 | * Ref https://wiki.multimedia.cx/index.php/MPEG-4_Audio 13 | */ 14 | 15 | enum { 16 | OBJECT_TYPE_AAC_LC = 2 17 | }; 18 | 19 | 20 | static const unsigned aac_sample_rates[13] = { 21 | 96000, 88200, 64000, 48000, 44100, 32000, 22 | 24000, 22050, 16000, 12000, 11025, 8000, 7350 23 | }; 24 | 25 | 26 | static const unsigned aac_channels[8] = { 27 | 0, 1, 2, 3, 4, 5, 6, 8 28 | }; 29 | 30 | 31 | /** 32 | * Decode an AAC header 33 | * 34 | * @param hdr Decoded AAC header 35 | * @param p Packet to decode 36 | * @param len Packet length 37 | * 38 | * @return 0 if success, otherwise errorcode 39 | */ 40 | int aac_header_decode(struct aac_header *hdr, const uint8_t *p, size_t len) 41 | { 42 | uint8_t object_type; 43 | uint8_t srate_index; 44 | uint8_t channel_index; 45 | 46 | if (!hdr || !p || len<2) 47 | return EINVAL; 48 | 49 | object_type = (p[0] >> 3) & 0x1f; 50 | 51 | if (object_type != OBJECT_TYPE_AAC_LC) 52 | return EBADMSG; 53 | 54 | srate_index = (p[0] & 0x07) << 1; 55 | srate_index |= (p[1] & 0x80) >> 7; 56 | 57 | channel_index = (p[1] >> 3) & 0xf; 58 | 59 | if (srate_index >= RE_ARRAY_SIZE(aac_sample_rates)) 60 | return ENOTSUP; 61 | if (channel_index >= RE_ARRAY_SIZE(aac_channels)) 62 | return ENOTSUP; 63 | 64 | hdr->sample_rate = aac_sample_rates[srate_index]; 65 | hdr->channels = aac_channels[channel_index]; 66 | hdr->frame_size = ((p[1] >> 2) & 1) ? 960 : 1024; 67 | 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /rem/au/fmt.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file au/fmt.c Audio formats 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | 9 | 10 | /* Number of bytes per sample */ 11 | size_t aufmt_sample_size(enum aufmt fmt) 12 | { 13 | switch (fmt) { 14 | 15 | case AUFMT_S16LE: return sizeof(int16_t); 16 | case AUFMT_S32LE: return sizeof(int32_t); 17 | case AUFMT_RAW: return 1; 18 | case AUFMT_PCMA: return 1; 19 | case AUFMT_PCMU: return 1; 20 | case AUFMT_FLOAT: return sizeof(float); 21 | case AUFMT_S24_3LE: return 3; 22 | default: return 0; 23 | } 24 | } 25 | 26 | 27 | const char *aufmt_name(enum aufmt fmt) 28 | { 29 | switch (fmt) { 30 | 31 | case AUFMT_S16LE: return "S16LE"; 32 | case AUFMT_S32LE: return "S32LE"; 33 | case AUFMT_PCMA: return "PCMA"; 34 | case AUFMT_PCMU: return "PCMU"; 35 | case AUFMT_FLOAT: return "FLOAT"; 36 | case AUFMT_S24_3LE: return "S24_3LE"; 37 | case AUFMT_RAW: return "RAW"; 38 | default: return "???"; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /rem/au/util.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file util.c Audio utility functions 3 | * 4 | * Copyright (C) 2022 Commend.com - c.spielberger@commend.com 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | 11 | /** 12 | * Calculate number of samples from sample rate, channels and packet time 13 | * 14 | * @param srate Sample rate in [Hz] 15 | * @param channels Number of channels 16 | * @param ptime Packet time in [ms] 17 | * 18 | * @return Number of samples 19 | */ 20 | uint32_t au_calc_nsamp(uint32_t srate, uint8_t channels, uint16_t ptime) 21 | { 22 | return srate * channels * ptime / 1000; 23 | } 24 | -------------------------------------------------------------------------------- /rem/aubuf/ajb.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file ajb.h Adaptive Jitter Buffer interface 3 | * 4 | * Copyright (C) 2022 Commend.com - c.spielberger@commend.com 5 | */ 6 | 7 | enum ajb_state { 8 | AJB_GOOD = 0, 9 | AJB_LOW, 10 | AJB_HIGH, 11 | }; 12 | 13 | struct ajb; 14 | 15 | struct ajb *ajb_alloc(double silence, size_t wish_sz); 16 | void ajb_reset(struct ajb *ajb); 17 | void ajb_calc(struct ajb *ajb, const struct auframe *af, size_t sampc); 18 | enum ajb_state ajb_get(struct ajb *ajb, struct auframe *af); 19 | int32_t ajb_debug(const struct ajb *ajb); 20 | void plot_underrun(struct ajb *ajb); 21 | void ajb_set_ts0(struct ajb *ajb, uint64_t timestamp); 22 | -------------------------------------------------------------------------------- /rem/aufile/aufile.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file aufile.h Audio File -- internal API 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | 8 | enum wavfmt { 9 | WAVE_FMT_PCM = 0x0001, 10 | WAVE_FMT_ALAW = 0x0006, 11 | WAVE_FMT_ULAW = 0x0007, 12 | }; 13 | 14 | /** WAVE format sub-chunk */ 15 | struct wav_fmt { 16 | uint16_t format; 17 | uint16_t channels; 18 | uint32_t srate; 19 | uint32_t byterate; 20 | uint16_t block_align; 21 | uint16_t bps; 22 | uint16_t extra; 23 | }; 24 | 25 | int wav_header_encode(FILE *f, uint16_t format, uint16_t channels, 26 | uint32_t srate, uint16_t bps, size_t bytes); 27 | int wav_header_decode(struct wav_fmt *fmt, size_t *datasize, FILE *f); 28 | -------------------------------------------------------------------------------- /rem/fir/fir.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file fir.c FIR -- Finite Impulse Response 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | 12 | /** 13 | * Reset the FIR-filter 14 | * 15 | * @param fir FIR-filter state 16 | */ 17 | void fir_reset(struct fir *fir) 18 | { 19 | if (!fir) 20 | return; 21 | 22 | memset(fir, 0, sizeof(*fir)); 23 | } 24 | 25 | 26 | /** 27 | * Process samples with the FIR filter 28 | * 29 | * @note product of channel and tap-count must be power of two 30 | * 31 | * @param fir FIR filter 32 | * @param outv Output samples 33 | * @param inv Input samples 34 | * @param inc Number of samples 35 | * @param ch Number of channels 36 | * @param tapv Filter taps 37 | * @param tapc Number of taps 38 | */ 39 | void fir_filter(struct fir *fir, int16_t *outv, const int16_t *inv, size_t inc, 40 | unsigned ch, const int16_t *tapv, size_t tapc) 41 | { 42 | const unsigned hmask = (ch * (unsigned)tapc) - 1; 43 | 44 | if (!fir || !outv || !inv || !ch || !tapv || !tapc) 45 | return; 46 | 47 | if (hmask >= RE_ARRAY_SIZE(fir->history) || hmask & (hmask+1)) 48 | return; 49 | 50 | while (inc--) { 51 | 52 | int64_t acc = 0; 53 | unsigned i, j; 54 | 55 | fir->history[fir->index & hmask] = *inv++; 56 | 57 | for (i=0, j=fir->index++; ihistory[j & hmask] * tapv[i]; 59 | 60 | if (acc > 0x3fffffff) 61 | acc = 0x3fffffff; 62 | else if (acc < -0x40000000) 63 | acc = -0x40000000; 64 | 65 | *outv++ = (int16_t)(acc>>15); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /rem/goertzel/goertzel.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file goertzel.c Goertzel algorithm 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | 12 | #define PI 3.14159265358979323846264338327 13 | 14 | 15 | /** 16 | * Initialize goertzel state 17 | * 18 | * @param g Goertzel state 19 | * @param freq Target frequency 20 | * @param srate Sample rate 21 | */ 22 | void goertzel_init(struct goertzel *g, double freq, unsigned srate) 23 | { 24 | g->q1 = 0.0; 25 | g->q2 = 0.0; 26 | g->coef = 2.0 * cos(2.0 * PI * (freq/(double)srate)); 27 | } 28 | 29 | 30 | /** 31 | * Reset goertzel state 32 | * 33 | * @param g Goertzel state 34 | */ 35 | void goertzel_reset(struct goertzel *g) 36 | { 37 | g->q1 = 0.0; 38 | g->q2 = 0.0; 39 | } 40 | 41 | 42 | /** 43 | * Calculate result and reset state 44 | * 45 | * @param g Goertzel state 46 | * 47 | * @return Result value 48 | */ 49 | double goertzel_result(struct goertzel *g) 50 | { 51 | double res; 52 | 53 | goertzel_update(g, 0); 54 | 55 | res = g->q1*g->q1 + g->q2*g->q2 - g->q1*g->q2*g->coef; 56 | 57 | goertzel_reset(g); 58 | 59 | return res * 2.0; 60 | } 61 | -------------------------------------------------------------------------------- /rem/vid/fmt.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file vid/fmt.c Video Formats 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | 11 | /** Video format description table */ 12 | const struct vidfmt_desc vidfmt_descv[VID_FMT_N] = { 13 | 14 | {"yuv420p", 3, 3, { {0, 1}, {1, 1}, {2, 1}, {0, 0} } }, 15 | {"yuyv422", 1, 3, { {0, 2}, {0, 4}, {0, 4}, {0, 0} } }, 16 | {"uyvy422", 1, 3, { {0, 2}, {0, 4}, {0, 4}, {0, 0} } }, 17 | {"rgb32", 1, 4, { {0, 4}, {0, 4}, {0, 4}, {0, 4} } }, 18 | {"argb", 1, 4, { {0, 4}, {0, 4}, {0, 4}, {0, 4} } }, 19 | {"rgb565", 1, 3, { {0, 2}, {0, 2}, {0, 2}, {0, 0} } }, 20 | {"nv12", 3, 2, { {0, 1}, {1, 2}, {1, 2}, {0, 0} } }, 21 | {"nv21", 3, 2, { {0, 1}, {1, 2}, {1, 2}, {0, 0} } }, 22 | {"yuv444p", 3, 3, { {0, 1}, {1, 1}, {2, 1}, {0, 0} } }, 23 | {"yuv422p", 3, 3, { {0, 1}, {1, 1}, {2, 1}, {0, 0} } }, 24 | }; 25 | 26 | 27 | /** 28 | * Get the name of a video format 29 | * 30 | * @param fmt Video format 31 | * 32 | * @return Name of the video format 33 | */ 34 | const char *vidfmt_name(enum vidfmt fmt) 35 | { 36 | if (fmt >= VID_FMT_N) 37 | return "???"; 38 | 39 | return vidfmt_descv[fmt].name; 40 | } 41 | -------------------------------------------------------------------------------- /sonar-project.properties: -------------------------------------------------------------------------------- 1 | sonar.projectKey=baresip_re 2 | sonar.organization=baresip 3 | sonar.cfamily.threads=2 4 | -------------------------------------------------------------------------------- /src/aes/stub.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file aes/stub.c AES stub 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | 9 | 10 | int aes_alloc(struct aes **stp, enum aes_mode mode, 11 | const uint8_t *key, size_t key_bits, 12 | const uint8_t *iv) 13 | { 14 | (void)stp; 15 | (void)mode; 16 | (void)key; 17 | (void)key_bits; 18 | (void)iv; 19 | return ENOSYS; 20 | } 21 | 22 | 23 | void aes_set_iv(struct aes *aes, const uint8_t *iv) 24 | { 25 | (void)aes; 26 | (void)iv; 27 | } 28 | 29 | 30 | int aes_encr(struct aes *st, uint8_t *out, const uint8_t *in, size_t len) 31 | { 32 | (void)st; 33 | (void)out; 34 | (void)in; 35 | (void)len; 36 | return ENOSYS; 37 | } 38 | 39 | 40 | int aes_decr(struct aes *st, uint8_t *out, const uint8_t *in, size_t len) 41 | { 42 | (void)st; 43 | (void)out; 44 | (void)in; 45 | (void)len; 46 | return ENOSYS; 47 | } 48 | 49 | 50 | int aes_get_authtag(struct aes *aes, uint8_t *tag, size_t taglen) 51 | { 52 | (void)aes; 53 | (void)tag; 54 | (void)taglen; 55 | 56 | return ENOSYS; 57 | } 58 | 59 | 60 | int aes_authenticate(struct aes *aes, const uint8_t *tag, size_t taglen) 61 | { 62 | (void)aes; 63 | (void)tag; 64 | (void)taglen; 65 | 66 | return ENOSYS; 67 | } 68 | -------------------------------------------------------------------------------- /src/av1/depack.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file av1/depack.c AV1 De-packetizer 3 | * 4 | * Copyright (C) 2010 - 2022 Alfred E. Heggestad 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | 13 | /** 14 | * Decode an AV1 Aggregation header from mbuffer 15 | * 16 | * @param hdr Decoded aggregation header 17 | * @param mb Mbuffer to decode from 18 | * 19 | * @return 0 if success, otherwise errorcode 20 | */ 21 | int av1_aggr_hdr_decode(struct av1_aggr_hdr *hdr, struct mbuf *mb) 22 | { 23 | uint8_t v; 24 | 25 | if (!hdr || !mb) 26 | return EINVAL; 27 | 28 | memset(hdr, 0, sizeof(*hdr)); 29 | 30 | if (mbuf_get_left(mb) < 1) 31 | return EBADMSG; 32 | 33 | v = mbuf_read_u8(mb); 34 | 35 | hdr->z = v>>7 & 0x1; 36 | hdr->y = v>>6 & 0x1; 37 | hdr->w = v>>4 & 0x3; 38 | hdr->n = v>>3 & 0x1; 39 | 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /src/bfcp/bfcp.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file bfcp.h Internal interface to Binary Floor Control Protocol (BFCP) 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | struct bfcp_strans { 8 | enum bfcp_prim prim; 9 | uint32_t confid; 10 | uint16_t tid; 11 | uint16_t userid; 12 | }; 13 | 14 | struct bfcp_conn { 15 | struct bfcp_strans st; 16 | struct list ctransl; 17 | struct tmr tmr1; 18 | struct tmr tmr2; 19 | struct udp_sock *us; 20 | struct tcp_sock *ts; 21 | struct tcp_conn *tc; 22 | struct sa sa_peer; 23 | struct mbuf *mb; 24 | bfcp_conn_h *connh; 25 | bfcp_estab_h *estabh; 26 | bfcp_recv_h *recvh; 27 | bfcp_close_h *closeh; 28 | void *arg; 29 | enum bfcp_transp tp; 30 | unsigned txc; 31 | uint16_t tid; 32 | }; 33 | 34 | 35 | /* attributes */ 36 | int bfcp_attrs_decode(struct list *attrl, struct mbuf *mb, size_t len, 37 | struct bfcp_unknown_attr *uma); 38 | struct bfcp_attr *bfcp_attrs_find(const struct list *attrl, 39 | enum bfcp_attrib type); 40 | struct bfcp_attr *bfcp_attrs_apply(const struct list *attrl, 41 | bfcp_attr_h *h, void *arg); 42 | int bfcp_attrs_print(struct re_printf *pf, const struct list *attrl, 43 | unsigned level); 44 | 45 | 46 | /* connection */ 47 | int bfcp_send(struct bfcp_conn *bc, const struct sa *dst, struct mbuf *mb); 48 | 49 | 50 | /* request */ 51 | bool bfcp_handle_response(struct bfcp_conn *bc, const struct bfcp_msg *msg); 52 | int bfcp_vrequest(struct bfcp_conn *bc, const struct sa *dst, uint8_t ver, 53 | enum bfcp_prim prim, uint32_t confid, uint16_t userid, 54 | bfcp_resp_h *resph, void *arg, unsigned attrc, va_list *ap); 55 | -------------------------------------------------------------------------------- /src/dd/putbit.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file putbit.c Put bits helper 3 | * 4 | * Copyright (C) 2023 Alfred E. Heggestad 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | 12 | void putbit_init(struct putbit *pb, struct mbuf *mb) 13 | { 14 | if (!pb || !mb) 15 | return; 16 | 17 | pb->mb = mb; 18 | pb->bit_pos = 0; 19 | 20 | memset(pb->mb->buf, 0, pb->mb->size); 21 | } 22 | 23 | 24 | int putbit_one(struct putbit *pb, unsigned bit) 25 | { 26 | if (!pb) 27 | return EINVAL; 28 | 29 | size_t byte_pos = pb->bit_pos >> 0x3; 30 | 31 | /* resize mbuf */ 32 | if (byte_pos >= pb->mb->size) { 33 | 34 | int err = mbuf_resize(pb->mb, pb->mb->size * 2); 35 | if (err) 36 | return err; 37 | } 38 | 39 | uint8_t *p = pb->mb->buf; 40 | size_t bit_pos = (size_t)(1u << (0x7 - (pb->bit_pos & 0x7))); 41 | 42 | if (bit) { 43 | p[byte_pos] |= bit_pos; 44 | } 45 | else { 46 | p[byte_pos] &= ~bit_pos; 47 | } 48 | 49 | ++pb->bit_pos; 50 | 51 | /* NOTE: mb->pos not used */ 52 | mbuf_set_end(pb->mb, (pb->bit_pos + 7) >> 0x3); 53 | 54 | return 0; 55 | } 56 | 57 | 58 | int putbit_write(struct putbit *pb, unsigned count, unsigned val) 59 | { 60 | if (!pb) 61 | return EINVAL; 62 | 63 | if (count > 32) 64 | return EINVAL; 65 | 66 | for (unsigned i=0; i> shift) & 0x1; 70 | 71 | int err = putbit_one(pb, bit); 72 | if (err) 73 | return err; 74 | } 75 | 76 | return 0; 77 | } 78 | 79 | 80 | int putbit_write_ns(struct putbit *pb, unsigned n, unsigned v) 81 | { 82 | if (!pb) 83 | return EINVAL; 84 | 85 | int err; 86 | 87 | #if 0 88 | /* TODO: check this */ 89 | if (n == 1) 90 | return EINVAL; 91 | #endif 92 | 93 | unsigned w = 0; 94 | unsigned x = n; 95 | 96 | while (x != 0) { 97 | x = x >> 1; 98 | ++w; 99 | } 100 | 101 | unsigned m = (1 << w) - n; 102 | if (v < m) 103 | err = putbit_write(pb, w - 1, v); 104 | else 105 | err = putbit_write(pb, w, v + m); 106 | 107 | return err; 108 | } 109 | -------------------------------------------------------------------------------- /src/dns/cstr.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file cstr.c DNS character strings encoding 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | 15 | /** 16 | * Encode a DNS character string into a memory buffer 17 | * 18 | * @param mb Memory buffer to encode into 19 | * @param str Character string 20 | * 21 | * @return 0 if success, otherwise errorcode 22 | */ 23 | int dns_cstr_encode(struct mbuf *mb, const char *str) 24 | { 25 | uint8_t len; 26 | int err = 0; 27 | 28 | if (!mb || !str) 29 | return EINVAL; 30 | 31 | len = (uint8_t)strlen(str); 32 | 33 | err |= mbuf_write_u8(mb, len); 34 | err |= mbuf_write_mem(mb, (const uint8_t *)str, len); 35 | 36 | return err; 37 | } 38 | 39 | 40 | /** 41 | * Decode a DNS character string from a memory buffer 42 | * 43 | * @param mb Memory buffer to decode from 44 | * @param str Pointer to allocated character string 45 | * 46 | * @return 0 if success, otherwise errorcode 47 | */ 48 | int dns_cstr_decode(struct mbuf *mb, char **str) 49 | { 50 | uint8_t len; 51 | 52 | if (!mb || !str || (mbuf_get_left(mb) < 1)) 53 | return EINVAL; 54 | 55 | len = mbuf_read_u8(mb); 56 | 57 | if (mbuf_get_left(mb) < len) 58 | return EBADMSG; 59 | 60 | return mbuf_strdup(mb, str, len); 61 | } 62 | -------------------------------------------------------------------------------- /src/dns/darwin/srv.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file darwin/srv.c Get DNS Server IP code for Mac OS X 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include "../dns.h" 13 | #define __CF_USE_FRAMEWORK_INCLUDES__ 14 | #include 15 | 16 | 17 | int get_darwin_dns(char *domain, size_t dsize, struct sa *nsv, uint32_t *n) 18 | { 19 | #if TARGET_OS_IPHONE 20 | (void)domain; 21 | (void)dsize; 22 | (void)nsv; 23 | (void)n; 24 | return ENOSYS; 25 | #else 26 | SCDynamicStoreContext context = {0, NULL, NULL, NULL, NULL}; 27 | CFArrayRef addresses, domains; 28 | SCDynamicStoreRef store; 29 | CFStringRef key, dom; 30 | CFDictionaryRef dict; 31 | uint32_t c, i; 32 | int err = ENOENT; 33 | 34 | if (!nsv || !n) 35 | return EINVAL; 36 | 37 | store = SCDynamicStoreCreate(NULL, CFSTR("get_darwin_dns"), 38 | NULL, &context); 39 | if (!store) 40 | return ENOENT; 41 | 42 | key = CFSTR("State:/Network/Global/DNS"); 43 | dict = SCDynamicStoreCopyValue(store, key); 44 | if (!dict) 45 | goto out1; 46 | 47 | addresses = CFDictionaryGetValue(dict, kSCPropNetDNSServerAddresses); 48 | if (!addresses) 49 | goto out; 50 | 51 | c = (uint32_t)CFArrayGetCount(addresses); 52 | *n = min(*n, c); 53 | 54 | for (i=0; i<*n; i++) { 55 | CFStringRef address = CFArrayGetValueAtIndex(addresses, i); 56 | char str[64]; 57 | 58 | CFStringGetCString(address, str, sizeof(str), 59 | kCFStringEncodingUTF8); 60 | 61 | err = sa_set_str(&nsv[i], str, DNS_PORT); 62 | if (err) 63 | break; 64 | } 65 | 66 | domains = CFDictionaryGetValue(dict, kSCPropNetDNSSearchDomains); 67 | if (!domains) 68 | goto out; 69 | 70 | if (CFArrayGetCount(domains) < 1) 71 | goto out; 72 | 73 | dom = CFArrayGetValueAtIndex(domains, 0); 74 | CFStringGetCString(dom, domain, dsize, kCFStringEncodingUTF8); 75 | 76 | out: 77 | CFRelease(dict); 78 | out1: 79 | CFRelease(store); 80 | 81 | return err; 82 | #endif 83 | } 84 | -------------------------------------------------------------------------------- /src/dns/dns.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file dns.h Internal DNS header file 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | 8 | #ifdef HAVE_RESOLV 9 | int get_resolv_dns(char *domain, size_t dsize, struct sa *nsv, uint32_t *n); 10 | #endif 11 | #ifdef WIN32 12 | int get_windns(char *domain, size_t dsize, struct sa *nav, uint32_t *n); 13 | #endif 14 | #ifdef DARWIN 15 | int get_darwin_dns(char *domain, size_t dsize, struct sa *nsv, uint32_t *n); 16 | #endif 17 | -------------------------------------------------------------------------------- /src/dns/res.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file res.c Get DNS Server IP using resolv 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include "dns.h" 19 | 20 | 21 | int get_resolv_dns(char *domain, size_t dsize, struct sa *nsv, uint32_t *n) 22 | { 23 | struct __res_state state; 24 | uint32_t i; 25 | int ret, err; 26 | 27 | #ifdef OPENBSD 28 | ret = res_init(); 29 | state = _res; 30 | #else 31 | memset(&state, 0, sizeof(state)); 32 | ret = res_ninit(&state); 33 | #endif 34 | if (0 != ret) 35 | return ENOENT; 36 | 37 | if (state.dnsrch[0]) 38 | str_ncpy(domain, state.dnsrch[0], dsize); 39 | else if (str_isset(state.defdname)) 40 | str_ncpy(domain, state.defdname, dsize); 41 | 42 | if (!state.nscount) { 43 | err = ENOENT; 44 | goto out; 45 | } 46 | 47 | err = 0; 48 | #ifdef DARWIN 49 | int memsize = state.nscount * sizeof(union res_sockaddr_union); 50 | union res_sockaddr_union *addr = mem_alloc(memsize, NULL); 51 | int servers = res_getservers(&state, addr, state.nscount); 52 | 53 | for (i = 0; i < min(*n, (uint32_t)servers) && !err; i++) { 54 | if (addr[i].sin.sin_family == AF_INET) 55 | err |= sa_set_sa(&nsv[i], 56 | (struct sockaddr *)&addr[i].sin); 57 | else if (addr[i].sin6.sin6_family == AF_INET6) 58 | err |= sa_set_sa(&nsv[i], 59 | (struct sockaddr *)&addr[i].sin6); 60 | else 61 | (void)re_fprintf(stderr, 62 | "get_resolv_dns: Undefined family.\n"); 63 | } 64 | mem_deref(addr); 65 | #else 66 | for (i=0; i 7 | #include 8 | 9 | 10 | /** 11 | * Convert an ASCII hex character to binary format 12 | * 13 | * @param ch ASCII hex character 14 | * 15 | * @return Binary value 16 | */ 17 | uint8_t ch_hex(char ch) 18 | { 19 | if ('0' <= ch && ch <= '9') 20 | return ch - '0'; 21 | 22 | else if ('A' <= ch && ch <= 'F') 23 | return ch - 'A' + 10; 24 | 25 | else if ('a' <= ch && ch <= 'f') 26 | return ch - 'a' + 10; 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /src/fmt/hexdump.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file hexdump.c Hexadecimal dumping 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | /** 12 | * Hexadecimal dump of binary buffer. Similar output to HEXDUMP(1) 13 | * 14 | * @param f File stream for output (e.g. stderr, stdout) 15 | * @param p Pointer to data 16 | * @param len Number of bytes 17 | */ 18 | void hexdump(FILE *f, const void *p, size_t len) 19 | { 20 | const uint8_t *buf = p; 21 | uint32_t j; 22 | size_t i; 23 | 24 | if (!f || !buf) 25 | return; 26 | 27 | for (i=0; i < len; i += 16) { 28 | 29 | (void)re_fprintf(f, "%08zx ", i); 30 | 31 | for (j=0; j<16; j++) { 32 | const size_t pos = i+j; 33 | if (pos < len) 34 | (void)re_fprintf(f, " %02x", buf[pos]); 35 | else 36 | (void)re_fprintf(f, " "); 37 | 38 | if (j == 7) 39 | (void)re_fprintf(f, " "); 40 | } 41 | 42 | (void)re_fprintf(f, " |"); 43 | 44 | for (j=0; j<16; j++) { 45 | const size_t pos = i+j; 46 | uint8_t v; 47 | if (pos >= len) 48 | break; 49 | v = buf[pos]; 50 | (void)re_fprintf(f, "%c", isprint(v) ? v : '.'); 51 | if (j == 7) 52 | (void)re_fprintf(f, " "); 53 | } 54 | 55 | (void)re_fprintf(f, "|\n"); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/fmt/str_error.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file str_error.c System error messages 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | /** 12 | * Look up an error message string corresponding to an error number. 13 | * 14 | * @param errnum Error Code 15 | * @param buf Buffer for storing error message 16 | * @param sz Buffer size 17 | * 18 | * @return Error message string 19 | */ 20 | const char *str_error(int errnum, char *buf, size_t sz) 21 | { 22 | const char *s; 23 | char msg[128] = {0}; 24 | 25 | if (!buf || !sz) 26 | return NULL; 27 | 28 | #ifdef HAVE_STRERROR_R 29 | 30 | #ifdef __GLIBC__ 31 | s = strerror_r(errnum, msg, sizeof(msg)); 32 | #else 33 | (void)strerror_r(errnum, msg, sizeof(msg)); 34 | s = msg; 35 | #endif 36 | 37 | #elif defined (WIN32) 38 | (void)strerror_s(msg, sizeof(msg), errnum); 39 | s = msg; 40 | #else 41 | /* fallback */ 42 | (void)errnum; 43 | s = "unknown error"; 44 | #endif 45 | 46 | re_snprintf(buf, sz, "%s [%d]", s, errnum); 47 | 48 | return buf; 49 | } 50 | -------------------------------------------------------------------------------- /src/fmt/text2pcap.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | 8 | int re_text2pcap(struct re_printf *pf, struct re_text2pcap *pcap) 9 | { 10 | if (!pcap) 11 | return EINVAL; 12 | 13 | uint8_t *buf = mbuf_buf(pcap->mb); 14 | if (!buf) 15 | return EINVAL; 16 | 17 | re_hprintf(pf, "%s %H 000000", pcap->in ? "I" : "O", fmt_timestamp_us, 18 | NULL); 19 | 20 | size_t sz = mbuf_get_left(pcap->mb); 21 | for (size_t i = 0; i < sz; i++) { 22 | re_hprintf(pf, " %02x", buf[i]); 23 | } 24 | 25 | re_hprintf(pf, " %s", pcap->id); 26 | 27 | return 0; 28 | } 29 | 30 | 31 | void re_text2pcap_trace(const char *name, const char *id, bool in, 32 | const struct mbuf *mb) 33 | { 34 | struct re_text2pcap pcap = {.in = in, .mb = mb, .id = id}; 35 | size_t pcap_buf_sz = (mbuf_get_left(mb) * 3) + 64; 36 | 37 | char *pcap_buf = mem_alloc(pcap_buf_sz, NULL); 38 | if (!pcap_buf) 39 | return; 40 | 41 | (void)re_snprintf(pcap_buf, pcap_buf_sz, "%H", re_text2pcap, &pcap); 42 | 43 | re_trace_event("pcap", name, 'I', NULL, RE_TRACE_ARG_STRING_COPY, 44 | "pcap", pcap_buf); 45 | 46 | mem_deref(pcap_buf); 47 | } 48 | -------------------------------------------------------------------------------- /src/h264/h264.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file h264/h264.h Internal interface 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/hmac/apple/hmac.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file apple/hmac.c HMAC using Apple API 3 | * 4 | * Copyright (C) 2010 - 2015 Creytiv.com 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | 15 | enum { KEY_SIZE = 256 }; 16 | 17 | struct hmac { 18 | CCHmacContext ctx; 19 | uint8_t key[KEY_SIZE]; 20 | size_t key_len; 21 | CCHmacAlgorithm algo; 22 | }; 23 | 24 | 25 | static void destructor(void *arg) 26 | { 27 | struct hmac *hmac = arg; 28 | 29 | memset(&hmac->ctx, 0, sizeof(hmac->ctx)); 30 | } 31 | 32 | 33 | int hmac_create(struct hmac **hmacp, enum hmac_hash hash, 34 | const uint8_t *key, size_t key_len) 35 | { 36 | struct hmac *hmac; 37 | CCHmacAlgorithm algo; 38 | 39 | if (!hmacp || !key || !key_len || key_len > KEY_SIZE) 40 | return EINVAL; 41 | 42 | switch (hash) { 43 | 44 | case HMAC_HASH_SHA1: 45 | algo = kCCHmacAlgSHA1; 46 | break; 47 | 48 | case HMAC_HASH_SHA256: 49 | algo = kCCHmacAlgSHA256; 50 | break; 51 | 52 | default: 53 | return ENOTSUP; 54 | } 55 | 56 | hmac = mem_zalloc(sizeof(*hmac), destructor); 57 | if (!hmac) 58 | return ENOMEM; 59 | 60 | memcpy(hmac->key, key, key_len); 61 | hmac->key_len = key_len; 62 | hmac->algo = algo; 63 | 64 | *hmacp = hmac; 65 | 66 | return 0; 67 | } 68 | 69 | 70 | int hmac_digest(struct hmac *hmac, uint8_t *md, size_t md_len, 71 | const uint8_t *data, size_t data_len) 72 | { 73 | if (!hmac || !md || !md_len || !data || !data_len) 74 | return EINVAL; 75 | 76 | /* reset state */ 77 | CCHmacInit(&hmac->ctx, hmac->algo, hmac->key, hmac->key_len); 78 | 79 | CCHmacUpdate(&hmac->ctx, data, data_len); 80 | CCHmacFinal(&hmac->ctx, md); 81 | 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /src/hmac/hmac.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file hmac/hmac.c HMAC-SHA1 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | 13 | struct hmac { 14 | uint8_t key[SHA_DIGEST_LENGTH]; 15 | size_t key_len; 16 | }; 17 | 18 | 19 | static void destructor(void *arg) 20 | { 21 | struct hmac *hmac = arg; 22 | 23 | memset(hmac, 0, sizeof(*hmac)); 24 | } 25 | 26 | 27 | int hmac_create(struct hmac **hmacp, enum hmac_hash hash, 28 | const uint8_t *key, size_t key_len) 29 | { 30 | struct hmac *hmac; 31 | 32 | if (!hmacp || !key || !key_len) 33 | return EINVAL; 34 | 35 | if (hash != HMAC_HASH_SHA1) 36 | return ENOTSUP; 37 | 38 | if (key_len > SHA_DIGEST_LENGTH) 39 | return EINVAL; 40 | 41 | hmac = mem_zalloc(sizeof(*hmac), destructor); 42 | if (!hmac) 43 | return ENOMEM; 44 | 45 | memcpy(hmac->key, key, key_len); 46 | hmac->key_len = key_len; 47 | 48 | *hmacp = hmac; 49 | 50 | return 0; 51 | } 52 | 53 | 54 | int hmac_digest(struct hmac *hmac, uint8_t *md, size_t md_len, 55 | const uint8_t *data, size_t data_len) 56 | { 57 | if (!hmac || !md || !md_len || !data || !data_len) 58 | return EINVAL; 59 | 60 | hmac_sha1(hmac->key, hmac->key_len, data, data_len, md, md_len); 61 | 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /src/hmac/openssl/hmac.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file openssl/hmac.c HMAC using OpenSSL 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | * Copyright (C) 2022 Sebastian Reimers 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | 16 | struct hmac { 17 | const EVP_MD *evp; 18 | uint8_t *key; 19 | int key_len; 20 | }; 21 | 22 | 23 | static void destructor(void *arg) 24 | { 25 | struct hmac *hmac = arg; 26 | 27 | mem_deref(hmac->key); 28 | } 29 | 30 | 31 | int hmac_create(struct hmac **hmacp, enum hmac_hash hash, const uint8_t *key, 32 | size_t key_len) 33 | { 34 | struct hmac *hmac; 35 | int err = 0; 36 | 37 | if (!hmacp || !key || !key_len) 38 | return EINVAL; 39 | 40 | hmac = mem_zalloc(sizeof(*hmac), destructor); 41 | if (!hmac) 42 | return ENOMEM; 43 | 44 | hmac->key = mem_zalloc(key_len, NULL); 45 | if (!hmac->key) { 46 | err = ENOMEM; 47 | goto error; 48 | } 49 | 50 | memcpy(hmac->key, key, key_len); 51 | hmac->key_len = (int)key_len; 52 | 53 | switch (hash) { 54 | 55 | case HMAC_HASH_SHA1: 56 | hmac->evp = EVP_sha1(); 57 | break; 58 | 59 | case HMAC_HASH_SHA256: 60 | hmac->evp = EVP_sha256(); 61 | break; 62 | 63 | default: 64 | err = ENOTSUP; 65 | goto error; 66 | } 67 | 68 | *hmacp = hmac; 69 | 70 | return 0; 71 | 72 | error: 73 | mem_deref(hmac); 74 | return err; 75 | } 76 | 77 | 78 | int hmac_digest(struct hmac *hmac, uint8_t *md, size_t md_len, 79 | const uint8_t *data, size_t data_len) 80 | { 81 | unsigned int len = (unsigned int)md_len; 82 | unsigned char *rval; 83 | 84 | if (!hmac || !md || !md_len || !data || !data_len) 85 | return EINVAL; 86 | 87 | rval = HMAC(hmac->evp, hmac->key, hmac->key_len, data, data_len, md, 88 | &len); 89 | if (!rval) { 90 | ERR_clear_error(); 91 | return EPROTO; 92 | } 93 | 94 | return 0; 95 | } 96 | -------------------------------------------------------------------------------- /src/http/chunk.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file http/chunk.c Chunked Transfer Encoding 3 | * 4 | * Copyright (C) 2011 Creytiv.com 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include "http.h" 11 | 12 | 13 | static int decode_chunk_size(struct http_chunk *chunk, struct mbuf *mb) 14 | { 15 | while (mbuf_get_left(mb)) { 16 | 17 | char ch = (char)mbuf_read_u8(mb); 18 | uint8_t c; 19 | 20 | if (ch == '\n') { 21 | if (chunk->digit) { 22 | chunk->digit = false; 23 | chunk->param = false; 24 | 25 | return 0; 26 | } 27 | else 28 | continue; 29 | } 30 | 31 | if (chunk->param) 32 | continue; 33 | 34 | if ('0' <= ch && ch <= '9') 35 | c = ch - '0'; 36 | else if ('A' <= ch && ch <= 'F') 37 | c = ch - 'A' + 10; 38 | else if ('a' <= ch && ch <= 'f') 39 | c = ch - 'a' + 10; 40 | else if (ch == '\r' || ch == ' ' || ch == '\t') 41 | continue; 42 | else if (ch == ';' && chunk->digit) { 43 | chunk->param = true; 44 | continue; 45 | } 46 | else 47 | return EPROTO; 48 | 49 | chunk->digit = true; 50 | 51 | chunk->size <<= 4; 52 | chunk->size += c; 53 | } 54 | 55 | return ENODATA; 56 | } 57 | 58 | 59 | static int decode_trailer(struct http_chunk *chunk, struct mbuf *mb) 60 | { 61 | while (mbuf_get_left(mb)) { 62 | 63 | char ch = (char)mbuf_read_u8(mb); 64 | 65 | if (ch == '\n') { 66 | if (++chunk->lf >= 2) 67 | return 0; 68 | } 69 | else if (ch != '\r') 70 | chunk->lf = 0; 71 | } 72 | 73 | return ENODATA; 74 | } 75 | 76 | 77 | int http_chunk_decode(struct http_chunk *chunk, struct mbuf *mb, size_t *size) 78 | { 79 | int err; 80 | 81 | if (!chunk || !mb || !size) 82 | return EINVAL; 83 | 84 | if (chunk->trailer) { 85 | err = decode_trailer(chunk, mb); 86 | if (err) 87 | return err; 88 | 89 | *size = 0; 90 | 91 | return 0; 92 | } 93 | 94 | err = decode_chunk_size(chunk, mb); 95 | if (err) 96 | return err; 97 | 98 | if (chunk->size == 0) { 99 | chunk->trailer = true; 100 | chunk->lf = 1; 101 | 102 | err = decode_trailer(chunk, mb); 103 | if (err) 104 | return err; 105 | } 106 | 107 | *size = chunk->size; 108 | chunk->size = 0; 109 | 110 | return 0; 111 | } 112 | -------------------------------------------------------------------------------- /src/http/http.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file http.h HTTP Private Interface 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | 8 | struct http_chunk { 9 | size_t size; 10 | unsigned lf; 11 | bool trailer; 12 | bool digit; 13 | bool param; 14 | }; 15 | 16 | 17 | int http_chunk_decode(struct http_chunk *chunk, struct mbuf *mb, size_t *size); 18 | -------------------------------------------------------------------------------- /src/ice/icestr.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file icestr.c ICE Strings 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "ice.h" 15 | 16 | 17 | const char *ice_cand_type2name(enum ice_cand_type type) 18 | { 19 | switch (type) { 20 | 21 | case ICE_CAND_TYPE_HOST: return "host"; 22 | case ICE_CAND_TYPE_SRFLX: return "srflx"; 23 | case ICE_CAND_TYPE_PRFLX: return "prflx"; 24 | case ICE_CAND_TYPE_RELAY: return "relay"; 25 | default: return "???"; 26 | } 27 | } 28 | 29 | 30 | enum ice_cand_type ice_cand_name2type(const char *name) 31 | { 32 | if (0 == str_casecmp(name, "host")) return ICE_CAND_TYPE_HOST; 33 | if (0 == str_casecmp(name, "srflx")) return ICE_CAND_TYPE_SRFLX; 34 | if (0 == str_casecmp(name, "prflx")) return ICE_CAND_TYPE_PRFLX; 35 | if (0 == str_casecmp(name, "relay")) return ICE_CAND_TYPE_RELAY; 36 | 37 | return (enum ice_cand_type)-1; 38 | } 39 | 40 | 41 | const char *ice_role2name(enum ice_role role) 42 | { 43 | switch (role) { 44 | 45 | case ICE_ROLE_UNKNOWN: return "Unknown"; 46 | case ICE_ROLE_CONTROLLING: return "Controlling"; 47 | case ICE_ROLE_CONTROLLED: return "Controlled"; 48 | default: return "???"; 49 | } 50 | } 51 | 52 | 53 | const char *ice_candpair_state2name(enum ice_candpair_state st) 54 | { 55 | switch (st) { 56 | 57 | case ICE_CANDPAIR_FROZEN: return "Frozen"; 58 | case ICE_CANDPAIR_WAITING: return "Waiting"; 59 | case ICE_CANDPAIR_INPROGRESS: return "InProgress"; 60 | case ICE_CANDPAIR_SUCCEEDED: return "Succeeded"; 61 | case ICE_CANDPAIR_FAILED: return "Failed"; 62 | default: return "???"; 63 | } 64 | } 65 | 66 | 67 | const char *ice_checkl_state2name(enum ice_checkl_state cst) 68 | { 69 | switch (cst) { 70 | 71 | case ICE_CHECKLIST_NULL: return "(NULL)"; 72 | case ICE_CHECKLIST_RUNNING: return "Running"; 73 | case ICE_CHECKLIST_COMPLETED: return "Completed"; 74 | case ICE_CHECKLIST_FAILED: return "Failed"; 75 | default: return "???"; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/json/encode.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file json/encode.c JSON encoder 3 | * 4 | * Copyright (C) 2010 - 2015 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | 13 | static int encode_entry(struct re_printf *pf, const struct odict_entry *e) 14 | { 15 | struct odict *array; 16 | struct le *le; 17 | int err; 18 | 19 | if (!e) 20 | return 0; 21 | 22 | switch (odict_entry_type(e)) { 23 | 24 | case ODICT_OBJECT: 25 | err = json_encode_odict(pf, odict_entry_object(e)); 26 | break; 27 | 28 | case ODICT_ARRAY: 29 | array = odict_entry_array(e); 30 | if (!array) 31 | return 0; 32 | 33 | err = re_hprintf(pf, "["); 34 | 35 | for (le=array->lst.head; le; le=le->next) { 36 | 37 | const struct odict_entry *ae = le->data; 38 | 39 | err |= re_hprintf(pf, "%H%s", 40 | encode_entry, ae, 41 | le->next ? "," : ""); 42 | } 43 | 44 | err |= re_hprintf(pf, "]"); 45 | break; 46 | 47 | case ODICT_INT: 48 | err = re_hprintf(pf, "%lld", odict_entry_int(e)); 49 | break; 50 | 51 | case ODICT_DOUBLE: 52 | err = re_hprintf(pf, "%f", odict_entry_dbl(e)); 53 | break; 54 | 55 | case ODICT_STRING: 56 | err = re_hprintf(pf, "\"%H\"", utf8_encode, 57 | odict_entry_str(e)); 58 | break; 59 | 60 | case ODICT_BOOL: 61 | err = re_hprintf(pf, "%s", 62 | odict_entry_boolean(e) ? "true" : "false"); 63 | break; 64 | 65 | case ODICT_NULL: 66 | err = re_hprintf(pf, "null"); 67 | break; 68 | 69 | default: 70 | re_fprintf(stderr, "json: unsupported type %d\n", 71 | odict_entry_type(e)); 72 | err = EINVAL; 73 | } 74 | 75 | return err; 76 | } 77 | 78 | 79 | int json_encode_odict(struct re_printf *pf, const struct odict *o) 80 | { 81 | struct le *le; 82 | int err; 83 | 84 | if (!o) 85 | return 0; 86 | 87 | err = re_hprintf(pf, "{"); 88 | 89 | for (le=o->lst.head; le; le=le->next) { 90 | 91 | const struct odict_entry *e = le->data; 92 | 93 | err |= re_hprintf(pf, "\"%H\":%H%s", 94 | utf8_encode, odict_entry_key(e), 95 | encode_entry, e, 96 | le->next ? "," : ""); 97 | } 98 | 99 | err |= re_hprintf(pf, "}"); 100 | 101 | return err; 102 | } 103 | -------------------------------------------------------------------------------- /src/main/main.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file main.h Internal interface to main polling loop 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | #ifdef USE_OPENSSL 13 | int openssl_init(void); 14 | #endif 15 | 16 | #ifdef __cplusplus 17 | } 18 | #endif 19 | -------------------------------------------------------------------------------- /src/main/method.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file method.c Polling methods 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "main.h" 12 | 13 | 14 | static const char str_select[] = "select"; /**< POSIX.1-2001 select */ 15 | static const char str_epoll[] = "epoll"; /**< Linux epoll */ 16 | static const char str_kqueue[] = "kqueue"; 17 | 18 | 19 | /** 20 | * Choose the best async I/O polling method 21 | * 22 | * @return Polling method 23 | */ 24 | enum poll_method poll_method_best(void) 25 | { 26 | #ifdef HAVE_EPOLL 27 | /* Supported from Linux 2.5.66 */ 28 | return METHOD_EPOLL; 29 | #endif 30 | 31 | #ifdef HAVE_KQUEUE 32 | return METHOD_KQUEUE; 33 | #endif 34 | 35 | #ifdef HAVE_SELECT 36 | return METHOD_SELECT; 37 | #endif 38 | 39 | return METHOD_NULL; 40 | } 41 | 42 | 43 | /** 44 | * Get the name of the polling method 45 | * 46 | * @param method Polling method 47 | * 48 | * @return Polling name string 49 | */ 50 | const char *poll_method_name(enum poll_method method) 51 | { 52 | switch (method) { 53 | 54 | case METHOD_SELECT: return str_select; 55 | case METHOD_EPOLL: return str_epoll; 56 | case METHOD_KQUEUE: return str_kqueue; 57 | default: return "???"; 58 | } 59 | } 60 | 61 | 62 | /** 63 | * Get the polling method type from a string 64 | * 65 | * @param method Returned polling method 66 | * @param name Polling method name string 67 | * 68 | * @return 0 if success, otherwise errorcode 69 | */ 70 | int poll_method_type(enum poll_method *method, const struct pl *name) 71 | { 72 | if (!method || !name) 73 | return EINVAL; 74 | 75 | if (0 == pl_strcasecmp(name, str_select)) 76 | *method = METHOD_SELECT; 77 | else if (0 == pl_strcasecmp(name, str_epoll)) 78 | *method = METHOD_EPOLL; 79 | else if (0 == pl_strcasecmp(name, str_kqueue)) 80 | *method = METHOD_KQUEUE; 81 | else 82 | return ENOENT; 83 | 84 | return 0; 85 | } 86 | -------------------------------------------------------------------------------- /src/main/openssl.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file openssl.c OpenSSL initialisation and multi-threading routines 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #ifdef HAVE_SIGNAL 7 | #include 8 | #endif 9 | #include 10 | #include "main.h" 11 | 12 | 13 | #ifdef SIGPIPE 14 | static void sigpipe_handler(int x) 15 | { 16 | (void)x; 17 | (void)signal(SIGPIPE, sigpipe_handler); 18 | } 19 | #endif 20 | 21 | 22 | int openssl_init(void) 23 | { 24 | #ifdef SIGPIPE 25 | (void)signal(SIGPIPE, sigpipe_handler); 26 | #endif 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /src/mem/secure.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file mem/secure.c Secure memory functions 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #if !defined(__GNUC__) && defined(WIN32) 11 | #if !defined(WIN32_LEAN_AND_MEAN) 12 | #define WIN32_LEAN_AND_MEAN 13 | #endif 14 | #include 15 | #endif /* !defined(__GNUC__) && defined(WIN32) */ 16 | 17 | /** 18 | * Compare two byte strings in constant time. This function can be used 19 | * by secure code to compare secret data, such as authentication tags, 20 | * to avoid side-channel attacks. 21 | * 22 | * @param s1 First byte string 23 | * @param s2 Second byte string 24 | * @param n Number of bytes 25 | * 26 | * @return a negative number if argument errors 27 | * 0 if both byte strings matching 28 | * a positive number if not matching 29 | */ 30 | int mem_seccmp(const uint8_t *s1, const uint8_t *s2, size_t n) 31 | { 32 | uint8_t val = 0; 33 | const volatile uint8_t *p1 = s1; 34 | const volatile uint8_t *p2 = s2; 35 | 36 | if (!p1 || !p2) 37 | return -1; 38 | 39 | while (n--) 40 | val |= *p1++ ^ *p2++; 41 | 42 | return val; 43 | } 44 | 45 | 46 | #if !defined(__GNUC__) && !defined(WIN32) 47 | /* Use a volatile pointer to memset to force the compiler always 48 | * call it and not optimize away. */ 49 | typedef void *(memset_t)(void *, int, size_t); 50 | static memset_t *const volatile memset_ptr = &memset; 51 | #endif 52 | 53 | /** 54 | * Securely clean memory. This function is guaranteed not to get optimized 55 | * away by compiler. 56 | * 57 | * @param data Pointer to data buffer 58 | * @param size Size of the buffer 59 | */ 60 | void mem_secclean(void *data, size_t size) 61 | { 62 | #if defined(__GNUC__) 63 | memset(data, 0, size); 64 | /* Insert an asm statement that may potentially depend 65 | * on the memory contents that were affected by memset. 66 | * This prevents optimizing away the memset. */ 67 | __asm__ __volatile__("" : : "r" (data), "r" (size) : "memory"); 68 | #elif defined(WIN32) 69 | SecureZeroMemory(data, size); 70 | #else 71 | (*memset_ptr)(data, 0, size); 72 | #endif 73 | } 74 | -------------------------------------------------------------------------------- /src/mod/dl.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file dl.c Interface to dynamic linking loader 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include "mod_internal.h" 10 | 11 | 12 | #define DEBUG_MODULE "dl" 13 | #define DEBUG_LEVEL 5 14 | #include 15 | 16 | 17 | static const int dl_flag = RTLD_NOW | RTLD_LOCAL; 18 | 19 | 20 | /** 21 | * Load a dynamic library file 22 | * 23 | * @param name Name of library to load 24 | * 25 | * @return Opaque library handle, NULL if not loaded 26 | */ 27 | void *_mod_open(const char *name) 28 | { 29 | void *h; 30 | 31 | if (!name) 32 | return NULL; 33 | 34 | h = dlopen(name, dl_flag); 35 | if (!h) { 36 | DEBUG_WARNING("mod: %s (%s)\n", name, dlerror()); 37 | return NULL; 38 | } 39 | 40 | return h; 41 | } 42 | 43 | 44 | /** 45 | * Resolve address of symbol in dynamic library 46 | * 47 | * @param h Library handle 48 | * @param symbol Name of symbol to resolve 49 | * 50 | * @return Address, NULL if failure 51 | */ 52 | void *_mod_sym(void *h, const char *symbol) 53 | { 54 | void *sym; 55 | const char *err; 56 | 57 | if (!h || !symbol) 58 | return NULL; 59 | 60 | (void)dlerror(); /* Clear any existing error */ 61 | 62 | sym = dlsym(h, symbol); 63 | err = dlerror(); 64 | if (err) { 65 | DEBUG_WARNING("dlsym: %s\n", err); 66 | return NULL; 67 | } 68 | 69 | return sym; 70 | } 71 | 72 | 73 | /** 74 | * Unload a dynamic library 75 | * 76 | * @param h Library handle 77 | */ 78 | void _mod_close(void *h) 79 | { 80 | int err; 81 | 82 | if (!h) 83 | return; 84 | 85 | err = dlclose(h); 86 | if (0 != err) { 87 | DEBUG_WARNING("dlclose: %d\n", err); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/mod/mod_internal.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file mod_internal.h Internal interface to loadable module 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | 13 | void *_mod_open(const char *name); 14 | void *_mod_sym(void *h, const char *symbol); 15 | void _mod_close(void *h); 16 | 17 | 18 | #ifdef __cplusplus 19 | } 20 | #endif 21 | -------------------------------------------------------------------------------- /src/mod/win32/dll.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file dll.c Dynamic library loading for Windows 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include "../mod_internal.h" 9 | 10 | 11 | #define DEBUG_MODULE "dll" 12 | #define DEBUG_LEVEL 5 13 | #include 14 | 15 | 16 | /* 17 | * Open a DLL file 18 | * 19 | * @param name Name of DLL to open 20 | * 21 | * @return Handle (NULL if failed) 22 | */ 23 | void *_mod_open(const char *name) 24 | { 25 | HINSTANCE DllHandle = 0; 26 | 27 | DEBUG_INFO("loading %s\n", name); 28 | 29 | DllHandle = LoadLibraryA(name); 30 | if (!DllHandle) { 31 | DEBUG_WARNING("open: %s LoadLibraryA() failed\n", name); 32 | return NULL; 33 | } 34 | 35 | return DllHandle; 36 | } 37 | 38 | 39 | /* 40 | * Resolve a symbol address in a DLL 41 | * 42 | * @param h DLL Handle 43 | * @param symbol Symbol to resolve 44 | * 45 | * @return Address of symbol 46 | */ 47 | void *_mod_sym(void *h, const char *symbol) 48 | { 49 | HINSTANCE DllHandle = (HINSTANCE)h; 50 | union { 51 | FARPROC sym; 52 | void *ptr; 53 | } u; 54 | 55 | if (!DllHandle) 56 | return NULL; 57 | 58 | DEBUG_INFO("get symbol: %s\n", symbol); 59 | 60 | u.sym = GetProcAddress(DllHandle, symbol); 61 | if (!u.sym) { 62 | DEBUG_WARNING("GetProcAddress: no symbol %s\n", symbol); 63 | return NULL; 64 | } 65 | 66 | return u.ptr; 67 | } 68 | 69 | 70 | /* 71 | * Close a DLL 72 | * 73 | * @param h DLL Handle 74 | */ 75 | void _mod_close(void *h) 76 | { 77 | HINSTANCE DllHandle = (HINSTANCE)h; 78 | 79 | DEBUG_INFO("unloading %p\n", h); 80 | 81 | if (!DllHandle) 82 | return; 83 | 84 | FreeLibrary(DllHandle); 85 | } 86 | -------------------------------------------------------------------------------- /src/mqueue/mqueue.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file mqueue.h Thread Safe Message Queue -- Internal API 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | 8 | #ifdef WIN32 9 | int pipe(re_sock_t fds[2]); 10 | ssize_t pipe_read(re_sock_t s, void *buf, size_t len); 11 | ssize_t pipe_write(re_sock_t s, const void *buf, size_t len); 12 | #else 13 | static inline ssize_t pipe_read(re_sock_t s, void *buf, size_t len) 14 | { 15 | return read(s, buf, len); 16 | } 17 | 18 | 19 | static inline ssize_t pipe_write(re_sock_t s, const void *buf, size_t len) 20 | { 21 | return write(s, buf, len); 22 | } 23 | #endif 24 | -------------------------------------------------------------------------------- /src/mqueue/win32/pipe.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file pipe.c Pipe-emulation for Windows 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "../mqueue.h" 11 | 12 | 13 | /* 14 | * Emulate pipe on Windows -- pipe() with select() is not working 15 | */ 16 | int pipe(re_sock_t fds[2]) 17 | { 18 | SOCKET s, rd, wr; 19 | struct sockaddr_in serv_addr; 20 | int len = sizeof(serv_addr); 21 | 22 | if ((s = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) 23 | return ENOSYS; 24 | 25 | memset((void *) &serv_addr, 0, sizeof(serv_addr)); 26 | serv_addr.sin_family = AF_INET; 27 | serv_addr.sin_port = htons(0); 28 | serv_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 29 | if (bind(s, (SOCKADDR *) & serv_addr, len) == SOCKET_ERROR) 30 | goto error; 31 | 32 | if (listen(s, 1) == SOCKET_ERROR) 33 | goto error; 34 | 35 | if (getsockname(s, (SOCKADDR *) &serv_addr, &len) == SOCKET_ERROR) 36 | goto error; 37 | 38 | if ((wr = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) 39 | goto error; 40 | 41 | if (connect(wr, (SOCKADDR *) &serv_addr, len) == SOCKET_ERROR) { 42 | closesocket(wr); 43 | goto error; 44 | } 45 | 46 | rd = accept(s, (SOCKADDR *) &serv_addr, &len); 47 | if (rd == INVALID_SOCKET) { 48 | closesocket(wr); 49 | goto error; 50 | } 51 | 52 | fds[0] = rd; 53 | fds[1] = wr; 54 | 55 | closesocket(s); 56 | return 0; 57 | 58 | error: 59 | closesocket(s); 60 | return ENOSYS; 61 | } 62 | 63 | 64 | ssize_t pipe_read(re_sock_t s, void *buf, size_t len) 65 | { 66 | int ret = recv(s, buf, (int)len, 0); 67 | 68 | if (ret < 0 && WSAGetLastError() == WSAECONNRESET) 69 | ret = 0; 70 | 71 | return ret; 72 | } 73 | 74 | 75 | ssize_t pipe_write(re_sock_t s, const void *buf, size_t len) 76 | { 77 | return send(s, buf, (int)len, 0); 78 | } 79 | 80 | -------------------------------------------------------------------------------- /src/msg/ctype.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file ctype.c Content-Type decode 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | /** 12 | * Decode a pointer-length string into Content-Type header 13 | * 14 | * @param ctype Content-Type header 15 | * @param pl Pointer-length string 16 | * 17 | * @return 0 for success, otherwise errorcode 18 | */ 19 | int msg_ctype_decode(struct msg_ctype *ctype, const struct pl *pl) 20 | { 21 | struct pl ws; 22 | 23 | if (!ctype || !pl) 24 | return EINVAL; 25 | 26 | if (re_regex(pl->p, pl->l, 27 | "[ \t\r\n]*[^ \t\r\n;/]+[ \t\r\n]*/[ \t\r\n]*[^ \t\r\n;]+" 28 | "[^]*", 29 | &ws, &ctype->type, NULL, NULL, &ctype->subtype, 30 | &ctype->params)) 31 | return EBADMSG; 32 | 33 | if (ws.p != pl->p) 34 | return EBADMSG; 35 | 36 | return 0; 37 | } 38 | 39 | 40 | /** 41 | * Compare Content-Type 42 | * 43 | * @param ctype Content-Type header 44 | * @param type Media type 45 | * @param subtype Media sub-type 46 | * 47 | * @return true if match, false if no match 48 | */ 49 | bool msg_ctype_cmp(const struct msg_ctype *ctype, 50 | const char *type, const char *subtype) 51 | { 52 | if (!ctype || !type || !subtype) 53 | return false; 54 | 55 | if (pl_strcasecmp(&ctype->type, type)) 56 | return false; 57 | 58 | if (pl_strcasecmp(&ctype->subtype, subtype)) 59 | return false; 60 | 61 | return true; 62 | } 63 | -------------------------------------------------------------------------------- /src/msg/param.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file param.c SIP Parameter decode 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | /** 12 | * Check if a parameter exists 13 | * 14 | * @param pl Pointer-length string 15 | * @param name Parameter name 16 | * @param val Returned parameter value 17 | * 18 | * @return 0 for success, otherwise errorcode 19 | */ 20 | int msg_param_exists(const struct pl *pl, const char *name, struct pl *val) 21 | { 22 | struct pl v1, v2; 23 | char xpr[128]; 24 | 25 | if (!pl || !name || !val) 26 | return EINVAL; 27 | 28 | (void)re_snprintf(xpr, sizeof(xpr), ";[ \t\r\n]*%s[ \t\r\n;=]*", name); 29 | 30 | if (re_regex(pl->p, pl->l, xpr, &v1, &v2)) 31 | return ENOENT; 32 | 33 | if (!v2.l && v2.p < pl->p + pl->l) 34 | return ENOENT; 35 | 36 | val->p = v1.p - 1; 37 | val->l = v2.p - val->p; 38 | 39 | return 0; 40 | } 41 | 42 | 43 | /** 44 | * Decode a Parameter 45 | * 46 | * @param pl Pointer-length string 47 | * @param name Parameter name 48 | * @param val Returned parameter value 49 | * 50 | * @return 0 for success, otherwise errorcode 51 | */ 52 | int msg_param_decode(const struct pl *pl, const char *name, struct pl *val) 53 | { 54 | char expr[128]; 55 | struct pl v; 56 | 57 | if (!pl || !name || !val) 58 | return EINVAL; 59 | 60 | (void)re_snprintf(expr, sizeof(expr), 61 | ";[ \t\r\n]*%s[ \t\r\n]*=[ \t\r\n]*[~ \t\r\n;]+", 62 | name); 63 | 64 | if (re_regex(pl->p, pl->l, expr, NULL, NULL, NULL, &v)) 65 | return ENOENT; 66 | 67 | *val = v; 68 | 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /src/net/ifaddrs.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file ifaddrs.c Network interface code using getifaddrs(). 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | 16 | #define DEBUG_MODULE "ifaddrs" 17 | #define DEBUG_LEVEL 5 18 | #include 19 | 20 | 21 | /** 22 | * Get a list of all network interfaces including name and IP address. 23 | * Both IPv4 and IPv6 are supported. 24 | * 25 | * @param ifh Interface handler, called once per network interface. 26 | * @param arg Handler argument. 27 | * 28 | * @return 0 if success, otherwise errorcode. 29 | */ 30 | int net_getifaddrs(net_ifaddr_h *ifh, void *arg) 31 | { 32 | struct ifaddrs *ifa, *ifp; 33 | int err; 34 | 35 | if (!ifh) 36 | return EINVAL; 37 | 38 | if (0 != getifaddrs(&ifa)) { 39 | err = errno; 40 | DEBUG_WARNING("getifaddrs: %m\n", err); 41 | return err; 42 | } 43 | 44 | for (ifp = ifa; ifa; ifa = ifa->ifa_next) { 45 | struct sa sa; 46 | 47 | DEBUG_INFO("ifaddr: %10s flags=%08x\n", ifa->ifa_name, 48 | ifa->ifa_flags); 49 | 50 | if (ifa->ifa_flags & IFF_UP) { 51 | err = sa_set_sa(&sa, ifa->ifa_addr); 52 | if (err) 53 | continue; 54 | 55 | if (ifh(ifa->ifa_name, &sa, arg)) 56 | break; 57 | } 58 | } 59 | 60 | freeifaddrs(ifp); 61 | 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /src/net/linux/macros.h: -------------------------------------------------------------------------------- 1 | /* Override macros to avoid casting alignment warning */ 2 | #undef RTM_RTA 3 | #define RTM_RTA(r) (void *)(((char *)(r)) + NLMSG_ALIGN(sizeof(struct rtmsg))) 4 | #undef RTA_NEXT 5 | #define RTA_NEXT(rta, len) \ 6 | ((len) -= RTA_ALIGN((rta)->rta_len), \ 7 | (void *)(((char *)(rta)) + RTA_ALIGN((rta)->rta_len))) 8 | #undef NLMSG_NEXT 9 | #define NLMSG_NEXT(nlh, len) \ 10 | ((len) -= NLMSG_ALIGN((nlh)->nlmsg_len), \ 11 | (void *)(((char *)(nlh)) + NLMSG_ALIGN((nlh)->nlmsg_len))) 12 | #undef IFA_RTA 13 | #define IFA_RTA(r) \ 14 | ((void *)(((char *)(r)) + NLMSG_ALIGN(sizeof(struct ifaddrmsg)))) 15 | -------------------------------------------------------------------------------- /src/net/netstr.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file netstr.c Network strings 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | /** 12 | * Get the name of a protocol 13 | * 14 | * @param proto Protocol 15 | * 16 | * @return Protocol name 17 | */ 18 | const char *net_proto2name(int proto) 19 | { 20 | switch (proto) { 21 | 22 | case IPPROTO_UDP: return "UDP"; 23 | case IPPROTO_TCP: return "TCP"; 24 | #ifdef IPPROTO_SCTP 25 | case IPPROTO_SCTP: return "SCTP"; 26 | #endif 27 | default: return "???"; 28 | } 29 | } 30 | 31 | 32 | /** 33 | * Get the name of a address family 34 | * 35 | * @param af Address family 36 | * 37 | * @return Address family name 38 | */ 39 | const char *net_af2name(int af) 40 | { 41 | switch (af) { 42 | 43 | case AF_UNSPEC: return "AF_UNSPEC"; 44 | case AF_INET: return "AF_INET"; 45 | case AF_INET6: return "AF_INET6"; 46 | default: return "???"; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/net/sock.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file net/sock.c Networking sockets code 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | 12 | #define DEBUG_MODULE "netsock" 13 | #define DEBUG_LEVEL 5 14 | #include 15 | 16 | 17 | static bool inited = false; 18 | 19 | 20 | #ifdef WIN32 21 | static int wsa_init(void) 22 | { 23 | WORD wVersionRequested = MAKEWORD(2, 2); 24 | WSADATA wsaData; 25 | int err; 26 | 27 | err = WSAStartup(wVersionRequested, &wsaData); 28 | if (err != 0) { 29 | DEBUG_WARNING("Could not load winsock (%m)\n", err); 30 | return err; 31 | } 32 | 33 | /* Confirm that the WinSock DLL supports 2.2.*/ 34 | /* Note that if the DLL supports versions greater */ 35 | /* than 2.2 in addition to 2.2, it will still return */ 36 | /* 2.2 in wVersion since that is the version we */ 37 | /* requested. */ 38 | if (LOBYTE(wsaData.wVersion) != 2 || 39 | HIBYTE(wsaData.wVersion) != 2 ) { 40 | WSACleanup(); 41 | DEBUG_WARNING("Bad winsock version (%d.%d)\n", 42 | HIBYTE(wsaData.wVersion), 43 | LOBYTE(wsaData.wVersion)); 44 | return EINVAL; 45 | } 46 | 47 | return 0; 48 | } 49 | #endif 50 | 51 | 52 | /** 53 | * Initialise network sockets 54 | * 55 | * @return 0 if success, otherwise errorcode 56 | */ 57 | int net_sock_init(void) 58 | { 59 | int err = 0; 60 | 61 | DEBUG_INFO("sock init: inited=%d\n", inited); 62 | 63 | if (inited) 64 | return 0; 65 | 66 | #ifdef WIN32 67 | err = wsa_init(); 68 | #endif 69 | 70 | inited = true; 71 | 72 | return err; 73 | } 74 | 75 | 76 | /** 77 | * Cleanup network sockets 78 | */ 79 | void net_sock_close(void) 80 | { 81 | #ifdef WIN32 82 | const int err = WSACleanup(); 83 | if (0 != err) { 84 | DEBUG_WARNING("sock close: WSACleanup (%d)\n", err); 85 | } 86 | #endif 87 | 88 | inited = false; 89 | 90 | DEBUG_INFO("sock close\n"); 91 | } 92 | -------------------------------------------------------------------------------- /src/odict/odict.h: -------------------------------------------------------------------------------- 1 | struct odict_entry { 2 | struct le le, he; 3 | char *key; 4 | union { 5 | struct odict *odict; /* ODICT_OBJECT / ODICT_ARRAY */ 6 | char *str; /* ODICT_STRING */ 7 | int64_t integer; /* ODICT_INT */ 8 | double dbl; /* ODICT_DOUBLE */ 9 | bool boolean; /* ODICT_BOOL */ 10 | } u; 11 | enum odict_type type; 12 | }; 13 | -------------------------------------------------------------------------------- /src/odict/type.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file type.c Ordered Dictionary -- value types 3 | * 4 | * Copyright (C) 2010 - 2015 Creytiv.com 5 | */ 6 | 7 | #include "re_types.h" 8 | #include "re_fmt.h" 9 | #include "re_mem.h" 10 | #include "re_list.h" 11 | #include "re_hash.h" 12 | #include "re_odict.h" 13 | 14 | 15 | bool odict_type_iscontainer(enum odict_type type) 16 | { 17 | switch (type) { 18 | 19 | case ODICT_OBJECT: 20 | case ODICT_ARRAY: 21 | return true; 22 | 23 | default: 24 | return false; 25 | } 26 | } 27 | 28 | 29 | bool odict_type_isreal(enum odict_type type) 30 | { 31 | switch (type) { 32 | 33 | case ODICT_STRING: 34 | case ODICT_INT: 35 | case ODICT_DOUBLE: 36 | case ODICT_BOOL: 37 | case ODICT_NULL: 38 | return true; 39 | 40 | default: 41 | return false; 42 | } 43 | } 44 | 45 | 46 | const char *odict_type_name(enum odict_type type) 47 | { 48 | switch (type) { 49 | 50 | case ODICT_OBJECT: return "Object"; 51 | case ODICT_ARRAY: return "Array"; 52 | case ODICT_STRING: return "String"; 53 | case ODICT_INT: return "Integer"; 54 | case ODICT_DOUBLE: return "Double"; 55 | case ODICT_BOOL: return "Boolean"; 56 | case ODICT_NULL: return "Null"; 57 | default: return "???"; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/pcp/README: -------------------------------------------------------------------------------- 1 | PCP README: 2 | ---------- 3 | 4 | Port Control Protocol (PCP) as of RFC 6887 5 | 6 | 7 | 8 | 9 | other PCP implementations: 10 | 11 | https://github.com/libpcp/pcp 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/pcp/pcp.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file pcp/pcp.h PCP protocol -- Internal interface 3 | * 4 | * Copyright (C) 2010 - 2016 Alfred E. Heggestad 5 | */ 6 | 7 | 8 | int pcp_payload_encode(struct mbuf *mb, enum pcp_opcode opcode, 9 | const union pcp_payload *pld); 10 | -------------------------------------------------------------------------------- /src/rtmp/chunk.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file rtmp/chunk.c Real Time Messaging Protocol (RTMP) -- Chunking 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include "rtmp.h" 17 | 18 | 19 | /* 20 | * Stateless RTMP chunker 21 | */ 22 | int rtmp_chunker(unsigned format, uint32_t chunk_id, 23 | uint32_t timestamp, uint32_t timestamp_delta, 24 | uint8_t msg_type_id, uint32_t msg_stream_id, 25 | const uint8_t *payload, size_t payload_len, 26 | size_t max_chunk_sz, struct tcp_conn *tc) 27 | { 28 | const uint8_t *pend = payload + payload_len; 29 | struct rtmp_header hdr; 30 | struct mbuf *mb; 31 | size_t chunk_sz; 32 | int err; 33 | 34 | if (!payload || !payload_len || !max_chunk_sz || !tc) 35 | return EINVAL; 36 | 37 | mb = mbuf_alloc(payload_len + 256); 38 | if (!mb) 39 | return ENOMEM; 40 | 41 | memset(&hdr, 0, sizeof(hdr)); 42 | 43 | hdr.format = format; 44 | hdr.chunk_id = chunk_id; 45 | 46 | hdr.timestamp = timestamp; 47 | hdr.timestamp_delta = timestamp_delta; 48 | hdr.length = (uint32_t)payload_len; 49 | hdr.type_id = msg_type_id; 50 | hdr.stream_id = msg_stream_id; 51 | 52 | chunk_sz = min(payload_len, max_chunk_sz); 53 | 54 | err = rtmp_header_encode(mb, &hdr); 55 | err |= mbuf_write_mem(mb, payload, chunk_sz); 56 | if (err) 57 | goto out; 58 | 59 | payload += chunk_sz; 60 | 61 | hdr.format = 3; 62 | 63 | while (payload < pend) { 64 | 65 | const size_t len = pend - payload; 66 | 67 | chunk_sz = min(len, max_chunk_sz); 68 | 69 | err = rtmp_header_encode(mb, &hdr); 70 | err |= mbuf_write_mem(mb, payload, chunk_sz); 71 | if (err) 72 | goto out; 73 | 74 | payload += chunk_sz; 75 | } 76 | 77 | mb->pos = 0; 78 | 79 | err = tcp_send(tc, mb); 80 | if (err) 81 | goto out; 82 | 83 | out: 84 | mem_deref(mb); 85 | 86 | return err; 87 | } 88 | -------------------------------------------------------------------------------- /src/rtp/member.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file member.c Real-time Transport Control Protocol member 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include "rtcp.h" 16 | 17 | 18 | static void destructor(void *data) 19 | { 20 | struct rtp_member *mbr = data; 21 | 22 | hash_unlink(&mbr->le); 23 | mem_deref(mbr->s); 24 | } 25 | 26 | 27 | struct rtp_member *rtp_member_add(struct hash *ht, uint32_t src) 28 | { 29 | struct rtp_member *mbr; 30 | 31 | mbr = mem_zalloc(sizeof(*mbr), destructor); 32 | if (!mbr) 33 | return NULL; 34 | 35 | hash_append(ht, src, &mbr->le, mbr); 36 | mbr->src = src; 37 | 38 | return mbr; 39 | } 40 | 41 | 42 | static bool hash_cmp_handler(struct le *le, void *arg) 43 | { 44 | const struct rtp_member *mbr = le->data; 45 | 46 | return mbr->src == *(uint32_t *)arg; 47 | } 48 | 49 | 50 | struct rtp_member *rtp_member_find(struct hash *ht, uint32_t src) 51 | { 52 | return list_ledata(hash_lookup(ht, src, hash_cmp_handler, &src)); 53 | } 54 | -------------------------------------------------------------------------------- /src/rtp/rr.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file rtp/rr.c RTCP Reception report 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include "rtcp.h" 17 | 18 | 19 | int rtcp_rr_alloc(struct rtcp_rr **rrp, size_t count) 20 | { 21 | struct rtcp_rr *rr; 22 | 23 | if (!rrp) 24 | return EINVAL; 25 | 26 | rr = mem_alloc(count * sizeof(*rr), NULL); 27 | if (!rr) 28 | return ENOMEM; 29 | 30 | *rrp = rr; 31 | return 0; 32 | } 33 | 34 | 35 | int rtcp_rr_encode(struct mbuf *mb, const struct rtcp_rr *rr) 36 | { 37 | int err; 38 | 39 | if (!mb || !rr) 40 | return EINVAL; 41 | 42 | err = mbuf_write_u32(mb, htonl(rr->ssrc)); 43 | err |= mbuf_write_u32(mb, htonl(rr->fraction<<24 | 44 | (rr->lost & 0x00ffffff))); 45 | err |= mbuf_write_u32(mb, htonl(rr->last_seq)); 46 | err |= mbuf_write_u32(mb, htonl(rr->jitter)); 47 | err |= mbuf_write_u32(mb, htonl(rr->lsr)); 48 | err |= mbuf_write_u32(mb, htonl(rr->dlsr)); 49 | 50 | return err; 51 | } 52 | 53 | 54 | int rtcp_rr_decode(struct mbuf *mb, struct rtcp_rr *rr) 55 | { 56 | uint32_t w; 57 | 58 | if (!rr) 59 | return EINVAL; 60 | if (mbuf_get_left(mb) < RTCP_RR_SIZE) 61 | return EBADMSG; 62 | 63 | rr->ssrc = ntohl(mbuf_read_u32(mb)); 64 | w = ntohl(mbuf_read_u32(mb)); 65 | rr->fraction = w>>24; rr->lost = w & 0x00ffffffU; 66 | rr->last_seq = ntohl(mbuf_read_u32(mb)); 67 | rr->jitter = ntohl(mbuf_read_u32(mb)); 68 | rr->lsr = ntohl(mbuf_read_u32(mb)); 69 | rr->dlsr = ntohl(mbuf_read_u32(mb)); 70 | 71 | return 0; 72 | } 73 | -------------------------------------------------------------------------------- /src/sa/printaddr.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file sa/printaddr.c Socket Address printing 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #ifdef HAVE_GETIFADDRS 7 | #include 8 | #include 9 | #include 10 | #endif 11 | #include 12 | #include 13 | #include 14 | 15 | 16 | /** 17 | * Print a Socket Address including IPv6 scope identifier 18 | * 19 | * @param pf Print function 20 | * @param sa Socket Address 21 | * 22 | * @return 0 if success, otherwise errorcode 23 | */ 24 | int sa_print_addr(struct re_printf *pf, const struct sa *sa) 25 | { 26 | int err; 27 | 28 | if (!sa) 29 | return 0; 30 | 31 | err = re_hprintf(pf, "%j", sa); 32 | 33 | if (sa_af(sa) == AF_INET6 && sa_is_linklocal(sa)) { 34 | #ifdef HAVE_GETIFADDRS 35 | char ifname[IF_NAMESIZE]; 36 | 37 | if (!if_indextoname(sa->u.in6.sin6_scope_id, ifname)) 38 | return errno; 39 | 40 | err |= re_hprintf(pf, "%%%s", ifname); 41 | #else 42 | uint32_t scope_id = sa_scopeid(sa); 43 | err |= re_hprintf(pf, "%%%d", scope_id); 44 | #endif 45 | } 46 | 47 | return err; 48 | } 49 | -------------------------------------------------------------------------------- /src/sdp/str.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file sdp/str.c SDP strings 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | 13 | const char sdp_attr_fmtp[] = "fmtp"; /**< fmtp */ 14 | const char sdp_attr_maxptime[] = "maxptime"; /**< maxptime */ 15 | const char sdp_attr_ptime[] = "ptime"; /**< ptime */ 16 | const char sdp_attr_rtcp[] = "rtcp"; /**< rtcp */ 17 | const char sdp_attr_rtpmap[] = "rtpmap"; /**< rtpmap */ 18 | 19 | const char sdp_media_audio[] = "audio"; /**< Media type 'audio' */ 20 | const char sdp_media_video[] = "video"; /**< Media type 'video' */ 21 | const char sdp_media_text[] = "text"; /**< Media type 'text' */ 22 | 23 | const char sdp_proto_rtpavp[] = "RTP/AVP"; /**< RTP Profile */ 24 | const char sdp_proto_rtpsavp[] = "RTP/SAVP"; /**< Secure RTP Profile */ 25 | 26 | 27 | /** 28 | * Get the SDP media direction name 29 | * 30 | * @param dir Media direction 31 | * 32 | * @return Name of media direction 33 | */ 34 | const char *sdp_dir_name(enum sdp_dir dir) 35 | { 36 | switch (dir) { 37 | 38 | case SDP_INACTIVE: return "inactive"; 39 | case SDP_RECVONLY: return "recvonly"; 40 | case SDP_SENDONLY: return "sendonly"; 41 | case SDP_SENDRECV: return "sendrecv"; 42 | default: return "??"; 43 | } 44 | } 45 | 46 | 47 | /** 48 | * Get the SDP bandwidth name 49 | * 50 | * @param type Bandwidth type 51 | * 52 | * @return Bandwidth name 53 | */ 54 | const char *sdp_bandwidth_name(enum sdp_bandwidth type) 55 | { 56 | switch (type) { 57 | 58 | case SDP_BANDWIDTH_CT: return "CT"; 59 | case SDP_BANDWIDTH_AS: return "AS"; 60 | case SDP_BANDWIDTH_RS: return "RS"; 61 | case SDP_BANDWIDTH_RR: return "RR"; 62 | case SDP_BANDWIDTH_TIAS: return "TIAS"; 63 | default: return "??"; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/sdp/util.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file sdp/util.c SDP utility functions 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | 14 | /** 15 | * Decode an SDP direction 16 | * 17 | * @param pl SDP direction as string 18 | * 19 | * @return sdp_dir SDP direction, SDP_SENDRECV as fallback 20 | */ 21 | enum sdp_dir sdp_dir_decode(const struct pl *pl) 22 | { 23 | if (!pl_strcmp(pl, "off")) { 24 | return SDP_INACTIVE; 25 | } 26 | else if (!pl_strcmp(pl, "inactive")) { 27 | return SDP_INACTIVE; 28 | } 29 | else if (!pl_strcmp(pl, "sendonly")) { 30 | return SDP_SENDONLY; 31 | } 32 | else if (!pl_strcmp(pl, "recvonly")) { 33 | return SDP_RECVONLY; 34 | } 35 | 36 | return SDP_SENDRECV; 37 | } 38 | 39 | /** 40 | * Decode RTP Header Extension SDP attribute value 41 | * 42 | * @param ext Extension-map object 43 | * @param val SDP attribute value 44 | * 45 | * @return 0 for success, otherwise errorcode 46 | */ 47 | int sdp_extmap_decode(struct sdp_extmap *ext, const char *val) 48 | { 49 | struct pl id, dir; 50 | 51 | if (!ext || !val) 52 | return EINVAL; 53 | 54 | if (re_regex(val, strlen(val), "[0-9]+[/]*[a-z]* [^ ]+[ ]*[^ ]*", 55 | &id, NULL, &dir, &ext->name, NULL, &ext->attrs)) 56 | return EBADMSG; 57 | 58 | ext->dir_set = false; 59 | ext->dir = SDP_SENDRECV; 60 | 61 | if (pl_isset(&dir)) { 62 | 63 | ext->dir_set = true; 64 | 65 | if (!pl_strcmp(&dir, "sendonly")) ext->dir = SDP_SENDONLY; 66 | else if (!pl_strcmp(&dir, "sendrecv")) ext->dir = SDP_SENDRECV; 67 | else if (!pl_strcmp(&dir, "recvonly")) ext->dir = SDP_RECVONLY; 68 | else if (!pl_strcmp(&dir, "inactive")) ext->dir = SDP_INACTIVE; 69 | else ext->dir_set = false; 70 | } 71 | 72 | ext->id = pl_u32(&id); 73 | 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /src/sip/addr.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file sip/addr.c SIP Address decode 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | 17 | /** 18 | * Decode a pointer-length string into a SIP Address object 19 | * 20 | * @param addr SIP Address object 21 | * @param pl Pointer-length string 22 | * 23 | * @return 0 for success, otherwise errorcode 24 | */ 25 | int sip_addr_decode(struct sip_addr *addr, const struct pl *pl) 26 | { 27 | int err; 28 | 29 | if (!addr || !pl) 30 | return EINVAL; 31 | 32 | memset(addr, 0, sizeof(*addr)); 33 | 34 | if (0 == re_regex(pl->p, pl->l, "[~ \t\r\n<]*[ \t\r\n]*<[^>]+>[^]*", 35 | &addr->dname, NULL, &addr->auri, &addr->params)) { 36 | 37 | if (!addr->dname.l) 38 | addr->dname.p = NULL; 39 | 40 | if (!addr->params.l) 41 | addr->params.p = NULL; 42 | } 43 | else { 44 | memset(addr, 0, sizeof(*addr)); 45 | 46 | if (re_regex(pl->p, pl->l, "[^;]+[^]*", 47 | &addr->auri, &addr->params)) 48 | return EBADMSG; 49 | } 50 | 51 | err = uri_decode(&addr->uri, &addr->auri); 52 | if (err) 53 | memset(addr, 0, sizeof(*addr)); 54 | 55 | return err; 56 | } 57 | -------------------------------------------------------------------------------- /src/sip/contact.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file sip/contact.c SIP contact functions 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | 17 | /** 18 | * Set contact parameters 19 | * 20 | * @param contact SIP Contact object 21 | * @param uri Username or URI 22 | * @param addr IP-address and port 23 | * @param tp SIP Transport 24 | */ 25 | void sip_contact_set(struct sip_contact *contact, const char *uri, 26 | const struct sa *addr, enum sip_transp tp) 27 | { 28 | if (!contact) 29 | return; 30 | 31 | contact->uri = uri; 32 | contact->addr = addr; 33 | contact->tp = tp; 34 | } 35 | 36 | 37 | /** 38 | * Print contact header 39 | * 40 | * @param pf Print function 41 | * @param contact SIP Contact object 42 | * 43 | * @return 0 for success, otherwise errorcode 44 | */ 45 | int sip_contact_print(struct re_printf *pf, const struct sip_contact *contact) 46 | { 47 | if (!contact) 48 | return 0; 49 | 50 | if (contact->uri && strchr(contact->uri, ':')) 51 | return re_hprintf(pf, "Contact: <%s>\r\n", contact->uri); 52 | else 53 | return re_hprintf(pf, "Contact: \r\n", 54 | contact->uri, 55 | contact->addr, 56 | sip_transp_param(contact->tp)); 57 | } 58 | -------------------------------------------------------------------------------- /src/sip/cseq.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file cseq.c SIP CSeq decode 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | 16 | /** 17 | * Decode a pointer-length string into a SIP CSeq header 18 | * 19 | * @param cseq SIP CSeq header 20 | * @param pl Pointer-length string 21 | * 22 | * @return 0 for success, otherwise errorcode 23 | */ 24 | int sip_cseq_decode(struct sip_cseq *cseq, const struct pl *pl) 25 | { 26 | struct pl num; 27 | int err; 28 | 29 | if (!cseq || !pl) 30 | return EINVAL; 31 | 32 | err = re_regex(pl->p, pl->l, "[0-9]+[ \t\r\n]+[^ \t\r\n]+", 33 | &num, NULL, &cseq->met); 34 | if (err) 35 | return err; 36 | 37 | cseq->num = pl_u32(&num); 38 | 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /src/sip/rack.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file rack.c SIP RAck decode (RFC 3262) 3 | * 4 | * Copyright (C) 2022 commend.com - m.fridrich@commend.com 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | /** 16 | * Decode a pointer-length string into a SIP RAck header 17 | * 18 | * @param rack SIP RAck header 19 | * @param pl Pointer-length string 20 | * 21 | * @return 0 for success, otherwise errorcode 22 | */ 23 | int sip_rack_decode(struct sip_rack *rack, const struct pl *pl) 24 | { 25 | struct pl rel_seq; 26 | struct pl cseq; 27 | int err; 28 | 29 | if (!rack || !pl) 30 | return EINVAL; 31 | 32 | err = re_regex(pl->p, pl->l, 33 | "[0-9]+[ \t\r\n]+[0-9]+[ \t\r\n]+[^ \t\r\n]+", 34 | &rel_seq, NULL, &cseq, NULL, &rack->met); 35 | if (err) 36 | return err; 37 | 38 | rack->rel_seq = pl_u32(&rel_seq); 39 | rack->cseq = pl_u32(&cseq); 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /src/sip/via.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file via.c SIP Via decode 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | 16 | static int decode_hostport(const struct pl *hostport, struct pl *host, 17 | struct pl *port) 18 | { 19 | /* Try IPv6 first */ 20 | if (!re_regex(hostport->p, hostport->l, "\\[[0-9a-f:]+\\][:]*[0-9]*", 21 | host, NULL, port)) 22 | return 0; 23 | 24 | /* Then non-IPv6 host */ 25 | return re_regex(hostport->p, hostport->l, "[^:]+[:]*[0-9]*", 26 | host, NULL, port); 27 | } 28 | 29 | 30 | /** 31 | * Decode a pointer-length string into a SIP Via header 32 | * 33 | * @param via SIP Via header 34 | * @param pl Pointer-length string 35 | * 36 | * @return 0 for success, otherwise errorcode 37 | */ 38 | int sip_via_decode(struct sip_via *via, const struct pl *pl) 39 | { 40 | struct pl transp, host, port; 41 | int err; 42 | 43 | if (!via || !pl) 44 | return EINVAL; 45 | 46 | err = re_regex(pl->p, pl->l, 47 | "SIP[ \t\r\n]*/[ \t\r\n]*2.0[ \t\r\n]*/[ \t\r\n]*" 48 | "[A-Z]+[ \t\r\n]*[^; \t\r\n]+[ \t\r\n]*[^]*", 49 | NULL, NULL, NULL, NULL, &transp, 50 | NULL, &via->sentby, NULL, &via->params); 51 | if (err) 52 | return err; 53 | 54 | if (!pl_strcmp(&transp, "TCP")) 55 | via->tp = SIP_TRANSP_TCP; 56 | else if (!pl_strcmp(&transp, "TLS")) 57 | via->tp = SIP_TRANSP_TLS; 58 | else if (!pl_strcmp(&transp, "UDP")) 59 | via->tp = SIP_TRANSP_UDP; 60 | else if (!pl_strcmp(&transp, "WS")) 61 | via->tp = SIP_TRANSP_WS; 62 | else if (!pl_strcmp(&transp, "WSS")) 63 | via->tp = SIP_TRANSP_WSS; 64 | else 65 | via->tp = SIP_TRANSP_NONE; 66 | 67 | err = decode_hostport(&via->sentby, &host, &port); 68 | if (err) 69 | return err; 70 | 71 | sa_init(&via->addr, AF_INET); 72 | 73 | (void)sa_set(&via->addr, &host, 0); 74 | 75 | if (pl_isset(&port)) 76 | sa_set_port(&via->addr, pl_u32(&port)); 77 | 78 | via->val = *pl; 79 | 80 | return msg_param_decode(&via->params, "branch", &via->branch); 81 | } 82 | -------------------------------------------------------------------------------- /src/sipevent/sipevent.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file sipevent.h SIP Event Private Interface 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | /* Listener Socket */ 8 | 9 | struct sipevent_sock { 10 | struct sip_lsnr *lsnr; 11 | struct hash *ht_not; 12 | struct hash *ht_sub; 13 | struct sip *sip; 14 | sip_msg_h *subh; 15 | void *arg; 16 | }; 17 | 18 | 19 | /* Notifier */ 20 | 21 | struct sipnot { 22 | struct le he; 23 | struct sip_loopstate ls; 24 | struct tmr tmr; 25 | struct sipevent_sock *sock; 26 | struct sip_request *req; 27 | struct sip_dialog *dlg; 28 | struct sip_auth *auth; 29 | struct sip *sip; 30 | struct mbuf *mb; 31 | char *event; 32 | char *id; 33 | char *cuser; 34 | char *hdrs; 35 | char *ctype; 36 | sipnot_close_h *closeh; 37 | void *arg; 38 | uint32_t expires; 39 | uint32_t expires_min; 40 | uint32_t expires_dfl; 41 | uint32_t expires_max; 42 | uint32_t retry_after; 43 | enum sipevent_subst substate; 44 | enum sipevent_reason reason; 45 | bool notify_pending; 46 | bool subscribed; 47 | bool terminated; 48 | bool termsent; 49 | }; 50 | 51 | void sipnot_refresh(struct sipnot *not, uint32_t expires); 52 | int sipnot_notify(struct sipnot *not); 53 | int sipnot_reply(struct sipnot *not, const struct sip_msg *msg, 54 | uint16_t scode, const char *reason); 55 | 56 | 57 | /* Subscriber */ 58 | 59 | struct sipsub { 60 | struct le he; 61 | struct sip_loopstate ls; 62 | struct tmr tmr; 63 | struct sipevent_sock *sock; 64 | struct sip_request *req; 65 | struct sip_dialog *dlg; 66 | struct sip_auth *auth; 67 | struct sip *sip; 68 | char *event; 69 | char *id; 70 | char *cuser; 71 | char *hdrs; 72 | char *refer_hdrs; 73 | sipsub_fork_h *forkh; 74 | sipsub_notify_h *notifyh; 75 | sipsub_close_h *closeh; 76 | void *arg; 77 | int32_t refer_cseq; 78 | uint32_t expires; 79 | uint32_t failc; 80 | bool subscribed; 81 | bool terminated; 82 | bool termconf; 83 | bool termwait; 84 | bool refer; 85 | }; 86 | 87 | struct sipsub *sipsub_find(struct sipevent_sock *sock, 88 | const struct sip_msg *msg, 89 | const struct sipevent_event *evt, bool full); 90 | void sipsub_reschedule(struct sipsub *sub, uint64_t wait); 91 | void sipsub_terminate(struct sipsub *sub, int err, const struct sip_msg *msg, 92 | const struct sipevent_substate *substate); 93 | -------------------------------------------------------------------------------- /src/sipsess/close.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file close.c SIP Session Close 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include "sipsess.h" 19 | 20 | 21 | static void bye_resp_handler(int err, const struct sip_msg *msg, void *arg) 22 | { 23 | struct sipsess *sess = arg; 24 | 25 | if (err || sip_request_loops(&sess->ls, msg->scode)) 26 | goto out; 27 | 28 | if (msg->scode < 200) { 29 | return; 30 | } 31 | else if (msg->scode < 300) { 32 | ; 33 | } 34 | else { 35 | if (sess->peerterm) 36 | goto out; 37 | 38 | switch (msg->scode) { 39 | 40 | case 401: 41 | case 407: 42 | err = sip_auth_authenticate(sess->auth, msg); 43 | if (err) 44 | break; 45 | 46 | err = sipsess_bye(sess, false); 47 | if (err) 48 | break; 49 | 50 | return; 51 | } 52 | } 53 | 54 | out: 55 | mem_deref(sess); 56 | } 57 | 58 | 59 | int sipsess_bye(struct sipsess *sess, bool reset_ls) 60 | { 61 | if (sess->req) 62 | return EPROTO; 63 | 64 | if (reset_ls) 65 | sip_loopstate_reset(&sess->ls); 66 | 67 | return sip_drequestf(&sess->req, sess->sip, true, "BYE", 68 | sess->dlg, 0, sess->auth, 69 | NULL, bye_resp_handler, sess, 70 | "%s" 71 | "Content-Length: 0\r\n" 72 | "\r\n", 73 | sess->close_hdrs); 74 | } 75 | -------------------------------------------------------------------------------- /src/sipsess/request.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file sipsess/request.c SIP Session Non-INVITE Request 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include "sipsess.h" 19 | 20 | 21 | static void destructor(void *arg) 22 | { 23 | struct sipsess_request *req = arg; 24 | 25 | tmr_cancel(&req->tmr); 26 | list_unlink(&req->le); 27 | mem_deref(req->ctype); 28 | mem_deref(req->body); 29 | mem_deref(req->req); 30 | 31 | /* wait for pending requests */ 32 | if (req->sess->terminated && !req->sess->requestl.head) 33 | mem_deref(req->sess); 34 | } 35 | 36 | 37 | static void internal_resp_handler(int err, const struct sip_msg *msg, 38 | void *arg) 39 | { 40 | (void)err; 41 | (void)msg; 42 | (void)arg; 43 | } 44 | 45 | 46 | int sipsess_request_alloc(struct sipsess_request **reqp, struct sipsess *sess, 47 | const char *ctype, struct mbuf *body, 48 | sip_resp_h *resph, void *arg) 49 | { 50 | struct sipsess_request *req; 51 | int err = 0; 52 | 53 | if (!reqp || !sess || sess->terminated) 54 | return EINVAL; 55 | 56 | req = mem_zalloc(sizeof(*req), destructor); 57 | if (!req) 58 | return ENOMEM; 59 | 60 | list_append(&sess->requestl, &req->le, req); 61 | 62 | if (ctype) { 63 | err = str_dup(&req->ctype, ctype); 64 | if (err) 65 | goto out; 66 | } 67 | 68 | req->sess = sess; 69 | req->body = mem_ref(body); 70 | req->resph = resph ? resph : internal_resp_handler; 71 | req->arg = arg; 72 | tmr_init(&req->tmr); 73 | 74 | out: 75 | if (err) 76 | mem_deref(req); 77 | else 78 | *reqp = req; 79 | 80 | return err; 81 | } 82 | -------------------------------------------------------------------------------- /src/srtp/README: -------------------------------------------------------------------------------- 1 | SRTP module 2 | ----------- 3 | 4 | The SRTP module implements Secure RTP as defined in RFC 3711. 5 | It provides a clean and user friendly API and can be used 6 | as a standalone module. 7 | 8 | 9 | 10 | 11 | Requirements and features: 12 | 13 | RFC 3711 yes 14 | RFC 6188 yes 15 | Multiple Master keys: no 16 | Key derivation rate: 0 (zero) 17 | Salting keys: yes 18 | SRTP protection: yes 19 | SRTCP protection: yes 20 | Replay protection: yes 21 | Encryption: yes 22 | Authentication: yes 23 | MKI (Master Key Identifier): no 24 | Authentication tag length: 32-bit and 80-bit 25 | ROC (Roll Over Counter): yes 26 | Master key lifetime: no 27 | Multiple SSRCs: yes 28 | Performance: better than libsrtp 29 | 30 | Cryptographic transforms: 31 | - AES in Counter mode: yes 32 | - AES in f8-mode: no 33 | - NULL Cipher: no 34 | 35 | Authentication transform: 36 | - HMAC-SHA1: yes 37 | - NULL auth: no 38 | 39 | master key lengths: 40 | - 128 bits yes 41 | - 192 bits no 42 | - 256 bits yes 43 | -------------------------------------------------------------------------------- /src/srtp/replay.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file srtp/replay.c SRTP replay protection 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "srtp.h" 12 | 13 | 14 | enum { 15 | SRTP_WINDOW_SIZE = 64 16 | }; 17 | 18 | 19 | void srtp_replay_init(struct replay *replay) 20 | { 21 | if (!replay) 22 | return; 23 | 24 | replay->bitmap = 0; 25 | replay->lix = 0; 26 | } 27 | 28 | 29 | /* 30 | * Returns false if packet disallowed, true if packet permitted 31 | */ 32 | bool srtp_replay_check(struct replay *replay, uint64_t ix) 33 | { 34 | uint64_t diff; 35 | 36 | if (!replay) 37 | return false; 38 | 39 | if (ix > replay->lix) { 40 | diff = ix - replay->lix; 41 | 42 | if (diff < SRTP_WINDOW_SIZE) { /* In window */ 43 | replay->bitmap <<= diff; 44 | replay->bitmap |= 1; /* set bit for this packet */ 45 | } 46 | else 47 | replay->bitmap = 1; 48 | 49 | replay->lix = ix; 50 | return true; 51 | } 52 | 53 | diff = replay->lix - ix; 54 | if (diff >= SRTP_WINDOW_SIZE) 55 | return false; 56 | 57 | if (replay->bitmap & (1ULL << diff)) 58 | return false; /* already seen */ 59 | 60 | /* mark as seen */ 61 | replay->bitmap |= (1ULL << diff); 62 | 63 | return true; 64 | } 65 | -------------------------------------------------------------------------------- /src/stun/ind.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file ind.c STUN Indication 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "stun.h" 14 | 15 | 16 | /** 17 | * Send a STUN Indication message 18 | * 19 | * @param proto Transport Protocol 20 | * @param sock Socket; UDP (struct udp_sock) or TCP (struct tcp_conn) 21 | * @param dst Destination network address 22 | * @param presz Number of bytes in preamble, if sending over TURN 23 | * @param method STUN Method 24 | * @param key Authentication key (optional) 25 | * @param keylen Number of bytes in authentication key 26 | * @param fp Use STUN Fingerprint attribute 27 | * @param attrc Number of attributes to encode (variable arguments) 28 | * @param ... Variable list of attribute-tuples 29 | * Each attribute has 2 arguments, attribute type and value 30 | * 31 | * @return 0 if success, otherwise errorcode 32 | */ 33 | int stun_indication(int proto, void *sock, const struct sa *dst, size_t presz, 34 | uint16_t method, const uint8_t *key, size_t keylen, 35 | bool fp, uint32_t attrc, ...) 36 | { 37 | uint8_t tid[STUN_TID_SIZE]; 38 | struct mbuf *mb; 39 | va_list ap; 40 | int err; 41 | 42 | if (!sock) 43 | return EINVAL; 44 | 45 | mb = mbuf_alloc(2048); 46 | if (!mb) 47 | return ENOMEM; 48 | 49 | stun_generate_tid(tid); 50 | 51 | va_start(ap, attrc); 52 | mb->pos = presz; 53 | err = stun_msg_vencode(mb, method, STUN_CLASS_INDICATION, tid, NULL, 54 | key, keylen, fp, 0x00, attrc, ap); 55 | va_end(ap); 56 | if (err) 57 | goto out; 58 | 59 | mb->pos = presz; 60 | err = stun_send(proto, sock, dst, mb); 61 | 62 | out: 63 | mem_deref(mb); 64 | 65 | return err; 66 | } 67 | -------------------------------------------------------------------------------- /src/stun/req.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file stun/req.c STUN request 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "stun.h" 14 | 15 | 16 | /** 17 | * Send a STUN request using a client transaction 18 | * 19 | * @param ctp Pointer to allocated client transaction (optional) 20 | * @param stun STUN Instance 21 | * @param proto Transport Protocol 22 | * @param sock Socket; UDP (struct udp_sock) or TCP (struct tcp_conn) 23 | * @param dst Destination network address 24 | * @param presz Number of bytes in preamble, if sending over TURN 25 | * @param method STUN Method 26 | * @param key Authentication key (optional) 27 | * @param keylen Number of bytes in authentication key 28 | * @param fp Use STUN Fingerprint attribute 29 | * @param resph Response handler 30 | * @param arg Response handler argument 31 | * @param attrc Number of attributes to encode (variable arguments) 32 | * @param ... Variable list of attribute-tuples 33 | * Each attribute has 2 arguments, attribute type and value 34 | * 35 | * @return 0 if success, otherwise errorcode 36 | */ 37 | int stun_request(struct stun_ctrans **ctp, struct stun *stun, int proto, 38 | void *sock, const struct sa *dst, size_t presz, 39 | uint16_t method, const uint8_t *key, size_t keylen, bool fp, 40 | stun_resp_h *resph, void *arg, uint32_t attrc, ...) 41 | { 42 | uint8_t tid[STUN_TID_SIZE]; 43 | struct mbuf *mb; 44 | va_list ap; 45 | int err; 46 | 47 | if (!stun) 48 | return EINVAL; 49 | 50 | mb = mbuf_alloc(512); 51 | if (!mb) 52 | return ENOMEM; 53 | 54 | stun_generate_tid(tid); 55 | 56 | va_start(ap, attrc); 57 | mb->pos = presz; 58 | err = stun_msg_vencode(mb, method, STUN_CLASS_REQUEST, 59 | tid, NULL, key, keylen, fp, 0x00, attrc, ap); 60 | va_end(ap); 61 | if (err) 62 | goto out; 63 | 64 | mb->pos = presz; 65 | err = stun_ctrans_request(ctp, stun, proto, sock, dst, mb, tid, method, 66 | key, keylen, resph, arg); 67 | if (err) 68 | goto out; 69 | 70 | out: 71 | mem_deref(mb); 72 | 73 | return err; 74 | } 75 | -------------------------------------------------------------------------------- /src/stun/stun.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file stun.h Internal STUN interface 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | 8 | /** STUN Protocol values */ 9 | enum { 10 | STUN_MAGIC_COOKIE = 0x2112a442 /**< Magic Cookie for 3489bis */ 11 | }; 12 | 13 | 14 | /** Calculate STUN message type from method and class */ 15 | #define STUN_TYPE(method, class) \ 16 | ((method)&0x0f80) << 2 | \ 17 | ((method)&0x0070) << 1 | \ 18 | ((method)&0x000f) << 0 | \ 19 | ((class)&0x2) << 7 | \ 20 | ((class)&0x1) << 4 21 | 22 | 23 | #define STUN_CLASS(type) \ 24 | ((type >> 7 | type >> 4) & 0x3) 25 | 26 | 27 | #define STUN_METHOD(type) \ 28 | ((type&0x3e00)>>2 | (type&0x00e0)>>1 | (type&0x000f)) 29 | 30 | 31 | struct stun_hdr { 32 | uint16_t type; /**< Message type */ 33 | uint16_t len; /**< Payload length */ 34 | uint32_t cookie; /**< Magic cookie */ 35 | uint8_t tid[STUN_TID_SIZE]; /**< Transaction ID */ 36 | }; 37 | 38 | 39 | struct stun { 40 | struct list ctl; 41 | struct stun_conf conf; 42 | stun_ind_h *indh; 43 | void *arg; 44 | }; 45 | 46 | int stun_hdr_encode(struct mbuf *mb, const struct stun_hdr *hdr); 47 | int stun_hdr_decode(struct mbuf *mb, struct stun_hdr *hdr); 48 | 49 | int stun_attr_encode(struct mbuf *mb, uint16_t type, const void *v, 50 | const uint8_t *tid, uint8_t padding); 51 | int stun_attr_decode(struct stun_attr **attrp, struct mbuf *mb, 52 | const uint8_t *tid, struct stun_unknown_attr *ua); 53 | void stun_attr_dump(const struct stun_attr *a); 54 | 55 | int stun_addr_encode(struct mbuf *mb, const struct sa *addr, 56 | const uint8_t *tid); 57 | int stun_addr_decode(struct mbuf *mb, struct sa *addr, const uint8_t *tid); 58 | 59 | int stun_ctrans_request(struct stun_ctrans **ctp, struct stun *stun, int proto, 60 | void *sock, const struct sa *dst, struct mbuf *mb, 61 | const uint8_t tid[], uint16_t met, const uint8_t *key, 62 | size_t keylen, stun_resp_h *resph, void *arg); 63 | void stun_ctrans_close(struct stun *stun); 64 | int stun_ctrans_debug(struct re_printf *pf, const struct stun *stun); 65 | -------------------------------------------------------------------------------- /src/stun/stunstr.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file stunstr.c STUN Strings 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | 13 | /* STUN Reason Phrase */ 14 | const char *stun_reason_300 = "Try Alternate"; 15 | const char *stun_reason_400 = "Bad Request"; 16 | const char *stun_reason_401 = "Unauthorized"; 17 | const char *stun_reason_403 = "Forbidden"; 18 | const char *stun_reason_420 = "Unknown Attribute"; 19 | const char *stun_reason_437 = "Allocation Mismatch"; 20 | const char *stun_reason_438 = "Stale Nonce"; 21 | const char *stun_reason_440 = "Address Family not Supported"; 22 | const char *stun_reason_441 = "Wrong Credentials"; 23 | const char *stun_reason_442 = "Unsupported Transport Protocol"; 24 | const char *stun_reason_443 = "Peer Address Family Mismatch"; 25 | const char *stun_reason_486 = "Allocation Quota Reached"; 26 | const char *stun_reason_500 = "Server Error"; 27 | const char *stun_reason_508 = "Insufficient Capacity"; 28 | 29 | 30 | /** 31 | * Get the name of a given STUN Transport 32 | * 33 | * @param tp STUN Transport 34 | * 35 | * @return Name of the corresponding STUN Transport 36 | */ 37 | const char *stun_transp_name(enum stun_transp tp) 38 | { 39 | switch (tp) { 40 | 41 | case STUN_TRANSP_UDP: return "UDP"; 42 | case STUN_TRANSP_TCP: return "TCP"; 43 | case STUN_TRANSP_DTLS: return "DTLS"; 44 | default: return "???"; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/sys/daemon.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file daemon.c Daemonize process 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #ifdef HAVE_UNISTD_H 9 | #include 10 | #endif 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | 19 | /** 20 | * Daemonize process 21 | * 22 | * @return 0 if success, otherwise errorcode 23 | */ 24 | int sys_daemon(void) 25 | { 26 | #ifdef HAVE_FORK 27 | pid_t pid; 28 | 29 | pid = fork(); 30 | if (-1 == pid) 31 | return errno; 32 | else if (pid > 0) 33 | exit(0); 34 | 35 | if (-1 == setsid()) 36 | return errno; 37 | 38 | (void)signal(SIGHUP, SIG_IGN); 39 | 40 | pid = fork(); 41 | if (-1 == pid) 42 | return errno; 43 | else if (pid > 0) 44 | exit(0); 45 | 46 | if (-1 == chdir("/")) 47 | return errno; 48 | (void)umask(0); 49 | 50 | /* Redirect standard files to /dev/null */ 51 | if (freopen("/dev/null", "r", stdin) == NULL) 52 | return errno; 53 | if (freopen("/dev/null", "w", stdout) == NULL) 54 | return errno; 55 | if (freopen("/dev/null", "w", stderr) == NULL) 56 | return errno; 57 | 58 | return 0; 59 | #else 60 | return ENOSYS; 61 | #endif 62 | } 63 | -------------------------------------------------------------------------------- /src/sys/sleep.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file sleep.c System sleep functions 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include 9 | #ifdef WIN32 10 | #include 11 | #endif 12 | #ifdef HAVE_UNISTD_H 13 | #include 14 | #endif 15 | #ifdef HAVE_SELECT_H 16 | #include 17 | #endif 18 | 19 | 20 | /** 21 | * Blocking sleep for [us] number of microseconds 22 | * 23 | * @param us Number of microseconds to sleep 24 | */ 25 | void sys_usleep(unsigned int us) 26 | { 27 | if (!us) 28 | return; 29 | 30 | #ifdef WIN32 31 | Sleep(us / 1000); 32 | #elif defined(HAVE_SELECT) 33 | do { 34 | struct timeval tv; 35 | 36 | tv.tv_sec = us / 1000000; 37 | tv.tv_usec = us % 1000000; 38 | 39 | (void)select(0, NULL, NULL, NULL, &tv); 40 | } while (0); 41 | #else 42 | (void)usleep(us); 43 | #endif 44 | } 45 | -------------------------------------------------------------------------------- /src/tls/openssl/tls.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file openssl/tls.h TLS backend using OpenSSL (Internal API) 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | /* also defined by wincrypt.h */ 8 | #ifdef WIN32 9 | #undef X509_NAME 10 | #endif 11 | 12 | /* 13 | * Mapping of feature macros 14 | */ 15 | 16 | #if defined(LIBRESSL_VERSION_NUMBER) 17 | typedef int (*SSL_verify_cb)(int preverify_ok, X509_STORE_CTX *x509_ctx); 18 | #else 19 | #define SSL_state SSL_get_state 20 | #define SSL_ST_OK TLS_ST_OK 21 | #endif 22 | 23 | typedef X509_NAME*(tls_get_certfield_h)(const X509 *); 24 | 25 | struct tls; 26 | struct tls_cert; 27 | 28 | void tls_flush_error(void); 29 | SSL_CTX *tls_ssl_ctx(const struct tls *tls); 30 | X509 *tls_cert_x509(struct tls_cert *hc); 31 | SSL_CTX *tls_cert_ctx(struct tls_cert *hc); 32 | 33 | const char *tls_cert_host(struct tls_cert *hc); 34 | const struct list *tls_certs(const struct tls *tls); 35 | 36 | struct tls_cert *tls_cert_for_sni(const struct tls *tls, const char *sni); 37 | void tls_enable_sni(struct tls *tls); 38 | -------------------------------------------------------------------------------- /src/trice/cand.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file cand.c Common ICE Candidates 3 | * 4 | * Copyright (C) 2010 Alfred E. Heggestad 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include "trice.h" 22 | 23 | 24 | const char *ice_tcptype_name(enum ice_tcptype tcptype) 25 | { 26 | switch (tcptype) { 27 | 28 | case ICE_TCP_ACTIVE: return "active"; 29 | case ICE_TCP_PASSIVE: return "passive"; 30 | case ICE_TCP_SO: return "so"; 31 | default: return "???"; 32 | } 33 | } 34 | 35 | 36 | /* 37 | Local Remote 38 | Candidate Candidate 39 | --------------------------- 40 | tcp-so tcp-so 41 | tcp-active tcp-passive 42 | tcp-passive tcp-active 43 | 44 | */ 45 | enum ice_tcptype ice_tcptype_reverse(enum ice_tcptype type) 46 | { 47 | switch (type) { 48 | 49 | case ICE_TCP_SO: return ICE_TCP_SO; 50 | case ICE_TCP_ACTIVE: return ICE_TCP_PASSIVE; 51 | case ICE_TCP_PASSIVE: return ICE_TCP_ACTIVE; 52 | default: return (enum ice_tcptype)-1; 53 | } 54 | } 55 | 56 | 57 | enum ice_cand_type ice_cand_type_base(enum ice_cand_type type) 58 | { 59 | switch (type) { 60 | 61 | case ICE_CAND_TYPE_HOST: return ICE_CAND_TYPE_HOST; 62 | case ICE_CAND_TYPE_SRFLX: return ICE_CAND_TYPE_HOST; 63 | case ICE_CAND_TYPE_PRFLX: return ICE_CAND_TYPE_HOST; 64 | case ICE_CAND_TYPE_RELAY: return ICE_CAND_TYPE_RELAY; 65 | default: return type; 66 | } 67 | } 68 | 69 | 70 | int trice_cand_print(struct re_printf *pf, const struct ice_cand_attr *cand) 71 | { 72 | int err = 0; 73 | 74 | if (!cand) 75 | return 0; 76 | 77 | err |= re_hprintf(pf, "%s|%s", ice_cand_type2name(cand->type), 78 | net_proto2name(cand->proto)); 79 | 80 | if (cand->proto == IPPROTO_TCP) { 81 | 82 | err |= re_hprintf(pf, ".%s", ice_tcptype_name(cand->tcptype)); 83 | } 84 | 85 | err |= re_hprintf(pf, "|%J", &cand->addr); 86 | 87 | return err; 88 | } 89 | -------------------------------------------------------------------------------- /src/udp/mcast.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file mcast.c UDP Multicast 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | 12 | static int multicast_update(struct udp_sock *us, const struct sa *group, 13 | bool join) 14 | { 15 | struct ip_mreq mreq; 16 | struct ipv6_mreq mreq6; 17 | int err; 18 | 19 | if (!us || !group) 20 | return EINVAL; 21 | 22 | switch (sa_af(group)) { 23 | 24 | case AF_INET: 25 | mreq.imr_multiaddr = group->u.in.sin_addr; 26 | mreq.imr_interface.s_addr = 0; 27 | 28 | err = udp_setsockopt(us, IPPROTO_IP, 29 | join 30 | ? IP_ADD_MEMBERSHIP 31 | : IP_DROP_MEMBERSHIP, 32 | &mreq, sizeof(mreq)); 33 | break; 34 | 35 | case AF_INET6: 36 | mreq6.ipv6mr_multiaddr = group->u.in6.sin6_addr; 37 | mreq6.ipv6mr_interface = sa_scopeid(group); 38 | 39 | err = udp_setsockopt(us, IPPROTO_IPV6, 40 | join 41 | ? IPV6_JOIN_GROUP 42 | : IPV6_LEAVE_GROUP, 43 | &mreq6, sizeof(mreq6)); 44 | break; 45 | 46 | default: 47 | return EAFNOSUPPORT; 48 | } 49 | 50 | return err; 51 | } 52 | 53 | 54 | int udp_multicast_join(struct udp_sock *us, const struct sa *group) 55 | { 56 | return multicast_update(us, group, true); 57 | } 58 | 59 | 60 | int udp_multicast_leave(struct udp_sock *us, const struct sa *group) 61 | { 62 | return multicast_update(us, group, false); 63 | } 64 | -------------------------------------------------------------------------------- /src/unixsock/unixsock.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file unixsock/unixsock.c Unix domain sockets 3 | * 4 | * Copyright (C) 2022 Sebastian Reimers 5 | */ 6 | 7 | #include 8 | #ifdef HAVE_UNISTD_H 9 | #include 10 | #endif 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #define DEBUG_MODULE "unixsock" 17 | #define DEBUG_LEVEL 5 18 | #include 19 | 20 | #ifdef WIN32 21 | #define close closesocket 22 | #define unlink _unlink 23 | #endif 24 | 25 | 26 | /** 27 | * Listen for incoming connections on a Unix domain socket. 28 | * 29 | * @param fdp Pointer to a re_sock_t variable where the listening socket 30 | * file descriptor will be stored. 31 | * @param sock Pointer to a struct sa containing the address of the 32 | * Unix domain socket. 33 | * 34 | * @return 0 if success, otherwise errorcode 35 | */ 36 | int unixsock_listen_fd(re_sock_t *fdp, const struct sa *sock) 37 | { 38 | int err = 0; 39 | re_sock_t fd; 40 | 41 | if (!fdp || !sock) 42 | return EINVAL; 43 | 44 | if (sa_af(sock) != AF_UNIX || !sa_isset(sock, SA_ADDR)) 45 | return EINVAL; 46 | 47 | fd = socket(AF_UNIX, SOCK_STREAM, 0); 48 | if (fd == RE_BAD_SOCK) { 49 | err = RE_ERRNO_SOCK; 50 | goto err; 51 | } 52 | 53 | err = net_sockopt_blocking_set(fd, false); 54 | if (err) { 55 | DEBUG_WARNING("unix listen: nonblock set: %m\n", err); 56 | goto err; 57 | } 58 | 59 | (void)unlink(sock->u.un.sun_path); 60 | 61 | if (bind(fd, &sock->u.sa, sock->len) < 0) { 62 | err = RE_ERRNO_SOCK; 63 | DEBUG_WARNING("bind(): %m (%J)\n", err, sock); 64 | goto err; 65 | } 66 | 67 | if (listen(fd, SOMAXCONN) < 0) { 68 | err = RE_ERRNO_SOCK; 69 | DEBUG_WARNING("listen(): %m (%J)\n", err, sock); 70 | goto err; 71 | } 72 | 73 | *fdp = fd; 74 | 75 | return 0; 76 | 77 | err: 78 | if (fd != RE_BAD_SOCK) { 79 | (void)close(fd); 80 | } 81 | 82 | return err; 83 | } 84 | -------------------------------------------------------------------------------- /test/aac.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file aac.c AAC (Advanced Audio Coding) Testcode 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include "test.h" 11 | 12 | 13 | #define DEBUG_MODULE "aactest" 14 | #define DEBUG_LEVEL 5 15 | #include 16 | 17 | 18 | int test_aac(void) 19 | { 20 | static const uint8_t buf[2] = {0x12, 0x10}; 21 | struct aac_header hdr; 22 | int err; 23 | 24 | err = aac_header_decode(&hdr, buf, sizeof(buf)); 25 | if (err) 26 | return err; 27 | 28 | TEST_EQUALS(44100, hdr.sample_rate); 29 | TEST_EQUALS(2, hdr.channels); 30 | TEST_EQUALS(1024, hdr.frame_size); 31 | 32 | out: 33 | return err; 34 | } 35 | -------------------------------------------------------------------------------- /test/au.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file au.c Audio testcode 3 | * 4 | * Copyright (C) 2024 Alfred E. Heggestad 5 | */ 6 | 7 | #include 8 | #include 9 | #include "test.h" 10 | 11 | 12 | #define DEBUG_MODULE "au" 13 | #define DEBUG_LEVEL 5 14 | #include 15 | 16 | 17 | int test_au(void) 18 | { 19 | int err = 0; 20 | 21 | uint32_t nsamp = au_calc_nsamp(8000, 1, 20); 22 | ASSERT_EQ(160, nsamp); 23 | 24 | out: 25 | return err; 26 | } 27 | -------------------------------------------------------------------------------- /test/aulength.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file src/aulength.c audio file duration test 3 | * 4 | * Copyright (C) 2023 Lars Immisch 5 | */ 6 | 7 | #include 8 | #include 9 | #include "test.h" 10 | 11 | 12 | #define DEBUG_MODULE "aulength" 13 | #define DEBUG_LEVEL 5 14 | #include 15 | 16 | 17 | int test_aulength(void) 18 | { 19 | struct aufile *af = NULL; 20 | struct aufile_prm prm; 21 | char path[256]; 22 | 23 | re_snprintf(path, sizeof(path), "%s/beep.wav", test_datapath()); 24 | 25 | int err = aufile_open(&af, &prm, path, AUFILE_READ); 26 | TEST_ERR(err); 27 | 28 | size_t length = aufile_get_length(af, &prm); 29 | TEST_EQUALS(67, length); 30 | 31 | out: 32 | mem_deref(af); 33 | 34 | return err; 35 | } 36 | -------------------------------------------------------------------------------- /test/aupos.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file src/aupos.c audio file setposition test 3 | * 4 | * Copyright (C) 2023 Lars Immisch 5 | */ 6 | 7 | #include 8 | #include 9 | #include "test.h" 10 | 11 | 12 | #define DEBUG_MODULE "auposition" 13 | #define DEBUG_LEVEL 5 14 | #include 15 | 16 | 17 | int test_auposition(void) 18 | { 19 | struct aufile *af = NULL; 20 | struct aufile_prm prm; 21 | char path[256]; 22 | uint8_t buffer[512]; 23 | 24 | re_snprintf(path, sizeof(path), "%s/beep.wav", test_datapath()); 25 | 26 | int err = aufile_open(&af, &prm, path, AUFILE_READ); 27 | TEST_ERR(err); 28 | 29 | err = aufile_set_position(af, &prm, 67); 30 | TEST_ERR(err); 31 | 32 | /* That file is exactly 67 ms long, so we shouldn't read anything */ 33 | size_t size = sizeof(buffer); 34 | err = aufile_read(af, buffer, &size); 35 | TEST_ERR(err); 36 | 37 | /* It's possible we read data up to a ms */ 38 | TEST_ASSERT(size < 16); 39 | 40 | af = mem_deref(af); 41 | 42 | err = aufile_open(&af, &prm, path, AUFILE_READ); 43 | TEST_ERR(err); 44 | 45 | err = aufile_set_position(af, &prm, 37); 46 | TEST_ERR(err); 47 | 48 | size = sizeof(buffer); 49 | err = aufile_read(af, buffer, &size); 50 | TEST_ERR(err); 51 | 52 | /* 30 ms should be left, at 8000Hz/s, one channels and 16 bit samples 53 | that's 480 bytes */ 54 | TEST_ASSERT(size - 480 < 16); 55 | 56 | 57 | out: 58 | mem_deref(af); 59 | 60 | return err; 61 | } 62 | -------------------------------------------------------------------------------- /test/auresamp.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file auresamp.c Audio-resampler Testcode 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include "test.h" 10 | 11 | 12 | #define DEBUG_MODULE "test_auresamp" 13 | #define DEBUG_LEVEL 5 14 | #include 15 | 16 | 17 | #define SRATE 44100 18 | #define CHANNELS_IN 1 19 | #define CHANNELS_OUT 2 20 | 21 | 22 | #define SAMPLES 8 23 | 24 | 25 | /* samples from random.org with atmospheric noise */ 26 | static const int16_t inv[CHANNELS_IN * SAMPLES] = { 27 | 0x513a, 28 | 0x3f11, 29 | 0x4224, 30 | 0x601d, 31 | 0x1dc6, 32 | 0x2fb1, 33 | 0x66ee, 34 | 0x7d53 35 | }; 36 | 37 | static const int16_t ref_outv[CHANNELS_OUT * SAMPLES] = { 38 | 0x513a, 39 | 0x513a, 40 | 0x3f11, 41 | 0x3f11, 42 | 0x4224, 43 | 0x4224, 44 | 0x601d, 45 | 0x601d, 46 | 0x1dc6, 47 | 0x1dc6, 48 | 0x2fb1, 49 | 0x2fb1, 50 | 0x66ee, 51 | 0x66ee, 52 | 0x7d53, 53 | 0x7d53 54 | }; 55 | 56 | 57 | int test_auresamp(void) 58 | { 59 | struct auresamp rs; 60 | int16_t outv[CHANNELS_OUT * SAMPLES]; 61 | size_t outc = RE_ARRAY_SIZE(outv); 62 | int err; 63 | 64 | auresamp_init(&rs); 65 | 66 | err = auresamp_setup(&rs, SRATE, CHANNELS_IN, SRATE, CHANNELS_OUT); 67 | TEST_ERR(err); 68 | 69 | /* resample from mono to stereo */ 70 | err = auresamp(&rs, outv, &outc, inv, RE_ARRAY_SIZE(inv)); 71 | TEST_ERR(err); 72 | 73 | TEST_EQUALS(RE_ARRAY_SIZE(outv), outc); 74 | 75 | #if 0 76 | re_printf("\nInput samples:\n"); 77 | hexdump(stdout, inv, sizeof(inv)); 78 | re_printf("Output samples:\n"); 79 | hexdump(stdout, outv, sizeof(outv)); 80 | #endif 81 | 82 | TEST_MEMCMP(ref_outv, sizeof(ref_outv), outv, sizeof(outv)); 83 | 84 | out: 85 | return err; 86 | } 87 | -------------------------------------------------------------------------------- /test/conf.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file conf.c Testcode for Configuration module 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include "test.h" 9 | 10 | #define DEBUG_MODULE "test_conf" 11 | #define DEBUG_LEVEL 5 12 | #include 13 | 14 | 15 | int test_conf(void) 16 | { 17 | static const char *cfg = 18 | "string_val\trattarei\n" 19 | "u32_val 42\n" 20 | "i32_val -23\n" 21 | "float_val 1.5\n"; 22 | char str[256]; 23 | struct conf *conf; 24 | struct pl pl; 25 | uint32_t u32; 26 | int32_t i32; 27 | double fl; 28 | int err; 29 | 30 | err = conf_alloc_buf(&conf, (uint8_t *)cfg, strlen(cfg)); 31 | if (err) 32 | return err; 33 | 34 | err = conf_get_str(conf, "string_val", str, sizeof(str)); 35 | TEST_ERR(err); 36 | if (strcmp(str, "rattarei")) 37 | goto badmsg; 38 | 39 | err = conf_get_u32(conf, "u32_val", &u32); 40 | TEST_ERR(err); 41 | TEST_EQUALS(42, u32); 42 | 43 | err = conf_get_i32(conf, "i32_val", &i32); 44 | TEST_ERR(err); 45 | TEST_EQUALS(-23, i32); 46 | 47 | err = conf_get_float(conf, "float_val", &fl); 48 | TEST_ERR(err); 49 | TEST_EQUALS(1.5, fl); 50 | 51 | /* Non-existing parameters */ 52 | if (0 == conf_get(conf, "rattarei", &pl)) 53 | goto badmsg; 54 | 55 | out: 56 | mem_deref(conf); 57 | return err; 58 | 59 | badmsg: 60 | mem_deref(conf); 61 | return EBADMSG; 62 | } 63 | -------------------------------------------------------------------------------- /test/convert.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file convert.c Conversion Testcode 3 | * 4 | * Copyright (C) 2022 Sebastian Reimers 5 | */ 6 | #include 7 | #include "test.h" 8 | 9 | #define DEBUG_MODULE "testconvert" 10 | #define DEBUG_LEVEL 5 11 | #include 12 | 13 | 14 | int test_try_into(void) 15 | { 16 | int err = 0; 17 | size_t size; 18 | uint16_t u16 = 0; 19 | int i; 20 | 21 | #if __STDC_VERSION__ >= 201112L /* Needs C11 support */ 22 | size = SIZE_MAX; 23 | err = try_into(u16, size); 24 | TEST_EQUALS(ERANGE, err); 25 | #endif 26 | size = 5000; 27 | err = try_into_u16_from_size(&u16, size); 28 | TEST_ERR(err); 29 | TEST_EQUALS(size, u16); 30 | 31 | size = SIZE_MAX; 32 | err = try_into_u16_from_size(&u16, size); 33 | TEST_EQUALS(ERANGE, err); 34 | 35 | /* Testing int -> uint16_t */ 36 | i = INT_MAX; 37 | err = try_into_u16_from_int(&u16, i); 38 | TEST_EQUALS(ERANGE, err); 39 | 40 | i = -50; 41 | err = try_into_u16_from_int(&u16, i); 42 | TEST_EQUALS(ERANGE, err); 43 | 44 | /* Testing size_t -> int */ 45 | size = SIZE_MAX; 46 | err = try_into_int_from_size(&i, size); 47 | TEST_EQUALS(ERANGE, err); 48 | 49 | size = INT_MAX; 50 | err = try_into_int_from_size(&i, size); 51 | TEST_ERR(err); 52 | TEST_EQUALS(INT_MAX, i); 53 | 54 | out: 55 | return err; 56 | } 57 | -------------------------------------------------------------------------------- /test/cplusplus.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file cplusplus.cpp Emulate C++ applications 3 | * 4 | * Copyright (C) 2025 Alfred E. Heggestad 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include "test.h" 11 | 12 | 13 | #define DEBUG_MODULE "cplusplus" 14 | #define DEBUG_LEVEL 5 15 | #include 16 | 17 | 18 | int test_cplusplus(void) 19 | { 20 | std::cout << "test\n"; 21 | 22 | DEBUG_NOTICE("%H\n", sys_kernel_get, nullptr); 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /test/crc32.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file crc32.c CRC32 Testcode 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include "test.h" 9 | 10 | 11 | #define DEBUG_MODULE "testcrc32" 12 | #define DEBUG_LEVEL 4 13 | #include 14 | 15 | 16 | int test_crc32(void) 17 | { 18 | const struct { 19 | const char *str; 20 | uint32_t crc; 21 | } testv[] = { 22 | {"string", 0x9ebeb2a9 }, 23 | {"hei", 0x95610594 }, 24 | {"0ndka98d198aloidks9zaz1oqs5jilk", 0x92a398f6 }, 25 | }; 26 | size_t i; 27 | 28 | for (i=0; i 7 | #include 8 | #include "test.h" 9 | 10 | 11 | #define DEBUG_MODULE "test/dsp" 12 | #define DEBUG_LEVEL 5 13 | #include 14 | 15 | 16 | static int test_saturate(void) 17 | { 18 | int err = 0; 19 | 20 | /* saturate_u8 */ 21 | TEST_EQUALS( 0, saturate_u8(-100)); 22 | TEST_EQUALS( 0, saturate_u8( 0)); 23 | TEST_EQUALS( 42, saturate_u8( 42)); 24 | TEST_EQUALS(255, saturate_u8( 255)); 25 | TEST_EQUALS(255, saturate_u8( 355)); 26 | TEST_EQUALS(255, saturate_u8(9692)); 27 | 28 | /* saturate_s16 */ 29 | TEST_EQUALS(-32768, saturate_s16(-65535)); 30 | TEST_EQUALS(-32768, saturate_s16(-32768)); 31 | TEST_EQUALS( 0, saturate_s16( 0)); 32 | TEST_EQUALS( 32767, saturate_s16( 32767)); 33 | TEST_EQUALS( 32767, saturate_s16( 65535)); 34 | 35 | /* saturate_add16 */ 36 | TEST_EQUALS(-32768, saturate_add16(-30000, -30000)); 37 | TEST_EQUALS( -2000, saturate_add16( -1000, -1000)); 38 | TEST_EQUALS( 2, saturate_add16( 1, 1)); 39 | TEST_EQUALS( 32767, saturate_add16( 32766, 1)); 40 | TEST_EQUALS( 32767, saturate_add16( 30000, 30000)); 41 | 42 | /* saturate_sub16 */ 43 | TEST_EQUALS(-32768, saturate_sub16(-50000, -10000)); 44 | TEST_EQUALS( -2000, saturate_sub16( -1000, 1000)); 45 | TEST_EQUALS( 0, saturate_sub16( 1, 1)); 46 | TEST_EQUALS( 32765, saturate_sub16( 32766, 1)); 47 | TEST_EQUALS( 32767, saturate_sub16( 50000, 10000)); 48 | 49 | out: 50 | return err; 51 | } 52 | 53 | 54 | int test_dsp(void) 55 | { 56 | int err; 57 | 58 | err = test_saturate(); 59 | TEST_ERR(err); 60 | 61 | out: 62 | return err; 63 | } 64 | -------------------------------------------------------------------------------- /test/dtmf.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file dtmf.c Testcode for librem's DTMF module 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include "test.h" 10 | 11 | 12 | #define DEBUG_MODULE "test/dtmf" 13 | #define DEBUG_LEVEL 5 14 | #include 15 | 16 | 17 | static void dtmf_dec_handler(char digit, void *arg) 18 | { 19 | char *buf = arg; 20 | 21 | buf[str_len(buf)] = digit; 22 | } 23 | 24 | 25 | int test_dtmf(void) 26 | { 27 | #define SRATE 8000 28 | static const char digits[] = "2*A#7"; 29 | char dbuf[256] = ""; 30 | struct dtmf_dec *dec = NULL; 31 | struct mbuf *mb = NULL; 32 | size_t i; 33 | int err = 0; 34 | 35 | mb = mbuf_alloc(1024); 36 | if (!mb) 37 | return ENOMEM; 38 | 39 | err = dtmf_dec_alloc(&dec, SRATE, 1, dtmf_dec_handler, dbuf); 40 | if (err) 41 | goto out; 42 | 43 | /* generate audio samples with test digits */ 44 | for (i=0; ibuf, mb->end / 2); 52 | 53 | TEST_STRCMP(digits, str_len(digits), dbuf, str_len(dbuf)); 54 | 55 | out: 56 | mem_deref(dec); 57 | mem_deref(mb); 58 | return err; 59 | } 60 | -------------------------------------------------------------------------------- /test/fir.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file fir.c FIR-filter Testcode 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include "test.h" 10 | 11 | 12 | #define DEBUG_MODULE "fir" 13 | #define DEBUG_LEVEL 5 14 | #include 15 | 16 | 17 | /* 48kHz sample-rate, 8kHz cutoff (pass 0-7kHz, stop 9-24kHz) */ 18 | static const int16_t fir_48_8[] = { 19 | 238, 198, -123, -738, -1268, -1204, -380, 714, 20 | 1164, 376, -1220, -2206, -1105, 2395, 6909, 10069, 21 | 10069, 6909, 2395, -1105, -2206, -1220, 376, 1164, 22 | 714, -380, -1204, -1268, -738, -123, 198, 238 23 | }; 24 | 25 | 26 | int test_fir(void) 27 | { 28 | #define NUM_SAMPLES 8 29 | struct fir fir; 30 | static const int16_t samp_in[NUM_SAMPLES] = 31 | {-8000, -4000, -2000, 0, 2000, 4000, 8000, 4000}; 32 | static const int16_t samp_out_exp[NUM_SAMPLES] = 33 | { -59, -78, -9, 183, 421, 534, 391, -38}; 34 | int16_t samp_out[NUM_SAMPLES]; 35 | int err = 0; 36 | 37 | fir_reset(&fir); 38 | 39 | /* verify FIR-filter state */ 40 | TEST_EQUALS(0, fir.index); 41 | 42 | /* process the FIR filter */ 43 | fir_filter(&fir, samp_out, samp_in, RE_ARRAY_SIZE(samp_in), 44 | 1, fir_48_8, RE_ARRAY_SIZE(fir_48_8)); 45 | 46 | /* verify FIR-filter state */ 47 | TEST_EQUALS(NUM_SAMPLES, fir.index); 48 | TEST_ASSERT(NUM_SAMPLES <= RE_ARRAY_SIZE(fir.history)); 49 | TEST_MEMCMP(samp_in, sizeof(samp_in), fir.history, sizeof(samp_in)); 50 | 51 | /* verify output samples */ 52 | TEST_MEMCMP(samp_out_exp, sizeof(samp_out_exp), 53 | samp_out, sizeof(samp_out)); 54 | 55 | out: 56 | return err; 57 | } 58 | -------------------------------------------------------------------------------- /test/md5.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file md5.c MD5 Testcode 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include "test.h" 9 | 10 | 11 | #define DEBUG_MODULE "testmd5" 12 | #define DEBUG_LEVEL 4 13 | #include 14 | 15 | 16 | int test_md5(void) 17 | { 18 | const struct pl str = PL("a93akjshdla81mx.kjda09sdkjl12jdlksaldkjas"); 19 | const uint8_t ref[16] = { 20 | 0x9d, 0x97, 0xa5, 0xf8, 0x8d, 0x1b, 0x09, 0x7c, 21 | 0x9f, 0xf9, 0xe2, 0x9d, 0xd5, 0x43, 0xb1, 0x1d 22 | }; 23 | uint8_t digest[16]; 24 | int err; 25 | 26 | /* Test constants */ 27 | if (16 != MD5_SIZE) { 28 | DEBUG_WARNING("MD5_SIZE is %u (should be 16)\n", MD5_SIZE); 29 | return EINVAL; 30 | } 31 | if (33 != MD5_STR_SIZE) { 32 | DEBUG_WARNING("MD5_STR_SIZE is %u (should be 33)\n", 33 | MD5_STR_SIZE); 34 | return EINVAL; 35 | } 36 | 37 | /* Test md5() */ 38 | md5((const uint8_t *)str.p, str.l, digest); 39 | 40 | if (0 != memcmp(digest, ref, sizeof(digest))) { 41 | DEBUG_WARNING("md5 b0Rken: %02w\n", digest, sizeof(digest)); 42 | return EINVAL; 43 | } 44 | 45 | /* Test md5_printf() */ 46 | err = md5_printf(digest, "%r", &str); 47 | if (err) 48 | goto out; 49 | 50 | if (0 != memcmp(digest, ref, sizeof(digest))) { 51 | DEBUG_WARNING("md5_printf() is b0Rken: %02w\n", digest, 52 | sizeof(digest)); 53 | return EINVAL; 54 | } 55 | 56 | out: 57 | return err; 58 | } 59 | -------------------------------------------------------------------------------- /test/mem_pool.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file mem_pool.c Memory Pool Testcode 3 | * 4 | * Copyright (C) 2025 Sebastian Reimers 5 | */ 6 | #include 7 | #include "test.h" 8 | 9 | 10 | #define DEBUG_MODULE "test_mem_pool" 11 | #define DEBUG_LEVEL 5 12 | #include 13 | 14 | struct object { 15 | int a; 16 | }; 17 | 18 | enum { 19 | NUM_OBJECTS = 10, 20 | }; 21 | 22 | 23 | int test_mem_pool(void) 24 | { 25 | int err; 26 | 27 | struct mem_pool *pool = NULL; 28 | err = mem_pool_alloc(&pool, NUM_OBJECTS, sizeof(struct object), NULL); 29 | TEST_ERR(err); 30 | 31 | struct mem_pool_entry *e; 32 | struct object *o; 33 | 34 | for (int i = 0; i < NUM_OBJECTS; i++) { 35 | e = mem_pool_borrow(pool); 36 | TEST_ASSERT(e); 37 | 38 | o = mem_pool_member(e); 39 | TEST_NOT_EQUALS(o->a, i + 1); 40 | 41 | o->a = i + 1; 42 | } 43 | 44 | TEST_ASSERT(!mem_pool_borrow(pool)); 45 | 46 | e = mem_pool_release(pool, e); 47 | TEST_ASSERT(!e); 48 | 49 | e = mem_pool_borrow(pool); 50 | TEST_ASSERT(e); 51 | 52 | TEST_ASSERT(!mem_pool_borrow(pool)); 53 | 54 | mem_pool_flush(pool); 55 | 56 | for (int i = 0; i < NUM_OBJECTS; i++) { 57 | e = mem_pool_borrow(pool); 58 | TEST_ASSERT(e); 59 | } 60 | 61 | TEST_ASSERT(!mem_pool_borrow(pool)); 62 | 63 | err = mem_pool_extend(pool, 1); 64 | TEST_ERR(err); 65 | 66 | e = mem_pool_borrow(pool); 67 | TEST_ASSERT(e); 68 | 69 | out: 70 | mem_deref(pool); 71 | return err; 72 | } 73 | -------------------------------------------------------------------------------- /test/mock/cert.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file cert.c TLS Certificate 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include "test.h" 8 | 9 | 10 | /** 11 | * X509/PEM certificate with ECDSA keypair 12 | * 13 | * $ openssl ecparam -out ec_key.pem -name prime256v1 -genkey 14 | * $ openssl req -new -key ec_key.pem -x509 -nodes -days 3650 -out cert.pem 15 | */ 16 | const char test_certificate_ecdsa[] = 17 | "-----BEGIN CERTIFICATE-----\r\n" 18 | "MIICBzCCAa2gAwIBAgIUZy0UqzsDq7fGUsZh6QxkXgCa030wCgYIKoZIzj0EAwIw\r\n" 19 | "WTELMAkGA1UEBhMCTk8xEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu\r\n" 20 | "dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDESMBAGA1UEAwwJMTI3LjAuMC4xMB4XDTE5\r\n" 21 | "MDUyNDE5NTM0OFoXDTI5MDUyMTE5NTM0OFowWTELMAkGA1UEBhMCTk8xEzARBgNV\r\n" 22 | "BAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0\r\n" 23 | "ZDESMBAGA1UEAwwJMTI3LjAuMC4xMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE\r\n" 24 | "inP/oBEqBbXRxDzyk7sbh8rRJbfbXBRG2uJl2g6YhSkYZkifGyEueJ7+A9D9LfBh\r\n" 25 | "b5+lKXuJc02XQW5IwUmToqNTMFEwHQYDVR0OBBYEFH1vSH2IBZvKYNDPfPOk41Dw\r\n" 26 | "hyTWMB8GA1UdIwQYMBaAFH1vSH2IBZvKYNDPfPOk41DwhyTWMA8GA1UdEwEB/wQF\r\n" 27 | "MAMBAf8wCgYIKoZIzj0EAwIDSAAwRQIhAOm79QetPxioy/S0Rk9lhPgfBslgM6f4\r\n" 28 | "tihVBSpe0FdJAiAC6Usj7p3H8dvu9Oa1gtOXSJkh1MT6pkfW21YseRWP4A==\r\n" 29 | "-----END CERTIFICATE-----\r\n" 30 | "-----BEGIN EC PARAMETERS-----\r\n" 31 | "BggqhkjOPQMBBw==\r\n" 32 | "-----END EC PARAMETERS-----\r\n" 33 | "-----BEGIN EC PRIVATE KEY-----\r\n" 34 | "MHcCAQEEIMWTO9/z24fiq13MM5UF1CVD3yJjVXRe0qpTCmmZU5ppoAoGCCqGSM49\r\n" 35 | "AwEHoUQDQgAEinP/oBEqBbXRxDzyk7sbh8rRJbfbXBRG2uJl2g6YhSkYZkifGyEu\r\n" 36 | "eJ7+A9D9LfBhb5+lKXuJc02XQW5IwUmTog==\r\n" 37 | "-----END EC PRIVATE KEY-----\r\n" 38 | ; 39 | -------------------------------------------------------------------------------- /test/mqueue.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file mqueue.c Message queue testcode 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include "test.h" 9 | 10 | 11 | #define DEBUG_MODULE "mqueue_test" 12 | #define DEBUG_LEVEL 5 13 | #include 14 | 15 | 16 | #define NUM_EVENTS 3 17 | 18 | 19 | struct test { 20 | int idv[NUM_EVENTS]; 21 | void *datav[NUM_EVENTS]; 22 | unsigned idc; 23 | }; 24 | 25 | 26 | static void mqueue_handler(int id, void *data, void *arg) 27 | { 28 | struct test *test = arg; 29 | 30 | test->idv [test->idc] = id; 31 | test->datav[test->idc] = data; 32 | 33 | test->idc++; 34 | 35 | if (test->idc >= NUM_EVENTS) 36 | re_cancel(); 37 | } 38 | 39 | 40 | int test_mqueue(void) 41 | { 42 | struct mqueue *mq; 43 | struct test test; 44 | int i; 45 | int err; 46 | 47 | memset(&test, 0, sizeof(test)); 48 | 49 | err = mqueue_alloc(&mq, mqueue_handler, &test); 50 | if (err) 51 | return err; 52 | 53 | for (i=0; i 5 | #include "test.h" 6 | 7 | 8 | #define DEBUG_MODULE "test_net" 9 | #define DEBUG_LEVEL 5 10 | #include 11 | 12 | 13 | static bool ipv6_handler(const char *ifname, const struct sa *sa, void *arg) 14 | { 15 | bool *supp = arg; 16 | (void)ifname; 17 | 18 | if (AF_INET6 == sa_af(sa)) { 19 | *supp = true; 20 | return true; 21 | } 22 | 23 | return false; 24 | } 25 | 26 | 27 | bool test_ipv6_supported(void) 28 | { 29 | bool supp = false; 30 | 31 | net_if_apply(ipv6_handler, &supp); 32 | 33 | return supp; 34 | } 35 | 36 | 37 | int test_net_dst_source_addr_get(void) 38 | { 39 | struct sa dst; 40 | struct sa ip; 41 | int err; 42 | 43 | sa_init(&dst, AF_INET); 44 | sa_init(&ip, AF_UNSPEC); 45 | 46 | sa_set_str(&dst, "127.0.0.1", 53); 47 | 48 | err = net_dst_source_addr_get(&dst, &ip); 49 | if (err) 50 | return err; 51 | 52 | TEST_ASSERT(sa_is_loopback(&ip)); 53 | 54 | if (test_ipv6_supported()) { 55 | 56 | sa_init(&dst, AF_INET6); 57 | sa_init(&ip, AF_UNSPEC); 58 | sa_set_str(&dst, "::1", 53); 59 | 60 | err = net_dst_source_addr_get(&dst, &ip); 61 | if (err) 62 | return err; 63 | 64 | TEST_ASSERT(sa_is_loopback(&ip)); 65 | } 66 | else { 67 | DEBUG_NOTICE("ipv6 disabled\n"); 68 | } 69 | 70 | out: 71 | return err; 72 | } 73 | 74 | 75 | int test_net_if(void) 76 | { 77 | struct sa ip; 78 | int err; 79 | char ifname[255]; 80 | 81 | sa_set_str(&ip, "127.0.0.1", 0); 82 | 83 | err = net_if_getname(ifname, sizeof(ifname), AF_INET, &ip); 84 | TEST_ERR(err); 85 | TEST_ASSERT(str_isset(ifname)); 86 | 87 | out: 88 | return err; 89 | } 90 | -------------------------------------------------------------------------------- /test/sha.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file sha.c SHA Testcode 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include "test.h" 10 | 11 | 12 | #define DEBUG_MODULE "testsha1" 13 | #define DEBUG_LEVEL 4 14 | #include 15 | 16 | 17 | static const char *test_data[] = { 18 | "abc", 19 | "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 20 | 21 | /* 64 bytes */ 22 | "9293haoijsdlasjd9ehr98wehrlsihdflskidjflaisjdlaisdjalsdkjasdlsda", 23 | 24 | /* 96 bytes */ 25 | "9293haoijsdlasjd9ehr98wehrlsihdflskidjflaisjdlaisdjalsdkjasdlsda" 26 | "9293haoijsdlasjd9ehr98wehrlsihdf", 27 | 28 | /* 128 bytes */ 29 | "9293haoijsdlasjd9ehr98wehrlsihdflskidjflaisjdlaisdjalsdkjasdlsda" 30 | "9293haoijsdlasjd82halsdlkajsdlkjasldkjasldjlskjd9ehr98wehrlsihdd", 31 | 32 | /* 256 bytes */ 33 | "9293haoijsdlasjd9ehr98wehrlsihdflskidjflaisjdlaisdjalsdkjasdlsda" 34 | "9293haoijsdlasjd82halsdlkajsdlkjasldkjasldjlskjd9ehr98wehrlsihdd" 35 | "9293haoijsdlasjd9ehr98wehrlsihdflskidjflaisjdlaisdjalsdkjasdlsda" 36 | "9293haoijsdlasjd82halsdlkajsdlkjasldkjasldjlskjd9ehr98wehrlsihdd", 37 | }; 38 | static const char *test_results[] = { 39 | "a9993e364706816aba3e25717850c26c9cd0d89d", 40 | "84983e441c3bd26ebaae4aa1f95129e5e54670f1", 41 | "105104a6ee22de58c0888d2f9cdd56d95c14d4e7", 42 | "9962f530d85f354304efcf35ceaa29a279a3208d", 43 | "17307171329ed5aeaccf4cd4f6d02223a69af9fb", 44 | "4f051b5c4fcd0916df00f9c9dbab8608cd3355a7"}; 45 | 46 | 47 | int test_sha1(void) 48 | { 49 | uint32_t k; 50 | uint8_t digest[20]; 51 | char output[80]; 52 | 53 | for (k = 0; k < RE_ARRAY_SIZE(test_data); k++) { 54 | 55 | sha1((uint8_t *)test_data[k], strlen(test_data[k]), digest); 56 | 57 | (void)re_snprintf(output, sizeof(output), "%02w", digest, 58 | sizeof(digest)); 59 | if (strcmp(output, test_results[k])) { 60 | DEBUG_WARNING("* hash of \"%s\" incorrect:\n", 61 | test_data[k]); 62 | DEBUG_WARNING("\t%s returned\n", output); 63 | DEBUG_WARNING("\t%s is correct\n", test_results[k]); 64 | return EINVAL; 65 | } 66 | } 67 | 68 | /* success */ 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /test/telev.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file telev.c Testcode for Telephone-event 3 | * 4 | * Copyright (C) 2010 Creytiv.com 5 | */ 6 | #include 7 | #include 8 | #include "test.h" 9 | 10 | 11 | int test_telev(void) 12 | { 13 | static const char digits[] = "1234567890ABCD*#"; 14 | struct telev *tlv = NULL; 15 | struct mbuf *mb; 16 | bool marker, expect_end = false; 17 | char digit; 18 | size_t i; 19 | int err; 20 | 21 | mb = mbuf_alloc(512); 22 | if (!mb) 23 | return ENOMEM; 24 | 25 | err = telev_alloc(&tlv, 1); 26 | if (err) 27 | goto out; 28 | 29 | /* Encode all digits */ 30 | for (i=0; ipos = 0; 43 | i = 0; 44 | while (mbuf_get_left(mb) && i 7 | #include 8 | #include "test.h" 9 | 10 | 11 | #define DEBUG_MODULE "testtmr" 12 | #define DEBUG_LEVEL 5 13 | #include 14 | 15 | 16 | int test_tmr_jiffies(void) 17 | { 18 | uint64_t tmr_start, tmr_end, diff; 19 | int err = 0; 20 | 21 | tmr_start = tmr_jiffies(); 22 | sys_msleep(1); 23 | tmr_end = tmr_jiffies(); 24 | diff = tmr_end - tmr_start; 25 | 26 | TEST_ASSERT(diff >= 1); 27 | TEST_ASSERT(diff < 50); 28 | 29 | out: 30 | return err; 31 | } 32 | 33 | 34 | int test_tmr_jiffies_usec(void) 35 | { 36 | uint64_t tmr_start, diff; 37 | int i; 38 | int err = 0; 39 | 40 | tmr_start = tmr_jiffies_usec(); 41 | diff = 0; 42 | for (i = 0; i < 100000 && !diff; i++) 43 | diff = tmr_jiffies_usec() - tmr_start; 44 | 45 | TEST_ASSERT(diff >= 1); 46 | TEST_ASSERT(diff < 1000); 47 | 48 | out: 49 | return err; 50 | } 51 | -------------------------------------------------------------------------------- /test/trace.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file trace.c Trace testcode 3 | */ 4 | 5 | #ifdef HAVE_UNISTD_H 6 | #include 7 | #endif 8 | #include 9 | #include "test.h" 10 | 11 | #define DEBUG_MODULE "test_trace" 12 | #define DEBUG_LEVEL 5 13 | #include 14 | 15 | static void test_loop(int count) 16 | { 17 | int i; 18 | 19 | for (i=0; i < count; i++) { 20 | RE_TRACE_INSTANT_I("test", "Instant", i); 21 | } 22 | } 23 | 24 | int test_trace(void) 25 | { 26 | int err; 27 | 28 | if (test_mode == TEST_THREAD) 29 | return ESKIPPED; 30 | 31 | err = re_trace_init("test_trace.json"); 32 | TEST_ERR(err); 33 | 34 | RE_TRACE_PROCESS_NAME("retest"); 35 | RE_TRACE_THREAD_NAME("test_trace"); 36 | RE_TRACE_BEGIN("test", "Test Loop Start"); 37 | 38 | test_loop(100); 39 | 40 | RE_TRACE_BEGIN("test", "Flush"); 41 | err = re_trace_flush(); 42 | TEST_ERR(err); 43 | 44 | RE_TRACE_END("test", "Flush"); 45 | 46 | test_loop(25); 47 | 48 | RE_TRACE_BEGIN_FUNC(); 49 | 50 | err = re_trace_flush(); 51 | TEST_ERR(err); 52 | 53 | RE_TRACE_END_FUNC(); 54 | 55 | RE_TRACE_END("test", "Test Loop End"); 56 | 57 | err = re_trace_close(); 58 | TEST_ERR(err); 59 | 60 | /* Test TRACE after close - should do nothing */ 61 | RE_TRACE_BEGIN("test", "test after close"); 62 | 63 | #ifdef WIN32 64 | (void)_unlink("test_trace.json"); 65 | #else 66 | (void)unlink("test_trace.json"); 67 | #endif 68 | 69 | out: 70 | if (err) 71 | re_trace_close(); 72 | return err; 73 | } 74 | -------------------------------------------------------------------------------- /test/types.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file types.c Types Testcode 3 | * 4 | */ 5 | #include 6 | #include "test.h" 7 | 8 | int test_re_assert_se(void) 9 | { 10 | int err; 11 | 12 | re_assert(true); 13 | re_assert_se(!(err = 0)); 14 | 15 | return err; 16 | } 17 | -------------------------------------------------------------------------------- /test/unixsock.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file src/unixsock.c Unix domain sockets 3 | * 4 | * Copyright (C) 2022 Sebastian Reimers 5 | */ 6 | 7 | #ifdef HAVE_UNISTD_H 8 | #include 9 | #endif 10 | #include 11 | #include "test.h" 12 | #ifdef WIN32 13 | #define unlink _unlink 14 | #endif 15 | 16 | #define DEBUG_MODULE "unixsock" 17 | #define DEBUG_LEVEL 5 18 | #include 19 | 20 | 21 | #if HAVE_UNIXSOCK 22 | static void http_req_handler(struct http_conn *conn, 23 | const struct http_msg *msg, void *arg) 24 | { 25 | (void)conn; 26 | (void)msg; 27 | (void)arg; 28 | } 29 | #endif 30 | 31 | 32 | int test_unixsock(void) 33 | { 34 | #if HAVE_UNIXSOCK 35 | struct sa srv; 36 | re_sock_t fd = RE_BAD_SOCK; 37 | struct http_sock *sock; 38 | int err; 39 | char filename[32]; 40 | char socket[128]; 41 | 42 | rand_str(filename, sizeof(filename)); 43 | re_snprintf(socket, sizeof(socket), "unix:http_%s.sock", filename); 44 | 45 | err = sa_set_str(&srv, socket, 0); 46 | TEST_ERR(err); 47 | 48 | err = unixsock_listen_fd(&fd, &srv); 49 | TEST_ERR(err); 50 | 51 | err = http_listen_fd(&sock, fd, http_req_handler, NULL); 52 | TEST_ERR(err); 53 | 54 | mem_deref(sock); 55 | 56 | err = unlink(&socket[5]); 57 | TEST_ERR(err); 58 | 59 | out: 60 | if (err) 61 | (void)unlink(&socket[5]); 62 | return err; 63 | #else 64 | return ESKIPPED; 65 | #endif 66 | } 67 | --------------------------------------------------------------------------------