-
Notifications
You must be signed in to change notification settings - Fork 879
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support SCTP port mapping #1825
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package main | ||
|
||
import ( | ||
"io" | ||
"log" | ||
"net" | ||
"sync" | ||
|
||
"github.com/ishidawataru/sctp" | ||
) | ||
|
||
// SCTPProxy is a proxy for SCTP connections. It implements the Proxy interface to | ||
// handle SCTP traffic forwarding between the frontend and backend addresses. | ||
type SCTPProxy struct { | ||
listener *sctp.SCTPListener | ||
frontendAddr *sctp.SCTPAddr | ||
backendAddr *sctp.SCTPAddr | ||
} | ||
|
||
// NewSCTPProxy creates a new SCTPProxy. | ||
func NewSCTPProxy(frontendAddr, backendAddr *sctp.SCTPAddr) (*SCTPProxy, error) { | ||
listener, err := sctp.ListenSCTP("sctp", frontendAddr) | ||
if err != nil { | ||
return nil, err | ||
} | ||
// If the port in frontendAddr was 0 then ListenSCTP will have a picked | ||
// a port to listen on, hence the call to Addr to get that actual port: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do you mean that if the port is not specified is ephemeral? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes. the comment is taken from |
||
return &SCTPProxy{ | ||
listener: listener, | ||
frontendAddr: listener.Addr().(*sctp.SCTPAddr), | ||
backendAddr: backendAddr, | ||
}, nil | ||
} | ||
|
||
func (proxy *SCTPProxy) clientLoop(client *sctp.SCTPConn, quit chan bool) { | ||
backend, err := sctp.DialSCTP("sctp", nil, proxy.backendAddr) | ||
if err != nil { | ||
log.Printf("Can't forward traffic to backend sctp/%v: %s\n", proxy.backendAddr, err) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please change this to use logrus package. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Currently, |
||
client.Close() | ||
return | ||
} | ||
clientC := sctp.NewSCTPSndRcvInfoWrappedConn(client) | ||
backendC := sctp.NewSCTPSndRcvInfoWrappedConn(backend) | ||
|
||
var wg sync.WaitGroup | ||
var broker = func(to, from net.Conn) { | ||
io.Copy(to, from) | ||
from.Close() | ||
to.Close() | ||
wg.Done() | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It doesn't appear that 'dir' is used here. Should it be removed and the invocations below adjusted? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, thought the placement would show more context. I mean the "dir" parameter of the broker function 7 lines up. |
||
wg.Add(2) | ||
go broker(clientC, backendC) | ||
go broker(backendC, clientC) | ||
|
||
finish := make(chan struct{}) | ||
go func() { | ||
wg.Wait() | ||
close(finish) | ||
}() | ||
|
||
select { | ||
case <-quit: | ||
case <-finish: | ||
} | ||
clientC.Close() | ||
backendC.Close() | ||
<-finish | ||
} | ||
|
||
// Run starts forwarding the traffic using SCTP. | ||
func (proxy *SCTPProxy) Run() { | ||
quit := make(chan bool) | ||
defer close(quit) | ||
for { | ||
client, err := proxy.listener.Accept() | ||
if err != nil { | ||
log.Printf("Stopping proxy on sctp/%v for sctp/%v (%s)", proxy.frontendAddr, proxy.backendAddr, err) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here use logrus There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As above, |
||
return | ||
} | ||
go proxy.clientLoop(client.(*sctp.SCTPConn), quit) | ||
} | ||
} | ||
|
||
// Close stops forwarding the traffic. | ||
func (proxy *SCTPProxy) Close() { proxy.listener.Close() } | ||
|
||
// FrontendAddr returns the SCTP address on which the proxy is listening. | ||
func (proxy *SCTPProxy) FrontendAddr() net.Addr { return proxy.frontendAddr } | ||
|
||
// BackendAddr returns the SCTP proxied address. | ||
func (proxy *SCTPProxy) BackendAddr() net.Addr { return proxy.backendAddr } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: should probably update the comment at the start of the function to include SCTP.