Giter Club home page Giter Club logo

viska's Introduction

Viska

A SIP server/framework built in Rust.

This is a wip, many things will change until it takes the final shape

Why

  • because building a customized modern SIP service on top of kamailio/asterisk/opensips as a developer is not intuitive.
  • because although there are some other servers like routr, but these are not made with development in mind, rather they have configuration that you can change. For instance you can't manipulate incoming or outgoing requests/responses.
  • because although there is nksip it requires you to not only understand how nkserver works but also Erlang and OTP in general
  • because the only real alternative is pjsip and if you are looking to build a SIP service you should probably look into that.

Having worked many years on HTTP frameworks, I really think that we can do something better in SIP.

How

It is built in Rust because that's a low lever, thread safe, performant language that I know well. It's built based on traits+generics, so that anything can be overriden at your will.

The idea is to create a small framework around the basic SIP layers, and then create libraries and implementations based on public traits for each SIP extension or service that is needed (like Registrar, Auth, Push notifications (RFC 8599) etc)

Progress

  • SIP general purpose library/parser with types
  • SDP general purpose library/parser with type
  • Transport layer
    • Udp transport
    • Tcp transport
    • WS transport
  • Transaction layer
    • Invite transaction + impl
    • Non Invite transaction + impl
  • TU layer trait
    • Registrar
    • Capabilities
    • Authentication
    • Dialogs
    • Sessions
      • Initiate a session
      • Modify a session
      • Terminating a session
    • Proxy behavior

viska's People

Contributors

vasilakisfil 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  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

viska's Issues

project progress

Hi, I see you say you will update the project this month, I would like to know when it will be possible. This project of yours is really good

Re: Update progress

Great work on this library so far. I have a project in mind that this will be perfect for.

Would you mind updating the progress on the readme to show what features are completed? Based on the code commits, some of the features appear to be completed already.

As a secondary matter, it would be great if there was an example of how to spin up a server instance that can receive SIP requests, e.g., invites. Thank you!

add config from yaml/env

Hi! I saw this item in your notes:

  • add config from yaml/env

Then I've decided to contribute some code which hopefully can be useful.
It basically aggregates .yaml files and resolves references.
The idea is simple: render a .yaml file in a loop until the result is equal to the input, meaning that all references are resolved.

#![allow(unused_parens)]

use anyhow::{Context,Result, anyhow};
use clap::{arg, App, AppSettings};
use std::ffi::OsStr;

fn main() -> Result<()> {
    let matches = App::new("mkvm")
        .about("Make virtual machines easily!")
        .setting(AppSettings::SubcommandRequiredElseHelp)
        .subcommand(
            App::new("vm")
                .about("start virtual machine(s)")
                .setting(AppSettings::ArgRequiredElseHelp)
                .arg(arg!(names: <NAME> ... "Virtual machines to start").allow_invalid_utf8(true))
                .arg(
                    arg!(files: [YAML])
                        .multiple_occurrences(true)
                        .allow_invalid_utf8(true)
                        .last(true),
                ),
        )
        .get_matches();

    let args: Args = validate(&matches, "vm")?;
    //XXX println!("Names: {:?}", args.names);
    //XXX println!("Files: {:?}", args.files);
    let yaml: String = args.render()?;
    println!("{}", yaml);
    Ok(())
}

struct Args<'a> {
    names: Vec<&'a OsStr>,
    files: Vec<&'a OsStr>,
}

fn validate<'a>(matches: &'a clap::ArgMatches, _subcommand: &str) -> Result<Args<'a>> {
    let mut stdin_seen  = false;
    let (names, files) = match matches.subcommand() {
        Some((_subcommand, sub_matches)) => {
            let names: Vec<&'a OsStr> = sub_matches
                .values_of_os("names").context("names of virtual machines is requered")?
                .collect::<Vec<_>>();
            let files: Vec<&'a OsStr> = sub_matches
                .values_of_os("files").context("a list of file names is requered")?
                .map(|path| if(path == "-" && stdin_seen) { Err(anyhow!("stdin specified multiple times")) } else { stdin_seen = true; Ok(path) })
                .map(|path| path.unwrap())
                .collect::<Vec<_>>();
            (names, files)
        }
        _ => unreachable!(),
    };
    Ok(Args{ names, files, })
}

/////////////////////////////////////////////////////////////////////////////////////////////////

#![recursion_limit = "256"]

use handlebars::Handlebars;
use serde_yaml::Value;

trait Render {
    fn render(&self) -> Result<String>;
}

impl Render for String {
    fn render(&self) -> Result<String> {
        let mut tmpl: String = self.clone();
        let mut data: Value = serde_yaml::from_str(&tmpl)?;
        let handlebars = Handlebars::new();
        let mut count = 0;
        loop {
            let rendered = handlebars.render_template(&tmpl, &data).unwrap();
            let exit = rendered == tmpl;
            tmpl = rendered;
            data = serde_yaml::from_str(&tmpl)?;
            if exit { break; }
            count = count +1;
            if (count > 10) { break; } // some extra care to avoid infinite loop. 
        }
        Ok(tmpl)
    }
}

impl Render for Vec<&OsStr> {
    fn render(&self) -> Result<String> {
        Ok((*self)
           .iter()
           .map(|path| path.reader().unwrap())
           .fold(String::new(), |mut acc, item| { acc.push_str("\n"); acc.push_str(&item); acc } )
           .render()?)
    }
}

impl<'a> Render for Args<'a> {
    fn render(&self) -> Result<String> {
        Ok((*self).files.render()?)
    }
}
 $ cargo run -- vm nginx mysql -- examples/simple/*.yaml

examples/simple/controller.yaml:

controller:
 hostname: mars
 domain: example.com
 email: [email protected]
 pubkey: "~/.ssh/id_ed25519_{{controller.hostname}}.{{controller.domain}}"

examples/simple/hypervisor.yaml:

hypervisor:
  hostname: terra
  hypervisor: libvirt
  network_bridge: br4300
  network_mode: bridge
  network_name: dmz
  pool_name: volumes
  storage_format: qcow2
  url: "qemu+ssh://rgomes@{{hypervisor.hostname}}.{{controller.domain}}/system?keyfile={{controller.pubkey}}"

It renders to:

controller:
  hostname: mars
  domain: example.com
  email: [email protected]
  pubkey: "~/.ssh/id_ed25519_mars.example.com"

hypervisor:
  hostname: terra
  hypervisor: libvirt
  network_bridge: br4300
  network_mode: bridge
  network_name: dmz
  pool_name: volumes
  storage_format: qcow2
  url: qemu+ssh://[email protected]/system?keyfile=~/.ssh/id_ed25519_mars.example.com

I'm looking forward to give Viska a try soon!
Thanks a lot :-)

Contributing to project

I'm looking to contribute to this project. I'm building out a VoIP as a personal project and am on board with the "whys" in the readme. I know the basics of SIP, I'm familiar with Rust. I'm unsure about how to go about starting up the server, or how to begin really.
I forked the project. If you could give me a basic run down at your convenience, I would be greatly appreciative.
My email is [email protected]

Also, any pointers to start out would be great as well.

Sip client implementation

I was looking into writing a minimal sip client (preferably in rust), avoiding the use of pjsip.
This project seems to be the closest thing to what I'm looking for, so far.
I see that the project currently aims to be a nice sip framework to build sip servers, will it support the client side application also?
Will it also provide implementation for media transport, or is it focused on signaling only?

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.