Giter Club home page Giter Club logo

go-m3ua's Introduction

go-m3ua

Simple M3UA protocol implementation in the Go programming language.

CI status golangci-lint Go Reference GitHub

Quickstart

Installation

Run go mod tidy in your project's directory to collect the required packages automatically.

This project follows the Release Policy of Go.

*Non-Linux machines are NOT supported, as this package relies much on github.com/ishidawataru/sctp.

Trying Examples

Working examples are available in examples directory. Just executing the following commands, you can see the client and server setting up M3UA connection.

# Run Server first
cd examples/server
go run m3ua-server.go

// Run Client then
cd examples/client
go run m3ua-client.go

There is also an example for Point Code format conversion, which works like this;

$ ./pc-conv -raw 1234 -variant 3-8-3
2023/04/05 06:07:08 PC successfully converted.
        Raw: 1234, Formatted: 0-154-2, Variant: 3-8-3
$ 
$ ./pc-conv -str 1-234-5 -variant 4-3-7
2023/04/05 06:07:08 PC successfully converted.
        Raw: 29957, Formatted: 1-234-5, Variant: 4-3-7

For Developers

The API design is kept as similar as possible to other protocols in standard net package. To establish M3UA connection as client/server, you can use Dial() and Listen()/Accept() without caring about the underlying SCTP association, as go-m3ua handles it together with M3UA ASPSM & ASPTM procedures.

Here is an example to develop your own M3UA client using go-m3ua.

First, you need to create *Config used to setup/maintain M3UA connection.

config := m3ua.NewClientConfig(
    &m3ua.HeartbeatInfo{
        Enabled:  true,
        Interval: time.Duration(3 * time.Second),
        Timer:    time.Duration(10 * time.Second),
    },
    0x11111111, // OriginatingPointCode
    0x22222222, // DestinationPointCode
    1,          // AspIdentifier
    params.TrafficModeLoadshare, // TrafficModeType
    0,                     // NetworkAppearance
    0,                     // CorrelationID
    []uint32{1, 2},        // RoutingContexts
    params.ServiceIndSCCP, // ServiceIndicator
    0, // NetworkIndicator
    0, // MessagePriority
    1, // SignalingLinkSelection
)
// set nil on unnecessary paramters.
config.CorrelationID = nil

Then, prepare network addresses and context and try to connect with Dial().

// setup SCTP peer on the specified IPs and Port.
raddr, err := sctp.ResolveSCTPAddr("sctp", SERVER_IPS)
if err != nil {
    log.Fatal(err)
}

ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
defer cancel()

conn, err := m3ua.Dial(ctx, "m3ua", nil, raddr, config)
if err != nil {
    log.Fatalf("Failed to dial M3UA: %s", err)
}
defer conn.Close()

Now you can Read() / Write() data from/to the remote endpoint.

if _, err := conn.Write(d); err != nil {
    log.Fatalf("Failed to write M3UA data: %s", err)
}
log.Printf("Successfully sent M3UA data: %x", d)

buf := make([]byte, 1500)
n, err := conn.Read(buf)
if err != nil {
    log.Fatal(err)
}

log.Printf("Successfully read M3UA data: %x", buf[:n])

See example/server directory for server example.

Supported Features

Messages

Class Message Supported Notes
Transfer Payload Data Message (DATA) Yes RFC4666#3.3
SSNM Destination Unavailable (DUNA) Yes RFC4666#3.4
Destination Available (DAVA) Yes
Destination State Audit (DAUD) Yes
Signalling Congestion (SCON) Yes
Destination User Part Unavailable (DUPU) Yes
Destination Restricted (DRST) Yes
ASPSM ASP Up Yes RFC4666#3.5
ASP Up Acknowledgement (ASP Up Ack) Yes
ASP Down Yes
ASP Down Acknowledgement (ASP Down Ack) Yes
Heartbeat (BEAT) Yes
Heartbeat Acknowledgement (BEAT Ack) Yes
RKM Registration Request (REG REQ) RFC4666#3.6
Registration Response (REG RSP)
Deregistration Request (DEREG REQ)
Deregistration Response (DEREG RSP)
ASPTM ASP Active Yes RFC4666#3.7
ASP Active Acknowledgement (ASP Active Ack) Yes
ASP Inactive Yes
ASP Inactive Acknowledgement (ASP Inactive Ack) Yes
MGMT Error Yes RFC4666#3.8
Notify Yes

Parameters

Type Parameters Supported Notes
Common INFO String Yes
Routing Context Yes
Diagnostic Information Yes
Heartbeat Data Yes
Traffic Mode Type Yes
Error Code Yes
Status Yes
ASP Identifier Yes
M3UA-specific Network Appearance Yes
User/Cause Yes
Congestion Indications Yes
Concerned Destination Yes
Routing Key Yes
Registration Result Yes
Deregistration Result Yes
Local Routing Key Identifier Yes
Destination Point Code Yes
Service Indicators Yes
Originating Point Code List Yes
Protocol Data Yes
Registration Status Yes
Deregistration Status Yes

Disclaimer

This is still experimental project. In some part, the behavior is not fully compliant with RFC, and some of the features are not even implemented yet.

Also note that some exported APIs may be changed without any notice before first release (v1.0.0).

Author

Yoshiyuki Kurauchi (Website)

LICENSE

MIT

go-m3ua's People

Contributors

dependabot-preview[bot] avatar dependabot[bot] avatar kazukiigeta avatar moznion avatar vazir avatar wmnsk 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

Watchers

 avatar  avatar  avatar  avatar  avatar

go-m3ua's Issues

Improve robustness

In current implementation the Decoder might crash when receiving malformed packets.
We should use gofuzz to find crashes and improve robustness.

m3ua.Conn is not concurrency-safe / has data-races

Hi!

Here are a few issues I found with m3ua.Conn:

  • messages.Data.MarshalBinary will call SetLength on its inner params.Param (eg. RoutingContexts)

    go-m3ua/conn.go

    Lines 94 to 100 in 3084b69

    d, err := messages.NewData(
    c.cfg.NetworkAppearance, c.cfg.RoutingContexts, params.NewProtocolData(
    c.cfg.OriginatingPointCode, c.cfg.DestinationPointCode,
    c.cfg.ServiceIndicator, c.cfg.NetworkIndicator,
    c.cfg.MessagePriority, c.cfg.SignalingLinkSelection, b,
    ), c.cfg.CorrelationID,
    ).MarshalBinary()

    But these params.Param are globals from the cfg, so SetLength will be called concurrently on these params.Param from concurrent Write to the m3ua.Conn.
    Solution (in order of perf impact):

    • Call SetLength once / only when the params.Param is modified
    • Deep copy the params.Param from cfg before handing it to messages.NewData
    • Call conn.Mu.Lock() in WriteToStreamWithConfig
  • c.cfg.HeartbeatInfo.Data is read and written concurrently without a mutex or an atomic pointer.

    myData := c.cfg.HeartbeatInfo.Data

IMHO, seeing these two issues; Conn.cfg should never be modifed by Conn, and only the user of a m3ua.Conn should be able to change the cfg.

  • c.state is read and written concurrently (eg. in conn.Write and some ASP state updates) without c.state reads not always being protected by a Mutex.
    Solution (in order of perf impact):
    • Use atomic.Pointer[State] to hold the conn's State, and Load/Store everywhere needed
    • Call conn.Mu.Lock() every time c.state is read

I hope it'll help!

Cheers,
Valentin

Current M3UA implementation, drops connection when heartbeat is enabled

All goes well, reading and writing works while HB interval set to 0

(excerpt from sample m3ua client)
hbInt = flag.Duration("hb-interval", 0, "Interval for M3UA BEAT. Put 0 to disable")

when not zero, reader code fails after a few reads with the following error

2020/10/27 00:38:55 Read: deadbeef
2020/10/27 00:38:55 Error reading from M3UA conn: M3UA Conn not established
2020/10/27 00:38:55 Recovered from crash occurred on connection with: %!s()

If HB is NOT enabled, that m3UA clent side does not understand the connection disappearance (until any write occures)

Sample code works, since there is HB = 0 in all configs and data direction is client to server
Testing is easy, just set HB interval to 1 and wait for a few packets to pass

in functions param SetLength calculate not correct len

example:

func (a *AspUpAck) SetLength() {
	if param := a.AspIdentifier; param != nil {
		param.SetLength()
	}
	if param := a.InfoString; param != nil {
		param.SetLength()
	}

	a.Header.SetLength() //8 byte header
	a.Header.Length += uint32(a.MarshalLen()) // MarshalLen return len payload+len header
}

When two SCTP messages arrives on the wire, only the second is returned by m3ua

Dear @wmnsk

Hit one bug, not sure where does it root comes from, but I traced to the wire:

When there is 2 messages on the SCTP returned as one packet, like that:

image

On the m3ua side there is only the ending packet (end dtid in the picture), and the 1st one (request report bcsm report on the pic) is lost.

image

I will be grateful if you can look at it

windows go 1.22 error on install

hi
i can not import this package
go version go1.22.1 windows/amd64

 go mod tidy
go: finding module for package github.com/wmnsk/go-tcap/tcap
go: finding module for package github.com/wmnsk/go-m3ua/messages/params
go: finding module for package github.com/wmnsk/go-m3ua/messages
go: finding module for package github.com/wmnsk/go-m3ua/sctp
go: found github.com/wmnsk/go-m3ua/messages in github.com/wmnsk/go-m3ua v0.1.9
go: found github.com/wmnsk/go-m3ua/messages/params in github.com/wmnsk/go-m3ua v0.1.9
go: finding module for package github.com/wmnsk/go-tcap/tcap
go: finding module for package github.com/wmnsk/go-m3ua/sctp
go: ss7test imports
        github.com/wmnsk/go-m3ua/sctp: module github.com/wmnsk/go-m3ua@latest found (v0.1.9), but does not contain package github.com/wmnsk/go-m3ua/sctp
go: ss7test imports
        github.com/wmnsk/go-tcap/tcap: module github.com/wmnsk/go-tcap@latest found (v0.0.0-20230328083004-def14b7674dd), but does not contain package github.com/wmnsk/go-tcap/tcap
PS D:\wamp64\www\1403\golang\ss7-m3ua>

Handling connection interruptions

@wmnsk , please review the pull request. Looks like io.EOF is received when the connection breaks (for instance killing the remote end m3ua server). Otherwise client stays connected, just producing errors, upon the write attempt.
Server in this case also immediately senses the remote client disconnected.

Is library support MultiHoming ?

Hi!

How I can use MultiHoming in my project? I can use only this method, for one connect:

sctpLocalAddr := &sctp.SCTPAddr{
	IPAddrs:  "10.10.10.4",,
	Port:    9500,
}
sctpRemoteIP := &sctp.SCTPAddr{
	IPAddrs: "10.10.10.5",
	Port:    9501,
}
conn, err := m3ua.Dial(*ctx, "m3ua", sctpLocalAddr, sctpRemoteIP, m3conf)

Thanks for help!

PC-based routing

Route packets by wrapping IP layer.

  • add PC variant converter
  • add interface to retrieve IP address/Port from PC
  • add helper functions to manage M3UA entity with PC

func Read reads data from the connection

Hi,

Please could you help me, give simple sample for uses func Read() in conn.go line 61:
func (c *Conn) Read(b []byte) (n int, err error)

How use its and how I can call its ?
Thanks!

gt

hi
can we send gt ( global title ) with this library?

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.