Giter Club home page Giter Club logo

libsip's Introduction

libsip

DEPRECIATED: Since the release of nom 6, this library fails to compile. It needs to be rewritten entirely for the new nom version.

libsip is a library implementation of the sip protocol as described in rfc3261. libsip intends to implement parsing the entire SIP Protocol, but will only provide helpers for certain common use cases. I begin developing this library because i was frustrated with many of the SIP clients / Libraries on linux.

WIP This library is still very much under construction.

License: MIT Crates.io Docs.rs Build Status Build status

Running the examples

git clone https://github.com/ByteHeathen/libsip
cd /libsip
# This example expects a server with the credentials in examples/udp_register.rs
# to be running without it will fail.
cargo run --example registration
# This example expects a server with the credentials in examples/console.rs
# to be running without it will fail. It prints all requests received to the terminal.
cargo run --example console

dependencies

Development

I've been using fusionpbx as the testing server for this library. I use a VirtualBox virtual machine running in bridged mode to simulate a PBX server running on my local network. At this point i have only been able to implement Placing Calls, Sending Messages and SIP registration.

Alternatives

  • parsip Is only for parsing SIP messages. I wanted libsip to be able to handle some user case's specifically Registration.
  • sip-codec I attempted to use this library first, lots of features are not implemented like writing sip requests and a few other fairly common things. I also wanted SIP Headers to be in the form of an enum witch would have required basically rewriting the whole crate.
  • sip This crate appears to be empty
  • tokio-sip This crate also appears to be empty

libsip's People

Contributors

fallingsnow avatar kalitaalexey avatar malarinv avatar vasilakisfil avatar wendivoid avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

libsip's Issues

Contact header does not follow RFC 3840

Hi,

First of all kudos for the parser. I mean, I am surprised how closely you are following the 3261 RFC, you have saved me tons of time. Now to the topic:

I am building a simple SIP server and I was trying to integrate with the Blink SIP client, but I couldn't even make it register, no matter what. I had to check what Kamailio responds to figure out what was missing from the SIP response. The following is produced by current libsip:

Contact: sip:[email protected]:5066;+sip.instance=<urn:uuid:1e020c2b-46f6-4867-9d11-65547b8967fa>;expires=600

and this is what it should produce:

Contact: sip:[email protected]:5066;+sip.instance="<urn:uuid:1e020c2b-46f6-4867-9d11-65547b8967fa>";expires=600

As you can see, it's just encapsulating the +sip.instance param value under double quotes. It's related to RFC 3840 (specifically +sip.instance is defined in RFC 5626 but follows the RFC 3840).

I haven't gone through the whole RFC3840, but it seems like the change is simple enough: if the param is well known (defined in RFC 3840) or starts with a plus sign (+) then the parser must check the RFC 3840 rules. Rules are simple, but specifically for the case that the value is a string, it must be enclosed by "< and >" (at least that's what I get from the ABNF).

This is the initial REGISTER request btw:

REGISTER sip:192.168.1.223 SIP/2.0
Via: SIP/2.0/UDP 192.168.1.223:5066;rport;branch=z9hG4bKPj4f07db29-94d9-4c31-8cc4-652dc54d5ec1
Max-Forwards: 70
From: "vasilakisfil" <sip:[email protected]>;tag=13727392-aeed-4660-8958-445820a1decf
To: "vasilakisfil" <sip:[email protected]>
Contact: <sip:[email protected]:5066>;+sip.instance="<urn:uuid:1e020c2b-46f6-4867-9d11-65547b8967fa>"
Call-ID: 07caac9f-6803-46b0-86f4-6c24475a6daa
CSeq: 1 REGISTER
Expires: 600
Supported: gruu
User-Agent: Blink 3.2.1 (Linux)
Content-Length:  0

Funny thing is that Blink incorporates a SIP logger, but it wouldn't even show the incoming requests without the proper encapsulation..

Update to nom 6.0.1

There are numerous errors like the one below using 6.0.0-alpha1.

error[E0277]: the trait bound `E: FromExternalError<&'a [u8], E>` is not satisfied
   --> /home/ayrton/Coding/rust/libsip/src/uri/domain.rs:77:43
    |
77  |     let (input, port) = opt::<_, _, E, _>(map_res::<_, _, _, _, E, _, _>(
    |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `FromExternalError<&'a [u8], E>` is not implemented for `E`
    | 
   ::: /home/ayrton/.cargo/registry/src/github.com-1ecc6299db9ec823/nom-6.0.1/src/combinator/mod.rs:115:37
    |
115 | pub fn map_res<I: Clone, O1, O2, E: FromExternalError<I, E2>, E2, F, G>(
    |                                     ------------------------ required by this bound in `map_res`
    |
help: consider further restricting this bound
    |
69  | pub fn parse_domain_domain<'a, E: ParseError<&'a [u8]> + FromExternalError<&'a [u8], E>>(
    |                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Return std::io::Error instead of failure

The main project i wrote this library for is Nirah. Witch mostly deals with io Error's instead of failure::Error. So just for ease of use as well as remove the necessary failure dependency

incomplete messages parsed as if they were correct?

I'm trying to use this parser but I'm seeing some strange behaviour on some messages I believe should not parse correctly (and they do).
For example, if I pass the following text (this is simulating a partially read message):

INVITE sip:[email protected] SIP/2.0
Via: SIP/2.0/TCP client.atlanta.example.com:5060;branch=z9hG4bK74bf9
Max-For

this ends up being parsed correctly and the parser believes "Max-For" is the body, which is incorrect.

Debug output of the parsed message is

Request { method: Invite, uri: Uri { schema: Some(Sip), host: Domain("biloxi.example.com", None), auth: Some(UriAuth { username: "bob", password: None }), parameters: [] }, version: Version(2, 0), headers: Headers([Via(ViaHeader { version: Version(2, 0), transport: Tcp, uri: Uri { schema: None, host: Domain("client.atlanta.example.com", Some(5060)), auth: None, parameters: [Branch("z9hG4bK74bf9")] } })]), body: [77, 97, 120, 45, 70, 111, 114] } []

shouldn't the parser expect a double line break (CRLF) after all headers, then optionally read body if Content-Length was found before?

As far as I can tell, this sample message should not parse correctly.

Named parsers fail to parse named headers without name

So, as titled.
Notation like From: sip:[email protected];tag=47e9e947377149ba882adad161eacae0 is allowed in rfc, but not implemented in libsip. Parser skips and parses them like Other header.
Maybe changing impl_named_parser to something like this will fix it.

macro_rules! impl_named_parser {
    ($name:tt, $tag:tt, $variant:ident) => {
        named!(pub $name<Header>, do_parse!(
            tag_no_case!($tag) >>
            opt!(take_while!(is_space)) >>
            char!(':') >>
            opt!(take_while!(is_space)) >>
            res: alt!(
                do_parse!(
                    out: parse_named_field_value >>
                    params: parse_named_field_params >>
                    tag!("\r\n") >> 
                    (Header::$variant(NamedHeader { display_name: out.0, uri: out.1, params: params }))
                ) | 
                do_parse!(
                    out: parse_uri >> 
                    params: parse_named_field_params >>
                    tag!("\r\n") >> 
                    (Header::$variant(NamedHeader { display_name: None, uri: out, params: params }))
                )
            ) >> 
            (res)
        ));
    }
}

Authentication

Only md5 basic digest auth is implemented in registration manager.

missing server authentication instrumentation

Looking at the code, the way I see it at least, it seems like the AuthHeader is only for client auth. We need to improve that part a bit and maybe making it a bit more safe (now all params are in a HashMap).

I am gonna come up with a solution this week cause I really need authentication working on my project.

server-side SIP

Hi, not a real issue but more curiosity: is that library focused on client-side SIP or on server side SIP as well ? When I say server I mean proxy,b2bua, registrar, redirect server etc.

For instance, the RegistrationManager is client-focused.

Project state and contributing

Hi, thank you for creating this library!
I would very much like to contribute to the project to help it reach future milestones.

I don’t see any issues though. What is the current status of this library?

debug nom errors

Hi,

I am curious how I can debug nom errors. In nom, most helpful functions (like convert_error) operate under &str while the libsip library uses &[u8]. At some point in my code I have something like:

async fn process_request(request: common::bytes::BytesMut) -> Result<Vec<u8>, String> {
    let (_, request) = libsip::parse_message::<VerboseError<&[u8]>>(&request.to_vec())
        .map_err(|e| e.to_string())?;
    let response = processor::get_response(request).await?;
    Ok(format!("{}", response).into_bytes())
}

the e.to_string() does not give very helpful data, even if I do format!("{:?}", e), it's just prints plain binary (array of numbers). Nom provides some pretty good support for human-friendly errors and I would like to use it somehow. Ideas how to convert the libsip VerboseError<&[u8]> to VerboseError<&str> ?

Sorry, I am a bit new to Rust.

Provide SipMessageError instead of many Missing...

I was thinking about adding more errors to such functions as method, status_code and etc.
I realized that it would make developers' life miserable because there will be more errors to handle.
I'm going to provide a pull request to provide only 1 error - enum SipMessageError

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.